From 79fb0dac2084406296a3baf216c946d0ebddc9e1 Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Wed, 4 Dec 2024 13:12:53 +0100 Subject: [PATCH 1/5] Drop vendor directory --- .../gocheckcompilerdirectives/LICENSE | 21 - .../checkcompilerdirectives.go | 105 - vendor/4d63.com/gochecknoglobals/LICENSE | 21 - .../checknoglobals/check_no_globals.go | 200 - vendor/github.com/4meepo/tagalign/.gitignore | 75 - .../github.com/4meepo/tagalign/.golangci.yml | 106 - .../4meepo/tagalign/.goreleaser.yml | 32 - vendor/github.com/4meepo/tagalign/LICENSE | 21 - vendor/github.com/4meepo/tagalign/Makefile | 7 - vendor/github.com/4meepo/tagalign/README.md | 130 - vendor/github.com/4meepo/tagalign/options.go | 37 - vendor/github.com/4meepo/tagalign/tagalign.go | 459 - .../github.com/Abirdcfly/dupword/.gitignore | 183 - .../Abirdcfly/dupword/.goreleaser.yml | 72 - vendor/github.com/Abirdcfly/dupword/LICENSE | 21 - vendor/github.com/Abirdcfly/dupword/README.md | 153 - .../github.com/Abirdcfly/dupword/dupword.go | 343 - .../github.com/Abirdcfly/dupword/version.go | 41 - vendor/github.com/Antonboom/errname/LICENSE | 21 - .../errname/pkg/analyzer/analyzer.go | 135 - .../Antonboom/errname/pkg/analyzer/facts.go | 272 - vendor/github.com/Antonboom/nilnil/LICENSE | 21 - .../Antonboom/nilnil/pkg/analyzer/analyzer.go | 184 - .../Antonboom/nilnil/pkg/analyzer/config.go | 79 - .../nilnil/pkg/analyzer/func_type_stack.go | 29 - .../github.com/Antonboom/testifylint/LICENSE | 21 - .../testifylint/analyzer/analyzer.go | 93 - .../testifylint/analyzer/checkers_factory.go | 81 - .../testifylint/internal/analysisutil/doc.go | 9 - .../testifylint/internal/analysisutil/file.go | 28 - .../internal/analysisutil/format.go | 34 - .../internal/analysisutil/object.go | 34 - .../testifylint/internal/analysisutil/pkg.go | 19 - .../internal/checkers/blank_import.go | 69 - .../internal/checkers/bool_compare.go | 212 - .../internal/checkers/call_meta.go | 133 - .../testifylint/internal/checkers/checker.go | 23 - .../internal/checkers/checkers_registry.go | 109 - .../testifylint/internal/checkers/compares.go | 99 - .../testifylint/internal/checkers/empty.go | 169 - .../internal/checkers/error_is_as.go | 142 - .../internal/checkers/error_nil.go | 92 - .../internal/checkers/expected_actual.go | 179 - .../internal/checkers/float_compare.go | 50 - .../internal/checkers/formatter.go | 187 - .../internal/checkers/go_require.go | 345 - .../testifylint/internal/checkers/helpers.go | 43 - .../internal/checkers/helpers_basic_type.go | 113 - .../internal/checkers/helpers_bool.go | 33 - .../internal/checkers/helpers_comparison.go | 68 - .../internal/checkers/helpers_context.go | 126 - .../internal/checkers/helpers_diagnostic.go | 80 - .../internal/checkers/helpers_error.go | 42 - .../internal/checkers/helpers_format.go | 26 - .../internal/checkers/helpers_http.go | 35 - .../internal/checkers/helpers_interface.go | 48 - .../internal/checkers/helpers_len.go | 55 - .../internal/checkers/helpers_naming.go | 26 - .../internal/checkers/helpers_nil.go | 18 - .../internal/checkers/helpers_suite.go | 40 - .../internal/checkers/helpers_testing.go | 36 - .../testifylint/internal/checkers/len.go | 64 - .../internal/checkers/negative_postive.go | 175 - .../internal/checkers/nil_compare.go | 56 - .../internal/checkers/printf/LICENSE | 27 - .../internal/checkers/printf/doc.go | 6 - .../internal/checkers/printf/printf.go | 559 - .../internal/checkers/require_error.go | 250 - .../checkers/suite_broken_parallel.go | 89 - .../internal/checkers/suite_dont_use_pkg.go | 80 - .../checkers/suite_extra_assert_call.go | 99 - .../internal/checkers/suite_subtest_run.go | 60 - .../internal/checkers/suite_thelper.go | 67 - .../internal/checkers/useless_assert.go | 88 - .../testifylint/internal/config/config.go | 154 - .../internal/config/flag_value_types.go | 114 - .../testifylint/internal/testify/const.go | 17 - vendor/github.com/BurntSushi/toml/.gitignore | 2 - vendor/github.com/BurntSushi/toml/COPYING | 21 - vendor/github.com/BurntSushi/toml/README.md | 120 - vendor/github.com/BurntSushi/toml/decode.go | 615 - .../github.com/BurntSushi/toml/deprecated.go | 29 - vendor/github.com/BurntSushi/toml/doc.go | 8 - vendor/github.com/BurntSushi/toml/encode.go | 778 - vendor/github.com/BurntSushi/toml/error.go | 347 - .../github.com/BurntSushi/toml/internal/tz.go | 36 - vendor/github.com/BurntSushi/toml/lex.go | 1287 - vendor/github.com/BurntSushi/toml/meta.go | 148 - vendor/github.com/BurntSushi/toml/parse.go | 846 - .../github.com/BurntSushi/toml/type_fields.go | 238 - .../github.com/BurntSushi/toml/type_toml.go | 65 - .../github.com/Crocmagnon/fatcontext/LICENSE | 21 - .../fatcontext/pkg/analyzer/analyzer.go | 224 - .../github.com/Djarvur/go-err113/.gitignore | 15 - .../Djarvur/go-err113/.golangci.yml | 150 - .../github.com/Djarvur/go-err113/.travis.yml | 24 - vendor/github.com/Djarvur/go-err113/LICENSE | 21 - .../github.com/Djarvur/go-err113/README.adoc | 75 - .../Djarvur/go-err113/comparison.go | 123 - .../Djarvur/go-err113/definition.go | 74 - vendor/github.com/Djarvur/go-err113/err113.go | 90 - .../go-exhaustruct/v3/LICENSE | 21 - .../go-exhaustruct/v3/analyzer/analyzer.go | 318 - .../v3/internal/comment/cache.go | 35 - .../v3/internal/comment/directive.go | 28 - .../v3/internal/pattern/list.go | 82 - .../v3/internal/structure/fields-cache.go | 35 - .../v3/internal/structure/fields.go | 127 - .../Masterminds/semver/v3/.gitignore | 1 - .../Masterminds/semver/v3/.golangci.yml | 27 - .../Masterminds/semver/v3/CHANGELOG.md | 242 - .../Masterminds/semver/v3/LICENSE.txt | 19 - .../github.com/Masterminds/semver/v3/Makefile | 31 - .../Masterminds/semver/v3/README.md | 258 - .../Masterminds/semver/v3/SECURITY.md | 19 - .../Masterminds/semver/v3/collection.go | 24 - .../Masterminds/semver/v3/constraints.go | 594 - .../github.com/Masterminds/semver/v3/doc.go | 184 - .../Masterminds/semver/v3/version.go | 639 - .../OpenPeeDeeP/depguard/v2/.gitignore | 15 - .../OpenPeeDeeP/depguard/v2/LICENSE | 674 - .../OpenPeeDeeP/depguard/v2/README.md | 163 - .../OpenPeeDeeP/depguard/v2/depguard.go | 95 - .../depguard/v2/internal/utils/errors.go | 18 - .../depguard/v2/internal/utils/variables.go | 131 - .../OpenPeeDeeP/depguard/v2/settings.go | 240 - vendor/github.com/PuerkitoBio/rehttp/LICENSE | 14 - .../github.com/PuerkitoBio/rehttp/README.md | 18 - .../PuerkitoBio/rehttp/cancelreader.go | 36 - .../PuerkitoBio/rehttp/context_post17.go | 11 - .../PuerkitoBio/rehttp/context_pre17.go | 10 - .../rehttp/perattempttimeout_post17.go | 19 - .../rehttp/perattempttimeout_pre17.go | 19 - .../github.com/PuerkitoBio/rehttp/rehttp.go | 405 - .../PuerkitoBio/rehttp/timeouterr_post113.go | 18 - .../PuerkitoBio/rehttp/timeouterr_pre113.go | 15 - vendor/github.com/adjust/rmq/v5/.gitignore | 27 - vendor/github.com/adjust/rmq/v5/LICENSE | 22 - vendor/github.com/adjust/rmq/v5/README.md | 654 - .../adjust/rmq/v5/batch_consumer.go | 11 - vendor/github.com/adjust/rmq/v5/cleaner.go | 83 - vendor/github.com/adjust/rmq/v5/connection.go | 351 - vendor/github.com/adjust/rmq/v5/consumer.go | 11 - vendor/github.com/adjust/rmq/v5/deliveries.go | 46 - vendor/github.com/adjust/rmq/v5/delivery.go | 118 - vendor/github.com/adjust/rmq/v5/errors.go | 53 - vendor/github.com/adjust/rmq/v5/header.go | 79 - vendor/github.com/adjust/rmq/v5/queue.go | 589 - vendor/github.com/adjust/rmq/v5/rand.go | 22 - .../github.com/adjust/rmq/v5/redis_client.go | 26 - vendor/github.com/adjust/rmq/v5/redis_keys.go | 27 - .../github.com/adjust/rmq/v5/redis_wrapper.go | 76 - vendor/github.com/adjust/rmq/v5/state.go | 12 - .../github.com/adjust/rmq/v5/state_string.go | 16 - vendor/github.com/adjust/rmq/v5/stats.go | 273 - .../adjust/rmq/v5/test_batch_consumer.go | 57 - .../adjust/rmq/v5/test_connection.go | 64 - .../github.com/adjust/rmq/v5/test_consumer.go | 75 - .../github.com/adjust/rmq/v5/test_delivery.go | 58 - vendor/github.com/adjust/rmq/v5/test_queue.go | 60 - .../adjust/rmq/v5/test_redis_client.go | 435 - vendor/github.com/adjust/rmq/v5/test_util.go | 89 - .../go-check-sumtype/.goreleaser.yml | 32 - .../alecthomas/go-check-sumtype/COPYING | 3 - .../alecthomas/go-check-sumtype/LICENSE-MIT | 21 - .../alecthomas/go-check-sumtype/README.md | 120 - .../alecthomas/go-check-sumtype/UNLICENSE | 24 - .../alecthomas/go-check-sumtype/check.go | 184 - .../alecthomas/go-check-sumtype/decl.go | 69 - .../alecthomas/go-check-sumtype/def.go | 173 - .../alecthomas/go-check-sumtype/doc.go | 53 - .../alecthomas/go-check-sumtype/run.go | 26 - .../alexkohler/nakedret/v2/.gitignore | 8 - .../github.com/alexkohler/nakedret/v2/LICENSE | 21 - .../alexkohler/nakedret/v2/README.md | 125 - .../alexkohler/nakedret/v2/import.go | 310 - .../alexkohler/nakedret/v2/nakedret.go | 309 - vendor/github.com/alexkohler/prealloc/LICENSE | 21 - .../alexkohler/prealloc/pkg/prealloc.go | 267 - .../github.com/alicebob/gopher-json/LICENSE | 24 - .../github.com/alicebob/gopher-json/README.md | 7 - vendor/github.com/alicebob/gopher-json/doc.go | 35 - .../github.com/alicebob/gopher-json/json.go | 189 - .../alicebob/miniredis/v2/.gitignore | 6 - .../alicebob/miniredis/v2/CHANGELOG.md | 270 - .../github.com/alicebob/miniredis/v2/LICENSE | 21 - .../github.com/alicebob/miniredis/v2/Makefile | 12 - .../alicebob/miniredis/v2/README.md | 334 - .../github.com/alicebob/miniredis/v2/check.go | 63 - .../alicebob/miniredis/v2/cmd_cluster.go | 67 - .../alicebob/miniredis/v2/cmd_command.go | 14 - .../alicebob/miniredis/v2/cmd_connection.go | 285 - .../alicebob/miniredis/v2/cmd_generic.go | 729 - .../alicebob/miniredis/v2/cmd_geo.go | 609 - .../alicebob/miniredis/v2/cmd_hash.go | 683 - .../alicebob/miniredis/v2/cmd_hll.go | 95 - .../alicebob/miniredis/v2/cmd_info.go | 40 - .../alicebob/miniredis/v2/cmd_list.go | 1054 - .../alicebob/miniredis/v2/cmd_pubsub.go | 262 - .../alicebob/miniredis/v2/cmd_scripting.go | 343 - .../alicebob/miniredis/v2/cmd_server.go | 112 - .../alicebob/miniredis/v2/cmd_set.go | 715 - .../alicebob/miniredis/v2/cmd_sorted_set.go | 1924 - .../alicebob/miniredis/v2/cmd_stream.go | 1798 - .../alicebob/miniredis/v2/cmd_string.go | 1364 - .../alicebob/miniredis/v2/cmd_transactions.go | 179 - vendor/github.com/alicebob/miniredis/v2/db.go | 718 - .../alicebob/miniredis/v2/direct.go | 821 - .../github.com/alicebob/miniredis/v2/geo.go | 46 - .../alicebob/miniredis/v2/geohash/LICENSE | 22 - .../alicebob/miniredis/v2/geohash/README.md | 2 - .../alicebob/miniredis/v2/geohash/base32.go | 44 - .../alicebob/miniredis/v2/geohash/geohash.go | 269 - .../github.com/alicebob/miniredis/v2/hll.go | 42 - .../alicebob/miniredis/v2/hyperloglog/LICENSE | 21 - .../miniredis/v2/hyperloglog/README.md | 1 - .../miniredis/v2/hyperloglog/compressed.go | 180 - .../miniredis/v2/hyperloglog/hyperloglog.go | 424 - .../miniredis/v2/hyperloglog/registers.go | 114 - .../miniredis/v2/hyperloglog/sparse.go | 92 - .../miniredis/v2/hyperloglog/utils.go | 69 - .../github.com/alicebob/miniredis/v2/keys.go | 83 - .../github.com/alicebob/miniredis/v2/lua.go | 256 - .../alicebob/miniredis/v2/metro/LICENSE | 24 - .../alicebob/miniredis/v2/metro/README.md | 1 - .../alicebob/miniredis/v2/metro/metro64.go | 87 - .../alicebob/miniredis/v2/miniredis.go | 728 - .../github.com/alicebob/miniredis/v2/opts.go | 44 - .../alicebob/miniredis/v2/pubsub.go | 240 - .../github.com/alicebob/miniredis/v2/redis.go | 249 - .../alicebob/miniredis/v2/server/Makefile | 9 - .../alicebob/miniredis/v2/server/proto.go | 157 - .../alicebob/miniredis/v2/server/server.go | 504 - .../alicebob/miniredis/v2/sorted_set.go | 98 - .../alicebob/miniredis/v2/stream.go | 484 - .../github.com/alingse/asasalint/.gitignore | 18 - .../alingse/asasalint/.goreleaser.yml | 72 - vendor/github.com/alingse/asasalint/LICENSE | 21 - vendor/github.com/alingse/asasalint/Makefile | 15 - vendor/github.com/alingse/asasalint/README.md | 76 - .../github.com/alingse/asasalint/asasalint.go | 166 - .../asaskevich/govalidator/.gitignore | 15 - .../asaskevich/govalidator/.travis.yml | 12 - .../asaskevich/govalidator/CODE_OF_CONDUCT.md | 43 - .../asaskevich/govalidator/CONTRIBUTING.md | 63 - .../github.com/asaskevich/govalidator/LICENSE | 21 - .../asaskevich/govalidator/README.md | 622 - .../asaskevich/govalidator/arrays.go | 87 - .../asaskevich/govalidator/converter.go | 81 - .../github.com/asaskevich/govalidator/doc.go | 3 - .../asaskevich/govalidator/error.go | 47 - .../asaskevich/govalidator/numerics.go | 100 - .../asaskevich/govalidator/patterns.go | 113 - .../asaskevich/govalidator/types.go | 656 - .../asaskevich/govalidator/utils.go | 270 - .../asaskevich/govalidator/validator.go | 1768 - .../asaskevich/govalidator/wercker.yml | 15 - .../github.com/ashanbrown/forbidigo/LICENSE | 13 - .../forbidigo/forbidigo/config_options.go | 129 - .../forbidigo/forbidigo/forbidigo.go | 398 - .../forbidigo/forbidigo/patterns.go | 127 - vendor/github.com/ashanbrown/makezero/LICENSE | 13 - .../ashanbrown/makezero/makezero/makezero.go | 230 - vendor/github.com/beorn7/perks/LICENSE | 20 - .../beorn7/perks/quantile/exampledata.txt | 2388 -- .../beorn7/perks/quantile/stream.go | 316 - vendor/github.com/bkielbasa/cyclop/LICENSE | 21 - .../bkielbasa/cyclop/pkg/analyzer/analyzer.go | 107 - .../blizzy78/varnamelen/.editorconfig | 13 - .../github.com/blizzy78/varnamelen/.gitignore | 1 - .../blizzy78/varnamelen/.golangci.yml | 70 - vendor/github.com/blizzy78/varnamelen/LICENSE | 18 - .../github.com/blizzy78/varnamelen/README.md | 155 - vendor/github.com/blizzy78/varnamelen/doc.go | 3 - .../github.com/blizzy78/varnamelen/flags.go | 109 - .../blizzy78/varnamelen/typeparam.go | 35 - .../blizzy78/varnamelen/typeparam_go1.16.go | 11 - .../varnamelen/varnamelen.code-workspace | 13 - .../blizzy78/varnamelen/varnamelen.go | 891 - vendor/github.com/bombsimon/wsl/v4/.gitignore | 72 - .../github.com/bombsimon/wsl/v4/.golangci.yml | 80 - vendor/github.com/bombsimon/wsl/v4/LICENSE | 21 - vendor/github.com/bombsimon/wsl/v4/README.md | 98 - .../github.com/bombsimon/wsl/v4/analyzer.go | 148 - vendor/github.com/bombsimon/wsl/v4/wsl.go | 1416 - vendor/github.com/breml/bidichk/LICENSE | 21 - .../breml/bidichk/pkg/bidichk/bidichk.go | 180 - .../breml/bidichk/pkg/bidichk/version.go | 19 - vendor/github.com/breml/errchkjson/.gitignore | 29 - .../breml/errchkjson/.goreleaser.yml | 34 - vendor/github.com/breml/errchkjson/LICENSE | 21 - vendor/github.com/breml/errchkjson/README.md | 131 - .../github.com/breml/errchkjson/errchkjson.go | 348 - .../breml/errchkjson/noexported_error.go | 23 - .../breml/errchkjson/unsupported_error.go | 23 - vendor/github.com/breml/errchkjson/version.go | 19 - vendor/github.com/bsm/redislock/.golangci.yml | 4 - vendor/github.com/bsm/redislock/CHANGELOG.md | 51 - vendor/github.com/bsm/redislock/LICENSE | 13 - vendor/github.com/bsm/redislock/Makefile | 15 - vendor/github.com/bsm/redislock/README.md | 74 - vendor/github.com/bsm/redislock/README.md.tpl | 28 - vendor/github.com/bsm/redislock/redislock.go | 304 - vendor/github.com/butuzov/ireturn/LICENSE | 21 - .../butuzov/ireturn/analyzer/analyzer.go | 277 - .../butuzov/ireturn/analyzer/disallow.go | 45 - .../ireturn/analyzer/internal/config/allow.go | 17 - .../analyzer/internal/config/config.go | 66 - .../ireturn/analyzer/internal/config/new.go | 74 - .../analyzer/internal/config/reject.go | 17 - .../ireturn/analyzer/internal/types/iface.go | 54 - .../ireturn/analyzer/internal/types/names.go | 9 - .../ireturn/analyzer/internal/types/types.go | 12 - .../butuzov/ireturn/analyzer/std.go | 203 - .../github.com/butuzov/mirror/.editorconfig | 28 - vendor/github.com/butuzov/mirror/.gitignore | 11 - .../butuzov/mirror/.goreleaser.yaml | 46 - vendor/github.com/butuzov/mirror/LICENSE | 21 - .../github.com/butuzov/mirror/MIRROR_FUNCS.md | 201 - vendor/github.com/butuzov/mirror/Makefile | 131 - vendor/github.com/butuzov/mirror/Taskfile.yml | 73 - vendor/github.com/butuzov/mirror/analyzer.go | 144 - .../butuzov/mirror/checkers_bufio.go | 52 - .../butuzov/mirror/checkers_bytes.go | 331 - .../butuzov/mirror/checkers_httptest.go | 36 - .../butuzov/mirror/checkers_maphash.go | 36 - .../github.com/butuzov/mirror/checkers_os.go | 36 - .../butuzov/mirror/checkers_regexp.go | 187 - .../butuzov/mirror/checkers_strings.go | 304 - .../butuzov/mirror/checkers_utf8.go | 138 - .../mirror/internal/checker/checker.go | 147 - .../mirror/internal/checker/imports.go | 89 - .../mirror/internal/checker/violation.go | 209 - vendor/github.com/butuzov/mirror/readme.md | 114 - vendor/github.com/caarlos0/env/v10/.gitignore | 4 - .../github.com/caarlos0/env/v10/.golangci.yml | 8 - .../caarlos0/env/v10/.goreleaser.yml | 3 - vendor/github.com/caarlos0/env/v10/.mailmap | 7 - vendor/github.com/caarlos0/env/v10/LICENSE.md | 21 - vendor/github.com/caarlos0/env/v10/Makefile | 37 - vendor/github.com/caarlos0/env/v10/README.md | 610 - vendor/github.com/caarlos0/env/v10/env.go | 614 - .../github.com/caarlos0/env/v10/env_tomap.go | 16 - .../caarlos0/env/v10/env_tomap_windows.go | 29 - vendor/github.com/caarlos0/env/v10/error.go | 164 - .../github.com/catenacyber/perfsprint/LICENSE | 21 - .../perfsprint/analyzer/analyzer.go | 603 - .../github.com/ccojocar/zxcvbn-go/.gitignore | 5 - .../ccojocar/zxcvbn-go/.golangci.yml | 39 - .../ccojocar/zxcvbn-go/.goreleaser.yml | 27 - .../github.com/ccojocar/zxcvbn-go/LICENSE.txt | 20 - vendor/github.com/ccojocar/zxcvbn-go/Makefile | 61 - .../github.com/ccojocar/zxcvbn-go/README.md | 78 - .../zxcvbn-go/adjacency/adjcmartix.go | 105 - .../ccojocar/zxcvbn-go/data/bindata.go | 446 - .../zxcvbn-go/entropy/entropyCalculator.go | 217 - .../ccojocar/zxcvbn-go/frequency/frequency.go | 50 - .../ccojocar/zxcvbn-go/match/match.go | 45 - .../zxcvbn-go/matching/dateMatchers.go | 206 - .../zxcvbn-go/matching/dictionaryMatch.go | 56 - .../ccojocar/zxcvbn-go/matching/leet.go | 234 - .../ccojocar/zxcvbn-go/matching/matching.go | 79 - .../zxcvbn-go/matching/repeatMatch.go | 68 - .../zxcvbn-go/matching/sequenceMatch.go | 74 - .../zxcvbn-go/matching/spatialMatch.go | 87 - .../ccojocar/zxcvbn-go/renovate.json | 25 - .../ccojocar/zxcvbn-go/scoring/scoring.go | 180 - .../zxcvbn-go/utils/math/mathutils.go | 40 - .../github.com/ccojocar/zxcvbn-go/zxcvbn.go | 22 - vendor/github.com/certifi/gocertifi/LICENSE | 373 - vendor/github.com/certifi/gocertifi/README.md | 69 - .../github.com/certifi/gocertifi/certifi.go | 3219 -- .../github.com/cespare/xxhash/v2/LICENSE.txt | 22 - vendor/github.com/cespare/xxhash/v2/README.md | 74 - .../github.com/cespare/xxhash/v2/testall.sh | 10 - vendor/github.com/cespare/xxhash/v2/xxhash.go | 243 - .../cespare/xxhash/v2/xxhash_amd64.s | 209 - .../cespare/xxhash/v2/xxhash_arm64.s | 183 - .../cespare/xxhash/v2/xxhash_asm.go | 15 - .../cespare/xxhash/v2/xxhash_other.go | 76 - .../cespare/xxhash/v2/xxhash_safe.go | 16 - .../cespare/xxhash/v2/xxhash_unsafe.go | 58 - .../charithe/durationcheck/.gitignore | 1 - .../github.com/charithe/durationcheck/LICENSE | 201 - .../charithe/durationcheck/Makefile | 5 - .../charithe/durationcheck/README.md | 51 - .../charithe/durationcheck/durationcheck.go | 191 - vendor/github.com/chavacava/garif/.gitignore | 3 - vendor/github.com/chavacava/garif/LICENSE | 21 - vendor/github.com/chavacava/garif/README.md | 52 - .../chavacava/garif/constructors.go | 338 - .../github.com/chavacava/garif/decorators.go | 94 - vendor/github.com/chavacava/garif/doc.go | 11 - vendor/github.com/chavacava/garif/enums.go | 41 - vendor/github.com/chavacava/garif/io.go | 26 - vendor/github.com/chavacava/garif/models.go | 1486 - .../github.com/ckaznocha/intrange/.gitignore | 191 - .../ckaznocha/intrange/.golangci.yml | 99 - .../ckaznocha/intrange/CONTRIBUTING.md | 25 - vendor/github.com/ckaznocha/intrange/LICENSE | 21 - .../github.com/ckaznocha/intrange/README.md | 90 - .../github.com/ckaznocha/intrange/SECURITY.md | 5 - vendor/github.com/ckaznocha/intrange/go.work | 6 - .../github.com/ckaznocha/intrange/intrange.go | 471 - .../curioswitch/go-reassign/.gitattributes | 2 - .../curioswitch/go-reassign/.gitignore | 6 - .../curioswitch/go-reassign/.golangci.yml | 38 - .../curioswitch/go-reassign/.goreleaser.yaml | 27 - .../curioswitch/go-reassign/LICENSE | 21 - .../curioswitch/go-reassign/README.md | 53 - .../curioswitch/go-reassign/analyzer.go | 13 - .../go-reassign/internal/analyzer/analyzer.go | 84 - vendor/github.com/daixiang0/gci/LICENSE | 29 - .../daixiang0/gci/pkg/config/config.go | 115 - .../daixiang0/gci/pkg/format/format.go | 46 - .../github.com/daixiang0/gci/pkg/gci/gci.go | 229 - .../daixiang0/gci/pkg/gci/testdata.go | 1298 - .../github.com/daixiang0/gci/pkg/io/file.go | 64 - .../github.com/daixiang0/gci/pkg/io/search.go | 77 - .../github.com/daixiang0/gci/pkg/io/stdin.go | 27 - .../github.com/daixiang0/gci/pkg/log/log.go | 50 - .../daixiang0/gci/pkg/parse/parse.go | 200 - .../daixiang0/gci/pkg/section/alias.go | 25 - .../daixiang0/gci/pkg/section/blank.go | 25 - .../daixiang0/gci/pkg/section/commentline.go | 24 - .../daixiang0/gci/pkg/section/default.go | 22 - .../daixiang0/gci/pkg/section/dot.go | 25 - .../daixiang0/gci/pkg/section/errors.go | 107 - .../daixiang0/gci/pkg/section/local_module.go | 59 - .../daixiang0/gci/pkg/section/newline.go | 22 - .../daixiang0/gci/pkg/section/parser.go | 49 - .../daixiang0/gci/pkg/section/prefix.go | 38 - .../daixiang0/gci/pkg/section/section.go | 36 - .../daixiang0/gci/pkg/section/standard.go | 30 - .../gci/pkg/section/standard_list.go | 175 - .../daixiang0/gci/pkg/specificity/default.go | 19 - .../gci/pkg/specificity/local_module.go | 15 - .../daixiang0/gci/pkg/specificity/match.go | 24 - .../daixiang0/gci/pkg/specificity/mismatch.go | 19 - .../daixiang0/gci/pkg/specificity/name.go | 19 - .../gci/pkg/specificity/specificity.go | 28 - .../daixiang0/gci/pkg/specificity/standard.go | 19 - .../daixiang0/gci/pkg/utils/constants.go | 12 - vendor/github.com/dave/jennifer/LICENSE | 21 - vendor/github.com/dave/jennifer/jen/add.go | 19 - .../github.com/dave/jennifer/jen/comments.go | 108 - vendor/github.com/dave/jennifer/jen/custom.go | 61 - vendor/github.com/dave/jennifer/jen/dict.go | 81 - vendor/github.com/dave/jennifer/jen/do.go | 22 - vendor/github.com/dave/jennifer/jen/file.go | 256 - .../github.com/dave/jennifer/jen/generated.go | 2274 -- vendor/github.com/dave/jennifer/jen/group.go | 147 - vendor/github.com/dave/jennifer/jen/hints.go | 273 - vendor/github.com/dave/jennifer/jen/jen.go | 168 - vendor/github.com/dave/jennifer/jen/lit.go | 154 - .../github.com/dave/jennifer/jen/reserved.go | 20 - .../github.com/dave/jennifer/jen/statement.go | 101 - vendor/github.com/dave/jennifer/jen/tag.go | 76 - vendor/github.com/dave/jennifer/jen/tokens.go | 301 - vendor/github.com/davecgh/go-spew/LICENSE | 15 - .../github.com/davecgh/go-spew/spew/bypass.go | 145 - .../davecgh/go-spew/spew/bypasssafe.go | 38 - .../github.com/davecgh/go-spew/spew/common.go | 341 - .../github.com/davecgh/go-spew/spew/config.go | 306 - vendor/github.com/davecgh/go-spew/spew/doc.go | 211 - .../github.com/davecgh/go-spew/spew/dump.go | 509 - .../github.com/davecgh/go-spew/spew/format.go | 419 - .../github.com/davecgh/go-spew/spew/spew.go | 148 - .../denis-tingaikin/go-header/.gitignore | 1 - .../denis-tingaikin/go-header/.go-header.yml | 19 - .../denis-tingaikin/go-header/LICENSE | 674 - .../denis-tingaikin/go-header/README.md | 83 - .../denis-tingaikin/go-header/analyzer.go | 256 - .../denis-tingaikin/go-header/config.go | 99 - .../denis-tingaikin/go-header/issue.go | 67 - .../denis-tingaikin/go-header/location.go | 35 - .../denis-tingaikin/go-header/option.go | 44 - .../denis-tingaikin/go-header/reader.go | 116 - .../denis-tingaikin/go-header/value.go | 150 - .../github.com/dgryski/go-rendezvous/LICENSE | 21 - .../github.com/dgryski/go-rendezvous/rdv.go | 79 - vendor/github.com/ettle/strcase/.gitignore | 18 - vendor/github.com/ettle/strcase/.golangci.yml | 82 - vendor/github.com/ettle/strcase/.readme.tmpl | 80 - vendor/github.com/ettle/strcase/LICENSE | 21 - vendor/github.com/ettle/strcase/Makefile | 19 - vendor/github.com/ettle/strcase/README.md | 553 - vendor/github.com/ettle/strcase/assert.go | 24 - vendor/github.com/ettle/strcase/caser.go | 87 - vendor/github.com/ettle/strcase/convert.go | 306 - vendor/github.com/ettle/strcase/doc.go | 150 - vendor/github.com/ettle/strcase/initialism.go | 43 - vendor/github.com/ettle/strcase/split.go | 165 - vendor/github.com/ettle/strcase/strcase.go | 81 - vendor/github.com/ettle/strcase/unicode.go | 48 - vendor/github.com/fatih/color/LICENSE.md | 20 - vendor/github.com/fatih/color/README.md | 176 - vendor/github.com/fatih/color/color.go | 655 - .../github.com/fatih/color/color_windows.go | 19 - vendor/github.com/fatih/color/doc.go | 134 - vendor/github.com/fatih/structtag/LICENSE | 60 - vendor/github.com/fatih/structtag/README.md | 73 - vendor/github.com/fatih/structtag/tags.go | 315 - .../firefart/nonamedreturns/LICENSE | 674 - .../nonamedreturns/analyzer/analyzer.go | 139 - .../fsnotify/fsnotify/.editorconfig | 12 - .../fsnotify/fsnotify/.gitattributes | 1 - .../github.com/fsnotify/fsnotify/.gitignore | 6 - vendor/github.com/fsnotify/fsnotify/.mailmap | 2 - vendor/github.com/fsnotify/fsnotify/AUTHORS | 62 - .../github.com/fsnotify/fsnotify/CHANGELOG.md | 357 - .../fsnotify/fsnotify/CONTRIBUTING.md | 60 - vendor/github.com/fsnotify/fsnotify/LICENSE | 28 - vendor/github.com/fsnotify/fsnotify/README.md | 120 - vendor/github.com/fsnotify/fsnotify/fen.go | 38 - .../github.com/fsnotify/fsnotify/fsnotify.go | 69 - .../fsnotify/fsnotify/fsnotify_unsupported.go | 36 - .../github.com/fsnotify/fsnotify/inotify.go | 351 - .../fsnotify/fsnotify/inotify_poller.go | 187 - vendor/github.com/fsnotify/fsnotify/kqueue.go | 535 - .../fsnotify/fsnotify/open_mode_bsd.go | 12 - .../fsnotify/fsnotify/open_mode_darwin.go | 13 - .../github.com/fsnotify/fsnotify/windows.go | 586 - vendor/github.com/fzipp/gocyclo/CHANGELOG.md | 58 - vendor/github.com/fzipp/gocyclo/CONTRIBUTORS | 7 - vendor/github.com/fzipp/gocyclo/LICENSE | 27 - vendor/github.com/fzipp/gocyclo/README.md | 106 - vendor/github.com/fzipp/gocyclo/analyze.go | 154 - vendor/github.com/fzipp/gocyclo/complexity.go | 48 - vendor/github.com/fzipp/gocyclo/directives.go | 39 - vendor/github.com/fzipp/gocyclo/recv.go | 26 - .../github.com/fzipp/gocyclo/recv_pre118.go | 24 - vendor/github.com/fzipp/gocyclo/stats.go | 73 - vendor/github.com/getkin/kin-openapi/LICENSE | 21 - .../getkin/kin-openapi/jsoninfo/doc.go | 2 - .../getkin/kin-openapi/jsoninfo/field_info.go | 122 - .../getkin/kin-openapi/jsoninfo/marshal.go | 162 - .../kin-openapi/jsoninfo/marshal_ref.go | 30 - .../kin-openapi/jsoninfo/strict_struct.go | 6 - .../getkin/kin-openapi/jsoninfo/type_info.go | 68 - .../getkin/kin-openapi/jsoninfo/unmarshal.go | 121 - .../jsoninfo/unsupported_properties_error.go | 45 - .../getkin/kin-openapi/openapi3/callback.go | 15 - .../getkin/kin-openapi/openapi3/components.go | 105 - .../getkin/kin-openapi/openapi3/content.go | 45 - .../getkin/kin-openapi/openapi3/doc.go | 5 - .../getkin/kin-openapi/openapi3/encoding.go | 61 - .../getkin/kin-openapi/openapi3/examples.go | 29 - .../getkin/kin-openapi/openapi3/extension.go | 37 - .../kin-openapi/openapi3/external_docs.go | 7 - .../getkin/kin-openapi/openapi3/header.go | 24 - .../getkin/kin-openapi/openapi3/info.go | 55 - .../getkin/kin-openapi/openapi3/link.go | 29 - .../getkin/kin-openapi/openapi3/media_type.go | 79 - .../getkin/kin-openapi/openapi3/operation.go | 98 - .../getkin/kin-openapi/openapi3/parameter.go | 158 - .../getkin/kin-openapi/openapi3/path_item.go | 124 - .../getkin/kin-openapi/openapi3/paths.go | 99 - .../getkin/kin-openapi/openapi3/refs.go | 199 - .../kin-openapi/openapi3/request_body.go | 69 - .../getkin/kin-openapi/openapi3/response.go | 82 - .../getkin/kin-openapi/openapi3/schema.go | 1200 - .../kin-openapi/openapi3/schema_formats.go | 33 - .../openapi3/security_requirements.go | 40 - .../kin-openapi/openapi3/security_scheme.go | 220 - .../getkin/kin-openapi/openapi3/server.go | 132 - .../getkin/kin-openapi/openapi3/swagger.go | 71 - .../kin-openapi/openapi3/swagger_loader.go | 480 - .../getkin/kin-openapi/openapi3/tag.go | 20 - .../getsentry/sentry-go/.codecov.yml | 13 - .../github.com/getsentry/sentry-go/.craft.yml | 13 - .../getsentry/sentry-go/.gitattributes | 5 - .../github.com/getsentry/sentry-go/.gitignore | 14 - .../getsentry/sentry-go/.golangci.yml | 46 - .../getsentry/sentry-go/CHANGELOG.md | 864 - .../getsentry/sentry-go/CONTRIBUTING.md | 98 - vendor/github.com/getsentry/sentry-go/LICENSE | 21 - .../getsentry/sentry-go/MIGRATION.md | 3 - .../github.com/getsentry/sentry-go/Makefile | 83 - .../github.com/getsentry/sentry-go/README.md | 102 - .../getsentry/sentry-go/check_in.go | 121 - .../github.com/getsentry/sentry-go/client.go | 740 - vendor/github.com/getsentry/sentry-go/doc.go | 6 - vendor/github.com/getsentry/sentry-go/dsn.go | 233 - .../sentry-go/dynamic_sampling_context.go | 152 - vendor/github.com/getsentry/sentry-go/hub.go | 424 - .../getsentry/sentry-go/integrations.go | 391 - .../getsentry/sentry-go/interfaces.go | 559 - .../sentry-go/internal/debug/transport.go | 79 - .../sentry-go/internal/otel/baggage/README.md | 12 - .../internal/otel/baggage/baggage.go | 604 - .../otel/baggage/internal/baggage/baggage.go | 45 - .../sentry-go/internal/ratelimit/category.go | 45 - .../sentry-go/internal/ratelimit/deadline.go | 22 - .../sentry-go/internal/ratelimit/doc.go | 3 - .../sentry-go/internal/ratelimit/map.go | 64 - .../internal/ratelimit/rate_limits.go | 76 - .../internal/ratelimit/retry_after.go | 40 - .../sentry-go/internal/traceparser/README.md | 15 - .../sentry-go/internal/traceparser/parser.go | 217 - .../github.com/getsentry/sentry-go/metrics.go | 427 - .../getsentry/sentry-go/profile_sample.go | 73 - .../getsentry/sentry-go/profiler.go | 451 - .../getsentry/sentry-go/profiler_other.go | 5 - .../getsentry/sentry-go/profiler_windows.go | 24 - .../sentry-go/propagation_context.go | 90 - .../github.com/getsentry/sentry-go/scope.go | 475 - .../github.com/getsentry/sentry-go/sentry.go | 132 - .../getsentry/sentry-go/sourcereader.go | 70 - .../getsentry/sentry-go/span_recorder.go | 56 - .../getsentry/sentry-go/stacktrace.go | 384 - .../sentry-go/stacktrace_below_go1.20.go | 15 - .../sentry-go/stacktrace_below_go1.21.go | 7 - .../getsentry/sentry-go/stacktrace_go1.20.go | 15 - .../getsentry/sentry-go/stacktrace_go1.21.go | 25 - .../getsentry/sentry-go/traces_profiler.go | 95 - .../getsentry/sentry-go/traces_sampler.go | 19 - .../github.com/getsentry/sentry-go/tracing.go | 1028 - .../getsentry/sentry-go/transport.go | 745 - vendor/github.com/getsentry/sentry-go/util.go | 118 - vendor/github.com/ghodss/yaml/.gitignore | 20 - vendor/github.com/ghodss/yaml/.travis.yml | 7 - vendor/github.com/ghodss/yaml/LICENSE | 50 - vendor/github.com/ghodss/yaml/README.md | 121 - vendor/github.com/ghodss/yaml/fields.go | 501 - vendor/github.com/ghodss/yaml/yaml.go | 277 - .../ghostiam/protogetter/.goreleaser.yaml | 24 - .../github.com/ghostiam/protogetter/LICENSE | 21 - .../github.com/ghostiam/protogetter/Makefile | 9 - .../github.com/ghostiam/protogetter/README.md | 73 - .../ghostiam/protogetter/posfilter.go | 65 - .../ghostiam/protogetter/processor.go | 351 - .../ghostiam/protogetter/protogetter.go | 279 - vendor/github.com/go-critic/go-critic/LICENSE | 21 - .../checkers/appendAssign_checker.go | 103 - .../checkers/appendCombine_checker.go | 103 - .../go-critic/checkers/badCond_checker.go | 161 - .../go-critic/checkers/badRegexp_checker.go | 446 - .../checkers/boolExprSimplify_checker.go | 346 - .../checkers/builtinShadowDecl_checker.go | 63 - .../checkers/builtinShadow_checker.go | 36 - .../go-critic/checkers/captLocal_checker.go | 49 - .../go-critic/checkers/caseOrder_checker.go | 88 - .../go-critic/go-critic/checkers/checkers.go | 19 - .../checkers/codegenComment_checker.go | 61 - .../checkers/commentFormatting_checker.go | 123 - .../checkers/commentedOutCode_checker.go | 167 - .../checkers/commentedOutImport_checker.go | 76 - .../checkers/defaultCaseOrder_checker.go | 65 - .../go-critic/checkers/deferInLoop_checker.go | 70 - .../checkers/deprecatedComment_checker.go | 156 - .../go-critic/checkers/docStub_checker.go | 95 - .../checkers/dupBranchBody_checker.go | 59 - .../go-critic/checkers/dupCase_checker.go | 70 - .../go-critic/checkers/dupImports_checker.go | 63 - .../go-critic/checkers/dupSubExpr_checker.go | 103 - .../go-critic/checkers/elseif_checker.go | 72 - .../go-critic/checkers/embedded_rules.go | 108 - .../checkers/emptyFallthrough_checker.go | 70 - .../go-critic/checkers/evalOrder_checker.go | 88 - .../checkers/exitAfterDefer_checker.go | 85 - .../checkers/filepathJoin_checker.go | 51 - .../go-critic/checkers/flagName_checker.go | 89 - .../go-critic/checkers/hexLiteral_checker.go | 61 - .../go-critic/checkers/hugeParam_checker.go | 83 - .../go-critic/checkers/ifElseChain_checker.go | 110 - .../checkers/importShadow_checker.go | 47 - .../go-critic/checkers/initClause_checker.go | 57 - .../internal/astwalk/comment_walker.go | 41 - .../internal/astwalk/doc_comment_walker.go | 48 - .../checkers/internal/astwalk/expr_walker.go | 31 - .../internal/astwalk/func_decl_walker.go | 23 - .../internal/astwalk/local_comment_walker.go | 32 - .../internal/astwalk/local_def_visitor.go | 49 - .../internal/astwalk/local_def_walker.go | 118 - .../internal/astwalk/local_expr_walker.go | 29 - .../internal/astwalk/stmt_list_walker.go | 33 - .../checkers/internal/astwalk/stmt_walker.go | 29 - .../internal/astwalk/type_expr_walker.go | 119 - .../checkers/internal/astwalk/visitor.go | 77 - .../checkers/internal/astwalk/walk_handler.go | 34 - .../checkers/internal/astwalk/walker.go | 57 - .../checkers/internal/lintutil/astfind.go | 41 - .../checkers/internal/lintutil/astflow.go | 86 - .../checkers/internal/lintutil/astset.go | 44 - .../checkers/internal/lintutil/zero_value.go | 94 - .../go-critic/checkers/mapKey_checker.go | 125 - .../checkers/methodExprCall_checker.go | 58 - .../checkers/nestingReduce_checker.go | 73 - .../go-critic/checkers/newDeref_checker.go | 51 - .../checkers/nilValReturn_checker.go | 72 - .../checkers/octalLiteral_checker.go | 51 - .../checkers/paramTypeCombine_checker.go | 97 - .../checkers/ptrToRefParam_checker.go | 70 - .../checkers/rangeExprCopy_checker.go | 80 - .../checkers/rangeValCopy_checker.go | 76 - .../checkers/regexpPattern_checker.go | 68 - .../checkers/regexpSimplify_checker.go | 512 - .../go-critic/checkers/ruleguard_checker.go | 322 - .../go-critic/checkers/rulesdata/rulesdata.go | 2521 -- .../checkers/singleCaseSwitch_checker.go | 85 - .../checkers/sloppyReassign_checker.go | 81 - .../checkers/sloppyTypeAssert_checker.go | 56 - .../go-critic/checkers/sortSlice_checker.go | 136 - .../go-critic/checkers/sqlQuery_checker.go | 168 - .../todoCommentWithoutDetail_checker.go | 50 - .../checkers/tooManyResults_checker.go | 54 - .../go-critic/checkers/truncateCmp_checker.go | 124 - .../checkers/typeAssertChain_checker.go | 133 - .../checkers/typeDefFirst_checker.go | 92 - .../checkers/typeSwitchVar_checker.go | 98 - .../go-critic/checkers/typeUnparen_checker.go | 96 - .../go-critic/checkers/underef_checker.go | 128 - .../go-critic/checkers/unlabelStmt_checker.go | 181 - .../go-critic/checkers/unlambda_checker.go | 118 - .../checkers/unnamedResult_checker.go | 103 - .../checkers/unnecessaryBlock_checker.go | 78 - .../checkers/unnecessaryDefer_checker.go | 112 - .../go-critic/go-critic/checkers/utils.go | 311 - .../go-critic/checkers/weakCond_checker.go | 78 - .../go-critic/checkers/whyNoLint_checker.go | 50 - .../go-critic/go-critic/linter/go_version.go | 52 - .../go-critic/go-critic/linter/helpers.go | 136 - .../go-critic/go-critic/linter/linter.go | 401 - .../github.com/go-kivik/couchdb/v3/.gitignore | 3 - .../go-kivik/couchdb/v3/.gitlab-ci.yml | 87 - .../go-kivik/couchdb/v3/.golangci.toml | 9 - .../github.com/go-kivik/couchdb/v3/LICENSE.md | 13 - .../github.com/go-kivik/couchdb/v3/README.md | 35 - .../go-kivik/couchdb/v3/attachments.go | 171 - vendor/github.com/go-kivik/couchdb/v3/auth.go | 140 - vendor/github.com/go-kivik/couchdb/v3/bulk.go | 106 - .../github.com/go-kivik/couchdb/v3/bulkget.go | 61 - .../github.com/go-kivik/couchdb/v3/changes.go | 120 - .../go-kivik/couchdb/v3/chttp/auth.go | 22 - .../go-kivik/couchdb/v3/chttp/basicauth.go | 34 - .../go-kivik/couchdb/v3/chttp/chttp.go | 535 - .../go-kivik/couchdb/v3/chttp/constants.go | 7 - .../go-kivik/couchdb/v3/chttp/cookieauth.go | 112 - .../go-kivik/couchdb/v3/chttp/encode.go | 25 - .../go-kivik/couchdb/v3/chttp/errors.go | 108 - .../go-kivik/couchdb/v3/chttp/exitstatus.go | 63 - .../go-kivik/couchdb/v3/chttp/proxyauth.go | 63 - .../go-kivik/couchdb/v3/chttp/trace.go | 136 - .../go-kivik/couchdb/v3/chttp/xerrors_13.go | 7 - .../couchdb/v3/chttp/xerrors_pre13.go | 11 - .../github.com/go-kivik/couchdb/v3/client.go | 104 - .../github.com/go-kivik/couchdb/v3/cluster.go | 35 - .../go-kivik/couchdb/v3/codecov.yml | 2 - .../github.com/go-kivik/couchdb/v3/config.go | 67 - .../go-kivik/couchdb/v3/constants.go | 44 - .../github.com/go-kivik/couchdb/v3/couchdb.go | 85 - vendor/github.com/go-kivik/couchdb/v3/db.go | 914 - .../github.com/go-kivik/couchdb/v3/dbstats.go | 129 - vendor/github.com/go-kivik/couchdb/v3/doc.go | 106 - .../github.com/go-kivik/couchdb/v3/errors.go | 12 - vendor/github.com/go-kivik/couchdb/v3/find.go | 149 - vendor/github.com/go-kivik/couchdb/v3/iter.go | 300 - vendor/github.com/go-kivik/couchdb/v3/json.go | 35 - .../github.com/go-kivik/couchdb/v3/options.go | 37 - .../go-kivik/couchdb/v3/replication.go | 319 - vendor/github.com/go-kivik/couchdb/v3/rows.go | 281 - .../go-kivik/couchdb/v3/scheduler.go | 235 - .../github.com/go-kivik/couchdb/v3/seqid.go | 15 - .../github.com/go-kivik/couchdb/v3/session.go | 50 - vendor/github.com/go-kivik/couchdb/v3/util.go | 29 - .../github.com/go-kivik/couchdb/v3/version.go | 43 - .../github.com/go-kivik/kivik/v3/.codecov.yml | 2 - .../github.com/go-kivik/kivik/v3/.gitignore | 6 - .../go-kivik/kivik/v3/.gitlab-ci.yml | 83 - .../go-kivik/kivik/v3/.golangci.toml | 12 - .../go-kivik/kivik/v3/CONTRIBUTING.md | 18 - .../go-kivik/kivik/v3/ISSUE_TEMPLATE.md | 11 - .../github.com/go-kivik/kivik/v3/LICENSE.md | 13 - vendor/github.com/go-kivik/kivik/v3/README.md | 174 - .../go-kivik/kivik/v3/attachments.go | 175 - vendor/github.com/go-kivik/kivik/v3/bulk.go | 155 - .../github.com/go-kivik/kivik/v3/changes.go | 124 - .../github.com/go-kivik/kivik/v3/cluster.go | 53 - .../github.com/go-kivik/kivik/v3/codecov.yml | 3 - vendor/github.com/go-kivik/kivik/v3/config.go | 81 - .../github.com/go-kivik/kivik/v3/constants.go | 27 - vendor/github.com/go-kivik/kivik/v3/db.go | 733 - vendor/github.com/go-kivik/kivik/v3/doc.go | 80 - .../go-kivik/kivik/v3/driver/bulkget.go | 17 - .../go-kivik/kivik/v3/driver/changes.go | 56 - .../go-kivik/kivik/v3/driver/config.go | 19 - .../go-kivik/kivik/v3/driver/doc.go | 5 - .../go-kivik/kivik/v3/driver/driver.go | 438 - .../go-kivik/kivik/v3/driver/errors.go | 11 - .../go-kivik/kivik/v3/driver/partition.go | 24 - .../go-kivik/kivik/v3/driver/rows.go | 65 - .../go-kivik/kivik/v3/driver/session.go | 33 - .../go-kivik/kivik/v3/driver/updates.go | 29 - vendor/github.com/go-kivik/kivik/v3/errors.go | 154 - vendor/github.com/go-kivik/kivik/v3/find.go | 128 - .../kivik/v3/internal/registry/registry.go | 36 - .../github.com/go-kivik/kivik/v3/iterator.go | 171 - vendor/github.com/go-kivik/kivik/v3/kivik.go | 206 - .../github.com/go-kivik/kivik/v3/package.json | 18 - .../go-kivik/kivik/v3/replication.go | 199 - vendor/github.com/go-kivik/kivik/v3/rows.go | 188 - .../github.com/go-kivik/kivik/v3/security.go | 13 - .../github.com/go-kivik/kivik/v3/session.go | 42 - .../github.com/go-kivik/kivik/v3/updates.go | 90 - vendor/github.com/go-pg/pg/.travis.yml | 23 - vendor/github.com/go-pg/pg/CHANGELOG.md | 70 - vendor/github.com/go-pg/pg/LICENSE | 24 - vendor/github.com/go-pg/pg/Makefile | 5 - vendor/github.com/go-pg/pg/README.md | 167 - vendor/github.com/go-pg/pg/db.go | 517 - vendor/github.com/go-pg/pg/doc.go | 4 - vendor/github.com/go-pg/pg/error.go | 61 - vendor/github.com/go-pg/pg/hook.go | 145 - vendor/github.com/go-pg/pg/internal/error.go | 59 - .../github.com/go-pg/pg/internal/internal.go | 24 - vendor/github.com/go-pg/pg/internal/log.go | 15 - .../go-pg/pg/internal/parser/array_parser.go | 92 - .../pg/internal/parser/composite_parser.go | 53 - .../go-pg/pg/internal/parser/hstore_parser.go | 40 - .../go-pg/pg/internal/parser/parser.go | 170 - .../go-pg/pg/internal/parser/util.go | 15 - .../github.com/go-pg/pg/internal/pool/conn.go | 129 - .../go-pg/pg/internal/pool/elastic_reader.go | 185 - .../github.com/go-pg/pg/internal/pool/pool.go | 476 - .../go-pg/pg/internal/pool/pool_single.go | 53 - .../go-pg/pg/internal/pool/reader.go | 71 - .../go-pg/pg/internal/pool/write_buffer.go | 96 - vendor/github.com/go-pg/pg/internal/safe.go | 11 - .../github.com/go-pg/pg/internal/strconv.go | 19 - .../go-pg/pg/internal/underscore.go | 93 - vendor/github.com/go-pg/pg/internal/unsafe.go | 22 - vendor/github.com/go-pg/pg/internal/util.go | 36 - vendor/github.com/go-pg/pg/listener.go | 316 - vendor/github.com/go-pg/pg/messages.go | 1093 - vendor/github.com/go-pg/pg/options.go | 242 - vendor/github.com/go-pg/pg/orm/composite.go | 56 - .../go-pg/pg/orm/composite_create.go | 68 - .../github.com/go-pg/pg/orm/composite_drop.go | 50 - .../github.com/go-pg/pg/orm/count_estimate.go | 85 - vendor/github.com/go-pg/pg/orm/delete.go | 83 - vendor/github.com/go-pg/pg/orm/field.go | 108 - vendor/github.com/go-pg/pg/orm/format.go | 286 - vendor/github.com/go-pg/pg/orm/hook.go | 199 - vendor/github.com/go-pg/pg/orm/inflection.go | 17 - vendor/github.com/go-pg/pg/orm/insert.go | 157 - vendor/github.com/go-pg/pg/orm/join.go | 345 - vendor/github.com/go-pg/pg/orm/model.go | 110 - .../github.com/go-pg/pg/orm/model_discard.go | 23 - vendor/github.com/go-pg/pg/orm/model_func.go | 89 - vendor/github.com/go-pg/pg/orm/model_scan.go | 68 - vendor/github.com/go-pg/pg/orm/model_slice.go | 35 - vendor/github.com/go-pg/pg/orm/model_table.go | 109 - .../go-pg/pg/orm/model_table_m2m.go | 135 - .../go-pg/pg/orm/model_table_many.go | 113 - .../go-pg/pg/orm/model_table_slice.go | 152 - .../go-pg/pg/orm/model_table_struct.go | 363 - vendor/github.com/go-pg/pg/orm/orm.go | 46 - vendor/github.com/go-pg/pg/orm/pager.go | 111 - vendor/github.com/go-pg/pg/orm/query.go | 1302 - vendor/github.com/go-pg/pg/orm/relation.go | 32 - vendor/github.com/go-pg/pg/orm/result.go | 14 - vendor/github.com/go-pg/pg/orm/select.go | 201 - vendor/github.com/go-pg/pg/orm/table.go | 891 - .../github.com/go-pg/pg/orm/table_create.go | 155 - vendor/github.com/go-pg/pg/orm/table_drop.go | 50 - .../github.com/go-pg/pg/orm/table_params.go | 29 - vendor/github.com/go-pg/pg/orm/tables.go | 112 - vendor/github.com/go-pg/pg/orm/tag.go | 145 - vendor/github.com/go-pg/pg/orm/update.go | 257 - vendor/github.com/go-pg/pg/orm/url_filter.go | 114 - vendor/github.com/go-pg/pg/orm/url_values.go | 106 - vendor/github.com/go-pg/pg/orm/util.go | 127 - vendor/github.com/go-pg/pg/orm/zero.go | 119 - vendor/github.com/go-pg/pg/pg.go | 209 - vendor/github.com/go-pg/pg/result.go | 49 - vendor/github.com/go-pg/pg/stmt.go | 278 - vendor/github.com/go-pg/pg/time.go | 58 - vendor/github.com/go-pg/pg/tx.go | 338 - vendor/github.com/go-pg/pg/types/append.go | 202 - .../github.com/go-pg/pg/types/append_array.go | 190 - .../github.com/go-pg/pg/types/append_field.go | 52 - .../go-pg/pg/types/append_hstore.go | 49 - .../github.com/go-pg/pg/types/append_jsonb.go | 41 - .../github.com/go-pg/pg/types/append_value.go | 181 - vendor/github.com/go-pg/pg/types/array.go | 52 - vendor/github.com/go-pg/pg/types/hstore.go | 52 - vendor/github.com/go-pg/pg/types/in_op.go | 49 - vendor/github.com/go-pg/pg/types/interface.go | 27 - vendor/github.com/go-pg/pg/types/scan.go | 83 - .../github.com/go-pg/pg/types/scan_array.go | 197 - .../github.com/go-pg/pg/types/scan_hstore.go | 58 - .../github.com/go-pg/pg/types/scan_value.go | 304 - vendor/github.com/go-pg/pg/types/time.go | 56 - .../github.com/go-toolsmith/astcast/LICENSE | 21 - .../github.com/go-toolsmith/astcast/README.md | 103 - .../go-toolsmith/astcast/astcast.go | 590 - .../github.com/go-toolsmith/astcopy/LICENSE | 21 - .../github.com/go-toolsmith/astcopy/README.md | 57 - .../go-toolsmith/astcopy/astcopy.go | 945 - .../go-toolsmith/astcopy/astcopy_go117.go | 30 - .../go-toolsmith/astcopy/astcopy_go118.go | 36 - .../go-toolsmith/astequal/.gitignore | 5 - .../github.com/go-toolsmith/astequal/LICENSE | 21 - .../go-toolsmith/astequal/README.md | 82 - .../go-toolsmith/astequal/astequal.go | 771 - .../github.com/go-toolsmith/astequal/diff.go | 23 - vendor/github.com/go-toolsmith/astfmt/LICENSE | 21 - .../github.com/go-toolsmith/astfmt/README.md | 55 - .../github.com/go-toolsmith/astfmt/astfmt.go | 111 - vendor/github.com/go-toolsmith/astp/LICENSE | 21 - vendor/github.com/go-toolsmith/astp/README.md | 54 - vendor/github.com/go-toolsmith/astp/decl.go | 39 - vendor/github.com/go-toolsmith/astp/expr.go | 141 - vendor/github.com/go-toolsmith/astp/stmt.go | 135 - .../github.com/go-toolsmith/strparse/LICENSE | 21 - .../go-toolsmith/strparse/README.md | 48 - .../go-toolsmith/strparse/strparse.go | 59 - vendor/github.com/go-toolsmith/typep/LICENSE | 21 - .../github.com/go-toolsmith/typep/README.md | 54 - vendor/github.com/go-toolsmith/typep/doc.go | 2 - .../go-toolsmith/typep/predicates.go | 36 - .../go-toolsmith/typep/safe_expr.go | 73 - .../go-toolsmith/typep/simple_predicates.go | 359 - .../go-viper/mapstructure/v2/.editorconfig | 18 - .../go-viper/mapstructure/v2/.envrc | 4 - .../go-viper/mapstructure/v2/.gitignore | 6 - .../go-viper/mapstructure/v2/.golangci.yaml | 23 - .../go-viper/mapstructure/v2/CHANGELOG.md | 104 - .../go-viper/mapstructure/v2/LICENSE | 21 - .../go-viper/mapstructure/v2/README.md | 80 - .../go-viper/mapstructure/v2/decode_hooks.go | 609 - .../go-viper/mapstructure/v2/flake.lock | 472 - .../go-viper/mapstructure/v2/flake.nix | 39 - .../mapstructure/v2/internal/errors/errors.go | 11 - .../mapstructure/v2/internal/errors/join.go | 9 - .../v2/internal/errors/join_go1_19.go | 61 - .../go-viper/mapstructure/v2/mapstructure.go | 1593 - .../mapstructure/v2/reflect_go1_19.go | 44 - .../mapstructure/v2/reflect_go1_20.go | 10 - vendor/github.com/go-xmlfmt/xmlfmt/LICENSE | 21 - vendor/github.com/go-xmlfmt/xmlfmt/README.md | 245 - vendor/github.com/go-xmlfmt/xmlfmt/xmlfmt.go | 92 - vendor/github.com/gobwas/glob/.gitignore | 8 - vendor/github.com/gobwas/glob/.travis.yml | 9 - vendor/github.com/gobwas/glob/LICENSE | 21 - vendor/github.com/gobwas/glob/bench.sh | 26 - .../gobwas/glob/compiler/compiler.go | 525 - vendor/github.com/gobwas/glob/glob.go | 80 - vendor/github.com/gobwas/glob/match/any.go | 45 - vendor/github.com/gobwas/glob/match/any_of.go | 82 - vendor/github.com/gobwas/glob/match/btree.go | 146 - .../github.com/gobwas/glob/match/contains.go | 58 - .../github.com/gobwas/glob/match/every_of.go | 99 - vendor/github.com/gobwas/glob/match/list.go | 49 - vendor/github.com/gobwas/glob/match/match.go | 81 - vendor/github.com/gobwas/glob/match/max.go | 49 - vendor/github.com/gobwas/glob/match/min.go | 57 - .../github.com/gobwas/glob/match/nothing.go | 27 - vendor/github.com/gobwas/glob/match/prefix.go | 50 - .../gobwas/glob/match/prefix_any.go | 55 - .../gobwas/glob/match/prefix_suffix.go | 62 - vendor/github.com/gobwas/glob/match/range.go | 48 - vendor/github.com/gobwas/glob/match/row.go | 77 - .../github.com/gobwas/glob/match/segments.go | 91 - vendor/github.com/gobwas/glob/match/single.go | 43 - vendor/github.com/gobwas/glob/match/suffix.go | 35 - .../gobwas/glob/match/suffix_any.go | 43 - vendor/github.com/gobwas/glob/match/super.go | 33 - vendor/github.com/gobwas/glob/match/text.go | 45 - vendor/github.com/gobwas/glob/readme.md | 148 - .../github.com/gobwas/glob/syntax/ast/ast.go | 122 - .../gobwas/glob/syntax/ast/parser.go | 157 - .../gobwas/glob/syntax/lexer/lexer.go | 273 - .../gobwas/glob/syntax/lexer/token.go | 88 - .../github.com/gobwas/glob/syntax/syntax.go | 14 - .../gobwas/glob/util/runes/runes.go | 154 - .../gobwas/glob/util/strings/strings.go | 39 - vendor/github.com/gofrs/flock/.gitignore | 24 - vendor/github.com/gofrs/flock/.golangci.yml | 114 - vendor/github.com/gofrs/flock/LICENSE | 28 - vendor/github.com/gofrs/flock/Makefile | 15 - vendor/github.com/gofrs/flock/README.md | 45 - vendor/github.com/gofrs/flock/SECURITY.md | 21 - vendor/github.com/gofrs/flock/build.sh | 18 - vendor/github.com/gofrs/flock/flock.go | 206 - vendor/github.com/gofrs/flock/flock_others.go | 40 - vendor/github.com/gofrs/flock/flock_unix.go | 210 - .../gofrs/flock/flock_unix_fcntl.go | 393 - .../github.com/gofrs/flock/flock_windows.go | 158 - .../github.com/golang-jwt/jwt/v5/.gitignore | 4 - vendor/github.com/golang-jwt/jwt/v5/LICENSE | 9 - .../golang-jwt/jwt/v5/MIGRATION_GUIDE.md | 195 - vendor/github.com/golang-jwt/jwt/v5/README.md | 167 - .../github.com/golang-jwt/jwt/v5/SECURITY.md | 19 - .../golang-jwt/jwt/v5/VERSION_HISTORY.md | 137 - vendor/github.com/golang-jwt/jwt/v5/claims.go | 16 - vendor/github.com/golang-jwt/jwt/v5/doc.go | 4 - vendor/github.com/golang-jwt/jwt/v5/ecdsa.go | 134 - .../golang-jwt/jwt/v5/ecdsa_utils.go | 69 - .../github.com/golang-jwt/jwt/v5/ed25519.go | 79 - .../golang-jwt/jwt/v5/ed25519_utils.go | 64 - vendor/github.com/golang-jwt/jwt/v5/errors.go | 49 - .../golang-jwt/jwt/v5/errors_go1_20.go | 47 - .../golang-jwt/jwt/v5/errors_go_other.go | 78 - vendor/github.com/golang-jwt/jwt/v5/hmac.go | 104 - .../golang-jwt/jwt/v5/map_claims.go | 109 - vendor/github.com/golang-jwt/jwt/v5/none.go | 50 - vendor/github.com/golang-jwt/jwt/v5/parser.go | 238 - .../golang-jwt/jwt/v5/parser_option.go | 128 - .../golang-jwt/jwt/v5/registered_claims.go | 63 - vendor/github.com/golang-jwt/jwt/v5/rsa.go | 93 - .../github.com/golang-jwt/jwt/v5/rsa_pss.go | 135 - .../github.com/golang-jwt/jwt/v5/rsa_utils.go | 107 - .../golang-jwt/jwt/v5/signing_method.go | 49 - .../golang-jwt/jwt/v5/staticcheck.conf | 1 - vendor/github.com/golang-jwt/jwt/v5/token.go | 100 - .../golang-jwt/jwt/v5/token_option.go | 5 - vendor/github.com/golang-jwt/jwt/v5/types.go | 149 - .../github.com/golang-jwt/jwt/v5/validator.go | 316 - vendor/github.com/golangci/dupl/.travis.yml | 5 - vendor/github.com/golangci/dupl/LICENSE | 21 - vendor/github.com/golangci/dupl/README.md | 63 - .../github.com/golangci/dupl/job/buildtree.go | 22 - vendor/github.com/golangci/dupl/job/parse.go | 36 - vendor/github.com/golangci/dupl/main.go | 148 - .../github.com/golangci/dupl/printer/html.go | 120 - .../golangci/dupl/printer/plumbing.go | 50 - .../golangci/dupl/printer/printer.go | 11 - .../github.com/golangci/dupl/printer/text.go | 100 - .../golangci/dupl/suffixtree/dupl.go | 98 - .../golangci/dupl/suffixtree/suffixtree.go | 216 - .../golangci/dupl/syntax/golang/golang.go | 392 - .../github.com/golangci/dupl/syntax/syntax.go | 175 - .../github.com/golangci/gofmt/gofmt/LICENSE | 27 - vendor/github.com/golangci/gofmt/gofmt/doc.go | 106 - .../github.com/golangci/gofmt/gofmt/gofmt.go | 570 - .../golangci/gofmt/gofmt/golangci.go | 100 - .../golangci/gofmt/gofmt/internal.go | 183 - .../gofmt/gofmt/internal/diff/diff.go | 261 - .../github.com/golangci/gofmt/gofmt/readme.md | 16 - .../golangci/gofmt/gofmt/rewrite.go | 309 - .../golangci/gofmt/gofmt/simplify.go | 169 - .../golangci/gofmt/goimports/LICENSE | 27 - .../golangci/gofmt/goimports/goimports.go | 88 - .../golangci/gofmt/goimports/golangci.go | 35 - .../golangci/gofmt/goimports/readme.md | 10 - .../github.com/golangci/golangci-lint/LICENSE | 674 - .../golangci-lint/cmd/golangci-lint/main.go | 81 - .../cmd/golangci-lint/plugins.go | 3 - .../golangci-lint/internal/cache/cache.go | 525 - .../golangci-lint/internal/cache/default.go | 88 - .../golangci-lint/internal/cache/hash.go | 186 - .../golangci-lint/internal/cache/readme.md | 18 - .../internal/errorutil/errors.go | 23 - .../internal/pkgcache/pkgcache.go | 229 - .../golangci-lint/internal/renameio/readme.md | 10 - .../internal/renameio/renameio.go | 93 - .../golangci-lint/internal/robustio/readme.md | 6 - .../internal/robustio/robustio.go | 53 - .../internal/robustio/robustio_darwin.go | 21 - .../internal/robustio/robustio_flaky.go | 91 - .../internal/robustio/robustio_other.go | 27 - .../internal/robustio/robustio_windows.go | 30 - .../golangci-lint/pkg/commands/cache.go | 82 - .../golangci-lint/pkg/commands/config.go | 122 - .../pkg/commands/config_verify.go | 179 - .../golangci-lint/pkg/commands/custom.go | 79 - .../golangci-lint/pkg/commands/flagsets.go | 146 - .../golangci-lint/pkg/commands/help.go | 142 - .../pkg/commands/internal/builder.go | 250 - .../pkg/commands/internal/configuration.go | 140 - .../pkg/commands/internal/imports.go | 69 - .../pkg/commands/internal/vibra.go | 59 - .../golangci-lint/pkg/commands/linters.go | 107 - .../golangci-lint/pkg/commands/root.go | 167 - .../golangci-lint/pkg/commands/run.go | 691 - .../golangci-lint/pkg/commands/version.go | 102 - .../golangci-lint/pkg/config/config.go | 90 - .../golangci-lint/pkg/config/issues.go | 246 - .../golangci-lint/pkg/config/linters.go | 65 - .../pkg/config/linters_settings.go | 1034 - .../golangci-lint/pkg/config/loader.go | 496 - .../golangci-lint/pkg/config/output.go | 117 - .../golangci/golangci-lint/pkg/config/run.go | 47 - .../golangci-lint/pkg/config/severity.go | 41 - .../golangci-lint/pkg/exitcodes/exitcodes.go | 32 - .../golangci-lint/pkg/fsutils/filecache.go | 65 - .../golangci-lint/pkg/fsutils/files.go | 33 - .../golangci-lint/pkg/fsutils/fsutils.go | 102 - .../golangci-lint/pkg/fsutils/linecache.go | 68 - .../golangci-lint/pkg/fsutils/path_unix.go | 8 - .../golangci-lint/pkg/fsutils/path_windows.go | 28 - .../golangci-lint/pkg/goanalysis/issue.go | 32 - .../golangci-lint/pkg/goanalysis/linter.go | 217 - .../pkg/goanalysis/load/guard.go | 30 - .../pkg/goanalysis/metalinter.go | 90 - .../pkg/goanalysis/pkgerrors/errors.go | 56 - .../pkg/goanalysis/pkgerrors/extract.go | 102 - .../pkg/goanalysis/pkgerrors/parse.go | 54 - .../golangci-lint/pkg/goanalysis/runner.go | 340 - .../pkg/goanalysis/runner_action.go | 385 - .../pkg/goanalysis/runner_facts.go | 125 - .../pkg/goanalysis/runner_loadingpackage.go | 509 - .../golangci-lint/pkg/goanalysis/runners.go | 274 - .../pkg/golinters/asasalint/asasalint.go | 31 - .../pkg/golinters/asciicheck/asciicheck.go | 19 - .../pkg/golinters/bidichk/bidichk.go | 59 - .../pkg/golinters/bodyclose/bodyclose.go | 19 - .../canonicalheader/canonicalheader.go | 19 - .../golinters/containedctx/containedctx.go | 19 - .../golinters/contextcheck/contextcheck.go | 22 - .../pkg/golinters/copyloopvar/copyloopvar.go | 29 - .../pkg/golinters/cyclop/cyclop.go | 37 - .../pkg/golinters/decorder/decorder.go | 44 - .../pkg/golinters/depguard/depguard.go | 50 - .../pkg/golinters/dogsled/dogsled.go | 110 - .../golangci-lint/pkg/golinters/dupl/dupl.go | 96 - .../pkg/golinters/dupword/dupword.go | 30 - .../golinters/durationcheck/durationcheck.go | 19 - .../pkg/golinters/err113/err113.go | 19 - .../pkg/golinters/errcheck/errcheck.go | 271 - .../pkg/golinters/errchkjson/errchkjson.go | 31 - .../pkg/golinters/errname/errname.go | 19 - .../pkg/golinters/errorlint/errorlint.go | 54 - .../pkg/golinters/execinquery/execinquery.go | 19 - .../pkg/golinters/exhaustive/exhaustive.go | 37 - .../pkg/golinters/exhaustruct/exhaustruct.go | 30 - .../golinters/exportloopref/exportloopref.go | 19 - .../pkg/golinters/fatcontext/fatcontext.go | 19 - .../pkg/golinters/forbidigo/forbidigo.go | 103 - .../forcetypeassert/forcetypeassert.go | 19 - .../pkg/golinters/funlen/funlen.go | 75 - .../golangci-lint/pkg/golinters/gci/gci.go | 250 - .../golinters/ginkgolinter/ginkgolinter.go | 39 - .../gocheckcompilerdirectives.go | 19 - .../gochecknoglobals/gochecknoglobals.go | 26 - .../gochecknoinits/gochecknoinits.go | 75 - .../gochecksumtype/gochecksumtype.go | 80 - .../pkg/golinters/gocognit/gocognit.go | 80 - .../pkg/golinters/goconst/goconst.go | 98 - .../pkg/golinters/gocritic/gocritic.go | 590 - .../pkg/golinters/gocyclo/gocyclo.go | 76 - .../pkg/golinters/godot/godot.go | 101 - .../pkg/golinters/godox/godox.go | 75 - .../pkg/golinters/gofmt/gofmt.go | 98 - .../pkg/golinters/gofumpt/gofumpt.go | 132 - .../pkg/golinters/goheader/goheader.go | 115 - .../pkg/golinters/goimports/goimports.go | 94 - .../gomoddirectives/gomoddirectives.go | 64 - .../pkg/golinters/gomodguard/gomodguard.go | 94 - .../goprintffuncname/goprintffuncname.go | 19 - .../pkg/golinters/gosec/gosec.go | 247 - .../pkg/golinters/gosimple/gosimple.go | 22 - .../golinters/gosmopolitan/gosmopolitan.go | 32 - .../pkg/golinters/govet/govet.go | 223 - .../pkg/golinters/grouper/grouper.go | 34 - .../pkg/golinters/importas/importas.go | 67 - .../pkg/golinters/inamedparam/inamedparam.go | 30 - .../pkg/golinters/ineffassign/ineffassign.go | 19 - .../interfacebloat/interfacebloat.go | 29 - .../pkg/golinters/internal/commons.go | 6 - .../pkg/golinters/internal/diff.go | 264 - .../golinters/internal/staticcheck_common.go | 154 - .../pkg/golinters/internal/util.go | 33 - .../pkg/golinters/intrange/intrange.go | 19 - .../pkg/golinters/ireturn/ireturn.go | 31 - .../golangci-lint/pkg/golinters/lll/lll.go | 157 - .../pkg/golinters/loggercheck/loggercheck.go | 44 - .../pkg/golinters/maintidx/maintidx.go | 30 - .../pkg/golinters/makezero/makezero.go | 74 - .../pkg/golinters/mirror/mirror.go | 70 - .../pkg/golinters/misspell/misspell.go | 189 - .../golangci-lint/pkg/golinters/mnd/mnd.go | 63 - .../pkg/golinters/musttag/musttag.go | 29 - .../pkg/golinters/nakedret/nakedret.go | 25 - .../pkg/golinters/nestif/nestif.go | 78 - .../pkg/golinters/nilerr/nilerr.go | 19 - .../pkg/golinters/nilnil/nilnil.go | 30 - .../pkg/golinters/nlreturn/nlreturn.go | 27 - .../pkg/golinters/noctx/noctx.go | 19 - .../golinters/nolintlint/internal/README.md | 31 - .../nolintlint/internal/nolintlint.go | 311 - .../pkg/golinters/nolintlint/nolintlint.go | 104 - .../nonamedreturns/nonamedreturns.go | 29 - .../nosprintfhostport/nosprintfhostport.go | 19 - .../golinters/paralleltest/paralleltest.go | 34 - .../pkg/golinters/perfsprint/perfsprint.go | 32 - .../pkg/golinters/prealloc/prealloc.go | 65 - .../pkg/golinters/predeclared/predeclared.go | 26 - .../pkg/golinters/promlinter/promlinter.go | 77 - .../pkg/golinters/protogetter/protogetter.go | 74 - .../pkg/golinters/reassign/reassign.go | 32 - .../pkg/golinters/revive/revive.go | 433 - .../golinters/rowserrcheck/rowserrcheck.go | 25 - .../pkg/golinters/sloglint/sloglint.go | 33 - .../pkg/golinters/spancheck/spancheck.go | 33 - .../golinters/sqlclosecheck/sqlclosecheck.go | 19 - .../pkg/golinters/staticcheck/staticcheck.go | 22 - .../pkg/golinters/stylecheck/stylecheck.go | 31 - .../pkg/golinters/tagalign/tagalign.go | 75 - .../pkg/golinters/tagliatelle/tagliatelle.go | 35 - .../golangci-lint/pkg/golinters/tenv/tenv.go | 29 - .../testableexamples/testableexamples.go | 19 - .../pkg/golinters/testifylint/testifylint.go | 51 - .../pkg/golinters/testpackage/testpackage.go | 28 - .../pkg/golinters/thelper/thelper.go | 81 - .../pkg/golinters/tparallel/tparallel.go | 18 - .../golangci-lint/pkg/golinters/typecheck.go | 24 - .../pkg/golinters/unconvert/unconvert.go | 62 - .../pkg/golinters/unparam/unparam.go | 90 - .../pkg/golinters/unused/unused.go | 112 - .../golinters/usestdlibvars/usestdlibvars.go | 38 - .../pkg/golinters/varnamelen/varnamelen.go | 46 - .../golinters/wastedassign/wastedassign.go | 19 - .../pkg/golinters/whitespace/whitespace.go | 102 - .../pkg/golinters/wrapcheck/wrapcheck.go | 36 - .../golangci-lint/pkg/golinters/wsl/wsl.go | 40 - .../pkg/golinters/zerologlint/zerologlint.go | 19 - .../golangci/golangci-lint/pkg/goutil/env.go | 63 - .../golangci-lint/pkg/goutil/version.go | 75 - .../golangci-lint/pkg/lint/context.go | 64 - .../golangci-lint/pkg/lint/linter/config.go | 181 - .../golangci-lint/pkg/lint/linter/context.go | 48 - .../golangci-lint/pkg/lint/linter/linter.go | 67 - .../pkg/lint/lintersdb/builder_linter.go | 843 - .../pkg/lint/lintersdb/builder_plugin_go.go | 136 - .../lint/lintersdb/builder_plugin_module.go | 85 - .../pkg/lint/lintersdb/manager.go | 313 - .../pkg/lint/lintersdb/validator.go | 120 - .../golangci-lint/pkg/lint/package.go | 283 - .../golangci/golangci-lint/pkg/lint/runner.go | 242 - .../golangci-lint/pkg/logutils/log.go | 31 - .../golangci-lint/pkg/logutils/logutils.go | 118 - .../golangci-lint/pkg/logutils/mock.go | 82 - .../golangci-lint/pkg/logutils/out.go | 11 - .../golangci-lint/pkg/logutils/stderr_log.go | 129 - .../golangci-lint/pkg/printers/checkstyle.go | 95 - .../golangci-lint/pkg/printers/codeclimate.go | 59 - .../pkg/printers/githubaction.go | 52 - .../golangci-lint/pkg/printers/html.go | 156 - .../golangci-lint/pkg/printers/json.go | 38 - .../golangci-lint/pkg/printers/junitxml.go | 99 - .../golangci-lint/pkg/printers/printer.go | 145 - .../golangci-lint/pkg/printers/sarif.go | 117 - .../golangci-lint/pkg/printers/tab.go | 67 - .../golangci-lint/pkg/printers/teamcity.go | 122 - .../golangci-lint/pkg/printers/text.go | 94 - .../golangci/golangci-lint/pkg/report/data.go | 26 - .../golangci/golangci-lint/pkg/report/log.go | 64 - .../golangci-lint/pkg/result/issue.go | 98 - .../processors/autogenerated_exclude.go | 177 - .../pkg/result/processors/base_rule.go | 68 - .../pkg/result/processors/cgo.go | 59 - .../pkg/result/processors/diff.go | 84 - .../pkg/result/processors/exclude.go | 55 - .../pkg/result/processors/exclude_rules.go | 105 - .../result/processors/filename_unadjuster.go | 133 - .../pkg/result/processors/fixer.go | 261 - .../result/processors/identifier_marker.go | 154 - .../pkg/result/processors/invalid_issue.go | 60 - .../pkg/result/processors/issues.go | 69 - .../pkg/result/processors/max_from_linter.go | 55 - .../processors/max_per_file_from_linter.go | 73 - .../pkg/result/processors/max_same_issues.go | 79 - .../pkg/result/processors/nolint.go | 315 - .../pkg/result/processors/path_prefixer.go | 36 - .../pkg/result/processors/path_prettifier.go | 40 - .../pkg/result/processors/path_shortener.go | 39 - .../pkg/result/processors/processor.go | 13 - .../pkg/result/processors/severity.go | 116 - .../pkg/result/processors/skip_dirs.go | 172 - .../pkg/result/processors/skip_files.go | 59 - .../pkg/result/processors/sort_results.go | 259 - .../pkg/result/processors/source_code.go | 50 - .../pkg/result/processors/uniq_by_line.go | 73 - .../golangci-lint/pkg/timeutils/stopwatch.go | 116 - .../github.com/golangci/misspell/.gitignore | 37 - .../golangci/misspell/.golangci.yml | 107 - .../golangci/misspell/.pre-commit-hooks.yaml | 8 - .../github.com/golangci/misspell/Dockerfile | 35 - vendor/github.com/golangci/misspell/LICENSE | 21 - vendor/github.com/golangci/misspell/Makefile | 66 - vendor/github.com/golangci/misspell/README.md | 401 - .../golangci/misspell/RELEASE-HOWTO.md | 38 - vendor/github.com/golangci/misspell/ascii.go | 60 - vendor/github.com/golangci/misspell/case.go | 58 - .../golangci/misspell/goreleaser.yml | 31 - .../golangci/misspell/install-misspell.sh | 377 - vendor/github.com/golangci/misspell/legal.go | 47 - vendor/github.com/golangci/misspell/mime.go | 206 - .../github.com/golangci/misspell/notwords.go | 102 - .../github.com/golangci/misspell/replace.go | 245 - .../golangci/misspell/stringreplacer.go | 336 - .../golangci/misspell/stringreplacer_test.gox | 421 - vendor/github.com/golangci/misspell/url.go | 18 - vendor/github.com/golangci/misspell/words.go | 31194 ---------------- vendor/github.com/golangci/modinfo/.gitignore | 1 - .../github.com/golangci/modinfo/.golangci.yml | 157 - vendor/github.com/golangci/modinfo/LICENSE | 674 - vendor/github.com/golangci/modinfo/Makefile | 12 - vendor/github.com/golangci/modinfo/module.go | 157 - vendor/github.com/golangci/modinfo/readme.md | 73 - .../golangci/plugin-module-register/LICENSE | 674 - .../register/register.go | 73 - vendor/github.com/golangci/revgrep/.gitignore | 1 - .../github.com/golangci/revgrep/.golangci.yml | 80 - vendor/github.com/golangci/revgrep/LICENSE | 201 - vendor/github.com/golangci/revgrep/Makefile | 12 - vendor/github.com/golangci/revgrep/README.md | 55 - vendor/github.com/golangci/revgrep/revgrep.go | 483 - vendor/github.com/golangci/unconvert/LICENSE | 27 - .../github.com/golangci/unconvert/README.md | 6 - .../github.com/golangci/unconvert/golangci.go | 78 - .../golangci/unconvert/unconvert.go | 650 - vendor/github.com/google/go-cmp/LICENSE | 27 - .../github.com/google/go-cmp/cmp/compare.go | 671 - vendor/github.com/google/go-cmp/cmp/export.go | 31 - .../go-cmp/cmp/internal/diff/debug_disable.go | 18 - .../go-cmp/cmp/internal/diff/debug_enable.go | 123 - .../google/go-cmp/cmp/internal/diff/diff.go | 402 - .../google/go-cmp/cmp/internal/flags/flags.go | 9 - .../go-cmp/cmp/internal/function/func.go | 99 - .../google/go-cmp/cmp/internal/value/name.go | 164 - .../go-cmp/cmp/internal/value/pointer.go | 34 - .../google/go-cmp/cmp/internal/value/sort.go | 106 - .../github.com/google/go-cmp/cmp/options.go | 554 - vendor/github.com/google/go-cmp/cmp/path.go | 390 - vendor/github.com/google/go-cmp/cmp/report.go | 54 - .../google/go-cmp/cmp/report_compare.go | 433 - .../google/go-cmp/cmp/report_references.go | 264 - .../google/go-cmp/cmp/report_reflect.go | 414 - .../google/go-cmp/cmp/report_slices.go | 614 - .../google/go-cmp/cmp/report_text.go | 432 - .../google/go-cmp/cmp/report_value.go | 121 - vendor/github.com/google/uuid/CHANGELOG.md | 41 - vendor/github.com/google/uuid/CONTRIBUTING.md | 26 - vendor/github.com/google/uuid/CONTRIBUTORS | 9 - vendor/github.com/google/uuid/LICENSE | 27 - vendor/github.com/google/uuid/README.md | 21 - vendor/github.com/google/uuid/dce.go | 80 - vendor/github.com/google/uuid/doc.go | 12 - vendor/github.com/google/uuid/hash.go | 59 - vendor/github.com/google/uuid/marshal.go | 38 - vendor/github.com/google/uuid/node.go | 90 - vendor/github.com/google/uuid/node_js.go | 12 - vendor/github.com/google/uuid/node_net.go | 33 - vendor/github.com/google/uuid/null.go | 118 - vendor/github.com/google/uuid/sql.go | 59 - vendor/github.com/google/uuid/time.go | 134 - vendor/github.com/google/uuid/util.go | 43 - vendor/github.com/google/uuid/uuid.go | 365 - vendor/github.com/google/uuid/version1.go | 44 - vendor/github.com/google/uuid/version4.go | 76 - vendor/github.com/google/uuid/version6.go | 56 - vendor/github.com/google/uuid/version7.go | 104 - .../gordonklaus/ineffassign/LICENSE | 21 - .../pkg/ineffassign/ineffassign.go | 610 - vendor/github.com/gorilla/mux/.editorconfig | 20 - vendor/github.com/gorilla/mux/.gitignore | 1 - vendor/github.com/gorilla/mux/LICENSE | 27 - vendor/github.com/gorilla/mux/Makefile | 34 - vendor/github.com/gorilla/mux/README.md | 812 - vendor/github.com/gorilla/mux/doc.go | 305 - vendor/github.com/gorilla/mux/middleware.go | 74 - vendor/github.com/gorilla/mux/mux.go | 608 - vendor/github.com/gorilla/mux/regexp.go | 388 - vendor/github.com/gorilla/mux/route.go | 765 - vendor/github.com/gorilla/mux/test_helpers.go | 19 - .../gostaticanalysis/analysisutil/LICENSE | 21 - .../gostaticanalysis/analysisutil/README.md | 5 - .../gostaticanalysis/analysisutil/call.go | 405 - .../analysisutil/diagnostic.go | 45 - .../gostaticanalysis/analysisutil/file.go | 30 - .../gostaticanalysis/analysisutil/pkg.go | 49 - .../gostaticanalysis/analysisutil/ssa.go | 152 - .../analysisutil/ssainspect.go | 47 - .../gostaticanalysis/analysisutil/types.go | 228 - .../gostaticanalysis/comment/LICENSE | 21 - .../gostaticanalysis/comment/README.md | 10 - .../gostaticanalysis/comment/comment.go | 152 - .../comment/passes/commentmap/commentmap.go | 21 - .../forcetypeassert/.reviewdog.yml | 8 - .../gostaticanalysis/forcetypeassert/LICENSE | 21 - .../forcetypeassert/README.md | 28 - .../forcetypeassert/forcetypeassert.go | 143 - .../gostaticanalysis/nilerr/LICENSE | 21 - .../gostaticanalysis/nilerr/README.md | 41 - .../gostaticanalysis/nilerr/nilerr.go | 291 - .../go-grpc-middleware/.gitignore | 204 - .../go-grpc-middleware/CONTRIBUTING.md | 20 - .../grpc-ecosystem/go-grpc-middleware/LICENSE | 201 - .../go-grpc-middleware/README.md | 93 - .../go-grpc-middleware/auth/auth.go | 68 - .../go-grpc-middleware/auth/doc.go | 20 - .../go-grpc-middleware/auth/metadata.go | 37 - .../go-grpc-middleware/chain.go | 166 - .../grpc-ecosystem/go-grpc-middleware/doc.go | 69 - .../go-grpc-middleware/makefile | 17 - .../providers/prometheus/LICENSE | 201 - .../providers/prometheus/client_metrics.go | 117 - .../providers/prometheus/client_options.go | 77 - .../providers/prometheus/constants.go | 23 - .../providers/prometheus/doc.go | 8 - .../providers/prometheus/options.go | 129 - .../providers/prometheus/reporter.go | 113 - .../providers/prometheus/server_metrics.go | 123 - .../providers/prometheus/server_options.go | 48 - .../go-grpc-middleware/retry/backoff.go | 44 - .../go-grpc-middleware/retry/doc.go | 25 - .../go-grpc-middleware/retry/options.go | 142 - .../go-grpc-middleware/retry/retry.go | 319 - .../go-grpc-middleware/slack.png | Bin 5088 -> 0 bytes .../go-grpc-middleware/tags/context.go | 78 - .../go-grpc-middleware/tags/doc.go | 22 - .../go-grpc-middleware/tags/fieldextractor.go | 85 - .../go-grpc-middleware/tags/interceptors.go | 85 - .../go-grpc-middleware/tags/options.go | 44 - .../opentracing/client_interceptors.go | 143 - .../tracing/opentracing/doc.go | 22 - .../tracing/opentracing/id_extract.go | 82 - .../tracing/opentracing/metadata.go | 50 - .../tracing/opentracing/options.go | 89 - .../opentracing/server_interceptors.go | 98 - .../util/backoffutils/backoff.go | 28 - .../go-grpc-middleware/util/metautils/doc.go | 19 - .../util/metautils/nicemd.go | 126 - .../go-grpc-middleware/v2/COPYRIGHT | 2 - .../go-grpc-middleware/v2/LICENSE | 201 - .../v2/interceptors/client.go | 83 - .../go-grpc-middleware/v2/interceptors/doc.go | 12 - .../v2/interceptors/reporter.go | 116 - .../v2/interceptors/server.go | 74 - .../go-grpc-middleware/wrappers.go | 30 - .../hashicorp/go-version/CHANGELOG.md | 64 - .../github.com/hashicorp/go-version/LICENSE | 356 - .../github.com/hashicorp/go-version/README.md | 66 - .../hashicorp/go-version/constraint.go | 298 - .../hashicorp/go-version/version.go | 441 - .../go-version/version_collection.go | 20 - vendor/github.com/hashicorp/hcl/.gitignore | 9 - vendor/github.com/hashicorp/hcl/.travis.yml | 13 - vendor/github.com/hashicorp/hcl/LICENSE | 354 - vendor/github.com/hashicorp/hcl/Makefile | 18 - vendor/github.com/hashicorp/hcl/README.md | 125 - vendor/github.com/hashicorp/hcl/appveyor.yml | 19 - vendor/github.com/hashicorp/hcl/decoder.go | 729 - vendor/github.com/hashicorp/hcl/hcl.go | 11 - .../github.com/hashicorp/hcl/hcl/ast/ast.go | 219 - .../github.com/hashicorp/hcl/hcl/ast/walk.go | 52 - .../hashicorp/hcl/hcl/parser/error.go | 17 - .../hashicorp/hcl/hcl/parser/parser.go | 532 - .../hashicorp/hcl/hcl/printer/nodes.go | 789 - .../hashicorp/hcl/hcl/printer/printer.go | 66 - .../hashicorp/hcl/hcl/scanner/scanner.go | 652 - .../hashicorp/hcl/hcl/strconv/quote.go | 241 - .../hashicorp/hcl/hcl/token/position.go | 46 - .../hashicorp/hcl/hcl/token/token.go | 219 - .../hashicorp/hcl/json/parser/flatten.go | 117 - .../hashicorp/hcl/json/parser/parser.go | 313 - .../hashicorp/hcl/json/scanner/scanner.go | 451 - .../hashicorp/hcl/json/token/position.go | 46 - .../hashicorp/hcl/json/token/token.go | 118 - vendor/github.com/hashicorp/hcl/lex.go | 38 - vendor/github.com/hashicorp/hcl/parse.go | 39 - vendor/github.com/hexops/gotextdiff/LICENSE | 27 - vendor/github.com/hexops/gotextdiff/README.md | 54 - vendor/github.com/hexops/gotextdiff/diff.go | 159 - .../hexops/gotextdiff/myers/diff.go | 205 - .../hexops/gotextdiff/span/parse.go | 100 - .../github.com/hexops/gotextdiff/span/span.go | 285 - .../hexops/gotextdiff/span/token.go | 194 - .../hexops/gotextdiff/span/token111.go | 39 - .../hexops/gotextdiff/span/token112.go | 16 - .../github.com/hexops/gotextdiff/span/uri.go | 169 - .../hexops/gotextdiff/span/utf16.go | 91 - .../github.com/hexops/gotextdiff/unified.go | 210 - .../inconshreveable/mousetrap/LICENSE | 201 - .../inconshreveable/mousetrap/README.md | 23 - .../inconshreveable/mousetrap/trap_others.go | 16 - .../inconshreveable/mousetrap/trap_windows.go | 42 - vendor/github.com/jgautheron/goconst/LICENSE | 21 - .../github.com/jgautheron/goconst/README.md | 51 - vendor/github.com/jgautheron/goconst/api.go | 76 - .../github.com/jgautheron/goconst/parser.go | 187 - .../github.com/jgautheron/goconst/visitor.go | 160 - .../github.com/jingyugao/rowserrcheck/LICENSE | 21 - .../rowserrcheck/passes/rowserr/rowserr.go | 304 - vendor/github.com/jinzhu/inflection/LICENSE | 21 - vendor/github.com/jinzhu/inflection/README.md | 55 - .../jinzhu/inflection/inflections.go | 273 - .../github.com/jinzhu/inflection/wercker.yml | 23 - .../jirfag/go-printf-func-name/LICENSE | 21 - .../pkg/analyzer/analyzer.go | 74 - .../github.com/jjti/go-spancheck/.gitignore | 19 - .../jjti/go-spancheck/.golangci.yml | 103 - .../jjti/go-spancheck/CONTRIBUTING.md | 51 - vendor/github.com/jjti/go-spancheck/LICENSE | 21 - vendor/github.com/jjti/go-spancheck/Makefile | 27 - vendor/github.com/jjti/go-spancheck/README.md | 268 - vendor/github.com/jjti/go-spancheck/config.go | 223 - vendor/github.com/jjti/go-spancheck/doc.go | 37 - vendor/github.com/jjti/go-spancheck/go.work | 8 - .../github.com/jjti/go-spancheck/go.work.sum | 4 - .../github.com/jjti/go-spancheck/spancheck.go | 466 - vendor/github.com/jpillora/backoff/LICENSE | 21 - vendor/github.com/jpillora/backoff/README.md | 119 - vendor/github.com/jpillora/backoff/backoff.go | 100 - .../github.com/json-iterator/go/.codecov.yml | 3 - vendor/github.com/json-iterator/go/.gitignore | 4 - .../github.com/json-iterator/go/.travis.yml | 14 - vendor/github.com/json-iterator/go/Gopkg.lock | 21 - vendor/github.com/json-iterator/go/Gopkg.toml | 26 - vendor/github.com/json-iterator/go/LICENSE | 21 - vendor/github.com/json-iterator/go/README.md | 85 - vendor/github.com/json-iterator/go/adapter.go | 150 - vendor/github.com/json-iterator/go/any.go | 325 - .../github.com/json-iterator/go/any_array.go | 278 - .../github.com/json-iterator/go/any_bool.go | 137 - .../github.com/json-iterator/go/any_float.go | 83 - .../github.com/json-iterator/go/any_int32.go | 74 - .../github.com/json-iterator/go/any_int64.go | 74 - .../json-iterator/go/any_invalid.go | 82 - vendor/github.com/json-iterator/go/any_nil.go | 69 - .../github.com/json-iterator/go/any_number.go | 123 - .../github.com/json-iterator/go/any_object.go | 374 - vendor/github.com/json-iterator/go/any_str.go | 166 - .../github.com/json-iterator/go/any_uint32.go | 74 - .../github.com/json-iterator/go/any_uint64.go | 74 - vendor/github.com/json-iterator/go/build.sh | 12 - vendor/github.com/json-iterator/go/config.go | 375 - .../go/fuzzy_mode_convert_table.md | 7 - vendor/github.com/json-iterator/go/iter.go | 349 - .../github.com/json-iterator/go/iter_array.go | 64 - .../github.com/json-iterator/go/iter_float.go | 342 - .../github.com/json-iterator/go/iter_int.go | 346 - .../json-iterator/go/iter_object.go | 267 - .../github.com/json-iterator/go/iter_skip.go | 130 - .../json-iterator/go/iter_skip_sloppy.go | 163 - .../json-iterator/go/iter_skip_strict.go | 99 - .../github.com/json-iterator/go/iter_str.go | 215 - .../github.com/json-iterator/go/jsoniter.go | 18 - vendor/github.com/json-iterator/go/pool.go | 42 - vendor/github.com/json-iterator/go/reflect.go | 337 - .../json-iterator/go/reflect_array.go | 104 - .../json-iterator/go/reflect_dynamic.go | 70 - .../json-iterator/go/reflect_extension.go | 483 - .../json-iterator/go/reflect_json_number.go | 112 - .../go/reflect_json_raw_message.go | 76 - .../json-iterator/go/reflect_map.go | 346 - .../json-iterator/go/reflect_marshaler.go | 225 - .../json-iterator/go/reflect_native.go | 453 - .../json-iterator/go/reflect_optional.go | 129 - .../json-iterator/go/reflect_slice.go | 99 - .../go/reflect_struct_decoder.go | 1097 - .../go/reflect_struct_encoder.go | 211 - vendor/github.com/json-iterator/go/stream.go | 210 - .../json-iterator/go/stream_float.go | 111 - .../github.com/json-iterator/go/stream_int.go | 190 - .../github.com/json-iterator/go/stream_str.go | 372 - vendor/github.com/json-iterator/go/test.sh | 12 - vendor/github.com/julz/importas/.gitignore | 2 - vendor/github.com/julz/importas/LICENSE | 201 - vendor/github.com/julz/importas/README.md | 59 - vendor/github.com/julz/importas/analyzer.go | 141 - vendor/github.com/julz/importas/config.go | 70 - vendor/github.com/julz/importas/flags.go | 32 - .../karamaru-alpha/copyloopvar/.gitignore | 2 - .../karamaru-alpha/copyloopvar/LICENSE | 21 - .../karamaru-alpha/copyloopvar/README.md | 27 - .../karamaru-alpha/copyloopvar/copyloopvar.go | 133 - vendor/github.com/kisielk/errcheck/LICENSE | 22 - .../kisielk/errcheck/errcheck/analyzer.go | 77 - .../errcheck/errcheck/embedded_walker.go | 143 - .../kisielk/errcheck/errcheck/errcheck.go | 668 - .../kisielk/errcheck/errcheck/excludes.go | 79 - .../kisielk/errcheck/errcheck/tags.go | 12 - .../kisielk/errcheck/errcheck/tags_compat.go | 13 - .../kkHAIKE/contextcheck/.gitignore | 20 - .../github.com/kkHAIKE/contextcheck/LICENSE | 201 - .../github.com/kkHAIKE/contextcheck/Makefile | 15 - .../github.com/kkHAIKE/contextcheck/README.md | 157 - .../kkHAIKE/contextcheck/contextcheck.go | 825 - vendor/github.com/klauspost/cpuid/.gitignore | 24 - vendor/github.com/klauspost/cpuid/.travis.yml | 46 - .../klauspost/cpuid/CONTRIBUTING.txt | 35 - vendor/github.com/klauspost/cpuid/LICENSE | 22 - vendor/github.com/klauspost/cpuid/README.md | 191 - vendor/github.com/klauspost/cpuid/cpuid.go | 1504 - vendor/github.com/klauspost/cpuid/cpuid_386.s | 42 - .../github.com/klauspost/cpuid/cpuid_amd64.s | 42 - .../github.com/klauspost/cpuid/cpuid_arm64.s | 26 - .../klauspost/cpuid/detect_arm64.go | 219 - .../klauspost/cpuid/detect_intel.go | 33 - .../github.com/klauspost/cpuid/detect_ref.go | 14 - vendor/github.com/kulti/thelper/LICENSE | 21 - .../kulti/thelper/pkg/analyzer/analyzer.go | 639 - .../kulti/thelper/pkg/analyzer/report.go | 56 - .../kunwardeep/paralleltest/LICENSE | 21 - .../pkg/paralleltest/paralleltest.go | 320 - .../kyoh86/exportloopref/.golangci.yml | 4 - .../kyoh86/exportloopref/.goreleaser.yml | 51 - .../github.com/kyoh86/exportloopref/LICENSE | 21 - .../github.com/kyoh86/exportloopref/Makefile | 16 - .../github.com/kyoh86/exportloopref/README.md | 223 - .../kyoh86/exportloopref/exportloopref.go | 334 - .../lasiar/canonicalheader/.gitignore | 1 - .../lasiar/canonicalheader/.golangci.yaml | 802 - .../lasiar/canonicalheader/.goreleaser.yaml | 18 - .../github.com/lasiar/canonicalheader/LICENCE | 21 - .../lasiar/canonicalheader/README.md | 77 - .../lasiar/canonicalheader/analyzer.go | 264 - .../lasiar/canonicalheader/constant_string.go | 50 - .../lasiar/canonicalheader/initialism.go | 75 - .../lasiar/canonicalheader/literal_string.go | 80 - .../lasiar/canonicalheader/makefile | 12 - .../ldez/gomoddirectives/.gitignore | 2 - .../ldez/gomoddirectives/.golangci.yml | 102 - .../github.com/ldez/gomoddirectives/LICENSE | 190 - .../github.com/ldez/gomoddirectives/Makefile | 15 - .../ldez/gomoddirectives/gomoddirectives.go | 125 - .../github.com/ldez/gomoddirectives/module.go | 48 - .../github.com/ldez/gomoddirectives/readme.md | 16 - vendor/github.com/ldez/tagliatelle/.gitignore | 3 - .../github.com/ldez/tagliatelle/.golangci.yml | 88 - vendor/github.com/ldez/tagliatelle/LICENSE | 190 - vendor/github.com/ldez/tagliatelle/Makefile | 15 - vendor/github.com/ldez/tagliatelle/readme.md | 177 - .../ldez/tagliatelle/tagliatelle.go | 218 - .../github.com/leonklingele/grouper/LICENSE | 674 - .../grouper/pkg/analyzer/analyzer.go | 91 - .../grouper/pkg/analyzer/config.go | 15 - .../grouper/pkg/analyzer/consts/analyzer.go | 19 - .../grouper/pkg/analyzer/consts/config.go | 6 - .../grouper/pkg/analyzer/flags.go | 37 - .../grouper/pkg/analyzer/globals/analyzer.go | 105 - .../grouper/pkg/analyzer/imports/analyzer.go | 103 - .../grouper/pkg/analyzer/imports/config.go | 6 - .../grouper/pkg/analyzer/types/analyzer.go | 19 - .../grouper/pkg/analyzer/types/config.go | 6 - .../grouper/pkg/analyzer/vars/analyzer.go | 19 - .../grouper/pkg/analyzer/vars/config.go | 6 - .../github.com/lufeee/execinquery/.gitignore | 1 - vendor/github.com/lufeee/execinquery/LICENSE | 21 - .../github.com/lufeee/execinquery/README.md | 76 - .../lufeee/execinquery/execinquery.go | 135 - .../github.com/macabu/inamedparam/.gitignore | 22 - .../macabu/inamedparam/.golangci.yml | 33 - .../github.com/macabu/inamedparam/LICENSE-MIT | 21 - .../github.com/macabu/inamedparam/README.md | 38 - .../macabu/inamedparam/inamedparam.go | 94 - .../magiconair/properties/.gitignore | 6 - .../magiconair/properties/.travis.yml | 17 - .../magiconair/properties/CHANGELOG.md | 160 - .../magiconair/properties/LICENSE.md | 24 - .../magiconair/properties/README.md | 128 - .../magiconair/properties/decode.go | 289 - .../github.com/magiconair/properties/doc.go | 156 - .../magiconair/properties/integrate.go | 34 - .../github.com/magiconair/properties/lex.go | 395 - .../github.com/magiconair/properties/load.go | 293 - .../magiconair/properties/parser.go | 86 - .../magiconair/properties/properties.go | 853 - .../magiconair/properties/rangecheck.go | 31 - .../maratori/testableexamples/LICENSE | 21 - .../pkg/testableexamples/testableexamples.go | 34 - .../github.com/maratori/testpackage/LICENSE | 21 - .../pkg/testpackage/testpackage.go | 73 - vendor/github.com/matoous/godox/.gitignore | 19 - vendor/github.com/matoous/godox/.golangci.yml | 71 - vendor/github.com/matoous/godox/.revive.toml | 135 - vendor/github.com/matoous/godox/LICENSE | 21 - vendor/github.com/matoous/godox/README.md | 23 - vendor/github.com/matoous/godox/godox.go | 119 - vendor/github.com/mattn/go-colorable/LICENSE | 21 - .../github.com/mattn/go-colorable/README.md | 48 - .../mattn/go-colorable/colorable_appengine.go | 38 - .../mattn/go-colorable/colorable_others.go | 38 - .../mattn/go-colorable/colorable_windows.go | 1047 - .../github.com/mattn/go-colorable/go.test.sh | 12 - .../mattn/go-colorable/noncolorable.go | 57 - vendor/github.com/mattn/go-isatty/LICENSE | 9 - vendor/github.com/mattn/go-isatty/README.md | 50 - vendor/github.com/mattn/go-isatty/doc.go | 2 - vendor/github.com/mattn/go-isatty/go.test.sh | 12 - .../github.com/mattn/go-isatty/isatty_bsd.go | 20 - .../mattn/go-isatty/isatty_others.go | 17 - .../mattn/go-isatty/isatty_plan9.go | 23 - .../mattn/go-isatty/isatty_solaris.go | 21 - .../mattn/go-isatty/isatty_tcgets.go | 20 - .../mattn/go-isatty/isatty_windows.go | 125 - vendor/github.com/mattn/go-runewidth/LICENSE | 21 - .../github.com/mattn/go-runewidth/README.md | 27 - .../mattn/go-runewidth/runewidth.go | 358 - .../mattn/go-runewidth/runewidth_appengine.go | 9 - .../mattn/go-runewidth/runewidth_js.go | 9 - .../mattn/go-runewidth/runewidth_posix.go | 81 - .../mattn/go-runewidth/runewidth_table.go | 439 - .../mattn/go-runewidth/runewidth_windows.go | 28 - vendor/github.com/mattn/goveralls/.gitignore | 3 - vendor/github.com/mattn/goveralls/.travis.yml | 8 - vendor/github.com/mattn/goveralls/LICENSE | 21 - vendor/github.com/mattn/goveralls/README.md | 295 - vendor/github.com/mattn/goveralls/gitinfo.go | 146 - vendor/github.com/mattn/goveralls/gocover.go | 188 - .../github.com/mattn/goveralls/goveralls.go | 581 - .../github.com/mattn/goveralls/renovate.json | 6 - vendor/github.com/mgechev/revive/LICENSE | 21 - .../mgechev/revive/config/config.go | 260 - .../mgechev/revive/formatter/checkstyle.go | 77 - .../mgechev/revive/formatter/default.go | 28 - .../mgechev/revive/formatter/doc.go | 2 - .../mgechev/revive/formatter/friendly.go | 141 - .../mgechev/revive/formatter/json.go | 40 - .../mgechev/revive/formatter/ndjson.go | 35 - .../mgechev/revive/formatter/plain.go | 28 - .../mgechev/revive/formatter/sarif.go | 107 - .../mgechev/revive/formatter/severity.go | 13 - .../mgechev/revive/formatter/stylish.go | 89 - .../mgechev/revive/formatter/unix.go | 30 - .../mgechev/revive/internal/ifelse/args.go | 11 - .../mgechev/revive/internal/ifelse/branch.go | 93 - .../revive/internal/ifelse/branch_kind.go | 101 - .../mgechev/revive/internal/ifelse/chain.go | 10 - .../mgechev/revive/internal/ifelse/doc.go | 6 - .../mgechev/revive/internal/ifelse/func.go | 51 - .../mgechev/revive/internal/ifelse/rule.go | 105 - .../mgechev/revive/internal/ifelse/target.go | 25 - .../revive/internal/typeparams/typeparams.go | 29 - .../internal/typeparams/typeparams_go117.go | 12 - .../internal/typeparams/typeparams_go118.go | 20 - .../github.com/mgechev/revive/lint/config.go | 71 - vendor/github.com/mgechev/revive/lint/doc.go | 2 - .../github.com/mgechev/revive/lint/failure.go | 39 - vendor/github.com/mgechev/revive/lint/file.go | 280 - .../mgechev/revive/lint/filefilter.go | 128 - .../mgechev/revive/lint/formatter.go | 14 - .../github.com/mgechev/revive/lint/linter.go | 244 - .../github.com/mgechev/revive/lint/package.go | 200 - vendor/github.com/mgechev/revive/lint/rule.go | 31 - .../github.com/mgechev/revive/lint/utils.go | 133 - .../mgechev/revive/rule/add-constant.go | 266 - .../mgechev/revive/rule/argument-limit.go | 84 - .../github.com/mgechev/revive/rule/atomic.go | 94 - .../mgechev/revive/rule/banned-characters.go | 90 - .../mgechev/revive/rule/bare-return.go | 84 - .../mgechev/revive/rule/blank-imports.go | 75 - .../revive/rule/bool-literal-in-expr.go | 73 - .../mgechev/revive/rule/call-to-gc.go | 70 - .../revive/rule/cognitive-complexity.go | 212 - .../mgechev/revive/rule/comment-spacings.go | 86 - .../mgechev/revive/rule/comments-density.go | 95 - .../mgechev/revive/rule/confusing-naming.go | 207 - .../mgechev/revive/rule/confusing-results.go | 66 - .../revive/rule/constant-logical-expr.go | 100 - .../revive/rule/context-as-argument.go | 110 - .../mgechev/revive/rule/context-keys-type.go | 81 - .../mgechev/revive/rule/cyclomatic.go | 136 - .../mgechev/revive/rule/datarace.go | 144 - .../mgechev/revive/rule/deep-exit.go | 94 - .../github.com/mgechev/revive/rule/defer.go | 177 - vendor/github.com/mgechev/revive/rule/doc.go | 2 - .../mgechev/revive/rule/dot-imports.go | 106 - .../mgechev/revive/rule/duplicated-imports.go | 39 - .../mgechev/revive/rule/early-return.go | 51 - .../mgechev/revive/rule/empty-block.go | 75 - .../mgechev/revive/rule/empty-lines.go | 105 - .../mgechev/revive/rule/enforce-map-style.go | 164 - .../rule/enforce-repeated-arg-type-style.go | 191 - .../revive/rule/enforce-slice-style.go | 214 - .../mgechev/revive/rule/error-naming.go | 79 - .../mgechev/revive/rule/error-return.go | 67 - .../mgechev/revive/rule/error-strings.go | 199 - .../github.com/mgechev/revive/rule/errorf.go | 93 - .../mgechev/revive/rule/exported.go | 340 - .../mgechev/revive/rule/file-header.go | 87 - .../mgechev/revive/rule/flag-param.go | 105 - .../mgechev/revive/rule/function-length.go | 177 - .../revive/rule/function-result-limit.go | 83 - .../mgechev/revive/rule/get-return.go | 70 - .../mgechev/revive/rule/identical-branches.go | 84 - .../mgechev/revive/rule/if-return.go | 115 - .../revive/rule/import-alias-naming.go | 126 - .../mgechev/revive/rule/import-shadowing.go | 115 - .../mgechev/revive/rule/imports-blocklist.go | 73 - .../revive/rule/increment-decrement.go | 73 - .../mgechev/revive/rule/indent-error-flow.go | 45 - .../mgechev/revive/rule/line-length-limit.go | 102 - .../revive/rule/max-control-nesting.go | 128 - .../mgechev/revive/rule/max-public-structs.go | 88 - .../mgechev/revive/rule/modifies-param.go | 80 - .../revive/rule/modifies-value-receiver.go | 129 - .../mgechev/revive/rule/nested-structs.go | 75 - .../revive/rule/optimize-operands-order.go | 86 - .../mgechev/revive/rule/package-comments.go | 164 - .../mgechev/revive/rule/range-val-address.go | 166 - .../revive/rule/range-val-in-closure.go | 125 - .../github.com/mgechev/revive/rule/range.go | 82 - .../mgechev/revive/rule/receiver-naming.go | 81 - .../revive/rule/redefines-builtin-id.go | 179 - .../revive/rule/redundant-import-alias.go | 52 - .../mgechev/revive/rule/string-format.go | 311 - .../mgechev/revive/rule/string-of-int.go | 95 - .../mgechev/revive/rule/struct-tag.go | 421 - .../mgechev/revive/rule/superfluous-else.go | 46 - .../mgechev/revive/rule/time-equal.go | 76 - .../mgechev/revive/rule/time-naming.go | 95 - .../revive/rule/unchecked-type-assertion.go | 194 - .../revive/rule/unconditional-recursion.go | 199 - .../mgechev/revive/rule/unexported-naming.go | 115 - .../mgechev/revive/rule/unexported-return.go | 107 - .../mgechev/revive/rule/unhandled-error.go | 178 - .../mgechev/revive/rule/unnecessary-stmt.go | 107 - .../mgechev/revive/rule/unreachable-code.go | 122 - .../mgechev/revive/rule/unused-param.go | 167 - .../mgechev/revive/rule/unused-receiver.go | 133 - .../github.com/mgechev/revive/rule/use-any.go | 54 - .../mgechev/revive/rule/useless-break.go | 82 - .../github.com/mgechev/revive/rule/utils.go | 173 - .../mgechev/revive/rule/var-declarations.go | 120 - .../mgechev/revive/rule/var-naming.go | 281 - .../mgechev/revive/rule/waitgroup-by-value.go | 66 - vendor/github.com/minio/md5-simd/LICENSE | 202 - vendor/github.com/minio/md5-simd/README.md | 196 - .../minio/md5-simd/block-generic.go | 132 - .../github.com/minio/md5-simd/block16_amd64.s | 227 - .../github.com/minio/md5-simd/block8_amd64.s | 279 - .../github.com/minio/md5-simd/block_amd64.go | 199 - .../minio/md5-simd/md5-digest_amd64.go | 178 - .../minio/md5-simd/md5-server_amd64.go | 307 - .../minio/md5-simd/md5-server_fallback.go | 12 - .../minio/md5-simd/md5-util_amd64.go | 70 - vendor/github.com/minio/md5-simd/md5.go | 57 - .../github.com/minio/minio-go/v7/.gitignore | 4 - .../minio/minio-go/v7/.golangci.yml | 16 - vendor/github.com/minio/minio-go/v7/CNAME | 1 - .../minio/minio-go/v7/CONTRIBUTING.md | 23 - vendor/github.com/minio/minio-go/v7/LICENSE | 202 - .../minio/minio-go/v7/MAINTAINERS.md | 35 - vendor/github.com/minio/minio-go/v7/Makefile | 32 - vendor/github.com/minio/minio-go/v7/NOTICE | 9 - vendor/github.com/minio/minio-go/v7/README.md | 251 - .../minio/minio-go/v7/README_zh_CN.md | 260 - .../minio-go/v7/api-bucket-encryption.go | 134 - .../minio/minio-go/v7/api-bucket-lifecycle.go | 147 - .../minio-go/v7/api-bucket-notification.go | 255 - .../minio/minio-go/v7/api-bucket-policy.go | 142 - .../minio-go/v7/api-bucket-replication.go | 149 - .../minio/minio-go/v7/api-bucket-tagging.go | 135 - .../minio-go/v7/api-bucket-versioning.go | 137 - .../minio/minio-go/v7/api-compose-object.go | 575 - .../minio/minio-go/v7/api-datatypes.go | 173 - .../minio/minio-go/v7/api-error-response.go | 271 - .../minio/minio-go/v7/api-get-object-acl.go | 140 - .../minio/minio-go/v7/api-get-object-file.go | 127 - .../minio/minio-go/v7/api-get-object.go | 646 - .../minio/minio-go/v7/api-get-options.go | 140 - .../github.com/minio/minio-go/v7/api-list.go | 950 - .../minio-go/v7/api-object-legal-hold.go | 176 - .../minio/minio-go/v7/api-object-lock.go | 241 - .../minio/minio-go/v7/api-object-retention.go | 165 - .../minio/minio-go/v7/api-object-tagging.go | 157 - .../minio/minio-go/v7/api-presigned.go | 216 - .../minio/minio-go/v7/api-put-bucket.go | 123 - .../minio-go/v7/api-put-object-common.go | 148 - .../minio/minio-go/v7/api-put-object-copy.go | 77 - .../v7/api-put-object-file-context.go | 64 - .../minio-go/v7/api-put-object-multipart.go | 385 - .../minio-go/v7/api-put-object-streaming.go | 487 - .../minio/minio-go/v7/api-put-object.go | 366 - .../minio/minio-go/v7/api-remove.go | 415 - .../minio/minio-go/v7/api-s3-datatypes.go | 361 - .../minio/minio-go/v7/api-select.go | 751 - .../github.com/minio/minio-go/v7/api-stat.go | 127 - vendor/github.com/minio/minio-go/v7/api.go | 899 - .../minio/minio-go/v7/bucket-cache.go | 253 - .../minio/minio-go/v7/code_of_conduct.md | 80 - .../github.com/minio/minio-go/v7/constants.go | 91 - vendor/github.com/minio/minio-go/v7/core.go | 133 - .../minio/minio-go/v7/hook-reader.go | 85 - .../v7/pkg/credentials/assume_role.go | 214 - .../minio-go/v7/pkg/credentials/chain.go | 89 - .../v7/pkg/credentials/config.json.sample | 17 - .../v7/pkg/credentials/credentials.go | 178 - .../v7/pkg/credentials/credentials.sample | 12 - .../minio/minio-go/v7/pkg/credentials/doc.go | 62 - .../minio-go/v7/pkg/credentials/env_aws.go | 71 - .../minio-go/v7/pkg/credentials/env_minio.go | 62 - .../pkg/credentials/file_aws_credentials.go | 120 - .../v7/pkg/credentials/file_minio_client.go | 135 - .../minio-go/v7/pkg/credentials/iam_aws.go | 324 - .../v7/pkg/credentials/signature-type.go | 77 - .../minio-go/v7/pkg/credentials/static.go | 67 - .../v7/pkg/credentials/sts_client_grants.go | 162 - .../v7/pkg/credentials/sts_ldap_identity.go | 124 - .../v7/pkg/credentials/sts_web_identity.go | 181 - .../minio-go/v7/pkg/encrypt/server-side.go | 198 - .../minio-go/v7/pkg/lifecycle/lifecycle.go | 288 - .../minio-go/v7/pkg/notification/info.go | 78 - .../v7/pkg/notification/notification.go | 395 - .../v7/pkg/replication/replication.go | 610 - .../minio/minio-go/v7/pkg/s3utils/utils.go | 384 - .../minio/minio-go/v7/pkg/set/stringset.go | 200 - .../pkg/signer/request-signature-streaming.go | 306 - .../v7/pkg/signer/request-signature-v2.go | 317 - .../v7/pkg/signer/request-signature-v4.go | 318 - .../minio/minio-go/v7/pkg/signer/utils.go | 59 - .../minio/minio-go/v7/pkg/sse/sse.go | 66 - .../minio/minio-go/v7/pkg/tags/tags.go | 342 - .../minio/minio-go/v7/post-policy.go | 327 - .../minio/minio-go/v7/retry-continous.go | 69 - vendor/github.com/minio/minio-go/v7/retry.go | 124 - .../minio/minio-go/v7/s3-endpoints.go | 57 - .../github.com/minio/minio-go/v7/s3-error.go | 61 - .../minio/minio-go/v7/staticcheck.conf | 1 - .../github.com/minio/minio-go/v7/transport.go | 83 - vendor/github.com/minio/minio-go/v7/utils.go | 488 - .../github.com/minio/sha256-simd/.gitignore | 1 - .../github.com/minio/sha256-simd/.travis.yml | 25 - vendor/github.com/minio/sha256-simd/LICENSE | 202 - vendor/github.com/minio/sha256-simd/README.md | 133 - .../github.com/minio/sha256-simd/appveyor.yml | 32 - vendor/github.com/minio/sha256-simd/cpuid.go | 119 - .../github.com/minio/sha256-simd/cpuid_386.go | 24 - .../github.com/minio/sha256-simd/cpuid_386.s | 53 - .../minio/sha256-simd/cpuid_amd64.go | 24 - .../minio/sha256-simd/cpuid_amd64.s | 53 - .../github.com/minio/sha256-simd/cpuid_arm.go | 32 - .../minio/sha256-simd/cpuid_linux_arm64.go | 49 - .../minio/sha256-simd/cpuid_other.go | 34 - vendor/github.com/minio/sha256-simd/sha256.go | 409 - .../sha256-simd/sha256blockAvx2_amd64.go | 22 - .../minio/sha256-simd/sha256blockAvx2_amd64.s | 1449 - .../sha256-simd/sha256blockAvx512_amd64.asm | 686 - .../sha256-simd/sha256blockAvx512_amd64.go | 500 - .../sha256-simd/sha256blockAvx512_amd64.s | 267 - .../minio/sha256-simd/sha256blockAvx_amd64.go | 22 - .../minio/sha256-simd/sha256blockAvx_amd64.s | 408 - .../minio/sha256-simd/sha256blockSha_amd64.go | 6 - .../minio/sha256-simd/sha256blockSha_amd64.s | 266 - .../sha256-simd/sha256blockSsse_amd64.go | 22 - .../minio/sha256-simd/sha256blockSsse_amd64.s | 429 - .../minio/sha256-simd/sha256block_amd64.go | 53 - .../minio/sha256-simd/sha256block_arm64.go | 37 - .../minio/sha256-simd/sha256block_arm64.s | 192 - .../minio/sha256-simd/sha256block_other.go | 25 - .../minio/sha256-simd/test-architectures.sh | 15 - .../github.com/mitchellh/go-homedir/LICENSE | 21 - .../github.com/mitchellh/go-homedir/README.md | 14 - .../mitchellh/go-homedir/homedir.go | 167 - .../mitchellh/mapstructure/CHANGELOG.md | 96 - .../github.com/mitchellh/mapstructure/LICENSE | 21 - .../mitchellh/mapstructure/README.md | 46 - .../mitchellh/mapstructure/decode_hooks.go | 279 - .../mitchellh/mapstructure/error.go | 50 - .../mitchellh/mapstructure/mapstructure.go | 1540 - .../modern-go/concurrent/.gitignore | 1 - .../modern-go/concurrent/.travis.yml | 14 - .../github.com/modern-go/concurrent/LICENSE | 201 - .../github.com/modern-go/concurrent/README.md | 49 - .../modern-go/concurrent/executor.go | 14 - .../modern-go/concurrent/go_above_19.go | 15 - .../modern-go/concurrent/go_below_19.go | 33 - vendor/github.com/modern-go/concurrent/log.go | 13 - .../github.com/modern-go/concurrent/test.sh | 12 - .../concurrent/unbounded_executor.go | 119 - .../github.com/modern-go/reflect2/.gitignore | 2 - .../github.com/modern-go/reflect2/.travis.yml | 15 - .../github.com/modern-go/reflect2/Gopkg.lock | 9 - .../github.com/modern-go/reflect2/Gopkg.toml | 31 - vendor/github.com/modern-go/reflect2/LICENSE | 201 - .../github.com/modern-go/reflect2/README.md | 71 - .../modern-go/reflect2/go_above_118.go | 23 - .../modern-go/reflect2/go_above_19.go | 17 - .../modern-go/reflect2/go_below_118.go | 21 - .../github.com/modern-go/reflect2/reflect2.go | 300 - .../modern-go/reflect2/reflect2_amd64.s | 0 .../modern-go/reflect2/reflect2_kind.go | 30 - .../modern-go/reflect2/relfect2_386.s | 0 .../modern-go/reflect2/relfect2_amd64p32.s | 0 .../modern-go/reflect2/relfect2_arm.s | 0 .../modern-go/reflect2/relfect2_arm64.s | 0 .../modern-go/reflect2/relfect2_mips64x.s | 0 .../modern-go/reflect2/relfect2_mipsx.s | 0 .../modern-go/reflect2/relfect2_ppc64x.s | 0 .../modern-go/reflect2/relfect2_s390x.s | 0 .../modern-go/reflect2/safe_field.go | 58 - .../github.com/modern-go/reflect2/safe_map.go | 101 - .../modern-go/reflect2/safe_slice.go | 92 - .../modern-go/reflect2/safe_struct.go | 29 - .../modern-go/reflect2/safe_type.go | 78 - .../github.com/modern-go/reflect2/type_map.go | 70 - .../modern-go/reflect2/unsafe_array.go | 65 - .../modern-go/reflect2/unsafe_eface.go | 59 - .../modern-go/reflect2/unsafe_field.go | 74 - .../modern-go/reflect2/unsafe_iface.go | 64 - .../modern-go/reflect2/unsafe_link.go | 76 - .../modern-go/reflect2/unsafe_map.go | 130 - .../modern-go/reflect2/unsafe_ptr.go | 46 - .../modern-go/reflect2/unsafe_slice.go | 177 - .../modern-go/reflect2/unsafe_struct.go | 59 - .../modern-go/reflect2/unsafe_type.go | 85 - .../github.com/moricho/tparallel/.gitignore | 3 - .../moricho/tparallel/.goreleaser.yaml | 58 - vendor/github.com/moricho/tparallel/LICENSE | 21 - vendor/github.com/moricho/tparallel/Makefile | 13 - vendor/github.com/moricho/tparallel/README.md | 112 - .../moricho/tparallel/pkg/ssafunc/ssafunc.go | 34 - .../tparallel/pkg/ssainstr/ssainstr.go | 63 - .../github.com/moricho/tparallel/testmap.go | 67 - .../github.com/moricho/tparallel/tparallel.go | 72 - vendor/github.com/nakabonne/nestif/.gitignore | 16 - vendor/github.com/nakabonne/nestif/LICENSE | 25 - vendor/github.com/nakabonne/nestif/README.md | 128 - vendor/github.com/nakabonne/nestif/nestif.go | 148 - .../nishanths/exhaustive/.gitignore | 12 - .../github.com/nishanths/exhaustive/LICENSE | 25 - .../github.com/nishanths/exhaustive/Makefile | 43 - .../github.com/nishanths/exhaustive/README.md | 104 - .../nishanths/exhaustive/comment.go | 29 - .../nishanths/exhaustive/comment_go121.go | 11 - .../nishanths/exhaustive/comment_pre_go121.go | 27 - .../github.com/nishanths/exhaustive/common.go | 474 - vendor/github.com/nishanths/exhaustive/doc.go | 216 - .../github.com/nishanths/exhaustive/enum.go | 177 - .../nishanths/exhaustive/exhaustive.go | 152 - .../github.com/nishanths/exhaustive/fact.go | 28 - .../github.com/nishanths/exhaustive/flag.go | 75 - vendor/github.com/nishanths/exhaustive/map.go | 134 - .../github.com/nishanths/exhaustive/switch.go | 236 - .../github.com/nishanths/predeclared/LICENSE | 29 - .../predeclared/passes/predeclared/go18.go | 9 - .../passes/predeclared/pre_go18.go | 53 - .../passes/predeclared/predeclared.go | 202 - .../nunnatsa/ginkgolinter/.gitignore | 2 - .../nunnatsa/ginkgolinter/.golangci.yml | 3 - .../github.com/nunnatsa/ginkgolinter/LICENSE | 21 - .../github.com/nunnatsa/ginkgolinter/Makefile | 27 - .../nunnatsa/ginkgolinter/README.md | 553 - .../nunnatsa/ginkgolinter/analyzer.go | 58 - .../github.com/nunnatsa/ginkgolinter/doc.go | 99 - .../internal/ginkgohandler/handler.go | 129 - .../internal/gomegahandler/handler.go | 241 - .../internal/interfaces/interfaces.go | 76 - .../internal/intervals/intervals.go | 285 - .../internal/reports/report-builder.go | 98 - .../reverseassertion/reverse_assertion.go | 42 - .../ginkgolinter/linter/ginkgo_linter.go | 1673 - .../nunnatsa/ginkgolinter/types/boolean.go | 32 - .../nunnatsa/ginkgolinter/types/config.go | 99 - .../nunnatsa/ginkgolinter/version/version.go | 14 - .../olekukonko/tablewriter/.gitignore | 15 - .../olekukonko/tablewriter/.travis.yml | 22 - .../olekukonko/tablewriter/LICENSE.md | 19 - .../olekukonko/tablewriter/README.md | 431 - .../github.com/olekukonko/tablewriter/csv.go | 52 - .../olekukonko/tablewriter/table.go | 967 - .../tablewriter/table_with_color.go | 136 - .../github.com/olekukonko/tablewriter/util.go | 93 - .../github.com/olekukonko/tablewriter/wrap.go | 99 - .../opentracing/opentracing-go/.gitignore | 1 - .../opentracing/opentracing-go/.travis.yml | 20 - .../opentracing/opentracing-go/CHANGELOG.md | 46 - .../opentracing/opentracing-go/LICENSE | 201 - .../opentracing/opentracing-go/Makefile | 20 - .../opentracing/opentracing-go/README.md | 171 - .../opentracing/opentracing-go/ext/tags.go | 210 - .../opentracing-go/globaltracer.go | 42 - .../opentracing/opentracing-go/gocontext.go | 60 - .../opentracing/opentracing-go/log/field.go | 269 - .../opentracing/opentracing-go/log/util.go | 54 - .../opentracing/opentracing-go/noop.go | 64 - .../opentracing/opentracing-go/propagation.go | 176 - .../opentracing/opentracing-go/span.go | 189 - .../opentracing/opentracing-go/tracer.go | 304 - .../pelletier/go-toml/.dockerignore | 2 - .../github.com/pelletier/go-toml/.gitignore | 5 - .../pelletier/go-toml/CONTRIBUTING.md | 132 - .../github.com/pelletier/go-toml/Dockerfile | 11 - vendor/github.com/pelletier/go-toml/LICENSE | 247 - vendor/github.com/pelletier/go-toml/Makefile | 29 - .../go-toml/PULL_REQUEST_TEMPLATE.md | 5 - vendor/github.com/pelletier/go-toml/README.md | 176 - .../github.com/pelletier/go-toml/SECURITY.md | 19 - .../pelletier/go-toml/azure-pipelines.yml | 188 - .../github.com/pelletier/go-toml/benchmark.sh | 35 - vendor/github.com/pelletier/go-toml/doc.go | 23 - .../pelletier/go-toml/example-crlf.toml | 30 - .../github.com/pelletier/go-toml/example.toml | 30 - vendor/github.com/pelletier/go-toml/fuzz.go | 31 - vendor/github.com/pelletier/go-toml/fuzz.sh | 15 - .../pelletier/go-toml/keysparsing.go | 112 - vendor/github.com/pelletier/go-toml/lexer.go | 1031 - .../github.com/pelletier/go-toml/localtime.go | 287 - .../github.com/pelletier/go-toml/marshal.go | 1308 - .../go-toml/marshal_OrderPreserve_test.toml | 39 - .../pelletier/go-toml/marshal_test.toml | 39 - vendor/github.com/pelletier/go-toml/parser.go | 507 - .../github.com/pelletier/go-toml/position.go | 29 - vendor/github.com/pelletier/go-toml/token.go | 136 - vendor/github.com/pelletier/go-toml/toml.go | 533 - .../github.com/pelletier/go-toml/tomlpub.go | 71 - .../pelletier/go-toml/tomltree_create.go | 155 - .../pelletier/go-toml/tomltree_write.go | 552 - .../pelletier/go-toml/tomltree_writepub.go | 6 - .../pelletier/go-toml/v2/.dockerignore | 2 - .../pelletier/go-toml/v2/.gitattributes | 4 - .../pelletier/go-toml/v2/.gitignore | 7 - .../pelletier/go-toml/v2/.golangci.toml | 84 - .../pelletier/go-toml/v2/.goreleaser.yaml | 127 - .../pelletier/go-toml/v2/CONTRIBUTING.md | 193 - .../pelletier/go-toml/v2/Dockerfile | 5 - .../github.com/pelletier/go-toml/v2/LICENSE | 22 - .../github.com/pelletier/go-toml/v2/README.md | 576 - .../pelletier/go-toml/v2/SECURITY.md | 16 - vendor/github.com/pelletier/go-toml/v2/ci.sh | 284 - .../github.com/pelletier/go-toml/v2/decode.go | 550 - vendor/github.com/pelletier/go-toml/v2/doc.go | 2 - .../github.com/pelletier/go-toml/v2/errors.go | 252 - .../go-toml/v2/internal/characters/ascii.go | 42 - .../go-toml/v2/internal/characters/utf8.go | 199 - .../go-toml/v2/internal/danger/danger.go | 65 - .../go-toml/v2/internal/danger/typeid.go | 23 - .../go-toml/v2/internal/tracker/key.go | 48 - .../go-toml/v2/internal/tracker/seen.go | 358 - .../go-toml/v2/internal/tracker/tracker.go | 1 - .../pelletier/go-toml/v2/localtime.go | 122 - .../pelletier/go-toml/v2/marshaler.go | 1133 - .../github.com/pelletier/go-toml/v2/strict.go | 107 - .../github.com/pelletier/go-toml/v2/toml.abnf | 243 - .../github.com/pelletier/go-toml/v2/types.go | 14 - .../pelletier/go-toml/v2/unmarshaler.go | 1334 - .../pelletier/go-toml/v2/unstable/ast.go | 136 - .../pelletier/go-toml/v2/unstable/builder.go | 71 - .../pelletier/go-toml/v2/unstable/doc.go | 3 - .../pelletier/go-toml/v2/unstable/kind.go | 71 - .../pelletier/go-toml/v2/unstable/parser.go | 1245 - .../pelletier/go-toml/v2/unstable/scanner.go | 270 - .../go-toml/v2/unstable/unmarshaler.go | 7 - vendor/github.com/pkg/errors/.gitignore | 24 - vendor/github.com/pkg/errors/.travis.yml | 10 - vendor/github.com/pkg/errors/LICENSE | 23 - vendor/github.com/pkg/errors/Makefile | 44 - vendor/github.com/pkg/errors/README.md | 59 - vendor/github.com/pkg/errors/appveyor.yml | 32 - vendor/github.com/pkg/errors/errors.go | 288 - vendor/github.com/pkg/errors/go113.go | 38 - vendor/github.com/pkg/errors/stack.go | 177 - vendor/github.com/pmezard/go-difflib/LICENSE | 27 - .../pmezard/go-difflib/difflib/difflib.go | 772 - .../github.com/polyfloyd/go-errorlint/LICENSE | 21 - .../go-errorlint/errorlint/allowed.go | 251 - .../go-errorlint/errorlint/analysis.go | 116 - .../polyfloyd/go-errorlint/errorlint/lint.go | 385 - .../go-errorlint/errorlint/options.go | 15 - .../go-errorlint/errorlint/printf.go | 122 - .../prometheus/client_golang/LICENSE | 201 - .../prometheus/client_golang/NOTICE | 23 - .../client_golang/prometheus/.gitignore | 1 - .../client_golang/prometheus/README.md | 1 - .../prometheus/build_info_collector.go | 38 - .../client_golang/prometheus/collector.go | 128 - .../client_golang/prometheus/counter.go | 358 - .../client_golang/prometheus/desc.go | 207 - .../client_golang/prometheus/doc.go | 210 - .../prometheus/expvar_collector.go | 86 - .../client_golang/prometheus/fnv.go | 42 - .../client_golang/prometheus/gauge.go | 311 - .../client_golang/prometheus/get_pid.go | 26 - .../prometheus/get_pid_gopherjs.go | 23 - .../client_golang/prometheus/go_collector.go | 281 - .../prometheus/go_collector_go116.go | 122 - .../prometheus/go_collector_latest.go | 567 - .../client_golang/prometheus/histogram.go | 1577 - .../prometheus/internal/almost_equal.go | 60 - .../prometheus/internal/difflib.go | 654 - .../internal/go_collector_options.go | 32 - .../prometheus/internal/go_runtime_metrics.go | 142 - .../prometheus/internal/metric.go | 101 - .../client_golang/prometheus/labels.go | 188 - .../client_golang/prometheus/metric.go | 257 - .../client_golang/prometheus/num_threads.go | 25 - .../prometheus/num_threads_gopherjs.go | 22 - .../client_golang/prometheus/observer.go | 64 - .../prometheus/process_collector.go | 164 - .../prometheus/process_collector_js.go | 26 - .../prometheus/process_collector_other.go | 66 - .../prometheus/process_collector_wasip1.go | 26 - .../prometheus/process_collector_windows.go | 116 - .../prometheus/promhttp/delegator.go | 374 - .../client_golang/prometheus/promhttp/http.go | 408 - .../prometheus/promhttp/instrument_client.go | 249 - .../prometheus/promhttp/instrument_server.go | 576 - .../prometheus/promhttp/option.go | 84 - .../client_golang/prometheus/registry.go | 1075 - .../client_golang/prometheus/summary.go | 785 - .../prometheus/testutil/promlint/problem.go | 33 - .../prometheus/testutil/promlint/promlint.go | 123 - .../testutil/promlint/validation.go | 33 - .../validations/counter_validations.go | 40 - .../validations/generic_name_validations.go | 101 - .../promlint/validations/help_validations.go | 32 - .../validations/histogram_validations.go | 63 - .../testutil/promlint/validations/units.go | 118 - .../client_golang/prometheus/timer.go | 81 - .../client_golang/prometheus/untyped.go | 42 - .../client_golang/prometheus/value.go | 274 - .../client_golang/prometheus/vec.go | 709 - .../client_golang/prometheus/vnext.go | 23 - .../client_golang/prometheus/wrap.go | 214 - .../prometheus/client_model/LICENSE | 201 - .../github.com/prometheus/client_model/NOTICE | 5 - .../prometheus/client_model/go/metrics.pb.go | 1376 - vendor/github.com/prometheus/common/LICENSE | 201 - vendor/github.com/prometheus/common/NOTICE | 5 - .../prometheus/common/expfmt/decode.go | 431 - .../prometheus/common/expfmt/encode.go | 191 - .../prometheus/common/expfmt/expfmt.go | 167 - .../prometheus/common/expfmt/fuzz.go | 37 - .../common/expfmt/openmetrics_create.go | 558 - .../prometheus/common/expfmt/text_create.go | 520 - .../prometheus/common/expfmt/text_parse.go | 781 - .../bitbucket.org/ww/goautoneg/README.txt | 67 - .../bitbucket.org/ww/goautoneg/autoneg.go | 160 - .../prometheus/common/model/alert.go | 136 - .../prometheus/common/model/fingerprinting.go | 105 - .../github.com/prometheus/common/model/fnv.go | 42 - .../prometheus/common/model/labels.go | 226 - .../prometheus/common/model/labelset.go | 169 - .../prometheus/common/model/metadata.go | 28 - .../prometheus/common/model/metric.go | 456 - .../prometheus/common/model/model.go | 16 - .../prometheus/common/model/signature.go | 142 - .../prometheus/common/model/silence.go | 106 - .../prometheus/common/model/time.go | 340 - .../prometheus/common/model/value.go | 364 - .../prometheus/common/model/value_float.go | 98 - .../common/model/value_histogram.go | 178 - .../prometheus/common/model/value_type.go | 83 - .../github.com/prometheus/procfs/.gitignore | 2 - .../prometheus/procfs/.golangci.yml | 15 - .../prometheus/procfs/CODE_OF_CONDUCT.md | 3 - .../prometheus/procfs/CONTRIBUTING.md | 121 - vendor/github.com/prometheus/procfs/LICENSE | 201 - .../prometheus/procfs/MAINTAINERS.md | 2 - vendor/github.com/prometheus/procfs/Makefile | 31 - .../prometheus/procfs/Makefile.common | 269 - vendor/github.com/prometheus/procfs/NOTICE | 7 - vendor/github.com/prometheus/procfs/README.md | 61 - .../github.com/prometheus/procfs/SECURITY.md | 6 - vendor/github.com/prometheus/procfs/arp.go | 116 - .../github.com/prometheus/procfs/buddyinfo.go | 85 - .../github.com/prometheus/procfs/cmdline.go | 30 - .../github.com/prometheus/procfs/cpuinfo.go | 519 - .../prometheus/procfs/cpuinfo_armx.go | 20 - .../prometheus/procfs/cpuinfo_loong64.go | 19 - .../prometheus/procfs/cpuinfo_mipsx.go | 20 - .../prometheus/procfs/cpuinfo_others.go | 19 - .../prometheus/procfs/cpuinfo_ppcx.go | 20 - .../prometheus/procfs/cpuinfo_riscvx.go | 20 - .../prometheus/procfs/cpuinfo_s390x.go | 19 - .../prometheus/procfs/cpuinfo_x86.go | 20 - vendor/github.com/prometheus/procfs/crypto.go | 154 - vendor/github.com/prometheus/procfs/doc.go | 44 - vendor/github.com/prometheus/procfs/fs.go | 50 - .../prometheus/procfs/fs_statfs_notype.go | 23 - .../prometheus/procfs/fs_statfs_type.go | 33 - .../github.com/prometheus/procfs/fscache.go | 422 - .../prometheus/procfs/internal/fs/fs.go | 55 - .../prometheus/procfs/internal/util/parse.go | 112 - .../procfs/internal/util/readfile.go | 37 - .../procfs/internal/util/sysreadfile.go | 50 - .../internal/util/sysreadfile_compat.go | 27 - .../procfs/internal/util/valueparser.go | 91 - vendor/github.com/prometheus/procfs/ipvs.go | 241 - .../prometheus/procfs/kernel_random.go | 63 - .../github.com/prometheus/procfs/loadavg.go | 62 - vendor/github.com/prometheus/procfs/mdstat.go | 266 - .../github.com/prometheus/procfs/meminfo.go | 277 - .../github.com/prometheus/procfs/mountinfo.go | 180 - .../prometheus/procfs/mountstats.go | 712 - .../prometheus/procfs/net_conntrackstat.go | 118 - .../github.com/prometheus/procfs/net_dev.go | 205 - .../prometheus/procfs/net_ip_socket.go | 228 - .../prometheus/procfs/net_protocols.go | 180 - .../github.com/prometheus/procfs/net_route.go | 143 - .../prometheus/procfs/net_sockstat.go | 162 - .../prometheus/procfs/net_softnet.go | 155 - .../github.com/prometheus/procfs/net_tcp.go | 64 - .../github.com/prometheus/procfs/net_udp.go | 64 - .../github.com/prometheus/procfs/net_unix.go | 257 - .../prometheus/procfs/net_wireless.go | 182 - .../github.com/prometheus/procfs/net_xfrm.go | 189 - .../github.com/prometheus/procfs/netstat.go | 82 - vendor/github.com/prometheus/procfs/proc.go | 338 - .../prometheus/procfs/proc_cgroup.go | 98 - .../prometheus/procfs/proc_cgroups.go | 98 - .../prometheus/procfs/proc_environ.go | 37 - .../prometheus/procfs/proc_fdinfo.go | 138 - .../prometheus/procfs/proc_interrupts.go | 98 - .../github.com/prometheus/procfs/proc_io.go | 59 - .../prometheus/procfs/proc_limits.go | 160 - .../github.com/prometheus/procfs/proc_maps.go | 211 - .../prometheus/procfs/proc_netstat.go | 443 - .../github.com/prometheus/procfs/proc_ns.go | 68 - .../github.com/prometheus/procfs/proc_psi.go | 102 - .../prometheus/procfs/proc_smaps.go | 166 - .../github.com/prometheus/procfs/proc_snmp.go | 353 - .../prometheus/procfs/proc_snmp6.go | 381 - .../github.com/prometheus/procfs/proc_stat.go | 222 - .../prometheus/procfs/proc_status.go | 221 - .../github.com/prometheus/procfs/proc_sys.go | 51 - .../github.com/prometheus/procfs/schedstat.go | 121 - vendor/github.com/prometheus/procfs/slab.go | 151 - .../github.com/prometheus/procfs/softirqs.go | 160 - vendor/github.com/prometheus/procfs/stat.go | 258 - vendor/github.com/prometheus/procfs/swaps.go | 89 - vendor/github.com/prometheus/procfs/thread.go | 80 - vendor/github.com/prometheus/procfs/ttar | 413 - vendor/github.com/prometheus/procfs/vm.go | 212 - .../github.com/prometheus/procfs/zoneinfo.go | 196 - .../github.com/quasilyte/go-ruleguard/LICENSE | 29 - .../quasilyte/go-ruleguard/dsl/LICENSE | 29 - .../quasilyte/go-ruleguard/dsl/bundle.go | 19 - .../quasilyte/go-ruleguard/dsl/do.go | 19 - .../quasilyte/go-ruleguard/dsl/dsl.go | 361 - .../quasilyte/go-ruleguard/dsl/filter.go | 24 - .../quasilyte/go-ruleguard/dsl/internal.go | 6 - .../quasilyte/go-ruleguard/dsl/types/ext.go | 21 - .../go-ruleguard/dsl/types/type_impl.go | 17 - .../quasilyte/go-ruleguard/dsl/types/types.go | 68 - .../go-ruleguard/internal/goenv/goenv.go | 34 - .../go-ruleguard/internal/golist/golist.go | 30 - .../internal/xsrcimporter/xsrcimporter.go | 29 - .../go-ruleguard/internal/xtypes/xtypes.go | 270 - .../go-ruleguard/ruleguard/ast_walker.go | 369 - .../go-ruleguard/ruleguard/bundle.go | 19 - .../go-ruleguard/ruleguard/engine.go | 270 - .../go-ruleguard/ruleguard/filters.go | 835 - .../go-ruleguard/ruleguard/go_version.go | 58 - .../go-ruleguard/ruleguard/gorule.go | 154 - .../go-ruleguard/ruleguard/goutil/goutil.go | 67 - .../go-ruleguard/ruleguard/goutil/resolve.go | 33 - .../go-ruleguard/ruleguard/importer.go | 95 - .../ruleguard/ir/filter_op.gen.go | 282 - .../ruleguard/ir/gen_filter_op.go | 148 - .../quasilyte/go-ruleguard/ruleguard/ir/ir.go | 113 - .../go-ruleguard/ruleguard/ir_loader.go | 890 - .../go-ruleguard/ruleguard/ir_utils.go | 41 - .../go-ruleguard/ruleguard/irconv/irconv.go | 857 - .../go-ruleguard/ruleguard/libdsl.go | 401 - .../go-ruleguard/ruleguard/match_data.go | 19 - .../go-ruleguard/ruleguard/nodepath.go | 49 - .../ruleguard/profiling/no_labels.go | 16 - .../ruleguard/profiling/with_labels.go | 21 - .../go-ruleguard/ruleguard/quasigo/compile.go | 869 - .../ruleguard/quasigo/debug_info.go | 17 - .../go-ruleguard/ruleguard/quasigo/disasm.go | 84 - .../go-ruleguard/ruleguard/quasigo/env.go | 42 - .../go-ruleguard/ruleguard/quasigo/eval.go | 265 - .../ruleguard/quasigo/gen_opcodes.go | 192 - .../ruleguard/quasigo/opcode_string.go | 69 - .../ruleguard/quasigo/opcodes.gen.go | 249 - .../go-ruleguard/ruleguard/quasigo/quasigo.go | 199 - .../ruleguard/quasigo/stdlib/qfmt/qfmt.go | 17 - .../quasigo/stdlib/qstrconv/qstrconv.go | 24 - .../quasigo/stdlib/qstrings/qstrings.go | 62 - .../go-ruleguard/ruleguard/quasigo/utils.go | 60 - .../go-ruleguard/ruleguard/ruleguard.go | 221 - .../go-ruleguard/ruleguard/runner.go | 562 - .../ruleguard/textmatch/compile.go | 84 - .../ruleguard/textmatch/matchers.go | 72 - .../ruleguard/textmatch/textmatch.go | 26 - .../ruleguard/typematch/patternop_string.go | 36 - .../ruleguard/typematch/typematch.go | 607 - .../quasilyte/go-ruleguard/ruleguard/utils.go | 304 - vendor/github.com/quasilyte/gogrep/.gitignore | 4 - .../github.com/quasilyte/gogrep/.golangci.yml | 49 - vendor/github.com/quasilyte/gogrep/LICENSE | 33 - vendor/github.com/quasilyte/gogrep/Makefile | 19 - vendor/github.com/quasilyte/gogrep/README.md | 41 - vendor/github.com/quasilyte/gogrep/compile.go | 1264 - .../quasilyte/gogrep/compile_import.go | 57 - .../quasilyte/gogrep/gen_operations.go | 366 - vendor/github.com/quasilyte/gogrep/gogrep.go | 187 - .../quasilyte/gogrep/instructions.go | 116 - .../gogrep/internal/stdinfo/stdinfo.go | 151 - vendor/github.com/quasilyte/gogrep/match.go | 1024 - .../quasilyte/gogrep/nodetag/nodetag.go | 287 - .../quasilyte/gogrep/operation_string.go | 154 - .../quasilyte/gogrep/operations.gen.go | 1671 - vendor/github.com/quasilyte/gogrep/parse.go | 403 - vendor/github.com/quasilyte/gogrep/slices.go | 150 - .../github.com/quasilyte/regex/syntax/LICENSE | 21 - .../quasilyte/regex/syntax/README.md | 29 - .../github.com/quasilyte/regex/syntax/ast.go | 64 - .../quasilyte/regex/syntax/errors.go | 27 - .../quasilyte/regex/syntax/lexer.go | 454 - .../quasilyte/regex/syntax/operation.go | 195 - .../regex/syntax/operation_string.go | 59 - .../quasilyte/regex/syntax/parser.go | 503 - .../github.com/quasilyte/regex/syntax/pos.go | 10 - .../regex/syntax/tokenkind_string.go | 59 - .../quasilyte/regex/syntax/utils.go | 30 - vendor/github.com/quasilyte/stdinfo/LICENSE | 21 - .../github.com/quasilyte/stdinfo/stdinfo.go | 30 - .../quasilyte/stdinfo/stdinfo_gen.go | 274 - .../github.com/redis/go-redis/v9/.gitignore | 6 - .../redis/go-redis/v9/.golangci.yml | 4 - .../redis/go-redis/v9/.prettierrc.yml | 4 - .../github.com/redis/go-redis/v9/CHANGELOG.md | 124 - .../redis/go-redis/v9/CONTRIBUTING.md | 101 - vendor/github.com/redis/go-redis/v9/LICENSE | 25 - vendor/github.com/redis/go-redis/v9/Makefile | 44 - vendor/github.com/redis/go-redis/v9/README.md | 274 - .../github.com/redis/go-redis/v9/RELEASING.md | 15 - .../redis/go-redis/v9/acl_commands.go | 35 - .../redis/go-redis/v9/bitmap_commands.go | 163 - .../redis/go-redis/v9/cluster_commands.go | 192 - .../github.com/redis/go-redis/v9/command.go | 5483 --- .../github.com/redis/go-redis/v9/commands.go | 718 - vendor/github.com/redis/go-redis/v9/doc.go | 4 - vendor/github.com/redis/go-redis/v9/error.go | 156 - .../redis/go-redis/v9/gears_commands.go | 149 - .../redis/go-redis/v9/generic_commands.go | 384 - .../redis/go-redis/v9/geo_commands.go | 155 - .../redis/go-redis/v9/hash_commands.go | 174 - .../redis/go-redis/v9/hyperloglog_commands.go | 42 - .../redis/go-redis/v9/internal/arg.go | 58 - .../go-redis/v9/internal/hashtag/hashtag.go | 78 - .../redis/go-redis/v9/internal/hscan/hscan.go | 207 - .../go-redis/v9/internal/hscan/structmap.go | 125 - .../redis/go-redis/v9/internal/internal.go | 29 - .../redis/go-redis/v9/internal/log.go | 26 - .../redis/go-redis/v9/internal/once.go | 63 - .../redis/go-redis/v9/internal/pool/conn.go | 127 - .../go-redis/v9/internal/pool/conn_check.go | 49 - .../v9/internal/pool/conn_check_dummy.go | 9 - .../redis/go-redis/v9/internal/pool/pool.go | 518 - .../go-redis/v9/internal/pool/pool_single.go | 58 - .../go-redis/v9/internal/pool/pool_sticky.go | 201 - .../go-redis/v9/internal/proto/reader.go | 552 - .../redis/go-redis/v9/internal/proto/scan.go | 185 - .../go-redis/v9/internal/proto/writer.go | 189 - .../redis/go-redis/v9/internal/rand/rand.go | 50 - .../redis/go-redis/v9/internal/util.go | 66 - .../redis/go-redis/v9/internal/util/safe.go | 11 - .../go-redis/v9/internal/util/strconv.go | 19 - .../redis/go-redis/v9/internal/util/type.go | 5 - .../redis/go-redis/v9/internal/util/unsafe.go | 22 - .../github.com/redis/go-redis/v9/iterator.go | 66 - vendor/github.com/redis/go-redis/v9/json.go | 599 - .../redis/go-redis/v9/list_commands.go | 289 - .../github.com/redis/go-redis/v9/options.go | 518 - .../redis/go-redis/v9/osscluster.go | 1913 - .../redis/go-redis/v9/osscluster_commands.go | 109 - .../github.com/redis/go-redis/v9/pipeline.go | 121 - .../redis/go-redis/v9/probabilistic.go | 1429 - vendor/github.com/redis/go-redis/v9/pubsub.go | 729 - .../redis/go-redis/v9/pubsub_commands.go | 76 - vendor/github.com/redis/go-redis/v9/redis.go | 852 - vendor/github.com/redis/go-redis/v9/result.go | 188 - vendor/github.com/redis/go-redis/v9/ring.go | 827 - vendor/github.com/redis/go-redis/v9/script.go | 84 - .../redis/go-redis/v9/scripting_commands.go | 215 - .../github.com/redis/go-redis/v9/sentinel.go | 838 - .../redis/go-redis/v9/set_commands.go | 217 - .../redis/go-redis/v9/sortedset_commands.go | 772 - .../redis/go-redis/v9/stream_commands.go | 438 - .../redis/go-redis/v9/string_commands.go | 303 - .../redis/go-redis/v9/timeseries_commands.go | 922 - vendor/github.com/redis/go-redis/v9/tx.go | 151 - .../github.com/redis/go-redis/v9/universal.go | 247 - .../github.com/redis/go-redis/v9/version.go | 6 - vendor/github.com/rivo/uniseg/LICENSE.txt | 21 - vendor/github.com/rivo/uniseg/README.md | 62 - vendor/github.com/rivo/uniseg/doc.go | 8 - vendor/github.com/rivo/uniseg/grapheme.go | 268 - vendor/github.com/rivo/uniseg/properties.go | 1658 - vendor/github.com/rs/xid/.appveyor.yml | 27 - vendor/github.com/rs/xid/.golangci.yml | 5 - vendor/github.com/rs/xid/.travis.yml | 8 - vendor/github.com/rs/xid/LICENSE | 19 - vendor/github.com/rs/xid/README.md | 119 - vendor/github.com/rs/xid/error.go | 11 - vendor/github.com/rs/xid/hostid_darwin.go | 9 - vendor/github.com/rs/xid/hostid_fallback.go | 9 - vendor/github.com/rs/xid/hostid_freebsd.go | 9 - vendor/github.com/rs/xid/hostid_linux.go | 13 - vendor/github.com/rs/xid/hostid_windows.go | 38 - vendor/github.com/rs/xid/id.go | 391 - vendor/github.com/rs/zerolog/.gitignore | 25 - vendor/github.com/rs/zerolog/CNAME | 1 - vendor/github.com/rs/zerolog/LICENSE | 21 - vendor/github.com/rs/zerolog/README.md | 786 - vendor/github.com/rs/zerolog/_config.yml | 1 - vendor/github.com/rs/zerolog/array.go | 240 - vendor/github.com/rs/zerolog/console.go | 469 - vendor/github.com/rs/zerolog/context.go | 474 - vendor/github.com/rs/zerolog/ctx.go | 52 - vendor/github.com/rs/zerolog/encoder.go | 56 - vendor/github.com/rs/zerolog/encoder_cbor.go | 45 - vendor/github.com/rs/zerolog/encoder_json.go | 51 - vendor/github.com/rs/zerolog/event.go | 830 - vendor/github.com/rs/zerolog/example.jsonl | 7 - vendor/github.com/rs/zerolog/fields.go | 292 - vendor/github.com/rs/zerolog/globals.go | 170 - vendor/github.com/rs/zerolog/go112.go | 7 - vendor/github.com/rs/zerolog/hook.go | 64 - .../rs/zerolog/internal/cbor/README.md | 56 - .../rs/zerolog/internal/cbor/base.go | 19 - .../rs/zerolog/internal/cbor/cbor.go | 102 - .../rs/zerolog/internal/cbor/decode_stream.go | 654 - .../rs/zerolog/internal/cbor/string.go | 117 - .../rs/zerolog/internal/cbor/time.go | 93 - .../rs/zerolog/internal/cbor/types.go | 486 - .../rs/zerolog/internal/json/base.go | 19 - .../rs/zerolog/internal/json/bytes.go | 85 - .../rs/zerolog/internal/json/string.go | 149 - .../rs/zerolog/internal/json/time.go | 113 - .../rs/zerolog/internal/json/types.go | 414 - vendor/github.com/rs/zerolog/log.go | 518 - vendor/github.com/rs/zerolog/log/log.go | 131 - vendor/github.com/rs/zerolog/not_go112.go | 5 - vendor/github.com/rs/zerolog/pretty.png | Bin 118839 -> 0 bytes vendor/github.com/rs/zerolog/sampler.go | 134 - vendor/github.com/rs/zerolog/syslog.go | 89 - vendor/github.com/rs/zerolog/writer.go | 346 - .../ryancurrah/gomodguard/.dockerignore | 1 - .../ryancurrah/gomodguard/.gitignore | 25 - .../ryancurrah/gomodguard/.golangci.yml | 23 - .../ryancurrah/gomodguard/.goreleaser.yml | 37 - .../ryancurrah/gomodguard/Dockerfile | 13 - .../gomodguard/Dockerfile.goreleaser | 6 - .../github.com/ryancurrah/gomodguard/LICENSE | 21 - .../github.com/ryancurrah/gomodguard/Makefile | 46 - .../ryancurrah/gomodguard/README.md | 131 - .../ryancurrah/gomodguard/allowed.go | 39 - .../ryancurrah/gomodguard/blocked.go | 187 - .../github.com/ryancurrah/gomodguard/issue.go | 20 - .../ryancurrah/gomodguard/processor.go | 306 - .../ryanrolds/sqlclosecheck/LICENSE | 19 - .../sqlclosecheck/pkg/analyzer/analyzer.go | 405 - .../sanposhiho/wastedassign/v2/LICENSE | 21 - .../sanposhiho/wastedassign/v2/README.md | 75 - .../wastedassign/v2/wastedassign.go | 272 - .../santhosh-tekuri/jsonschema/v5/.gitignore | 4 - .../santhosh-tekuri/jsonschema/v5/.gitmodules | 3 - .../santhosh-tekuri/jsonschema/v5/LICENSE | 175 - .../santhosh-tekuri/jsonschema/v5/README.md | 220 - .../santhosh-tekuri/jsonschema/v5/compiler.go | 812 - .../santhosh-tekuri/jsonschema/v5/content.go | 29 - .../santhosh-tekuri/jsonschema/v5/doc.go | 49 - .../santhosh-tekuri/jsonschema/v5/draft.go | 1454 - .../santhosh-tekuri/jsonschema/v5/errors.go | 129 - .../jsonschema/v5/extension.go | 116 - .../santhosh-tekuri/jsonschema/v5/format.go | 567 - .../jsonschema/v5/httploader/httploader.go | 38 - .../santhosh-tekuri/jsonschema/v5/loader.go | 60 - .../santhosh-tekuri/jsonschema/v5/output.go | 77 - .../santhosh-tekuri/jsonschema/v5/resource.go | 280 - .../santhosh-tekuri/jsonschema/v5/schema.go | 900 - .../sashamelentyev/interfacebloat/LICENSE | 21 - .../interfacebloat/pkg/analyzer/analyzer.go | 57 - .../sashamelentyev/usestdlibvars/LICENSE | 21 - .../usestdlibvars/pkg/analyzer/analyzer.go | 519 - .../pkg/analyzer/internal/mapping/mapping.go | 202 - .../github.com/securego/gosec/v2/.gitignore | 40 - .../securego/gosec/v2/.golangci.yml | 49 - .../securego/gosec/v2/.goreleaser.yml | 37 - .../github.com/securego/gosec/v2/Dockerfile | 15 - .../github.com/securego/gosec/v2/LICENSE.txt | 154 - vendor/github.com/securego/gosec/v2/Makefile | 98 - vendor/github.com/securego/gosec/v2/README.md | 491 - vendor/github.com/securego/gosec/v2/USERS.md | 30 - .../github.com/securego/gosec/v2/action.yml | 19 - .../github.com/securego/gosec/v2/analyzer.go | 718 - .../gosec/v2/analyzers/analyzers_set.go | 38 - .../gosec/v2/analyzers/analyzerslist.go | 95 - .../gosec/v2/analyzers/conversion_overflow.go | 526 - .../gosec/v2/analyzers/hardcodedNonce.go | 246 - .../gosec/v2/analyzers/slice_bounds.go | 399 - .../securego/gosec/v2/analyzers/util.go | 100 - .../github.com/securego/gosec/v2/call_list.go | 118 - vendor/github.com/securego/gosec/v2/config.go | 137 - .../github.com/securego/gosec/v2/cosign.pub | 4 - .../github.com/securego/gosec/v2/cwe/data.go | 150 - .../github.com/securego/gosec/v2/cwe/types.go | 38 - .../securego/gosec/v2/entrypoint.sh | 11 - vendor/github.com/securego/gosec/v2/errors.go | 33 - .../github.com/securego/gosec/v2/helpers.go | 555 - .../securego/gosec/v2/import_tracker.go | 78 - .../github.com/securego/gosec/v2/install.sh | 377 - .../securego/gosec/v2/issue/issue.go | 232 - .../github.com/securego/gosec/v2/perf-diff.sh | 44 - .../securego/gosec/v2/renovate.json | 25 - vendor/github.com/securego/gosec/v2/report.go | 28 - .../github.com/securego/gosec/v2/resolve.go | 95 - vendor/github.com/securego/gosec/v2/rule.go | 72 - .../securego/gosec/v2/rules/archive.go | 66 - .../securego/gosec/v2/rules/bind.go | 84 - .../securego/gosec/v2/rules/blocklist.go | 109 - .../gosec/v2/rules/decompression-bomb.go | 111 - .../gosec/v2/rules/directory-traversal.go | 65 - .../securego/gosec/v2/rules/errors.go | 122 - .../securego/gosec/v2/rules/fileperms.go | 176 - .../gosec/v2/rules/hardcoded_credentials.go | 394 - .../securego/gosec/v2/rules/http_serve.go | 39 - .../gosec/v2/rules/implicit_aliasing.go | 148 - .../gosec/v2/rules/integer_overflow.go | 90 - .../securego/gosec/v2/rules/math_big_rat.go | 45 - .../securego/gosec/v2/rules/pprof.go | 43 - .../securego/gosec/v2/rules/rand.go | 63 - .../securego/gosec/v2/rules/readfile.go | 153 - .../github.com/securego/gosec/v2/rules/rsa.go | 59 - .../securego/gosec/v2/rules/rulelist.go | 134 - .../securego/gosec/v2/rules/slowloris.go | 71 - .../github.com/securego/gosec/v2/rules/sql.go | 405 - .../github.com/securego/gosec/v2/rules/ssh.go | 39 - .../securego/gosec/v2/rules/ssrf.go | 67 - .../securego/gosec/v2/rules/subproc.go | 123 - .../securego/gosec/v2/rules/tempfiles.go | 88 - .../securego/gosec/v2/rules/templates.go | 64 - .../github.com/securego/gosec/v2/rules/tls.go | 239 - .../securego/gosec/v2/rules/tls_config.go | 93 - .../securego/gosec/v2/rules/unsafe.go | 54 - .../securego/gosec/v2/rules/weakcrypto.go | 57 - .../securego/gosec/v2/rules/weakcryptohash.go | 55 - .../v2/rules/weakdepricatedcryptohash.go | 57 - vendor/github.com/shazow/go-diff/LICENSE | 22 - .../shazow/go-diff/difflib/differ.go | 39 - .../github.com/shopspring/decimal/.gitignore | 9 - .../github.com/shopspring/decimal/.travis.yml | 19 - .../shopspring/decimal/CHANGELOG.md | 49 - vendor/github.com/shopspring/decimal/LICENSE | 45 - .../github.com/shopspring/decimal/README.md | 130 - .../shopspring/decimal/decimal-go.go | 415 - .../github.com/shopspring/decimal/decimal.go | 1904 - .../github.com/shopspring/decimal/rounding.go | 160 - vendor/github.com/sirupsen/logrus/.gitignore | 4 - .../github.com/sirupsen/logrus/.golangci.yml | 40 - vendor/github.com/sirupsen/logrus/.travis.yml | 15 - .../github.com/sirupsen/logrus/CHANGELOG.md | 259 - vendor/github.com/sirupsen/logrus/LICENSE | 21 - vendor/github.com/sirupsen/logrus/README.md | 515 - vendor/github.com/sirupsen/logrus/alt_exit.go | 76 - .../github.com/sirupsen/logrus/appveyor.yml | 14 - .../github.com/sirupsen/logrus/buffer_pool.go | 43 - vendor/github.com/sirupsen/logrus/doc.go | 26 - vendor/github.com/sirupsen/logrus/entry.go | 442 - vendor/github.com/sirupsen/logrus/exported.go | 270 - .../github.com/sirupsen/logrus/formatter.go | 78 - vendor/github.com/sirupsen/logrus/hooks.go | 34 - .../sirupsen/logrus/json_formatter.go | 128 - vendor/github.com/sirupsen/logrus/logger.go | 417 - vendor/github.com/sirupsen/logrus/logrus.go | 186 - .../logrus/terminal_check_appengine.go | 11 - .../sirupsen/logrus/terminal_check_bsd.go | 13 - .../sirupsen/logrus/terminal_check_js.go | 7 - .../logrus/terminal_check_no_terminal.go | 11 - .../logrus/terminal_check_notappengine.go | 17 - .../sirupsen/logrus/terminal_check_solaris.go | 11 - .../sirupsen/logrus/terminal_check_unix.go | 13 - .../sirupsen/logrus/terminal_check_windows.go | 27 - .../sirupsen/logrus/text_formatter.go | 339 - vendor/github.com/sirupsen/logrus/writer.go | 102 - .../sivchari/containedctx/.golangci.yml | 38 - .../github.com/sivchari/containedctx/LICENCE | 21 - .../sivchari/containedctx/README.md | 64 - .../sivchari/containedctx/containedctx.go | 45 - vendor/github.com/sivchari/tenv/.gitignore | 17 - vendor/github.com/sivchari/tenv/.golangci.yml | 38 - vendor/github.com/sivchari/tenv/LICENSE | 21 - vendor/github.com/sivchari/tenv/README.md | 107 - vendor/github.com/sivchari/tenv/tenv.go | 244 - vendor/github.com/sivchari/tenv/tenv.png | Bin 247119 -> 0 bytes vendor/github.com/sonatard/noctx/.gitignore | 1 - .../github.com/sonatard/noctx/.golangci.yml | 14 - vendor/github.com/sonatard/noctx/LICENSE | 21 - vendor/github.com/sonatard/noctx/Makefile | 16 - vendor/github.com/sonatard/noctx/README.md | 174 - .../github.com/sonatard/noctx/ngfunc/main.go | 61 - .../sonatard/noctx/ngfunc/report.go | 29 - .../github.com/sonatard/noctx/ngfunc/types.go | 65 - vendor/github.com/sonatard/noctx/noctx.go | 35 - .../sonatard/noctx/reqwithoutctx/main.go | 14 - .../sonatard/noctx/reqwithoutctx/report.go | 26 - .../sonatard/noctx/reqwithoutctx/ssa.go | 185 - vendor/github.com/sony/gobreaker/LICENSE | 21 - vendor/github.com/sony/gobreaker/README.md | 132 - vendor/github.com/sony/gobreaker/gobreaker.go | 380 - vendor/github.com/sourcegraph/go-diff/LICENSE | 46 - .../sourcegraph/go-diff/diff/diff.go | 136 - .../sourcegraph/go-diff/diff/doc.go | 2 - .../sourcegraph/go-diff/diff/parse.go | 865 - .../sourcegraph/go-diff/diff/print.go | 141 - .../sourcegraph/go-diff/diff/reader_util.go | 120 - vendor/github.com/spf13/afero/.gitignore | 2 - vendor/github.com/spf13/afero/LICENSE.txt | 174 - vendor/github.com/spf13/afero/README.md | 442 - vendor/github.com/spf13/afero/afero.go | 111 - vendor/github.com/spf13/afero/appveyor.yml | 10 - vendor/github.com/spf13/afero/basepath.go | 222 - .../github.com/spf13/afero/cacheOnReadFs.go | 315 - vendor/github.com/spf13/afero/const_bsds.go | 23 - .../github.com/spf13/afero/const_win_unix.go | 22 - .../github.com/spf13/afero/copyOnWriteFs.go | 327 - vendor/github.com/spf13/afero/httpFs.go | 114 - .../spf13/afero/internal/common/adapters.go | 27 - vendor/github.com/spf13/afero/iofs.go | 298 - vendor/github.com/spf13/afero/ioutil.go | 243 - vendor/github.com/spf13/afero/lstater.go | 27 - vendor/github.com/spf13/afero/match.go | 110 - vendor/github.com/spf13/afero/mem/dir.go | 37 - vendor/github.com/spf13/afero/mem/dirmap.go | 43 - vendor/github.com/spf13/afero/mem/file.go | 359 - vendor/github.com/spf13/afero/memmap.go | 465 - vendor/github.com/spf13/afero/os.go | 113 - vendor/github.com/spf13/afero/path.go | 106 - vendor/github.com/spf13/afero/readonlyfs.go | 96 - vendor/github.com/spf13/afero/regexpfs.go | 223 - vendor/github.com/spf13/afero/symlink.go | 55 - vendor/github.com/spf13/afero/unionFile.go | 330 - vendor/github.com/spf13/afero/util.go | 329 - vendor/github.com/spf13/cast/.gitignore | 25 - vendor/github.com/spf13/cast/LICENSE | 21 - vendor/github.com/spf13/cast/Makefile | 40 - vendor/github.com/spf13/cast/README.md | 75 - vendor/github.com/spf13/cast/cast.go | 176 - vendor/github.com/spf13/cast/caste.go | 1476 - .../spf13/cast/timeformattype_string.go | 27 - vendor/github.com/spf13/cobra/.gitignore | 39 - vendor/github.com/spf13/cobra/.golangci.yml | 57 - vendor/github.com/spf13/cobra/.mailmap | 3 - vendor/github.com/spf13/cobra/CONDUCT.md | 37 - vendor/github.com/spf13/cobra/CONTRIBUTING.md | 50 - vendor/github.com/spf13/cobra/LICENSE.txt | 174 - vendor/github.com/spf13/cobra/MAINTAINERS | 13 - vendor/github.com/spf13/cobra/Makefile | 35 - vendor/github.com/spf13/cobra/README.md | 112 - vendor/github.com/spf13/cobra/active_help.go | 60 - vendor/github.com/spf13/cobra/args.go | 131 - .../spf13/cobra/bash_completions.go | 709 - .../spf13/cobra/bash_completionsV2.go | 396 - vendor/github.com/spf13/cobra/cobra.go | 242 - vendor/github.com/spf13/cobra/command.go | 1896 - .../github.com/spf13/cobra/command_notwin.go | 20 - vendor/github.com/spf13/cobra/command_win.go | 41 - vendor/github.com/spf13/cobra/completions.go | 939 - .../spf13/cobra/fish_completions.go | 292 - vendor/github.com/spf13/cobra/flag_groups.go | 290 - .../spf13/cobra/powershell_completions.go | 325 - .../spf13/cobra/shell_completions.go | 98 - .../github.com/spf13/cobra/zsh_completions.go | 308 - .../spf13/jwalterweatherman/.gitignore | 24 - .../spf13/jwalterweatherman/LICENSE | 21 - .../spf13/jwalterweatherman/README.md | 148 - .../jwalterweatherman/default_notepad.go | 111 - .../spf13/jwalterweatherman/log_counter.go | 46 - .../spf13/jwalterweatherman/notepad.go | 225 - vendor/github.com/spf13/pflag/.gitignore | 2 - vendor/github.com/spf13/pflag/.travis.yml | 22 - vendor/github.com/spf13/pflag/LICENSE | 28 - vendor/github.com/spf13/pflag/README.md | 296 - vendor/github.com/spf13/pflag/bool.go | 94 - vendor/github.com/spf13/pflag/bool_slice.go | 185 - vendor/github.com/spf13/pflag/bytes.go | 209 - vendor/github.com/spf13/pflag/count.go | 96 - vendor/github.com/spf13/pflag/duration.go | 86 - .../github.com/spf13/pflag/duration_slice.go | 166 - vendor/github.com/spf13/pflag/flag.go | 1239 - vendor/github.com/spf13/pflag/float32.go | 88 - .../github.com/spf13/pflag/float32_slice.go | 174 - vendor/github.com/spf13/pflag/float64.go | 84 - .../github.com/spf13/pflag/float64_slice.go | 166 - vendor/github.com/spf13/pflag/golangflag.go | 105 - vendor/github.com/spf13/pflag/int.go | 84 - vendor/github.com/spf13/pflag/int16.go | 88 - vendor/github.com/spf13/pflag/int32.go | 88 - vendor/github.com/spf13/pflag/int32_slice.go | 174 - vendor/github.com/spf13/pflag/int64.go | 84 - vendor/github.com/spf13/pflag/int64_slice.go | 166 - vendor/github.com/spf13/pflag/int8.go | 88 - vendor/github.com/spf13/pflag/int_slice.go | 158 - vendor/github.com/spf13/pflag/ip.go | 94 - vendor/github.com/spf13/pflag/ip_slice.go | 186 - vendor/github.com/spf13/pflag/ipmask.go | 122 - vendor/github.com/spf13/pflag/ipnet.go | 98 - vendor/github.com/spf13/pflag/string.go | 80 - vendor/github.com/spf13/pflag/string_array.go | 129 - vendor/github.com/spf13/pflag/string_slice.go | 163 - .../github.com/spf13/pflag/string_to_int.go | 149 - .../github.com/spf13/pflag/string_to_int64.go | 149 - .../spf13/pflag/string_to_string.go | 160 - vendor/github.com/spf13/pflag/uint.go | 88 - vendor/github.com/spf13/pflag/uint16.go | 88 - vendor/github.com/spf13/pflag/uint32.go | 88 - vendor/github.com/spf13/pflag/uint64.go | 88 - vendor/github.com/spf13/pflag/uint8.go | 88 - vendor/github.com/spf13/pflag/uint_slice.go | 168 - vendor/github.com/spf13/viper/.editorconfig | 15 - vendor/github.com/spf13/viper/.gitignore | 5 - vendor/github.com/spf13/viper/.golangci.yaml | 96 - vendor/github.com/spf13/viper/LICENSE | 21 - vendor/github.com/spf13/viper/Makefile | 76 - vendor/github.com/spf13/viper/README.md | 874 - .../github.com/spf13/viper/TROUBLESHOOTING.md | 32 - .../spf13/viper/experimental_logger.go | 11 - vendor/github.com/spf13/viper/flags.go | 57 - vendor/github.com/spf13/viper/fs.go | 65 - .../spf13/viper/internal/encoding/decoder.go | 61 - .../viper/internal/encoding/dotenv/codec.go | 61 - .../internal/encoding/dotenv/map_utils.go | 41 - .../spf13/viper/internal/encoding/encoder.go | 60 - .../spf13/viper/internal/encoding/error.go | 7 - .../viper/internal/encoding/hcl/codec.go | 40 - .../viper/internal/encoding/ini/codec.go | 99 - .../viper/internal/encoding/ini/map_utils.go | 74 - .../internal/encoding/javaproperties/codec.go | 86 - .../encoding/javaproperties/map_utils.go | 74 - .../viper/internal/encoding/json/codec.go | 17 - .../viper/internal/encoding/toml/codec.go | 39 - .../viper/internal/encoding/toml/codec2.go | 19 - .../viper/internal/encoding/yaml/codec.go | 14 - .../viper/internal/encoding/yaml/yaml2.go | 14 - .../viper/internal/encoding/yaml/yaml3.go | 14 - vendor/github.com/spf13/viper/logger.go | 77 - vendor/github.com/spf13/viper/util.go | 204 - vendor/github.com/spf13/viper/viper.go | 2124 -- vendor/github.com/spf13/viper/viper_go1_15.go | 57 - vendor/github.com/spf13/viper/viper_go1_16.go | 32 - vendor/github.com/spf13/viper/watch.go | 12 - vendor/github.com/spf13/viper/watch_wasm.go | 30 - vendor/github.com/ssgreg/nlreturn/v2/LICENSE | 21 - .../nlreturn/v2/pkg/nlreturn/nlreturn.go | 95 - .../stbenjam/no-sprintf-host-port/LICENSE | 21 - .../pkg/analyzer/analyzer.go | 96 - .../github.com/stretchr/objx/.codeclimate.yml | 21 - vendor/github.com/stretchr/objx/.gitignore | 11 - vendor/github.com/stretchr/objx/LICENSE | 22 - vendor/github.com/stretchr/objx/README.md | 80 - vendor/github.com/stretchr/objx/Taskfile.yml | 27 - vendor/github.com/stretchr/objx/accessors.go | 197 - .../github.com/stretchr/objx/conversions.go | 280 - vendor/github.com/stretchr/objx/doc.go | 66 - vendor/github.com/stretchr/objx/map.go | 214 - vendor/github.com/stretchr/objx/mutations.go | 77 - vendor/github.com/stretchr/objx/security.go | 12 - vendor/github.com/stretchr/objx/tests.go | 17 - .../github.com/stretchr/objx/type_specific.go | 346 - .../stretchr/objx/type_specific_codegen.go | 2261 -- vendor/github.com/stretchr/objx/value.go | 159 - vendor/github.com/stretchr/testify/LICENSE | 21 - .../testify/assert/assertion_compare.go | 480 - .../testify/assert/assertion_format.go | 815 - .../testify/assert/assertion_format.go.tmpl | 5 - .../testify/assert/assertion_forward.go | 1621 - .../testify/assert/assertion_forward.go.tmpl | 5 - .../testify/assert/assertion_order.go | 81 - .../stretchr/testify/assert/assertions.go | 2105 -- .../github.com/stretchr/testify/assert/doc.go | 46 - .../stretchr/testify/assert/errors.go | 10 - .../testify/assert/forward_assertions.go | 16 - .../testify/assert/http_assertions.go | 165 - .../github.com/stretchr/testify/mock/doc.go | 44 - .../github.com/stretchr/testify/mock/mock.go | 1241 - .../stretchr/testify/require/doc.go | 29 - .../testify/require/forward_requirements.go | 16 - .../stretchr/testify/require/require.go | 2060 - .../stretchr/testify/require/require.go.tmpl | 6 - .../testify/require/require_forward.go | 1622 - .../testify/require/require_forward.go.tmpl | 5 - .../stretchr/testify/require/requirements.go | 29 - .../github.com/stretchr/testify/suite/doc.go | 66 - .../stretchr/testify/suite/interfaces.go | 66 - .../stretchr/testify/suite/stats.go | 46 - .../stretchr/testify/suite/suite.go | 253 - vendor/github.com/subosito/gotenv/.env | 1 - .../github.com/subosito/gotenv/.env.invalid | 1 - vendor/github.com/subosito/gotenv/.gitignore | 4 - .../github.com/subosito/gotenv/.golangci.yaml | 7 - .../github.com/subosito/gotenv/CHANGELOG.md | 68 - vendor/github.com/subosito/gotenv/LICENSE | 21 - vendor/github.com/subosito/gotenv/README.md | 129 - vendor/github.com/subosito/gotenv/gotenv.go | 369 - .../github.com/tdakkota/asciicheck/.gitignore | 32 - vendor/github.com/tdakkota/asciicheck/LICENSE | 21 - .../github.com/tdakkota/asciicheck/README.md | 72 - .../github.com/tdakkota/asciicheck/ascii.go | 21 - .../tdakkota/asciicheck/asciicheck.go | 49 - vendor/github.com/tetafro/godot/.gitignore | 5 - vendor/github.com/tetafro/godot/.godot.yaml | 16 - vendor/github.com/tetafro/godot/.golangci.yml | 79 - .../github.com/tetafro/godot/.goreleaser.yml | 11 - vendor/github.com/tetafro/godot/LICENSE | 21 - vendor/github.com/tetafro/godot/Makefile | 25 - vendor/github.com/tetafro/godot/README.md | 84 - vendor/github.com/tetafro/godot/checks.go | 297 - vendor/github.com/tetafro/godot/getters.go | 289 - vendor/github.com/tetafro/godot/godot.go | 129 - vendor/github.com/tetafro/godot/settings.go | 29 - vendor/github.com/timakin/bodyclose/LICENSE | 21 - .../bodyclose/passes/bodyclose/bodyclose.go | 388 - .../timonwong/loggercheck/.codecov.yml | 16 - .../timonwong/loggercheck/.gitignore | 9 - .../timonwong/loggercheck/.golangci.yml | 94 - .../timonwong/loggercheck/.goreleaser.yml | 59 - .../github.com/timonwong/loggercheck/LICENSE | 21 - .../github.com/timonwong/loggercheck/Makefile | 22 - .../timonwong/loggercheck/README.md | 103 - .../internal/bytebufferpool/pool.go | 22 - .../loggercheck/internal/checkers/checker.go | 59 - .../loggercheck/internal/checkers/common.go | 49 - .../loggercheck/internal/checkers/general.go | 68 - .../internal/checkers/printf/printf.go | 252 - .../loggercheck/internal/checkers/zap.go | 42 - .../loggercheck/internal/rules/rules.go | 201 - .../loggercheck/internal/sets/string.go | 59 - .../loggercheck/internal/stringutil/is.go | 15 - .../timonwong/loggercheck/loggercheck.go | 196 - .../timonwong/loggercheck/options.go | 31 - .../timonwong/loggercheck/staticrules.go | 68 - .../github.com/tomarrell/wrapcheck/v2/LICENSE | 21 - .../wrapcheck/v2/wrapcheck/wrapcheck.go | 463 - .../tommy-muehle/go-mnd/v2/.editorconfig | 21 - .../tommy-muehle/go-mnd/v2/.gitattributes | 9 - .../tommy-muehle/go-mnd/v2/.gitignore | 3 - .../tommy-muehle/go-mnd/v2/.goreleaser.yml | 54 - .../tommy-muehle/go-mnd/v2/Dockerfile | 17 - .../github.com/tommy-muehle/go-mnd/v2/LICENSE | 21 - .../tommy-muehle/go-mnd/v2/Makefile | 32 - .../tommy-muehle/go-mnd/v2/README.md | 230 - .../tommy-muehle/go-mnd/v2/action.yml | 19 - .../tommy-muehle/go-mnd/v2/analyzer.go | 118 - .../tommy-muehle/go-mnd/v2/checks/argument.go | 125 - .../tommy-muehle/go-mnd/v2/checks/assign.go | 86 - .../tommy-muehle/go-mnd/v2/checks/case.go | 68 - .../tommy-muehle/go-mnd/v2/checks/checks.go | 3 - .../go-mnd/v2/checks/condition.go | 55 - .../go-mnd/v2/checks/operation.go | 77 - .../tommy-muehle/go-mnd/v2/checks/return.go | 68 - .../tommy-muehle/go-mnd/v2/config/config.go | 124 - .../tommy-muehle/go-mnd/v2/entrypoint.sh | 7 - vendor/github.com/ultraware/funlen/LICENSE | 7 - vendor/github.com/ultraware/funlen/README.md | 47 - vendor/github.com/ultraware/funlen/main.go | 124 - .../github.com/ultraware/whitespace/LICENSE | 7 - .../github.com/ultraware/whitespace/README.md | 9 - .../ultraware/whitespace/whitespace.go | 307 - vendor/github.com/uudashr/gocognit/LICENSE | 21 - vendor/github.com/uudashr/gocognit/README.md | 228 - vendor/github.com/uudashr/gocognit/doc.go | 2 - .../github.com/uudashr/gocognit/gocognit.go | 399 - vendor/github.com/uudashr/gocognit/recv.go | 24 - .../uudashr/gocognit/recv_pre118.go | 20 - .../xen0n/gosmopolitan/.editorconfig | 23 - .../github.com/xen0n/gosmopolitan/.gitignore | 188 - .../xen0n/gosmopolitan/.golangci.yml | 31 - vendor/github.com/xen0n/gosmopolitan/LICENSE | 674 - .../github.com/xen0n/gosmopolitan/README.md | 84 - .../xen0n/gosmopolitan/README.zh-Hans.md | 69 - vendor/github.com/xen0n/gosmopolitan/lib.go | 385 - vendor/github.com/yagipy/maintidx/.gitignore | 2 - vendor/github.com/yagipy/maintidx/LICENSE | 21 - vendor/github.com/yagipy/maintidx/Makefile | 2 - vendor/github.com/yagipy/maintidx/README.md | 45 - vendor/github.com/yagipy/maintidx/maintidx.go | 63 - .../github.com/yagipy/maintidx/pkg/cyc/cyc.go | 36 - .../yagipy/maintidx/pkg/halstvol/halstvol.go | 71 - .../yagipy/maintidx/pkg/halstvol/handle.go | 151 - vendor/github.com/yagipy/maintidx/visitor.go | 77 - .../github.com/yeya24/promlinter/.gitignore | 20 - vendor/github.com/yeya24/promlinter/LICENSE | 201 - vendor/github.com/yeya24/promlinter/Makefile | 39 - vendor/github.com/yeya24/promlinter/README.md | 80 - .../yeya24/promlinter/promlinter.go | 831 - .../ykadowak/zerologlint/.goreleaser.yaml | 24 - .../github.com/ykadowak/zerologlint/LICENSE | 21 - .../github.com/ykadowak/zerologlint/README.md | 63 - .../ykadowak/zerologlint/zerologlint.go | 261 - vendor/github.com/yuin/gopher-lua/LICENSE | 21 - vendor/github.com/yuin/gopher-lua/Makefile | 10 - vendor/github.com/yuin/gopher-lua/README.rst | 890 - vendor/github.com/yuin/gopher-lua/_state.go | 2085 -- vendor/github.com/yuin/gopher-lua/_vm.go | 1033 - vendor/github.com/yuin/gopher-lua/alloc.go | 79 - vendor/github.com/yuin/gopher-lua/ast/ast.go | 29 - vendor/github.com/yuin/gopher-lua/ast/expr.go | 138 - vendor/github.com/yuin/gopher-lua/ast/misc.go | 17 - vendor/github.com/yuin/gopher-lua/ast/stmt.go | 107 - .../github.com/yuin/gopher-lua/ast/token.go | 22 - vendor/github.com/yuin/gopher-lua/auxlib.go | 460 - vendor/github.com/yuin/gopher-lua/baselib.go | 597 - .../github.com/yuin/gopher-lua/channellib.go | 184 - vendor/github.com/yuin/gopher-lua/compile.go | 1869 - vendor/github.com/yuin/gopher-lua/config.go | 43 - .../yuin/gopher-lua/coroutinelib.go | 112 - vendor/github.com/yuin/gopher-lua/debuglib.go | 173 - vendor/github.com/yuin/gopher-lua/function.go | 193 - vendor/github.com/yuin/gopher-lua/iolib.go | 746 - vendor/github.com/yuin/gopher-lua/linit.go | 54 - vendor/github.com/yuin/gopher-lua/loadlib.go | 128 - vendor/github.com/yuin/gopher-lua/mathlib.go | 231 - vendor/github.com/yuin/gopher-lua/opcode.go | 371 - vendor/github.com/yuin/gopher-lua/oslib.go | 232 - vendor/github.com/yuin/gopher-lua/package.go | 7 - .../github.com/yuin/gopher-lua/parse/Makefile | 7 - .../github.com/yuin/gopher-lua/parse/lexer.go | 549 - .../yuin/gopher-lua/parse/parser.go | 1385 - .../yuin/gopher-lua/parse/parser.go.y | 535 - vendor/github.com/yuin/gopher-lua/pm/pm.go | 638 - vendor/github.com/yuin/gopher-lua/state.go | 2244 -- .../github.com/yuin/gopher-lua/stringlib.go | 448 - vendor/github.com/yuin/gopher-lua/table.go | 387 - vendor/github.com/yuin/gopher-lua/tablelib.go | 100 - vendor/github.com/yuin/gopher-lua/utils.go | 265 - vendor/github.com/yuin/gopher-lua/value.go | 247 - vendor/github.com/yuin/gopher-lua/vm.go | 1726 - vendor/github.com/zenazn/goji/LICENSE | 20 - .../github.com/zenazn/goji/web/mutil/mutil.go | 3 - .../zenazn/goji/web/mutil/writer_proxy.go | 151 - .../goji/web/mutil/writer_proxy_go1_8.go | 136 - vendor/gitlab.com/bosi/decorder/.gitignore | 7 - .../bosi/decorder/.gitlab-ci.params.yml | 15 - .../gitlab.com/bosi/decorder/.gitlab-ci.yml | 63 - vendor/gitlab.com/bosi/decorder/LICENSE.md | 16 - vendor/gitlab.com/bosi/decorder/Makefile | 7 - vendor/gitlab.com/bosi/decorder/README.md | 50 - vendor/gitlab.com/bosi/decorder/analyzer.go | 255 - vendor/gitlab.com/bosi/decorder/renovate.json | 7 - vendor/go-simpler.org/musttag/.golangci.yml | 23 - vendor/go-simpler.org/musttag/.goreleaser.yml | 18 - vendor/go-simpler.org/musttag/LICENSE | 373 - vendor/go-simpler.org/musttag/Makefile | 28 - vendor/go-simpler.org/musttag/README.md | 102 - vendor/go-simpler.org/musttag/builtins.go | 133 - vendor/go-simpler.org/musttag/musttag.go | 282 - vendor/go-simpler.org/musttag/utils.go | 49 - vendor/go-simpler.org/sloglint/.golangci.yml | 22 - .../go-simpler.org/sloglint/.goreleaser.yml | 18 - vendor/go-simpler.org/sloglint/LICENSE | 373 - vendor/go-simpler.org/sloglint/Makefile | 28 - vendor/go-simpler.org/sloglint/README.md | 186 - vendor/go-simpler.org/sloglint/sloglint.go | 426 - vendor/go.uber.org/atomic/.codecov.yml | 19 - vendor/go.uber.org/atomic/.gitignore | 12 - vendor/go.uber.org/atomic/.travis.yml | 27 - vendor/go.uber.org/atomic/CHANGELOG.md | 76 - vendor/go.uber.org/atomic/LICENSE.txt | 19 - vendor/go.uber.org/atomic/Makefile | 78 - vendor/go.uber.org/atomic/README.md | 63 - vendor/go.uber.org/atomic/bool.go | 81 - vendor/go.uber.org/atomic/bool_ext.go | 53 - vendor/go.uber.org/atomic/doc.go | 23 - vendor/go.uber.org/atomic/duration.go | 82 - vendor/go.uber.org/atomic/duration_ext.go | 40 - vendor/go.uber.org/atomic/error.go | 51 - vendor/go.uber.org/atomic/error_ext.go | 39 - vendor/go.uber.org/atomic/float64.go | 76 - vendor/go.uber.org/atomic/float64_ext.go | 47 - vendor/go.uber.org/atomic/gen.go | 26 - vendor/go.uber.org/atomic/int32.go | 102 - vendor/go.uber.org/atomic/int64.go | 102 - vendor/go.uber.org/atomic/nocmp.go | 35 - vendor/go.uber.org/atomic/string.go | 54 - vendor/go.uber.org/atomic/string_ext.go | 43 - vendor/go.uber.org/atomic/uint32.go | 102 - vendor/go.uber.org/atomic/uint64.go | 102 - vendor/go.uber.org/atomic/value.go | 31 - vendor/go.uber.org/automaxprocs/LICENSE | 19 - .../automaxprocs/internal/cgroups/cgroup.go | 79 - .../automaxprocs/internal/cgroups/cgroups.go | 118 - .../automaxprocs/internal/cgroups/cgroups2.go | 176 - .../automaxprocs/internal/cgroups/doc.go | 23 - .../automaxprocs/internal/cgroups/errors.go | 52 - .../internal/cgroups/mountpoint.go | 171 - .../automaxprocs/internal/cgroups/subsys.go | 103 - .../internal/runtime/cpu_quota_linux.go | 71 - .../internal/runtime/cpu_quota_unsupported.go | 31 - .../automaxprocs/internal/runtime/runtime.go | 33 - .../automaxprocs/maxprocs/maxprocs.go | 130 - .../automaxprocs/maxprocs/version.go | 24 - vendor/go.uber.org/multierr/.codecov.yml | 15 - vendor/go.uber.org/multierr/.gitignore | 4 - vendor/go.uber.org/multierr/.travis.yml | 23 - vendor/go.uber.org/multierr/CHANGELOG.md | 60 - vendor/go.uber.org/multierr/LICENSE.txt | 19 - vendor/go.uber.org/multierr/Makefile | 42 - vendor/go.uber.org/multierr/README.md | 23 - vendor/go.uber.org/multierr/error.go | 449 - vendor/go.uber.org/multierr/glide.yaml | 8 - vendor/go.uber.org/multierr/go113.go | 52 - vendor/go.uber.org/zap/.codecov.yml | 17 - vendor/go.uber.org/zap/.gitignore | 32 - vendor/go.uber.org/zap/.readme.tmpl | 109 - vendor/go.uber.org/zap/CHANGELOG.md | 617 - vendor/go.uber.org/zap/CODE_OF_CONDUCT.md | 75 - vendor/go.uber.org/zap/CONTRIBUTING.md | 70 - vendor/go.uber.org/zap/FAQ.md | 164 - vendor/go.uber.org/zap/LICENSE.txt | 19 - vendor/go.uber.org/zap/Makefile | 73 - vendor/go.uber.org/zap/README.md | 133 - vendor/go.uber.org/zap/array.go | 320 - vendor/go.uber.org/zap/array_go118.go | 156 - vendor/go.uber.org/zap/buffer/buffer.go | 141 - vendor/go.uber.org/zap/buffer/pool.go | 49 - vendor/go.uber.org/zap/checklicense.sh | 17 - vendor/go.uber.org/zap/config.go | 264 - vendor/go.uber.org/zap/doc.go | 117 - vendor/go.uber.org/zap/encoder.go | 79 - vendor/go.uber.org/zap/error.go | 80 - vendor/go.uber.org/zap/field.go | 549 - vendor/go.uber.org/zap/flag.go | 39 - vendor/go.uber.org/zap/glide.yaml | 34 - vendor/go.uber.org/zap/global.go | 169 - vendor/go.uber.org/zap/http_handler.go | 133 - .../zap/internal/bufferpool/bufferpool.go | 31 - .../go.uber.org/zap/internal/color/color.go | 44 - vendor/go.uber.org/zap/internal/exit/exit.go | 66 - .../go.uber.org/zap/internal/level_enabler.go | 35 - vendor/go.uber.org/zap/level.go | 152 - vendor/go.uber.org/zap/logger.go | 400 - vendor/go.uber.org/zap/options.go | 167 - vendor/go.uber.org/zap/sink.go | 179 - vendor/go.uber.org/zap/stacktrace.go | 176 - vendor/go.uber.org/zap/sugar.go | 416 - vendor/go.uber.org/zap/time.go | 27 - vendor/go.uber.org/zap/writer.go | 98 - .../zap/zapcore/buffered_write_syncer.go | 219 - vendor/go.uber.org/zap/zapcore/clock.go | 48 - .../zap/zapcore/console_encoder.go | 157 - vendor/go.uber.org/zap/zapcore/core.go | 122 - vendor/go.uber.org/zap/zapcore/doc.go | 24 - vendor/go.uber.org/zap/zapcore/encoder.go | 451 - vendor/go.uber.org/zap/zapcore/entry.go | 300 - vendor/go.uber.org/zap/zapcore/error.go | 132 - vendor/go.uber.org/zap/zapcore/field.go | 233 - vendor/go.uber.org/zap/zapcore/hook.go | 77 - .../go.uber.org/zap/zapcore/increase_level.go | 75 - .../go.uber.org/zap/zapcore/json_encoder.go | 562 - vendor/go.uber.org/zap/zapcore/level.go | 229 - .../go.uber.org/zap/zapcore/level_strings.go | 46 - vendor/go.uber.org/zap/zapcore/marshaler.go | 61 - .../go.uber.org/zap/zapcore/memory_encoder.go | 179 - .../zap/zapcore/reflected_encoder.go | 41 - vendor/go.uber.org/zap/zapcore/sampler.go | 230 - vendor/go.uber.org/zap/zapcore/tee.go | 96 - .../go.uber.org/zap/zapcore/write_syncer.go | 122 - vendor/golang.org/x/crypto/LICENSE | 27 - vendor/golang.org/x/crypto/PATENTS | 22 - vendor/golang.org/x/crypto/argon2/argon2.go | 283 - vendor/golang.org/x/crypto/argon2/blake2b.go | 53 - .../x/crypto/argon2/blamka_amd64.go | 60 - .../golang.org/x/crypto/argon2/blamka_amd64.s | 2791 -- .../x/crypto/argon2/blamka_generic.go | 163 - .../golang.org/x/crypto/argon2/blamka_ref.go | 15 - vendor/golang.org/x/crypto/blake2b/blake2b.go | 291 - .../x/crypto/blake2b/blake2bAVX2_amd64.go | 37 - .../x/crypto/blake2b/blake2bAVX2_amd64.s | 4559 --- .../x/crypto/blake2b/blake2b_amd64.s | 1441 - .../x/crypto/blake2b/blake2b_generic.go | 182 - .../x/crypto/blake2b/blake2b_ref.go | 11 - vendor/golang.org/x/crypto/blake2b/blake2x.go | 177 - .../golang.org/x/crypto/blake2b/register.go | 30 - vendor/golang.org/x/exp/LICENSE | 27 - vendor/golang.org/x/exp/PATENTS | 22 - .../x/exp/constraints/constraints.go | 50 - vendor/golang.org/x/exp/maps/maps.go | 94 - vendor/golang.org/x/exp/slices/cmp.go | 44 - vendor/golang.org/x/exp/slices/slices.go | 515 - vendor/golang.org/x/exp/slices/sort.go | 197 - .../golang.org/x/exp/slices/zsortanyfunc.go | 479 - .../golang.org/x/exp/slices/zsortordered.go | 481 - vendor/golang.org/x/exp/typeparams/LICENSE | 27 - vendor/golang.org/x/exp/typeparams/common.go | 182 - .../golang.org/x/exp/typeparams/normalize.go | 200 - .../golang.org/x/exp/typeparams/termlist.go | 172 - .../x/exp/typeparams/typeparams_go117.go | 201 - .../x/exp/typeparams/typeparams_go118.go | 147 - .../golang.org/x/exp/typeparams/typeterm.go | 169 - vendor/golang.org/x/mod/LICENSE | 27 - vendor/golang.org/x/mod/PATENTS | 22 - .../x/mod/internal/lazyregexp/lazyre.go | 78 - vendor/golang.org/x/mod/modfile/print.go | 184 - vendor/golang.org/x/mod/modfile/read.go | 959 - vendor/golang.org/x/mod/modfile/rule.go | 1836 - vendor/golang.org/x/mod/modfile/work.go | 335 - vendor/golang.org/x/mod/module/module.go | 841 - vendor/golang.org/x/mod/module/pseudo.go | 250 - vendor/golang.org/x/mod/semver/semver.go | 401 - vendor/golang.org/x/net/LICENSE | 27 - vendor/golang.org/x/net/PATENTS | 22 - vendor/golang.org/x/net/http/httpguts/guts.go | 50 - .../golang.org/x/net/http/httpguts/httplex.go | 347 - vendor/golang.org/x/net/http2/.gitignore | 2 - vendor/golang.org/x/net/http2/ascii.go | 53 - vendor/golang.org/x/net/http2/ciphers.go | 641 - .../x/net/http2/client_conn_pool.go | 311 - vendor/golang.org/x/net/http2/databuffer.go | 149 - vendor/golang.org/x/net/http2/errors.go | 145 - vendor/golang.org/x/net/http2/flow.go | 120 - vendor/golang.org/x/net/http2/frame.go | 1691 - vendor/golang.org/x/net/http2/gotrack.go | 170 - vendor/golang.org/x/net/http2/headermap.go | 105 - vendor/golang.org/x/net/http2/hpack/encode.go | 245 - vendor/golang.org/x/net/http2/hpack/hpack.go | 523 - .../golang.org/x/net/http2/hpack/huffman.go | 226 - .../x/net/http2/hpack/static_table.go | 188 - vendor/golang.org/x/net/http2/hpack/tables.go | 403 - vendor/golang.org/x/net/http2/http2.go | 392 - vendor/golang.org/x/net/http2/pipe.go | 184 - vendor/golang.org/x/net/http2/server.go | 3326 -- vendor/golang.org/x/net/http2/timer.go | 20 - vendor/golang.org/x/net/http2/transport.go | 3332 -- vendor/golang.org/x/net/http2/write.go | 370 - vendor/golang.org/x/net/http2/writesched.go | 251 - .../x/net/http2/writesched_priority.go | 451 - .../x/net/http2/writesched_random.go | 77 - .../x/net/http2/writesched_roundrobin.go | 119 - vendor/golang.org/x/net/idna/go118.go | 13 - vendor/golang.org/x/net/idna/idna10.0.0.go | 769 - vendor/golang.org/x/net/idna/idna9.0.0.go | 717 - vendor/golang.org/x/net/idna/pre_go118.go | 11 - vendor/golang.org/x/net/idna/punycode.go | 217 - vendor/golang.org/x/net/idna/tables10.0.0.go | 4559 --- vendor/golang.org/x/net/idna/tables11.0.0.go | 4653 --- vendor/golang.org/x/net/idna/tables12.0.0.go | 4733 --- vendor/golang.org/x/net/idna/tables13.0.0.go | 4959 --- vendor/golang.org/x/net/idna/tables15.0.0.go | 5144 --- vendor/golang.org/x/net/idna/tables9.0.0.go | 4486 --- vendor/golang.org/x/net/idna/trie.go | 51 - vendor/golang.org/x/net/idna/trie12.0.0.go | 30 - vendor/golang.org/x/net/idna/trie13.0.0.go | 30 - vendor/golang.org/x/net/idna/trieval.go | 119 - .../x/net/internal/timeseries/timeseries.go | 525 - .../x/net/publicsuffix/data/children | Bin 2976 -> 0 bytes .../golang.org/x/net/publicsuffix/data/nodes | Bin 46610 -> 0 bytes .../golang.org/x/net/publicsuffix/data/text | 1 - vendor/golang.org/x/net/publicsuffix/list.go | 203 - vendor/golang.org/x/net/publicsuffix/table.go | 70 - vendor/golang.org/x/net/trace/events.go | 532 - vendor/golang.org/x/net/trace/histogram.go | 365 - vendor/golang.org/x/net/trace/trace.go | 1130 - vendor/golang.org/x/sync/LICENSE | 27 - vendor/golang.org/x/sync/PATENTS | 22 - vendor/golang.org/x/sync/errgroup/errgroup.go | 135 - vendor/golang.org/x/sync/errgroup/go120.go | 13 - .../golang.org/x/sync/errgroup/pre_go120.go | 14 - .../golang.org/x/sync/semaphore/semaphore.go | 160 - vendor/golang.org/x/sys/LICENSE | 27 - vendor/golang.org/x/sys/PATENTS | 22 - vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s | 17 - vendor/golang.org/x/sys/cpu/byteorder.go | 66 - vendor/golang.org/x/sys/cpu/cpu.go | 312 - vendor/golang.org/x/sys/cpu/cpu_aix.go | 33 - vendor/golang.org/x/sys/cpu/cpu_arm.go | 73 - vendor/golang.org/x/sys/cpu/cpu_arm64.go | 194 - vendor/golang.org/x/sys/cpu/cpu_arm64.s | 39 - vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go | 12 - vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go | 21 - vendor/golang.org/x/sys/cpu/cpu_gc_x86.go | 15 - .../golang.org/x/sys/cpu/cpu_gccgo_arm64.go | 11 - .../golang.org/x/sys/cpu/cpu_gccgo_s390x.go | 22 - vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c | 37 - vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go | 31 - vendor/golang.org/x/sys/cpu/cpu_linux.go | 15 - vendor/golang.org/x/sys/cpu/cpu_linux_arm.go | 39 - .../golang.org/x/sys/cpu/cpu_linux_arm64.go | 121 - .../golang.org/x/sys/cpu/cpu_linux_mips64x.go | 22 - .../golang.org/x/sys/cpu/cpu_linux_noinit.go | 9 - .../golang.org/x/sys/cpu/cpu_linux_ppc64x.go | 30 - .../golang.org/x/sys/cpu/cpu_linux_riscv64.go | 137 - .../golang.org/x/sys/cpu/cpu_linux_s390x.go | 40 - vendor/golang.org/x/sys/cpu/cpu_loong64.go | 12 - vendor/golang.org/x/sys/cpu/cpu_mips64x.go | 15 - vendor/golang.org/x/sys/cpu/cpu_mipsx.go | 11 - .../golang.org/x/sys/cpu/cpu_netbsd_arm64.go | 173 - .../golang.org/x/sys/cpu/cpu_openbsd_arm64.go | 65 - .../golang.org/x/sys/cpu/cpu_openbsd_arm64.s | 11 - vendor/golang.org/x/sys/cpu/cpu_other_arm.go | 9 - .../golang.org/x/sys/cpu/cpu_other_arm64.go | 9 - .../golang.org/x/sys/cpu/cpu_other_mips64x.go | 11 - .../golang.org/x/sys/cpu/cpu_other_ppc64x.go | 12 - .../golang.org/x/sys/cpu/cpu_other_riscv64.go | 11 - vendor/golang.org/x/sys/cpu/cpu_ppc64x.go | 16 - vendor/golang.org/x/sys/cpu/cpu_riscv64.go | 20 - vendor/golang.org/x/sys/cpu/cpu_s390x.go | 172 - vendor/golang.org/x/sys/cpu/cpu_s390x.s | 57 - vendor/golang.org/x/sys/cpu/cpu_wasm.go | 17 - vendor/golang.org/x/sys/cpu/cpu_x86.go | 151 - vendor/golang.org/x/sys/cpu/cpu_x86.s | 26 - vendor/golang.org/x/sys/cpu/cpu_zos.go | 10 - vendor/golang.org/x/sys/cpu/cpu_zos_s390x.go | 25 - vendor/golang.org/x/sys/cpu/endian_big.go | 10 - vendor/golang.org/x/sys/cpu/endian_little.go | 10 - vendor/golang.org/x/sys/cpu/hwcap_linux.go | 71 - vendor/golang.org/x/sys/cpu/parse.go | 43 - .../x/sys/cpu/proc_cpuinfo_linux.go | 53 - vendor/golang.org/x/sys/cpu/runtime_auxv.go | 16 - .../x/sys/cpu/runtime_auxv_go121.go | 18 - .../golang.org/x/sys/cpu/syscall_aix_gccgo.go | 26 - .../x/sys/cpu/syscall_aix_ppc64_gc.go | 35 - vendor/golang.org/x/sys/execabs/execabs.go | 102 - .../golang.org/x/sys/execabs/execabs_go118.go | 17 - .../golang.org/x/sys/execabs/execabs_go119.go | 20 - vendor/golang.org/x/sys/unix/.gitignore | 2 - vendor/golang.org/x/sys/unix/README.md | 184 - .../golang.org/x/sys/unix/affinity_linux.go | 86 - vendor/golang.org/x/sys/unix/aliases.go | 13 - vendor/golang.org/x/sys/unix/asm_aix_ppc64.s | 17 - vendor/golang.org/x/sys/unix/asm_bsd_386.s | 27 - vendor/golang.org/x/sys/unix/asm_bsd_amd64.s | 27 - vendor/golang.org/x/sys/unix/asm_bsd_arm.s | 27 - vendor/golang.org/x/sys/unix/asm_bsd_arm64.s | 27 - vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s | 29 - .../golang.org/x/sys/unix/asm_bsd_riscv64.s | 27 - vendor/golang.org/x/sys/unix/asm_linux_386.s | 65 - .../golang.org/x/sys/unix/asm_linux_amd64.s | 57 - vendor/golang.org/x/sys/unix/asm_linux_arm.s | 56 - .../golang.org/x/sys/unix/asm_linux_arm64.s | 50 - .../golang.org/x/sys/unix/asm_linux_loong64.s | 51 - .../golang.org/x/sys/unix/asm_linux_mips64x.s | 54 - .../golang.org/x/sys/unix/asm_linux_mipsx.s | 52 - .../golang.org/x/sys/unix/asm_linux_ppc64x.s | 42 - .../golang.org/x/sys/unix/asm_linux_riscv64.s | 47 - .../golang.org/x/sys/unix/asm_linux_s390x.s | 54 - .../x/sys/unix/asm_openbsd_mips64.s | 29 - .../golang.org/x/sys/unix/asm_solaris_amd64.s | 17 - vendor/golang.org/x/sys/unix/asm_zos_s390x.s | 382 - .../golang.org/x/sys/unix/bluetooth_linux.go | 36 - vendor/golang.org/x/sys/unix/bpxsvc_zos.go | 657 - vendor/golang.org/x/sys/unix/bpxsvc_zos.s | 192 - vendor/golang.org/x/sys/unix/cap_freebsd.go | 195 - vendor/golang.org/x/sys/unix/constants.go | 13 - vendor/golang.org/x/sys/unix/dev_aix_ppc.go | 26 - vendor/golang.org/x/sys/unix/dev_aix_ppc64.go | 28 - vendor/golang.org/x/sys/unix/dev_darwin.go | 24 - vendor/golang.org/x/sys/unix/dev_dragonfly.go | 30 - vendor/golang.org/x/sys/unix/dev_freebsd.go | 30 - vendor/golang.org/x/sys/unix/dev_linux.go | 42 - vendor/golang.org/x/sys/unix/dev_netbsd.go | 29 - vendor/golang.org/x/sys/unix/dev_openbsd.go | 29 - vendor/golang.org/x/sys/unix/dev_zos.go | 28 - vendor/golang.org/x/sys/unix/dirent.go | 102 - vendor/golang.org/x/sys/unix/endian_big.go | 9 - vendor/golang.org/x/sys/unix/endian_little.go | 9 - vendor/golang.org/x/sys/unix/env_unix.go | 31 - vendor/golang.org/x/sys/unix/fcntl.go | 36 - vendor/golang.org/x/sys/unix/fcntl_darwin.go | 24 - .../x/sys/unix/fcntl_linux_32bit.go | 13 - vendor/golang.org/x/sys/unix/fdset.go | 29 - vendor/golang.org/x/sys/unix/gccgo.go | 59 - vendor/golang.org/x/sys/unix/gccgo_c.c | 44 - .../x/sys/unix/gccgo_linux_amd64.go | 20 - vendor/golang.org/x/sys/unix/ifreq_linux.go | 141 - vendor/golang.org/x/sys/unix/ioctl_linux.go | 238 - vendor/golang.org/x/sys/unix/ioctl_signed.go | 69 - .../golang.org/x/sys/unix/ioctl_unsigned.go | 69 - vendor/golang.org/x/sys/unix/ioctl_zos.go | 71 - vendor/golang.org/x/sys/unix/mkall.sh | 249 - vendor/golang.org/x/sys/unix/mkerrors.sh | 793 - vendor/golang.org/x/sys/unix/mmap_nomremap.go | 13 - vendor/golang.org/x/sys/unix/mremap.go | 57 - vendor/golang.org/x/sys/unix/pagesize_unix.go | 15 - .../golang.org/x/sys/unix/pledge_openbsd.go | 111 - vendor/golang.org/x/sys/unix/ptrace_darwin.go | 11 - vendor/golang.org/x/sys/unix/ptrace_ios.go | 11 - vendor/golang.org/x/sys/unix/race.go | 30 - vendor/golang.org/x/sys/unix/race0.go | 25 - .../x/sys/unix/readdirent_getdents.go | 12 - .../x/sys/unix/readdirent_getdirentries.go | 19 - .../x/sys/unix/sockcmsg_dragonfly.go | 16 - .../golang.org/x/sys/unix/sockcmsg_linux.go | 85 - vendor/golang.org/x/sys/unix/sockcmsg_unix.go | 106 - .../x/sys/unix/sockcmsg_unix_other.go | 46 - vendor/golang.org/x/sys/unix/sockcmsg_zos.go | 58 - .../golang.org/x/sys/unix/symaddr_zos_s390x.s | 75 - vendor/golang.org/x/sys/unix/syscall.go | 86 - vendor/golang.org/x/sys/unix/syscall_aix.go | 582 - .../golang.org/x/sys/unix/syscall_aix_ppc.go | 52 - .../x/sys/unix/syscall_aix_ppc64.go | 83 - vendor/golang.org/x/sys/unix/syscall_bsd.go | 609 - .../golang.org/x/sys/unix/syscall_darwin.go | 707 - .../x/sys/unix/syscall_darwin_amd64.go | 50 - .../x/sys/unix/syscall_darwin_arm64.go | 50 - .../x/sys/unix/syscall_darwin_libSystem.go | 26 - .../x/sys/unix/syscall_dragonfly.go | 347 - .../x/sys/unix/syscall_dragonfly_amd64.go | 56 - .../golang.org/x/sys/unix/syscall_freebsd.go | 455 - .../x/sys/unix/syscall_freebsd_386.go | 64 - .../x/sys/unix/syscall_freebsd_amd64.go | 64 - .../x/sys/unix/syscall_freebsd_arm.go | 60 - .../x/sys/unix/syscall_freebsd_arm64.go | 60 - .../x/sys/unix/syscall_freebsd_riscv64.go | 60 - vendor/golang.org/x/sys/unix/syscall_hurd.go | 30 - .../golang.org/x/sys/unix/syscall_hurd_386.go | 28 - .../golang.org/x/sys/unix/syscall_illumos.go | 78 - vendor/golang.org/x/sys/unix/syscall_linux.go | 2595 -- .../x/sys/unix/syscall_linux_386.go | 314 - .../x/sys/unix/syscall_linux_alarm.go | 12 - .../x/sys/unix/syscall_linux_amd64.go | 145 - .../x/sys/unix/syscall_linux_amd64_gc.go | 12 - .../x/sys/unix/syscall_linux_arm.go | 216 - .../x/sys/unix/syscall_linux_arm64.go | 184 - .../golang.org/x/sys/unix/syscall_linux_gc.go | 14 - .../x/sys/unix/syscall_linux_gc_386.go | 16 - .../x/sys/unix/syscall_linux_gc_arm.go | 13 - .../x/sys/unix/syscall_linux_gccgo_386.go | 30 - .../x/sys/unix/syscall_linux_gccgo_arm.go | 20 - .../x/sys/unix/syscall_linux_loong64.go | 216 - .../x/sys/unix/syscall_linux_mips64x.go | 188 - .../x/sys/unix/syscall_linux_mipsx.go | 174 - .../x/sys/unix/syscall_linux_ppc.go | 204 - .../x/sys/unix/syscall_linux_ppc64x.go | 115 - .../x/sys/unix/syscall_linux_riscv64.go | 189 - .../x/sys/unix/syscall_linux_s390x.go | 296 - .../x/sys/unix/syscall_linux_sparc64.go | 112 - .../golang.org/x/sys/unix/syscall_netbsd.go | 371 - .../x/sys/unix/syscall_netbsd_386.go | 37 - .../x/sys/unix/syscall_netbsd_amd64.go | 37 - .../x/sys/unix/syscall_netbsd_arm.go | 37 - .../x/sys/unix/syscall_netbsd_arm64.go | 37 - .../golang.org/x/sys/unix/syscall_openbsd.go | 342 - .../x/sys/unix/syscall_openbsd_386.go | 41 - .../x/sys/unix/syscall_openbsd_amd64.go | 41 - .../x/sys/unix/syscall_openbsd_arm.go | 41 - .../x/sys/unix/syscall_openbsd_arm64.go | 41 - .../x/sys/unix/syscall_openbsd_libc.go | 26 - .../x/sys/unix/syscall_openbsd_mips64.go | 39 - .../x/sys/unix/syscall_openbsd_ppc64.go | 41 - .../x/sys/unix/syscall_openbsd_riscv64.go | 41 - .../golang.org/x/sys/unix/syscall_solaris.go | 1104 - .../x/sys/unix/syscall_solaris_amd64.go | 27 - vendor/golang.org/x/sys/unix/syscall_unix.go | 615 - .../golang.org/x/sys/unix/syscall_unix_gc.go | 14 - .../x/sys/unix/syscall_unix_gc_ppc64x.go | 22 - .../x/sys/unix/syscall_zos_s390x.go | 3117 -- vendor/golang.org/x/sys/unix/sysvshm_linux.go | 20 - vendor/golang.org/x/sys/unix/sysvshm_unix.go | 51 - .../x/sys/unix/sysvshm_unix_other.go | 13 - vendor/golang.org/x/sys/unix/timestruct.go | 76 - .../golang.org/x/sys/unix/unveil_openbsd.go | 51 - vendor/golang.org/x/sys/unix/xattr_bsd.go | 280 - .../golang.org/x/sys/unix/zerrors_aix_ppc.go | 1384 - .../x/sys/unix/zerrors_aix_ppc64.go | 1385 - .../x/sys/unix/zerrors_darwin_amd64.go | 1922 - .../x/sys/unix/zerrors_darwin_arm64.go | 1922 - .../x/sys/unix/zerrors_dragonfly_amd64.go | 1737 - .../x/sys/unix/zerrors_freebsd_386.go | 2042 - .../x/sys/unix/zerrors_freebsd_amd64.go | 2039 - .../x/sys/unix/zerrors_freebsd_arm.go | 2033 - .../x/sys/unix/zerrors_freebsd_arm64.go | 2033 - .../x/sys/unix/zerrors_freebsd_riscv64.go | 2147 -- vendor/golang.org/x/sys/unix/zerrors_linux.go | 3694 -- .../x/sys/unix/zerrors_linux_386.go | 845 - .../x/sys/unix/zerrors_linux_amd64.go | 845 - .../x/sys/unix/zerrors_linux_arm.go | 850 - .../x/sys/unix/zerrors_linux_arm64.go | 845 - .../x/sys/unix/zerrors_linux_loong64.go | 837 - .../x/sys/unix/zerrors_linux_mips.go | 851 - .../x/sys/unix/zerrors_linux_mips64.go | 851 - .../x/sys/unix/zerrors_linux_mips64le.go | 851 - .../x/sys/unix/zerrors_linux_mipsle.go | 851 - .../x/sys/unix/zerrors_linux_ppc.go | 903 - .../x/sys/unix/zerrors_linux_ppc64.go | 907 - .../x/sys/unix/zerrors_linux_ppc64le.go | 907 - .../x/sys/unix/zerrors_linux_riscv64.go | 834 - .../x/sys/unix/zerrors_linux_s390x.go | 906 - .../x/sys/unix/zerrors_linux_sparc64.go | 949 - .../x/sys/unix/zerrors_netbsd_386.go | 1779 - .../x/sys/unix/zerrors_netbsd_amd64.go | 1769 - .../x/sys/unix/zerrors_netbsd_arm.go | 1758 - .../x/sys/unix/zerrors_netbsd_arm64.go | 1769 - .../x/sys/unix/zerrors_openbsd_386.go | 1905 - .../x/sys/unix/zerrors_openbsd_amd64.go | 1905 - .../x/sys/unix/zerrors_openbsd_arm.go | 1905 - .../x/sys/unix/zerrors_openbsd_arm64.go | 1905 - .../x/sys/unix/zerrors_openbsd_mips64.go | 1905 - .../x/sys/unix/zerrors_openbsd_ppc64.go | 1904 - .../x/sys/unix/zerrors_openbsd_riscv64.go | 1903 - .../x/sys/unix/zerrors_solaris_amd64.go | 1556 - .../x/sys/unix/zerrors_zos_s390x.go | 990 - .../x/sys/unix/zptrace_armnn_linux.go | 40 - .../x/sys/unix/zptrace_linux_arm64.go | 17 - .../x/sys/unix/zptrace_mipsnn_linux.go | 49 - .../x/sys/unix/zptrace_mipsnnle_linux.go | 49 - .../x/sys/unix/zptrace_x86_linux.go | 79 - .../x/sys/unix/zsymaddr_zos_s390x.s | 364 - .../golang.org/x/sys/unix/zsyscall_aix_ppc.go | 1461 - .../x/sys/unix/zsyscall_aix_ppc64.go | 1420 - .../x/sys/unix/zsyscall_aix_ppc64_gc.go | 1188 - .../x/sys/unix/zsyscall_aix_ppc64_gccgo.go | 1069 - .../x/sys/unix/zsyscall_darwin_amd64.go | 2644 -- .../x/sys/unix/zsyscall_darwin_amd64.s | 779 - .../x/sys/unix/zsyscall_darwin_arm64.go | 2644 -- .../x/sys/unix/zsyscall_darwin_arm64.s | 779 - .../x/sys/unix/zsyscall_dragonfly_amd64.go | 1666 - .../x/sys/unix/zsyscall_freebsd_386.go | 1886 - .../x/sys/unix/zsyscall_freebsd_amd64.go | 1886 - .../x/sys/unix/zsyscall_freebsd_arm.go | 1886 - .../x/sys/unix/zsyscall_freebsd_arm64.go | 1886 - .../x/sys/unix/zsyscall_freebsd_riscv64.go | 1886 - .../x/sys/unix/zsyscall_illumos_amd64.go | 101 - .../golang.org/x/sys/unix/zsyscall_linux.go | 2247 -- .../x/sys/unix/zsyscall_linux_386.go | 486 - .../x/sys/unix/zsyscall_linux_amd64.go | 653 - .../x/sys/unix/zsyscall_linux_arm.go | 601 - .../x/sys/unix/zsyscall_linux_arm64.go | 552 - .../x/sys/unix/zsyscall_linux_loong64.go | 486 - .../x/sys/unix/zsyscall_linux_mips.go | 653 - .../x/sys/unix/zsyscall_linux_mips64.go | 647 - .../x/sys/unix/zsyscall_linux_mips64le.go | 636 - .../x/sys/unix/zsyscall_linux_mipsle.go | 653 - .../x/sys/unix/zsyscall_linux_ppc.go | 658 - .../x/sys/unix/zsyscall_linux_ppc64.go | 704 - .../x/sys/unix/zsyscall_linux_ppc64le.go | 704 - .../x/sys/unix/zsyscall_linux_riscv64.go | 548 - .../x/sys/unix/zsyscall_linux_s390x.go | 495 - .../x/sys/unix/zsyscall_linux_sparc64.go | 648 - .../x/sys/unix/zsyscall_netbsd_386.go | 1848 - .../x/sys/unix/zsyscall_netbsd_amd64.go | 1848 - .../x/sys/unix/zsyscall_netbsd_arm.go | 1848 - .../x/sys/unix/zsyscall_netbsd_arm64.go | 1848 - .../x/sys/unix/zsyscall_openbsd_386.go | 2323 -- .../x/sys/unix/zsyscall_openbsd_386.s | 699 - .../x/sys/unix/zsyscall_openbsd_amd64.go | 2323 -- .../x/sys/unix/zsyscall_openbsd_amd64.s | 699 - .../x/sys/unix/zsyscall_openbsd_arm.go | 2323 -- .../x/sys/unix/zsyscall_openbsd_arm.s | 699 - .../x/sys/unix/zsyscall_openbsd_arm64.go | 2323 -- .../x/sys/unix/zsyscall_openbsd_arm64.s | 699 - .../x/sys/unix/zsyscall_openbsd_mips64.go | 2323 -- .../x/sys/unix/zsyscall_openbsd_mips64.s | 699 - .../x/sys/unix/zsyscall_openbsd_ppc64.go | 2323 -- .../x/sys/unix/zsyscall_openbsd_ppc64.s | 838 - .../x/sys/unix/zsyscall_openbsd_riscv64.go | 2323 -- .../x/sys/unix/zsyscall_openbsd_riscv64.s | 699 - .../x/sys/unix/zsyscall_solaris_amd64.go | 2103 -- .../x/sys/unix/zsyscall_zos_s390x.go | 3458 -- .../x/sys/unix/zsysctl_openbsd_386.go | 280 - .../x/sys/unix/zsysctl_openbsd_amd64.go | 280 - .../x/sys/unix/zsysctl_openbsd_arm.go | 280 - .../x/sys/unix/zsysctl_openbsd_arm64.go | 280 - .../x/sys/unix/zsysctl_openbsd_mips64.go | 280 - .../x/sys/unix/zsysctl_openbsd_ppc64.go | 280 - .../x/sys/unix/zsysctl_openbsd_riscv64.go | 281 - .../x/sys/unix/zsysnum_darwin_amd64.go | 439 - .../x/sys/unix/zsysnum_darwin_arm64.go | 437 - .../x/sys/unix/zsysnum_dragonfly_amd64.go | 316 - .../x/sys/unix/zsysnum_freebsd_386.go | 393 - .../x/sys/unix/zsysnum_freebsd_amd64.go | 393 - .../x/sys/unix/zsysnum_freebsd_arm.go | 393 - .../x/sys/unix/zsysnum_freebsd_arm64.go | 393 - .../x/sys/unix/zsysnum_freebsd_riscv64.go | 393 - .../x/sys/unix/zsysnum_linux_386.go | 461 - .../x/sys/unix/zsysnum_linux_amd64.go | 383 - .../x/sys/unix/zsysnum_linux_arm.go | 425 - .../x/sys/unix/zsysnum_linux_arm64.go | 328 - .../x/sys/unix/zsysnum_linux_loong64.go | 322 - .../x/sys/unix/zsysnum_linux_mips.go | 445 - .../x/sys/unix/zsysnum_linux_mips64.go | 375 - .../x/sys/unix/zsysnum_linux_mips64le.go | 375 - .../x/sys/unix/zsysnum_linux_mipsle.go | 445 - .../x/sys/unix/zsysnum_linux_ppc.go | 452 - .../x/sys/unix/zsysnum_linux_ppc64.go | 424 - .../x/sys/unix/zsysnum_linux_ppc64le.go | 424 - .../x/sys/unix/zsysnum_linux_riscv64.go | 329 - .../x/sys/unix/zsysnum_linux_s390x.go | 390 - .../x/sys/unix/zsysnum_linux_sparc64.go | 403 - .../x/sys/unix/zsysnum_netbsd_386.go | 274 - .../x/sys/unix/zsysnum_netbsd_amd64.go | 274 - .../x/sys/unix/zsysnum_netbsd_arm.go | 274 - .../x/sys/unix/zsysnum_netbsd_arm64.go | 274 - .../x/sys/unix/zsysnum_openbsd_386.go | 219 - .../x/sys/unix/zsysnum_openbsd_amd64.go | 219 - .../x/sys/unix/zsysnum_openbsd_arm.go | 219 - .../x/sys/unix/zsysnum_openbsd_arm64.go | 218 - .../x/sys/unix/zsysnum_openbsd_mips64.go | 221 - .../x/sys/unix/zsysnum_openbsd_ppc64.go | 217 - .../x/sys/unix/zsysnum_openbsd_riscv64.go | 218 - .../x/sys/unix/zsysnum_zos_s390x.go | 2852 -- .../golang.org/x/sys/unix/ztypes_aix_ppc.go | 353 - .../golang.org/x/sys/unix/ztypes_aix_ppc64.go | 357 - .../x/sys/unix/ztypes_darwin_amd64.go | 818 - .../x/sys/unix/ztypes_darwin_arm64.go | 818 - .../x/sys/unix/ztypes_dragonfly_amd64.go | 473 - .../x/sys/unix/ztypes_freebsd_386.go | 651 - .../x/sys/unix/ztypes_freebsd_amd64.go | 656 - .../x/sys/unix/ztypes_freebsd_arm.go | 642 - .../x/sys/unix/ztypes_freebsd_arm64.go | 636 - .../x/sys/unix/ztypes_freebsd_riscv64.go | 638 - vendor/golang.org/x/sys/unix/ztypes_linux.go | 6038 --- .../golang.org/x/sys/unix/ztypes_linux_386.go | 689 - .../x/sys/unix/ztypes_linux_amd64.go | 703 - .../golang.org/x/sys/unix/ztypes_linux_arm.go | 683 - .../x/sys/unix/ztypes_linux_arm64.go | 682 - .../x/sys/unix/ztypes_linux_loong64.go | 683 - .../x/sys/unix/ztypes_linux_mips.go | 688 - .../x/sys/unix/ztypes_linux_mips64.go | 685 - .../x/sys/unix/ztypes_linux_mips64le.go | 685 - .../x/sys/unix/ztypes_linux_mipsle.go | 688 - .../golang.org/x/sys/unix/ztypes_linux_ppc.go | 696 - .../x/sys/unix/ztypes_linux_ppc64.go | 691 - .../x/sys/unix/ztypes_linux_ppc64le.go | 691 - .../x/sys/unix/ztypes_linux_riscv64.go | 770 - .../x/sys/unix/ztypes_linux_s390x.go | 705 - .../x/sys/unix/ztypes_linux_sparc64.go | 686 - .../x/sys/unix/ztypes_netbsd_386.go | 585 - .../x/sys/unix/ztypes_netbsd_amd64.go | 593 - .../x/sys/unix/ztypes_netbsd_arm.go | 590 - .../x/sys/unix/ztypes_netbsd_arm64.go | 593 - .../x/sys/unix/ztypes_openbsd_386.go | 568 - .../x/sys/unix/ztypes_openbsd_amd64.go | 568 - .../x/sys/unix/ztypes_openbsd_arm.go | 575 - .../x/sys/unix/ztypes_openbsd_arm64.go | 568 - .../x/sys/unix/ztypes_openbsd_mips64.go | 568 - .../x/sys/unix/ztypes_openbsd_ppc64.go | 570 - .../x/sys/unix/ztypes_openbsd_riscv64.go | 570 - .../x/sys/unix/ztypes_solaris_amd64.go | 516 - .../golang.org/x/sys/unix/ztypes_zos_s390x.go | 546 - vendor/golang.org/x/sys/windows/aliases.go | 12 - .../golang.org/x/sys/windows/dll_windows.go | 416 - .../golang.org/x/sys/windows/env_windows.go | 57 - vendor/golang.org/x/sys/windows/eventlog.go | 20 - .../golang.org/x/sys/windows/exec_windows.go | 248 - .../x/sys/windows/memory_windows.go | 48 - vendor/golang.org/x/sys/windows/mkerrors.bash | 70 - .../x/sys/windows/mkknownfolderids.bash | 27 - vendor/golang.org/x/sys/windows/mksyscall.go | 9 - vendor/golang.org/x/sys/windows/race.go | 30 - vendor/golang.org/x/sys/windows/race0.go | 25 - .../x/sys/windows/security_windows.go | 1458 - vendor/golang.org/x/sys/windows/service.go | 257 - .../x/sys/windows/setupapi_windows.go | 1425 - vendor/golang.org/x/sys/windows/str.go | 22 - vendor/golang.org/x/sys/windows/syscall.go | 104 - .../x/sys/windows/syscall_windows.go | 1930 - .../golang.org/x/sys/windows/types_windows.go | 3476 -- .../x/sys/windows/types_windows_386.go | 35 - .../x/sys/windows/types_windows_amd64.go | 34 - .../x/sys/windows/types_windows_arm.go | 35 - .../x/sys/windows/types_windows_arm64.go | 34 - .../x/sys/windows/zerrors_windows.go | 9468 ----- .../x/sys/windows/zknownfolderids_windows.go | 149 - .../x/sys/windows/zsyscall_windows.go | 4615 --- vendor/golang.org/x/telemetry/.dockerignore | 17 - vendor/golang.org/x/telemetry/.eslintrc.json | 11 - vendor/golang.org/x/telemetry/.gitattributes | 14 - vendor/golang.org/x/telemetry/.gitignore | 2 - .../golang.org/x/telemetry/.prettierrc.json | 1 - .../golang.org/x/telemetry/.stylelintrc.json | 11 - vendor/golang.org/x/telemetry/CONTRIBUTING.md | 30 - vendor/golang.org/x/telemetry/LICENSE | 27 - vendor/golang.org/x/telemetry/PATENTS | 22 - vendor/golang.org/x/telemetry/README.md | 60 - .../golang.org/x/telemetry/counter/counter.go | 121 - vendor/golang.org/x/telemetry/counter/doc.go | 51 - vendor/golang.org/x/telemetry/dir.go | 12 - vendor/golang.org/x/telemetry/doc.go | 1 - .../x/telemetry/internal/config/config.go | 140 - .../internal/configstore/download.go | 70 - .../x/telemetry/internal/counter/counter.go | 359 - .../x/telemetry/internal/counter/file.go | 683 - .../x/telemetry/internal/counter/parse.go | 82 - .../internal/counter/stackcounter.go | 202 - .../internal/crashmonitor/crash_go123.go | 17 - .../internal/crashmonitor/monitor.go | 256 - .../x/telemetry/internal/mmap/mmap.go | 37 - .../x/telemetry/internal/mmap/mmap_other.go | 25 - .../x/telemetry/internal/mmap/mmap_unix.go | 47 - .../x/telemetry/internal/mmap/mmap_windows.go | 52 - .../x/telemetry/internal/telemetry/dir.go | 160 - .../telemetry/internal/telemetry/proginfo.go | 53 - .../x/telemetry/internal/telemetry/types.go | 51 - .../x/telemetry/internal/upload/Doc.txt | 45 - .../x/telemetry/internal/upload/date.go | 84 - .../x/telemetry/internal/upload/findwork.go | 102 - .../x/telemetry/internal/upload/reports.go | 341 - .../x/telemetry/internal/upload/run.go | 211 - .../x/telemetry/internal/upload/upload.go | 113 - vendor/golang.org/x/telemetry/mode.go | 38 - vendor/golang.org/x/telemetry/npm | 13 - vendor/golang.org/x/telemetry/npx | 13 - .../golang.org/x/telemetry/package-lock.json | 4363 --- vendor/golang.org/x/telemetry/package.json | 23 - vendor/golang.org/x/telemetry/start.go | 322 - vendor/golang.org/x/telemetry/start_posix.go | 22 - .../golang.org/x/telemetry/start_windows.go | 29 - vendor/golang.org/x/telemetry/tsconfig.json | 26 - vendor/golang.org/x/telemetry/types_alias.go | 21 - vendor/golang.org/x/text/LICENSE | 27 - vendor/golang.org/x/text/PATENTS | 22 - vendor/golang.org/x/text/cases/cases.go | 162 - vendor/golang.org/x/text/cases/context.go | 376 - vendor/golang.org/x/text/cases/fold.go | 34 - vendor/golang.org/x/text/cases/icu.go | 61 - vendor/golang.org/x/text/cases/info.go | 82 - vendor/golang.org/x/text/cases/map.go | 816 - .../golang.org/x/text/cases/tables10.0.0.go | 2255 -- .../golang.org/x/text/cases/tables11.0.0.go | 2316 -- .../golang.org/x/text/cases/tables12.0.0.go | 2359 -- .../golang.org/x/text/cases/tables13.0.0.go | 2399 -- .../golang.org/x/text/cases/tables15.0.0.go | 2527 -- vendor/golang.org/x/text/cases/tables9.0.0.go | 2215 -- vendor/golang.org/x/text/cases/trieval.go | 217 - vendor/golang.org/x/text/internal/internal.go | 49 - .../x/text/internal/language/common.go | 16 - .../x/text/internal/language/compact.go | 29 - .../text/internal/language/compact/compact.go | 61 - .../internal/language/compact/language.go | 260 - .../text/internal/language/compact/parents.go | 120 - .../text/internal/language/compact/tables.go | 1015 - .../x/text/internal/language/compact/tags.go | 91 - .../x/text/internal/language/compose.go | 167 - .../x/text/internal/language/coverage.go | 28 - .../x/text/internal/language/language.go | 627 - .../x/text/internal/language/lookup.go | 412 - .../x/text/internal/language/match.go | 226 - .../x/text/internal/language/parse.go | 608 - .../x/text/internal/language/tables.go | 3494 -- .../x/text/internal/language/tags.go | 48 - vendor/golang.org/x/text/internal/match.go | 67 - vendor/golang.org/x/text/internal/tag/tag.go | 100 - vendor/golang.org/x/text/language/coverage.go | 187 - vendor/golang.org/x/text/language/doc.go | 98 - vendor/golang.org/x/text/language/language.go | 605 - vendor/golang.org/x/text/language/match.go | 735 - vendor/golang.org/x/text/language/parse.go | 256 - vendor/golang.org/x/text/language/tables.go | 298 - vendor/golang.org/x/text/language/tags.go | 145 - vendor/golang.org/x/text/runes/cond.go | 187 - vendor/golang.org/x/text/runes/runes.go | 355 - .../x/text/secure/bidirule/bidirule.go | 336 - .../x/text/secure/bidirule/bidirule10.0.0.go | 11 - .../x/text/secure/bidirule/bidirule9.0.0.go | 14 - .../golang.org/x/text/transform/transform.go | 709 - vendor/golang.org/x/text/unicode/bidi/bidi.go | 359 - .../golang.org/x/text/unicode/bidi/bracket.go | 335 - vendor/golang.org/x/text/unicode/bidi/core.go | 1071 - vendor/golang.org/x/text/unicode/bidi/prop.go | 206 - .../x/text/unicode/bidi/tables10.0.0.go | 1815 - .../x/text/unicode/bidi/tables11.0.0.go | 1887 - .../x/text/unicode/bidi/tables12.0.0.go | 1923 - .../x/text/unicode/bidi/tables13.0.0.go | 1955 - .../x/text/unicode/bidi/tables15.0.0.go | 2042 - .../x/text/unicode/bidi/tables9.0.0.go | 1781 - .../golang.org/x/text/unicode/bidi/trieval.go | 48 - .../x/text/unicode/norm/composition.go | 512 - .../x/text/unicode/norm/forminfo.go | 279 - .../golang.org/x/text/unicode/norm/input.go | 109 - vendor/golang.org/x/text/unicode/norm/iter.go | 458 - .../x/text/unicode/norm/normalize.go | 610 - .../x/text/unicode/norm/readwriter.go | 125 - .../x/text/unicode/norm/tables10.0.0.go | 7657 ---- .../x/text/unicode/norm/tables11.0.0.go | 7693 ---- .../x/text/unicode/norm/tables12.0.0.go | 7710 ---- .../x/text/unicode/norm/tables13.0.0.go | 7760 ---- .../x/text/unicode/norm/tables15.0.0.go | 7907 ---- .../x/text/unicode/norm/tables9.0.0.go | 7637 ---- .../x/text/unicode/norm/transform.go | 88 - vendor/golang.org/x/text/unicode/norm/trie.go | 54 - vendor/golang.org/x/text/width/kind_string.go | 28 - .../golang.org/x/text/width/tables10.0.0.go | 1328 - .../golang.org/x/text/width/tables11.0.0.go | 1340 - .../golang.org/x/text/width/tables12.0.0.go | 1360 - .../golang.org/x/text/width/tables13.0.0.go | 1361 - .../golang.org/x/text/width/tables15.0.0.go | 1367 - vendor/golang.org/x/text/width/tables9.0.0.go | 1296 - vendor/golang.org/x/text/width/transform.go | 239 - vendor/golang.org/x/text/width/trieval.go | 30 - vendor/golang.org/x/text/width/width.go | 206 - vendor/golang.org/x/tools/LICENSE | 27 - vendor/golang.org/x/tools/PATENTS | 22 - vendor/golang.org/x/tools/cover/profile.go | 266 - .../x/tools/go/analysis/analysis.go | 249 - .../x/tools/go/analysis/diagnostic.go | 85 - vendor/golang.org/x/tools/go/analysis/doc.go | 317 - .../go/analysis/passes/appends/appends.go | 47 - .../x/tools/go/analysis/passes/appends/doc.go | 20 - .../go/analysis/passes/asmdecl/asmdecl.go | 826 - .../tools/go/analysis/passes/assign/assign.go | 88 - .../x/tools/go/analysis/passes/assign/doc.go | 14 - .../tools/go/analysis/passes/atomic/atomic.go | 85 - .../x/tools/go/analysis/passes/atomic/doc.go | 17 - .../passes/atomicalign/atomicalign.go | 108 - .../x/tools/go/analysis/passes/bools/bools.go | 183 - .../go/analysis/passes/buildssa/buildssa.go | 94 - .../go/analysis/passes/buildtag/buildtag.go | 418 - .../go/analysis/passes/cgocall/cgocall.go | 379 - .../analysis/passes/cgocall/cgocall_go120.go | 13 - .../analysis/passes/cgocall/cgocall_go121.go | 13 - .../go/analysis/passes/composite/composite.go | 160 - .../go/analysis/passes/composite/whitelist.go | 35 - .../go/analysis/passes/copylock/copylock.go | 353 - .../go/analysis/passes/ctrlflow/ctrlflow.go | 231 - .../passes/deepequalerrors/deepequalerrors.go | 119 - .../tools/go/analysis/passes/defers/defers.go | 59 - .../x/tools/go/analysis/passes/defers/doc.go | 25 - .../go/analysis/passes/directive/directive.go | 204 - .../go/analysis/passes/errorsas/errorsas.go | 89 - .../passes/fieldalignment/fieldalignment.go | 383 - .../go/analysis/passes/findcall/findcall.go | 99 - .../passes/framepointer/framepointer.go | 92 - .../passes/httpresponse/httpresponse.go | 176 - .../go/analysis/passes/ifaceassert/doc.go | 24 - .../passes/ifaceassert/ifaceassert.go | 101 - .../go/analysis/passes/inspect/inspect.go | 49 - .../passes/internal/analysisutil/util.go | 162 - .../go/analysis/passes/loopclosure/doc.go | 75 - .../passes/loopclosure/loopclosure.go | 372 - .../go/analysis/passes/lostcancel/doc.go | 16 - .../analysis/passes/lostcancel/lostcancel.go | 329 - .../x/tools/go/analysis/passes/nilfunc/doc.go | 13 - .../go/analysis/passes/nilfunc/nilfunc.go | 83 - .../x/tools/go/analysis/passes/nilness/doc.go | 72 - .../go/analysis/passes/nilness/nilness.go | 498 - .../go/analysis/passes/pkgfact/pkgfact.go | 128 - .../x/tools/go/analysis/passes/printf/doc.go | 103 - .../tools/go/analysis/passes/printf/printf.go | 1102 - .../tools/go/analysis/passes/printf/types.go | 302 - .../passes/reflectvaluecompare/doc.go | 27 - .../reflectvaluecompare.go | 77 - .../x/tools/go/analysis/passes/shadow/doc.go | 33 - .../tools/go/analysis/passes/shadow/shadow.go | 268 - .../x/tools/go/analysis/passes/shift/dead.go | 101 - .../x/tools/go/analysis/passes/shift/shift.go | 134 - .../go/analysis/passes/sigchanyzer/doc.go | 17 - .../passes/sigchanyzer/sigchanyzer.go | 159 - .../x/tools/go/analysis/passes/slog/doc.go | 23 - .../x/tools/go/analysis/passes/slog/slog.go | 243 - .../go/analysis/passes/sortslice/analyzer.go | 134 - .../go/analysis/passes/stdmethods/doc.go | 30 - .../analysis/passes/stdmethods/stdmethods.go | 202 - .../go/analysis/passes/stringintconv/doc.go | 21 - .../analysis/passes/stringintconv/string.go | 263 - .../go/analysis/passes/structtag/structtag.go | 314 - .../analysis/passes/testinggoroutine/doc.go | 22 - .../testinggoroutine/testinggoroutine.go | 279 - .../analysis/passes/testinggoroutine/util.go | 96 - .../x/tools/go/analysis/passes/tests/doc.go | 18 - .../x/tools/go/analysis/passes/tests/tests.go | 485 - .../go/analysis/passes/timeformat/doc.go | 15 - .../analysis/passes/timeformat/timeformat.go | 120 - .../tools/go/analysis/passes/unmarshal/doc.go | 14 - .../go/analysis/passes/unmarshal/unmarshal.go | 103 - .../go/analysis/passes/unreachable/doc.go | 14 - .../passes/unreachable/unreachable.go | 324 - .../tools/go/analysis/passes/unsafeptr/doc.go | 17 - .../go/analysis/passes/unsafeptr/unsafeptr.go | 158 - .../go/analysis/passes/unusedresult/doc.go | 19 - .../passes/unusedresult/unusedresult.go | 161 - .../go/analysis/passes/unusedwrite/doc.go | 34 - .../passes/unusedwrite/unusedwrite.go | 153 - .../x/tools/go/analysis/validate.go | 137 - .../x/tools/go/ast/astutil/enclosing.go | 654 - .../x/tools/go/ast/astutil/imports.go | 485 - .../x/tools/go/ast/astutil/rewrite.go | 486 - .../golang.org/x/tools/go/ast/astutil/util.go | 19 - .../x/tools/go/ast/inspector/inspector.go | 220 - .../x/tools/go/ast/inspector/typeof.go | 227 - .../x/tools/go/buildutil/allpackages.go | 195 - .../x/tools/go/buildutil/fakecontext.go | 111 - .../x/tools/go/buildutil/overlay.go | 101 - .../golang.org/x/tools/go/buildutil/tags.go | 100 - .../golang.org/x/tools/go/buildutil/util.go | 209 - .../x/tools/go/callgraph/callgraph.go | 129 - .../x/tools/go/callgraph/cha/cha.go | 164 - .../golang.org/x/tools/go/callgraph/util.go | 180 - .../x/tools/go/callgraph/vta/graph.go | 812 - .../go/callgraph/vta/internal/trie/bits.go | 127 - .../go/callgraph/vta/internal/trie/builder.go | 516 - .../go/callgraph/vta/internal/trie/scope.go | 28 - .../go/callgraph/vta/internal/trie/trie.go | 229 - .../x/tools/go/callgraph/vta/propagation.go | 198 - .../x/tools/go/callgraph/vta/utils.go | 199 - .../x/tools/go/callgraph/vta/vta.go | 198 - vendor/golang.org/x/tools/go/cfg/builder.go | 513 - vendor/golang.org/x/tools/go/cfg/cfg.go | 247 - .../x/tools/go/gcexportdata/gcexportdata.go | 186 - .../x/tools/go/gcexportdata/importer.go | 75 - .../golang.org/x/tools/go/internal/cgo/cgo.go | 219 - .../x/tools/go/internal/cgo/cgo_pkgconfig.go | 42 - vendor/golang.org/x/tools/go/loader/doc.go | 202 - vendor/golang.org/x/tools/go/loader/loader.go | 1066 - vendor/golang.org/x/tools/go/loader/util.go | 123 - vendor/golang.org/x/tools/go/packages/doc.go | 242 - .../x/tools/go/packages/external.go | 156 - .../golang.org/x/tools/go/packages/golist.go | 1066 - .../x/tools/go/packages/golist_overlay.go | 83 - .../x/tools/go/packages/loadmode_string.go | 57 - .../x/tools/go/packages/packages.go | 1515 - .../golang.org/x/tools/go/packages/visit.go | 68 - vendor/golang.org/x/tools/go/ssa/TODO | 16 - vendor/golang.org/x/tools/go/ssa/block.go | 113 - vendor/golang.org/x/tools/go/ssa/blockopt.go | 183 - vendor/golang.org/x/tools/go/ssa/builder.go | 3276 -- vendor/golang.org/x/tools/go/ssa/const.go | 232 - vendor/golang.org/x/tools/go/ssa/coretype.go | 161 - vendor/golang.org/x/tools/go/ssa/create.go | 318 - vendor/golang.org/x/tools/go/ssa/doc.go | 122 - vendor/golang.org/x/tools/go/ssa/dom.go | 340 - vendor/golang.org/x/tools/go/ssa/emit.go | 614 - vendor/golang.org/x/tools/go/ssa/func.go | 816 - .../golang.org/x/tools/go/ssa/instantiate.go | 131 - vendor/golang.org/x/tools/go/ssa/lift.go | 688 - vendor/golang.org/x/tools/go/ssa/lvalue.go | 155 - vendor/golang.org/x/tools/go/ssa/methods.go | 281 - vendor/golang.org/x/tools/go/ssa/mode.go | 111 - vendor/golang.org/x/tools/go/ssa/print.go | 470 - vendor/golang.org/x/tools/go/ssa/sanity.go | 560 - vendor/golang.org/x/tools/go/ssa/source.go | 288 - vendor/golang.org/x/tools/go/ssa/ssa.go | 1871 - .../golang.org/x/tools/go/ssa/ssautil/load.go | 214 - .../x/tools/go/ssa/ssautil/switch.go | 230 - .../x/tools/go/ssa/ssautil/visit.go | 157 - vendor/golang.org/x/tools/go/ssa/subst.go | 642 - vendor/golang.org/x/tools/go/ssa/task.go | 103 - vendor/golang.org/x/tools/go/ssa/util.go | 430 - .../golang.org/x/tools/go/ssa/util_go120.go | 17 - vendor/golang.org/x/tools/go/ssa/wrappers.go | 348 - .../x/tools/go/types/objectpath/objectpath.go | 788 - .../x/tools/go/types/typeutil/callee.go | 69 - .../x/tools/go/types/typeutil/imports.go | 30 - .../x/tools/go/types/typeutil/map.go | 518 - .../tools/go/types/typeutil/methodsetcache.go | 73 - .../x/tools/go/types/typeutil/ui.go | 55 - vendor/golang.org/x/tools/imports/forward.go | 77 - .../x/tools/internal/aliases/aliases.go | 32 - .../x/tools/internal/aliases/aliases_go121.go | 35 - .../x/tools/internal/aliases/aliases_go122.go | 99 - .../internal/analysisinternal/analysis.go | 513 - .../internal/analysisinternal/extractdoc.go | 113 - .../x/tools/internal/event/core/event.go | 85 - .../x/tools/internal/event/core/export.go | 70 - .../x/tools/internal/event/core/fast.go | 77 - .../golang.org/x/tools/internal/event/doc.go | 7 - .../x/tools/internal/event/event.go | 127 - .../x/tools/internal/event/keys/keys.go | 564 - .../x/tools/internal/event/keys/standard.go | 22 - .../x/tools/internal/event/keys/util.go | 21 - .../x/tools/internal/event/label/label.go | 215 - .../x/tools/internal/gcimporter/bimport.go | 150 - .../x/tools/internal/gcimporter/exportdata.go | 99 - .../x/tools/internal/gcimporter/gcimporter.go | 266 - .../x/tools/internal/gcimporter/iexport.go | 1332 - .../x/tools/internal/gcimporter/iimport.go | 1100 - .../internal/gcimporter/newInterface10.go | 22 - .../internal/gcimporter/newInterface11.go | 14 - .../internal/gcimporter/support_go118.go | 34 - .../x/tools/internal/gcimporter/unified_no.go | 10 - .../tools/internal/gcimporter/unified_yes.go | 10 - .../tools/internal/gcimporter/ureader_yes.go | 728 - .../x/tools/internal/gocommand/invoke.go | 555 - .../x/tools/internal/gocommand/vendor.go | 163 - .../x/tools/internal/gocommand/version.go | 71 - .../x/tools/internal/gopathwalk/walk.go | 337 - .../x/tools/internal/imports/fix.go | 1963 - .../x/tools/internal/imports/imports.go | 354 - .../x/tools/internal/imports/mod.go | 837 - .../x/tools/internal/imports/mod_cache.go | 331 - .../x/tools/internal/imports/sortimports.go | 297 - .../internal/packagesinternal/packages.go | 22 - .../x/tools/internal/pkgbits/codes.go | 77 - .../x/tools/internal/pkgbits/decoder.go | 517 - .../x/tools/internal/pkgbits/doc.go | 32 - .../x/tools/internal/pkgbits/encoder.go | 383 - .../x/tools/internal/pkgbits/flags.go | 9 - .../x/tools/internal/pkgbits/frames_go1.go | 21 - .../x/tools/internal/pkgbits/frames_go17.go | 28 - .../x/tools/internal/pkgbits/reloc.go | 42 - .../x/tools/internal/pkgbits/support.go | 17 - .../x/tools/internal/pkgbits/sync.go | 113 - .../internal/pkgbits/syncmarker_string.go | 89 - .../x/tools/internal/stdlib/manifest.go | 17431 --------- .../x/tools/internal/stdlib/stdlib.go | 97 - .../internal/tokeninternal/tokeninternal.go | 137 - .../x/tools/internal/typeparams/common.go | 142 - .../x/tools/internal/typeparams/coretype.go | 150 - .../x/tools/internal/typeparams/free.go | 120 - .../x/tools/internal/typeparams/normalize.go | 218 - .../x/tools/internal/typeparams/termlist.go | 163 - .../x/tools/internal/typeparams/typeterm.go | 169 - .../tools/internal/typesinternal/errorcode.go | 1560 - .../typesinternal/errorcode_string.go | 179 - .../x/tools/internal/typesinternal/recv.go | 43 - .../x/tools/internal/typesinternal/toonew.go | 89 - .../x/tools/internal/typesinternal/types.go | 65 - .../x/tools/internal/versions/constraint.go | 13 - .../internal/versions/constraint_go121.go | 14 - .../x/tools/internal/versions/features.go | 43 - .../x/tools/internal/versions/gover.go | 172 - .../x/tools/internal/versions/toolchain.go | 14 - .../internal/versions/toolchain_go119.go | 14 - .../internal/versions/toolchain_go120.go | 14 - .../internal/versions/toolchain_go121.go | 14 - .../x/tools/internal/versions/types.go | 19 - .../x/tools/internal/versions/types_go121.go | 30 - .../x/tools/internal/versions/types_go122.go | 41 - .../x/tools/internal/versions/versions.go | 57 - vendor/golang.org/x/vuln/LICENSE | 27 - vendor/golang.org/x/vuln/PATENTS | 22 - .../golang.org/x/vuln/cmd/govulncheck/doc.go | 103 - .../golang.org/x/vuln/cmd/govulncheck/main.go | 34 - .../x/vuln/cmd/govulncheck/test_utils.go | 125 - .../x/vuln/internal/buildinfo/README.md | 9 - .../internal/buildinfo/additions_buildinfo.go | 257 - .../vuln/internal/buildinfo/additions_scan.go | 160 - .../x/vuln/internal/buildinfo/buildinfo.go | 221 - .../x/vuln/internal/client/client.go | 347 - .../x/vuln/internal/client/index.go | 120 - .../x/vuln/internal/client/schema.go | 77 - .../x/vuln/internal/client/source.go | 150 - .../x/vuln/internal/derrors/derrors.go | 23 - .../x/vuln/internal/gosym/README.md | 11 - .../x/vuln/internal/gosym/additions.go | 184 - .../x/vuln/internal/gosym/pclntab.go | 704 - .../x/vuln/internal/gosym/symtab.go | 776 - .../x/vuln/internal/goversion/asm.go | 349 - .../x/vuln/internal/goversion/exe.go | 324 - .../x/vuln/internal/goversion/read.go | 246 - .../vuln/internal/govulncheck/govulncheck.go | 217 - .../x/vuln/internal/govulncheck/handler.go | 59 - .../vuln/internal/govulncheck/jsonhandler.go | 44 - vendor/golang.org/x/vuln/internal/internal.go | 32 - .../x/vuln/internal/openvex/handler.go | 186 - .../golang.org/x/vuln/internal/openvex/vex.go | 108 - vendor/golang.org/x/vuln/internal/osv/osv.go | 240 - .../x/vuln/internal/osv/review_status.go | 67 - .../x/vuln/internal/sarif/handler.go | 395 - .../golang.org/x/vuln/internal/sarif/sarif.go | 213 - .../golang.org/x/vuln/internal/sarif/utils.go | 46 - .../golang.org/x/vuln/internal/scan/binary.go | 99 - .../golang.org/x/vuln/internal/scan/color.go | 97 - .../golang.org/x/vuln/internal/scan/errors.go | 67 - .../x/vuln/internal/scan/extract.go | 60 - .../x/vuln/internal/scan/filepath.go | 35 - .../golang.org/x/vuln/internal/scan/flags.go | 303 - .../golang.org/x/vuln/internal/scan/query.go | 74 - vendor/golang.org/x/vuln/internal/scan/run.go | 160 - .../golang.org/x/vuln/internal/scan/source.go | 102 - .../golang.org/x/vuln/internal/scan/stdlib.go | 71 - .../x/vuln/internal/scan/template.go | 280 - .../golang.org/x/vuln/internal/scan/text.go | 507 - .../golang.org/x/vuln/internal/scan/util.go | 60 - .../x/vuln/internal/semver/affects.go | 94 - .../x/vuln/internal/semver/fixed.go | 36 - .../x/vuln/internal/semver/semver.go | 95 - .../x/vuln/internal/traces/traces.go | 46 - .../x/vuln/internal/vulncheck/binary.go | 183 - .../x/vuln/internal/vulncheck/doc.go | 54 - .../x/vuln/internal/vulncheck/emit.go | 198 - .../x/vuln/internal/vulncheck/entries.go | 56 - .../x/vuln/internal/vulncheck/fetch.go | 42 - .../x/vuln/internal/vulncheck/packages.go | 252 - .../x/vuln/internal/vulncheck/slicing.go | 55 - .../x/vuln/internal/vulncheck/source.go | 308 - .../x/vuln/internal/vulncheck/utils.go | 353 - .../x/vuln/internal/vulncheck/vulncheck.go | 329 - .../x/vuln/internal/vulncheck/witness.go | 449 - vendor/golang.org/x/vuln/internal/web/url.go | 143 - vendor/golang.org/x/vuln/scan/scan.go | 106 - vendor/golang.org/x/xerrors/LICENSE | 27 - vendor/golang.org/x/xerrors/PATENTS | 22 - vendor/golang.org/x/xerrors/README | 2 - vendor/golang.org/x/xerrors/adaptor.go | 193 - vendor/golang.org/x/xerrors/codereview.cfg | 1 - vendor/golang.org/x/xerrors/doc.go | 23 - vendor/golang.org/x/xerrors/errors.go | 33 - vendor/golang.org/x/xerrors/fmt.go | 190 - vendor/golang.org/x/xerrors/format.go | 34 - vendor/golang.org/x/xerrors/frame.go | 56 - .../golang.org/x/xerrors/internal/internal.go | 8 - vendor/golang.org/x/xerrors/wrap.go | 112 - .../genproto/googleapis/rpc/LICENSE | 202 - .../googleapis/rpc/status/status.pb.go | 203 - vendor/google.golang.org/grpc/AUTHORS | 1 - .../google.golang.org/grpc/CODE-OF-CONDUCT.md | 3 - vendor/google.golang.org/grpc/CONTRIBUTING.md | 73 - vendor/google.golang.org/grpc/GOVERNANCE.md | 1 - vendor/google.golang.org/grpc/LICENSE | 202 - vendor/google.golang.org/grpc/MAINTAINERS.md | 36 - vendor/google.golang.org/grpc/Makefile | 49 - vendor/google.golang.org/grpc/NOTICE.txt | 13 - vendor/google.golang.org/grpc/README.md | 107 - vendor/google.golang.org/grpc/SECURITY.md | 3 - .../grpc/attributes/attributes.go | 141 - vendor/google.golang.org/grpc/backoff.go | 61 - .../google.golang.org/grpc/backoff/backoff.go | 52 - .../grpc/balancer/balancer.go | 464 - .../grpc/balancer/base/balancer.go | 264 - .../grpc/balancer/base/base.go | 71 - .../grpc/balancer/conn_state_evaluator.go | 74 - .../grpc/balancer/grpclb/state/state.go | 51 - .../grpc/balancer/pickfirst/pickfirst.go | 283 - .../grpc/balancer/roundrobin/roundrobin.go | 81 - .../grpc/balancer_wrapper.go | 365 - .../grpc_binarylog_v1/binarylog.pb.go | 1183 - vendor/google.golang.org/grpc/call.go | 74 - .../grpc/channelz/channelz.go | 36 - vendor/google.golang.org/grpc/clientconn.go | 1827 - .../grpc/cmd/protoc-gen-go-grpc/LICENSE | 202 - .../grpc/cmd/protoc-gen-go-grpc/README.md | 21 - .../grpc/cmd/protoc-gen-go-grpc/grpc.go | 535 - .../grpc/cmd/protoc-gen-go-grpc/main.go | 71 - vendor/google.golang.org/grpc/codec.go | 105 - .../grpc/codes/code_string.go | 111 - vendor/google.golang.org/grpc/codes/codes.go | 250 - .../grpc/connectivity/connectivity.go | 94 - .../grpc/credentials/credentials.go | 291 - .../grpc/credentials/insecure/insecure.go | 98 - .../google.golang.org/grpc/credentials/tls.go | 283 - vendor/google.golang.org/grpc/dialoptions.go | 765 - vendor/google.golang.org/grpc/doc.go | 26 - .../grpc/encoding/encoding.go | 131 - .../grpc/encoding/encoding_v2.go | 81 - .../grpc/encoding/proto/proto.go | 96 - .../grpc/experimental/stats/metricregistry.go | 270 - .../grpc/experimental/stats/metrics.go | 114 - .../grpc/grpclog/component.go | 115 - .../google.golang.org/grpc/grpclog/grpclog.go | 186 - .../grpc/grpclog/internal/grpclog.go | 26 - .../grpc/grpclog/internal/logger.go | 87 - .../grpc/grpclog/internal/loggerv2.go | 204 - .../google.golang.org/grpc/grpclog/logger.go | 34 - .../grpc/grpclog/loggerv2.go | 97 - vendor/google.golang.org/grpc/interceptor.go | 104 - .../grpc/internal/backoff/backoff.go | 109 - .../balancer/gracefulswitch/config.go | 82 - .../balancer/gracefulswitch/gracefulswitch.go | 419 - .../grpc/internal/balancerload/load.go | 46 - .../grpc/internal/binarylog/binarylog.go | 192 - .../internal/binarylog/binarylog_testutil.go | 42 - .../grpc/internal/binarylog/env_config.go | 208 - .../grpc/internal/binarylog/method_logger.go | 446 - .../grpc/internal/binarylog/sink.go | 170 - .../grpc/internal/buffer/unbounded.go | 116 - .../grpc/internal/channelz/channel.go | 255 - .../grpc/internal/channelz/channelmap.go | 402 - .../grpc/internal/channelz/funcs.go | 230 - .../grpc/internal/channelz/logging.go | 75 - .../grpc/internal/channelz/server.go | 119 - .../grpc/internal/channelz/socket.go | 130 - .../grpc/internal/channelz/subchannel.go | 151 - .../grpc/internal/channelz/syscall_linux.go | 65 - .../internal/channelz/syscall_nonlinux.go | 47 - .../grpc/internal/channelz/trace.go | 204 - .../grpc/internal/credentials/credentials.go | 49 - .../grpc/internal/credentials/spiffe.go | 75 - .../grpc/internal/credentials/syscallconn.go | 58 - .../grpc/internal/credentials/util.go | 52 - .../grpc/internal/envconfig/envconfig.go | 76 - .../grpc/internal/envconfig/observability.go | 42 - .../grpc/internal/envconfig/xds.go | 56 - .../grpc/internal/experimental.go | 28 - .../grpc/internal/grpclog/prefix_logger.go | 79 - .../internal/grpcsync/callback_serializer.go | 112 - .../grpc/internal/grpcsync/event.go | 61 - .../grpc/internal/grpcsync/oncefunc.go | 32 - .../grpc/internal/grpcsync/pubsub.go | 121 - .../grpc/internal/grpcutil/compressor.go | 42 - .../grpc/internal/grpcutil/encode_duration.go | 63 - .../grpc/internal/grpcutil/grpcutil.go | 20 - .../grpc/internal/grpcutil/metadata.go | 40 - .../grpc/internal/grpcutil/method.go | 88 - .../grpc/internal/grpcutil/regex.go | 31 - .../grpc/internal/idle/idle.go | 278 - .../grpc/internal/internal.go | 260 - .../grpc/internal/metadata/metadata.go | 132 - .../grpc/internal/pretty/pretty.go | 73 - .../grpc/internal/resolver/config_selector.go | 167 - .../internal/resolver/dns/dns_resolver.go | 458 - .../resolver/dns/internal/internal.go | 77 - .../resolver/passthrough/passthrough.go | 64 - .../grpc/internal/resolver/unix/unix.go | 78 - .../grpc/internal/serviceconfig/duration.go | 130 - .../internal/serviceconfig/serviceconfig.go | 180 - .../grpc/internal/stats/labels.go | 42 - .../internal/stats/metrics_recorder_list.go | 95 - .../grpc/internal/status/status.go | 205 - .../grpc/internal/syscall/syscall_linux.go | 112 - .../grpc/internal/syscall/syscall_nonlinux.go | 77 - .../grpc/internal/tcp_keepalive_others.go | 29 - .../grpc/internal/tcp_keepalive_unix.go | 54 - .../grpc/internal/tcp_keepalive_windows.go | 54 - .../grpc/internal/transport/bdp_estimator.go | 141 - .../grpc/internal/transport/controlbuf.go | 1042 - .../grpc/internal/transport/defaults.go | 55 - .../grpc/internal/transport/flowcontrol.go | 215 - .../grpc/internal/transport/handler_server.go | 502 - .../grpc/internal/transport/http2_client.go | 1831 - .../grpc/internal/transport/http2_server.go | 1475 - .../grpc/internal/transport/http_util.go | 468 - .../grpc/internal/transport/logging.go | 40 - .../transport/networktype/networktype.go | 46 - .../grpc/internal/transport/proxy.go | 150 - .../grpc/internal/transport/transport.go | 934 - .../grpc/keepalive/keepalive.go | 85 - .../google.golang.org/grpc/mem/buffer_pool.go | 194 - .../grpc/mem/buffer_slice.go | 224 - vendor/google.golang.org/grpc/mem/buffers.go | 252 - .../grpc/metadata/metadata.go | 295 - vendor/google.golang.org/grpc/peer/peer.go | 83 - .../google.golang.org/grpc/picker_wrapper.go | 219 - vendor/google.golang.org/grpc/preloader.go | 85 - .../grpc/resolver/dns/dns_resolver.go | 60 - vendor/google.golang.org/grpc/resolver/map.go | 251 - .../grpc/resolver/resolver.go | 332 - .../grpc/resolver_wrapper.go | 201 - vendor/google.golang.org/grpc/rpc_util.go | 1069 - vendor/google.golang.org/grpc/server.go | 2207 -- .../google.golang.org/grpc/service_config.go | 356 - .../grpc/serviceconfig/serviceconfig.go | 44 - .../google.golang.org/grpc/stats/handlers.go | 63 - vendor/google.golang.org/grpc/stats/stats.go | 343 - .../google.golang.org/grpc/status/status.go | 162 - vendor/google.golang.org/grpc/stream.go | 1841 - .../grpc/stream_interfaces.go | 152 - vendor/google.golang.org/grpc/tap/tap.go | 62 - vendor/google.golang.org/grpc/trace.go | 143 - .../google.golang.org/grpc/trace_notrace.go | 52 - .../google.golang.org/grpc/trace_withtrace.go | 39 - vendor/google.golang.org/grpc/version.go | 22 - vendor/google.golang.org/protobuf/LICENSE | 27 - vendor/google.golang.org/protobuf/PATENTS | 22 - .../cmd/protoc-gen-go/internal_gengo/init.go | 168 - .../cmd/protoc-gen-go/internal_gengo/main.go | 908 - .../protoc-gen-go/internal_gengo/reflect.go | 372 - .../internal_gengo/well_known_types.go | 1079 - .../protobuf/cmd/protoc-gen-go/main.go | 58 - .../protobuf/compiler/protogen/protogen.go | 1398 - .../encoding/protodelim/protodelim.go | 160 - .../protobuf/encoding/protojson/decode.go | 685 - .../protobuf/encoding/protojson/doc.go | 11 - .../protobuf/encoding/protojson/encode.go | 382 - .../encoding/protojson/well_known_types.go | 876 - .../protobuf/encoding/prototext/decode.go | 772 - .../protobuf/encoding/prototext/doc.go | 7 - .../protobuf/encoding/prototext/encode.go | 380 - .../protobuf/encoding/protowire/wire.go | 547 - .../protobuf/internal/descfmt/stringer.go | 414 - .../protobuf/internal/descopts/options.go | 29 - .../protobuf/internal/detrand/rand.go | 69 - .../internal/editiondefaults/defaults.go | 12 - .../editiondefaults/editions_defaults.binpb | Bin 93 -> 0 bytes .../internal/editionssupport/editions.go | 13 - .../internal/encoding/defval/default.go | 213 - .../protobuf/internal/encoding/json/decode.go | 340 - .../internal/encoding/json/decode_number.go | 254 - .../internal/encoding/json/decode_string.go | 91 - .../internal/encoding/json/decode_token.go | 192 - .../protobuf/internal/encoding/json/encode.go | 278 - .../encoding/messageset/messageset.go | 242 - .../protobuf/internal/encoding/tag/tag.go | 207 - .../protobuf/internal/encoding/text/decode.go | 686 - .../internal/encoding/text/decode_number.go | 211 - .../internal/encoding/text/decode_string.go | 161 - .../internal/encoding/text/decode_token.go | 373 - .../protobuf/internal/encoding/text/doc.go | 29 - .../protobuf/internal/encoding/text/encode.go | 272 - .../protobuf/internal/errors/errors.go | 104 - .../protobuf/internal/errors/is_go112.go | 40 - .../protobuf/internal/errors/is_go113.go | 13 - .../protobuf/internal/filedesc/build.go | 157 - .../protobuf/internal/filedesc/desc.go | 733 - .../protobuf/internal/filedesc/desc_init.go | 558 - .../protobuf/internal/filedesc/desc_lazy.go | 701 - .../protobuf/internal/filedesc/desc_list.go | 457 - .../internal/filedesc/desc_list_gen.go | 367 - .../protobuf/internal/filedesc/editions.go | 156 - .../protobuf/internal/filedesc/placeholder.go | 110 - .../protobuf/internal/filetype/build.go | 296 - .../protobuf/internal/flags/flags.go | 24 - .../internal/flags/proto_legacy_disable.go | 10 - .../internal/flags/proto_legacy_enable.go | 10 - .../protobuf/internal/genid/any_gen.go | 34 - .../protobuf/internal/genid/api_gen.go | 106 - .../protobuf/internal/genid/descriptor_gen.go | 1270 - .../protobuf/internal/genid/doc.go | 11 - .../protobuf/internal/genid/duration_gen.go | 34 - .../protobuf/internal/genid/empty_gen.go | 19 - .../protobuf/internal/genid/field_mask_gen.go | 31 - .../internal/genid/go_features_gen.go | 31 - .../protobuf/internal/genid/goname.go | 25 - .../protobuf/internal/genid/map_entry.go | 16 - .../internal/genid/source_context_gen.go | 31 - .../protobuf/internal/genid/struct_gen.go | 121 - .../protobuf/internal/genid/timestamp_gen.go | 34 - .../protobuf/internal/genid/type_gen.go | 228 - .../protobuf/internal/genid/wrappers.go | 13 - .../protobuf/internal/genid/wrappers_gen.go | 175 - .../protobuf/internal/impl/api_export.go | 177 - .../protobuf/internal/impl/checkinit.go | 141 - .../protobuf/internal/impl/codec_extension.go | 237 - .../protobuf/internal/impl/codec_field.go | 860 - .../protobuf/internal/impl/codec_gen.go | 5724 --- .../protobuf/internal/impl/codec_map.go | 399 - .../protobuf/internal/impl/codec_map_go111.go | 38 - .../protobuf/internal/impl/codec_map_go112.go | 12 - .../protobuf/internal/impl/codec_message.go | 217 - .../internal/impl/codec_messageset.go | 145 - .../protobuf/internal/impl/codec_reflect.go | 210 - .../protobuf/internal/impl/codec_tables.go | 557 - .../protobuf/internal/impl/codec_unsafe.go | 18 - .../protobuf/internal/impl/convert.go | 495 - .../protobuf/internal/impl/convert_list.go | 141 - .../protobuf/internal/impl/convert_map.go | 121 - .../protobuf/internal/impl/decode.go | 285 - .../protobuf/internal/impl/encode.go | 237 - .../protobuf/internal/impl/enum.go | 21 - .../protobuf/internal/impl/extension.go | 156 - .../protobuf/internal/impl/legacy_enum.go | 219 - .../protobuf/internal/impl/legacy_export.go | 92 - .../internal/impl/legacy_extension.go | 176 - .../protobuf/internal/impl/legacy_file.go | 81 - .../protobuf/internal/impl/legacy_message.go | 572 - .../protobuf/internal/impl/merge.go | 176 - .../protobuf/internal/impl/merge_gen.go | 209 - .../protobuf/internal/impl/message.go | 284 - .../protobuf/internal/impl/message_reflect.go | 462 - .../internal/impl/message_reflect_field.go | 543 - .../internal/impl/message_reflect_gen.go | 271 - .../protobuf/internal/impl/pointer_reflect.go | 215 - .../protobuf/internal/impl/pointer_unsafe.go | 215 - .../protobuf/internal/impl/validate.go | 576 - .../protobuf/internal/impl/weak.go | 74 - .../protobuf/internal/msgfmt/format.go | 261 - .../protobuf/internal/order/order.go | 89 - .../protobuf/internal/order/range.go | 115 - .../protobuf/internal/pragma/pragma.go | 29 - .../protobuf/internal/set/ints.go | 58 - .../protobuf/internal/strs/strings.go | 196 - .../protobuf/internal/strs/strings_pure.go | 28 - .../internal/strs/strings_unsafe_go120.go | 95 - .../internal/strs/strings_unsafe_go121.go | 74 - .../protobuf/internal/version/version.go | 79 - .../protobuf/proto/checkinit.go | 71 - .../protobuf/proto/decode.go | 296 - .../protobuf/proto/decode_gen.go | 603 - .../google.golang.org/protobuf/proto/doc.go | 86 - .../protobuf/proto/encode.go | 354 - .../protobuf/proto/encode_gen.go | 97 - .../google.golang.org/protobuf/proto/equal.go | 57 - .../protobuf/proto/extension.go | 95 - .../google.golang.org/protobuf/proto/merge.go | 139 - .../protobuf/proto/messageset.go | 98 - .../google.golang.org/protobuf/proto/proto.go | 45 - .../protobuf/proto/proto_methods.go | 20 - .../protobuf/proto/proto_reflect.go | 20 - .../google.golang.org/protobuf/proto/reset.go | 43 - .../google.golang.org/protobuf/proto/size.go | 103 - .../protobuf/proto/size_gen.go | 55 - .../protobuf/proto/wrappers.go | 29 - .../protobuf/protoadapt/convert.go | 31 - .../protobuf/reflect/protodesc/desc.go | 286 - .../protobuf/reflect/protodesc/desc_init.go | 285 - .../reflect/protodesc/desc_resolve.go | 291 - .../reflect/protodesc/desc_validate.go | 371 - .../protobuf/reflect/protodesc/editions.go | 145 - .../protobuf/reflect/protodesc/proto.go | 274 - .../protobuf/reflect/protopath/path.go | 122 - .../protobuf/reflect/protopath/step.go | 241 - .../protobuf/reflect/protorange/range.go | 316 - .../protobuf/reflect/protoreflect/methods.go | 78 - .../protobuf/reflect/protoreflect/proto.go | 513 - .../protobuf/reflect/protoreflect/source.go | 129 - .../reflect/protoreflect/source_gen.go | 573 - .../protobuf/reflect/protoreflect/type.go | 672 - .../protobuf/reflect/protoreflect/value.go | 285 - .../reflect/protoreflect/value_equal.go | 168 - .../reflect/protoreflect/value_pure.go | 60 - .../reflect/protoreflect/value_union.go | 438 - .../protoreflect/value_unsafe_go120.go | 99 - .../protoreflect/value_unsafe_go121.go | 87 - .../reflect/protoregistry/registry.go | 882 - .../protobuf/runtime/protoiface/legacy.go | 15 - .../protobuf/runtime/protoiface/methods.go | 168 - .../protobuf/runtime/protoimpl/impl.go | 44 - .../protobuf/runtime/protoimpl/version.go | 60 - .../types/descriptorpb/descriptor.pb.go | 5825 --- .../protobuf/types/dynamicpb/dynamic.go | 718 - .../protobuf/types/dynamicpb/types.go | 184 - .../types/gofeaturespb/go_features.pb.go | 181 - .../protobuf/types/known/anypb/any.pb.go | 496 - .../types/known/durationpb/duration.pb.go | 374 - .../types/known/timestamppb/timestamp.pb.go | 383 - .../protobuf/types/pluginpb/plugin.pb.go | 690 - vendor/gopkg.in/ini.v1/.editorconfig | 12 - vendor/gopkg.in/ini.v1/.gitignore | 7 - vendor/gopkg.in/ini.v1/.golangci.yml | 27 - vendor/gopkg.in/ini.v1/LICENSE | 191 - vendor/gopkg.in/ini.v1/Makefile | 15 - vendor/gopkg.in/ini.v1/README.md | 43 - vendor/gopkg.in/ini.v1/codecov.yml | 16 - vendor/gopkg.in/ini.v1/data_source.go | 76 - vendor/gopkg.in/ini.v1/deprecated.go | 22 - vendor/gopkg.in/ini.v1/error.go | 49 - vendor/gopkg.in/ini.v1/file.go | 541 - vendor/gopkg.in/ini.v1/helper.go | 24 - vendor/gopkg.in/ini.v1/ini.go | 176 - vendor/gopkg.in/ini.v1/key.go | 837 - vendor/gopkg.in/ini.v1/parser.go | 520 - vendor/gopkg.in/ini.v1/section.go | 256 - vendor/gopkg.in/ini.v1/struct.go | 747 - vendor/gopkg.in/yaml.v2/.travis.yml | 17 - vendor/gopkg.in/yaml.v2/LICENSE | 201 - vendor/gopkg.in/yaml.v2/LICENSE.libyaml | 31 - vendor/gopkg.in/yaml.v2/NOTICE | 13 - vendor/gopkg.in/yaml.v2/README.md | 133 - vendor/gopkg.in/yaml.v2/apic.go | 744 - vendor/gopkg.in/yaml.v2/decode.go | 815 - vendor/gopkg.in/yaml.v2/emitterc.go | 1685 - vendor/gopkg.in/yaml.v2/encode.go | 390 - vendor/gopkg.in/yaml.v2/parserc.go | 1095 - vendor/gopkg.in/yaml.v2/readerc.go | 412 - vendor/gopkg.in/yaml.v2/resolve.go | 258 - vendor/gopkg.in/yaml.v2/scannerc.go | 2711 -- vendor/gopkg.in/yaml.v2/sorter.go | 113 - vendor/gopkg.in/yaml.v2/writerc.go | 26 - vendor/gopkg.in/yaml.v2/yaml.go | 478 - vendor/gopkg.in/yaml.v2/yamlh.go | 739 - vendor/gopkg.in/yaml.v2/yamlprivateh.go | 173 - vendor/gopkg.in/yaml.v3/LICENSE | 50 - vendor/gopkg.in/yaml.v3/NOTICE | 13 - vendor/gopkg.in/yaml.v3/README.md | 150 - vendor/gopkg.in/yaml.v3/apic.go | 747 - vendor/gopkg.in/yaml.v3/decode.go | 1000 - vendor/gopkg.in/yaml.v3/emitterc.go | 2020 - vendor/gopkg.in/yaml.v3/encode.go | 577 - vendor/gopkg.in/yaml.v3/parserc.go | 1258 - vendor/gopkg.in/yaml.v3/readerc.go | 434 - vendor/gopkg.in/yaml.v3/resolve.go | 326 - vendor/gopkg.in/yaml.v3/scannerc.go | 3038 -- vendor/gopkg.in/yaml.v3/sorter.go | 134 - vendor/gopkg.in/yaml.v3/writerc.go | 48 - vendor/gopkg.in/yaml.v3/yaml.go | 698 - vendor/gopkg.in/yaml.v3/yamlh.go | 807 - vendor/gopkg.in/yaml.v3/yamlprivateh.go | 198 - vendor/honnef.co/go/tools/LICENSE | 20 - vendor/honnef.co/go/tools/LICENSE-THIRD-PARTY | 121 - .../go/tools/analysis/callcheck/callcheck.go | 161 - .../honnef.co/go/tools/analysis/code/code.go | 593 - .../honnef.co/go/tools/analysis/code/visit.go | 51 - .../honnef.co/go/tools/analysis/edit/edit.go | 83 - .../analysis/facts/deprecated/deprecated.go | 154 - .../analysis/facts/directives/directives.go | 20 - .../analysis/facts/generated/generated.go | 97 - .../tools/analysis/facts/nilness/nilness.go | 255 - .../go/tools/analysis/facts/purity/purity.go | 264 - .../tools/analysis/facts/tokenfile/token.go | 24 - .../analysis/facts/typedness/typedness.go | 253 - .../honnef.co/go/tools/analysis/lint/lint.go | 221 - .../go/tools/analysis/report/report.go | 281 - vendor/honnef.co/go/tools/config/config.go | 266 - vendor/honnef.co/go/tools/config/example.conf | 14 - .../go/tools/go/ast/astutil/upstream.go | 20 - .../honnef.co/go/tools/go/ast/astutil/util.go | 473 - vendor/honnef.co/go/tools/go/ir/LICENSE | 28 - vendor/honnef.co/go/tools/go/ir/UPSTREAM | 9 - vendor/honnef.co/go/tools/go/ir/blockopt.go | 205 - vendor/honnef.co/go/tools/go/ir/builder.go | 3461 -- vendor/honnef.co/go/tools/go/ir/const.go | 297 - vendor/honnef.co/go/tools/go/ir/create.go | 296 - vendor/honnef.co/go/tools/go/ir/doc.go | 131 - vendor/honnef.co/go/tools/go/ir/dom.go | 466 - vendor/honnef.co/go/tools/go/ir/emit.go | 639 - vendor/honnef.co/go/tools/go/ir/exits.go | 369 - vendor/honnef.co/go/tools/go/ir/func.go | 1090 - vendor/honnef.co/go/tools/go/ir/html.go | 1127 - .../honnef.co/go/tools/go/ir/irutil/load.go | 183 - .../honnef.co/go/tools/go/ir/irutil/loops.go | 54 - .../honnef.co/go/tools/go/ir/irutil/stub.go | 32 - .../honnef.co/go/tools/go/ir/irutil/switch.go | 260 - .../go/tools/go/ir/irutil/terminates.go | 70 - .../honnef.co/go/tools/go/ir/irutil/util.go | 178 - .../honnef.co/go/tools/go/ir/irutil/visit.go | 78 - vendor/honnef.co/go/tools/go/ir/lift.go | 1819 - vendor/honnef.co/go/tools/go/ir/lvalue.go | 175 - vendor/honnef.co/go/tools/go/ir/methods.go | 244 - vendor/honnef.co/go/tools/go/ir/mode.go | 104 - vendor/honnef.co/go/tools/go/ir/print.go | 539 - vendor/honnef.co/go/tools/go/ir/sanity.go | 568 - vendor/honnef.co/go/tools/go/ir/source.go | 263 - vendor/honnef.co/go/tools/go/ir/ssa.go | 2160 -- vendor/honnef.co/go/tools/go/ir/util.go | 162 - vendor/honnef.co/go/tools/go/ir/wrappers.go | 343 - vendor/honnef.co/go/tools/go/ir/write.go | 5 - .../go/tools/go/types/typeutil/ext.go | 27 - .../go/tools/go/types/typeutil/typeparams.go | 110 - .../go/tools/go/types/typeutil/upstream.go | 52 - .../go/tools/go/types/typeutil/util.go | 211 - .../tools/internal/passes/buildir/buildir.go | 107 - .../go/tools/internal/sharedcheck/lint.go | 209 - vendor/honnef.co/go/tools/knowledge/arg.go | 77 - .../go/tools/knowledge/deprecated.go | 214 - vendor/honnef.co/go/tools/knowledge/doc.go | 2 - .../go/tools/knowledge/signatures.go | 107 - .../honnef.co/go/tools/knowledge/targets.go | 38 - vendor/honnef.co/go/tools/pattern/convert.go | 243 - vendor/honnef.co/go/tools/pattern/doc.go | 272 - vendor/honnef.co/go/tools/pattern/lexer.go | 221 - vendor/honnef.co/go/tools/pattern/match.go | 714 - vendor/honnef.co/go/tools/pattern/parser.go | 526 - vendor/honnef.co/go/tools/pattern/pattern.go | 524 - vendor/honnef.co/go/tools/printf/fuzz.go | 12 - vendor/honnef.co/go/tools/printf/printf.go | 198 - vendor/honnef.co/go/tools/simple/analysis.go | 80 - vendor/honnef.co/go/tools/simple/doc.go | 6 - .../honnef.co/go/tools/simple/s1000/s1000.go | 71 - .../honnef.co/go/tools/simple/s1001/s1001.go | 197 - .../honnef.co/go/tools/simple/s1002/s1002.go | 88 - .../honnef.co/go/tools/simple/s1003/s1003.go | 118 - .../honnef.co/go/tools/simple/s1004/s1004.go | 72 - .../honnef.co/go/tools/simple/s1005/s1005.go | 108 - .../honnef.co/go/tools/simple/s1006/s1006.go | 46 - .../honnef.co/go/tools/simple/s1007/s1007.go | 93 - .../honnef.co/go/tools/simple/s1008/s1008.go | 148 - .../honnef.co/go/tools/simple/s1009/s1009.go | 185 - .../honnef.co/go/tools/simple/s1010/s1010.go | 48 - .../honnef.co/go/tools/simple/s1011/s1011.go | 144 - .../honnef.co/go/tools/simple/s1012/s1012.go | 51 - .../honnef.co/go/tools/simple/s1016/s1016.go | 189 - .../honnef.co/go/tools/simple/s1017/s1017.go | 239 - .../honnef.co/go/tools/simple/s1018/s1018.go | 84 - .../honnef.co/go/tools/simple/s1019/s1019.go | 71 - .../honnef.co/go/tools/simple/s1020/s1020.go | 86 - .../honnef.co/go/tools/simple/s1021/s1021.go | 118 - .../honnef.co/go/tools/simple/s1023/s1023.go | 79 - .../honnef.co/go/tools/simple/s1024/s1024.go | 59 - .../honnef.co/go/tools/simple/s1025/s1025.go | 158 - .../honnef.co/go/tools/simple/s1028/s1028.go | 50 - .../honnef.co/go/tools/simple/s1029/s1029.go | 31 - .../honnef.co/go/tools/simple/s1030/s1030.go | 83 - .../honnef.co/go/tools/simple/s1031/s1031.go | 79 - .../honnef.co/go/tools/simple/s1032/s1032.go | 128 - .../honnef.co/go/tools/simple/s1033/s1033.go | 55 - .../honnef.co/go/tools/simple/s1034/s1034.go | 119 - .../honnef.co/go/tools/simple/s1035/s1035.go | 56 - .../honnef.co/go/tools/simple/s1036/s1036.go | 92 - .../honnef.co/go/tools/simple/s1037/s1037.go | 59 - .../honnef.co/go/tools/simple/s1038/s1038.go | 188 - .../honnef.co/go/tools/simple/s1039/s1039.go | 71 - .../honnef.co/go/tools/simple/s1040/s1040.go | 73 - .../go/tools/staticcheck/analysis.go | 200 - vendor/honnef.co/go/tools/staticcheck/doc.go | 5 - .../go/tools/staticcheck/fakejson/encode.go | 370 - .../staticcheck/fakereflect/fakereflect.go | 131 - .../go/tools/staticcheck/fakexml/marshal.go | 375 - .../go/tools/staticcheck/fakexml/typeinfo.go | 388 - .../go/tools/staticcheck/fakexml/xml.go | 33 - .../go/tools/staticcheck/sa1000/sa1000.go | 46 - .../go/tools/staticcheck/sa1001/sa1001.go | 76 - .../go/tools/staticcheck/sa1002/sa1002.go | 45 - .../go/tools/staticcheck/sa1003/sa1003.go | 92 - .../go/tools/staticcheck/sa1004/sa1004.go | 78 - .../go/tools/staticcheck/sa1005/sa1005.go | 68 - .../go/tools/staticcheck/sa1006/sa1006.go | 107 - .../go/tools/staticcheck/sa1007/sa1007.go | 43 - .../go/tools/staticcheck/sa1008/sa1008.go | 111 - .../go/tools/staticcheck/sa1010/sa1010.go | 53 - .../go/tools/staticcheck/sa1011/sa1011.go | 47 - .../go/tools/staticcheck/sa1012/sa1012.go | 72 - .../go/tools/staticcheck/sa1013/sa1013.go | 50 - .../go/tools/staticcheck/sa1014/sa1014.go | 52 - .../go/tools/staticcheck/sa1015/sa1015.go | 69 - .../go/tools/staticcheck/sa1016/sa1016.go | 112 - .../go/tools/staticcheck/sa1017/sa1017.go | 64 - .../go/tools/staticcheck/sa1018/sa1018.go | 47 - .../go/tools/staticcheck/sa1019/sa1019.go | 212 - .../go/tools/staticcheck/sa1020/sa1020.go | 94 - .../go/tools/staticcheck/sa1021/sa1021.go | 49 - .../go/tools/staticcheck/sa1023/sa1023.go | 72 - .../go/tools/staticcheck/sa1024/sa1024.go | 75 - .../go/tools/staticcheck/sa1025/sa1025.go | 92 - .../go/tools/staticcheck/sa1026/sa1026.go | 77 - .../go/tools/staticcheck/sa1027/sa1027.go | 76 - .../go/tools/staticcheck/sa1028/sa1028.go | 57 - .../go/tools/staticcheck/sa1029/sa1029.go | 61 - .../go/tools/staticcheck/sa1030/sa1030.go | 134 - .../go/tools/staticcheck/sa1031/sa1031.go | 81 - .../go/tools/staticcheck/sa1032/sa1032.go | 79 - .../go/tools/staticcheck/sa2000/sa2000.go | 48 - .../go/tools/staticcheck/sa2001/sa2001.go | 111 - .../go/tools/staticcheck/sa2002/sa2002.go | 93 - .../go/tools/staticcheck/sa2003/sa2003.go | 87 - .../go/tools/staticcheck/sa3000/sa3000.go | 118 - .../go/tools/staticcheck/sa3001/sa3001.go | 55 - .../go/tools/staticcheck/sa4000/sa4000.go | 146 - .../go/tools/staticcheck/sa4001/sa4001.go | 52 - .../go/tools/staticcheck/sa4003/sa4003.go | 159 - .../go/tools/staticcheck/sa4004/sa4004.go | 159 - .../go/tools/staticcheck/sa4005/sa4005.go | 138 - .../go/tools/staticcheck/sa4006/sa4006.go | 155 - .../go/tools/staticcheck/sa4008/sa4008.go | 114 - .../go/tools/staticcheck/sa4009/sa4009.go | 106 - .../go/tools/staticcheck/sa4010/sa4010.go | 216 - .../go/tools/staticcheck/sa4011/sa4011.go | 88 - .../go/tools/staticcheck/sa4012/sa4012.go | 51 - .../go/tools/staticcheck/sa4013/sa4013.go | 44 - .../go/tools/staticcheck/sa4014/sa4014.go | 78 - .../go/tools/staticcheck/sa4015/sa4015.go | 56 - .../go/tools/staticcheck/sa4016/sa4016.go | 116 - .../go/tools/staticcheck/sa4017/sa4017.go | 87 - .../go/tools/staticcheck/sa4018/sa4018.go | 61 - .../go/tools/staticcheck/sa4019/sa4019.go | 82 - .../go/tools/staticcheck/sa4020/sa4020.go | 172 - .../go/tools/staticcheck/sa4021/sa4021.go | 44 - .../go/tools/staticcheck/sa4022/sa4022.go | 48 - .../go/tools/staticcheck/sa4023/sa4023.go | 205 - .../go/tools/staticcheck/sa4024/sa4024.go | 66 - .../go/tools/staticcheck/sa4025/sa4025.go | 77 - .../go/tools/staticcheck/sa4026/sa4026.go | 87 - .../go/tools/staticcheck/sa4027/sa4027.go | 64 - .../go/tools/staticcheck/sa4028/sa4028.go | 43 - .../go/tools/staticcheck/sa4029/sa4029.go | 87 - .../go/tools/staticcheck/sa4030/sa4030.go | 64 - .../go/tools/staticcheck/sa4031/sa4031.go | 162 - .../go/tools/staticcheck/sa4032/sa4032.go | 218 - .../go/tools/staticcheck/sa5000/sa5000.go | 49 - .../go/tools/staticcheck/sa5001/sa5001.go | 109 - .../go/tools/staticcheck/sa5002/sa5002.go | 74 - .../go/tools/staticcheck/sa5003/sa5003.go | 74 - .../go/tools/staticcheck/sa5004/sa5004.go | 55 - .../go/tools/staticcheck/sa5005/sa5005.go | 90 - .../go/tools/staticcheck/sa5007/sa5007.go | 77 - .../go/tools/staticcheck/sa5008/sa5008.go | 179 - .../go/tools/staticcheck/sa5008/structtag.go | 58 - .../go/tools/staticcheck/sa5009/sa5009.go | 409 - .../go/tools/staticcheck/sa5010/sa5010.go | 106 - .../go/tools/staticcheck/sa5011/sa5011.go | 221 - .../go/tools/staticcheck/sa5012/sa5012.go | 286 - .../go/tools/staticcheck/sa6000/sa6000.go | 57 - .../go/tools/staticcheck/sa6001/sa6001.go | 124 - .../go/tools/staticcheck/sa6002/sa6002.go | 52 - .../go/tools/staticcheck/sa6003/sa6003.go | 42 - .../go/tools/staticcheck/sa6005/sa6005.go | 80 - .../go/tools/staticcheck/sa6006/sa6006.go | 53 - .../go/tools/staticcheck/sa9001/sa9001.go | 69 - .../go/tools/staticcheck/sa9002/sa9002.go | 63 - .../go/tools/staticcheck/sa9003/sa9003.go | 62 - .../go/tools/staticcheck/sa9004/sa9004.go | 183 - .../go/tools/staticcheck/sa9005/sa9005.go | 94 - .../go/tools/staticcheck/sa9006/sa9006.go | 106 - .../go/tools/staticcheck/sa9007/sa9007.go | 114 - .../go/tools/staticcheck/sa9008/sa9008.go | 130 - .../go/tools/staticcheck/sa9009/sa9009.go | 68 - .../honnef.co/go/tools/stylecheck/analysis.go | 46 - vendor/honnef.co/go/tools/stylecheck/doc.go | 10 - .../go/tools/stylecheck/st1000/st1000.go | 83 - .../go/tools/stylecheck/st1001/st1001.go | 71 - .../go/tools/stylecheck/st1003/st1003.go | 310 - .../go/tools/stylecheck/st1005/st1005.go | 130 - .../go/tools/stylecheck/st1006/st1006.go | 65 - .../go/tools/stylecheck/st1008/st1008.go | 58 - .../go/tools/stylecheck/st1011/st1011.go | 88 - .../go/tools/stylecheck/st1012/st1012.go | 68 - .../go/tools/stylecheck/st1013/st1013.go | 151 - .../go/tools/stylecheck/st1015/st1015.go | 77 - .../go/tools/stylecheck/st1016/st1016.go | 74 - .../go/tools/stylecheck/st1017/st1017.go | 52 - .../go/tools/stylecheck/st1018/st1018.go | 157 - .../go/tools/stylecheck/st1019/st1019.go | 78 - .../go/tools/stylecheck/st1020/st1020.go | 101 - .../go/tools/stylecheck/st1021/st1021.go | 124 - .../go/tools/stylecheck/st1022/st1022.go | 105 - .../go/tools/stylecheck/st1023/st1023.go | 22 - .../honnef.co/go/tools/unused/implements.go | 151 - vendor/honnef.co/go/tools/unused/runtime.go | 331 - vendor/honnef.co/go/tools/unused/serialize.go | 99 - vendor/honnef.co/go/tools/unused/unused.go | 1692 - vendor/modules.txt | 1434 - vendor/mvdan.cc/gofumpt/LICENSE | 27 - vendor/mvdan.cc/gofumpt/LICENSE.google | 27 - vendor/mvdan.cc/gofumpt/format/format.go | 1075 - vendor/mvdan.cc/gofumpt/format/rewrite.go | 113 - vendor/mvdan.cc/gofumpt/format/simplify.go | 169 - .../internal/govendor/go/doc/comment/doc.go | 36 - .../internal/govendor/go/doc/comment/html.go | 169 - .../govendor/go/doc/comment/markdown.go | 188 - .../internal/govendor/go/doc/comment/parse.go | 1260 - .../internal/govendor/go/doc/comment/print.go | 288 - .../internal/govendor/go/doc/comment/std.go | 50 - .../internal/govendor/go/doc/comment/text.go | 337 - .../internal/govendor/go/format/format.go | 134 - .../internal/govendor/go/format/internal.go | 177 - .../internal/govendor/go/printer/comment.go | 156 - .../internal/govendor/go/printer/gobuild.go | 170 - .../internal/govendor/go/printer/nodes.go | 2001 - .../internal/govendor/go/printer/printer.go | 1432 - .../gofumpt/internal/version/version.go | 105 - vendor/mvdan.cc/unparam/LICENSE | 27 - vendor/mvdan.cc/unparam/check/check.go | 1025 - 4691 files changed, 1158256 deletions(-) delete mode 100644 vendor/4d63.com/gocheckcompilerdirectives/LICENSE delete mode 100644 vendor/4d63.com/gocheckcompilerdirectives/checkcompilerdirectives/checkcompilerdirectives.go delete mode 100644 vendor/4d63.com/gochecknoglobals/LICENSE delete mode 100644 vendor/4d63.com/gochecknoglobals/checknoglobals/check_no_globals.go delete mode 100644 vendor/github.com/4meepo/tagalign/.gitignore delete mode 100644 vendor/github.com/4meepo/tagalign/.golangci.yml delete mode 100644 vendor/github.com/4meepo/tagalign/.goreleaser.yml delete mode 100644 vendor/github.com/4meepo/tagalign/LICENSE delete mode 100644 vendor/github.com/4meepo/tagalign/Makefile delete mode 100644 vendor/github.com/4meepo/tagalign/README.md delete mode 100644 vendor/github.com/4meepo/tagalign/options.go delete mode 100644 vendor/github.com/4meepo/tagalign/tagalign.go delete mode 100644 vendor/github.com/Abirdcfly/dupword/.gitignore delete mode 100644 vendor/github.com/Abirdcfly/dupword/.goreleaser.yml delete mode 100644 vendor/github.com/Abirdcfly/dupword/LICENSE delete mode 100644 vendor/github.com/Abirdcfly/dupword/README.md delete mode 100644 vendor/github.com/Abirdcfly/dupword/dupword.go delete mode 100644 vendor/github.com/Abirdcfly/dupword/version.go delete mode 100644 vendor/github.com/Antonboom/errname/LICENSE delete mode 100644 vendor/github.com/Antonboom/errname/pkg/analyzer/analyzer.go delete mode 100644 vendor/github.com/Antonboom/errname/pkg/analyzer/facts.go delete mode 100644 vendor/github.com/Antonboom/nilnil/LICENSE delete mode 100644 vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go delete mode 100644 vendor/github.com/Antonboom/nilnil/pkg/analyzer/config.go delete mode 100644 vendor/github.com/Antonboom/nilnil/pkg/analyzer/func_type_stack.go delete mode 100644 vendor/github.com/Antonboom/testifylint/LICENSE delete mode 100644 vendor/github.com/Antonboom/testifylint/analyzer/analyzer.go delete mode 100644 vendor/github.com/Antonboom/testifylint/analyzer/checkers_factory.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/analysisutil/doc.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/analysisutil/file.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/analysisutil/format.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/analysisutil/object.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/analysisutil/pkg.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/blank_import.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/bool_compare.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/call_meta.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/checker.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/checkers_registry.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/compares.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/empty.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/error_is_as.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/error_nil.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/expected_actual.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/float_compare.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/formatter.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/go_require.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_basic_type.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_bool.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_comparison.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_context.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_diagnostic.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_error.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_format.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_http.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_interface.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_len.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_naming.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_nil.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_suite.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_testing.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/len.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/negative_postive.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/nil_compare.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/printf/LICENSE delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/printf/doc.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/printf/printf.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/require_error.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/suite_broken_parallel.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/suite_dont_use_pkg.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/suite_extra_assert_call.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/suite_subtest_run.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/suite_thelper.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/checkers/useless_assert.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/config/config.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/config/flag_value_types.go delete mode 100644 vendor/github.com/Antonboom/testifylint/internal/testify/const.go delete mode 100644 vendor/github.com/BurntSushi/toml/.gitignore delete mode 100644 vendor/github.com/BurntSushi/toml/COPYING delete mode 100644 vendor/github.com/BurntSushi/toml/README.md delete mode 100644 vendor/github.com/BurntSushi/toml/decode.go delete mode 100644 vendor/github.com/BurntSushi/toml/deprecated.go delete mode 100644 vendor/github.com/BurntSushi/toml/doc.go delete mode 100644 vendor/github.com/BurntSushi/toml/encode.go delete mode 100644 vendor/github.com/BurntSushi/toml/error.go delete mode 100644 vendor/github.com/BurntSushi/toml/internal/tz.go delete mode 100644 vendor/github.com/BurntSushi/toml/lex.go delete mode 100644 vendor/github.com/BurntSushi/toml/meta.go delete mode 100644 vendor/github.com/BurntSushi/toml/parse.go delete mode 100644 vendor/github.com/BurntSushi/toml/type_fields.go delete mode 100644 vendor/github.com/BurntSushi/toml/type_toml.go delete mode 100644 vendor/github.com/Crocmagnon/fatcontext/LICENSE delete mode 100644 vendor/github.com/Crocmagnon/fatcontext/pkg/analyzer/analyzer.go delete mode 100644 vendor/github.com/Djarvur/go-err113/.gitignore delete mode 100644 vendor/github.com/Djarvur/go-err113/.golangci.yml delete mode 100644 vendor/github.com/Djarvur/go-err113/.travis.yml delete mode 100644 vendor/github.com/Djarvur/go-err113/LICENSE delete mode 100644 vendor/github.com/Djarvur/go-err113/README.adoc delete mode 100644 vendor/github.com/Djarvur/go-err113/comparison.go delete mode 100644 vendor/github.com/Djarvur/go-err113/definition.go delete mode 100644 vendor/github.com/Djarvur/go-err113/err113.go delete mode 100644 vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/LICENSE delete mode 100644 vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go delete mode 100644 vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/cache.go delete mode 100644 vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/directive.go delete mode 100644 vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/pattern/list.go delete mode 100644 vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields-cache.go delete mode 100644 vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields.go delete mode 100644 vendor/github.com/Masterminds/semver/v3/.gitignore delete mode 100644 vendor/github.com/Masterminds/semver/v3/.golangci.yml delete mode 100644 vendor/github.com/Masterminds/semver/v3/CHANGELOG.md delete mode 100644 vendor/github.com/Masterminds/semver/v3/LICENSE.txt delete mode 100644 vendor/github.com/Masterminds/semver/v3/Makefile delete mode 100644 vendor/github.com/Masterminds/semver/v3/README.md delete mode 100644 vendor/github.com/Masterminds/semver/v3/SECURITY.md delete mode 100644 vendor/github.com/Masterminds/semver/v3/collection.go delete mode 100644 vendor/github.com/Masterminds/semver/v3/constraints.go delete mode 100644 vendor/github.com/Masterminds/semver/v3/doc.go delete mode 100644 vendor/github.com/Masterminds/semver/v3/version.go delete mode 100644 vendor/github.com/OpenPeeDeeP/depguard/v2/.gitignore delete mode 100644 vendor/github.com/OpenPeeDeeP/depguard/v2/LICENSE delete mode 100644 vendor/github.com/OpenPeeDeeP/depguard/v2/README.md delete mode 100644 vendor/github.com/OpenPeeDeeP/depguard/v2/depguard.go delete mode 100644 vendor/github.com/OpenPeeDeeP/depguard/v2/internal/utils/errors.go delete mode 100644 vendor/github.com/OpenPeeDeeP/depguard/v2/internal/utils/variables.go delete mode 100644 vendor/github.com/OpenPeeDeeP/depguard/v2/settings.go delete mode 100644 vendor/github.com/PuerkitoBio/rehttp/LICENSE delete mode 100644 vendor/github.com/PuerkitoBio/rehttp/README.md delete mode 100644 vendor/github.com/PuerkitoBio/rehttp/cancelreader.go delete mode 100644 vendor/github.com/PuerkitoBio/rehttp/context_post17.go delete mode 100644 vendor/github.com/PuerkitoBio/rehttp/context_pre17.go delete mode 100644 vendor/github.com/PuerkitoBio/rehttp/perattempttimeout_post17.go delete mode 100644 vendor/github.com/PuerkitoBio/rehttp/perattempttimeout_pre17.go delete mode 100644 vendor/github.com/PuerkitoBio/rehttp/rehttp.go delete mode 100644 vendor/github.com/PuerkitoBio/rehttp/timeouterr_post113.go delete mode 100644 vendor/github.com/PuerkitoBio/rehttp/timeouterr_pre113.go delete mode 100644 vendor/github.com/adjust/rmq/v5/.gitignore delete mode 100644 vendor/github.com/adjust/rmq/v5/LICENSE delete mode 100644 vendor/github.com/adjust/rmq/v5/README.md delete mode 100644 vendor/github.com/adjust/rmq/v5/batch_consumer.go delete mode 100644 vendor/github.com/adjust/rmq/v5/cleaner.go delete mode 100644 vendor/github.com/adjust/rmq/v5/connection.go delete mode 100644 vendor/github.com/adjust/rmq/v5/consumer.go delete mode 100644 vendor/github.com/adjust/rmq/v5/deliveries.go delete mode 100644 vendor/github.com/adjust/rmq/v5/delivery.go delete mode 100644 vendor/github.com/adjust/rmq/v5/errors.go delete mode 100644 vendor/github.com/adjust/rmq/v5/header.go delete mode 100644 vendor/github.com/adjust/rmq/v5/queue.go delete mode 100644 vendor/github.com/adjust/rmq/v5/rand.go delete mode 100644 vendor/github.com/adjust/rmq/v5/redis_client.go delete mode 100644 vendor/github.com/adjust/rmq/v5/redis_keys.go delete mode 100644 vendor/github.com/adjust/rmq/v5/redis_wrapper.go delete mode 100644 vendor/github.com/adjust/rmq/v5/state.go delete mode 100644 vendor/github.com/adjust/rmq/v5/state_string.go delete mode 100644 vendor/github.com/adjust/rmq/v5/stats.go delete mode 100644 vendor/github.com/adjust/rmq/v5/test_batch_consumer.go delete mode 100644 vendor/github.com/adjust/rmq/v5/test_connection.go delete mode 100644 vendor/github.com/adjust/rmq/v5/test_consumer.go delete mode 100644 vendor/github.com/adjust/rmq/v5/test_delivery.go delete mode 100644 vendor/github.com/adjust/rmq/v5/test_queue.go delete mode 100644 vendor/github.com/adjust/rmq/v5/test_redis_client.go delete mode 100644 vendor/github.com/adjust/rmq/v5/test_util.go delete mode 100644 vendor/github.com/alecthomas/go-check-sumtype/.goreleaser.yml delete mode 100644 vendor/github.com/alecthomas/go-check-sumtype/COPYING delete mode 100644 vendor/github.com/alecthomas/go-check-sumtype/LICENSE-MIT delete mode 100644 vendor/github.com/alecthomas/go-check-sumtype/README.md delete mode 100644 vendor/github.com/alecthomas/go-check-sumtype/UNLICENSE delete mode 100644 vendor/github.com/alecthomas/go-check-sumtype/check.go delete mode 100644 vendor/github.com/alecthomas/go-check-sumtype/decl.go delete mode 100644 vendor/github.com/alecthomas/go-check-sumtype/def.go delete mode 100644 vendor/github.com/alecthomas/go-check-sumtype/doc.go delete mode 100644 vendor/github.com/alecthomas/go-check-sumtype/run.go delete mode 100644 vendor/github.com/alexkohler/nakedret/v2/.gitignore delete mode 100644 vendor/github.com/alexkohler/nakedret/v2/LICENSE delete mode 100644 vendor/github.com/alexkohler/nakedret/v2/README.md delete mode 100644 vendor/github.com/alexkohler/nakedret/v2/import.go delete mode 100644 vendor/github.com/alexkohler/nakedret/v2/nakedret.go delete mode 100644 vendor/github.com/alexkohler/prealloc/LICENSE delete mode 100644 vendor/github.com/alexkohler/prealloc/pkg/prealloc.go delete mode 100644 vendor/github.com/alicebob/gopher-json/LICENSE delete mode 100644 vendor/github.com/alicebob/gopher-json/README.md delete mode 100644 vendor/github.com/alicebob/gopher-json/doc.go delete mode 100644 vendor/github.com/alicebob/gopher-json/json.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/.gitignore delete mode 100644 vendor/github.com/alicebob/miniredis/v2/CHANGELOG.md delete mode 100644 vendor/github.com/alicebob/miniredis/v2/LICENSE delete mode 100644 vendor/github.com/alicebob/miniredis/v2/Makefile delete mode 100644 vendor/github.com/alicebob/miniredis/v2/README.md delete mode 100644 vendor/github.com/alicebob/miniredis/v2/check.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_cluster.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_command.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_connection.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_generic.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_geo.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_hash.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_hll.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_info.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_list.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_pubsub.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_scripting.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_server.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_set.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_sorted_set.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_stream.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_string.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/cmd_transactions.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/db.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/direct.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/geo.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/geohash/LICENSE delete mode 100644 vendor/github.com/alicebob/miniredis/v2/geohash/README.md delete mode 100644 vendor/github.com/alicebob/miniredis/v2/geohash/base32.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/geohash/geohash.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/hll.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/hyperloglog/LICENSE delete mode 100644 vendor/github.com/alicebob/miniredis/v2/hyperloglog/README.md delete mode 100644 vendor/github.com/alicebob/miniredis/v2/hyperloglog/compressed.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/hyperloglog/hyperloglog.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/hyperloglog/registers.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/hyperloglog/sparse.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/hyperloglog/utils.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/keys.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/lua.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/metro/LICENSE delete mode 100644 vendor/github.com/alicebob/miniredis/v2/metro/README.md delete mode 100644 vendor/github.com/alicebob/miniredis/v2/metro/metro64.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/miniredis.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/opts.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/pubsub.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/redis.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/server/Makefile delete mode 100644 vendor/github.com/alicebob/miniredis/v2/server/proto.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/server/server.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/sorted_set.go delete mode 100644 vendor/github.com/alicebob/miniredis/v2/stream.go delete mode 100644 vendor/github.com/alingse/asasalint/.gitignore delete mode 100644 vendor/github.com/alingse/asasalint/.goreleaser.yml delete mode 100644 vendor/github.com/alingse/asasalint/LICENSE delete mode 100644 vendor/github.com/alingse/asasalint/Makefile delete mode 100644 vendor/github.com/alingse/asasalint/README.md delete mode 100644 vendor/github.com/alingse/asasalint/asasalint.go delete mode 100644 vendor/github.com/asaskevich/govalidator/.gitignore delete mode 100644 vendor/github.com/asaskevich/govalidator/.travis.yml delete mode 100644 vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md delete mode 100644 vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md delete mode 100644 vendor/github.com/asaskevich/govalidator/LICENSE delete mode 100644 vendor/github.com/asaskevich/govalidator/README.md delete mode 100644 vendor/github.com/asaskevich/govalidator/arrays.go delete mode 100644 vendor/github.com/asaskevich/govalidator/converter.go delete mode 100644 vendor/github.com/asaskevich/govalidator/doc.go delete mode 100644 vendor/github.com/asaskevich/govalidator/error.go delete mode 100644 vendor/github.com/asaskevich/govalidator/numerics.go delete mode 100644 vendor/github.com/asaskevich/govalidator/patterns.go delete mode 100644 vendor/github.com/asaskevich/govalidator/types.go delete mode 100644 vendor/github.com/asaskevich/govalidator/utils.go delete mode 100644 vendor/github.com/asaskevich/govalidator/validator.go delete mode 100644 vendor/github.com/asaskevich/govalidator/wercker.yml delete mode 100644 vendor/github.com/ashanbrown/forbidigo/LICENSE delete mode 100644 vendor/github.com/ashanbrown/forbidigo/forbidigo/config_options.go delete mode 100644 vendor/github.com/ashanbrown/forbidigo/forbidigo/forbidigo.go delete mode 100644 vendor/github.com/ashanbrown/forbidigo/forbidigo/patterns.go delete mode 100644 vendor/github.com/ashanbrown/makezero/LICENSE delete mode 100644 vendor/github.com/ashanbrown/makezero/makezero/makezero.go delete mode 100644 vendor/github.com/beorn7/perks/LICENSE delete mode 100644 vendor/github.com/beorn7/perks/quantile/exampledata.txt delete mode 100644 vendor/github.com/beorn7/perks/quantile/stream.go delete mode 100644 vendor/github.com/bkielbasa/cyclop/LICENSE delete mode 100644 vendor/github.com/bkielbasa/cyclop/pkg/analyzer/analyzer.go delete mode 100644 vendor/github.com/blizzy78/varnamelen/.editorconfig delete mode 100644 vendor/github.com/blizzy78/varnamelen/.gitignore delete mode 100644 vendor/github.com/blizzy78/varnamelen/.golangci.yml delete mode 100644 vendor/github.com/blizzy78/varnamelen/LICENSE delete mode 100644 vendor/github.com/blizzy78/varnamelen/README.md delete mode 100644 vendor/github.com/blizzy78/varnamelen/doc.go delete mode 100644 vendor/github.com/blizzy78/varnamelen/flags.go delete mode 100644 vendor/github.com/blizzy78/varnamelen/typeparam.go delete mode 100644 vendor/github.com/blizzy78/varnamelen/typeparam_go1.16.go delete mode 100644 vendor/github.com/blizzy78/varnamelen/varnamelen.code-workspace delete mode 100644 vendor/github.com/blizzy78/varnamelen/varnamelen.go delete mode 100644 vendor/github.com/bombsimon/wsl/v4/.gitignore delete mode 100644 vendor/github.com/bombsimon/wsl/v4/.golangci.yml delete mode 100644 vendor/github.com/bombsimon/wsl/v4/LICENSE delete mode 100644 vendor/github.com/bombsimon/wsl/v4/README.md delete mode 100644 vendor/github.com/bombsimon/wsl/v4/analyzer.go delete mode 100644 vendor/github.com/bombsimon/wsl/v4/wsl.go delete mode 100644 vendor/github.com/breml/bidichk/LICENSE delete mode 100644 vendor/github.com/breml/bidichk/pkg/bidichk/bidichk.go delete mode 100644 vendor/github.com/breml/bidichk/pkg/bidichk/version.go delete mode 100644 vendor/github.com/breml/errchkjson/.gitignore delete mode 100644 vendor/github.com/breml/errchkjson/.goreleaser.yml delete mode 100644 vendor/github.com/breml/errchkjson/LICENSE delete mode 100644 vendor/github.com/breml/errchkjson/README.md delete mode 100644 vendor/github.com/breml/errchkjson/errchkjson.go delete mode 100644 vendor/github.com/breml/errchkjson/noexported_error.go delete mode 100644 vendor/github.com/breml/errchkjson/unsupported_error.go delete mode 100644 vendor/github.com/breml/errchkjson/version.go delete mode 100644 vendor/github.com/bsm/redislock/.golangci.yml delete mode 100644 vendor/github.com/bsm/redislock/CHANGELOG.md delete mode 100644 vendor/github.com/bsm/redislock/LICENSE delete mode 100644 vendor/github.com/bsm/redislock/Makefile delete mode 100644 vendor/github.com/bsm/redislock/README.md delete mode 100644 vendor/github.com/bsm/redislock/README.md.tpl delete mode 100644 vendor/github.com/bsm/redislock/redislock.go delete mode 100644 vendor/github.com/butuzov/ireturn/LICENSE delete mode 100644 vendor/github.com/butuzov/ireturn/analyzer/analyzer.go delete mode 100644 vendor/github.com/butuzov/ireturn/analyzer/disallow.go delete mode 100644 vendor/github.com/butuzov/ireturn/analyzer/internal/config/allow.go delete mode 100644 vendor/github.com/butuzov/ireturn/analyzer/internal/config/config.go delete mode 100644 vendor/github.com/butuzov/ireturn/analyzer/internal/config/new.go delete mode 100644 vendor/github.com/butuzov/ireturn/analyzer/internal/config/reject.go delete mode 100644 vendor/github.com/butuzov/ireturn/analyzer/internal/types/iface.go delete mode 100644 vendor/github.com/butuzov/ireturn/analyzer/internal/types/names.go delete mode 100644 vendor/github.com/butuzov/ireturn/analyzer/internal/types/types.go delete mode 100644 vendor/github.com/butuzov/ireturn/analyzer/std.go delete mode 100644 vendor/github.com/butuzov/mirror/.editorconfig delete mode 100644 vendor/github.com/butuzov/mirror/.gitignore delete mode 100644 vendor/github.com/butuzov/mirror/.goreleaser.yaml delete mode 100644 vendor/github.com/butuzov/mirror/LICENSE delete mode 100644 vendor/github.com/butuzov/mirror/MIRROR_FUNCS.md delete mode 100644 vendor/github.com/butuzov/mirror/Makefile delete mode 100644 vendor/github.com/butuzov/mirror/Taskfile.yml delete mode 100644 vendor/github.com/butuzov/mirror/analyzer.go delete mode 100644 vendor/github.com/butuzov/mirror/checkers_bufio.go delete mode 100644 vendor/github.com/butuzov/mirror/checkers_bytes.go delete mode 100644 vendor/github.com/butuzov/mirror/checkers_httptest.go delete mode 100644 vendor/github.com/butuzov/mirror/checkers_maphash.go delete mode 100644 vendor/github.com/butuzov/mirror/checkers_os.go delete mode 100644 vendor/github.com/butuzov/mirror/checkers_regexp.go delete mode 100644 vendor/github.com/butuzov/mirror/checkers_strings.go delete mode 100644 vendor/github.com/butuzov/mirror/checkers_utf8.go delete mode 100644 vendor/github.com/butuzov/mirror/internal/checker/checker.go delete mode 100644 vendor/github.com/butuzov/mirror/internal/checker/imports.go delete mode 100644 vendor/github.com/butuzov/mirror/internal/checker/violation.go delete mode 100644 vendor/github.com/butuzov/mirror/readme.md delete mode 100644 vendor/github.com/caarlos0/env/v10/.gitignore delete mode 100644 vendor/github.com/caarlos0/env/v10/.golangci.yml delete mode 100644 vendor/github.com/caarlos0/env/v10/.goreleaser.yml delete mode 100644 vendor/github.com/caarlos0/env/v10/.mailmap delete mode 100644 vendor/github.com/caarlos0/env/v10/LICENSE.md delete mode 100644 vendor/github.com/caarlos0/env/v10/Makefile delete mode 100644 vendor/github.com/caarlos0/env/v10/README.md delete mode 100644 vendor/github.com/caarlos0/env/v10/env.go delete mode 100644 vendor/github.com/caarlos0/env/v10/env_tomap.go delete mode 100644 vendor/github.com/caarlos0/env/v10/env_tomap_windows.go delete mode 100644 vendor/github.com/caarlos0/env/v10/error.go delete mode 100644 vendor/github.com/catenacyber/perfsprint/LICENSE delete mode 100644 vendor/github.com/catenacyber/perfsprint/analyzer/analyzer.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/.gitignore delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/.golangci.yml delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/.goreleaser.yml delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/LICENSE.txt delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/Makefile delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/README.md delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/adjacency/adjcmartix.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/data/bindata.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/entropy/entropyCalculator.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/frequency/frequency.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/match/match.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/matching/dateMatchers.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/matching/dictionaryMatch.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/matching/leet.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/matching/matching.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/matching/repeatMatch.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/matching/sequenceMatch.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/matching/spatialMatch.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/renovate.json delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/scoring/scoring.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/utils/math/mathutils.go delete mode 100644 vendor/github.com/ccojocar/zxcvbn-go/zxcvbn.go delete mode 100644 vendor/github.com/certifi/gocertifi/LICENSE delete mode 100644 vendor/github.com/certifi/gocertifi/README.md delete mode 100644 vendor/github.com/certifi/gocertifi/certifi.go delete mode 100644 vendor/github.com/cespare/xxhash/v2/LICENSE.txt delete mode 100644 vendor/github.com/cespare/xxhash/v2/README.md delete mode 100644 vendor/github.com/cespare/xxhash/v2/testall.sh delete mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash.go delete mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s delete mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s delete mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash_asm.go delete mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash_other.go delete mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash_safe.go delete mode 100644 vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go delete mode 100644 vendor/github.com/charithe/durationcheck/.gitignore delete mode 100644 vendor/github.com/charithe/durationcheck/LICENSE delete mode 100644 vendor/github.com/charithe/durationcheck/Makefile delete mode 100644 vendor/github.com/charithe/durationcheck/README.md delete mode 100644 vendor/github.com/charithe/durationcheck/durationcheck.go delete mode 100644 vendor/github.com/chavacava/garif/.gitignore delete mode 100644 vendor/github.com/chavacava/garif/LICENSE delete mode 100644 vendor/github.com/chavacava/garif/README.md delete mode 100644 vendor/github.com/chavacava/garif/constructors.go delete mode 100644 vendor/github.com/chavacava/garif/decorators.go delete mode 100644 vendor/github.com/chavacava/garif/doc.go delete mode 100644 vendor/github.com/chavacava/garif/enums.go delete mode 100644 vendor/github.com/chavacava/garif/io.go delete mode 100644 vendor/github.com/chavacava/garif/models.go delete mode 100644 vendor/github.com/ckaznocha/intrange/.gitignore delete mode 100644 vendor/github.com/ckaznocha/intrange/.golangci.yml delete mode 100644 vendor/github.com/ckaznocha/intrange/CONTRIBUTING.md delete mode 100644 vendor/github.com/ckaznocha/intrange/LICENSE delete mode 100644 vendor/github.com/ckaznocha/intrange/README.md delete mode 100644 vendor/github.com/ckaznocha/intrange/SECURITY.md delete mode 100644 vendor/github.com/ckaznocha/intrange/go.work delete mode 100644 vendor/github.com/ckaznocha/intrange/intrange.go delete mode 100644 vendor/github.com/curioswitch/go-reassign/.gitattributes delete mode 100644 vendor/github.com/curioswitch/go-reassign/.gitignore delete mode 100644 vendor/github.com/curioswitch/go-reassign/.golangci.yml delete mode 100644 vendor/github.com/curioswitch/go-reassign/.goreleaser.yaml delete mode 100644 vendor/github.com/curioswitch/go-reassign/LICENSE delete mode 100644 vendor/github.com/curioswitch/go-reassign/README.md delete mode 100644 vendor/github.com/curioswitch/go-reassign/analyzer.go delete mode 100644 vendor/github.com/curioswitch/go-reassign/internal/analyzer/analyzer.go delete mode 100644 vendor/github.com/daixiang0/gci/LICENSE delete mode 100644 vendor/github.com/daixiang0/gci/pkg/config/config.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/format/format.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/gci/gci.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/gci/testdata.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/io/file.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/io/search.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/io/stdin.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/log/log.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/parse/parse.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/alias.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/blank.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/commentline.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/default.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/dot.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/errors.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/local_module.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/newline.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/parser.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/prefix.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/section.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/standard.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/section/standard_list.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/specificity/default.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/specificity/local_module.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/specificity/match.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/specificity/mismatch.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/specificity/name.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/specificity/specificity.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/specificity/standard.go delete mode 100644 vendor/github.com/daixiang0/gci/pkg/utils/constants.go delete mode 100644 vendor/github.com/dave/jennifer/LICENSE delete mode 100644 vendor/github.com/dave/jennifer/jen/add.go delete mode 100644 vendor/github.com/dave/jennifer/jen/comments.go delete mode 100644 vendor/github.com/dave/jennifer/jen/custom.go delete mode 100644 vendor/github.com/dave/jennifer/jen/dict.go delete mode 100644 vendor/github.com/dave/jennifer/jen/do.go delete mode 100644 vendor/github.com/dave/jennifer/jen/file.go delete mode 100644 vendor/github.com/dave/jennifer/jen/generated.go delete mode 100644 vendor/github.com/dave/jennifer/jen/group.go delete mode 100644 vendor/github.com/dave/jennifer/jen/hints.go delete mode 100644 vendor/github.com/dave/jennifer/jen/jen.go delete mode 100644 vendor/github.com/dave/jennifer/jen/lit.go delete mode 100644 vendor/github.com/dave/jennifer/jen/reserved.go delete mode 100644 vendor/github.com/dave/jennifer/jen/statement.go delete mode 100644 vendor/github.com/dave/jennifer/jen/tag.go delete mode 100644 vendor/github.com/dave/jennifer/jen/tokens.go delete mode 100644 vendor/github.com/davecgh/go-spew/LICENSE delete mode 100644 vendor/github.com/davecgh/go-spew/spew/bypass.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/bypasssafe.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/common.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/config.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/doc.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/dump.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/format.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/spew.go delete mode 100644 vendor/github.com/denis-tingaikin/go-header/.gitignore delete mode 100644 vendor/github.com/denis-tingaikin/go-header/.go-header.yml delete mode 100644 vendor/github.com/denis-tingaikin/go-header/LICENSE delete mode 100644 vendor/github.com/denis-tingaikin/go-header/README.md delete mode 100644 vendor/github.com/denis-tingaikin/go-header/analyzer.go delete mode 100644 vendor/github.com/denis-tingaikin/go-header/config.go delete mode 100644 vendor/github.com/denis-tingaikin/go-header/issue.go delete mode 100644 vendor/github.com/denis-tingaikin/go-header/location.go delete mode 100644 vendor/github.com/denis-tingaikin/go-header/option.go delete mode 100644 vendor/github.com/denis-tingaikin/go-header/reader.go delete mode 100644 vendor/github.com/denis-tingaikin/go-header/value.go delete mode 100644 vendor/github.com/dgryski/go-rendezvous/LICENSE delete mode 100644 vendor/github.com/dgryski/go-rendezvous/rdv.go delete mode 100644 vendor/github.com/ettle/strcase/.gitignore delete mode 100644 vendor/github.com/ettle/strcase/.golangci.yml delete mode 100644 vendor/github.com/ettle/strcase/.readme.tmpl delete mode 100644 vendor/github.com/ettle/strcase/LICENSE delete mode 100644 vendor/github.com/ettle/strcase/Makefile delete mode 100644 vendor/github.com/ettle/strcase/README.md delete mode 100644 vendor/github.com/ettle/strcase/assert.go delete mode 100644 vendor/github.com/ettle/strcase/caser.go delete mode 100644 vendor/github.com/ettle/strcase/convert.go delete mode 100644 vendor/github.com/ettle/strcase/doc.go delete mode 100644 vendor/github.com/ettle/strcase/initialism.go delete mode 100644 vendor/github.com/ettle/strcase/split.go delete mode 100644 vendor/github.com/ettle/strcase/strcase.go delete mode 100644 vendor/github.com/ettle/strcase/unicode.go delete mode 100644 vendor/github.com/fatih/color/LICENSE.md delete mode 100644 vendor/github.com/fatih/color/README.md delete mode 100644 vendor/github.com/fatih/color/color.go delete mode 100644 vendor/github.com/fatih/color/color_windows.go delete mode 100644 vendor/github.com/fatih/color/doc.go delete mode 100644 vendor/github.com/fatih/structtag/LICENSE delete mode 100644 vendor/github.com/fatih/structtag/README.md delete mode 100644 vendor/github.com/fatih/structtag/tags.go delete mode 100644 vendor/github.com/firefart/nonamedreturns/LICENSE delete mode 100644 vendor/github.com/firefart/nonamedreturns/analyzer/analyzer.go delete mode 100644 vendor/github.com/fsnotify/fsnotify/.editorconfig delete mode 100644 vendor/github.com/fsnotify/fsnotify/.gitattributes delete mode 100644 vendor/github.com/fsnotify/fsnotify/.gitignore delete mode 100644 vendor/github.com/fsnotify/fsnotify/.mailmap delete mode 100644 vendor/github.com/fsnotify/fsnotify/AUTHORS delete mode 100644 vendor/github.com/fsnotify/fsnotify/CHANGELOG.md delete mode 100644 vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md delete mode 100644 vendor/github.com/fsnotify/fsnotify/LICENSE delete mode 100644 vendor/github.com/fsnotify/fsnotify/README.md delete mode 100644 vendor/github.com/fsnotify/fsnotify/fen.go delete mode 100644 vendor/github.com/fsnotify/fsnotify/fsnotify.go delete mode 100644 vendor/github.com/fsnotify/fsnotify/fsnotify_unsupported.go delete mode 100644 vendor/github.com/fsnotify/fsnotify/inotify.go delete mode 100644 vendor/github.com/fsnotify/fsnotify/inotify_poller.go delete mode 100644 vendor/github.com/fsnotify/fsnotify/kqueue.go delete mode 100644 vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go delete mode 100644 vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go delete mode 100644 vendor/github.com/fsnotify/fsnotify/windows.go delete mode 100644 vendor/github.com/fzipp/gocyclo/CHANGELOG.md delete mode 100644 vendor/github.com/fzipp/gocyclo/CONTRIBUTORS delete mode 100644 vendor/github.com/fzipp/gocyclo/LICENSE delete mode 100644 vendor/github.com/fzipp/gocyclo/README.md delete mode 100644 vendor/github.com/fzipp/gocyclo/analyze.go delete mode 100644 vendor/github.com/fzipp/gocyclo/complexity.go delete mode 100644 vendor/github.com/fzipp/gocyclo/directives.go delete mode 100644 vendor/github.com/fzipp/gocyclo/recv.go delete mode 100644 vendor/github.com/fzipp/gocyclo/recv_pre118.go delete mode 100644 vendor/github.com/fzipp/gocyclo/stats.go delete mode 100644 vendor/github.com/getkin/kin-openapi/LICENSE delete mode 100644 vendor/github.com/getkin/kin-openapi/jsoninfo/doc.go delete mode 100644 vendor/github.com/getkin/kin-openapi/jsoninfo/field_info.go delete mode 100644 vendor/github.com/getkin/kin-openapi/jsoninfo/marshal.go delete mode 100644 vendor/github.com/getkin/kin-openapi/jsoninfo/marshal_ref.go delete mode 100644 vendor/github.com/getkin/kin-openapi/jsoninfo/strict_struct.go delete mode 100644 vendor/github.com/getkin/kin-openapi/jsoninfo/type_info.go delete mode 100644 vendor/github.com/getkin/kin-openapi/jsoninfo/unmarshal.go delete mode 100644 vendor/github.com/getkin/kin-openapi/jsoninfo/unsupported_properties_error.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/callback.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/components.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/content.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/doc.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/encoding.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/examples.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/extension.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/external_docs.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/header.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/info.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/link.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/media_type.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/operation.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/parameter.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/path_item.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/paths.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/refs.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/request_body.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/response.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/schema.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/schema_formats.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/security_requirements.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/security_scheme.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/server.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/swagger.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/swagger_loader.go delete mode 100644 vendor/github.com/getkin/kin-openapi/openapi3/tag.go delete mode 100644 vendor/github.com/getsentry/sentry-go/.codecov.yml delete mode 100644 vendor/github.com/getsentry/sentry-go/.craft.yml delete mode 100644 vendor/github.com/getsentry/sentry-go/.gitattributes delete mode 100644 vendor/github.com/getsentry/sentry-go/.gitignore delete mode 100644 vendor/github.com/getsentry/sentry-go/.golangci.yml delete mode 100644 vendor/github.com/getsentry/sentry-go/CHANGELOG.md delete mode 100644 vendor/github.com/getsentry/sentry-go/CONTRIBUTING.md delete mode 100644 vendor/github.com/getsentry/sentry-go/LICENSE delete mode 100644 vendor/github.com/getsentry/sentry-go/MIGRATION.md delete mode 100644 vendor/github.com/getsentry/sentry-go/Makefile delete mode 100644 vendor/github.com/getsentry/sentry-go/README.md delete mode 100644 vendor/github.com/getsentry/sentry-go/check_in.go delete mode 100644 vendor/github.com/getsentry/sentry-go/client.go delete mode 100644 vendor/github.com/getsentry/sentry-go/doc.go delete mode 100644 vendor/github.com/getsentry/sentry-go/dsn.go delete mode 100644 vendor/github.com/getsentry/sentry-go/dynamic_sampling_context.go delete mode 100644 vendor/github.com/getsentry/sentry-go/hub.go delete mode 100644 vendor/github.com/getsentry/sentry-go/integrations.go delete mode 100644 vendor/github.com/getsentry/sentry-go/interfaces.go delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/debug/transport.go delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/otel/baggage/README.md delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/otel/baggage/baggage.go delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/otel/baggage/internal/baggage/baggage.go delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/ratelimit/category.go delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/ratelimit/deadline.go delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/ratelimit/doc.go delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/ratelimit/map.go delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/ratelimit/rate_limits.go delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/ratelimit/retry_after.go delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/traceparser/README.md delete mode 100644 vendor/github.com/getsentry/sentry-go/internal/traceparser/parser.go delete mode 100644 vendor/github.com/getsentry/sentry-go/metrics.go delete mode 100644 vendor/github.com/getsentry/sentry-go/profile_sample.go delete mode 100644 vendor/github.com/getsentry/sentry-go/profiler.go delete mode 100644 vendor/github.com/getsentry/sentry-go/profiler_other.go delete mode 100644 vendor/github.com/getsentry/sentry-go/profiler_windows.go delete mode 100644 vendor/github.com/getsentry/sentry-go/propagation_context.go delete mode 100644 vendor/github.com/getsentry/sentry-go/scope.go delete mode 100644 vendor/github.com/getsentry/sentry-go/sentry.go delete mode 100644 vendor/github.com/getsentry/sentry-go/sourcereader.go delete mode 100644 vendor/github.com/getsentry/sentry-go/span_recorder.go delete mode 100644 vendor/github.com/getsentry/sentry-go/stacktrace.go delete mode 100644 vendor/github.com/getsentry/sentry-go/stacktrace_below_go1.20.go delete mode 100644 vendor/github.com/getsentry/sentry-go/stacktrace_below_go1.21.go delete mode 100644 vendor/github.com/getsentry/sentry-go/stacktrace_go1.20.go delete mode 100644 vendor/github.com/getsentry/sentry-go/stacktrace_go1.21.go delete mode 100644 vendor/github.com/getsentry/sentry-go/traces_profiler.go delete mode 100644 vendor/github.com/getsentry/sentry-go/traces_sampler.go delete mode 100644 vendor/github.com/getsentry/sentry-go/tracing.go delete mode 100644 vendor/github.com/getsentry/sentry-go/transport.go delete mode 100644 vendor/github.com/getsentry/sentry-go/util.go delete mode 100644 vendor/github.com/ghodss/yaml/.gitignore delete mode 100644 vendor/github.com/ghodss/yaml/.travis.yml delete mode 100644 vendor/github.com/ghodss/yaml/LICENSE delete mode 100644 vendor/github.com/ghodss/yaml/README.md delete mode 100644 vendor/github.com/ghodss/yaml/fields.go delete mode 100644 vendor/github.com/ghodss/yaml/yaml.go delete mode 100644 vendor/github.com/ghostiam/protogetter/.goreleaser.yaml delete mode 100644 vendor/github.com/ghostiam/protogetter/LICENSE delete mode 100644 vendor/github.com/ghostiam/protogetter/Makefile delete mode 100644 vendor/github.com/ghostiam/protogetter/README.md delete mode 100644 vendor/github.com/ghostiam/protogetter/posfilter.go delete mode 100644 vendor/github.com/ghostiam/protogetter/processor.go delete mode 100644 vendor/github.com/ghostiam/protogetter/protogetter.go delete mode 100644 vendor/github.com/go-critic/go-critic/LICENSE delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/appendAssign_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/appendCombine_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/badCond_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/badRegexp_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/boolExprSimplify_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/builtinShadowDecl_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/builtinShadow_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/captLocal_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/caseOrder_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/checkers.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/codegenComment_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/commentFormatting_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/commentedOutImport_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/defaultCaseOrder_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/deferInLoop_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/deprecatedComment_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/docStub_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/dupBranchBody_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/dupCase_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/dupImports_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/dupSubExpr_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/elseif_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/embedded_rules.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/emptyFallthrough_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/evalOrder_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/exitAfterDefer_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/filepathJoin_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/flagName_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/hexLiteral_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/hugeParam_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/ifElseChain_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/importShadow_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/initClause_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/comment_walker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/doc_comment_walker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/expr_walker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/func_decl_walker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_comment_walker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_def_visitor.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_def_walker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_expr_walker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_list_walker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_walker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/type_expr_walker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/visitor.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/walk_handler.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/walker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astfind.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astflow.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astset.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/zero_value.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/mapKey_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/methodExprCall_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/nestingReduce_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/newDeref_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/nilValReturn_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/octalLiteral_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/paramTypeCombine_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/ptrToRefParam_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/rangeExprCopy_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/rangeValCopy_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/regexpPattern_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/regexpSimplify_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/ruleguard_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/singleCaseSwitch_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/sloppyReassign_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/sloppyTypeAssert_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/sortSlice_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/todoCommentWithoutDetail_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/tooManyResults_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/truncateCmp_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/typeAssertChain_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/typeDefFirst_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/typeSwitchVar_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/typeUnparen_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/underef_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/unlabelStmt_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/unlambda_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/unnamedResult_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/unnecessaryBlock_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/unnecessaryDefer_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/utils.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/weakCond_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/checkers/whyNoLint_checker.go delete mode 100644 vendor/github.com/go-critic/go-critic/linter/go_version.go delete mode 100644 vendor/github.com/go-critic/go-critic/linter/helpers.go delete mode 100644 vendor/github.com/go-critic/go-critic/linter/linter.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/.gitignore delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/.gitlab-ci.yml delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/.golangci.toml delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/LICENSE.md delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/README.md delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/attachments.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/auth.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/bulk.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/bulkget.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/changes.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/auth.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/basicauth.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/chttp.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/constants.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/cookieauth.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/encode.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/errors.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/exitstatus.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/proxyauth.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/trace.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/xerrors_13.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/chttp/xerrors_pre13.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/client.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/cluster.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/codecov.yml delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/config.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/constants.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/couchdb.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/db.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/dbstats.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/doc.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/errors.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/find.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/iter.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/json.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/options.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/replication.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/rows.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/scheduler.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/seqid.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/session.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/util.go delete mode 100644 vendor/github.com/go-kivik/couchdb/v3/version.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/.codecov.yml delete mode 100644 vendor/github.com/go-kivik/kivik/v3/.gitignore delete mode 100644 vendor/github.com/go-kivik/kivik/v3/.gitlab-ci.yml delete mode 100644 vendor/github.com/go-kivik/kivik/v3/.golangci.toml delete mode 100644 vendor/github.com/go-kivik/kivik/v3/CONTRIBUTING.md delete mode 100644 vendor/github.com/go-kivik/kivik/v3/ISSUE_TEMPLATE.md delete mode 100644 vendor/github.com/go-kivik/kivik/v3/LICENSE.md delete mode 100644 vendor/github.com/go-kivik/kivik/v3/README.md delete mode 100644 vendor/github.com/go-kivik/kivik/v3/attachments.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/bulk.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/changes.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/cluster.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/codecov.yml delete mode 100644 vendor/github.com/go-kivik/kivik/v3/config.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/constants.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/db.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/doc.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/driver/bulkget.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/driver/changes.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/driver/config.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/driver/doc.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/driver/driver.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/driver/errors.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/driver/partition.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/driver/rows.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/driver/session.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/driver/updates.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/errors.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/find.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/internal/registry/registry.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/iterator.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/kivik.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/package.json delete mode 100644 vendor/github.com/go-kivik/kivik/v3/replication.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/rows.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/security.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/session.go delete mode 100644 vendor/github.com/go-kivik/kivik/v3/updates.go delete mode 100644 vendor/github.com/go-pg/pg/.travis.yml delete mode 100644 vendor/github.com/go-pg/pg/CHANGELOG.md delete mode 100644 vendor/github.com/go-pg/pg/LICENSE delete mode 100644 vendor/github.com/go-pg/pg/Makefile delete mode 100644 vendor/github.com/go-pg/pg/README.md delete mode 100644 vendor/github.com/go-pg/pg/db.go delete mode 100644 vendor/github.com/go-pg/pg/doc.go delete mode 100644 vendor/github.com/go-pg/pg/error.go delete mode 100644 vendor/github.com/go-pg/pg/hook.go delete mode 100644 vendor/github.com/go-pg/pg/internal/error.go delete mode 100644 vendor/github.com/go-pg/pg/internal/internal.go delete mode 100644 vendor/github.com/go-pg/pg/internal/log.go delete mode 100644 vendor/github.com/go-pg/pg/internal/parser/array_parser.go delete mode 100644 vendor/github.com/go-pg/pg/internal/parser/composite_parser.go delete mode 100644 vendor/github.com/go-pg/pg/internal/parser/hstore_parser.go delete mode 100644 vendor/github.com/go-pg/pg/internal/parser/parser.go delete mode 100644 vendor/github.com/go-pg/pg/internal/parser/util.go delete mode 100644 vendor/github.com/go-pg/pg/internal/pool/conn.go delete mode 100644 vendor/github.com/go-pg/pg/internal/pool/elastic_reader.go delete mode 100644 vendor/github.com/go-pg/pg/internal/pool/pool.go delete mode 100644 vendor/github.com/go-pg/pg/internal/pool/pool_single.go delete mode 100644 vendor/github.com/go-pg/pg/internal/pool/reader.go delete mode 100644 vendor/github.com/go-pg/pg/internal/pool/write_buffer.go delete mode 100644 vendor/github.com/go-pg/pg/internal/safe.go delete mode 100644 vendor/github.com/go-pg/pg/internal/strconv.go delete mode 100644 vendor/github.com/go-pg/pg/internal/underscore.go delete mode 100644 vendor/github.com/go-pg/pg/internal/unsafe.go delete mode 100644 vendor/github.com/go-pg/pg/internal/util.go delete mode 100644 vendor/github.com/go-pg/pg/listener.go delete mode 100644 vendor/github.com/go-pg/pg/messages.go delete mode 100644 vendor/github.com/go-pg/pg/options.go delete mode 100644 vendor/github.com/go-pg/pg/orm/composite.go delete mode 100644 vendor/github.com/go-pg/pg/orm/composite_create.go delete mode 100644 vendor/github.com/go-pg/pg/orm/composite_drop.go delete mode 100644 vendor/github.com/go-pg/pg/orm/count_estimate.go delete mode 100644 vendor/github.com/go-pg/pg/orm/delete.go delete mode 100644 vendor/github.com/go-pg/pg/orm/field.go delete mode 100644 vendor/github.com/go-pg/pg/orm/format.go delete mode 100644 vendor/github.com/go-pg/pg/orm/hook.go delete mode 100644 vendor/github.com/go-pg/pg/orm/inflection.go delete mode 100644 vendor/github.com/go-pg/pg/orm/insert.go delete mode 100644 vendor/github.com/go-pg/pg/orm/join.go delete mode 100644 vendor/github.com/go-pg/pg/orm/model.go delete mode 100644 vendor/github.com/go-pg/pg/orm/model_discard.go delete mode 100644 vendor/github.com/go-pg/pg/orm/model_func.go delete mode 100644 vendor/github.com/go-pg/pg/orm/model_scan.go delete mode 100644 vendor/github.com/go-pg/pg/orm/model_slice.go delete mode 100644 vendor/github.com/go-pg/pg/orm/model_table.go delete mode 100644 vendor/github.com/go-pg/pg/orm/model_table_m2m.go delete mode 100644 vendor/github.com/go-pg/pg/orm/model_table_many.go delete mode 100644 vendor/github.com/go-pg/pg/orm/model_table_slice.go delete mode 100644 vendor/github.com/go-pg/pg/orm/model_table_struct.go delete mode 100644 vendor/github.com/go-pg/pg/orm/orm.go delete mode 100644 vendor/github.com/go-pg/pg/orm/pager.go delete mode 100644 vendor/github.com/go-pg/pg/orm/query.go delete mode 100644 vendor/github.com/go-pg/pg/orm/relation.go delete mode 100644 vendor/github.com/go-pg/pg/orm/result.go delete mode 100644 vendor/github.com/go-pg/pg/orm/select.go delete mode 100644 vendor/github.com/go-pg/pg/orm/table.go delete mode 100644 vendor/github.com/go-pg/pg/orm/table_create.go delete mode 100644 vendor/github.com/go-pg/pg/orm/table_drop.go delete mode 100644 vendor/github.com/go-pg/pg/orm/table_params.go delete mode 100644 vendor/github.com/go-pg/pg/orm/tables.go delete mode 100644 vendor/github.com/go-pg/pg/orm/tag.go delete mode 100644 vendor/github.com/go-pg/pg/orm/update.go delete mode 100644 vendor/github.com/go-pg/pg/orm/url_filter.go delete mode 100644 vendor/github.com/go-pg/pg/orm/url_values.go delete mode 100644 vendor/github.com/go-pg/pg/orm/util.go delete mode 100644 vendor/github.com/go-pg/pg/orm/zero.go delete mode 100644 vendor/github.com/go-pg/pg/pg.go delete mode 100644 vendor/github.com/go-pg/pg/result.go delete mode 100644 vendor/github.com/go-pg/pg/stmt.go delete mode 100644 vendor/github.com/go-pg/pg/time.go delete mode 100644 vendor/github.com/go-pg/pg/tx.go delete mode 100644 vendor/github.com/go-pg/pg/types/append.go delete mode 100644 vendor/github.com/go-pg/pg/types/append_array.go delete mode 100644 vendor/github.com/go-pg/pg/types/append_field.go delete mode 100644 vendor/github.com/go-pg/pg/types/append_hstore.go delete mode 100644 vendor/github.com/go-pg/pg/types/append_jsonb.go delete mode 100644 vendor/github.com/go-pg/pg/types/append_value.go delete mode 100644 vendor/github.com/go-pg/pg/types/array.go delete mode 100644 vendor/github.com/go-pg/pg/types/hstore.go delete mode 100644 vendor/github.com/go-pg/pg/types/in_op.go delete mode 100644 vendor/github.com/go-pg/pg/types/interface.go delete mode 100644 vendor/github.com/go-pg/pg/types/scan.go delete mode 100644 vendor/github.com/go-pg/pg/types/scan_array.go delete mode 100644 vendor/github.com/go-pg/pg/types/scan_hstore.go delete mode 100644 vendor/github.com/go-pg/pg/types/scan_value.go delete mode 100644 vendor/github.com/go-pg/pg/types/time.go delete mode 100644 vendor/github.com/go-toolsmith/astcast/LICENSE delete mode 100644 vendor/github.com/go-toolsmith/astcast/README.md delete mode 100644 vendor/github.com/go-toolsmith/astcast/astcast.go delete mode 100644 vendor/github.com/go-toolsmith/astcopy/LICENSE delete mode 100644 vendor/github.com/go-toolsmith/astcopy/README.md delete mode 100644 vendor/github.com/go-toolsmith/astcopy/astcopy.go delete mode 100644 vendor/github.com/go-toolsmith/astcopy/astcopy_go117.go delete mode 100644 vendor/github.com/go-toolsmith/astcopy/astcopy_go118.go delete mode 100644 vendor/github.com/go-toolsmith/astequal/.gitignore delete mode 100644 vendor/github.com/go-toolsmith/astequal/LICENSE delete mode 100644 vendor/github.com/go-toolsmith/astequal/README.md delete mode 100644 vendor/github.com/go-toolsmith/astequal/astequal.go delete mode 100644 vendor/github.com/go-toolsmith/astequal/diff.go delete mode 100644 vendor/github.com/go-toolsmith/astfmt/LICENSE delete mode 100644 vendor/github.com/go-toolsmith/astfmt/README.md delete mode 100644 vendor/github.com/go-toolsmith/astfmt/astfmt.go delete mode 100644 vendor/github.com/go-toolsmith/astp/LICENSE delete mode 100644 vendor/github.com/go-toolsmith/astp/README.md delete mode 100644 vendor/github.com/go-toolsmith/astp/decl.go delete mode 100644 vendor/github.com/go-toolsmith/astp/expr.go delete mode 100644 vendor/github.com/go-toolsmith/astp/stmt.go delete mode 100644 vendor/github.com/go-toolsmith/strparse/LICENSE delete mode 100644 vendor/github.com/go-toolsmith/strparse/README.md delete mode 100644 vendor/github.com/go-toolsmith/strparse/strparse.go delete mode 100644 vendor/github.com/go-toolsmith/typep/LICENSE delete mode 100644 vendor/github.com/go-toolsmith/typep/README.md delete mode 100644 vendor/github.com/go-toolsmith/typep/doc.go delete mode 100644 vendor/github.com/go-toolsmith/typep/predicates.go delete mode 100644 vendor/github.com/go-toolsmith/typep/safe_expr.go delete mode 100644 vendor/github.com/go-toolsmith/typep/simple_predicates.go delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/.editorconfig delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/.envrc delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/.gitignore delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/.golangci.yaml delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/CHANGELOG.md delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/LICENSE delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/README.md delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/flake.lock delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/flake.nix delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/internal/errors/errors.go delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/internal/errors/join.go delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/internal/errors/join_go1_19.go delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/mapstructure.go delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/reflect_go1_19.go delete mode 100644 vendor/github.com/go-viper/mapstructure/v2/reflect_go1_20.go delete mode 100644 vendor/github.com/go-xmlfmt/xmlfmt/LICENSE delete mode 100644 vendor/github.com/go-xmlfmt/xmlfmt/README.md delete mode 100644 vendor/github.com/go-xmlfmt/xmlfmt/xmlfmt.go delete mode 100644 vendor/github.com/gobwas/glob/.gitignore delete mode 100644 vendor/github.com/gobwas/glob/.travis.yml delete mode 100644 vendor/github.com/gobwas/glob/LICENSE delete mode 100644 vendor/github.com/gobwas/glob/bench.sh delete mode 100644 vendor/github.com/gobwas/glob/compiler/compiler.go delete mode 100644 vendor/github.com/gobwas/glob/glob.go delete mode 100644 vendor/github.com/gobwas/glob/match/any.go delete mode 100644 vendor/github.com/gobwas/glob/match/any_of.go delete mode 100644 vendor/github.com/gobwas/glob/match/btree.go delete mode 100644 vendor/github.com/gobwas/glob/match/contains.go delete mode 100644 vendor/github.com/gobwas/glob/match/every_of.go delete mode 100644 vendor/github.com/gobwas/glob/match/list.go delete mode 100644 vendor/github.com/gobwas/glob/match/match.go delete mode 100644 vendor/github.com/gobwas/glob/match/max.go delete mode 100644 vendor/github.com/gobwas/glob/match/min.go delete mode 100644 vendor/github.com/gobwas/glob/match/nothing.go delete mode 100644 vendor/github.com/gobwas/glob/match/prefix.go delete mode 100644 vendor/github.com/gobwas/glob/match/prefix_any.go delete mode 100644 vendor/github.com/gobwas/glob/match/prefix_suffix.go delete mode 100644 vendor/github.com/gobwas/glob/match/range.go delete mode 100644 vendor/github.com/gobwas/glob/match/row.go delete mode 100644 vendor/github.com/gobwas/glob/match/segments.go delete mode 100644 vendor/github.com/gobwas/glob/match/single.go delete mode 100644 vendor/github.com/gobwas/glob/match/suffix.go delete mode 100644 vendor/github.com/gobwas/glob/match/suffix_any.go delete mode 100644 vendor/github.com/gobwas/glob/match/super.go delete mode 100644 vendor/github.com/gobwas/glob/match/text.go delete mode 100644 vendor/github.com/gobwas/glob/readme.md delete mode 100644 vendor/github.com/gobwas/glob/syntax/ast/ast.go delete mode 100644 vendor/github.com/gobwas/glob/syntax/ast/parser.go delete mode 100644 vendor/github.com/gobwas/glob/syntax/lexer/lexer.go delete mode 100644 vendor/github.com/gobwas/glob/syntax/lexer/token.go delete mode 100644 vendor/github.com/gobwas/glob/syntax/syntax.go delete mode 100644 vendor/github.com/gobwas/glob/util/runes/runes.go delete mode 100644 vendor/github.com/gobwas/glob/util/strings/strings.go delete mode 100644 vendor/github.com/gofrs/flock/.gitignore delete mode 100644 vendor/github.com/gofrs/flock/.golangci.yml delete mode 100644 vendor/github.com/gofrs/flock/LICENSE delete mode 100644 vendor/github.com/gofrs/flock/Makefile delete mode 100644 vendor/github.com/gofrs/flock/README.md delete mode 100644 vendor/github.com/gofrs/flock/SECURITY.md delete mode 100644 vendor/github.com/gofrs/flock/build.sh delete mode 100644 vendor/github.com/gofrs/flock/flock.go delete mode 100644 vendor/github.com/gofrs/flock/flock_others.go delete mode 100644 vendor/github.com/gofrs/flock/flock_unix.go delete mode 100644 vendor/github.com/gofrs/flock/flock_unix_fcntl.go delete mode 100644 vendor/github.com/gofrs/flock/flock_windows.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/.gitignore delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/LICENSE delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/README.md delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/SECURITY.md delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/claims.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/doc.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/ecdsa.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/ed25519.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/errors.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/errors_go1_20.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/errors_go_other.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/hmac.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/map_claims.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/none.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/parser.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/parser_option.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/registered_claims.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/rsa.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/signing_method.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/staticcheck.conf delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/token.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/token_option.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/types.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v5/validator.go delete mode 100644 vendor/github.com/golangci/dupl/.travis.yml delete mode 100644 vendor/github.com/golangci/dupl/LICENSE delete mode 100644 vendor/github.com/golangci/dupl/README.md delete mode 100644 vendor/github.com/golangci/dupl/job/buildtree.go delete mode 100644 vendor/github.com/golangci/dupl/job/parse.go delete mode 100644 vendor/github.com/golangci/dupl/main.go delete mode 100644 vendor/github.com/golangci/dupl/printer/html.go delete mode 100644 vendor/github.com/golangci/dupl/printer/plumbing.go delete mode 100644 vendor/github.com/golangci/dupl/printer/printer.go delete mode 100644 vendor/github.com/golangci/dupl/printer/text.go delete mode 100644 vendor/github.com/golangci/dupl/suffixtree/dupl.go delete mode 100644 vendor/github.com/golangci/dupl/suffixtree/suffixtree.go delete mode 100644 vendor/github.com/golangci/dupl/syntax/golang/golang.go delete mode 100644 vendor/github.com/golangci/dupl/syntax/syntax.go delete mode 100644 vendor/github.com/golangci/gofmt/gofmt/LICENSE delete mode 100644 vendor/github.com/golangci/gofmt/gofmt/doc.go delete mode 100644 vendor/github.com/golangci/gofmt/gofmt/gofmt.go delete mode 100644 vendor/github.com/golangci/gofmt/gofmt/golangci.go delete mode 100644 vendor/github.com/golangci/gofmt/gofmt/internal.go delete mode 100644 vendor/github.com/golangci/gofmt/gofmt/internal/diff/diff.go delete mode 100644 vendor/github.com/golangci/gofmt/gofmt/readme.md delete mode 100644 vendor/github.com/golangci/gofmt/gofmt/rewrite.go delete mode 100644 vendor/github.com/golangci/gofmt/gofmt/simplify.go delete mode 100644 vendor/github.com/golangci/gofmt/goimports/LICENSE delete mode 100644 vendor/github.com/golangci/gofmt/goimports/goimports.go delete mode 100644 vendor/github.com/golangci/gofmt/goimports/golangci.go delete mode 100644 vendor/github.com/golangci/gofmt/goimports/readme.md delete mode 100644 vendor/github.com/golangci/golangci-lint/LICENSE delete mode 100644 vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/main.go delete mode 100644 vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/plugins.go delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/cache/cache.go delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/cache/default.go delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/cache/hash.go delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/cache/readme.md delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/errorutil/errors.go delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/pkgcache/pkgcache.go delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/renameio/readme.md delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/renameio/renameio.go delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/robustio/readme.md delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/robustio/robustio.go delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_darwin.go delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_flaky.go delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_other.go delete mode 100644 vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_windows.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/cache.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/config.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/config_verify.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/custom.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/flagsets.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/help.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/internal/builder.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/internal/configuration.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/internal/imports.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/internal/vibra.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/linters.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/root.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/run.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/commands/version.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/config/config.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/config/issues.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/config/linters.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/config/linters_settings.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/config/loader.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/config/output.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/config/run.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/config/severity.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/exitcodes/exitcodes.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/fsutils/filecache.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/fsutils/files.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/fsutils/fsutils.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/fsutils/linecache.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/fsutils/path_unix.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/fsutils/path_windows.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/issue.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/linter.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/load/guard.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/metalinter.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/errors.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/extract.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/parse.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_action.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_facts.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_loadingpackage.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runners.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/asasalint/asasalint.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/asciicheck/asciicheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/bidichk/bidichk.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/bodyclose/bodyclose.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/canonicalheader/canonicalheader.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/containedctx/containedctx.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/contextcheck/contextcheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/copyloopvar/copyloopvar.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/cyclop/cyclop.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/decorder/decorder.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/depguard/depguard.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/dogsled/dogsled.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/dupl/dupl.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/dupword/dupword.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/durationcheck/durationcheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/err113/err113.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/errcheck/errcheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/errchkjson/errchkjson.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/errname/errname.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/errorlint/errorlint.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/execinquery/execinquery.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustive/exhaustive.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustruct/exhaustruct.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/exportloopref/exportloopref.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/fatcontext/fatcontext.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/forbidigo/forbidigo.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/forcetypeassert/forcetypeassert.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/funlen/funlen.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gci/gci.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/ginkgolinter/ginkgolinter.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoglobals/gochecknoglobals.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoinits/gochecknoinits.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecksumtype/gochecksumtype.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gocognit/gocognit.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/goconst/goconst.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gocritic/gocritic.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gocyclo/gocyclo.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/godot/godot.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/godox/godox.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gofmt/gofmt.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gofumpt/gofumpt.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/goheader/goheader.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/goimports/goimports.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gomoddirectives/gomoddirectives.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gomodguard/gomodguard.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/goprintffuncname/goprintffuncname.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gosec/gosec.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gosimple/gosimple.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/gosmopolitan/gosmopolitan.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/govet/govet.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/grouper/grouper.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/importas/importas.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/inamedparam/inamedparam.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/ineffassign/ineffassign.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/interfacebloat/interfacebloat.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/commons.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/diff.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/staticcheck_common.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/util.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/intrange/intrange.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/ireturn/ireturn.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/lll/lll.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/loggercheck/loggercheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/maintidx/maintidx.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/makezero/makezero.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/mirror/mirror.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/misspell/misspell.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/mnd/mnd.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/musttag/musttag.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/nakedret/nakedret.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/nestif/nestif.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/nilerr/nilerr.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/nilnil/nilnil.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/nlreturn/nlreturn.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/noctx/noctx.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/README.md delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/nolintlint.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/nolintlint.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/nonamedreturns/nonamedreturns.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/nosprintfhostport/nosprintfhostport.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/paralleltest/paralleltest.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/perfsprint/perfsprint.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/prealloc/prealloc.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/predeclared/predeclared.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/promlinter/promlinter.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/protogetter/protogetter.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/reassign/reassign.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/revive/revive.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/rowserrcheck/rowserrcheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/sloglint/sloglint.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/spancheck/spancheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/sqlclosecheck/sqlclosecheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/staticcheck/staticcheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/stylecheck/stylecheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/tagalign/tagalign.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/tagliatelle/tagliatelle.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/tenv/tenv.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/testableexamples/testableexamples.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/testifylint/testifylint.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/testpackage/testpackage.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/thelper/thelper.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/tparallel/tparallel.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/typecheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/unconvert/unconvert.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/unparam/unparam.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/unused/unused.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/usestdlibvars/usestdlibvars.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/varnamelen/varnamelen.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/wastedassign/wastedassign.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/whitespace/whitespace.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/wrapcheck/wrapcheck.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/wsl/wsl.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/golinters/zerologlint/zerologlint.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goutil/env.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/goutil/version.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/lint/context.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/lint/linter/config.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/lint/linter/context.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/lint/linter/linter.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_linter.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_go.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_module.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/manager.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/validator.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/lint/package.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/lint/runner.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/logutils/log.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/logutils/logutils.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/logutils/mock.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/logutils/out.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/logutils/stderr_log.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/printers/checkstyle.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/printers/codeclimate.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/printers/githubaction.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/printers/html.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/printers/json.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/printers/junitxml.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/printers/printer.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/printers/sarif.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/printers/tab.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/printers/teamcity.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/printers/text.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/report/data.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/report/log.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/issue.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/autogenerated_exclude.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/base_rule.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/cgo.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/diff.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclude.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclude_rules.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/filename_unadjuster.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/fixer.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/identifier_marker.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/invalid_issue.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/issues.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_from_linter.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_per_file_from_linter.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_same_issues.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/nolint.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_prefixer.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_prettifier.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_shortener.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/processor.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/severity.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_dirs.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_files.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/sort_results.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/source_code.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/result/processors/uniq_by_line.go delete mode 100644 vendor/github.com/golangci/golangci-lint/pkg/timeutils/stopwatch.go delete mode 100644 vendor/github.com/golangci/misspell/.gitignore delete mode 100644 vendor/github.com/golangci/misspell/.golangci.yml delete mode 100644 vendor/github.com/golangci/misspell/.pre-commit-hooks.yaml delete mode 100644 vendor/github.com/golangci/misspell/Dockerfile delete mode 100644 vendor/github.com/golangci/misspell/LICENSE delete mode 100644 vendor/github.com/golangci/misspell/Makefile delete mode 100644 vendor/github.com/golangci/misspell/README.md delete mode 100644 vendor/github.com/golangci/misspell/RELEASE-HOWTO.md delete mode 100644 vendor/github.com/golangci/misspell/ascii.go delete mode 100644 vendor/github.com/golangci/misspell/case.go delete mode 100644 vendor/github.com/golangci/misspell/goreleaser.yml delete mode 100644 vendor/github.com/golangci/misspell/install-misspell.sh delete mode 100644 vendor/github.com/golangci/misspell/legal.go delete mode 100644 vendor/github.com/golangci/misspell/mime.go delete mode 100644 vendor/github.com/golangci/misspell/notwords.go delete mode 100644 vendor/github.com/golangci/misspell/replace.go delete mode 100644 vendor/github.com/golangci/misspell/stringreplacer.go delete mode 100644 vendor/github.com/golangci/misspell/stringreplacer_test.gox delete mode 100644 vendor/github.com/golangci/misspell/url.go delete mode 100644 vendor/github.com/golangci/misspell/words.go delete mode 100644 vendor/github.com/golangci/modinfo/.gitignore delete mode 100644 vendor/github.com/golangci/modinfo/.golangci.yml delete mode 100644 vendor/github.com/golangci/modinfo/LICENSE delete mode 100644 vendor/github.com/golangci/modinfo/Makefile delete mode 100644 vendor/github.com/golangci/modinfo/module.go delete mode 100644 vendor/github.com/golangci/modinfo/readme.md delete mode 100644 vendor/github.com/golangci/plugin-module-register/LICENSE delete mode 100644 vendor/github.com/golangci/plugin-module-register/register/register.go delete mode 100644 vendor/github.com/golangci/revgrep/.gitignore delete mode 100644 vendor/github.com/golangci/revgrep/.golangci.yml delete mode 100644 vendor/github.com/golangci/revgrep/LICENSE delete mode 100644 vendor/github.com/golangci/revgrep/Makefile delete mode 100644 vendor/github.com/golangci/revgrep/README.md delete mode 100644 vendor/github.com/golangci/revgrep/revgrep.go delete mode 100644 vendor/github.com/golangci/unconvert/LICENSE delete mode 100644 vendor/github.com/golangci/unconvert/README.md delete mode 100644 vendor/github.com/golangci/unconvert/golangci.go delete mode 100644 vendor/github.com/golangci/unconvert/unconvert.go delete mode 100644 vendor/github.com/google/go-cmp/LICENSE delete mode 100644 vendor/github.com/google/go-cmp/cmp/compare.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/export.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/internal/function/func.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/internal/value/name.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/internal/value/pointer.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/internal/value/sort.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/options.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/path.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/report.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/report_compare.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/report_references.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/report_reflect.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/report_slices.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/report_text.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/report_value.go delete mode 100644 vendor/github.com/google/uuid/CHANGELOG.md delete mode 100644 vendor/github.com/google/uuid/CONTRIBUTING.md delete mode 100644 vendor/github.com/google/uuid/CONTRIBUTORS delete mode 100644 vendor/github.com/google/uuid/LICENSE delete mode 100644 vendor/github.com/google/uuid/README.md delete mode 100644 vendor/github.com/google/uuid/dce.go delete mode 100644 vendor/github.com/google/uuid/doc.go delete mode 100644 vendor/github.com/google/uuid/hash.go delete mode 100644 vendor/github.com/google/uuid/marshal.go delete mode 100644 vendor/github.com/google/uuid/node.go delete mode 100644 vendor/github.com/google/uuid/node_js.go delete mode 100644 vendor/github.com/google/uuid/node_net.go delete mode 100644 vendor/github.com/google/uuid/null.go delete mode 100644 vendor/github.com/google/uuid/sql.go delete mode 100644 vendor/github.com/google/uuid/time.go delete mode 100644 vendor/github.com/google/uuid/util.go delete mode 100644 vendor/github.com/google/uuid/uuid.go delete mode 100644 vendor/github.com/google/uuid/version1.go delete mode 100644 vendor/github.com/google/uuid/version4.go delete mode 100644 vendor/github.com/google/uuid/version6.go delete mode 100644 vendor/github.com/google/uuid/version7.go delete mode 100644 vendor/github.com/gordonklaus/ineffassign/LICENSE delete mode 100644 vendor/github.com/gordonklaus/ineffassign/pkg/ineffassign/ineffassign.go delete mode 100644 vendor/github.com/gorilla/mux/.editorconfig delete mode 100644 vendor/github.com/gorilla/mux/.gitignore delete mode 100644 vendor/github.com/gorilla/mux/LICENSE delete mode 100644 vendor/github.com/gorilla/mux/Makefile delete mode 100644 vendor/github.com/gorilla/mux/README.md delete mode 100644 vendor/github.com/gorilla/mux/doc.go delete mode 100644 vendor/github.com/gorilla/mux/middleware.go delete mode 100644 vendor/github.com/gorilla/mux/mux.go delete mode 100644 vendor/github.com/gorilla/mux/regexp.go delete mode 100644 vendor/github.com/gorilla/mux/route.go delete mode 100644 vendor/github.com/gorilla/mux/test_helpers.go delete mode 100644 vendor/github.com/gostaticanalysis/analysisutil/LICENSE delete mode 100644 vendor/github.com/gostaticanalysis/analysisutil/README.md delete mode 100644 vendor/github.com/gostaticanalysis/analysisutil/call.go delete mode 100644 vendor/github.com/gostaticanalysis/analysisutil/diagnostic.go delete mode 100644 vendor/github.com/gostaticanalysis/analysisutil/file.go delete mode 100644 vendor/github.com/gostaticanalysis/analysisutil/pkg.go delete mode 100644 vendor/github.com/gostaticanalysis/analysisutil/ssa.go delete mode 100644 vendor/github.com/gostaticanalysis/analysisutil/ssainspect.go delete mode 100644 vendor/github.com/gostaticanalysis/analysisutil/types.go delete mode 100644 vendor/github.com/gostaticanalysis/comment/LICENSE delete mode 100644 vendor/github.com/gostaticanalysis/comment/README.md delete mode 100644 vendor/github.com/gostaticanalysis/comment/comment.go delete mode 100644 vendor/github.com/gostaticanalysis/comment/passes/commentmap/commentmap.go delete mode 100644 vendor/github.com/gostaticanalysis/forcetypeassert/.reviewdog.yml delete mode 100644 vendor/github.com/gostaticanalysis/forcetypeassert/LICENSE delete mode 100644 vendor/github.com/gostaticanalysis/forcetypeassert/README.md delete mode 100644 vendor/github.com/gostaticanalysis/forcetypeassert/forcetypeassert.go delete mode 100644 vendor/github.com/gostaticanalysis/nilerr/LICENSE delete mode 100644 vendor/github.com/gostaticanalysis/nilerr/README.md delete mode 100644 vendor/github.com/gostaticanalysis/nilerr/nilerr.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/.gitignore delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/CONTRIBUTING.md delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/auth.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/doc.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/metadata.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/LICENSE delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_metrics.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_options.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/constants.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/doc.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/backoff.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/doc.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/options.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/retry.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/slack.png delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/client_interceptors.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/doc.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/id_extract.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/metadata.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/options.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/server_interceptors.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/backoffutils/backoff.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/COPYRIGHT delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/LICENSE delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/client.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/doc.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/reporter.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/server.go delete mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go delete mode 100644 vendor/github.com/hashicorp/go-version/CHANGELOG.md delete mode 100644 vendor/github.com/hashicorp/go-version/LICENSE delete mode 100644 vendor/github.com/hashicorp/go-version/README.md delete mode 100644 vendor/github.com/hashicorp/go-version/constraint.go delete mode 100644 vendor/github.com/hashicorp/go-version/version.go delete mode 100644 vendor/github.com/hashicorp/go-version/version_collection.go delete mode 100644 vendor/github.com/hashicorp/hcl/.gitignore delete mode 100644 vendor/github.com/hashicorp/hcl/.travis.yml delete mode 100644 vendor/github.com/hashicorp/hcl/LICENSE delete mode 100644 vendor/github.com/hashicorp/hcl/Makefile delete mode 100644 vendor/github.com/hashicorp/hcl/README.md delete mode 100644 vendor/github.com/hashicorp/hcl/appveyor.yml delete mode 100644 vendor/github.com/hashicorp/hcl/decoder.go delete mode 100644 vendor/github.com/hashicorp/hcl/hcl.go delete mode 100644 vendor/github.com/hashicorp/hcl/hcl/ast/ast.go delete mode 100644 vendor/github.com/hashicorp/hcl/hcl/ast/walk.go delete mode 100644 vendor/github.com/hashicorp/hcl/hcl/parser/error.go delete mode 100644 vendor/github.com/hashicorp/hcl/hcl/parser/parser.go delete mode 100644 vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go delete mode 100644 vendor/github.com/hashicorp/hcl/hcl/printer/printer.go delete mode 100644 vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go delete mode 100644 vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go delete mode 100644 vendor/github.com/hashicorp/hcl/hcl/token/position.go delete mode 100644 vendor/github.com/hashicorp/hcl/hcl/token/token.go delete mode 100644 vendor/github.com/hashicorp/hcl/json/parser/flatten.go delete mode 100644 vendor/github.com/hashicorp/hcl/json/parser/parser.go delete mode 100644 vendor/github.com/hashicorp/hcl/json/scanner/scanner.go delete mode 100644 vendor/github.com/hashicorp/hcl/json/token/position.go delete mode 100644 vendor/github.com/hashicorp/hcl/json/token/token.go delete mode 100644 vendor/github.com/hashicorp/hcl/lex.go delete mode 100644 vendor/github.com/hashicorp/hcl/parse.go delete mode 100644 vendor/github.com/hexops/gotextdiff/LICENSE delete mode 100644 vendor/github.com/hexops/gotextdiff/README.md delete mode 100644 vendor/github.com/hexops/gotextdiff/diff.go delete mode 100644 vendor/github.com/hexops/gotextdiff/myers/diff.go delete mode 100644 vendor/github.com/hexops/gotextdiff/span/parse.go delete mode 100644 vendor/github.com/hexops/gotextdiff/span/span.go delete mode 100644 vendor/github.com/hexops/gotextdiff/span/token.go delete mode 100644 vendor/github.com/hexops/gotextdiff/span/token111.go delete mode 100644 vendor/github.com/hexops/gotextdiff/span/token112.go delete mode 100644 vendor/github.com/hexops/gotextdiff/span/uri.go delete mode 100644 vendor/github.com/hexops/gotextdiff/span/utf16.go delete mode 100644 vendor/github.com/hexops/gotextdiff/unified.go delete mode 100644 vendor/github.com/inconshreveable/mousetrap/LICENSE delete mode 100644 vendor/github.com/inconshreveable/mousetrap/README.md delete mode 100644 vendor/github.com/inconshreveable/mousetrap/trap_others.go delete mode 100644 vendor/github.com/inconshreveable/mousetrap/trap_windows.go delete mode 100644 vendor/github.com/jgautheron/goconst/LICENSE delete mode 100644 vendor/github.com/jgautheron/goconst/README.md delete mode 100644 vendor/github.com/jgautheron/goconst/api.go delete mode 100644 vendor/github.com/jgautheron/goconst/parser.go delete mode 100644 vendor/github.com/jgautheron/goconst/visitor.go delete mode 100644 vendor/github.com/jingyugao/rowserrcheck/LICENSE delete mode 100644 vendor/github.com/jingyugao/rowserrcheck/passes/rowserr/rowserr.go delete mode 100644 vendor/github.com/jinzhu/inflection/LICENSE delete mode 100644 vendor/github.com/jinzhu/inflection/README.md delete mode 100644 vendor/github.com/jinzhu/inflection/inflections.go delete mode 100644 vendor/github.com/jinzhu/inflection/wercker.yml delete mode 100644 vendor/github.com/jirfag/go-printf-func-name/LICENSE delete mode 100644 vendor/github.com/jirfag/go-printf-func-name/pkg/analyzer/analyzer.go delete mode 100644 vendor/github.com/jjti/go-spancheck/.gitignore delete mode 100644 vendor/github.com/jjti/go-spancheck/.golangci.yml delete mode 100644 vendor/github.com/jjti/go-spancheck/CONTRIBUTING.md delete mode 100644 vendor/github.com/jjti/go-spancheck/LICENSE delete mode 100644 vendor/github.com/jjti/go-spancheck/Makefile delete mode 100644 vendor/github.com/jjti/go-spancheck/README.md delete mode 100644 vendor/github.com/jjti/go-spancheck/config.go delete mode 100644 vendor/github.com/jjti/go-spancheck/doc.go delete mode 100644 vendor/github.com/jjti/go-spancheck/go.work delete mode 100644 vendor/github.com/jjti/go-spancheck/go.work.sum delete mode 100644 vendor/github.com/jjti/go-spancheck/spancheck.go delete mode 100644 vendor/github.com/jpillora/backoff/LICENSE delete mode 100644 vendor/github.com/jpillora/backoff/README.md delete mode 100644 vendor/github.com/jpillora/backoff/backoff.go delete mode 100644 vendor/github.com/json-iterator/go/.codecov.yml delete mode 100644 vendor/github.com/json-iterator/go/.gitignore delete mode 100644 vendor/github.com/json-iterator/go/.travis.yml delete mode 100644 vendor/github.com/json-iterator/go/Gopkg.lock delete mode 100644 vendor/github.com/json-iterator/go/Gopkg.toml delete mode 100644 vendor/github.com/json-iterator/go/LICENSE delete mode 100644 vendor/github.com/json-iterator/go/README.md delete mode 100644 vendor/github.com/json-iterator/go/adapter.go delete mode 100644 vendor/github.com/json-iterator/go/any.go delete mode 100644 vendor/github.com/json-iterator/go/any_array.go delete mode 100644 vendor/github.com/json-iterator/go/any_bool.go delete mode 100644 vendor/github.com/json-iterator/go/any_float.go delete mode 100644 vendor/github.com/json-iterator/go/any_int32.go delete mode 100644 vendor/github.com/json-iterator/go/any_int64.go delete mode 100644 vendor/github.com/json-iterator/go/any_invalid.go delete mode 100644 vendor/github.com/json-iterator/go/any_nil.go delete mode 100644 vendor/github.com/json-iterator/go/any_number.go delete mode 100644 vendor/github.com/json-iterator/go/any_object.go delete mode 100644 vendor/github.com/json-iterator/go/any_str.go delete mode 100644 vendor/github.com/json-iterator/go/any_uint32.go delete mode 100644 vendor/github.com/json-iterator/go/any_uint64.go delete mode 100644 vendor/github.com/json-iterator/go/build.sh delete mode 100644 vendor/github.com/json-iterator/go/config.go delete mode 100644 vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md delete mode 100644 vendor/github.com/json-iterator/go/iter.go delete mode 100644 vendor/github.com/json-iterator/go/iter_array.go delete mode 100644 vendor/github.com/json-iterator/go/iter_float.go delete mode 100644 vendor/github.com/json-iterator/go/iter_int.go delete mode 100644 vendor/github.com/json-iterator/go/iter_object.go delete mode 100644 vendor/github.com/json-iterator/go/iter_skip.go delete mode 100644 vendor/github.com/json-iterator/go/iter_skip_sloppy.go delete mode 100644 vendor/github.com/json-iterator/go/iter_skip_strict.go delete mode 100644 vendor/github.com/json-iterator/go/iter_str.go delete mode 100644 vendor/github.com/json-iterator/go/jsoniter.go delete mode 100644 vendor/github.com/json-iterator/go/pool.go delete mode 100644 vendor/github.com/json-iterator/go/reflect.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_array.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_dynamic.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_extension.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_json_number.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_json_raw_message.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_map.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_marshaler.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_native.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_optional.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_slice.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_struct_decoder.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_struct_encoder.go delete mode 100644 vendor/github.com/json-iterator/go/stream.go delete mode 100644 vendor/github.com/json-iterator/go/stream_float.go delete mode 100644 vendor/github.com/json-iterator/go/stream_int.go delete mode 100644 vendor/github.com/json-iterator/go/stream_str.go delete mode 100644 vendor/github.com/json-iterator/go/test.sh delete mode 100644 vendor/github.com/julz/importas/.gitignore delete mode 100644 vendor/github.com/julz/importas/LICENSE delete mode 100644 vendor/github.com/julz/importas/README.md delete mode 100644 vendor/github.com/julz/importas/analyzer.go delete mode 100644 vendor/github.com/julz/importas/config.go delete mode 100644 vendor/github.com/julz/importas/flags.go delete mode 100644 vendor/github.com/karamaru-alpha/copyloopvar/.gitignore delete mode 100644 vendor/github.com/karamaru-alpha/copyloopvar/LICENSE delete mode 100644 vendor/github.com/karamaru-alpha/copyloopvar/README.md delete mode 100644 vendor/github.com/karamaru-alpha/copyloopvar/copyloopvar.go delete mode 100644 vendor/github.com/kisielk/errcheck/LICENSE delete mode 100644 vendor/github.com/kisielk/errcheck/errcheck/analyzer.go delete mode 100644 vendor/github.com/kisielk/errcheck/errcheck/embedded_walker.go delete mode 100644 vendor/github.com/kisielk/errcheck/errcheck/errcheck.go delete mode 100644 vendor/github.com/kisielk/errcheck/errcheck/excludes.go delete mode 100644 vendor/github.com/kisielk/errcheck/errcheck/tags.go delete mode 100644 vendor/github.com/kisielk/errcheck/errcheck/tags_compat.go delete mode 100644 vendor/github.com/kkHAIKE/contextcheck/.gitignore delete mode 100644 vendor/github.com/kkHAIKE/contextcheck/LICENSE delete mode 100644 vendor/github.com/kkHAIKE/contextcheck/Makefile delete mode 100644 vendor/github.com/kkHAIKE/contextcheck/README.md delete mode 100644 vendor/github.com/kkHAIKE/contextcheck/contextcheck.go delete mode 100644 vendor/github.com/klauspost/cpuid/.gitignore delete mode 100644 vendor/github.com/klauspost/cpuid/.travis.yml delete mode 100644 vendor/github.com/klauspost/cpuid/CONTRIBUTING.txt delete mode 100644 vendor/github.com/klauspost/cpuid/LICENSE delete mode 100644 vendor/github.com/klauspost/cpuid/README.md delete mode 100644 vendor/github.com/klauspost/cpuid/cpuid.go delete mode 100644 vendor/github.com/klauspost/cpuid/cpuid_386.s delete mode 100644 vendor/github.com/klauspost/cpuid/cpuid_amd64.s delete mode 100644 vendor/github.com/klauspost/cpuid/cpuid_arm64.s delete mode 100644 vendor/github.com/klauspost/cpuid/detect_arm64.go delete mode 100644 vendor/github.com/klauspost/cpuid/detect_intel.go delete mode 100644 vendor/github.com/klauspost/cpuid/detect_ref.go delete mode 100644 vendor/github.com/kulti/thelper/LICENSE delete mode 100644 vendor/github.com/kulti/thelper/pkg/analyzer/analyzer.go delete mode 100644 vendor/github.com/kulti/thelper/pkg/analyzer/report.go delete mode 100644 vendor/github.com/kunwardeep/paralleltest/LICENSE delete mode 100644 vendor/github.com/kunwardeep/paralleltest/pkg/paralleltest/paralleltest.go delete mode 100644 vendor/github.com/kyoh86/exportloopref/.golangci.yml delete mode 100644 vendor/github.com/kyoh86/exportloopref/.goreleaser.yml delete mode 100644 vendor/github.com/kyoh86/exportloopref/LICENSE delete mode 100644 vendor/github.com/kyoh86/exportloopref/Makefile delete mode 100644 vendor/github.com/kyoh86/exportloopref/README.md delete mode 100644 vendor/github.com/kyoh86/exportloopref/exportloopref.go delete mode 100644 vendor/github.com/lasiar/canonicalheader/.gitignore delete mode 100644 vendor/github.com/lasiar/canonicalheader/.golangci.yaml delete mode 100644 vendor/github.com/lasiar/canonicalheader/.goreleaser.yaml delete mode 100644 vendor/github.com/lasiar/canonicalheader/LICENCE delete mode 100644 vendor/github.com/lasiar/canonicalheader/README.md delete mode 100644 vendor/github.com/lasiar/canonicalheader/analyzer.go delete mode 100644 vendor/github.com/lasiar/canonicalheader/constant_string.go delete mode 100644 vendor/github.com/lasiar/canonicalheader/initialism.go delete mode 100644 vendor/github.com/lasiar/canonicalheader/literal_string.go delete mode 100644 vendor/github.com/lasiar/canonicalheader/makefile delete mode 100644 vendor/github.com/ldez/gomoddirectives/.gitignore delete mode 100644 vendor/github.com/ldez/gomoddirectives/.golangci.yml delete mode 100644 vendor/github.com/ldez/gomoddirectives/LICENSE delete mode 100644 vendor/github.com/ldez/gomoddirectives/Makefile delete mode 100644 vendor/github.com/ldez/gomoddirectives/gomoddirectives.go delete mode 100644 vendor/github.com/ldez/gomoddirectives/module.go delete mode 100644 vendor/github.com/ldez/gomoddirectives/readme.md delete mode 100644 vendor/github.com/ldez/tagliatelle/.gitignore delete mode 100644 vendor/github.com/ldez/tagliatelle/.golangci.yml delete mode 100644 vendor/github.com/ldez/tagliatelle/LICENSE delete mode 100644 vendor/github.com/ldez/tagliatelle/Makefile delete mode 100644 vendor/github.com/ldez/tagliatelle/readme.md delete mode 100644 vendor/github.com/ldez/tagliatelle/tagliatelle.go delete mode 100644 vendor/github.com/leonklingele/grouper/LICENSE delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/analyzer.go delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/config.go delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/consts/analyzer.go delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/consts/config.go delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/flags.go delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/globals/analyzer.go delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/imports/analyzer.go delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/imports/config.go delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/types/analyzer.go delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/types/config.go delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/vars/analyzer.go delete mode 100644 vendor/github.com/leonklingele/grouper/pkg/analyzer/vars/config.go delete mode 100644 vendor/github.com/lufeee/execinquery/.gitignore delete mode 100644 vendor/github.com/lufeee/execinquery/LICENSE delete mode 100644 vendor/github.com/lufeee/execinquery/README.md delete mode 100644 vendor/github.com/lufeee/execinquery/execinquery.go delete mode 100644 vendor/github.com/macabu/inamedparam/.gitignore delete mode 100644 vendor/github.com/macabu/inamedparam/.golangci.yml delete mode 100644 vendor/github.com/macabu/inamedparam/LICENSE-MIT delete mode 100644 vendor/github.com/macabu/inamedparam/README.md delete mode 100644 vendor/github.com/macabu/inamedparam/inamedparam.go delete mode 100644 vendor/github.com/magiconair/properties/.gitignore delete mode 100644 vendor/github.com/magiconair/properties/.travis.yml delete mode 100644 vendor/github.com/magiconair/properties/CHANGELOG.md delete mode 100644 vendor/github.com/magiconair/properties/LICENSE.md delete mode 100644 vendor/github.com/magiconair/properties/README.md delete mode 100644 vendor/github.com/magiconair/properties/decode.go delete mode 100644 vendor/github.com/magiconair/properties/doc.go delete mode 100644 vendor/github.com/magiconair/properties/integrate.go delete mode 100644 vendor/github.com/magiconair/properties/lex.go delete mode 100644 vendor/github.com/magiconair/properties/load.go delete mode 100644 vendor/github.com/magiconair/properties/parser.go delete mode 100644 vendor/github.com/magiconair/properties/properties.go delete mode 100644 vendor/github.com/magiconair/properties/rangecheck.go delete mode 100644 vendor/github.com/maratori/testableexamples/LICENSE delete mode 100644 vendor/github.com/maratori/testableexamples/pkg/testableexamples/testableexamples.go delete mode 100644 vendor/github.com/maratori/testpackage/LICENSE delete mode 100644 vendor/github.com/maratori/testpackage/pkg/testpackage/testpackage.go delete mode 100644 vendor/github.com/matoous/godox/.gitignore delete mode 100644 vendor/github.com/matoous/godox/.golangci.yml delete mode 100644 vendor/github.com/matoous/godox/.revive.toml delete mode 100644 vendor/github.com/matoous/godox/LICENSE delete mode 100644 vendor/github.com/matoous/godox/README.md delete mode 100644 vendor/github.com/matoous/godox/godox.go delete mode 100644 vendor/github.com/mattn/go-colorable/LICENSE delete mode 100644 vendor/github.com/mattn/go-colorable/README.md delete mode 100644 vendor/github.com/mattn/go-colorable/colorable_appengine.go delete mode 100644 vendor/github.com/mattn/go-colorable/colorable_others.go delete mode 100644 vendor/github.com/mattn/go-colorable/colorable_windows.go delete mode 100644 vendor/github.com/mattn/go-colorable/go.test.sh delete mode 100644 vendor/github.com/mattn/go-colorable/noncolorable.go delete mode 100644 vendor/github.com/mattn/go-isatty/LICENSE delete mode 100644 vendor/github.com/mattn/go-isatty/README.md delete mode 100644 vendor/github.com/mattn/go-isatty/doc.go delete mode 100644 vendor/github.com/mattn/go-isatty/go.test.sh delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_bsd.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_others.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_plan9.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_solaris.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_tcgets.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_windows.go delete mode 100644 vendor/github.com/mattn/go-runewidth/LICENSE delete mode 100644 vendor/github.com/mattn/go-runewidth/README.md delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_appengine.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_js.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_posix.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_table.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_windows.go delete mode 100644 vendor/github.com/mattn/goveralls/.gitignore delete mode 100644 vendor/github.com/mattn/goveralls/.travis.yml delete mode 100644 vendor/github.com/mattn/goveralls/LICENSE delete mode 100644 vendor/github.com/mattn/goveralls/README.md delete mode 100644 vendor/github.com/mattn/goveralls/gitinfo.go delete mode 100644 vendor/github.com/mattn/goveralls/gocover.go delete mode 100644 vendor/github.com/mattn/goveralls/goveralls.go delete mode 100644 vendor/github.com/mattn/goveralls/renovate.json delete mode 100644 vendor/github.com/mgechev/revive/LICENSE delete mode 100644 vendor/github.com/mgechev/revive/config/config.go delete mode 100644 vendor/github.com/mgechev/revive/formatter/checkstyle.go delete mode 100644 vendor/github.com/mgechev/revive/formatter/default.go delete mode 100644 vendor/github.com/mgechev/revive/formatter/doc.go delete mode 100644 vendor/github.com/mgechev/revive/formatter/friendly.go delete mode 100644 vendor/github.com/mgechev/revive/formatter/json.go delete mode 100644 vendor/github.com/mgechev/revive/formatter/ndjson.go delete mode 100644 vendor/github.com/mgechev/revive/formatter/plain.go delete mode 100644 vendor/github.com/mgechev/revive/formatter/sarif.go delete mode 100644 vendor/github.com/mgechev/revive/formatter/severity.go delete mode 100644 vendor/github.com/mgechev/revive/formatter/stylish.go delete mode 100644 vendor/github.com/mgechev/revive/formatter/unix.go delete mode 100644 vendor/github.com/mgechev/revive/internal/ifelse/args.go delete mode 100644 vendor/github.com/mgechev/revive/internal/ifelse/branch.go delete mode 100644 vendor/github.com/mgechev/revive/internal/ifelse/branch_kind.go delete mode 100644 vendor/github.com/mgechev/revive/internal/ifelse/chain.go delete mode 100644 vendor/github.com/mgechev/revive/internal/ifelse/doc.go delete mode 100644 vendor/github.com/mgechev/revive/internal/ifelse/func.go delete mode 100644 vendor/github.com/mgechev/revive/internal/ifelse/rule.go delete mode 100644 vendor/github.com/mgechev/revive/internal/ifelse/target.go delete mode 100644 vendor/github.com/mgechev/revive/internal/typeparams/typeparams.go delete mode 100644 vendor/github.com/mgechev/revive/internal/typeparams/typeparams_go117.go delete mode 100644 vendor/github.com/mgechev/revive/internal/typeparams/typeparams_go118.go delete mode 100644 vendor/github.com/mgechev/revive/lint/config.go delete mode 100644 vendor/github.com/mgechev/revive/lint/doc.go delete mode 100644 vendor/github.com/mgechev/revive/lint/failure.go delete mode 100644 vendor/github.com/mgechev/revive/lint/file.go delete mode 100644 vendor/github.com/mgechev/revive/lint/filefilter.go delete mode 100644 vendor/github.com/mgechev/revive/lint/formatter.go delete mode 100644 vendor/github.com/mgechev/revive/lint/linter.go delete mode 100644 vendor/github.com/mgechev/revive/lint/package.go delete mode 100644 vendor/github.com/mgechev/revive/lint/rule.go delete mode 100644 vendor/github.com/mgechev/revive/lint/utils.go delete mode 100644 vendor/github.com/mgechev/revive/rule/add-constant.go delete mode 100644 vendor/github.com/mgechev/revive/rule/argument-limit.go delete mode 100644 vendor/github.com/mgechev/revive/rule/atomic.go delete mode 100644 vendor/github.com/mgechev/revive/rule/banned-characters.go delete mode 100644 vendor/github.com/mgechev/revive/rule/bare-return.go delete mode 100644 vendor/github.com/mgechev/revive/rule/blank-imports.go delete mode 100644 vendor/github.com/mgechev/revive/rule/bool-literal-in-expr.go delete mode 100644 vendor/github.com/mgechev/revive/rule/call-to-gc.go delete mode 100644 vendor/github.com/mgechev/revive/rule/cognitive-complexity.go delete mode 100644 vendor/github.com/mgechev/revive/rule/comment-spacings.go delete mode 100644 vendor/github.com/mgechev/revive/rule/comments-density.go delete mode 100644 vendor/github.com/mgechev/revive/rule/confusing-naming.go delete mode 100644 vendor/github.com/mgechev/revive/rule/confusing-results.go delete mode 100644 vendor/github.com/mgechev/revive/rule/constant-logical-expr.go delete mode 100644 vendor/github.com/mgechev/revive/rule/context-as-argument.go delete mode 100644 vendor/github.com/mgechev/revive/rule/context-keys-type.go delete mode 100644 vendor/github.com/mgechev/revive/rule/cyclomatic.go delete mode 100644 vendor/github.com/mgechev/revive/rule/datarace.go delete mode 100644 vendor/github.com/mgechev/revive/rule/deep-exit.go delete mode 100644 vendor/github.com/mgechev/revive/rule/defer.go delete mode 100644 vendor/github.com/mgechev/revive/rule/doc.go delete mode 100644 vendor/github.com/mgechev/revive/rule/dot-imports.go delete mode 100644 vendor/github.com/mgechev/revive/rule/duplicated-imports.go delete mode 100644 vendor/github.com/mgechev/revive/rule/early-return.go delete mode 100644 vendor/github.com/mgechev/revive/rule/empty-block.go delete mode 100644 vendor/github.com/mgechev/revive/rule/empty-lines.go delete mode 100644 vendor/github.com/mgechev/revive/rule/enforce-map-style.go delete mode 100644 vendor/github.com/mgechev/revive/rule/enforce-repeated-arg-type-style.go delete mode 100644 vendor/github.com/mgechev/revive/rule/enforce-slice-style.go delete mode 100644 vendor/github.com/mgechev/revive/rule/error-naming.go delete mode 100644 vendor/github.com/mgechev/revive/rule/error-return.go delete mode 100644 vendor/github.com/mgechev/revive/rule/error-strings.go delete mode 100644 vendor/github.com/mgechev/revive/rule/errorf.go delete mode 100644 vendor/github.com/mgechev/revive/rule/exported.go delete mode 100644 vendor/github.com/mgechev/revive/rule/file-header.go delete mode 100644 vendor/github.com/mgechev/revive/rule/flag-param.go delete mode 100644 vendor/github.com/mgechev/revive/rule/function-length.go delete mode 100644 vendor/github.com/mgechev/revive/rule/function-result-limit.go delete mode 100644 vendor/github.com/mgechev/revive/rule/get-return.go delete mode 100644 vendor/github.com/mgechev/revive/rule/identical-branches.go delete mode 100644 vendor/github.com/mgechev/revive/rule/if-return.go delete mode 100644 vendor/github.com/mgechev/revive/rule/import-alias-naming.go delete mode 100644 vendor/github.com/mgechev/revive/rule/import-shadowing.go delete mode 100644 vendor/github.com/mgechev/revive/rule/imports-blocklist.go delete mode 100644 vendor/github.com/mgechev/revive/rule/increment-decrement.go delete mode 100644 vendor/github.com/mgechev/revive/rule/indent-error-flow.go delete mode 100644 vendor/github.com/mgechev/revive/rule/line-length-limit.go delete mode 100644 vendor/github.com/mgechev/revive/rule/max-control-nesting.go delete mode 100644 vendor/github.com/mgechev/revive/rule/max-public-structs.go delete mode 100644 vendor/github.com/mgechev/revive/rule/modifies-param.go delete mode 100644 vendor/github.com/mgechev/revive/rule/modifies-value-receiver.go delete mode 100644 vendor/github.com/mgechev/revive/rule/nested-structs.go delete mode 100644 vendor/github.com/mgechev/revive/rule/optimize-operands-order.go delete mode 100644 vendor/github.com/mgechev/revive/rule/package-comments.go delete mode 100644 vendor/github.com/mgechev/revive/rule/range-val-address.go delete mode 100644 vendor/github.com/mgechev/revive/rule/range-val-in-closure.go delete mode 100644 vendor/github.com/mgechev/revive/rule/range.go delete mode 100644 vendor/github.com/mgechev/revive/rule/receiver-naming.go delete mode 100644 vendor/github.com/mgechev/revive/rule/redefines-builtin-id.go delete mode 100644 vendor/github.com/mgechev/revive/rule/redundant-import-alias.go delete mode 100644 vendor/github.com/mgechev/revive/rule/string-format.go delete mode 100644 vendor/github.com/mgechev/revive/rule/string-of-int.go delete mode 100644 vendor/github.com/mgechev/revive/rule/struct-tag.go delete mode 100644 vendor/github.com/mgechev/revive/rule/superfluous-else.go delete mode 100644 vendor/github.com/mgechev/revive/rule/time-equal.go delete mode 100644 vendor/github.com/mgechev/revive/rule/time-naming.go delete mode 100644 vendor/github.com/mgechev/revive/rule/unchecked-type-assertion.go delete mode 100644 vendor/github.com/mgechev/revive/rule/unconditional-recursion.go delete mode 100644 vendor/github.com/mgechev/revive/rule/unexported-naming.go delete mode 100644 vendor/github.com/mgechev/revive/rule/unexported-return.go delete mode 100644 vendor/github.com/mgechev/revive/rule/unhandled-error.go delete mode 100644 vendor/github.com/mgechev/revive/rule/unnecessary-stmt.go delete mode 100644 vendor/github.com/mgechev/revive/rule/unreachable-code.go delete mode 100644 vendor/github.com/mgechev/revive/rule/unused-param.go delete mode 100644 vendor/github.com/mgechev/revive/rule/unused-receiver.go delete mode 100644 vendor/github.com/mgechev/revive/rule/use-any.go delete mode 100644 vendor/github.com/mgechev/revive/rule/useless-break.go delete mode 100644 vendor/github.com/mgechev/revive/rule/utils.go delete mode 100644 vendor/github.com/mgechev/revive/rule/var-declarations.go delete mode 100644 vendor/github.com/mgechev/revive/rule/var-naming.go delete mode 100644 vendor/github.com/mgechev/revive/rule/waitgroup-by-value.go delete mode 100644 vendor/github.com/minio/md5-simd/LICENSE delete mode 100644 vendor/github.com/minio/md5-simd/README.md delete mode 100644 vendor/github.com/minio/md5-simd/block-generic.go delete mode 100644 vendor/github.com/minio/md5-simd/block16_amd64.s delete mode 100644 vendor/github.com/minio/md5-simd/block8_amd64.s delete mode 100644 vendor/github.com/minio/md5-simd/block_amd64.go delete mode 100644 vendor/github.com/minio/md5-simd/md5-digest_amd64.go delete mode 100644 vendor/github.com/minio/md5-simd/md5-server_amd64.go delete mode 100644 vendor/github.com/minio/md5-simd/md5-server_fallback.go delete mode 100644 vendor/github.com/minio/md5-simd/md5-util_amd64.go delete mode 100644 vendor/github.com/minio/md5-simd/md5.go delete mode 100644 vendor/github.com/minio/minio-go/v7/.gitignore delete mode 100644 vendor/github.com/minio/minio-go/v7/.golangci.yml delete mode 100644 vendor/github.com/minio/minio-go/v7/CNAME delete mode 100644 vendor/github.com/minio/minio-go/v7/CONTRIBUTING.md delete mode 100644 vendor/github.com/minio/minio-go/v7/LICENSE delete mode 100644 vendor/github.com/minio/minio-go/v7/MAINTAINERS.md delete mode 100644 vendor/github.com/minio/minio-go/v7/Makefile delete mode 100644 vendor/github.com/minio/minio-go/v7/NOTICE delete mode 100644 vendor/github.com/minio/minio-go/v7/README.md delete mode 100644 vendor/github.com/minio/minio-go/v7/README_zh_CN.md delete mode 100644 vendor/github.com/minio/minio-go/v7/api-bucket-encryption.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-bucket-lifecycle.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-bucket-notification.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-bucket-policy.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-bucket-replication.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-bucket-tagging.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-bucket-versioning.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-compose-object.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-datatypes.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-error-response.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-get-object-acl.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-get-object-file.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-get-object.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-get-options.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-list.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-object-legal-hold.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-object-lock.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-object-retention.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-object-tagging.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-presigned.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-put-bucket.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-put-object-common.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-put-object-copy.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-put-object-file-context.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-put-object-multipart.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-put-object.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-remove.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-s3-datatypes.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-select.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api-stat.go delete mode 100644 vendor/github.com/minio/minio-go/v7/api.go delete mode 100644 vendor/github.com/minio/minio-go/v7/bucket-cache.go delete mode 100644 vendor/github.com/minio/minio-go/v7/code_of_conduct.md delete mode 100644 vendor/github.com/minio/minio-go/v7/constants.go delete mode 100644 vendor/github.com/minio/minio-go/v7/core.go delete mode 100644 vendor/github.com/minio/minio-go/v7/hook-reader.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/chain.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/config.json.sample delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.sample delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/doc.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/env_aws.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/env_minio.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/file_aws_credentials.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/file_minio_client.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/iam_aws.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/signature-type.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/static.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_client_grants.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_ldap_identity.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_web_identity.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/encrypt/server-side.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/notification/info.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/notification/notification.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/replication/replication.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/s3utils/utils.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/set/stringset.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-streaming.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-v2.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-v4.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/signer/utils.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/sse/sse.go delete mode 100644 vendor/github.com/minio/minio-go/v7/pkg/tags/tags.go delete mode 100644 vendor/github.com/minio/minio-go/v7/post-policy.go delete mode 100644 vendor/github.com/minio/minio-go/v7/retry-continous.go delete mode 100644 vendor/github.com/minio/minio-go/v7/retry.go delete mode 100644 vendor/github.com/minio/minio-go/v7/s3-endpoints.go delete mode 100644 vendor/github.com/minio/minio-go/v7/s3-error.go delete mode 100644 vendor/github.com/minio/minio-go/v7/staticcheck.conf delete mode 100644 vendor/github.com/minio/minio-go/v7/transport.go delete mode 100644 vendor/github.com/minio/minio-go/v7/utils.go delete mode 100644 vendor/github.com/minio/sha256-simd/.gitignore delete mode 100644 vendor/github.com/minio/sha256-simd/.travis.yml delete mode 100644 vendor/github.com/minio/sha256-simd/LICENSE delete mode 100644 vendor/github.com/minio/sha256-simd/README.md delete mode 100644 vendor/github.com/minio/sha256-simd/appveyor.yml delete mode 100644 vendor/github.com/minio/sha256-simd/cpuid.go delete mode 100644 vendor/github.com/minio/sha256-simd/cpuid_386.go delete mode 100644 vendor/github.com/minio/sha256-simd/cpuid_386.s delete mode 100644 vendor/github.com/minio/sha256-simd/cpuid_amd64.go delete mode 100644 vendor/github.com/minio/sha256-simd/cpuid_amd64.s delete mode 100644 vendor/github.com/minio/sha256-simd/cpuid_arm.go delete mode 100644 vendor/github.com/minio/sha256-simd/cpuid_linux_arm64.go delete mode 100644 vendor/github.com/minio/sha256-simd/cpuid_other.go delete mode 100644 vendor/github.com/minio/sha256-simd/sha256.go delete mode 100644 vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.go delete mode 100644 vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.s delete mode 100644 vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.asm delete mode 100644 vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.go delete mode 100644 vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.s delete mode 100644 vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.go delete mode 100644 vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.s delete mode 100644 vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.go delete mode 100644 vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.s delete mode 100644 vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.go delete mode 100644 vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.s delete mode 100644 vendor/github.com/minio/sha256-simd/sha256block_amd64.go delete mode 100644 vendor/github.com/minio/sha256-simd/sha256block_arm64.go delete mode 100644 vendor/github.com/minio/sha256-simd/sha256block_arm64.s delete mode 100644 vendor/github.com/minio/sha256-simd/sha256block_other.go delete mode 100644 vendor/github.com/minio/sha256-simd/test-architectures.sh delete mode 100644 vendor/github.com/mitchellh/go-homedir/LICENSE delete mode 100644 vendor/github.com/mitchellh/go-homedir/README.md delete mode 100644 vendor/github.com/mitchellh/go-homedir/homedir.go delete mode 100644 vendor/github.com/mitchellh/mapstructure/CHANGELOG.md delete mode 100644 vendor/github.com/mitchellh/mapstructure/LICENSE delete mode 100644 vendor/github.com/mitchellh/mapstructure/README.md delete mode 100644 vendor/github.com/mitchellh/mapstructure/decode_hooks.go delete mode 100644 vendor/github.com/mitchellh/mapstructure/error.go delete mode 100644 vendor/github.com/mitchellh/mapstructure/mapstructure.go delete mode 100644 vendor/github.com/modern-go/concurrent/.gitignore delete mode 100644 vendor/github.com/modern-go/concurrent/.travis.yml delete mode 100644 vendor/github.com/modern-go/concurrent/LICENSE delete mode 100644 vendor/github.com/modern-go/concurrent/README.md delete mode 100644 vendor/github.com/modern-go/concurrent/executor.go delete mode 100644 vendor/github.com/modern-go/concurrent/go_above_19.go delete mode 100644 vendor/github.com/modern-go/concurrent/go_below_19.go delete mode 100644 vendor/github.com/modern-go/concurrent/log.go delete mode 100644 vendor/github.com/modern-go/concurrent/test.sh delete mode 100644 vendor/github.com/modern-go/concurrent/unbounded_executor.go delete mode 100644 vendor/github.com/modern-go/reflect2/.gitignore delete mode 100644 vendor/github.com/modern-go/reflect2/.travis.yml delete mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.lock delete mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.toml delete mode 100644 vendor/github.com/modern-go/reflect2/LICENSE delete mode 100644 vendor/github.com/modern-go/reflect2/README.md delete mode 100644 vendor/github.com/modern-go/reflect2/go_above_118.go delete mode 100644 vendor/github.com/modern-go/reflect2/go_above_19.go delete mode 100644 vendor/github.com/modern-go/reflect2/go_below_118.go delete mode 100644 vendor/github.com/modern-go/reflect2/reflect2.go delete mode 100644 vendor/github.com/modern-go/reflect2/reflect2_amd64.s delete mode 100644 vendor/github.com/modern-go/reflect2/reflect2_kind.go delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_386.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm64.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mips64x.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mipsx.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_s390x.s delete mode 100644 vendor/github.com/modern-go/reflect2/safe_field.go delete mode 100644 vendor/github.com/modern-go/reflect2/safe_map.go delete mode 100644 vendor/github.com/modern-go/reflect2/safe_slice.go delete mode 100644 vendor/github.com/modern-go/reflect2/safe_struct.go delete mode 100644 vendor/github.com/modern-go/reflect2/safe_type.go delete mode 100644 vendor/github.com/modern-go/reflect2/type_map.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_array.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_eface.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_field.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_iface.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_link.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_map.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_ptr.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_slice.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_struct.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_type.go delete mode 100644 vendor/github.com/moricho/tparallel/.gitignore delete mode 100644 vendor/github.com/moricho/tparallel/.goreleaser.yaml delete mode 100644 vendor/github.com/moricho/tparallel/LICENSE delete mode 100644 vendor/github.com/moricho/tparallel/Makefile delete mode 100644 vendor/github.com/moricho/tparallel/README.md delete mode 100644 vendor/github.com/moricho/tparallel/pkg/ssafunc/ssafunc.go delete mode 100644 vendor/github.com/moricho/tparallel/pkg/ssainstr/ssainstr.go delete mode 100644 vendor/github.com/moricho/tparallel/testmap.go delete mode 100644 vendor/github.com/moricho/tparallel/tparallel.go delete mode 100644 vendor/github.com/nakabonne/nestif/.gitignore delete mode 100644 vendor/github.com/nakabonne/nestif/LICENSE delete mode 100644 vendor/github.com/nakabonne/nestif/README.md delete mode 100644 vendor/github.com/nakabonne/nestif/nestif.go delete mode 100644 vendor/github.com/nishanths/exhaustive/.gitignore delete mode 100644 vendor/github.com/nishanths/exhaustive/LICENSE delete mode 100644 vendor/github.com/nishanths/exhaustive/Makefile delete mode 100644 vendor/github.com/nishanths/exhaustive/README.md delete mode 100644 vendor/github.com/nishanths/exhaustive/comment.go delete mode 100644 vendor/github.com/nishanths/exhaustive/comment_go121.go delete mode 100644 vendor/github.com/nishanths/exhaustive/comment_pre_go121.go delete mode 100644 vendor/github.com/nishanths/exhaustive/common.go delete mode 100644 vendor/github.com/nishanths/exhaustive/doc.go delete mode 100644 vendor/github.com/nishanths/exhaustive/enum.go delete mode 100644 vendor/github.com/nishanths/exhaustive/exhaustive.go delete mode 100644 vendor/github.com/nishanths/exhaustive/fact.go delete mode 100644 vendor/github.com/nishanths/exhaustive/flag.go delete mode 100644 vendor/github.com/nishanths/exhaustive/map.go delete mode 100644 vendor/github.com/nishanths/exhaustive/switch.go delete mode 100644 vendor/github.com/nishanths/predeclared/LICENSE delete mode 100644 vendor/github.com/nishanths/predeclared/passes/predeclared/go18.go delete mode 100644 vendor/github.com/nishanths/predeclared/passes/predeclared/pre_go18.go delete mode 100644 vendor/github.com/nishanths/predeclared/passes/predeclared/predeclared.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/.gitignore delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/.golangci.yml delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/LICENSE delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/Makefile delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/README.md delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/analyzer.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/doc.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/internal/ginkgohandler/handler.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/internal/gomegahandler/handler.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/internal/interfaces/interfaces.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/internal/intervals/intervals.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/internal/reports/report-builder.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/internal/reverseassertion/reverse_assertion.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/linter/ginkgo_linter.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/types/boolean.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/types/config.go delete mode 100644 vendor/github.com/nunnatsa/ginkgolinter/version/version.go delete mode 100644 vendor/github.com/olekukonko/tablewriter/.gitignore delete mode 100644 vendor/github.com/olekukonko/tablewriter/.travis.yml delete mode 100644 vendor/github.com/olekukonko/tablewriter/LICENSE.md delete mode 100644 vendor/github.com/olekukonko/tablewriter/README.md delete mode 100644 vendor/github.com/olekukonko/tablewriter/csv.go delete mode 100644 vendor/github.com/olekukonko/tablewriter/table.go delete mode 100644 vendor/github.com/olekukonko/tablewriter/table_with_color.go delete mode 100644 vendor/github.com/olekukonko/tablewriter/util.go delete mode 100644 vendor/github.com/olekukonko/tablewriter/wrap.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/.gitignore delete mode 100644 vendor/github.com/opentracing/opentracing-go/.travis.yml delete mode 100644 vendor/github.com/opentracing/opentracing-go/CHANGELOG.md delete mode 100644 vendor/github.com/opentracing/opentracing-go/LICENSE delete mode 100644 vendor/github.com/opentracing/opentracing-go/Makefile delete mode 100644 vendor/github.com/opentracing/opentracing-go/README.md delete mode 100644 vendor/github.com/opentracing/opentracing-go/ext/tags.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/globaltracer.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/gocontext.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/log/field.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/log/util.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/noop.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/propagation.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/span.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/tracer.go delete mode 100644 vendor/github.com/pelletier/go-toml/.dockerignore delete mode 100644 vendor/github.com/pelletier/go-toml/.gitignore delete mode 100644 vendor/github.com/pelletier/go-toml/CONTRIBUTING.md delete mode 100644 vendor/github.com/pelletier/go-toml/Dockerfile delete mode 100644 vendor/github.com/pelletier/go-toml/LICENSE delete mode 100644 vendor/github.com/pelletier/go-toml/Makefile delete mode 100644 vendor/github.com/pelletier/go-toml/PULL_REQUEST_TEMPLATE.md delete mode 100644 vendor/github.com/pelletier/go-toml/README.md delete mode 100644 vendor/github.com/pelletier/go-toml/SECURITY.md delete mode 100644 vendor/github.com/pelletier/go-toml/azure-pipelines.yml delete mode 100644 vendor/github.com/pelletier/go-toml/benchmark.sh delete mode 100644 vendor/github.com/pelletier/go-toml/doc.go delete mode 100644 vendor/github.com/pelletier/go-toml/example-crlf.toml delete mode 100644 vendor/github.com/pelletier/go-toml/example.toml delete mode 100644 vendor/github.com/pelletier/go-toml/fuzz.go delete mode 100644 vendor/github.com/pelletier/go-toml/fuzz.sh delete mode 100644 vendor/github.com/pelletier/go-toml/keysparsing.go delete mode 100644 vendor/github.com/pelletier/go-toml/lexer.go delete mode 100644 vendor/github.com/pelletier/go-toml/localtime.go delete mode 100644 vendor/github.com/pelletier/go-toml/marshal.go delete mode 100644 vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_test.toml delete mode 100644 vendor/github.com/pelletier/go-toml/marshal_test.toml delete mode 100644 vendor/github.com/pelletier/go-toml/parser.go delete mode 100644 vendor/github.com/pelletier/go-toml/position.go delete mode 100644 vendor/github.com/pelletier/go-toml/token.go delete mode 100644 vendor/github.com/pelletier/go-toml/toml.go delete mode 100644 vendor/github.com/pelletier/go-toml/tomlpub.go delete mode 100644 vendor/github.com/pelletier/go-toml/tomltree_create.go delete mode 100644 vendor/github.com/pelletier/go-toml/tomltree_write.go delete mode 100644 vendor/github.com/pelletier/go-toml/tomltree_writepub.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/.dockerignore delete mode 100644 vendor/github.com/pelletier/go-toml/v2/.gitattributes delete mode 100644 vendor/github.com/pelletier/go-toml/v2/.gitignore delete mode 100644 vendor/github.com/pelletier/go-toml/v2/.golangci.toml delete mode 100644 vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml delete mode 100644 vendor/github.com/pelletier/go-toml/v2/CONTRIBUTING.md delete mode 100644 vendor/github.com/pelletier/go-toml/v2/Dockerfile delete mode 100644 vendor/github.com/pelletier/go-toml/v2/LICENSE delete mode 100644 vendor/github.com/pelletier/go-toml/v2/README.md delete mode 100644 vendor/github.com/pelletier/go-toml/v2/SECURITY.md delete mode 100644 vendor/github.com/pelletier/go-toml/v2/ci.sh delete mode 100644 vendor/github.com/pelletier/go-toml/v2/decode.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/doc.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/errors.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/characters/ascii.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/characters/utf8.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/danger/danger.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/danger/typeid.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/tracker/key.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/tracker/seen.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/tracker/tracker.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/localtime.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/marshaler.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/strict.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/toml.abnf delete mode 100644 vendor/github.com/pelletier/go-toml/v2/types.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/unmarshaler.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/unstable/ast.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/unstable/builder.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/unstable/doc.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/unstable/kind.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/unstable/parser.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/unstable/scanner.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/unstable/unmarshaler.go delete mode 100644 vendor/github.com/pkg/errors/.gitignore delete mode 100644 vendor/github.com/pkg/errors/.travis.yml delete mode 100644 vendor/github.com/pkg/errors/LICENSE delete mode 100644 vendor/github.com/pkg/errors/Makefile delete mode 100644 vendor/github.com/pkg/errors/README.md delete mode 100644 vendor/github.com/pkg/errors/appveyor.yml delete mode 100644 vendor/github.com/pkg/errors/errors.go delete mode 100644 vendor/github.com/pkg/errors/go113.go delete mode 100644 vendor/github.com/pkg/errors/stack.go delete mode 100644 vendor/github.com/pmezard/go-difflib/LICENSE delete mode 100644 vendor/github.com/pmezard/go-difflib/difflib/difflib.go delete mode 100644 vendor/github.com/polyfloyd/go-errorlint/LICENSE delete mode 100644 vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go delete mode 100644 vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go delete mode 100644 vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go delete mode 100644 vendor/github.com/polyfloyd/go-errorlint/errorlint/options.go delete mode 100644 vendor/github.com/polyfloyd/go-errorlint/errorlint/printf.go delete mode 100644 vendor/github.com/prometheus/client_golang/LICENSE delete mode 100644 vendor/github.com/prometheus/client_golang/NOTICE delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/.gitignore delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/README.md delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/build_info_collector.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/collector.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/counter.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/desc.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/doc.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/fnv.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/gauge.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/get_pid.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/go_collector.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/histogram.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/labels.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/metric.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/num_threads.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/observer.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/registry.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/summary.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/problem.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/promlint.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/validation.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/validations/counter_validations.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/validations/generic_name_validations.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/validations/help_validations.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/validations/histogram_validations.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/testutil/promlint/validations/units.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/timer.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/untyped.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/value.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/vec.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/vnext.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/wrap.go delete mode 100644 vendor/github.com/prometheus/client_model/LICENSE delete mode 100644 vendor/github.com/prometheus/client_model/NOTICE delete mode 100644 vendor/github.com/prometheus/client_model/go/metrics.pb.go delete mode 100644 vendor/github.com/prometheus/common/LICENSE delete mode 100644 vendor/github.com/prometheus/common/NOTICE delete mode 100644 vendor/github.com/prometheus/common/expfmt/decode.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/encode.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/expfmt.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/fuzz.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/openmetrics_create.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/text_create.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/text_parse.go delete mode 100644 vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt delete mode 100644 vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go delete mode 100644 vendor/github.com/prometheus/common/model/alert.go delete mode 100644 vendor/github.com/prometheus/common/model/fingerprinting.go delete mode 100644 vendor/github.com/prometheus/common/model/fnv.go delete mode 100644 vendor/github.com/prometheus/common/model/labels.go delete mode 100644 vendor/github.com/prometheus/common/model/labelset.go delete mode 100644 vendor/github.com/prometheus/common/model/metadata.go delete mode 100644 vendor/github.com/prometheus/common/model/metric.go delete mode 100644 vendor/github.com/prometheus/common/model/model.go delete mode 100644 vendor/github.com/prometheus/common/model/signature.go delete mode 100644 vendor/github.com/prometheus/common/model/silence.go delete mode 100644 vendor/github.com/prometheus/common/model/time.go delete mode 100644 vendor/github.com/prometheus/common/model/value.go delete mode 100644 vendor/github.com/prometheus/common/model/value_float.go delete mode 100644 vendor/github.com/prometheus/common/model/value_histogram.go delete mode 100644 vendor/github.com/prometheus/common/model/value_type.go delete mode 100644 vendor/github.com/prometheus/procfs/.gitignore delete mode 100644 vendor/github.com/prometheus/procfs/.golangci.yml delete mode 100644 vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md delete mode 100644 vendor/github.com/prometheus/procfs/CONTRIBUTING.md delete mode 100644 vendor/github.com/prometheus/procfs/LICENSE delete mode 100644 vendor/github.com/prometheus/procfs/MAINTAINERS.md delete mode 100644 vendor/github.com/prometheus/procfs/Makefile delete mode 100644 vendor/github.com/prometheus/procfs/Makefile.common delete mode 100644 vendor/github.com/prometheus/procfs/NOTICE delete mode 100644 vendor/github.com/prometheus/procfs/README.md delete mode 100644 vendor/github.com/prometheus/procfs/SECURITY.md delete mode 100644 vendor/github.com/prometheus/procfs/arp.go delete mode 100644 vendor/github.com/prometheus/procfs/buddyinfo.go delete mode 100644 vendor/github.com/prometheus/procfs/cmdline.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_armx.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_loong64.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_others.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_s390x.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_x86.go delete mode 100644 vendor/github.com/prometheus/procfs/crypto.go delete mode 100644 vendor/github.com/prometheus/procfs/doc.go delete mode 100644 vendor/github.com/prometheus/procfs/fs.go delete mode 100644 vendor/github.com/prometheus/procfs/fs_statfs_notype.go delete mode 100644 vendor/github.com/prometheus/procfs/fs_statfs_type.go delete mode 100644 vendor/github.com/prometheus/procfs/fscache.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/fs/fs.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/util/parse.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/util/readfile.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/util/valueparser.go delete mode 100644 vendor/github.com/prometheus/procfs/ipvs.go delete mode 100644 vendor/github.com/prometheus/procfs/kernel_random.go delete mode 100644 vendor/github.com/prometheus/procfs/loadavg.go delete mode 100644 vendor/github.com/prometheus/procfs/mdstat.go delete mode 100644 vendor/github.com/prometheus/procfs/meminfo.go delete mode 100644 vendor/github.com/prometheus/procfs/mountinfo.go delete mode 100644 vendor/github.com/prometheus/procfs/mountstats.go delete mode 100644 vendor/github.com/prometheus/procfs/net_conntrackstat.go delete mode 100644 vendor/github.com/prometheus/procfs/net_dev.go delete mode 100644 vendor/github.com/prometheus/procfs/net_ip_socket.go delete mode 100644 vendor/github.com/prometheus/procfs/net_protocols.go delete mode 100644 vendor/github.com/prometheus/procfs/net_route.go delete mode 100644 vendor/github.com/prometheus/procfs/net_sockstat.go delete mode 100644 vendor/github.com/prometheus/procfs/net_softnet.go delete mode 100644 vendor/github.com/prometheus/procfs/net_tcp.go delete mode 100644 vendor/github.com/prometheus/procfs/net_udp.go delete mode 100644 vendor/github.com/prometheus/procfs/net_unix.go delete mode 100644 vendor/github.com/prometheus/procfs/net_wireless.go delete mode 100644 vendor/github.com/prometheus/procfs/net_xfrm.go delete mode 100644 vendor/github.com/prometheus/procfs/netstat.go delete mode 100644 vendor/github.com/prometheus/procfs/proc.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_cgroup.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_cgroups.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_environ.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_fdinfo.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_interrupts.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_io.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_limits.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_maps.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_netstat.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_ns.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_psi.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_smaps.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_snmp.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_snmp6.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_stat.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_status.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_sys.go delete mode 100644 vendor/github.com/prometheus/procfs/schedstat.go delete mode 100644 vendor/github.com/prometheus/procfs/slab.go delete mode 100644 vendor/github.com/prometheus/procfs/softirqs.go delete mode 100644 vendor/github.com/prometheus/procfs/stat.go delete mode 100644 vendor/github.com/prometheus/procfs/swaps.go delete mode 100644 vendor/github.com/prometheus/procfs/thread.go delete mode 100644 vendor/github.com/prometheus/procfs/ttar delete mode 100644 vendor/github.com/prometheus/procfs/vm.go delete mode 100644 vendor/github.com/prometheus/procfs/zoneinfo.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/LICENSE delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/dsl/LICENSE delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/dsl/bundle.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/dsl/do.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/dsl/dsl.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/dsl/filter.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/dsl/internal.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/dsl/types/ext.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/dsl/types/type_impl.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/dsl/types/types.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/internal/goenv/goenv.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/internal/golist/golist.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/internal/xsrcimporter/xsrcimporter.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/internal/xtypes/xtypes.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/ast_walker.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/bundle.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/engine.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/filters.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/go_version.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/gorule.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/goutil/goutil.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/goutil/resolve.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/importer.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/ir/filter_op.gen.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/ir/gen_filter_op.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/ir/ir.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/ir_loader.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/ir_utils.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/irconv/irconv.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/libdsl.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/match_data.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/nodepath.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/profiling/no_labels.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/profiling/with_labels.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/compile.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/debug_info.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/disasm.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/env.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/eval.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/gen_opcodes.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/opcode_string.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/opcodes.gen.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/quasigo.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/stdlib/qfmt/qfmt.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/stdlib/qstrconv/qstrconv.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/stdlib/qstrings/qstrings.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/quasigo/utils.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/ruleguard.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/runner.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/textmatch/compile.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/textmatch/matchers.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/textmatch/textmatch.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/typematch/patternop_string.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/typematch/typematch.go delete mode 100644 vendor/github.com/quasilyte/go-ruleguard/ruleguard/utils.go delete mode 100644 vendor/github.com/quasilyte/gogrep/.gitignore delete mode 100644 vendor/github.com/quasilyte/gogrep/.golangci.yml delete mode 100644 vendor/github.com/quasilyte/gogrep/LICENSE delete mode 100644 vendor/github.com/quasilyte/gogrep/Makefile delete mode 100644 vendor/github.com/quasilyte/gogrep/README.md delete mode 100644 vendor/github.com/quasilyte/gogrep/compile.go delete mode 100644 vendor/github.com/quasilyte/gogrep/compile_import.go delete mode 100644 vendor/github.com/quasilyte/gogrep/gen_operations.go delete mode 100644 vendor/github.com/quasilyte/gogrep/gogrep.go delete mode 100644 vendor/github.com/quasilyte/gogrep/instructions.go delete mode 100644 vendor/github.com/quasilyte/gogrep/internal/stdinfo/stdinfo.go delete mode 100644 vendor/github.com/quasilyte/gogrep/match.go delete mode 100644 vendor/github.com/quasilyte/gogrep/nodetag/nodetag.go delete mode 100644 vendor/github.com/quasilyte/gogrep/operation_string.go delete mode 100644 vendor/github.com/quasilyte/gogrep/operations.gen.go delete mode 100644 vendor/github.com/quasilyte/gogrep/parse.go delete mode 100644 vendor/github.com/quasilyte/gogrep/slices.go delete mode 100644 vendor/github.com/quasilyte/regex/syntax/LICENSE delete mode 100644 vendor/github.com/quasilyte/regex/syntax/README.md delete mode 100644 vendor/github.com/quasilyte/regex/syntax/ast.go delete mode 100644 vendor/github.com/quasilyte/regex/syntax/errors.go delete mode 100644 vendor/github.com/quasilyte/regex/syntax/lexer.go delete mode 100644 vendor/github.com/quasilyte/regex/syntax/operation.go delete mode 100644 vendor/github.com/quasilyte/regex/syntax/operation_string.go delete mode 100644 vendor/github.com/quasilyte/regex/syntax/parser.go delete mode 100644 vendor/github.com/quasilyte/regex/syntax/pos.go delete mode 100644 vendor/github.com/quasilyte/regex/syntax/tokenkind_string.go delete mode 100644 vendor/github.com/quasilyte/regex/syntax/utils.go delete mode 100644 vendor/github.com/quasilyte/stdinfo/LICENSE delete mode 100644 vendor/github.com/quasilyte/stdinfo/stdinfo.go delete mode 100644 vendor/github.com/quasilyte/stdinfo/stdinfo_gen.go delete mode 100644 vendor/github.com/redis/go-redis/v9/.gitignore delete mode 100644 vendor/github.com/redis/go-redis/v9/.golangci.yml delete mode 100644 vendor/github.com/redis/go-redis/v9/.prettierrc.yml delete mode 100644 vendor/github.com/redis/go-redis/v9/CHANGELOG.md delete mode 100644 vendor/github.com/redis/go-redis/v9/CONTRIBUTING.md delete mode 100644 vendor/github.com/redis/go-redis/v9/LICENSE delete mode 100644 vendor/github.com/redis/go-redis/v9/Makefile delete mode 100644 vendor/github.com/redis/go-redis/v9/README.md delete mode 100644 vendor/github.com/redis/go-redis/v9/RELEASING.md delete mode 100644 vendor/github.com/redis/go-redis/v9/acl_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/bitmap_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/cluster_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/command.go delete mode 100644 vendor/github.com/redis/go-redis/v9/commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/doc.go delete mode 100644 vendor/github.com/redis/go-redis/v9/error.go delete mode 100644 vendor/github.com/redis/go-redis/v9/gears_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/generic_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/geo_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/hash_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/hyperloglog_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/arg.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/hashtag/hashtag.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/hscan/hscan.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/hscan/structmap.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/internal.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/log.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/once.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/pool/conn.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/pool/conn_check.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/pool/conn_check_dummy.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/pool/pool.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/pool/pool_single.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/pool/pool_sticky.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/proto/reader.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/proto/scan.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/proto/writer.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/rand/rand.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/util.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/util/safe.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/util/strconv.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/util/type.go delete mode 100644 vendor/github.com/redis/go-redis/v9/internal/util/unsafe.go delete mode 100644 vendor/github.com/redis/go-redis/v9/iterator.go delete mode 100644 vendor/github.com/redis/go-redis/v9/json.go delete mode 100644 vendor/github.com/redis/go-redis/v9/list_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/options.go delete mode 100644 vendor/github.com/redis/go-redis/v9/osscluster.go delete mode 100644 vendor/github.com/redis/go-redis/v9/osscluster_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/pipeline.go delete mode 100644 vendor/github.com/redis/go-redis/v9/probabilistic.go delete mode 100644 vendor/github.com/redis/go-redis/v9/pubsub.go delete mode 100644 vendor/github.com/redis/go-redis/v9/pubsub_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/redis.go delete mode 100644 vendor/github.com/redis/go-redis/v9/result.go delete mode 100644 vendor/github.com/redis/go-redis/v9/ring.go delete mode 100644 vendor/github.com/redis/go-redis/v9/script.go delete mode 100644 vendor/github.com/redis/go-redis/v9/scripting_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/sentinel.go delete mode 100644 vendor/github.com/redis/go-redis/v9/set_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/sortedset_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/stream_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/string_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/timeseries_commands.go delete mode 100644 vendor/github.com/redis/go-redis/v9/tx.go delete mode 100644 vendor/github.com/redis/go-redis/v9/universal.go delete mode 100644 vendor/github.com/redis/go-redis/v9/version.go delete mode 100644 vendor/github.com/rivo/uniseg/LICENSE.txt delete mode 100644 vendor/github.com/rivo/uniseg/README.md delete mode 100644 vendor/github.com/rivo/uniseg/doc.go delete mode 100644 vendor/github.com/rivo/uniseg/grapheme.go delete mode 100644 vendor/github.com/rivo/uniseg/properties.go delete mode 100644 vendor/github.com/rs/xid/.appveyor.yml delete mode 100644 vendor/github.com/rs/xid/.golangci.yml delete mode 100644 vendor/github.com/rs/xid/.travis.yml delete mode 100644 vendor/github.com/rs/xid/LICENSE delete mode 100644 vendor/github.com/rs/xid/README.md delete mode 100644 vendor/github.com/rs/xid/error.go delete mode 100644 vendor/github.com/rs/xid/hostid_darwin.go delete mode 100644 vendor/github.com/rs/xid/hostid_fallback.go delete mode 100644 vendor/github.com/rs/xid/hostid_freebsd.go delete mode 100644 vendor/github.com/rs/xid/hostid_linux.go delete mode 100644 vendor/github.com/rs/xid/hostid_windows.go delete mode 100644 vendor/github.com/rs/xid/id.go delete mode 100644 vendor/github.com/rs/zerolog/.gitignore delete mode 100644 vendor/github.com/rs/zerolog/CNAME delete mode 100644 vendor/github.com/rs/zerolog/LICENSE delete mode 100644 vendor/github.com/rs/zerolog/README.md delete mode 100644 vendor/github.com/rs/zerolog/_config.yml delete mode 100644 vendor/github.com/rs/zerolog/array.go delete mode 100644 vendor/github.com/rs/zerolog/console.go delete mode 100644 vendor/github.com/rs/zerolog/context.go delete mode 100644 vendor/github.com/rs/zerolog/ctx.go delete mode 100644 vendor/github.com/rs/zerolog/encoder.go delete mode 100644 vendor/github.com/rs/zerolog/encoder_cbor.go delete mode 100644 vendor/github.com/rs/zerolog/encoder_json.go delete mode 100644 vendor/github.com/rs/zerolog/event.go delete mode 100644 vendor/github.com/rs/zerolog/example.jsonl delete mode 100644 vendor/github.com/rs/zerolog/fields.go delete mode 100644 vendor/github.com/rs/zerolog/globals.go delete mode 100644 vendor/github.com/rs/zerolog/go112.go delete mode 100644 vendor/github.com/rs/zerolog/hook.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/README.md delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/base.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/cbor.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/string.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/time.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/types.go delete mode 100644 vendor/github.com/rs/zerolog/internal/json/base.go delete mode 100644 vendor/github.com/rs/zerolog/internal/json/bytes.go delete mode 100644 vendor/github.com/rs/zerolog/internal/json/string.go delete mode 100644 vendor/github.com/rs/zerolog/internal/json/time.go delete mode 100644 vendor/github.com/rs/zerolog/internal/json/types.go delete mode 100644 vendor/github.com/rs/zerolog/log.go delete mode 100644 vendor/github.com/rs/zerolog/log/log.go delete mode 100644 vendor/github.com/rs/zerolog/not_go112.go delete mode 100644 vendor/github.com/rs/zerolog/pretty.png delete mode 100644 vendor/github.com/rs/zerolog/sampler.go delete mode 100644 vendor/github.com/rs/zerolog/syslog.go delete mode 100644 vendor/github.com/rs/zerolog/writer.go delete mode 100644 vendor/github.com/ryancurrah/gomodguard/.dockerignore delete mode 100644 vendor/github.com/ryancurrah/gomodguard/.gitignore delete mode 100644 vendor/github.com/ryancurrah/gomodguard/.golangci.yml delete mode 100644 vendor/github.com/ryancurrah/gomodguard/.goreleaser.yml delete mode 100644 vendor/github.com/ryancurrah/gomodguard/Dockerfile delete mode 100644 vendor/github.com/ryancurrah/gomodguard/Dockerfile.goreleaser delete mode 100644 vendor/github.com/ryancurrah/gomodguard/LICENSE delete mode 100644 vendor/github.com/ryancurrah/gomodguard/Makefile delete mode 100644 vendor/github.com/ryancurrah/gomodguard/README.md delete mode 100644 vendor/github.com/ryancurrah/gomodguard/allowed.go delete mode 100644 vendor/github.com/ryancurrah/gomodguard/blocked.go delete mode 100644 vendor/github.com/ryancurrah/gomodguard/issue.go delete mode 100644 vendor/github.com/ryancurrah/gomodguard/processor.go delete mode 100644 vendor/github.com/ryanrolds/sqlclosecheck/LICENSE delete mode 100644 vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/analyzer.go delete mode 100644 vendor/github.com/sanposhiho/wastedassign/v2/LICENSE delete mode 100644 vendor/github.com/sanposhiho/wastedassign/v2/README.md delete mode 100644 vendor/github.com/sanposhiho/wastedassign/v2/wastedassign.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/.gitignore delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/.gitmodules delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/LICENSE delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/README.md delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/compiler.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/content.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/doc.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/draft.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/errors.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/extension.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/format.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/httploader/httploader.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/loader.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/output.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/resource.go delete mode 100644 vendor/github.com/santhosh-tekuri/jsonschema/v5/schema.go delete mode 100644 vendor/github.com/sashamelentyev/interfacebloat/LICENSE delete mode 100644 vendor/github.com/sashamelentyev/interfacebloat/pkg/analyzer/analyzer.go delete mode 100644 vendor/github.com/sashamelentyev/usestdlibvars/LICENSE delete mode 100644 vendor/github.com/sashamelentyev/usestdlibvars/pkg/analyzer/analyzer.go delete mode 100644 vendor/github.com/sashamelentyev/usestdlibvars/pkg/analyzer/internal/mapping/mapping.go delete mode 100644 vendor/github.com/securego/gosec/v2/.gitignore delete mode 100644 vendor/github.com/securego/gosec/v2/.golangci.yml delete mode 100644 vendor/github.com/securego/gosec/v2/.goreleaser.yml delete mode 100644 vendor/github.com/securego/gosec/v2/Dockerfile delete mode 100644 vendor/github.com/securego/gosec/v2/LICENSE.txt delete mode 100644 vendor/github.com/securego/gosec/v2/Makefile delete mode 100644 vendor/github.com/securego/gosec/v2/README.md delete mode 100644 vendor/github.com/securego/gosec/v2/USERS.md delete mode 100644 vendor/github.com/securego/gosec/v2/action.yml delete mode 100644 vendor/github.com/securego/gosec/v2/analyzer.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/analyzers_set.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/analyzerslist.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/conversion_overflow.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/hardcodedNonce.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/slice_bounds.go delete mode 100644 vendor/github.com/securego/gosec/v2/analyzers/util.go delete mode 100644 vendor/github.com/securego/gosec/v2/call_list.go delete mode 100644 vendor/github.com/securego/gosec/v2/config.go delete mode 100644 vendor/github.com/securego/gosec/v2/cosign.pub delete mode 100644 vendor/github.com/securego/gosec/v2/cwe/data.go delete mode 100644 vendor/github.com/securego/gosec/v2/cwe/types.go delete mode 100644 vendor/github.com/securego/gosec/v2/entrypoint.sh delete mode 100644 vendor/github.com/securego/gosec/v2/errors.go delete mode 100644 vendor/github.com/securego/gosec/v2/helpers.go delete mode 100644 vendor/github.com/securego/gosec/v2/import_tracker.go delete mode 100644 vendor/github.com/securego/gosec/v2/install.sh delete mode 100644 vendor/github.com/securego/gosec/v2/issue/issue.go delete mode 100644 vendor/github.com/securego/gosec/v2/perf-diff.sh delete mode 100644 vendor/github.com/securego/gosec/v2/renovate.json delete mode 100644 vendor/github.com/securego/gosec/v2/report.go delete mode 100644 vendor/github.com/securego/gosec/v2/resolve.go delete mode 100644 vendor/github.com/securego/gosec/v2/rule.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/archive.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/bind.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/blocklist.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/decompression-bomb.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/directory-traversal.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/errors.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/fileperms.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/http_serve.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/integer_overflow.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/math_big_rat.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/pprof.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/rand.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/readfile.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/rsa.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/rulelist.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/slowloris.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/sql.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/ssh.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/ssrf.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/subproc.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/tempfiles.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/templates.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/tls.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/tls_config.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/unsafe.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/weakcrypto.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/weakcryptohash.go delete mode 100644 vendor/github.com/securego/gosec/v2/rules/weakdepricatedcryptohash.go delete mode 100644 vendor/github.com/shazow/go-diff/LICENSE delete mode 100644 vendor/github.com/shazow/go-diff/difflib/differ.go delete mode 100644 vendor/github.com/shopspring/decimal/.gitignore delete mode 100644 vendor/github.com/shopspring/decimal/.travis.yml delete mode 100644 vendor/github.com/shopspring/decimal/CHANGELOG.md delete mode 100644 vendor/github.com/shopspring/decimal/LICENSE delete mode 100644 vendor/github.com/shopspring/decimal/README.md delete mode 100644 vendor/github.com/shopspring/decimal/decimal-go.go delete mode 100644 vendor/github.com/shopspring/decimal/decimal.go delete mode 100644 vendor/github.com/shopspring/decimal/rounding.go delete mode 100644 vendor/github.com/sirupsen/logrus/.gitignore delete mode 100644 vendor/github.com/sirupsen/logrus/.golangci.yml delete mode 100644 vendor/github.com/sirupsen/logrus/.travis.yml delete mode 100644 vendor/github.com/sirupsen/logrus/CHANGELOG.md delete mode 100644 vendor/github.com/sirupsen/logrus/LICENSE delete mode 100644 vendor/github.com/sirupsen/logrus/README.md delete mode 100644 vendor/github.com/sirupsen/logrus/alt_exit.go delete mode 100644 vendor/github.com/sirupsen/logrus/appveyor.yml delete mode 100644 vendor/github.com/sirupsen/logrus/buffer_pool.go delete mode 100644 vendor/github.com/sirupsen/logrus/doc.go delete mode 100644 vendor/github.com/sirupsen/logrus/entry.go delete mode 100644 vendor/github.com/sirupsen/logrus/exported.go delete mode 100644 vendor/github.com/sirupsen/logrus/formatter.go delete mode 100644 vendor/github.com/sirupsen/logrus/hooks.go delete mode 100644 vendor/github.com/sirupsen/logrus/json_formatter.go delete mode 100644 vendor/github.com/sirupsen/logrus/logger.go delete mode 100644 vendor/github.com/sirupsen/logrus/logrus.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_appengine.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_bsd.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_js.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_solaris.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_unix.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_windows.go delete mode 100644 vendor/github.com/sirupsen/logrus/text_formatter.go delete mode 100644 vendor/github.com/sirupsen/logrus/writer.go delete mode 100644 vendor/github.com/sivchari/containedctx/.golangci.yml delete mode 100644 vendor/github.com/sivchari/containedctx/LICENCE delete mode 100644 vendor/github.com/sivchari/containedctx/README.md delete mode 100644 vendor/github.com/sivchari/containedctx/containedctx.go delete mode 100644 vendor/github.com/sivchari/tenv/.gitignore delete mode 100644 vendor/github.com/sivchari/tenv/.golangci.yml delete mode 100644 vendor/github.com/sivchari/tenv/LICENSE delete mode 100644 vendor/github.com/sivchari/tenv/README.md delete mode 100644 vendor/github.com/sivchari/tenv/tenv.go delete mode 100644 vendor/github.com/sivchari/tenv/tenv.png delete mode 100644 vendor/github.com/sonatard/noctx/.gitignore delete mode 100644 vendor/github.com/sonatard/noctx/.golangci.yml delete mode 100644 vendor/github.com/sonatard/noctx/LICENSE delete mode 100644 vendor/github.com/sonatard/noctx/Makefile delete mode 100644 vendor/github.com/sonatard/noctx/README.md delete mode 100644 vendor/github.com/sonatard/noctx/ngfunc/main.go delete mode 100644 vendor/github.com/sonatard/noctx/ngfunc/report.go delete mode 100644 vendor/github.com/sonatard/noctx/ngfunc/types.go delete mode 100644 vendor/github.com/sonatard/noctx/noctx.go delete mode 100644 vendor/github.com/sonatard/noctx/reqwithoutctx/main.go delete mode 100644 vendor/github.com/sonatard/noctx/reqwithoutctx/report.go delete mode 100644 vendor/github.com/sonatard/noctx/reqwithoutctx/ssa.go delete mode 100644 vendor/github.com/sony/gobreaker/LICENSE delete mode 100644 vendor/github.com/sony/gobreaker/README.md delete mode 100644 vendor/github.com/sony/gobreaker/gobreaker.go delete mode 100644 vendor/github.com/sourcegraph/go-diff/LICENSE delete mode 100644 vendor/github.com/sourcegraph/go-diff/diff/diff.go delete mode 100644 vendor/github.com/sourcegraph/go-diff/diff/doc.go delete mode 100644 vendor/github.com/sourcegraph/go-diff/diff/parse.go delete mode 100644 vendor/github.com/sourcegraph/go-diff/diff/print.go delete mode 100644 vendor/github.com/sourcegraph/go-diff/diff/reader_util.go delete mode 100644 vendor/github.com/spf13/afero/.gitignore delete mode 100644 vendor/github.com/spf13/afero/LICENSE.txt delete mode 100644 vendor/github.com/spf13/afero/README.md delete mode 100644 vendor/github.com/spf13/afero/afero.go delete mode 100644 vendor/github.com/spf13/afero/appveyor.yml delete mode 100644 vendor/github.com/spf13/afero/basepath.go delete mode 100644 vendor/github.com/spf13/afero/cacheOnReadFs.go delete mode 100644 vendor/github.com/spf13/afero/const_bsds.go delete mode 100644 vendor/github.com/spf13/afero/const_win_unix.go delete mode 100644 vendor/github.com/spf13/afero/copyOnWriteFs.go delete mode 100644 vendor/github.com/spf13/afero/httpFs.go delete mode 100644 vendor/github.com/spf13/afero/internal/common/adapters.go delete mode 100644 vendor/github.com/spf13/afero/iofs.go delete mode 100644 vendor/github.com/spf13/afero/ioutil.go delete mode 100644 vendor/github.com/spf13/afero/lstater.go delete mode 100644 vendor/github.com/spf13/afero/match.go delete mode 100644 vendor/github.com/spf13/afero/mem/dir.go delete mode 100644 vendor/github.com/spf13/afero/mem/dirmap.go delete mode 100644 vendor/github.com/spf13/afero/mem/file.go delete mode 100644 vendor/github.com/spf13/afero/memmap.go delete mode 100644 vendor/github.com/spf13/afero/os.go delete mode 100644 vendor/github.com/spf13/afero/path.go delete mode 100644 vendor/github.com/spf13/afero/readonlyfs.go delete mode 100644 vendor/github.com/spf13/afero/regexpfs.go delete mode 100644 vendor/github.com/spf13/afero/symlink.go delete mode 100644 vendor/github.com/spf13/afero/unionFile.go delete mode 100644 vendor/github.com/spf13/afero/util.go delete mode 100644 vendor/github.com/spf13/cast/.gitignore delete mode 100644 vendor/github.com/spf13/cast/LICENSE delete mode 100644 vendor/github.com/spf13/cast/Makefile delete mode 100644 vendor/github.com/spf13/cast/README.md delete mode 100644 vendor/github.com/spf13/cast/cast.go delete mode 100644 vendor/github.com/spf13/cast/caste.go delete mode 100644 vendor/github.com/spf13/cast/timeformattype_string.go delete mode 100644 vendor/github.com/spf13/cobra/.gitignore delete mode 100644 vendor/github.com/spf13/cobra/.golangci.yml delete mode 100644 vendor/github.com/spf13/cobra/.mailmap delete mode 100644 vendor/github.com/spf13/cobra/CONDUCT.md delete mode 100644 vendor/github.com/spf13/cobra/CONTRIBUTING.md delete mode 100644 vendor/github.com/spf13/cobra/LICENSE.txt delete mode 100644 vendor/github.com/spf13/cobra/MAINTAINERS delete mode 100644 vendor/github.com/spf13/cobra/Makefile delete mode 100644 vendor/github.com/spf13/cobra/README.md delete mode 100644 vendor/github.com/spf13/cobra/active_help.go delete mode 100644 vendor/github.com/spf13/cobra/args.go delete mode 100644 vendor/github.com/spf13/cobra/bash_completions.go delete mode 100644 vendor/github.com/spf13/cobra/bash_completionsV2.go delete mode 100644 vendor/github.com/spf13/cobra/cobra.go delete mode 100644 vendor/github.com/spf13/cobra/command.go delete mode 100644 vendor/github.com/spf13/cobra/command_notwin.go delete mode 100644 vendor/github.com/spf13/cobra/command_win.go delete mode 100644 vendor/github.com/spf13/cobra/completions.go delete mode 100644 vendor/github.com/spf13/cobra/fish_completions.go delete mode 100644 vendor/github.com/spf13/cobra/flag_groups.go delete mode 100644 vendor/github.com/spf13/cobra/powershell_completions.go delete mode 100644 vendor/github.com/spf13/cobra/shell_completions.go delete mode 100644 vendor/github.com/spf13/cobra/zsh_completions.go delete mode 100644 vendor/github.com/spf13/jwalterweatherman/.gitignore delete mode 100644 vendor/github.com/spf13/jwalterweatherman/LICENSE delete mode 100644 vendor/github.com/spf13/jwalterweatherman/README.md delete mode 100644 vendor/github.com/spf13/jwalterweatherman/default_notepad.go delete mode 100644 vendor/github.com/spf13/jwalterweatherman/log_counter.go delete mode 100644 vendor/github.com/spf13/jwalterweatherman/notepad.go delete mode 100644 vendor/github.com/spf13/pflag/.gitignore delete mode 100644 vendor/github.com/spf13/pflag/.travis.yml delete mode 100644 vendor/github.com/spf13/pflag/LICENSE delete mode 100644 vendor/github.com/spf13/pflag/README.md delete mode 100644 vendor/github.com/spf13/pflag/bool.go delete mode 100644 vendor/github.com/spf13/pflag/bool_slice.go delete mode 100644 vendor/github.com/spf13/pflag/bytes.go delete mode 100644 vendor/github.com/spf13/pflag/count.go delete mode 100644 vendor/github.com/spf13/pflag/duration.go delete mode 100644 vendor/github.com/spf13/pflag/duration_slice.go delete mode 100644 vendor/github.com/spf13/pflag/flag.go delete mode 100644 vendor/github.com/spf13/pflag/float32.go delete mode 100644 vendor/github.com/spf13/pflag/float32_slice.go delete mode 100644 vendor/github.com/spf13/pflag/float64.go delete mode 100644 vendor/github.com/spf13/pflag/float64_slice.go delete mode 100644 vendor/github.com/spf13/pflag/golangflag.go delete mode 100644 vendor/github.com/spf13/pflag/int.go delete mode 100644 vendor/github.com/spf13/pflag/int16.go delete mode 100644 vendor/github.com/spf13/pflag/int32.go delete mode 100644 vendor/github.com/spf13/pflag/int32_slice.go delete mode 100644 vendor/github.com/spf13/pflag/int64.go delete mode 100644 vendor/github.com/spf13/pflag/int64_slice.go delete mode 100644 vendor/github.com/spf13/pflag/int8.go delete mode 100644 vendor/github.com/spf13/pflag/int_slice.go delete mode 100644 vendor/github.com/spf13/pflag/ip.go delete mode 100644 vendor/github.com/spf13/pflag/ip_slice.go delete mode 100644 vendor/github.com/spf13/pflag/ipmask.go delete mode 100644 vendor/github.com/spf13/pflag/ipnet.go delete mode 100644 vendor/github.com/spf13/pflag/string.go delete mode 100644 vendor/github.com/spf13/pflag/string_array.go delete mode 100644 vendor/github.com/spf13/pflag/string_slice.go delete mode 100644 vendor/github.com/spf13/pflag/string_to_int.go delete mode 100644 vendor/github.com/spf13/pflag/string_to_int64.go delete mode 100644 vendor/github.com/spf13/pflag/string_to_string.go delete mode 100644 vendor/github.com/spf13/pflag/uint.go delete mode 100644 vendor/github.com/spf13/pflag/uint16.go delete mode 100644 vendor/github.com/spf13/pflag/uint32.go delete mode 100644 vendor/github.com/spf13/pflag/uint64.go delete mode 100644 vendor/github.com/spf13/pflag/uint8.go delete mode 100644 vendor/github.com/spf13/pflag/uint_slice.go delete mode 100644 vendor/github.com/spf13/viper/.editorconfig delete mode 100644 vendor/github.com/spf13/viper/.gitignore delete mode 100644 vendor/github.com/spf13/viper/.golangci.yaml delete mode 100644 vendor/github.com/spf13/viper/LICENSE delete mode 100644 vendor/github.com/spf13/viper/Makefile delete mode 100644 vendor/github.com/spf13/viper/README.md delete mode 100644 vendor/github.com/spf13/viper/TROUBLESHOOTING.md delete mode 100644 vendor/github.com/spf13/viper/experimental_logger.go delete mode 100644 vendor/github.com/spf13/viper/flags.go delete mode 100644 vendor/github.com/spf13/viper/fs.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/decoder.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/encoder.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/error.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/ini/codec.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/json/codec.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/toml/codec.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/toml/codec2.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/yaml/yaml2.go delete mode 100644 vendor/github.com/spf13/viper/internal/encoding/yaml/yaml3.go delete mode 100644 vendor/github.com/spf13/viper/logger.go delete mode 100644 vendor/github.com/spf13/viper/util.go delete mode 100644 vendor/github.com/spf13/viper/viper.go delete mode 100644 vendor/github.com/spf13/viper/viper_go1_15.go delete mode 100644 vendor/github.com/spf13/viper/viper_go1_16.go delete mode 100644 vendor/github.com/spf13/viper/watch.go delete mode 100644 vendor/github.com/spf13/viper/watch_wasm.go delete mode 100644 vendor/github.com/ssgreg/nlreturn/v2/LICENSE delete mode 100644 vendor/github.com/ssgreg/nlreturn/v2/pkg/nlreturn/nlreturn.go delete mode 100644 vendor/github.com/stbenjam/no-sprintf-host-port/LICENSE delete mode 100644 vendor/github.com/stbenjam/no-sprintf-host-port/pkg/analyzer/analyzer.go delete mode 100644 vendor/github.com/stretchr/objx/.codeclimate.yml delete mode 100644 vendor/github.com/stretchr/objx/.gitignore delete mode 100644 vendor/github.com/stretchr/objx/LICENSE delete mode 100644 vendor/github.com/stretchr/objx/README.md delete mode 100644 vendor/github.com/stretchr/objx/Taskfile.yml delete mode 100644 vendor/github.com/stretchr/objx/accessors.go delete mode 100644 vendor/github.com/stretchr/objx/conversions.go delete mode 100644 vendor/github.com/stretchr/objx/doc.go delete mode 100644 vendor/github.com/stretchr/objx/map.go delete mode 100644 vendor/github.com/stretchr/objx/mutations.go delete mode 100644 vendor/github.com/stretchr/objx/security.go delete mode 100644 vendor/github.com/stretchr/objx/tests.go delete mode 100644 vendor/github.com/stretchr/objx/type_specific.go delete mode 100644 vendor/github.com/stretchr/objx/type_specific_codegen.go delete mode 100644 vendor/github.com/stretchr/objx/value.go delete mode 100644 vendor/github.com/stretchr/testify/LICENSE delete mode 100644 vendor/github.com/stretchr/testify/assert/assertion_compare.go delete mode 100644 vendor/github.com/stretchr/testify/assert/assertion_format.go delete mode 100644 vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl delete mode 100644 vendor/github.com/stretchr/testify/assert/assertion_forward.go delete mode 100644 vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl delete mode 100644 vendor/github.com/stretchr/testify/assert/assertion_order.go delete mode 100644 vendor/github.com/stretchr/testify/assert/assertions.go delete mode 100644 vendor/github.com/stretchr/testify/assert/doc.go delete mode 100644 vendor/github.com/stretchr/testify/assert/errors.go delete mode 100644 vendor/github.com/stretchr/testify/assert/forward_assertions.go delete mode 100644 vendor/github.com/stretchr/testify/assert/http_assertions.go delete mode 100644 vendor/github.com/stretchr/testify/mock/doc.go delete mode 100644 vendor/github.com/stretchr/testify/mock/mock.go delete mode 100644 vendor/github.com/stretchr/testify/require/doc.go delete mode 100644 vendor/github.com/stretchr/testify/require/forward_requirements.go delete mode 100644 vendor/github.com/stretchr/testify/require/require.go delete mode 100644 vendor/github.com/stretchr/testify/require/require.go.tmpl delete mode 100644 vendor/github.com/stretchr/testify/require/require_forward.go delete mode 100644 vendor/github.com/stretchr/testify/require/require_forward.go.tmpl delete mode 100644 vendor/github.com/stretchr/testify/require/requirements.go delete mode 100644 vendor/github.com/stretchr/testify/suite/doc.go delete mode 100644 vendor/github.com/stretchr/testify/suite/interfaces.go delete mode 100644 vendor/github.com/stretchr/testify/suite/stats.go delete mode 100644 vendor/github.com/stretchr/testify/suite/suite.go delete mode 100644 vendor/github.com/subosito/gotenv/.env delete mode 100644 vendor/github.com/subosito/gotenv/.env.invalid delete mode 100644 vendor/github.com/subosito/gotenv/.gitignore delete mode 100644 vendor/github.com/subosito/gotenv/.golangci.yaml delete mode 100644 vendor/github.com/subosito/gotenv/CHANGELOG.md delete mode 100644 vendor/github.com/subosito/gotenv/LICENSE delete mode 100644 vendor/github.com/subosito/gotenv/README.md delete mode 100644 vendor/github.com/subosito/gotenv/gotenv.go delete mode 100644 vendor/github.com/tdakkota/asciicheck/.gitignore delete mode 100644 vendor/github.com/tdakkota/asciicheck/LICENSE delete mode 100644 vendor/github.com/tdakkota/asciicheck/README.md delete mode 100644 vendor/github.com/tdakkota/asciicheck/ascii.go delete mode 100644 vendor/github.com/tdakkota/asciicheck/asciicheck.go delete mode 100644 vendor/github.com/tetafro/godot/.gitignore delete mode 100644 vendor/github.com/tetafro/godot/.godot.yaml delete mode 100644 vendor/github.com/tetafro/godot/.golangci.yml delete mode 100644 vendor/github.com/tetafro/godot/.goreleaser.yml delete mode 100644 vendor/github.com/tetafro/godot/LICENSE delete mode 100644 vendor/github.com/tetafro/godot/Makefile delete mode 100644 vendor/github.com/tetafro/godot/README.md delete mode 100644 vendor/github.com/tetafro/godot/checks.go delete mode 100644 vendor/github.com/tetafro/godot/getters.go delete mode 100644 vendor/github.com/tetafro/godot/godot.go delete mode 100644 vendor/github.com/tetafro/godot/settings.go delete mode 100644 vendor/github.com/timakin/bodyclose/LICENSE delete mode 100644 vendor/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go delete mode 100644 vendor/github.com/timonwong/loggercheck/.codecov.yml delete mode 100644 vendor/github.com/timonwong/loggercheck/.gitignore delete mode 100644 vendor/github.com/timonwong/loggercheck/.golangci.yml delete mode 100644 vendor/github.com/timonwong/loggercheck/.goreleaser.yml delete mode 100644 vendor/github.com/timonwong/loggercheck/LICENSE delete mode 100644 vendor/github.com/timonwong/loggercheck/Makefile delete mode 100644 vendor/github.com/timonwong/loggercheck/README.md delete mode 100644 vendor/github.com/timonwong/loggercheck/internal/bytebufferpool/pool.go delete mode 100644 vendor/github.com/timonwong/loggercheck/internal/checkers/checker.go delete mode 100644 vendor/github.com/timonwong/loggercheck/internal/checkers/common.go delete mode 100644 vendor/github.com/timonwong/loggercheck/internal/checkers/general.go delete mode 100644 vendor/github.com/timonwong/loggercheck/internal/checkers/printf/printf.go delete mode 100644 vendor/github.com/timonwong/loggercheck/internal/checkers/zap.go delete mode 100644 vendor/github.com/timonwong/loggercheck/internal/rules/rules.go delete mode 100644 vendor/github.com/timonwong/loggercheck/internal/sets/string.go delete mode 100644 vendor/github.com/timonwong/loggercheck/internal/stringutil/is.go delete mode 100644 vendor/github.com/timonwong/loggercheck/loggercheck.go delete mode 100644 vendor/github.com/timonwong/loggercheck/options.go delete mode 100644 vendor/github.com/timonwong/loggercheck/staticrules.go delete mode 100644 vendor/github.com/tomarrell/wrapcheck/v2/LICENSE delete mode 100644 vendor/github.com/tomarrell/wrapcheck/v2/wrapcheck/wrapcheck.go delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/.editorconfig delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/.gitattributes delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/.gitignore delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/.goreleaser.yml delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/Dockerfile delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/LICENSE delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/Makefile delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/README.md delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/action.yml delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/analyzer.go delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/checks/argument.go delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/checks/assign.go delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/checks/case.go delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/checks/checks.go delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/checks/condition.go delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/checks/operation.go delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/checks/return.go delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/config/config.go delete mode 100644 vendor/github.com/tommy-muehle/go-mnd/v2/entrypoint.sh delete mode 100644 vendor/github.com/ultraware/funlen/LICENSE delete mode 100644 vendor/github.com/ultraware/funlen/README.md delete mode 100644 vendor/github.com/ultraware/funlen/main.go delete mode 100644 vendor/github.com/ultraware/whitespace/LICENSE delete mode 100644 vendor/github.com/ultraware/whitespace/README.md delete mode 100644 vendor/github.com/ultraware/whitespace/whitespace.go delete mode 100644 vendor/github.com/uudashr/gocognit/LICENSE delete mode 100644 vendor/github.com/uudashr/gocognit/README.md delete mode 100644 vendor/github.com/uudashr/gocognit/doc.go delete mode 100644 vendor/github.com/uudashr/gocognit/gocognit.go delete mode 100644 vendor/github.com/uudashr/gocognit/recv.go delete mode 100644 vendor/github.com/uudashr/gocognit/recv_pre118.go delete mode 100644 vendor/github.com/xen0n/gosmopolitan/.editorconfig delete mode 100644 vendor/github.com/xen0n/gosmopolitan/.gitignore delete mode 100644 vendor/github.com/xen0n/gosmopolitan/.golangci.yml delete mode 100644 vendor/github.com/xen0n/gosmopolitan/LICENSE delete mode 100644 vendor/github.com/xen0n/gosmopolitan/README.md delete mode 100644 vendor/github.com/xen0n/gosmopolitan/README.zh-Hans.md delete mode 100644 vendor/github.com/xen0n/gosmopolitan/lib.go delete mode 100644 vendor/github.com/yagipy/maintidx/.gitignore delete mode 100644 vendor/github.com/yagipy/maintidx/LICENSE delete mode 100644 vendor/github.com/yagipy/maintidx/Makefile delete mode 100644 vendor/github.com/yagipy/maintidx/README.md delete mode 100644 vendor/github.com/yagipy/maintidx/maintidx.go delete mode 100644 vendor/github.com/yagipy/maintidx/pkg/cyc/cyc.go delete mode 100644 vendor/github.com/yagipy/maintidx/pkg/halstvol/halstvol.go delete mode 100644 vendor/github.com/yagipy/maintidx/pkg/halstvol/handle.go delete mode 100644 vendor/github.com/yagipy/maintidx/visitor.go delete mode 100644 vendor/github.com/yeya24/promlinter/.gitignore delete mode 100644 vendor/github.com/yeya24/promlinter/LICENSE delete mode 100644 vendor/github.com/yeya24/promlinter/Makefile delete mode 100644 vendor/github.com/yeya24/promlinter/README.md delete mode 100644 vendor/github.com/yeya24/promlinter/promlinter.go delete mode 100644 vendor/github.com/ykadowak/zerologlint/.goreleaser.yaml delete mode 100644 vendor/github.com/ykadowak/zerologlint/LICENSE delete mode 100644 vendor/github.com/ykadowak/zerologlint/README.md delete mode 100644 vendor/github.com/ykadowak/zerologlint/zerologlint.go delete mode 100644 vendor/github.com/yuin/gopher-lua/LICENSE delete mode 100644 vendor/github.com/yuin/gopher-lua/Makefile delete mode 100644 vendor/github.com/yuin/gopher-lua/README.rst delete mode 100644 vendor/github.com/yuin/gopher-lua/_state.go delete mode 100644 vendor/github.com/yuin/gopher-lua/_vm.go delete mode 100644 vendor/github.com/yuin/gopher-lua/alloc.go delete mode 100644 vendor/github.com/yuin/gopher-lua/ast/ast.go delete mode 100644 vendor/github.com/yuin/gopher-lua/ast/expr.go delete mode 100644 vendor/github.com/yuin/gopher-lua/ast/misc.go delete mode 100644 vendor/github.com/yuin/gopher-lua/ast/stmt.go delete mode 100644 vendor/github.com/yuin/gopher-lua/ast/token.go delete mode 100644 vendor/github.com/yuin/gopher-lua/auxlib.go delete mode 100644 vendor/github.com/yuin/gopher-lua/baselib.go delete mode 100644 vendor/github.com/yuin/gopher-lua/channellib.go delete mode 100644 vendor/github.com/yuin/gopher-lua/compile.go delete mode 100644 vendor/github.com/yuin/gopher-lua/config.go delete mode 100644 vendor/github.com/yuin/gopher-lua/coroutinelib.go delete mode 100644 vendor/github.com/yuin/gopher-lua/debuglib.go delete mode 100644 vendor/github.com/yuin/gopher-lua/function.go delete mode 100644 vendor/github.com/yuin/gopher-lua/iolib.go delete mode 100644 vendor/github.com/yuin/gopher-lua/linit.go delete mode 100644 vendor/github.com/yuin/gopher-lua/loadlib.go delete mode 100644 vendor/github.com/yuin/gopher-lua/mathlib.go delete mode 100644 vendor/github.com/yuin/gopher-lua/opcode.go delete mode 100644 vendor/github.com/yuin/gopher-lua/oslib.go delete mode 100644 vendor/github.com/yuin/gopher-lua/package.go delete mode 100644 vendor/github.com/yuin/gopher-lua/parse/Makefile delete mode 100644 vendor/github.com/yuin/gopher-lua/parse/lexer.go delete mode 100644 vendor/github.com/yuin/gopher-lua/parse/parser.go delete mode 100644 vendor/github.com/yuin/gopher-lua/parse/parser.go.y delete mode 100644 vendor/github.com/yuin/gopher-lua/pm/pm.go delete mode 100644 vendor/github.com/yuin/gopher-lua/state.go delete mode 100644 vendor/github.com/yuin/gopher-lua/stringlib.go delete mode 100644 vendor/github.com/yuin/gopher-lua/table.go delete mode 100644 vendor/github.com/yuin/gopher-lua/tablelib.go delete mode 100644 vendor/github.com/yuin/gopher-lua/utils.go delete mode 100644 vendor/github.com/yuin/gopher-lua/value.go delete mode 100644 vendor/github.com/yuin/gopher-lua/vm.go delete mode 100644 vendor/github.com/zenazn/goji/LICENSE delete mode 100644 vendor/github.com/zenazn/goji/web/mutil/mutil.go delete mode 100644 vendor/github.com/zenazn/goji/web/mutil/writer_proxy.go delete mode 100644 vendor/github.com/zenazn/goji/web/mutil/writer_proxy_go1_8.go delete mode 100644 vendor/gitlab.com/bosi/decorder/.gitignore delete mode 100644 vendor/gitlab.com/bosi/decorder/.gitlab-ci.params.yml delete mode 100644 vendor/gitlab.com/bosi/decorder/.gitlab-ci.yml delete mode 100644 vendor/gitlab.com/bosi/decorder/LICENSE.md delete mode 100644 vendor/gitlab.com/bosi/decorder/Makefile delete mode 100644 vendor/gitlab.com/bosi/decorder/README.md delete mode 100644 vendor/gitlab.com/bosi/decorder/analyzer.go delete mode 100644 vendor/gitlab.com/bosi/decorder/renovate.json delete mode 100644 vendor/go-simpler.org/musttag/.golangci.yml delete mode 100644 vendor/go-simpler.org/musttag/.goreleaser.yml delete mode 100644 vendor/go-simpler.org/musttag/LICENSE delete mode 100644 vendor/go-simpler.org/musttag/Makefile delete mode 100644 vendor/go-simpler.org/musttag/README.md delete mode 100644 vendor/go-simpler.org/musttag/builtins.go delete mode 100644 vendor/go-simpler.org/musttag/musttag.go delete mode 100644 vendor/go-simpler.org/musttag/utils.go delete mode 100644 vendor/go-simpler.org/sloglint/.golangci.yml delete mode 100644 vendor/go-simpler.org/sloglint/.goreleaser.yml delete mode 100644 vendor/go-simpler.org/sloglint/LICENSE delete mode 100644 vendor/go-simpler.org/sloglint/Makefile delete mode 100644 vendor/go-simpler.org/sloglint/README.md delete mode 100644 vendor/go-simpler.org/sloglint/sloglint.go delete mode 100644 vendor/go.uber.org/atomic/.codecov.yml delete mode 100644 vendor/go.uber.org/atomic/.gitignore delete mode 100644 vendor/go.uber.org/atomic/.travis.yml delete mode 100644 vendor/go.uber.org/atomic/CHANGELOG.md delete mode 100644 vendor/go.uber.org/atomic/LICENSE.txt delete mode 100644 vendor/go.uber.org/atomic/Makefile delete mode 100644 vendor/go.uber.org/atomic/README.md delete mode 100644 vendor/go.uber.org/atomic/bool.go delete mode 100644 vendor/go.uber.org/atomic/bool_ext.go delete mode 100644 vendor/go.uber.org/atomic/doc.go delete mode 100644 vendor/go.uber.org/atomic/duration.go delete mode 100644 vendor/go.uber.org/atomic/duration_ext.go delete mode 100644 vendor/go.uber.org/atomic/error.go delete mode 100644 vendor/go.uber.org/atomic/error_ext.go delete mode 100644 vendor/go.uber.org/atomic/float64.go delete mode 100644 vendor/go.uber.org/atomic/float64_ext.go delete mode 100644 vendor/go.uber.org/atomic/gen.go delete mode 100644 vendor/go.uber.org/atomic/int32.go delete mode 100644 vendor/go.uber.org/atomic/int64.go delete mode 100644 vendor/go.uber.org/atomic/nocmp.go delete mode 100644 vendor/go.uber.org/atomic/string.go delete mode 100644 vendor/go.uber.org/atomic/string_ext.go delete mode 100644 vendor/go.uber.org/atomic/uint32.go delete mode 100644 vendor/go.uber.org/atomic/uint64.go delete mode 100644 vendor/go.uber.org/atomic/value.go delete mode 100644 vendor/go.uber.org/automaxprocs/LICENSE delete mode 100644 vendor/go.uber.org/automaxprocs/internal/cgroups/cgroup.go delete mode 100644 vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups.go delete mode 100644 vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go delete mode 100644 vendor/go.uber.org/automaxprocs/internal/cgroups/doc.go delete mode 100644 vendor/go.uber.org/automaxprocs/internal/cgroups/errors.go delete mode 100644 vendor/go.uber.org/automaxprocs/internal/cgroups/mountpoint.go delete mode 100644 vendor/go.uber.org/automaxprocs/internal/cgroups/subsys.go delete mode 100644 vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_linux.go delete mode 100644 vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_unsupported.go delete mode 100644 vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go delete mode 100644 vendor/go.uber.org/automaxprocs/maxprocs/maxprocs.go delete mode 100644 vendor/go.uber.org/automaxprocs/maxprocs/version.go delete mode 100644 vendor/go.uber.org/multierr/.codecov.yml delete mode 100644 vendor/go.uber.org/multierr/.gitignore delete mode 100644 vendor/go.uber.org/multierr/.travis.yml delete mode 100644 vendor/go.uber.org/multierr/CHANGELOG.md delete mode 100644 vendor/go.uber.org/multierr/LICENSE.txt delete mode 100644 vendor/go.uber.org/multierr/Makefile delete mode 100644 vendor/go.uber.org/multierr/README.md delete mode 100644 vendor/go.uber.org/multierr/error.go delete mode 100644 vendor/go.uber.org/multierr/glide.yaml delete mode 100644 vendor/go.uber.org/multierr/go113.go delete mode 100644 vendor/go.uber.org/zap/.codecov.yml delete mode 100644 vendor/go.uber.org/zap/.gitignore delete mode 100644 vendor/go.uber.org/zap/.readme.tmpl delete mode 100644 vendor/go.uber.org/zap/CHANGELOG.md delete mode 100644 vendor/go.uber.org/zap/CODE_OF_CONDUCT.md delete mode 100644 vendor/go.uber.org/zap/CONTRIBUTING.md delete mode 100644 vendor/go.uber.org/zap/FAQ.md delete mode 100644 vendor/go.uber.org/zap/LICENSE.txt delete mode 100644 vendor/go.uber.org/zap/Makefile delete mode 100644 vendor/go.uber.org/zap/README.md delete mode 100644 vendor/go.uber.org/zap/array.go delete mode 100644 vendor/go.uber.org/zap/array_go118.go delete mode 100644 vendor/go.uber.org/zap/buffer/buffer.go delete mode 100644 vendor/go.uber.org/zap/buffer/pool.go delete mode 100644 vendor/go.uber.org/zap/checklicense.sh delete mode 100644 vendor/go.uber.org/zap/config.go delete mode 100644 vendor/go.uber.org/zap/doc.go delete mode 100644 vendor/go.uber.org/zap/encoder.go delete mode 100644 vendor/go.uber.org/zap/error.go delete mode 100644 vendor/go.uber.org/zap/field.go delete mode 100644 vendor/go.uber.org/zap/flag.go delete mode 100644 vendor/go.uber.org/zap/glide.yaml delete mode 100644 vendor/go.uber.org/zap/global.go delete mode 100644 vendor/go.uber.org/zap/http_handler.go delete mode 100644 vendor/go.uber.org/zap/internal/bufferpool/bufferpool.go delete mode 100644 vendor/go.uber.org/zap/internal/color/color.go delete mode 100644 vendor/go.uber.org/zap/internal/exit/exit.go delete mode 100644 vendor/go.uber.org/zap/internal/level_enabler.go delete mode 100644 vendor/go.uber.org/zap/level.go delete mode 100644 vendor/go.uber.org/zap/logger.go delete mode 100644 vendor/go.uber.org/zap/options.go delete mode 100644 vendor/go.uber.org/zap/sink.go delete mode 100644 vendor/go.uber.org/zap/stacktrace.go delete mode 100644 vendor/go.uber.org/zap/sugar.go delete mode 100644 vendor/go.uber.org/zap/time.go delete mode 100644 vendor/go.uber.org/zap/writer.go delete mode 100644 vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go delete mode 100644 vendor/go.uber.org/zap/zapcore/clock.go delete mode 100644 vendor/go.uber.org/zap/zapcore/console_encoder.go delete mode 100644 vendor/go.uber.org/zap/zapcore/core.go delete mode 100644 vendor/go.uber.org/zap/zapcore/doc.go delete mode 100644 vendor/go.uber.org/zap/zapcore/encoder.go delete mode 100644 vendor/go.uber.org/zap/zapcore/entry.go delete mode 100644 vendor/go.uber.org/zap/zapcore/error.go delete mode 100644 vendor/go.uber.org/zap/zapcore/field.go delete mode 100644 vendor/go.uber.org/zap/zapcore/hook.go delete mode 100644 vendor/go.uber.org/zap/zapcore/increase_level.go delete mode 100644 vendor/go.uber.org/zap/zapcore/json_encoder.go delete mode 100644 vendor/go.uber.org/zap/zapcore/level.go delete mode 100644 vendor/go.uber.org/zap/zapcore/level_strings.go delete mode 100644 vendor/go.uber.org/zap/zapcore/marshaler.go delete mode 100644 vendor/go.uber.org/zap/zapcore/memory_encoder.go delete mode 100644 vendor/go.uber.org/zap/zapcore/reflected_encoder.go delete mode 100644 vendor/go.uber.org/zap/zapcore/sampler.go delete mode 100644 vendor/go.uber.org/zap/zapcore/tee.go delete mode 100644 vendor/go.uber.org/zap/zapcore/write_syncer.go delete mode 100644 vendor/golang.org/x/crypto/LICENSE delete mode 100644 vendor/golang.org/x/crypto/PATENTS delete mode 100644 vendor/golang.org/x/crypto/argon2/argon2.go delete mode 100644 vendor/golang.org/x/crypto/argon2/blake2b.go delete mode 100644 vendor/golang.org/x/crypto/argon2/blamka_amd64.go delete mode 100644 vendor/golang.org/x/crypto/argon2/blamka_amd64.s delete mode 100644 vendor/golang.org/x/crypto/argon2/blamka_generic.go delete mode 100644 vendor/golang.org/x/crypto/argon2/blamka_ref.go delete mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b.go delete mode 100644 vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go delete mode 100644 vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s delete mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s delete mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_generic.go delete mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_ref.go delete mode 100644 vendor/golang.org/x/crypto/blake2b/blake2x.go delete mode 100644 vendor/golang.org/x/crypto/blake2b/register.go delete mode 100644 vendor/golang.org/x/exp/LICENSE delete mode 100644 vendor/golang.org/x/exp/PATENTS delete mode 100644 vendor/golang.org/x/exp/constraints/constraints.go delete mode 100644 vendor/golang.org/x/exp/maps/maps.go delete mode 100644 vendor/golang.org/x/exp/slices/cmp.go delete mode 100644 vendor/golang.org/x/exp/slices/slices.go delete mode 100644 vendor/golang.org/x/exp/slices/sort.go delete mode 100644 vendor/golang.org/x/exp/slices/zsortanyfunc.go delete mode 100644 vendor/golang.org/x/exp/slices/zsortordered.go delete mode 100644 vendor/golang.org/x/exp/typeparams/LICENSE delete mode 100644 vendor/golang.org/x/exp/typeparams/common.go delete mode 100644 vendor/golang.org/x/exp/typeparams/normalize.go delete mode 100644 vendor/golang.org/x/exp/typeparams/termlist.go delete mode 100644 vendor/golang.org/x/exp/typeparams/typeparams_go117.go delete mode 100644 vendor/golang.org/x/exp/typeparams/typeparams_go118.go delete mode 100644 vendor/golang.org/x/exp/typeparams/typeterm.go delete mode 100644 vendor/golang.org/x/mod/LICENSE delete mode 100644 vendor/golang.org/x/mod/PATENTS delete mode 100644 vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go delete mode 100644 vendor/golang.org/x/mod/modfile/print.go delete mode 100644 vendor/golang.org/x/mod/modfile/read.go delete mode 100644 vendor/golang.org/x/mod/modfile/rule.go delete mode 100644 vendor/golang.org/x/mod/modfile/work.go delete mode 100644 vendor/golang.org/x/mod/module/module.go delete mode 100644 vendor/golang.org/x/mod/module/pseudo.go delete mode 100644 vendor/golang.org/x/mod/semver/semver.go delete mode 100644 vendor/golang.org/x/net/LICENSE delete mode 100644 vendor/golang.org/x/net/PATENTS delete mode 100644 vendor/golang.org/x/net/http/httpguts/guts.go delete mode 100644 vendor/golang.org/x/net/http/httpguts/httplex.go delete mode 100644 vendor/golang.org/x/net/http2/.gitignore delete mode 100644 vendor/golang.org/x/net/http2/ascii.go delete mode 100644 vendor/golang.org/x/net/http2/ciphers.go delete mode 100644 vendor/golang.org/x/net/http2/client_conn_pool.go delete mode 100644 vendor/golang.org/x/net/http2/databuffer.go delete mode 100644 vendor/golang.org/x/net/http2/errors.go delete mode 100644 vendor/golang.org/x/net/http2/flow.go delete mode 100644 vendor/golang.org/x/net/http2/frame.go delete mode 100644 vendor/golang.org/x/net/http2/gotrack.go delete mode 100644 vendor/golang.org/x/net/http2/headermap.go delete mode 100644 vendor/golang.org/x/net/http2/hpack/encode.go delete mode 100644 vendor/golang.org/x/net/http2/hpack/hpack.go delete mode 100644 vendor/golang.org/x/net/http2/hpack/huffman.go delete mode 100644 vendor/golang.org/x/net/http2/hpack/static_table.go delete mode 100644 vendor/golang.org/x/net/http2/hpack/tables.go delete mode 100644 vendor/golang.org/x/net/http2/http2.go delete mode 100644 vendor/golang.org/x/net/http2/pipe.go delete mode 100644 vendor/golang.org/x/net/http2/server.go delete mode 100644 vendor/golang.org/x/net/http2/timer.go delete mode 100644 vendor/golang.org/x/net/http2/transport.go delete mode 100644 vendor/golang.org/x/net/http2/write.go delete mode 100644 vendor/golang.org/x/net/http2/writesched.go delete mode 100644 vendor/golang.org/x/net/http2/writesched_priority.go delete mode 100644 vendor/golang.org/x/net/http2/writesched_random.go delete mode 100644 vendor/golang.org/x/net/http2/writesched_roundrobin.go delete mode 100644 vendor/golang.org/x/net/idna/go118.go delete mode 100644 vendor/golang.org/x/net/idna/idna10.0.0.go delete mode 100644 vendor/golang.org/x/net/idna/idna9.0.0.go delete mode 100644 vendor/golang.org/x/net/idna/pre_go118.go delete mode 100644 vendor/golang.org/x/net/idna/punycode.go delete mode 100644 vendor/golang.org/x/net/idna/tables10.0.0.go delete mode 100644 vendor/golang.org/x/net/idna/tables11.0.0.go delete mode 100644 vendor/golang.org/x/net/idna/tables12.0.0.go delete mode 100644 vendor/golang.org/x/net/idna/tables13.0.0.go delete mode 100644 vendor/golang.org/x/net/idna/tables15.0.0.go delete mode 100644 vendor/golang.org/x/net/idna/tables9.0.0.go delete mode 100644 vendor/golang.org/x/net/idna/trie.go delete mode 100644 vendor/golang.org/x/net/idna/trie12.0.0.go delete mode 100644 vendor/golang.org/x/net/idna/trie13.0.0.go delete mode 100644 vendor/golang.org/x/net/idna/trieval.go delete mode 100644 vendor/golang.org/x/net/internal/timeseries/timeseries.go delete mode 100644 vendor/golang.org/x/net/publicsuffix/data/children delete mode 100644 vendor/golang.org/x/net/publicsuffix/data/nodes delete mode 100644 vendor/golang.org/x/net/publicsuffix/data/text delete mode 100644 vendor/golang.org/x/net/publicsuffix/list.go delete mode 100644 vendor/golang.org/x/net/publicsuffix/table.go delete mode 100644 vendor/golang.org/x/net/trace/events.go delete mode 100644 vendor/golang.org/x/net/trace/histogram.go delete mode 100644 vendor/golang.org/x/net/trace/trace.go delete mode 100644 vendor/golang.org/x/sync/LICENSE delete mode 100644 vendor/golang.org/x/sync/PATENTS delete mode 100644 vendor/golang.org/x/sync/errgroup/errgroup.go delete mode 100644 vendor/golang.org/x/sync/errgroup/go120.go delete mode 100644 vendor/golang.org/x/sync/errgroup/pre_go120.go delete mode 100644 vendor/golang.org/x/sync/semaphore/semaphore.go delete mode 100644 vendor/golang.org/x/sys/LICENSE delete mode 100644 vendor/golang.org/x/sys/PATENTS delete mode 100644 vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s delete mode 100644 vendor/golang.org/x/sys/cpu/byteorder.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_aix.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm64.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm64.s delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_x86.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_arm.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_loong64.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_mips64x.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_mipsx.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_arm.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_arm64.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_ppc64x.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_riscv64.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_s390x.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_s390x.s delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_wasm.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_x86.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_x86.s delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_zos.go delete mode 100644 vendor/golang.org/x/sys/cpu/cpu_zos_s390x.go delete mode 100644 vendor/golang.org/x/sys/cpu/endian_big.go delete mode 100644 vendor/golang.org/x/sys/cpu/endian_little.go delete mode 100644 vendor/golang.org/x/sys/cpu/hwcap_linux.go delete mode 100644 vendor/golang.org/x/sys/cpu/parse.go delete mode 100644 vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go delete mode 100644 vendor/golang.org/x/sys/cpu/runtime_auxv.go delete mode 100644 vendor/golang.org/x/sys/cpu/runtime_auxv_go121.go delete mode 100644 vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go delete mode 100644 vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go delete mode 100644 vendor/golang.org/x/sys/execabs/execabs.go delete mode 100644 vendor/golang.org/x/sys/execabs/execabs_go118.go delete mode 100644 vendor/golang.org/x/sys/execabs/execabs_go119.go delete mode 100644 vendor/golang.org/x/sys/unix/.gitignore delete mode 100644 vendor/golang.org/x/sys/unix/README.md delete mode 100644 vendor/golang.org/x/sys/unix/affinity_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/aliases.go delete mode 100644 vendor/golang.org/x/sys/unix/asm_aix_ppc64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_386.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_arm.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_arm64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_386.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_arm.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_arm64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_loong64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_mips64x.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_mipsx.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_riscv64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_s390x.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_solaris_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_zos_s390x.s delete mode 100644 vendor/golang.org/x/sys/unix/bluetooth_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/bpxsvc_zos.go delete mode 100644 vendor/golang.org/x/sys/unix/bpxsvc_zos.s delete mode 100644 vendor/golang.org/x/sys/unix/cap_freebsd.go delete mode 100644 vendor/golang.org/x/sys/unix/constants.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_aix_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_aix_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_darwin.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_dragonfly.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_freebsd.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_netbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_openbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_zos.go delete mode 100644 vendor/golang.org/x/sys/unix/dirent.go delete mode 100644 vendor/golang.org/x/sys/unix/endian_big.go delete mode 100644 vendor/golang.org/x/sys/unix/endian_little.go delete mode 100644 vendor/golang.org/x/sys/unix/env_unix.go delete mode 100644 vendor/golang.org/x/sys/unix/fcntl.go delete mode 100644 vendor/golang.org/x/sys/unix/fcntl_darwin.go delete mode 100644 vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go delete mode 100644 vendor/golang.org/x/sys/unix/fdset.go delete mode 100644 vendor/golang.org/x/sys/unix/gccgo.go delete mode 100644 vendor/golang.org/x/sys/unix/gccgo_c.c delete mode 100644 vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ifreq_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/ioctl_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/ioctl_signed.go delete mode 100644 vendor/golang.org/x/sys/unix/ioctl_unsigned.go delete mode 100644 vendor/golang.org/x/sys/unix/ioctl_zos.go delete mode 100644 vendor/golang.org/x/sys/unix/mkall.sh delete mode 100644 vendor/golang.org/x/sys/unix/mkerrors.sh delete mode 100644 vendor/golang.org/x/sys/unix/mmap_nomremap.go delete mode 100644 vendor/golang.org/x/sys/unix/mremap.go delete mode 100644 vendor/golang.org/x/sys/unix/pagesize_unix.go delete mode 100644 vendor/golang.org/x/sys/unix/pledge_openbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/ptrace_darwin.go delete mode 100644 vendor/golang.org/x/sys/unix/ptrace_ios.go delete mode 100644 vendor/golang.org/x/sys/unix/race.go delete mode 100644 vendor/golang.org/x/sys/unix/race0.go delete mode 100644 vendor/golang.org/x/sys/unix/readdirent_getdents.go delete mode 100644 vendor/golang.org/x/sys/unix/readdirent_getdirentries.go delete mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_dragonfly.go delete mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_unix.go delete mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go delete mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_zos.go delete mode 100644 vendor/golang.org/x/sys/unix/symaddr_zos_s390x.s delete mode 100644 vendor/golang.org/x/sys/unix/syscall.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_aix.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_aix_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_bsd.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_hurd.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_hurd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_illumos.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_alarm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gc.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_loong64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_solaris.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_unix.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_unix_gc.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_zos_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/sysvshm_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/sysvshm_unix.go delete mode 100644 vendor/golang.org/x/sys/unix/sysvshm_unix_other.go delete mode 100644 vendor/golang.org/x/sys/unix/timestruct.go delete mode 100644 vendor/golang.org/x/sys/unix/unveil_openbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/xattr_bsd.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/zptrace_x86_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/zsymaddr_zos_s390x.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_loong64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_zos_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_aix_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_386.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go delete mode 100644 vendor/golang.org/x/sys/windows/aliases.go delete mode 100644 vendor/golang.org/x/sys/windows/dll_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/env_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/eventlog.go delete mode 100644 vendor/golang.org/x/sys/windows/exec_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/memory_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/mkerrors.bash delete mode 100644 vendor/golang.org/x/sys/windows/mkknownfolderids.bash delete mode 100644 vendor/golang.org/x/sys/windows/mksyscall.go delete mode 100644 vendor/golang.org/x/sys/windows/race.go delete mode 100644 vendor/golang.org/x/sys/windows/race0.go delete mode 100644 vendor/golang.org/x/sys/windows/security_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/service.go delete mode 100644 vendor/golang.org/x/sys/windows/setupapi_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/str.go delete mode 100644 vendor/golang.org/x/sys/windows/syscall.go delete mode 100644 vendor/golang.org/x/sys/windows/syscall_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/types_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/types_windows_386.go delete mode 100644 vendor/golang.org/x/sys/windows/types_windows_amd64.go delete mode 100644 vendor/golang.org/x/sys/windows/types_windows_arm.go delete mode 100644 vendor/golang.org/x/sys/windows/types_windows_arm64.go delete mode 100644 vendor/golang.org/x/sys/windows/zerrors_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/zknownfolderids_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/zsyscall_windows.go delete mode 100644 vendor/golang.org/x/telemetry/.dockerignore delete mode 100644 vendor/golang.org/x/telemetry/.eslintrc.json delete mode 100644 vendor/golang.org/x/telemetry/.gitattributes delete mode 100644 vendor/golang.org/x/telemetry/.gitignore delete mode 100644 vendor/golang.org/x/telemetry/.prettierrc.json delete mode 100644 vendor/golang.org/x/telemetry/.stylelintrc.json delete mode 100644 vendor/golang.org/x/telemetry/CONTRIBUTING.md delete mode 100644 vendor/golang.org/x/telemetry/LICENSE delete mode 100644 vendor/golang.org/x/telemetry/PATENTS delete mode 100644 vendor/golang.org/x/telemetry/README.md delete mode 100644 vendor/golang.org/x/telemetry/counter/counter.go delete mode 100644 vendor/golang.org/x/telemetry/counter/doc.go delete mode 100644 vendor/golang.org/x/telemetry/dir.go delete mode 100644 vendor/golang.org/x/telemetry/doc.go delete mode 100644 vendor/golang.org/x/telemetry/internal/config/config.go delete mode 100644 vendor/golang.org/x/telemetry/internal/configstore/download.go delete mode 100644 vendor/golang.org/x/telemetry/internal/counter/counter.go delete mode 100644 vendor/golang.org/x/telemetry/internal/counter/file.go delete mode 100644 vendor/golang.org/x/telemetry/internal/counter/parse.go delete mode 100644 vendor/golang.org/x/telemetry/internal/counter/stackcounter.go delete mode 100644 vendor/golang.org/x/telemetry/internal/crashmonitor/crash_go123.go delete mode 100644 vendor/golang.org/x/telemetry/internal/crashmonitor/monitor.go delete mode 100644 vendor/golang.org/x/telemetry/internal/mmap/mmap.go delete mode 100644 vendor/golang.org/x/telemetry/internal/mmap/mmap_other.go delete mode 100644 vendor/golang.org/x/telemetry/internal/mmap/mmap_unix.go delete mode 100644 vendor/golang.org/x/telemetry/internal/mmap/mmap_windows.go delete mode 100644 vendor/golang.org/x/telemetry/internal/telemetry/dir.go delete mode 100644 vendor/golang.org/x/telemetry/internal/telemetry/proginfo.go delete mode 100644 vendor/golang.org/x/telemetry/internal/telemetry/types.go delete mode 100644 vendor/golang.org/x/telemetry/internal/upload/Doc.txt delete mode 100644 vendor/golang.org/x/telemetry/internal/upload/date.go delete mode 100644 vendor/golang.org/x/telemetry/internal/upload/findwork.go delete mode 100644 vendor/golang.org/x/telemetry/internal/upload/reports.go delete mode 100644 vendor/golang.org/x/telemetry/internal/upload/run.go delete mode 100644 vendor/golang.org/x/telemetry/internal/upload/upload.go delete mode 100644 vendor/golang.org/x/telemetry/mode.go delete mode 100644 vendor/golang.org/x/telemetry/npm delete mode 100644 vendor/golang.org/x/telemetry/npx delete mode 100644 vendor/golang.org/x/telemetry/package-lock.json delete mode 100644 vendor/golang.org/x/telemetry/package.json delete mode 100644 vendor/golang.org/x/telemetry/start.go delete mode 100644 vendor/golang.org/x/telemetry/start_posix.go delete mode 100644 vendor/golang.org/x/telemetry/start_windows.go delete mode 100644 vendor/golang.org/x/telemetry/tsconfig.json delete mode 100644 vendor/golang.org/x/telemetry/types_alias.go delete mode 100644 vendor/golang.org/x/text/LICENSE delete mode 100644 vendor/golang.org/x/text/PATENTS delete mode 100644 vendor/golang.org/x/text/cases/cases.go delete mode 100644 vendor/golang.org/x/text/cases/context.go delete mode 100644 vendor/golang.org/x/text/cases/fold.go delete mode 100644 vendor/golang.org/x/text/cases/icu.go delete mode 100644 vendor/golang.org/x/text/cases/info.go delete mode 100644 vendor/golang.org/x/text/cases/map.go delete mode 100644 vendor/golang.org/x/text/cases/tables10.0.0.go delete mode 100644 vendor/golang.org/x/text/cases/tables11.0.0.go delete mode 100644 vendor/golang.org/x/text/cases/tables12.0.0.go delete mode 100644 vendor/golang.org/x/text/cases/tables13.0.0.go delete mode 100644 vendor/golang.org/x/text/cases/tables15.0.0.go delete mode 100644 vendor/golang.org/x/text/cases/tables9.0.0.go delete mode 100644 vendor/golang.org/x/text/cases/trieval.go delete mode 100644 vendor/golang.org/x/text/internal/internal.go delete mode 100644 vendor/golang.org/x/text/internal/language/common.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact/compact.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact/language.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact/parents.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact/tables.go delete mode 100644 vendor/golang.org/x/text/internal/language/compact/tags.go delete mode 100644 vendor/golang.org/x/text/internal/language/compose.go delete mode 100644 vendor/golang.org/x/text/internal/language/coverage.go delete mode 100644 vendor/golang.org/x/text/internal/language/language.go delete mode 100644 vendor/golang.org/x/text/internal/language/lookup.go delete mode 100644 vendor/golang.org/x/text/internal/language/match.go delete mode 100644 vendor/golang.org/x/text/internal/language/parse.go delete mode 100644 vendor/golang.org/x/text/internal/language/tables.go delete mode 100644 vendor/golang.org/x/text/internal/language/tags.go delete mode 100644 vendor/golang.org/x/text/internal/match.go delete mode 100644 vendor/golang.org/x/text/internal/tag/tag.go delete mode 100644 vendor/golang.org/x/text/language/coverage.go delete mode 100644 vendor/golang.org/x/text/language/doc.go delete mode 100644 vendor/golang.org/x/text/language/language.go delete mode 100644 vendor/golang.org/x/text/language/match.go delete mode 100644 vendor/golang.org/x/text/language/parse.go delete mode 100644 vendor/golang.org/x/text/language/tables.go delete mode 100644 vendor/golang.org/x/text/language/tags.go delete mode 100644 vendor/golang.org/x/text/runes/cond.go delete mode 100644 vendor/golang.org/x/text/runes/runes.go delete mode 100644 vendor/golang.org/x/text/secure/bidirule/bidirule.go delete mode 100644 vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go delete mode 100644 vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go delete mode 100644 vendor/golang.org/x/text/transform/transform.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/bidi.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/bracket.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/core.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/prop.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/tables15.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/trieval.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/composition.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/forminfo.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/input.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/iter.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/normalize.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/readwriter.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/tables10.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/tables11.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/tables12.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/tables13.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/tables15.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/tables9.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/transform.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/trie.go delete mode 100644 vendor/golang.org/x/text/width/kind_string.go delete mode 100644 vendor/golang.org/x/text/width/tables10.0.0.go delete mode 100644 vendor/golang.org/x/text/width/tables11.0.0.go delete mode 100644 vendor/golang.org/x/text/width/tables12.0.0.go delete mode 100644 vendor/golang.org/x/text/width/tables13.0.0.go delete mode 100644 vendor/golang.org/x/text/width/tables15.0.0.go delete mode 100644 vendor/golang.org/x/text/width/tables9.0.0.go delete mode 100644 vendor/golang.org/x/text/width/transform.go delete mode 100644 vendor/golang.org/x/text/width/trieval.go delete mode 100644 vendor/golang.org/x/text/width/width.go delete mode 100644 vendor/golang.org/x/tools/LICENSE delete mode 100644 vendor/golang.org/x/tools/PATENTS delete mode 100644 vendor/golang.org/x/tools/cover/profile.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/analysis.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/diagnostic.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/appends/appends.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/appends/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/assign/assign.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/assign/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/atomic/atomic.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/atomic/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/atomicalign/atomicalign.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/bools/bools.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/buildssa/buildssa.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/cgocall/cgocall_go120.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/cgocall/cgocall_go121.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/composite/composite.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/composite/whitelist.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/copylock/copylock.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/ctrlflow/ctrlflow.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/deepequalerrors/deepequalerrors.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/defers/defers.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/defers/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/directive/directive.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/errorsas/errorsas.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/fieldalignment/fieldalignment.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/findcall/findcall.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/framepointer/framepointer.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/httpresponse/httpresponse.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/ifaceassert/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/internal/analysisutil/util.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/loopclosure/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/lostcancel/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/lostcancel/lostcancel.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/nilfunc/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/nilfunc/nilfunc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/nilness/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/nilness/nilness.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/pkgfact/pkgfact.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/printf/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/printf/types.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/reflectvaluecompare/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/reflectvaluecompare/reflectvaluecompare.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/shadow/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/shadow/shadow.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/shift/dead.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/shift/shift.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/sigchanyzer/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/sigchanyzer/sigchanyzer.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/slog/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/slog/slog.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/sortslice/analyzer.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/stdmethods/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/stringintconv/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/stringintconv/string.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine/testinggoroutine.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine/util.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/tests/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/timeformat/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/timeformat/timeformat.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/unmarshal/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/unmarshal/unmarshal.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/unreachable/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/unreachable/unreachable.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/unsafeptr/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/unsafeptr/unsafeptr.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/unusedresult/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/unusedwrite/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/unusedwrite/unusedwrite.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/validate.go delete mode 100644 vendor/golang.org/x/tools/go/ast/astutil/enclosing.go delete mode 100644 vendor/golang.org/x/tools/go/ast/astutil/imports.go delete mode 100644 vendor/golang.org/x/tools/go/ast/astutil/rewrite.go delete mode 100644 vendor/golang.org/x/tools/go/ast/astutil/util.go delete mode 100644 vendor/golang.org/x/tools/go/ast/inspector/inspector.go delete mode 100644 vendor/golang.org/x/tools/go/ast/inspector/typeof.go delete mode 100644 vendor/golang.org/x/tools/go/buildutil/allpackages.go delete mode 100644 vendor/golang.org/x/tools/go/buildutil/fakecontext.go delete mode 100644 vendor/golang.org/x/tools/go/buildutil/overlay.go delete mode 100644 vendor/golang.org/x/tools/go/buildutil/tags.go delete mode 100644 vendor/golang.org/x/tools/go/buildutil/util.go delete mode 100644 vendor/golang.org/x/tools/go/callgraph/callgraph.go delete mode 100644 vendor/golang.org/x/tools/go/callgraph/cha/cha.go delete mode 100644 vendor/golang.org/x/tools/go/callgraph/util.go delete mode 100644 vendor/golang.org/x/tools/go/callgraph/vta/graph.go delete mode 100644 vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/bits.go delete mode 100644 vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/builder.go delete mode 100644 vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/scope.go delete mode 100644 vendor/golang.org/x/tools/go/callgraph/vta/internal/trie/trie.go delete mode 100644 vendor/golang.org/x/tools/go/callgraph/vta/propagation.go delete mode 100644 vendor/golang.org/x/tools/go/callgraph/vta/utils.go delete mode 100644 vendor/golang.org/x/tools/go/callgraph/vta/vta.go delete mode 100644 vendor/golang.org/x/tools/go/cfg/builder.go delete mode 100644 vendor/golang.org/x/tools/go/cfg/cfg.go delete mode 100644 vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go delete mode 100644 vendor/golang.org/x/tools/go/gcexportdata/importer.go delete mode 100644 vendor/golang.org/x/tools/go/internal/cgo/cgo.go delete mode 100644 vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go delete mode 100644 vendor/golang.org/x/tools/go/loader/doc.go delete mode 100644 vendor/golang.org/x/tools/go/loader/loader.go delete mode 100644 vendor/golang.org/x/tools/go/loader/util.go delete mode 100644 vendor/golang.org/x/tools/go/packages/doc.go delete mode 100644 vendor/golang.org/x/tools/go/packages/external.go delete mode 100644 vendor/golang.org/x/tools/go/packages/golist.go delete mode 100644 vendor/golang.org/x/tools/go/packages/golist_overlay.go delete mode 100644 vendor/golang.org/x/tools/go/packages/loadmode_string.go delete mode 100644 vendor/golang.org/x/tools/go/packages/packages.go delete mode 100644 vendor/golang.org/x/tools/go/packages/visit.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/TODO delete mode 100644 vendor/golang.org/x/tools/go/ssa/block.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/blockopt.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/builder.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/const.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/coretype.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/create.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/doc.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/dom.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/emit.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/func.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/instantiate.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/lift.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/lvalue.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/methods.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/mode.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/print.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/sanity.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/source.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/ssa.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/ssautil/load.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/ssautil/switch.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/ssautil/visit.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/subst.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/task.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/util.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/util_go120.go delete mode 100644 vendor/golang.org/x/tools/go/ssa/wrappers.go delete mode 100644 vendor/golang.org/x/tools/go/types/objectpath/objectpath.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/callee.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/imports.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/map.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/ui.go delete mode 100644 vendor/golang.org/x/tools/imports/forward.go delete mode 100644 vendor/golang.org/x/tools/internal/aliases/aliases.go delete mode 100644 vendor/golang.org/x/tools/internal/aliases/aliases_go121.go delete mode 100644 vendor/golang.org/x/tools/internal/aliases/aliases_go122.go delete mode 100644 vendor/golang.org/x/tools/internal/analysisinternal/analysis.go delete mode 100644 vendor/golang.org/x/tools/internal/analysisinternal/extractdoc.go delete mode 100644 vendor/golang.org/x/tools/internal/event/core/event.go delete mode 100644 vendor/golang.org/x/tools/internal/event/core/export.go delete mode 100644 vendor/golang.org/x/tools/internal/event/core/fast.go delete mode 100644 vendor/golang.org/x/tools/internal/event/doc.go delete mode 100644 vendor/golang.org/x/tools/internal/event/event.go delete mode 100644 vendor/golang.org/x/tools/internal/event/keys/keys.go delete mode 100644 vendor/golang.org/x/tools/internal/event/keys/standard.go delete mode 100644 vendor/golang.org/x/tools/internal/event/keys/util.go delete mode 100644 vendor/golang.org/x/tools/internal/event/label/label.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/bimport.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/exportdata.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/iexport.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/iimport.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/support_go118.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/unified_no.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go delete mode 100644 vendor/golang.org/x/tools/internal/gocommand/invoke.go delete mode 100644 vendor/golang.org/x/tools/internal/gocommand/vendor.go delete mode 100644 vendor/golang.org/x/tools/internal/gocommand/version.go delete mode 100644 vendor/golang.org/x/tools/internal/gopathwalk/walk.go delete mode 100644 vendor/golang.org/x/tools/internal/imports/fix.go delete mode 100644 vendor/golang.org/x/tools/internal/imports/imports.go delete mode 100644 vendor/golang.org/x/tools/internal/imports/mod.go delete mode 100644 vendor/golang.org/x/tools/internal/imports/mod_cache.go delete mode 100644 vendor/golang.org/x/tools/internal/imports/sortimports.go delete mode 100644 vendor/golang.org/x/tools/internal/packagesinternal/packages.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/codes.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/decoder.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/doc.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/encoder.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/flags.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/reloc.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/support.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/sync.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go delete mode 100644 vendor/golang.org/x/tools/internal/stdlib/manifest.go delete mode 100644 vendor/golang.org/x/tools/internal/stdlib/stdlib.go delete mode 100644 vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/common.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/coretype.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/free.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/normalize.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/termlist.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/typeterm.go delete mode 100644 vendor/golang.org/x/tools/internal/typesinternal/errorcode.go delete mode 100644 vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go delete mode 100644 vendor/golang.org/x/tools/internal/typesinternal/recv.go delete mode 100644 vendor/golang.org/x/tools/internal/typesinternal/toonew.go delete mode 100644 vendor/golang.org/x/tools/internal/typesinternal/types.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/constraint.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/constraint_go121.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/features.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/gover.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/toolchain.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/toolchain_go119.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/toolchain_go120.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/toolchain_go121.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/types.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/types_go121.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/types_go122.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/versions.go delete mode 100644 vendor/golang.org/x/vuln/LICENSE delete mode 100644 vendor/golang.org/x/vuln/PATENTS delete mode 100644 vendor/golang.org/x/vuln/cmd/govulncheck/doc.go delete mode 100644 vendor/golang.org/x/vuln/cmd/govulncheck/main.go delete mode 100644 vendor/golang.org/x/vuln/cmd/govulncheck/test_utils.go delete mode 100644 vendor/golang.org/x/vuln/internal/buildinfo/README.md delete mode 100644 vendor/golang.org/x/vuln/internal/buildinfo/additions_buildinfo.go delete mode 100644 vendor/golang.org/x/vuln/internal/buildinfo/additions_scan.go delete mode 100644 vendor/golang.org/x/vuln/internal/buildinfo/buildinfo.go delete mode 100644 vendor/golang.org/x/vuln/internal/client/client.go delete mode 100644 vendor/golang.org/x/vuln/internal/client/index.go delete mode 100644 vendor/golang.org/x/vuln/internal/client/schema.go delete mode 100644 vendor/golang.org/x/vuln/internal/client/source.go delete mode 100644 vendor/golang.org/x/vuln/internal/derrors/derrors.go delete mode 100644 vendor/golang.org/x/vuln/internal/gosym/README.md delete mode 100644 vendor/golang.org/x/vuln/internal/gosym/additions.go delete mode 100644 vendor/golang.org/x/vuln/internal/gosym/pclntab.go delete mode 100644 vendor/golang.org/x/vuln/internal/gosym/symtab.go delete mode 100644 vendor/golang.org/x/vuln/internal/goversion/asm.go delete mode 100644 vendor/golang.org/x/vuln/internal/goversion/exe.go delete mode 100644 vendor/golang.org/x/vuln/internal/goversion/read.go delete mode 100644 vendor/golang.org/x/vuln/internal/govulncheck/govulncheck.go delete mode 100644 vendor/golang.org/x/vuln/internal/govulncheck/handler.go delete mode 100644 vendor/golang.org/x/vuln/internal/govulncheck/jsonhandler.go delete mode 100644 vendor/golang.org/x/vuln/internal/internal.go delete mode 100644 vendor/golang.org/x/vuln/internal/openvex/handler.go delete mode 100644 vendor/golang.org/x/vuln/internal/openvex/vex.go delete mode 100644 vendor/golang.org/x/vuln/internal/osv/osv.go delete mode 100644 vendor/golang.org/x/vuln/internal/osv/review_status.go delete mode 100644 vendor/golang.org/x/vuln/internal/sarif/handler.go delete mode 100644 vendor/golang.org/x/vuln/internal/sarif/sarif.go delete mode 100644 vendor/golang.org/x/vuln/internal/sarif/utils.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/binary.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/color.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/errors.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/extract.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/filepath.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/flags.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/query.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/run.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/source.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/stdlib.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/template.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/text.go delete mode 100644 vendor/golang.org/x/vuln/internal/scan/util.go delete mode 100644 vendor/golang.org/x/vuln/internal/semver/affects.go delete mode 100644 vendor/golang.org/x/vuln/internal/semver/fixed.go delete mode 100644 vendor/golang.org/x/vuln/internal/semver/semver.go delete mode 100644 vendor/golang.org/x/vuln/internal/traces/traces.go delete mode 100644 vendor/golang.org/x/vuln/internal/vulncheck/binary.go delete mode 100644 vendor/golang.org/x/vuln/internal/vulncheck/doc.go delete mode 100644 vendor/golang.org/x/vuln/internal/vulncheck/emit.go delete mode 100644 vendor/golang.org/x/vuln/internal/vulncheck/entries.go delete mode 100644 vendor/golang.org/x/vuln/internal/vulncheck/fetch.go delete mode 100644 vendor/golang.org/x/vuln/internal/vulncheck/packages.go delete mode 100644 vendor/golang.org/x/vuln/internal/vulncheck/slicing.go delete mode 100644 vendor/golang.org/x/vuln/internal/vulncheck/source.go delete mode 100644 vendor/golang.org/x/vuln/internal/vulncheck/utils.go delete mode 100644 vendor/golang.org/x/vuln/internal/vulncheck/vulncheck.go delete mode 100644 vendor/golang.org/x/vuln/internal/vulncheck/witness.go delete mode 100644 vendor/golang.org/x/vuln/internal/web/url.go delete mode 100644 vendor/golang.org/x/vuln/scan/scan.go delete mode 100644 vendor/golang.org/x/xerrors/LICENSE delete mode 100644 vendor/golang.org/x/xerrors/PATENTS delete mode 100644 vendor/golang.org/x/xerrors/README delete mode 100644 vendor/golang.org/x/xerrors/adaptor.go delete mode 100644 vendor/golang.org/x/xerrors/codereview.cfg delete mode 100644 vendor/golang.org/x/xerrors/doc.go delete mode 100644 vendor/golang.org/x/xerrors/errors.go delete mode 100644 vendor/golang.org/x/xerrors/fmt.go delete mode 100644 vendor/golang.org/x/xerrors/format.go delete mode 100644 vendor/golang.org/x/xerrors/frame.go delete mode 100644 vendor/golang.org/x/xerrors/internal/internal.go delete mode 100644 vendor/golang.org/x/xerrors/wrap.go delete mode 100644 vendor/google.golang.org/genproto/googleapis/rpc/LICENSE delete mode 100644 vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go delete mode 100644 vendor/google.golang.org/grpc/AUTHORS delete mode 100644 vendor/google.golang.org/grpc/CODE-OF-CONDUCT.md delete mode 100644 vendor/google.golang.org/grpc/CONTRIBUTING.md delete mode 100644 vendor/google.golang.org/grpc/GOVERNANCE.md delete mode 100644 vendor/google.golang.org/grpc/LICENSE delete mode 100644 vendor/google.golang.org/grpc/MAINTAINERS.md delete mode 100644 vendor/google.golang.org/grpc/Makefile delete mode 100644 vendor/google.golang.org/grpc/NOTICE.txt delete mode 100644 vendor/google.golang.org/grpc/README.md delete mode 100644 vendor/google.golang.org/grpc/SECURITY.md delete mode 100644 vendor/google.golang.org/grpc/attributes/attributes.go delete mode 100644 vendor/google.golang.org/grpc/backoff.go delete mode 100644 vendor/google.golang.org/grpc/backoff/backoff.go delete mode 100644 vendor/google.golang.org/grpc/balancer/balancer.go delete mode 100644 vendor/google.golang.org/grpc/balancer/base/balancer.go delete mode 100644 vendor/google.golang.org/grpc/balancer/base/base.go delete mode 100644 vendor/google.golang.org/grpc/balancer/conn_state_evaluator.go delete mode 100644 vendor/google.golang.org/grpc/balancer/grpclb/state/state.go delete mode 100644 vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go delete mode 100644 vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go delete mode 100644 vendor/google.golang.org/grpc/balancer_wrapper.go delete mode 100644 vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go delete mode 100644 vendor/google.golang.org/grpc/call.go delete mode 100644 vendor/google.golang.org/grpc/channelz/channelz.go delete mode 100644 vendor/google.golang.org/grpc/clientconn.go delete mode 100644 vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/LICENSE delete mode 100644 vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/README.md delete mode 100644 vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/grpc.go delete mode 100644 vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/main.go delete mode 100644 vendor/google.golang.org/grpc/codec.go delete mode 100644 vendor/google.golang.org/grpc/codes/code_string.go delete mode 100644 vendor/google.golang.org/grpc/codes/codes.go delete mode 100644 vendor/google.golang.org/grpc/connectivity/connectivity.go delete mode 100644 vendor/google.golang.org/grpc/credentials/credentials.go delete mode 100644 vendor/google.golang.org/grpc/credentials/insecure/insecure.go delete mode 100644 vendor/google.golang.org/grpc/credentials/tls.go delete mode 100644 vendor/google.golang.org/grpc/dialoptions.go delete mode 100644 vendor/google.golang.org/grpc/doc.go delete mode 100644 vendor/google.golang.org/grpc/encoding/encoding.go delete mode 100644 vendor/google.golang.org/grpc/encoding/encoding_v2.go delete mode 100644 vendor/google.golang.org/grpc/encoding/proto/proto.go delete mode 100644 vendor/google.golang.org/grpc/experimental/stats/metricregistry.go delete mode 100644 vendor/google.golang.org/grpc/experimental/stats/metrics.go delete mode 100644 vendor/google.golang.org/grpc/grpclog/component.go delete mode 100644 vendor/google.golang.org/grpc/grpclog/grpclog.go delete mode 100644 vendor/google.golang.org/grpc/grpclog/internal/grpclog.go delete mode 100644 vendor/google.golang.org/grpc/grpclog/internal/logger.go delete mode 100644 vendor/google.golang.org/grpc/grpclog/internal/loggerv2.go delete mode 100644 vendor/google.golang.org/grpc/grpclog/logger.go delete mode 100644 vendor/google.golang.org/grpc/grpclog/loggerv2.go delete mode 100644 vendor/google.golang.org/grpc/interceptor.go delete mode 100644 vendor/google.golang.org/grpc/internal/backoff/backoff.go delete mode 100644 vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go delete mode 100644 vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go delete mode 100644 vendor/google.golang.org/grpc/internal/balancerload/load.go delete mode 100644 vendor/google.golang.org/grpc/internal/binarylog/binarylog.go delete mode 100644 vendor/google.golang.org/grpc/internal/binarylog/binarylog_testutil.go delete mode 100644 vendor/google.golang.org/grpc/internal/binarylog/env_config.go delete mode 100644 vendor/google.golang.org/grpc/internal/binarylog/method_logger.go delete mode 100644 vendor/google.golang.org/grpc/internal/binarylog/sink.go delete mode 100644 vendor/google.golang.org/grpc/internal/buffer/unbounded.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/channel.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/channelmap.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/funcs.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/logging.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/server.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/socket.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/subchannel.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/syscall_linux.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go delete mode 100644 vendor/google.golang.org/grpc/internal/channelz/trace.go delete mode 100644 vendor/google.golang.org/grpc/internal/credentials/credentials.go delete mode 100644 vendor/google.golang.org/grpc/internal/credentials/spiffe.go delete mode 100644 vendor/google.golang.org/grpc/internal/credentials/syscallconn.go delete mode 100644 vendor/google.golang.org/grpc/internal/credentials/util.go delete mode 100644 vendor/google.golang.org/grpc/internal/envconfig/envconfig.go delete mode 100644 vendor/google.golang.org/grpc/internal/envconfig/observability.go delete mode 100644 vendor/google.golang.org/grpc/internal/envconfig/xds.go delete mode 100644 vendor/google.golang.org/grpc/internal/experimental.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpclog/prefix_logger.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcsync/event.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcsync/oncefunc.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcutil/compressor.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcutil/encode_duration.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcutil/grpcutil.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcutil/metadata.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcutil/method.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcutil/regex.go delete mode 100644 vendor/google.golang.org/grpc/internal/idle/idle.go delete mode 100644 vendor/google.golang.org/grpc/internal/internal.go delete mode 100644 vendor/google.golang.org/grpc/internal/metadata/metadata.go delete mode 100644 vendor/google.golang.org/grpc/internal/pretty/pretty.go delete mode 100644 vendor/google.golang.org/grpc/internal/resolver/config_selector.go delete mode 100644 vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go delete mode 100644 vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go delete mode 100644 vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go delete mode 100644 vendor/google.golang.org/grpc/internal/resolver/unix/unix.go delete mode 100644 vendor/google.golang.org/grpc/internal/serviceconfig/duration.go delete mode 100644 vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go delete mode 100644 vendor/google.golang.org/grpc/internal/stats/labels.go delete mode 100644 vendor/google.golang.org/grpc/internal/stats/metrics_recorder_list.go delete mode 100644 vendor/google.golang.org/grpc/internal/status/status.go delete mode 100644 vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go delete mode 100644 vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go delete mode 100644 vendor/google.golang.org/grpc/internal/tcp_keepalive_others.go delete mode 100644 vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go delete mode 100644 vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/bdp_estimator.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/controlbuf.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/defaults.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/flowcontrol.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/handler_server.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/http2_client.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/http2_server.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/http_util.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/logging.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/networktype/networktype.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/proxy.go delete mode 100644 vendor/google.golang.org/grpc/internal/transport/transport.go delete mode 100644 vendor/google.golang.org/grpc/keepalive/keepalive.go delete mode 100644 vendor/google.golang.org/grpc/mem/buffer_pool.go delete mode 100644 vendor/google.golang.org/grpc/mem/buffer_slice.go delete mode 100644 vendor/google.golang.org/grpc/mem/buffers.go delete mode 100644 vendor/google.golang.org/grpc/metadata/metadata.go delete mode 100644 vendor/google.golang.org/grpc/peer/peer.go delete mode 100644 vendor/google.golang.org/grpc/picker_wrapper.go delete mode 100644 vendor/google.golang.org/grpc/preloader.go delete mode 100644 vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go delete mode 100644 vendor/google.golang.org/grpc/resolver/map.go delete mode 100644 vendor/google.golang.org/grpc/resolver/resolver.go delete mode 100644 vendor/google.golang.org/grpc/resolver_wrapper.go delete mode 100644 vendor/google.golang.org/grpc/rpc_util.go delete mode 100644 vendor/google.golang.org/grpc/server.go delete mode 100644 vendor/google.golang.org/grpc/service_config.go delete mode 100644 vendor/google.golang.org/grpc/serviceconfig/serviceconfig.go delete mode 100644 vendor/google.golang.org/grpc/stats/handlers.go delete mode 100644 vendor/google.golang.org/grpc/stats/stats.go delete mode 100644 vendor/google.golang.org/grpc/status/status.go delete mode 100644 vendor/google.golang.org/grpc/stream.go delete mode 100644 vendor/google.golang.org/grpc/stream_interfaces.go delete mode 100644 vendor/google.golang.org/grpc/tap/tap.go delete mode 100644 vendor/google.golang.org/grpc/trace.go delete mode 100644 vendor/google.golang.org/grpc/trace_notrace.go delete mode 100644 vendor/google.golang.org/grpc/trace_withtrace.go delete mode 100644 vendor/google.golang.org/grpc/version.go delete mode 100644 vendor/google.golang.org/protobuf/LICENSE delete mode 100644 vendor/google.golang.org/protobuf/PATENTS delete mode 100644 vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/init.go delete mode 100644 vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go delete mode 100644 vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/reflect.go delete mode 100644 vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/well_known_types.go delete mode 100644 vendor/google.golang.org/protobuf/cmd/protoc-gen-go/main.go delete mode 100644 vendor/google.golang.org/protobuf/compiler/protogen/protogen.go delete mode 100644 vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go delete mode 100644 vendor/google.golang.org/protobuf/encoding/protojson/decode.go delete mode 100644 vendor/google.golang.org/protobuf/encoding/protojson/doc.go delete mode 100644 vendor/google.golang.org/protobuf/encoding/protojson/encode.go delete mode 100644 vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go delete mode 100644 vendor/google.golang.org/protobuf/encoding/prototext/decode.go delete mode 100644 vendor/google.golang.org/protobuf/encoding/prototext/doc.go delete mode 100644 vendor/google.golang.org/protobuf/encoding/prototext/encode.go delete mode 100644 vendor/google.golang.org/protobuf/encoding/protowire/wire.go delete mode 100644 vendor/google.golang.org/protobuf/internal/descfmt/stringer.go delete mode 100644 vendor/google.golang.org/protobuf/internal/descopts/options.go delete mode 100644 vendor/google.golang.org/protobuf/internal/detrand/rand.go delete mode 100644 vendor/google.golang.org/protobuf/internal/editiondefaults/defaults.go delete mode 100644 vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb delete mode 100644 vendor/google.golang.org/protobuf/internal/editionssupport/editions.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/defval/default.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/json/decode.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/json/decode_number.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/json/decode_string.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/json/decode_token.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/json/encode.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/messageset/messageset.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode_string.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode_token.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/doc.go delete mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/encode.go delete mode 100644 vendor/google.golang.org/protobuf/internal/errors/errors.go delete mode 100644 vendor/google.golang.org/protobuf/internal/errors/is_go112.go delete mode 100644 vendor/google.golang.org/protobuf/internal/errors/is_go113.go delete mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/build.go delete mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc.go delete mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go delete mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go delete mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go delete mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_list_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/editions.go delete mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go delete mode 100644 vendor/google.golang.org/protobuf/internal/filetype/build.go delete mode 100644 vendor/google.golang.org/protobuf/internal/flags/flags.go delete mode 100644 vendor/google.golang.org/protobuf/internal/flags/proto_legacy_disable.go delete mode 100644 vendor/google.golang.org/protobuf/internal/flags/proto_legacy_enable.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/any_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/api_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/doc.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/duration_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/empty_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/field_mask_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/go_features_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/goname.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/map_entry.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/source_context_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/struct_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/timestamp_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/type_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/wrappers.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genid/wrappers_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/api_export.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/checkinit.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_extension.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_field.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_map.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_message.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_messageset.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_tables.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/convert.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/convert_list.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/convert_map.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/decode.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/encode.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/enum.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/extension.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_export.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_file.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_message.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/merge.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/merge_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/message.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/message_reflect.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/validate.go delete mode 100644 vendor/google.golang.org/protobuf/internal/impl/weak.go delete mode 100644 vendor/google.golang.org/protobuf/internal/msgfmt/format.go delete mode 100644 vendor/google.golang.org/protobuf/internal/order/order.go delete mode 100644 vendor/google.golang.org/protobuf/internal/order/range.go delete mode 100644 vendor/google.golang.org/protobuf/internal/pragma/pragma.go delete mode 100644 vendor/google.golang.org/protobuf/internal/set/ints.go delete mode 100644 vendor/google.golang.org/protobuf/internal/strs/strings.go delete mode 100644 vendor/google.golang.org/protobuf/internal/strs/strings_pure.go delete mode 100644 vendor/google.golang.org/protobuf/internal/strs/strings_unsafe_go120.go delete mode 100644 vendor/google.golang.org/protobuf/internal/strs/strings_unsafe_go121.go delete mode 100644 vendor/google.golang.org/protobuf/internal/version/version.go delete mode 100644 vendor/google.golang.org/protobuf/proto/checkinit.go delete mode 100644 vendor/google.golang.org/protobuf/proto/decode.go delete mode 100644 vendor/google.golang.org/protobuf/proto/decode_gen.go delete mode 100644 vendor/google.golang.org/protobuf/proto/doc.go delete mode 100644 vendor/google.golang.org/protobuf/proto/encode.go delete mode 100644 vendor/google.golang.org/protobuf/proto/encode_gen.go delete mode 100644 vendor/google.golang.org/protobuf/proto/equal.go delete mode 100644 vendor/google.golang.org/protobuf/proto/extension.go delete mode 100644 vendor/google.golang.org/protobuf/proto/merge.go delete mode 100644 vendor/google.golang.org/protobuf/proto/messageset.go delete mode 100644 vendor/google.golang.org/protobuf/proto/proto.go delete mode 100644 vendor/google.golang.org/protobuf/proto/proto_methods.go delete mode 100644 vendor/google.golang.org/protobuf/proto/proto_reflect.go delete mode 100644 vendor/google.golang.org/protobuf/proto/reset.go delete mode 100644 vendor/google.golang.org/protobuf/proto/size.go delete mode 100644 vendor/google.golang.org/protobuf/proto/size_gen.go delete mode 100644 vendor/google.golang.org/protobuf/proto/wrappers.go delete mode 100644 vendor/google.golang.org/protobuf/protoadapt/convert.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protodesc/desc.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protodesc/editions.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protodesc/proto.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protopath/path.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protopath/step.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protorange/range.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/methods.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/source.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/type.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value_equal.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value_pure.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe_go120.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe_go121.go delete mode 100644 vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go delete mode 100644 vendor/google.golang.org/protobuf/runtime/protoiface/legacy.go delete mode 100644 vendor/google.golang.org/protobuf/runtime/protoiface/methods.go delete mode 100644 vendor/google.golang.org/protobuf/runtime/protoimpl/impl.go delete mode 100644 vendor/google.golang.org/protobuf/runtime/protoimpl/version.go delete mode 100644 vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go delete mode 100644 vendor/google.golang.org/protobuf/types/dynamicpb/dynamic.go delete mode 100644 vendor/google.golang.org/protobuf/types/dynamicpb/types.go delete mode 100644 vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.pb.go delete mode 100644 vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go delete mode 100644 vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go delete mode 100644 vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go delete mode 100644 vendor/google.golang.org/protobuf/types/pluginpb/plugin.pb.go delete mode 100644 vendor/gopkg.in/ini.v1/.editorconfig delete mode 100644 vendor/gopkg.in/ini.v1/.gitignore delete mode 100644 vendor/gopkg.in/ini.v1/.golangci.yml delete mode 100644 vendor/gopkg.in/ini.v1/LICENSE delete mode 100644 vendor/gopkg.in/ini.v1/Makefile delete mode 100644 vendor/gopkg.in/ini.v1/README.md delete mode 100644 vendor/gopkg.in/ini.v1/codecov.yml delete mode 100644 vendor/gopkg.in/ini.v1/data_source.go delete mode 100644 vendor/gopkg.in/ini.v1/deprecated.go delete mode 100644 vendor/gopkg.in/ini.v1/error.go delete mode 100644 vendor/gopkg.in/ini.v1/file.go delete mode 100644 vendor/gopkg.in/ini.v1/helper.go delete mode 100644 vendor/gopkg.in/ini.v1/ini.go delete mode 100644 vendor/gopkg.in/ini.v1/key.go delete mode 100644 vendor/gopkg.in/ini.v1/parser.go delete mode 100644 vendor/gopkg.in/ini.v1/section.go delete mode 100644 vendor/gopkg.in/ini.v1/struct.go delete mode 100644 vendor/gopkg.in/yaml.v2/.travis.yml delete mode 100644 vendor/gopkg.in/yaml.v2/LICENSE delete mode 100644 vendor/gopkg.in/yaml.v2/LICENSE.libyaml delete mode 100644 vendor/gopkg.in/yaml.v2/NOTICE delete mode 100644 vendor/gopkg.in/yaml.v2/README.md delete mode 100644 vendor/gopkg.in/yaml.v2/apic.go delete mode 100644 vendor/gopkg.in/yaml.v2/decode.go delete mode 100644 vendor/gopkg.in/yaml.v2/emitterc.go delete mode 100644 vendor/gopkg.in/yaml.v2/encode.go delete mode 100644 vendor/gopkg.in/yaml.v2/parserc.go delete mode 100644 vendor/gopkg.in/yaml.v2/readerc.go delete mode 100644 vendor/gopkg.in/yaml.v2/resolve.go delete mode 100644 vendor/gopkg.in/yaml.v2/scannerc.go delete mode 100644 vendor/gopkg.in/yaml.v2/sorter.go delete mode 100644 vendor/gopkg.in/yaml.v2/writerc.go delete mode 100644 vendor/gopkg.in/yaml.v2/yaml.go delete mode 100644 vendor/gopkg.in/yaml.v2/yamlh.go delete mode 100644 vendor/gopkg.in/yaml.v2/yamlprivateh.go delete mode 100644 vendor/gopkg.in/yaml.v3/LICENSE delete mode 100644 vendor/gopkg.in/yaml.v3/NOTICE delete mode 100644 vendor/gopkg.in/yaml.v3/README.md delete mode 100644 vendor/gopkg.in/yaml.v3/apic.go delete mode 100644 vendor/gopkg.in/yaml.v3/decode.go delete mode 100644 vendor/gopkg.in/yaml.v3/emitterc.go delete mode 100644 vendor/gopkg.in/yaml.v3/encode.go delete mode 100644 vendor/gopkg.in/yaml.v3/parserc.go delete mode 100644 vendor/gopkg.in/yaml.v3/readerc.go delete mode 100644 vendor/gopkg.in/yaml.v3/resolve.go delete mode 100644 vendor/gopkg.in/yaml.v3/scannerc.go delete mode 100644 vendor/gopkg.in/yaml.v3/sorter.go delete mode 100644 vendor/gopkg.in/yaml.v3/writerc.go delete mode 100644 vendor/gopkg.in/yaml.v3/yaml.go delete mode 100644 vendor/gopkg.in/yaml.v3/yamlh.go delete mode 100644 vendor/gopkg.in/yaml.v3/yamlprivateh.go delete mode 100644 vendor/honnef.co/go/tools/LICENSE delete mode 100644 vendor/honnef.co/go/tools/LICENSE-THIRD-PARTY delete mode 100644 vendor/honnef.co/go/tools/analysis/callcheck/callcheck.go delete mode 100644 vendor/honnef.co/go/tools/analysis/code/code.go delete mode 100644 vendor/honnef.co/go/tools/analysis/code/visit.go delete mode 100644 vendor/honnef.co/go/tools/analysis/edit/edit.go delete mode 100644 vendor/honnef.co/go/tools/analysis/facts/deprecated/deprecated.go delete mode 100644 vendor/honnef.co/go/tools/analysis/facts/directives/directives.go delete mode 100644 vendor/honnef.co/go/tools/analysis/facts/generated/generated.go delete mode 100644 vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go delete mode 100644 vendor/honnef.co/go/tools/analysis/facts/purity/purity.go delete mode 100644 vendor/honnef.co/go/tools/analysis/facts/tokenfile/token.go delete mode 100644 vendor/honnef.co/go/tools/analysis/facts/typedness/typedness.go delete mode 100644 vendor/honnef.co/go/tools/analysis/lint/lint.go delete mode 100644 vendor/honnef.co/go/tools/analysis/report/report.go delete mode 100644 vendor/honnef.co/go/tools/config/config.go delete mode 100644 vendor/honnef.co/go/tools/config/example.conf delete mode 100644 vendor/honnef.co/go/tools/go/ast/astutil/upstream.go delete mode 100644 vendor/honnef.co/go/tools/go/ast/astutil/util.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/LICENSE delete mode 100644 vendor/honnef.co/go/tools/go/ir/UPSTREAM delete mode 100644 vendor/honnef.co/go/tools/go/ir/blockopt.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/builder.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/const.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/create.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/doc.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/dom.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/emit.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/exits.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/func.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/html.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/irutil/load.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/irutil/loops.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/irutil/stub.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/irutil/switch.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/irutil/terminates.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/irutil/util.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/irutil/visit.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/lift.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/lvalue.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/methods.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/mode.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/print.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/sanity.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/source.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/ssa.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/util.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/wrappers.go delete mode 100644 vendor/honnef.co/go/tools/go/ir/write.go delete mode 100644 vendor/honnef.co/go/tools/go/types/typeutil/ext.go delete mode 100644 vendor/honnef.co/go/tools/go/types/typeutil/typeparams.go delete mode 100644 vendor/honnef.co/go/tools/go/types/typeutil/upstream.go delete mode 100644 vendor/honnef.co/go/tools/go/types/typeutil/util.go delete mode 100644 vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go delete mode 100644 vendor/honnef.co/go/tools/internal/sharedcheck/lint.go delete mode 100644 vendor/honnef.co/go/tools/knowledge/arg.go delete mode 100644 vendor/honnef.co/go/tools/knowledge/deprecated.go delete mode 100644 vendor/honnef.co/go/tools/knowledge/doc.go delete mode 100644 vendor/honnef.co/go/tools/knowledge/signatures.go delete mode 100644 vendor/honnef.co/go/tools/knowledge/targets.go delete mode 100644 vendor/honnef.co/go/tools/pattern/convert.go delete mode 100644 vendor/honnef.co/go/tools/pattern/doc.go delete mode 100644 vendor/honnef.co/go/tools/pattern/lexer.go delete mode 100644 vendor/honnef.co/go/tools/pattern/match.go delete mode 100644 vendor/honnef.co/go/tools/pattern/parser.go delete mode 100644 vendor/honnef.co/go/tools/pattern/pattern.go delete mode 100644 vendor/honnef.co/go/tools/printf/fuzz.go delete mode 100644 vendor/honnef.co/go/tools/printf/printf.go delete mode 100644 vendor/honnef.co/go/tools/simple/analysis.go delete mode 100644 vendor/honnef.co/go/tools/simple/doc.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1000/s1000.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1001/s1001.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1002/s1002.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1003/s1003.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1004/s1004.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1005/s1005.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1006/s1006.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1007/s1007.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1008/s1008.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1009/s1009.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1010/s1010.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1011/s1011.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1012/s1012.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1016/s1016.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1017/s1017.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1018/s1018.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1019/s1019.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1020/s1020.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1021/s1021.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1023/s1023.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1024/s1024.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1025/s1025.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1028/s1028.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1029/s1029.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1030/s1030.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1031/s1031.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1032/s1032.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1033/s1033.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1034/s1034.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1035/s1035.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1036/s1036.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1037/s1037.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1038/s1038.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1039/s1039.go delete mode 100644 vendor/honnef.co/go/tools/simple/s1040/s1040.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/analysis.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/doc.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/fakejson/encode.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/fakereflect/fakereflect.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/fakexml/marshal.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/fakexml/typeinfo.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/fakexml/xml.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1000/sa1000.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1001/sa1001.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1002/sa1002.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1003/sa1003.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1004/sa1004.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1005/sa1005.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1006/sa1006.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1007/sa1007.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1008/sa1008.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1010/sa1010.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1011/sa1011.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1012/sa1012.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1013/sa1013.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1014/sa1014.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1015/sa1015.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1016/sa1016.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1017/sa1017.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1018/sa1018.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1019/sa1019.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1020/sa1020.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1021/sa1021.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1023/sa1023.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1024/sa1024.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1025/sa1025.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1026/sa1026.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1027/sa1027.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1028/sa1028.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1029/sa1029.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1030/sa1030.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1031/sa1031.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa1032/sa1032.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa2000/sa2000.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa2001/sa2001.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa2002/sa2002.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa2003/sa2003.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa3000/sa3000.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa3001/sa3001.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4000/sa4000.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4001/sa4001.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4003/sa4003.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4004/sa4004.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4005/sa4005.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4006/sa4006.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4008/sa4008.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4009/sa4009.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4010/sa4010.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4011/sa4011.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4012/sa4012.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4013/sa4013.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4014/sa4014.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4015/sa4015.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4016/sa4016.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4017/sa4017.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4018/sa4018.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4019/sa4019.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4020/sa4020.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4021/sa4021.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4022/sa4022.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4024/sa4024.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4025/sa4025.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4026/sa4026.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4027/sa4027.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4028/sa4028.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4029/sa4029.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4030/sa4030.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4031/sa4031.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa4032/sa4032.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5000/sa5000.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5001/sa5001.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5002/sa5002.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5003/sa5003.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5004/sa5004.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5005/sa5005.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5007/sa5007.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5008/sa5008.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5008/structtag.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5010/sa5010.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5011/sa5011.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa5012/sa5012.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa6000/sa6000.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa6001/sa6001.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa6002/sa6002.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa6003/sa6003.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa6005/sa6005.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa6006/sa6006.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa9001/sa9001.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa9002/sa9002.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa9003/sa9003.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa9004/sa9004.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa9005/sa9005.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa9006/sa9006.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa9007/sa9007.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa9008/sa9008.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/sa9009/sa9009.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/analysis.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/doc.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1000/st1000.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1001/st1001.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1003/st1003.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1005/st1005.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1006/st1006.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1008/st1008.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1011/st1011.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1012/st1012.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1013/st1013.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1015/st1015.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1016/st1016.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1017/st1017.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1018/st1018.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1019/st1019.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1020/st1020.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1021/st1021.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1022/st1022.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/st1023/st1023.go delete mode 100644 vendor/honnef.co/go/tools/unused/implements.go delete mode 100644 vendor/honnef.co/go/tools/unused/runtime.go delete mode 100644 vendor/honnef.co/go/tools/unused/serialize.go delete mode 100644 vendor/honnef.co/go/tools/unused/unused.go delete mode 100644 vendor/modules.txt delete mode 100644 vendor/mvdan.cc/gofumpt/LICENSE delete mode 100644 vendor/mvdan.cc/gofumpt/LICENSE.google delete mode 100644 vendor/mvdan.cc/gofumpt/format/format.go delete mode 100644 vendor/mvdan.cc/gofumpt/format/rewrite.go delete mode 100644 vendor/mvdan.cc/gofumpt/format/simplify.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/doc.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/html.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/markdown.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/parse.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/print.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/std.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/text.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/format/format.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/format/internal.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/comment.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/gobuild.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/nodes.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/printer.go delete mode 100644 vendor/mvdan.cc/gofumpt/internal/version/version.go delete mode 100644 vendor/mvdan.cc/unparam/LICENSE delete mode 100644 vendor/mvdan.cc/unparam/check/check.go diff --git a/vendor/4d63.com/gocheckcompilerdirectives/LICENSE b/vendor/4d63.com/gocheckcompilerdirectives/LICENSE deleted file mode 100644 index 3f12625b0..000000000 --- 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 19948c454..000000000 --- a/vendor/4d63.com/gocheckcompilerdirectives/checkcompilerdirectives/checkcompilerdirectives.go +++ /dev/null @@ -1,105 +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 -} - -var known = []string{ - // 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 - "binary", - "build", - "buildsomethingelse", - "cgo_dynamic_linker", - "cgo_export_dynamic", - "cgo_export_static", - "cgo_import_dynamic", - "cgo_import_static", - "cgo_ldflag", - "cgo_unsafe_args", - "embed", - "generate", - "linkname", - "name", - "nocheckptr", - "noescape", - "noinline", - "nointerface", - "norace", - "nosplit", - "notinheap", - "nowritebarrier", - "nowritebarrierrec", - "systemstack", - "uintptrescapes", - "uintptrkeepalive", - "yeswritebarrierrec", -} diff --git a/vendor/4d63.com/gochecknoglobals/LICENSE b/vendor/4d63.com/gochecknoglobals/LICENSE deleted file mode 100644 index c401e6608..000000000 --- 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 edf9193ec..000000000 --- a/vendor/4d63.com/gochecknoglobals/checknoglobals/check_no_globals.go +++ /dev/null @@ -1,200 +0,0 @@ -package checknoglobals - -import ( - "flag" - "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, - Flags: flags(), - RunDespiteErrors: true, - } -} - -func flags() flag.FlagSet { - flags := flag.NewFlagSet("", flag.ExitOnError) - flags.Bool("t", false, "Include tests") - - return *flags -} - -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) { - includeTests := pass.Analyzer.Flags.Lookup("t").Value.(flag.Getter).Get().(bool) - - for _, file := range pass.Files { - filename := pass.Fset.Position(file.Pos()).Filename - if !strings.HasSuffix(filename, ".go") { - continue - } - if !includeTests && strings.HasSuffix(filename, "_test.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/github.com/4meepo/tagalign/.gitignore b/vendor/github.com/4meepo/tagalign/.gitignore deleted file mode 100644 index e37bb52e4..000000000 --- a/vendor/github.com/4meepo/tagalign/.gitignore +++ /dev/null @@ -1,75 +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 - -# 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 e65f604fe..000000000 --- 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 e7b6f6800..000000000 --- a/vendor/github.com/4meepo/tagalign/.goreleaser.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -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/ \ No newline at end of file diff --git a/vendor/github.com/4meepo/tagalign/LICENSE b/vendor/github.com/4meepo/tagalign/LICENSE deleted file mode 100644 index da3ae8270..000000000 --- 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 614e7773c..000000000 --- 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 9d04dccbf..000000000 --- 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 ddec98da7..000000000 --- a/vendor/github.com/4meepo/tagalign/options.go +++ /dev/null @@ -1,37 +0,0 @@ -package tagalign - -type Option func(*Helper) - -// WithMode specify the mode of tagalign. -func WithMode(mode Mode) Option { - return func(h *Helper) { - h.mode = mode - } -} - -// 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 4734b5666..000000000 --- a/vendor/github.com/4meepo/tagalign/tagalign.go +++ /dev/null @@ -1,459 +0,0 @@ -package tagalign - -import ( - "fmt" - "go/ast" - "go/token" - "log" - "reflect" - "sort" - "strconv" - "strings" - - "github.com/fatih/structtag" - - "golang.org/x/tools/go/analysis" -) - -type Mode int - -const ( - StandaloneMode Mode = iota - GolangciLintMode -) - -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) []Issue { - var issues []Issue - for _, f := range pass.Files { - h := &Helper{ - mode: StandaloneMode, - 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 nil - } - - ast.Inspect(f, func(n ast.Node) bool { - h.find(pass, n) - return true - }) - h.Process(pass) - issues = append(issues, h.issues...) - } - return issues -} - -type Helper struct { - mode Mode - - 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. - issues []Issue -} - -// Issue is used to integrate with golangci-lint's inline auto fix. -type Issue struct { - Pos token.Position - Message string - InlineFix InlineFix -} -type InlineFix struct { - StartCol int // zero-based - Length int - NewString string -} - -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, startCol int, msg, replaceStr string) { - if w.mode == GolangciLintMode { - iss := Issue{ - Pos: pass.Fset.Position(field.Tag.Pos()), - Message: msg, - InlineFix: InlineFix{ - StartCol: startCol, - Length: len(field.Tag.Value), - NewString: replaceStr, - }, - } - w.issues = append(w.issues, iss) - } - - if w.mode == StandaloneMode { - 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), - }, - }, - }, - }, - }) - } -} - -func (w *Helper) Process(pass *analysis.Pass) { //nolint:gocognit - // 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, column, 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, column, 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) - sortBy(w.fixedTagOrder, tags) - } - for _, t := range tags.Tags() { - addKey(t.Key) - } - tagsGroup = append(tagsGroup, tags.Tags()) - - i++ - } - - if w.sort && StrictStyle == w.style { - sortAllKeys(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, offsets[i], msg, newTagValue) - } - } - - // process single fields - for _, field := range w.singleFields { - column := pass.Fset.Position(field.Tag.Pos()).Column - 1 - tag, err := strconv.Unquote(field.Tag.Value) - if err != nil { - w.report(pass, field, column, errTagValueSyntax, field.Tag.Value) - continue - } - - tags, err := structtag.Parse(tag) - if err != nil { - w.report(pass, field, column, err.Error(), field.Tag.Value) - continue - } - originalTags := append([]*structtag.Tag(nil), tags.Tags()...) - if w.sort { - sortBy(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, column, msg, newTagValue) - } -} - -// Issues returns all issues found by the analyzer. -// It is used to integrate with golangci-lint. -func (w *Helper) Issues() []Issue { - log.Println("tagalign 's Issues() should only be called in golangci-lint mode") - return w.issues -} - -// sortBy sorts tags by fixed order. -// If a tag is not in the fixed order, it will be sorted by name. -func sortBy(fixedOrder []string, tags *structtag.Tags) { - // sort by fixed order - sort.Slice(tags.Tags(), func(i, j int) bool { - ti := tags.Tags()[i] - tj := tags.Tags()[j] - - oi := findIndex(fixedOrder, ti.Key) - oj := findIndex(fixedOrder, tj.Key) - - if oi == -1 && oj == -1 { - return ti.Key < tj.Key - } - - if oi == -1 { - return false - } - - if oj == -1 { - return true - } - - return oi < oj - }) -} - -func sortAllKeys(fixedOrder []string, keys []string) { - sort.Slice(keys, func(i, j int) bool { - oi := findIndex(fixedOrder, keys[i]) - oj := findIndex(fixedOrder, keys[j]) - - if oi == -1 && oj == -1 { - return keys[i] < keys[j] - } - - if oi == -1 { - return false - } - - if oj == -1 { - return true - } - - return oi < oj - }) -} - -func findIndex(s []string, e string) int { - for i, a := range s { - if a == e { - return i - } - } - return -1 -} - -func alignFormat(length int) string { - return "%" + fmt.Sprintf("-%ds", length) -} - -func max(a, b int) int { - if a > b { - return a - } - return b -} - -func removeField(fields []*ast.Field, index int) []*ast.Field { - if index < 0 || index >= len(fields) { - return fields - } - - return append(fields[:index], fields[index+1:]...) -} diff --git a/vendor/github.com/Abirdcfly/dupword/.gitignore b/vendor/github.com/Abirdcfly/dupword/.gitignore deleted file mode 100644 index b5109d2bb..000000000 --- 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 c3401787a..000000000 --- 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 afa64c6e1..000000000 --- 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 e6c5b919f..000000000 --- a/vendor/github.com/Abirdcfly/dupword/README.md +++ /dev/null @@ -1,153 +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) - -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 - -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 6838d7e75..000000000 --- a/vendor/github.com/Abirdcfly/dupword/dupword.go +++ /dev/null @@ -1,343 +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 that duplicate words -// int 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 = `//` -) - -var ( - defaultWord = []string{} - // defaultWord = []string{"the", "and", "a"} - ignoreWord = map[string]bool{} -) - -type analyzer struct { - KeyWord []string -} - -func (a *analyzer) String() string { - return strings.Join(a.KeyWord, ",") -} - -func (a *analyzer) Set(w string) error { - if len(w) != 0 { - a.KeyWord = make([]string, 0) - a.KeyWord = append(a.KeyWord, strings.Split(w, ",")...) - } - return nil -} - -type ignore struct { -} - -func (a *ignore) String() string { - t := make([]string, 0, len(ignoreWord)) - for k := range ignoreWord { - t = append(t, k) - } - return strings.Join(t, ",") -} - -func (a *ignore) Set(w string) error { - for _, k := range strings.Split(w, ",") { - ignoreWord[k] = true - } - return nil -} - -// for test only -func ClearIgnoreWord() { - ignoreWord = map[string]bool{} -} - -func NewAnalyzer() *analysis.Analyzer { - ignore := &ignore{} - analyzer := &analyzer{KeyWord: defaultWord} - 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, "keyword", "keywords for detecting duplicate words") - a.Flags.Var(ignore, "ignore", "ignore words") - a.Flags.Var(version{}, "V", "print version and exit") - return a -} - -func (a *analyzer) run(pass *analysis.Pass) (interface{}, error) { - for _, file := range pass.Files { - a.fixDuplicateWordInComment(pass, file) - } - 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 checked line. key is the keyword to check. empty means just check duplicate word. -func 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 !ExcludeWords(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 !ExcludeWords(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.KeyWord { - updateOne, _, findOne := CheckOneKey(raw, key) - if findOne { - raw = updateOne - find = findOne - update = updateOne - if keyword == "" { - keyword = key - } else { - keyword = keyword + "," + key - } - } - } - if len(a.KeyWord) == 0 { - return CheckOneKey(raw, "") - } - return -} - -// ExcludeWords determines whether duplicate words should be reported, -// -// e.g. %s, should not be reported. -func 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 := ignoreWord[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:") -} diff --git a/vendor/github.com/Abirdcfly/dupword/version.go b/vendor/github.com/Abirdcfly/dupword/version.go deleted file mode 100644 index 9d892d0c9..000000000 --- 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/Antonboom/errname/LICENSE b/vendor/github.com/Antonboom/errname/LICENSE deleted file mode 100644 index e2002e4d4..000000000 --- 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 aa8522510..000000000 --- a/vendor/github.com/Antonboom/errname/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,135 +0,0 @@ -package analyzer - -import ( - "fmt" - "go/ast" - "go/token" - "strconv" - "strings" - "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}, - } -} - -type stringSet = map[string]struct{} - -var ( - importNodes = []ast.Node{(*ast.ImportSpec)(nil)} - typeNodes = []ast.Node{(*ast.TypeSpec)(nil)} - funcNodes = []ast.Node{(*ast.FuncDecl)(nil)} -) - -func run(pass *analysis.Pass) (interface{}, error) { - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - pkgAliases := map[string]string{} - insp.Preorder(importNodes, func(node ast.Node) { - i := node.(*ast.ImportSpec) - if n := i.Name; n != nil && i.Path != nil { - if path, err := strconv.Unquote(i.Path.Value); err == nil { - pkgAliases[n.Name] = getPkgFromPath(path) - } - } - }) - - allTypes := stringSet{} - typesSpecs := map[string]*ast.TypeSpec{} - insp.Preorder(typeNodes, func(node ast.Node) { - t := node.(*ast.TypeSpec) - allTypes[t.Name.Name] = struct{}{} - typesSpecs[t.Name.Name] = t - }) - - errorTypes := stringSet{} - insp.Preorder(funcNodes, func(node ast.Node) { - f := node.(*ast.FuncDecl) - t, ok := isMethodError(f) - if !ok { - return - } - errorTypes[t] = struct{}{} - - tSpec, ok := typesSpecs[t] - if !ok { - panic(fmt.Sprintf("no specification for type %q", t)) - } - - if _, ok := tSpec.Type.(*ast.ArrayType); ok { - if !isValidErrorArrayTypeName(t) { - reportAboutErrorType(pass, tSpec.Pos(), t, true) - } - } else if !isValidErrorTypeName(t) { - reportAboutErrorType(pass, tSpec.Pos(), t, false) - } - }) - - errorFuncs := stringSet{} - insp.Preorder(funcNodes, func(node ast.Node) { - f := node.(*ast.FuncDecl) - if isFuncReturningErr(f.Type, allTypes, errorTypes) { - errorFuncs[f.Name.Name] = struct{}{} - } - }) - - inspectPkgLevelVarsOnly := func(node ast.Node) bool { - switch v := node.(type) { - case *ast.FuncDecl: - return false - - case *ast.ValueSpec: - if name, ok := isSentinelError(v, pkgAliases, allTypes, errorTypes, errorFuncs); ok && !isValidErrorVarName(name) { - reportAboutErrorVar(pass, v.Pos(), name) - } - } - return true - } - for _, f := range pass.Files { - ast.Inspect(f, inspectPkgLevelVarsOnly) - } - - return nil, nil //nolint:nilnil -} - -func reportAboutErrorType(pass *analysis.Pass, typePos token.Pos, typeName string, isArrayType bool) { - var form string - if unicode.IsLower([]rune(typeName)[0]) { - form = "xxxError" - } else { - form = "XxxError" - } - - if isArrayType { - form += "s" - } - pass.Reportf(typePos, "the type name `%s` should conform to the `%s` format", typeName, form) -} - -func reportAboutErrorVar(pass *analysis.Pass, pos token.Pos, varName string) { - var form string - if unicode.IsLower([]rune(varName)[0]) { - form = "errXxx" - } else { - form = "ErrXxx" - } - pass.Reportf(pos, "the variable name `%s` should conform to the `%s` format", varName, form) -} - -func getPkgFromPath(p string) string { - idx := strings.LastIndex(p, "/") - if idx == -1 { - return p - } - return p[idx+1:] -} 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 06f8d61d8..000000000 --- a/vendor/github.com/Antonboom/errname/pkg/analyzer/facts.go +++ /dev/null @@ -1,272 +0,0 @@ -package analyzer - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "strings" - "unicode" -) - -func isMethodError(f *ast.FuncDecl) (typeName string, ok bool) { - if f.Recv == nil || len(f.Recv.List) != 1 { - return "", false - } - if f.Name == nil || f.Name.Name != "Error" { - return "", false - } - - if f.Type == nil || f.Type.Results == nil || len(f.Type.Results.List) != 1 { - return "", false - } - - returnType, ok := f.Type.Results.List[0].Type.(*ast.Ident) - if !ok { - return "", false - } - - var receiverType string - - unwrapIdentName := func(e ast.Expr) string { - switch v := e.(type) { - case *ast.Ident: - return v.Name - case *ast.IndexExpr: - if i, ok := v.X.(*ast.Ident); ok { - return i.Name - } - case *ast.IndexListExpr: - if i, ok := v.X.(*ast.Ident); ok { - return i.Name - } - } - panic(fmt.Errorf("unsupported Error() receiver type %q", types.ExprString(e))) - } - - switch rt := f.Recv.List[0].Type; v := rt.(type) { - case *ast.Ident, *ast.IndexExpr, *ast.IndexListExpr: // SomeError, SomeError[T], SomeError[T1, T2, ...] - receiverType = unwrapIdentName(rt) - - case *ast.StarExpr: // *SomeError, *SomeError[T], *SomeError[T1, T2, ...] - receiverType = unwrapIdentName(v.X) - } - - return receiverType, returnType.Name == "string" -} - -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 { - return false - } - return words[len(words)-1] == "errors" -} - -func isFuncReturningErr(fType *ast.FuncType, allTypes, errorTypes stringSet) bool { - if fType == nil || fType.Results == nil || len(fType.Results.List) != 1 { - return false - } - - var returnTypeName string - switch rt := fType.Results.List[0].Type.(type) { - case *ast.Ident: - returnTypeName = rt.Name - case *ast.StarExpr: - if i, ok := rt.X.(*ast.Ident); ok { - returnTypeName = i.Name - } - } - - return isErrorType(returnTypeName, allTypes, errorTypes) -} - -func isErrorType(tName string, allTypes, errorTypes stringSet) bool { - _, isUserType := allTypes[tName] - _, isErrType := errorTypes[tName] - return isErrType || (tName == "error" && !isUserType) -} - -var knownErrConstructors = stringSet{ - "fmt.Errorf": {}, - "errors.Errorf": {}, - "errors.New": {}, - "errors.Newf": {}, - "errors.NewWithDepth": {}, - "errors.NewWithDepthf": {}, - "errors.NewAssertionErrorWithWrappedErrf": {}, -} - -func isSentinelError( //nolint:gocognit,gocyclo - v *ast.ValueSpec, - pkgAliases map[string]string, - allTypes, errorTypes, errorFuncs stringSet, -) (varName string, ok bool) { - if len(v.Names) != 1 { - return "", false - } - varName = v.Names[0].Name - - switch vv := v.Type.(type) { - // var ErrEndOfFile error - // var ErrEndOfFile SomeErrType - case *ast.Ident: - if isErrorType(vv.Name, allTypes, errorTypes) { - return varName, true - } - - // var ErrEndOfFile *SomeErrType - case *ast.StarExpr: - if i, ok := vv.X.(*ast.Ident); ok && isErrorType(i.Name, allTypes, errorTypes) { - return varName, true - } - } - - if len(v.Values) != 1 { - return "", false - } - - switch vv := v.Values[0].(type) { - case *ast.CallExpr: - switch fun := vv.Fun.(type) { - // var ErrEndOfFile = errors.New("end of file") - case *ast.SelectorExpr: - pkg, ok := fun.X.(*ast.Ident) - if !ok { - return "", false - } - pkgFun := fun.Sel - - pkgName := pkg.Name - if a, ok := pkgAliases[pkgName]; ok { - pkgName = a - } - - _, ok = knownErrConstructors[pkgName+"."+pkgFun.Name] - return varName, ok - - // var ErrEndOfFile = newErrEndOfFile() - // var ErrEndOfFile = new(EndOfFileError) - // const ErrEndOfFile = constError("end of file") - // var statusCodeError = new(SomePtrError[string]) - case *ast.Ident: - if isErrorType(fun.Name, allTypes, errorTypes) { - return varName, true - } - - if _, ok := errorFuncs[fun.Name]; ok { - return varName, true - } - - if fun.Name == "new" && len(vv.Args) == 1 { - switch i := vv.Args[0].(type) { - case *ast.Ident: - return varName, isErrorType(i.Name, allTypes, errorTypes) - case *ast.IndexExpr: - if ii, ok := i.X.(*ast.Ident); ok { - return varName, isErrorType(ii.Name, allTypes, errorTypes) - } - } - } - - // var ErrEndOfFile = func() error { ... } - case *ast.FuncLit: - return varName, isFuncReturningErr(fun.Type, allTypes, errorTypes) - } - - // var ErrEndOfFile = &EndOfFileError{} - // var ErrOK = &SomePtrError[string]{Code: "200 OK"} - case *ast.UnaryExpr: - if vv.Op == token.AND { // & - if lit, ok := vv.X.(*ast.CompositeLit); ok { - switch i := lit.Type.(type) { - case *ast.Ident: - return varName, isErrorType(i.Name, allTypes, errorTypes) - case *ast.IndexExpr: - if ii, ok := i.X.(*ast.Ident); ok { - return varName, isErrorType(ii.Name, allTypes, errorTypes) - } - } - } - } - - // var ErrEndOfFile = EndOfFileError{} - // var ErrNotFound = SomeError[string]{Code: "Not Found"} - case *ast.CompositeLit: - switch i := vv.Type.(type) { - case *ast.Ident: - return varName, isErrorType(i.Name, allTypes, errorTypes) - case *ast.IndexExpr: - if ii, ok := i.X.(*ast.Ident); ok { - return varName, isErrorType(ii.Name, allTypes, errorTypes) - } - } - } - - return "", false -} - -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 e2002e4d4..000000000 --- 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 5646ee909..000000000 --- a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,184 +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." - - reportMsg = "return both the `nil` error and invalid value: use a sentinel error 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", "coma separated list") - - return a -} - -type nilNil struct { - checkedTypes checkedTypes -} - -func newNilNil() *nilNil { - return &nilNil{ - checkedTypes: newDefaultCheckedTypes(), - } -} - -var funcAndReturns = []ast.Node{ - (*ast.FuncDecl)(nil), - (*ast.FuncLit)(nil), - (*ast.ReturnStmt)(nil), -} - -func (n *nilNil) run(pass *analysis.Pass) (interface{}, 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 || len(v.Results) != 2 || ft == nil || ft.Results == nil || len(ft.Results.List) != 2 { - return false - } - - fRes1Type := pass.TypesInfo.TypeOf(ft.Results.List[0].Type) - if fRes1Type == nil { - return false - } - - fRes2Type := pass.TypesInfo.TypeOf(ft.Results.List[1].Type) - if fRes2Type == nil { - return false - } - - ok, zv := n.isDangerNilType(fRes1Type) - if !(ok && isErrorType(fRes2Type)) { - return false - } - - retVal, retErr := v.Results[0], v.Results[1] - - var needWarn bool - switch zv { - case zeroValueNil: - needWarn = isNil(pass, retVal) && isNil(pass, retErr) - case zeroValueZero: - needWarn = isZero(retVal) && isNil(pass, retErr) - } - - if needWarn { - pass.Reportf(v.Pos(), reportMsg) - } - } - - return true - }) - - return nil, nil //nolint:nilnil -} - -type zeroValue int - -const ( - zeroValueNil = iota + 1 - zeroValueZero -) - -func (n *nilNil) isDangerNilType(t types.Type) (bool, zeroValue) { - switch v := t.(type) { - case *types.Pointer: - return n.checkedTypes.Contains(ptrType), zeroValueNil - - case *types.Signature: - return n.checkedTypes.Contains(funcType), zeroValueNil - - case *types.Interface: - return n.checkedTypes.Contains(ifaceType), zeroValueNil - - case *types.Map: - return n.checkedTypes.Contains(mapType), zeroValueNil - - case *types.Chan: - return n.checkedTypes.Contains(chanType), zeroValueNil - - case *types.Basic: - if v.Kind() == types.Uintptr { - return n.checkedTypes.Contains(uintptrType), zeroValueZero - } - if v.Kind() == types.UnsafePointer { - return n.checkedTypes.Contains(unsafeptrType), zeroValueNil - } - - case *types.Named: - return n.isDangerNilType(v.Underlying()) - } - return false, 0 -} - -var errorIface = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - -func isErrorType(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 c9b8e3eed..000000000 --- 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{ - ptrType: {}, - funcType: {}, - ifaceType: {}, - mapType: {}, - chanType: {}, - 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 081761547..000000000 --- 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 9b1cf3a39..000000000 --- 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 a9e41b0a8..000000000 --- a/vendor/github.com/Antonboom/testifylint/analyzer/analyzer.go +++ /dev/null @@ -1,93 +0,0 @@ -package analyzer - -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/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, - 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) { - filesToAnalysis := make([]*ast.File, 0, len(pass.Files)) - for _, f := range pass.Files { - if !analysisutil.Imports(f, testify.AssertPkgPath, testify.RequirePkgPath, testify.SuitePkgPath) { - continue - } - filesToAnalysis = append(filesToAnalysis, f) - } - - insp := inspector.New(filesToAnalysis) - - // 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 df04dfdc5..000000000 --- a/vendor/github.com/Antonboom/testifylint/analyzer/checkers_factory.go +++ /dev/null @@ -1,81 +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) - - 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 b57cbd938..000000000 --- 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/file.go b/vendor/github.com/Antonboom/testifylint/internal/analysisutil/file.go deleted file mode 100644 index 3fc1f42b8..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/file.go +++ /dev/null @@ -1,28 +0,0 @@ -package analysisutil - -import ( - "go/ast" - "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 - } - // NOTE(a.telyshev): Don't use `slices.Contains` to keep the minimum module version 1.20. - for _, pkg := range pkgs { // Small O(n). - if pkg == path { - 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 fcb4b847f..000000000 --- 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 4e0346d2b..000000000 --- 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 d34be5d34..000000000 --- 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 403691e27..000000000 --- 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, nil)) - } - } - 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 d125c43f9..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/bool_compare.go +++ /dev/null @@ -1,212 +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 !isBuiltinBool(pass, survivingArg) { - if checker.ignoreCustomTypes { - return nil - } - survivingArg = newBoolCast(survivingArg) - } - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - newSuggestedFuncReplacement(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 !isBuiltinBool(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" && !isBuiltinBool(pass, survivingArg) { - // NOTE(a.telyshev): `Exactly` assumes no type casting. - 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" && !isBuiltinBool(pass, survivingArg) { - // NOTE(a.telyshev): `Exactly` assumes no type casting. - 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 96b5b19b0..000000000 --- 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 ac23af6f6..000000000 --- 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, inspector *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 17c7d14ee..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/checkers_registry.go +++ /dev/null @@ -1,109 +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(NewLen), enabledByDefault: true}, - {factory: asCheckerFactory(NewNegativePositive), enabledByDefault: true}, - {factory: asCheckerFactory(NewCompares), enabledByDefault: true}, - {factory: asCheckerFactory(NewErrorNil), enabledByDefault: true}, - {factory: asCheckerFactory(NewNilCompare), enabledByDefault: true}, - {factory: asCheckerFactory(NewErrorIsAs), enabledByDefault: true}, - {factory: asCheckerFactory(NewExpectedActual), 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(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 bdde03d95..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/compares.go +++ /dev/null @@ -1,99 +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 - } - - if isPointer(pass, be.X) && isPointer(pass, be.Y) { - switch proposedFn { - case "Equal": - proposedFn = "Same" - case "NotEqual": - proposedFn = "NotSame" - } - } - - a, b := be.X, be.Y - return newUseFunctionDiagnostic(checker.Name(), call, proposedFn, - newSuggestedFuncReplacement(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/empty.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/empty.go deleted file mode 100644 index eafecb678..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/empty.go +++ /dev/null @@ -1,169 +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.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), 0) -// assert.Greater(t, 0, len(arr)) -// assert.Less(t, len(arr), 1) -// assert.Greater(t, 1, len(arr)) -// assert.Zero(t, len(arr)) -// assert.Empty(t, len(arr)) -// -// assert.NotEqual(t, 0, len(arr)) -// assert.NotEqualValues(t, 0, len(arr)) -// assert.Less(t, 0, len(arr)) -// assert.Greater(t, len(arr), 0) -// assert.Positive(t, len(arr)) -// assert.NotZero(t, len(arr)) -// assert.NotEmpty(t, len(arr)) -// -// and requires -// -// assert.Empty(t, arr) -// assert.NotEmpty(t, arr) -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 - newUseEmptyDiagnostic := func(replaceStart, replaceEnd token.Pos, replaceWith ast.Expr) *analysis.Diagnostic { - const proposed = "Empty" - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - newSuggestedFuncReplacement(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", "Empty": - lenArg, ok := isBuiltinLenCall(pass, a) - if ok { - return newUseEmptyDiagnostic(a.Pos(), a.End(), 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": - 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 - newUseNotEmptyDiagnostic := func(replaceStart, replaceEnd token.Pos, replaceWith ast.Expr) *analysis.Diagnostic { - const proposed = "NotEmpty" - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - newSuggestedFuncReplacement(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 "NotZero", "NotEmpty", "Positive": - lenArg, ok := isBuiltinLenCall(pass, a) - if ok { - return newUseNotEmptyDiagnostic(a.Pos(), a.End(), lenArg) - } - } - - if len(call.Args) < 2 { - return nil - } - b := call.Args[1] - - switch call.Fn.NameFTrimmed { - case "NotEqual", "NotEqualValues": - 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/error_is_as.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/error_is_as.go deleted file mode 100644 index ab92c2ec0..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/error_is_as.go +++ /dev/null @@ -1,142 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" -) - -// ErrorIsAs detects situations like -// -// assert.Error(t, err, errSentinel) -// assert.NoError(t, err, errSentinel) -// assert.True(t, errors.Is(err, errSentinel)) -// assert.False(t, errors.Is(err, errSentinel)) -// assert.True(t, errors.As(err, &target)) -// -// and requires -// -// assert.ErrorIs(t, err, errSentinel) -// assert.NotErrorIs(t, err, errSentinel) -// assert.ErrorAs(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]) { - 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 "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, - newSuggestedFuncReplacement(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 - } - - if isErrorsIsCall(pass, ce) { - const proposed = "NotErrorIs" - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - newSuggestedFuncReplacement(call, proposed, analysis.TextEdit{ - Pos: ce.Pos(), - End: ce.End(), - NewText: formatAsCallArgs(pass, ce.Args[0], ce.Args[1]), - }), - ) - } - - case "ErrorAs": - 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, nil) - } - if pt.Elem() == errorType { - return newDiagnostic(checker.Name(), call, errorPtrReport, nil) - } - - _, isInterface := pt.Elem().Underlying().(*types.Interface) - if !isInterface && !types.Implements(pt.Elem(), errorIface) { - return newDiagnostic(checker.Name(), call, defaultReport, nil) - } - } - return nil -} 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 1e56d222a..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/error_nil.go +++ /dev/null @@ -1,92 +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.NotNil(t, err) -// assert.Equal(t, nil, err) -// assert.EqualValues(t, nil, err) -// assert.Exactly(t, nil, err) -// assert.ErrorIs(t, err, nil) -// -// assert.NotEqual(t, nil, err) -// assert.NotEqualValues(t, nil, err) -// assert.NotErrorIs(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": - if len(call.Args) >= 1 && isError(pass, call.Args[0]) { - return noErrorFn, call.Args[0], call.Args[0].End() - } - - case "NotNil": - if len(call.Args) >= 1 && isError(pass, call.Args[0]) { - return errorFn, call.Args[0], call.Args[0].End() - } - - case "Equal", "EqualValues", "Exactly", "ErrorIs": - 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": - 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, - newSuggestedFuncReplacement(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 77784dc7b..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/expected_actual.go +++ /dev/null @@ -1,179 +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.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.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", - "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: - return (v.Op == token.AND) && checker.isExpectedValueCandidate(pass, v.X) // &value - - case *ast.CompositeLit: - return true - - case *ast.CallExpr: - 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 7436f9ca1..000000000 --- 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), nil) - } - 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 3401bb097..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/formatter.go +++ /dev/null @@ -1,187 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - "go/types" - "strconv" - - "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) -type Formatter struct { - checkFormatString bool - requireFFuncs bool -} - -// NewFormatter constructs Formatter checker. -func NewFormatter() *Formatter { - return &Formatter{ - checkFormatString: true, - requireFFuncs: false, - } -} - -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) 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, call.Fn.Signature) - if !ok { - return nil - } - - fFunc := call.Fn.Name + "f" - - if msgAndArgsPos == len(call.ArgsRaw)-1 { - msgAndArgs := call.ArgsRaw[msgAndArgsPos] - if args, ok := isFmtSprintfCall(pass, msgAndArgs); ok { - if checker.requireFFuncs { - msg := fmt.Sprintf("remove unnecessary fmt.Sprintf and use %s.%s", call.SelectorXStr, fFunc) - return newDiagnostic(checker.Name(), call, msg, - newSuggestedFuncReplacement(call, fFunc, analysis.TextEdit{ - Pos: msgAndArgs.Pos(), - End: msgAndArgs.End(), - NewText: formatAsCallArgs(pass, args...), - }), - ) - } - return newRemoveSprintfDiagnostic(pass, checker.Name(), call, msgAndArgs, args) - } - } - - if checker.requireFFuncs { - return newUseFunctionDiagnostic(checker.Name(), call, fFunc, newSuggestedFuncReplacement(call, fFunc)) - } - return nil -} - -func (checker Formatter) checkFmtAssertion(pass *analysis.Pass, call *CallMeta) (result *analysis.Diagnostic) { - formatPos := getMsgPosition(call.Fn.Signature) - if formatPos < 0 { - return nil - } - - msg := call.ArgsRaw[formatPos] - - if formatPos == len(call.ArgsRaw)-1 { - if args, ok := isFmtSprintfCall(pass, msg); ok { - return newRemoveSprintfDiagnostic(pass, checker.Name(), call, msg, args) - } - } - - if checker.checkFormatString { - report := pass.Report - defer func() { pass.Report = report }() - - pass.Report = func(d analysis.Diagnostic) { - result = newDiagnostic(checker.Name(), call, d.Message, nil) - } - - format, err := strconv.Unquote(analysisutil.NodeString(pass.Fset, msg)) - if err != nil { - return nil - } - printf.CheckPrintf(pass, call.Call, call.String(), format, formatPos) - } - return result -} - -func isPrintfLikeCall(pass *analysis.Pass, call *CallMeta, sig *types.Signature) (int, bool) { - msgAndArgsPos := getMsgAndArgsPosition(sig) - if msgAndArgsPos < 0 { - return -1, false - } - - fmtFn := analysisutil.ObjectOf(pass.Pkg, testify.AssertPkgPath, call.Fn.Name+"f") - if fmtFn == nil { - // NOTE(a.telyshev): No formatted analogue of assertion. - return -1, false - } - - return msgAndArgsPos, len(call.ArgsRaw) > msgAndArgsPos -} - -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 := 0; i < sig.Params().Len(); i++ { - param := sig.Params().At(i) - - if b, ok := param.Type().(*types.Basic); ok && b.Kind() == types.String && param.Name() == "msg" { - return i - } - } - return -1 -} - -func isFmtSprintfCall(pass *analysis.Pass, expr ast.Expr) ([]ast.Expr, bool) { - ce, ok := expr.(*ast.CallExpr) - if !ok { - return nil, false - } - - se, ok := ce.Fun.(*ast.SelectorExpr) - if !ok { - return nil, false - } - - sprintfObj := analysisutil.ObjectOf(pass.Pkg, "fmt", "Sprintf") - if sprintfObj == nil { - return nil, false - } - - if !analysisutil.IsObj(pass.TypesInfo, se.Sel, sprintfObj) { - return nil, false - } - - return ce.Args, true -} 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 060c96033..000000000 --- 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, inspector *inspector.Inspector) (diagnostics []analysis.Diagnostic) { - testsDecls := make(funcDeclarations) - inspector.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), - } - inspector.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"), nil) - diagnostics = append(diagnostics, *d) - - case goRequireVerdictAssertFailNow: - d := newDiagnostic(checker.Name(), testifyCall, fmt.Sprintf(goRequireCallReportFormat, testifyCall), nil) - 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), nil) - diagnostics = append(diagnostics, *d) - } - } - return true - }) - - if !checker.ignoreHTTPHandlers { - diagnostics = append(diagnostics, checker.checkHTTPHandlers(pass, inspector)...) - } - - 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"), nil) - diagnostics = append(diagnostics, *d) - - case goRequireVerdictAssertFailNow: - d := newDiagnostic(checker.Name(), testifyCall, fmt.Sprintf(goRequireHTTPHandlerReportFormat, testifyCall), nil) - 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 4e4735269..000000000 --- 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 432a3032c..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_basic_type.go +++ /dev/null @@ -1,113 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - - "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, types ...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 types { - if fn.Name == t { - return isIntNumber(ce.Args[0], v) - } - } - return false -} - -func isIntNumber(e ast.Expr, v int) bool { - bl, ok := e.(*ast.BasicLit) - return ok && bl.Kind == token.INT && bl.Value == fmt.Sprintf("%d", v) -} - -func isBasicLit(e ast.Expr) bool { - _, ok := e.(*ast.BasicLit) - return ok -} - -func isIntBasicLit(e ast.Expr) bool { - bl, ok := e.(*ast.BasicLit) - return ok && bl.Kind == token.INT -} - -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) bool { - _, ok := pass.TypesInfo.TypeOf(e).(*types.Pointer) - return ok -} - -// untype returns v from type(v) expression or v itself if there is no type cast. -func untype(e ast.Expr) ast.Expr { - ce, ok := e.(*ast.CallExpr) - if !ok || len(ce.Args) != 1 { - return e - } - return ce.Args[0] -} 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 13e579a2b..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_bool.go +++ /dev/null @@ -1,33 +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 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 isBuiltinBool(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 ac11d7399..000000000 --- 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, -) (ast.Expr, ast.Expr, 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 e8505fad0..000000000 --- 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 - 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 3ae88a560..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_diagnostic.go +++ /dev/null @@ -1,80 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/analysis" -) - -func newUseFunctionDiagnostic( - checker string, - call *CallMeta, - proposedFn string, - fix *analysis.SuggestedFix, -) *analysis.Diagnostic { - f := proposedFn - if call.Fn.IsFmt { - f += "f" - } - msg := fmt.Sprintf("use %s.%s", call.SelectorXStr, f) - - return newDiagnostic(checker, call, msg, fix) -} - -func newRemoveSprintfDiagnostic( - pass *analysis.Pass, - checker string, - call *CallMeta, - sprintfPos analysis.Range, - sprintfArgs []ast.Expr, -) *analysis.Diagnostic { - return newDiagnostic(checker, call, "remove unnecessary fmt.Sprintf", &analysis.SuggestedFix{ - Message: "Remove `fmt.Sprintf`", - TextEdits: []analysis.TextEdit{ - { - Pos: sprintfPos.Pos(), - End: sprintfPos.End(), - NewText: formatAsCallArgs(pass, sprintfArgs...), - }, - }, - }) -} - -func newDiagnostic( - checker string, - rng analysis.Range, - msg string, - fix *analysis.SuggestedFix, -) *analysis.Diagnostic { - d := analysis.Diagnostic{ - Pos: rng.Pos(), - End: rng.End(), - Category: checker, - Message: checker + ": " + msg, - } - if fix != nil { - d.SuggestedFixes = []analysis.SuggestedFix{*fix} - } - return &d -} - -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{ - { - Pos: call.Fn.Pos(), - End: call.Fn.End(), - NewText: []byte(proposedFn), - }, - }, additionalEdits...), - } -} 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 55cd5fd05..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_error.go +++ /dev/null @@ -1,42 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -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 isErrorsPkgFnCall(pass, ce, "Is") -} - -func isErrorsAsCall(pass *analysis.Pass, ce *ast.CallExpr) bool { - return isErrorsPkgFnCall(pass, ce, "As") -} - -func isErrorsPkgFnCall(pass *analysis.Pass, ce *ast.CallExpr, fn string) bool { - se, ok := ce.Fun.(*ast.SelectorExpr) - if !ok { - return false - } - - errorsIsObj := analysisutil.ObjectOf(pass.Pkg, "errors", fn) - if errorsIsObj == nil { - return false - } - - return analysisutil.IsObj(pass.TypesInfo, se.Sel, errorsIsObj) -} 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 765fce527..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_format.go +++ /dev/null @@ -1,26 +0,0 @@ -package checkers - -import ( - "bytes" - "go/ast" - - "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() -} 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 9dabb02a9..000000000 --- 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 := 0; i < sig.Params().Len(); i++ { - 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 b0c0d1302..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_interface.go +++ /dev/null @@ -1,48 +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 - } - - iface, ok := t.Type.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 904950ff3..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_len.go +++ /dev/null @@ -1,55 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "go/types" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -var lenObj = types.Universe.Lookup("len") - -func isLenEquality(pass *analysis.Pass, e ast.Expr) (ast.Expr, ast.Expr, bool) { - be, ok := e.(*ast.BinaryExpr) - if !ok { - return nil, nil, false - } - - if be.Op != token.EQL { - return nil, nil, false - } - return xorLenCall(pass, be.X, be.Y) -} - -func xorLenCall(pass *analysis.Pass, a, b ast.Expr) (lenArg ast.Expr, expectedLen ast.Expr, ok bool) { - arg1, ok1 := isBuiltinLenCall(pass, a) - arg2, ok2 := isBuiltinLenCall(pass, b) - - if xor(ok1, ok2) { - if ok1 { - return arg1, b, true - } - return arg2, a, true - } - return nil, nil, false -} - -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 1d92e3e81..000000000 --- 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 112fca38e..000000000 --- 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_suite.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_suite.go deleted file mode 100644 index 9f39d4653..000000000 --- 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 5c28ec883..000000000 --- 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 47330568c..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/len.go +++ /dev/null @@ -1,64 +0,0 @@ -package checkers - -import ( - "golang.org/x/tools/go/analysis" -) - -// Len detects situations like -// -// assert.Equal(t, 3, len(arr)) -// assert.EqualValues(t, 3, len(arr)) -// assert.Exactly(t, 3, len(arr)) -// assert.True(t, len(arr) == 3) -// -// and requires -// -// assert.Len(t, arr, 3) -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 { - const proposedFn = "Len" - - switch call.Fn.NameFTrimmed { - case "Equal", "EqualValues", "Exactly": - if len(call.Args) < 2 { - return nil - } - a, b := call.Args[0], call.Args[1] - - if lenArg, expectedLen, ok := xorLenCall(pass, a, b); ok { - if expectedLen == b && !isIntBasicLit(expectedLen) { - // https://github.com/Antonboom/testifylint/issues/9 - return nil - } - return newUseFunctionDiagnostic(checker.Name(), call, proposedFn, - newSuggestedFuncReplacement(call, proposedFn, analysis.TextEdit{ - Pos: a.Pos(), - End: b.End(), - NewText: formatAsCallArgs(pass, lenArg, expectedLen), - }), - ) - } - - case "True": - if len(call.Args) < 1 { - return nil - } - expr := call.Args[0] - - if lenArg, expectedLen, ok := isLenEquality(pass, expr); ok && isIntBasicLit(expectedLen) { - return newUseFunctionDiagnostic(checker.Name(), call, proposedFn, - newSuggestedFuncReplacement(call, proposedFn, analysis.TextEdit{ - Pos: expr.Pos(), - End: expr.End(), - NewText: formatAsCallArgs(pass, lenArg, expectedLen), - }), - ) - } - } - return nil -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/negative_postive.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/negative_postive.go deleted file mode 100644 index 274021f67..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/negative_postive.go +++ /dev/null @@ -1,175 +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, - newSuggestedFuncReplacement(call, proposed, analysis.TextEdit{ - Pos: replaceStart, - End: replaceEnd, - NewText: analysisutil.NodeBytes(pass.Fset, replaceWith), - }), - ) - } - - // NOTE(a.telyshev): We ignore uint-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 isSignedNotZero(pass, a) && isZeroOrSignedZero(b) { - return newUseNegativeDiagnostic(a.Pos(), b.End(), untype(a)) - } - - case "Greater": - if len(call.Args) < 2 { - return nil - } - a, b := call.Args[0], call.Args[1] - - if isZeroOrSignedZero(a) && isSignedNotZero(pass, b) { - return newUseNegativeDiagnostic(a.Pos(), b.End(), untype(b)) - } - - case "True": - if len(call.Args) < 1 { - return nil - } - expr := call.Args[0] - - a, _, ok1 := isStrictComparisonWith(pass, expr, isSignedNotZero, token.LSS, p(isZeroOrSignedZero)) // a < 0 - _, b, ok2 := isStrictComparisonWith(pass, expr, p(isZeroOrSignedZero), token.GTR, isSignedNotZero) // 0 > a - - survivingArg, ok := anyVal([]bool{ok1, ok2}, a, b) - if ok { - return newUseNegativeDiagnostic(expr.Pos(), expr.End(), untype(survivingArg)) - } - - case "False": - if len(call.Args) < 1 { - return nil - } - expr := call.Args[0] - - a, _, ok1 := isStrictComparisonWith(pass, expr, isSignedNotZero, token.GEQ, p(isZeroOrSignedZero)) // a >= 0 - _, b, ok2 := isStrictComparisonWith(pass, expr, p(isZeroOrSignedZero), token.LEQ, isSignedNotZero) // 0 <= a - - survivingArg, ok := anyVal([]bool{ok1, ok2}, a, b) - if ok { - return newUseNegativeDiagnostic(expr.Pos(), expr.End(), untype(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, - newSuggestedFuncReplacement(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(), untype(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(), untype(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(), untype(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(), untype(survivingArg)) - } - } - return nil -} 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 47c4a7383..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/nil_compare.go +++ /dev/null @@ -1,56 +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, - newSuggestedFuncReplacement(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 6a66aea5e..000000000 --- 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 09cd23993..000000000 --- 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 cfb47b542..000000000 --- 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. -func isTypeParam(t types.Type) bool { - _, ok := 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 := 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/require_error.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/require_error.go deleted file mode 100644 index 4303828fd..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/require_error.go +++ /dev/null @@ -1,250 +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, inspector *inspector.Inspector) []analysis.Diagnostic { - callsByFunc := make(map[funcID][]*callMeta) - - // Stage 1. Collect meta information about any calls inside functions. - - inspector.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, nil)) - } - } - - 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 { - nearestIf = parent - } else { - break - } - } - 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 f830fd2a5..000000000 --- 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 6150ae78d..000000000 --- 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 9adfe5190..000000000 --- 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_subtest_run.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_subtest_run.go deleted file mode 100644 index 67d9c252b..000000000 --- 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, nil)) - } - }) - 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 59455290d..000000000 --- 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, inspector *inspector.Inspector) (diagnostics []analysis.Diagnostic) { - inspector.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 := fmt.Sprintf("%s.T().Helper()", rcvName) - - firstStmt := fd.Body.List[0] - if analysisutil.NodeString(pass.Fset, firstStmt) == helperCallStr { - return - } - - msg := fmt.Sprintf("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 6f206d095..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/useless_assert.go +++ /dev/null @@ -1,88 +0,0 @@ -package checkers - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// UselessAssert detects useless asserts like -// -// 1) Asserting of the same variable -// -// assert.Equal(t, tt.value, tt.value) -// assert.ElementsMatch(t, users, users) -// ... -// assert.True(t, num > num) -// assert.False(t, num == num) -// -// 2) Open for contribution... -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 { - 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", - "IsType", - "JSONEq", - "Less", - "LessOrEqual", - "NotEqual", - "NotEqualValues", - "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", nil) - } - return nil -} 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 a8812e6d0..000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/config/config.go +++ /dev/null @@ -1,154 +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, - }, - 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 -} - -// 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 if format string is used") - - 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 5b08ec47b..000000000 --- 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 3476e4040..000000000 --- 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 fe79e3add..000000000 --- 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 01b574320..000000000 --- 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 639e6c399..000000000 --- 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://godocs.io/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 c05a0b7e5..000000000 --- a/vendor/github.com/BurntSushi/toml/decode.go +++ /dev/null @@ -1,615 +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)) -} - -// 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) - } - 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 155709a80..000000000 --- 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 82c90a905..000000000 --- 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 73366c0d9..000000000 --- a/vendor/github.com/BurntSushi/toml/encode.go +++ /dev/null @@ -1,778 +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 []string - for _, mapKey := range rv.MapKeys() { - k := mapKey.String() - if typeIsTable(tomlTypeOfGo(eindirect(rv.MapIndex(mapKey)))) { - mapKeysSub = append(mapKeysSub, k) - } else { - mapKeysDirect = append(mapKeysDirect, k) - } - } - - var writeMapKeys = func(mapKeys []string, trailC bool) { - sort.Strings(mapKeys) - for i, mapKey := range mapKeys { - val := eindirect(rv.MapIndex(reflect.ValueOf(mapKey))) - if isNil(val) { - continue - } - - if inline { - enc.writeKeyValue(Key{mapKey}, val, true) - if trailC || i != len(mapKeys)-1 { - enc.wf(", ") - } - } else { - enc.encode(key.add(mapKey), val) - } - } - } - - if inline { - enc.wf("{") - } - writeMapKeys(mapKeysDirect, len(mapKeysSub) > 0) - writeMapKeys(mapKeysSub, false) - if inline { - enc.wf("}") - } -} - -const is32Bit = (32 << (^uint(0) >> 63)) == 32 - -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)) - - if is32Bit { - // Copy so it works correct on 32bit archs; not clear why this - // is needed. See #314, and https://www.reddit.com/r/golang/comments/pnx8v4 - // This also works fine on 64bit, but 32bit archs are somewhat - // rare and this is a wee bit faster. - 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) { - 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] != len(fields)-1 { - enc.wf(", ") - } - } else { - enc.encode(key.add(keyName), fieldVal) - } - } - } - - if inline { - enc.wf("{") - } - writeFields(fieldsDirect) - writeFields(fieldsSub) - 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 1dd523211..000000000 --- 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 // Lenght 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 022f15bc2..000000000 --- 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 6878d9d69..000000000 --- a/vendor/github.com/BurntSushi/toml/lex.go +++ /dev/null @@ -1,1287 +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() - 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 hexidecimal 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 { - if tomlNext { - return (r >= 'A' && r <= 'Z') || - (r >= 'a' && r <= 'z') || - (r >= '0' && r <= '9') || - r == '_' || r == '-' || - r == 0xb2 || r == 0xb3 || r == 0xb9 || (r >= 0xbc && r <= 0xbe) || - (r >= 0xc0 && r <= 0xd6) || (r >= 0xd8 && r <= 0xf6) || (r >= 0xf8 && r <= 0x037d) || - (r >= 0x037f && r <= 0x1fff) || - (r >= 0x200c && r <= 0x200d) || (r >= 0x203f && r <= 0x2040) || - (r >= 0x2070 && r <= 0x218f) || (r >= 0x2460 && r <= 0x24ff) || - (r >= 0x2c00 && r <= 0x2fef) || (r >= 0x3001 && r <= 0xd7ff) || - (r >= 0xf900 && r <= 0xfdcf) || (r >= 0xfdf0 && r <= 0xfffd) || - (r >= 0x10000 && r <= 0xeffff) - } - - 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 e61453730..000000000 --- a/vendor/github.com/BurntSushi/toml/meta.go +++ /dev/null @@ -1,148 +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 { - if cap(k) > len(k) { - return append(k, piece) - } - 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 3f2c090c8..000000000 --- a/vendor/github.com/BurntSushi/toml/parse.go +++ /dev/null @@ -1,846 +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:] - //lint:ignore S1017 https://github.com/dominikh/go-tools/issues/1447 - } 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 - } - } - - // isHexis a superset of all the permissable 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 10c51f7ee..000000000 --- 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 1c090d331..000000000 --- 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/Crocmagnon/fatcontext/LICENSE b/vendor/github.com/Crocmagnon/fatcontext/LICENSE deleted file mode 100644 index 96f153ca4..000000000 --- a/vendor/github.com/Crocmagnon/fatcontext/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Gabriel Augendre - -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/Crocmagnon/fatcontext/pkg/analyzer/analyzer.go b/vendor/github.com/Crocmagnon/fatcontext/pkg/analyzer/analyzer.go deleted file mode 100644 index a65efbba8..000000000 --- a/vendor/github.com/Crocmagnon/fatcontext/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,224 +0,0 @@ -package analyzer - -import ( - "bytes" - "errors" - "fmt" - "go/ast" - "go/printer" - "go/token" - "go/types" - - "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: "fatcontext", - Doc: "detects nested contexts in loops and function literals", - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, -} - -var errUnknown = errors.New("unknown node type") - -func run(pass *analysis.Pass) (interface{}, error) { - inspctr := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - nodeFilter := []ast.Node{ - (*ast.ForStmt)(nil), - (*ast.RangeStmt)(nil), - (*ast.FuncLit)(nil), - } - - inspctr.Preorder(nodeFilter, func(node ast.Node) { - body, err := getBody(node) - if err != nil { - return - } - - assignStmt := findNestedContext(pass, node, body.List) - if assignStmt == nil { - return - } - - suggestedStmt := ast.AssignStmt{ - Lhs: assignStmt.Lhs, - TokPos: assignStmt.TokPos, - Tok: token.DEFINE, - Rhs: assignStmt.Rhs, - } - suggested, err := render(pass.Fset, &suggestedStmt) - - var fixes []analysis.SuggestedFix - if err == nil { - fixes = append(fixes, analysis.SuggestedFix{ - Message: "replace `=` with `:=`", - TextEdits: []analysis.TextEdit{ - { - Pos: assignStmt.Pos(), - End: assignStmt.End(), - NewText: []byte(suggested), - }, - }, - }) - } - - pass.Report(analysis.Diagnostic{ - Pos: assignStmt.Pos(), - Message: getReportMessage(node), - SuggestedFixes: fixes, - }) - }) - - return nil, nil -} - -func getReportMessage(node ast.Node) string { - switch node.(type) { - case *ast.ForStmt, *ast.RangeStmt: - return "nested context in loop" - case *ast.FuncLit: - return "nested context in function literal" - default: - return "unsupported nested context type" - } -} - -func getBody(node ast.Node) (*ast.BlockStmt, error) { - forStmt, ok := node.(*ast.ForStmt) - if ok { - return forStmt.Body, nil - } - - rangeStmt, ok := node.(*ast.RangeStmt) - if ok { - return rangeStmt.Body, nil - } - - funcLit, ok := node.(*ast.FuncLit) - if ok { - return funcLit.Body, nil - } - - return nil, errUnknown -} - -func findNestedContext(pass *analysis.Pass, node ast.Node, stmts []ast.Stmt) *ast.AssignStmt { - for _, stmt := range stmts { - // Recurse if necessary - if inner, ok := stmt.(*ast.BlockStmt); ok { - found := findNestedContext(pass, node, inner.List) - if found != nil { - return found - } - } - - if inner, ok := stmt.(*ast.IfStmt); ok { - found := findNestedContext(pass, node, inner.Body.List) - if found != nil { - return found - } - } - - if inner, ok := stmt.(*ast.SwitchStmt); ok { - found := findNestedContext(pass, node, inner.Body.List) - if found != nil { - return found - } - } - - if inner, ok := stmt.(*ast.CaseClause); ok { - found := findNestedContext(pass, node, inner.Body) - if found != nil { - return found - } - } - - if inner, ok := stmt.(*ast.SelectStmt); ok { - found := findNestedContext(pass, node, inner.Body.List) - if found != nil { - return found - } - } - - if inner, ok := stmt.(*ast.CommClause); ok { - found := findNestedContext(pass, node, inner.Body) - if found != nil { - return found - } - } - - // Actually check for nested context - assignStmt, ok := stmt.(*ast.AssignStmt) - if !ok { - continue - } - - t := pass.TypesInfo.TypeOf(assignStmt.Lhs[0]) - if t == nil { - continue - } - - if t.String() != "context.Context" { - continue - } - - if assignStmt.Tok == token.DEFINE { - continue - } - - // allow assignment to non-pointer children of values defined within the loop - if lhs := getRootIdent(pass, assignStmt.Lhs[0]); lhs != nil { - if obj := pass.TypesInfo.ObjectOf(lhs); obj != nil { - if checkObjectScopeWithinNode(obj.Parent(), node) { - continue // definition is within the loop - } - } - } - - return assignStmt - } - - return nil -} - -func checkObjectScopeWithinNode(scope *types.Scope, node ast.Node) bool { - if scope == nil { - return false - } - - if scope.Pos() >= node.Pos() && scope.End() <= node.End() { - return true - } - - return false -} - -func getRootIdent(pass *analysis.Pass, node ast.Node) *ast.Ident { - for { - switch n := node.(type) { - case *ast.Ident: - return n - case *ast.IndexExpr: - node = n.X - case *ast.SelectorExpr: - if sel, ok := pass.TypesInfo.Selections[n]; ok && sel.Indirect() { - return nil // indirected (pointer) roots don't imply a (safe) copy - } - node = n.X - default: - return nil - } - } -} - -// render returns the pretty-print of the given node -func render(fset *token.FileSet, x interface{}) (string, error) { - var buf bytes.Buffer - if err := printer.Fprint(&buf, fset, x); err != nil { - return "", fmt.Errorf("printing node: %w", err) - } - return buf.String(), nil -} diff --git a/vendor/github.com/Djarvur/go-err113/.gitignore b/vendor/github.com/Djarvur/go-err113/.gitignore deleted file mode 100644 index 66fd13c90..000000000 --- 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 2abdfc639..000000000 --- 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 44fe77d53..000000000 --- a/vendor/github.com/Djarvur/go-err113/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: go - -go: - - "1.13" - - "1.14" - - tip - -env: - - GO111MODULE=on - -before_install: - - go get github.com/axw/gocov/gocov - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cmd/cover - - go get golang.org/x/tools/cmd/goimports - - 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.14" && 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 a78ad8c77..000000000 --- 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 b26af4038..000000000 --- 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 8a8555783..000000000 --- a/vendor/github.com/Djarvur/go-err113/comparison.go +++ /dev/null @@ -1,123 +0,0 @@ -package err113 - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - - "golang.org/x/tools/go/analysis" -) - -func inspectComparision(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 - } - - 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 -} - -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 689236bac..000000000 --- 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 ec4f52ac7..000000000 --- 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 ( - "bytes" - "go/ast" - "go/printer" - "go/token" - - "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) (interface{}, error) { - for _, file := range pass.Files { - tlds := enumerateFileDecls(file) - - ast.Inspect( - file, - func(n ast.Node) bool { - return inspectComparision(pass, n) && - inspectDefinition(pass, tlds, n) - }, - ) - } - - return nil, nil -} - -// render returns the pretty-print of the given node. -func render(fset *token.FileSet, x interface{}) string { - var buf bytes.Buffer - 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/GaijinEntertainment/go-exhaustruct/v3/LICENSE b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/LICENSE deleted file mode 100644 index 6698196c5..000000000 --- a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/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/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go deleted file mode 100644 index ec75fd409..000000000 --- a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go +++ /dev/null @@ -1,318 +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" - - "github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment" - "github.com/GaijinEntertainment/go-exhaustruct/v3/internal/pattern" - "github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure" -) - -type analyzer struct { - include pattern.List `exhaustruct:"optional"` - exclude pattern.List `exhaustruct:"optional"` - - structFields structure.FieldsCache `exhaustruct:"optional"` - comments comment.Cache `exhaustruct:"optional"` - - typeProcessingNeed map[string]bool - typeProcessingNeedMu sync.RWMutex `exhaustruct:"optional"` -} - -func NewAnalyzer(include, exclude []string) (*analysis.Analyzer, error) { - a := analyzer{ - typeProcessingNeed: make(map[string]bool), - comments: comment.Cache{}, - } - - var err error - - a.include, err = pattern.NewList(include...) - if err != nil { - return nil, err //nolint:wrapcheck - } - - a.exclude, err = pattern.NewList(exclude...) - if err != nil { - return nil, err //nolint:wrapcheck - } - - 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.newFlagSet(), - }, nil -} - -func (a *analyzer) newFlagSet() flag.FlagSet { - fs := flag.NewFlagSet("", flag.PanicOnError) - - fs.Var(&a.include, "i", `Regular expression to match type names, can receive multiple flags. -Anonymous structs can be matched by '' alias. -4ex: - github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer\. - github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer\.TypeInfo`) - fs.Var(&a.exclude, "e", `Regular expression to exclude type names, can receive multiple flags. -Anonymous structs can be matched by '' alias. -4ex: - github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer\. - github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer\.TypeInfo`) - - return *fs -} - -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 { - if ret, ok := stackParentIsReturn(stack); ok { - if returnContainsNonNilError(pass, ret, n) { - // it is okay to return uninitialized structure in case struct's direct parent is - // a return statement containing non-nil error - 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, msg) - } - - return true - } -} - -// 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 node.(type) { - case *ast.CompositeLit, // stack[len(stack)-1] - *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 - comments = append(comments, cm[node]...) - - default: - return comments - } - } - - return comments -} - -func getStructType(pass *analysis.Pass, lit *ast.CompositeLit) (*types.Struct, *TypeInfo, bool) { - switch typ := 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 stackParentIsReturn(stack []ast.Node) (*ast.ReturnStmt, bool) { - // it is safe to skip boundary check, since stack always has at least one element - // we also have no reason to check the first element, since it is always a file - for i := len(stack) - 2; i > 0; i-- { - switch st := stack[i].(type) { - case *ast.ReturnStmt: - return st, true - - case *ast.UnaryExpr: - // in case we're dealing with pointers - it is still viable to check pointer's - // parent for return statement - continue - - default: - return nil, false - } - } - - return nil, false -} - -// errorIface is a type that represents [error] interface and all types will be -// compared against. -var errorIface = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - -func returnContainsNonNilError(pass *analysis.Pass, ret *ast.ReturnStmt, except ast.Node) bool { - // errors are mostly located at the end of return statement, so we're starting - // from the end. - for i := len(ret.Results) - 1; i >= 0; i-- { - ri := ret.Results[i] - - // skip current node - if ri == except { - continue - } - - if un, ok := ri.(*ast.UnaryExpr); ok { - if un.X == except { - continue - } - } - - if types.Implements(pass.TypesInfo.TypeOf(ri), errorIface) { - return true - } - } - - return 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.include) == 0 && len(a.exclude) == 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.include != nil && !a.include.MatchFullString(name) { - res = false - } - - if res && a.exclude != nil && a.exclude.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/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/cache.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/cache.go deleted file mode 100644 index 88edef638..000000000 --- a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/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/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/directive.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/directive.go deleted file mode 100644 index a39a8076f..000000000 --- a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/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/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/pattern/list.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/pattern/list.go deleted file mode 100644 index a16e5058d..000000000 --- a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/pattern/list.go +++ /dev/null @@ -1,82 +0,0 @@ -package pattern - -import ( - "fmt" - "regexp" - "strings" -) - -var ( - ErrEmptyPattern = fmt.Errorf("pattern can't be empty") - ErrCompilationFailed = fmt.Errorf("pattern compilation failed") -) - -// List is a list of regular expressions. -type List []*regexp.Regexp - -// NewList parses slice of strings to a slice of compiled regular expressions. -func NewList(strs ...string) (List, error) { - if len(strs) == 0 { - return nil, nil - } - - l := make(List, 0, len(strs)) - - for _, str := range strs { - re, err := strToRe(str) - if err != nil { - return nil, err - } - - l = append(l, re) - } - - return l, nil -} - -// MatchFullString matches provided string against all regexps in a slice and returns -// true if any of them matches whole string. -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 -} - -func (l *List) Set(value string) error { - re, err := strToRe(value) - if err != nil { - return err - } - - *l = append(*l, re) - - return nil -} - -func (l *List) String() string { - res := make([]string, 0, len(*l)) - - for _, re := range *l { - res = append(res, `"`+re.String()+`"`) - } - - return strings.Join(res, ", ") -} - -// strToRe parses string to a compiled regular expression that matches full string. -func strToRe(str string) (*regexp.Regexp, error) { - if str == "" { - return nil, ErrEmptyPattern - } - - re, err := regexp.Compile(str) - if err != nil { - return nil, fmt.Errorf("%w: %s: %w", ErrCompilationFailed, str, err) - } - - return re, nil -} diff --git a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields-cache.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields-cache.go deleted file mode 100644 index 12a379692..000000000 --- a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/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/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields.go deleted file mode 100644 index b6b1a48c8..000000000 --- a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/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/github.com/Masterminds/semver/v3/.gitignore b/vendor/github.com/Masterminds/semver/v3/.gitignore deleted file mode 100644 index 6b061e617..000000000 --- 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 fbc633259..000000000 --- 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 f95a504fe..000000000 --- a/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md +++ /dev/null @@ -1,242 +0,0 @@ -# Changelog - -## 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 9ff7da9c4..000000000 --- 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 9ca87a2c7..000000000 --- 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 ed5693608..000000000 --- a/vendor/github.com/Masterminds/semver/v3/README.md +++ /dev/null @@ -1,258 +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. - -## 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. - -### 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://github.com/Masterminds/semver) -* [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 a30a66b1f..000000000 --- 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 a78235895..000000000 --- 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 8461c7ed9..000000000 --- a/vendor/github.com/Masterminds/semver/v3/constraints.go +++ /dev/null @@ -1,594 +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 -} - -// 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, "||") - or := make([][]*constraint, len(ors)) - for k, v := range ors { - - // TODO: Find a way to validate and fetch all the constraints in a simpler form - - // 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 - } - - result[i] = pc - } - or[k] = result - } - - o := &Constraints{constraints: or} - 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 _, o := range cs.constraints { - joy := true - for _, c := range o { - if check, _ := c.check(v); !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 _, 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 c.con.pre == "" && 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); 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) (bool, error) { - return constraintOps[c.origfunc](v, c) -} - -// 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) (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) (bool, error) { - if c.dirty { - - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - 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) (bool, error) { - - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - 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) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - 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) (bool, error) { - - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - 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) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - 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) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - 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) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - 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) - } - - 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) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - 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 74f97caa5..000000000 --- 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 ff499fb66..000000000 --- a/vendor/github.com/Masterminds/semver/v3/version.go +++ /dev/null @@ -1,639 +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 ( - // 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. -const semVerRegex 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 + "$") -} - -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) { - m := versionRegex.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: %s", 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: %s", 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: %s", 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 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 !containsOnly(p, allowed) { - return ErrInvalidMetadata - } - } - return nil -} diff --git a/vendor/github.com/OpenPeeDeeP/depguard/v2/.gitignore b/vendor/github.com/OpenPeeDeeP/depguard/v2/.gitignore deleted file mode 100644 index e189bdb22..000000000 --- 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 94a9ed024..000000000 --- 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 2ccfa22c5..000000000 --- a/vendor/github.com/OpenPeeDeeP/depguard/v2/README.md +++ /dev/null @@ -1,163 +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@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$ -``` - -## Golangci-lint - -This linter was built with -[Golangci-lint](https://github.com/golangci/golangci-lint) in mind. It is compatible -and read their docs to see how to implement all their linters, including this one. 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 2729091e8..000000000 --- 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 (settings LinterSettings) run(pass *analysis.Pass) (interface{}, error) { - s, err := settings.compile() - if err != nil { - return nil, err - } - return s.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 65325f612..000000000 --- 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 3363bd840..000000000 --- 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 311cacc88..000000000 --- a/vendor/github.com/OpenPeeDeeP/depguard/v2/settings.go +++ /dev/null @@ -1,240 +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 (ls linterSettings) whichLists(fileName string) []*list { - var matches []*list - for _, l := range ls { - 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 - } - return strings.HasPrefix(str, prefixList[idx]), idx -} diff --git a/vendor/github.com/PuerkitoBio/rehttp/LICENSE b/vendor/github.com/PuerkitoBio/rehttp/LICENSE deleted file mode 100644 index c2c7e00cd..000000000 --- a/vendor/github.com/PuerkitoBio/rehttp/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ -The BSD 3-clause license (https://opensource.org/licenses/BSD-3-Clause). - -Copyright (c) 2015-2016, Martin Angers -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 author 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/PuerkitoBio/rehttp/README.md b/vendor/github.com/PuerkitoBio/rehttp/README.md deleted file mode 100644 index 1c730fdfb..000000000 --- a/vendor/github.com/PuerkitoBio/rehttp/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# rehttp [![Build Status](https://github.com/PuerkitoBio/rehttp/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/PuerkitoBio/rehttp/actions) [![Go Reference](https://pkg.go.dev/badge/github.com/PuerkitoBio/rehttp.svg)](https://pkg.go.dev/github.com/PuerkitoBio/rehttp) - -Package rehttp implements an HTTP Transport (an `http.RoundTripper`) that handles retries. See the [godoc][] for details. - -Please note that rehttp requires Go1.6+, because it uses the `http.Request.Cancel` field to check for cancelled requests. It *should* work on Go1.5, but only if there is no timeout set on the `*http.Client`. Go's stdlib will return an error on the first request if that's the case, because it requires a `RoundTripper` that implements the (now deprecated in Go1.6) `CancelRequest` method. - -On Go1.7+, it uses the context returned by `http.Request.Context` to check for cancelled requests. - -## Installation - - $ go get github.com/PuerkitoBio/rehttp - -## License - -The [BSD 3-Clause license][bsd]. - -[bsd]: http://opensource.org/licenses/BSD-3-Clause -[godoc]: http://godoc.org/github.com/PuerkitoBio/rehttp diff --git a/vendor/github.com/PuerkitoBio/rehttp/cancelreader.go b/vendor/github.com/PuerkitoBio/rehttp/cancelreader.go deleted file mode 100644 index 13f794c00..000000000 --- a/vendor/github.com/PuerkitoBio/rehttp/cancelreader.go +++ /dev/null @@ -1,36 +0,0 @@ -package rehttp - -import ( - "context" - "io" - "net/http" -) - -type cancelReader struct { - io.ReadCloser - - cancel context.CancelFunc -} - -func (r cancelReader) Close() error { - r.cancel() - return r.ReadCloser.Close() -} - -// injectCancelReader propagates the ability for the caller to cancel the request context -// once done with the response. If the transport cancels before the body stream is read, -// a race begins where the caller may be unable to read the response bytes before the stream -// is closed and an error is returned. This helper function wraps a response body in a -// io.ReadCloser that cancels the context once the body is closed, preventing a context leak. -// Solution based on https://github.com/go-kit/kit/issues/773. -func injectCancelReader(res *http.Response, cancel context.CancelFunc) *http.Response { - if res == nil { - return nil - } - - res.Body = cancelReader{ - ReadCloser: res.Body, - cancel: cancel, - } - return res -} diff --git a/vendor/github.com/PuerkitoBio/rehttp/context_post17.go b/vendor/github.com/PuerkitoBio/rehttp/context_post17.go deleted file mode 100644 index dc5eb1c02..000000000 --- a/vendor/github.com/PuerkitoBio/rehttp/context_post17.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build go1.7 -// +build go1.7 - -package rehttp - -import "net/http" - -func contextForRequest(req *http.Request) <-chan struct{} { - // req.Context always returns non-nil. - return req.Context().Done() -} diff --git a/vendor/github.com/PuerkitoBio/rehttp/context_pre17.go b/vendor/github.com/PuerkitoBio/rehttp/context_pre17.go deleted file mode 100644 index 41ca441f7..000000000 --- a/vendor/github.com/PuerkitoBio/rehttp/context_pre17.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !go1.7 -// +build !go1.7 - -package rehttp - -import "net/http" - -func contextForRequest(req *http.Request) <-chan struct{} { - return nil -} diff --git a/vendor/github.com/PuerkitoBio/rehttp/perattempttimeout_post17.go b/vendor/github.com/PuerkitoBio/rehttp/perattempttimeout_post17.go deleted file mode 100644 index e92c34979..000000000 --- a/vendor/github.com/PuerkitoBio/rehttp/perattempttimeout_post17.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build go1.7 -// +build go1.7 - -package rehttp - -import ( - "context" - "net/http" - "time" -) - -func getRequestContext(req *http.Request) context.Context { - return req.Context() -} - -func getPerAttemptTimeoutInfo(ctx context.Context, req *http.Request, timeout time.Duration) (*http.Request, context.CancelFunc) { - tctx, cancel := context.WithTimeout(ctx, timeout) - return req.WithContext(tctx), cancel -} diff --git a/vendor/github.com/PuerkitoBio/rehttp/perattempttimeout_pre17.go b/vendor/github.com/PuerkitoBio/rehttp/perattempttimeout_pre17.go deleted file mode 100644 index e44e4e5ea..000000000 --- a/vendor/github.com/PuerkitoBio/rehttp/perattempttimeout_pre17.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build !go1.7 -// +build !go1.7 - -package rehttp - -import ( - "context" - "net/http" - "time" -) - -func getRequestContext(req *http.Request) context.Context { - return nil // req.Context() doesn't exist before 1.7 -} - -func getPerAttemptTimeoutInfo(ctx context.Context, req *http.Request, timeout time.Duration) (*http.Request, context.CancelFunc) { - // req.WithContext() doesn't exist before 1.7, so noop - return req, func() {} -} diff --git a/vendor/github.com/PuerkitoBio/rehttp/rehttp.go b/vendor/github.com/PuerkitoBio/rehttp/rehttp.go deleted file mode 100644 index 394be84c1..000000000 --- a/vendor/github.com/PuerkitoBio/rehttp/rehttp.go +++ /dev/null @@ -1,405 +0,0 @@ -// Package rehttp implements an HTTP transport that handles retries. -// An HTTP client can be created with a *rehttp.Transport as RoundTripper -// and it will apply the retry strategy to its requests. -// -// The retry strategy is provided by the Transport, which determines -// whether or not the request should be retried, and if so, what delay -// to apply before retrying, based on the RetryFn and DelayFn -// functions passed to NewTransport. -// -// The package offers common delay strategies as ready-made functions that -// return a DelayFn: -// - ConstDelay(delay time.Duration) DelayFn -// - ExpJitterDelay(base, max time.Duration) DelayFn -// - ExpJitterDelayWithRand(base, max time.Duration, generator func(int64) int64) DelayFn -// -// It also provides common retry helpers that return a RetryFn: -// - RetryIsErr(func(error) bool) RetryFn -// - RetryHTTPMethods(methods ...string) RetryFn -// - RetryMaxRetries(max int) RetryFn -// - RetryStatuses(statuses ...int) RetryFn -// - RetryStatusInterval(fromStatus, toStatus int) RetryFn -// - RetryTimeoutErr() RetryFn -// - RetryTemporaryErr() RetryFn -// -// Those can be combined with RetryAny or RetryAll as needed. RetryAny -// enables retries if any of the RetryFn return true, while RetryAll -// enables retries if all RetryFn return true. Typically, the RetryFn -// of the Transport should use at least RetryMaxRetries and some other -// retry condition(s), combined using RetryAll. -// -// By default, the Transport will buffer the request's body in order to -// be able to retry the request, as a request attempt will consume and -// close the existing body. Sometimes this is not desirable, so it can -// be prevented by setting PreventRetryWithBody to true on the Transport. -// Doing so will disable retries when a request has a non-nil body. -// -// This package requires Go version 1.6+, since it uses the new -// http.Request.Cancel field in order to cancel requests. It doesn't -// implement the deprecated http.Transport.CancelRequest method -// (https://golang.org/pkg/net/http/#Transport.CancelRequest). -// -// On Go1.7+, it uses the context returned by http.Request.Context -// to check for cancelled requests. Before Go1.7, PerAttemptTimeout -// has no effect. -// -// It should work on Go1.5, but only if there is no timeout set on the -// *http.Client. Go's stdlib will return an error on the first request -// if that's the case, because it requires a RoundTripper that -// implements the CancelRequest method. -package rehttp - -import ( - "bytes" - "context" - "errors" - "io" - "io/ioutil" - "math" - "math/rand" - "net/http" - "strings" - "time" -) - -// PRNG is the *math.Rand value to use to add jitter to the backoff -// algorithm used in ExpJitterDelay. By default it uses a *rand.Rand -// initialized with a source based on the current time in nanoseconds. -// -// Deprecated: math/rand sources can panic if used concurrently without -// synchronization. PRNG is no longer used by this package and its use -// outside this package is discouraged. -// https://github.com/PuerkitoBio/rehttp/issues/12 -var PRNG = rand.New(rand.NewSource(time.Now().UnixNano())) - -// terribly named interface to detect errors that support Temporary. -type temporaryer interface { - Temporary() bool -} - -// Attempt holds the data describing a RoundTrip attempt. -type Attempt struct { - // Index is the attempt index starting at 0. - Index int - - // Request is the request for this attempt. If a non-nil Response - // is present, this is the same as Response.Request, but since a - // Response may not be available, it is guaranteed to be set on this - // field. - Request *http.Request - - // Response is the response for this attempt. It may be nil if an - // error occurred an no response was received. - Response *http.Response - - // Error is the error returned by the attempt, if any. - Error error -} - -// retryFn is the signature for functions that implement retry strategies. -type retryFn func(attempt Attempt) (bool, time.Duration) - -// DelayFn is the signature for functions that return the delay to apply -// before the next retry. -type DelayFn func(attempt Attempt) time.Duration - -// RetryFn is the signature for functions that return whether a -// retry should be done for the request. -type RetryFn func(attempt Attempt) bool - -// NewTransport creates a Transport with a retry strategy based on -// retry and delay to control the retry logic. It uses the provided -// RoundTripper to execute the requests. If rt is nil, -// http.DefaultTransport is used. -func NewTransport(rt http.RoundTripper, retry RetryFn, delay DelayFn) *Transport { - if rt == nil { - rt = http.DefaultTransport - } - return &Transport{ - RoundTripper: rt, - retry: toRetryFn(retry, delay), - } -} - -// toRetryFn combines retry and delay into a retryFn. -func toRetryFn(retry RetryFn, delay DelayFn) retryFn { - return func(attempt Attempt) (bool, time.Duration) { - if ok := retry(attempt); !ok { - return false, 0 - } - return true, delay(attempt) - } -} - -// RetryAny returns a RetryFn that allows a retry as long as one of -// the retryFns returns true. If retryFns is empty, it always returns false. -func RetryAny(retryFns ...RetryFn) RetryFn { - return func(attempt Attempt) bool { - for _, fn := range retryFns { - if fn(attempt) { - return true - } - } - return false - } -} - -// RetryAll returns a RetryFn that allows a retry if all retryFns -// return true. If retryFns is empty, it always returns true. -func RetryAll(retryFns ...RetryFn) RetryFn { - return func(attempt Attempt) bool { - for _, fn := range retryFns { - if !fn(attempt) { - return false - } - } - return true - } -} - -// RetryMaxRetries returns a RetryFn that retries if the number of -// retries is less than or equal to max. -func RetryMaxRetries(max int) RetryFn { - return func(attempt Attempt) bool { - // < instead of <= because attempt.Index is 0-based, so if max = 1 - // (1 retry), it will return true when attempt.Index == 0 only. - return attempt.Index < max - } -} - -// RetryIsErr returns a RetryFn that retries if the provided -// error predicate - a function that receives an error and returns a -// boolean - returns true for the error associated with the Attempt. -// Note that fn may be called with a nil error. -func RetryIsErr(fn func(error) bool) RetryFn { - return func(attempt Attempt) bool { - return fn(attempt.Error) - } -} - -// RetryTemporaryErr returns a RetryFn that retries if the Attempt's error -// is a temporary error. A temporary error is one that implements -// the Temporary() bool method. Most errors from the net package implement -// this. -// This interface was deprecated in go 1.18. Favor RetryTimeoutErr. -// https://github.com/golang/go/issues/45729 -func RetryTemporaryErr() RetryFn { - return RetryIsErr(func(err error) bool { - if terr, ok := err.(temporaryer); ok { - return terr.Temporary() - } - return false - }) -} - -// RetryTimeoutErr returns a RetryFn that retries if the Attempt's error -// is a timeout error. Before go 1.13, a timeout error is one that implements -// the Timeout() bool method. Most errors from the net package implement this. -// After go 1.13, a timeout error is one that implements the net.Error interface -// which includes both Timeout() and Temporary() to make it less likely to -// falsely identify errors that occurred outside of the net package. -func RetryTimeoutErr() RetryFn { - return RetryIsErr(isTimeoutErr) -} - -// RetryStatusInterval returns a RetryFn that retries if the response's -// status code is in the provided half-closed interval [fromStatus, toStatus) -// (that is, it retries if fromStatus <= Response.StatusCode < toStatus, so -// RetryStatusInterval(400, 500) would retry for any 4xx code, but not for -// 500). -func RetryStatusInterval(fromStatus, toStatus int) RetryFn { - return func(attempt Attempt) bool { - return attempt.Response != nil && - attempt.Response.StatusCode >= fromStatus && - attempt.Response.StatusCode < toStatus - } -} - -// RetryStatuses returns a RetryFn that retries if the response's status -// code is one of the provided statuses. -func RetryStatuses(statuses ...int) RetryFn { - return func(attempt Attempt) bool { - if attempt.Response == nil { - return false - } - for _, st := range statuses { - if st == attempt.Response.StatusCode { - return true - } - } - return false - } -} - -// RetryHTTPMethods returns a RetryFn that retries if the request's -// HTTP method is one of the provided methods. It is meant to be used -// in conjunction with another RetryFn such as RetryTimeoutErr combined -// using RetryAll, otherwise this function will retry any successful -// request made with one of the provided methods. -func RetryHTTPMethods(methods ...string) RetryFn { - for i, m := range methods { - methods[i] = strings.ToUpper(m) - } - - return func(attempt Attempt) bool { - curMeth := strings.ToUpper(attempt.Request.Method) - for _, m := range methods { - if curMeth == m { - return true - } - } - return false - } -} - -// ConstDelay returns a DelayFn that always returns the same delay. -func ConstDelay(delay time.Duration) DelayFn { - return func(attempt Attempt) time.Duration { - return delay - } -} - -// ExpJitterDelay is identical to [ExpJitterDelayWithRand], using -// math/rand.Int63n as the random generator function. -// This package does not call [rand.Seed], so it is the caller's -// responsibility to ensure the default generator is properly seeded. -func ExpJitterDelay(base, max time.Duration) DelayFn { - return ExpJitterDelayWithRand(base, max, rand.Int63n) -} - -// ExpJitterDelayWithRand returns a DelayFn that returns a delay -// between 0 and base * 2^attempt capped at max (an exponential -// backoff delay with jitter). The generator argument is expected -// to generate a random int64 in the half open interval [0, n). -// It is the caller's responsibility to ensure that the function is -// safe for concurrent use. -// -// See the full jitter algorithm in: -// http://www.awsarchitectureblog.com/2015/03/backoff.html -func ExpJitterDelayWithRand(base, max time.Duration, generator func(n int64) int64) DelayFn { - return func(attempt Attempt) time.Duration { - exp := math.Pow(2, float64(attempt.Index)) - top := float64(base) * exp - return time.Duration( - generator(int64(math.Min(float64(max), top))), - ) - } -} - -// Transport wraps a RoundTripper such as *http.Transport and adds -// retry logic. -type Transport struct { - http.RoundTripper - - // PreventRetryWithBody prevents retrying if the request has a body. Since - // the body is consumed on a request attempt, in order to retry a request - // with a body, the body has to be buffered in memory. Setting this - // to true avoids this buffering: the retry logic is bypassed if the body - // is non-nil. - PreventRetryWithBody bool - - // PerAttemptTimeout can be optionally set to add per-attempt timeouts. - // These may be used in place of or in conjunction with overall timeouts. - // For example, a per-attempt timeout of 5s would mean an attempt will - // be canceled after 5s, then the delay fn will be consulted before - // potentially making another attempt, which will again be capped at 5s. - // This means that the overall duration may be up to - // (PerAttemptTimeout + delay) * n, where n is the maximum attempts. - // If using an overall timeout (whether on the http client or the request - // context), the request will stop at whichever timeout is reached first. - // Your RetryFn can determine if a request hit the per-attempt timeout by - // checking if attempt.Error == context.DeadlineExceeded (or use errors.Is - // on go 1.13+). - // time.Duration(0) signals that no per-attempt timeout should be used. - // Note that before go 1.7 this option has no effect. - PerAttemptTimeout time.Duration - - // retry is a function that determines if the request should be retried. - // Unless a retry is prevented based on PreventRetryWithBody, all requests - // go through that function, even those that are typically considered - // successful. - // - // If it returns false, no retry is attempted, otherwise a retry is - // attempted after the specified duration. - retry retryFn -} - -// RoundTrip implements http.RoundTripper for the Transport type. -// It calls its underlying http.RoundTripper to execute the request, and -// adds retry logic as per its configuration. -func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { - var attempt int - preventRetry := req.Body != nil && req.Body != http.NoBody && t.PreventRetryWithBody - - // used as a baseline to set fresh timeouts per-attempt if needed - ctx := getRequestContext(req) - - // get the done cancellation channel for the context, will be nil - // for < go1.7. - done := contextForRequest(req) - - // buffer the body if needed - var br *bytes.Reader - if req.Body != nil && req.Body != http.NoBody && !preventRetry { - var buf bytes.Buffer - if _, err := io.Copy(&buf, req.Body); err != nil { - // cannot even try the first attempt, body has been consumed - req.Body.Close() - return nil, err - } - req.Body.Close() - - br = bytes.NewReader(buf.Bytes()) - req.Body = ioutil.NopCloser(br) - } - - for { - var cancel context.CancelFunc = func() {} // empty unless a timeout is set - reqWithTimeout := req - if t.PerAttemptTimeout != 0 { - reqWithTimeout, cancel = getPerAttemptTimeoutInfo(ctx, req, t.PerAttemptTimeout) - } - res, err := t.RoundTripper.RoundTrip(reqWithTimeout) - if preventRetry { - return injectCancelReader(res, cancel), err - } - - retry, delay := t.retry(Attempt{ - Request: reqWithTimeout, - Response: res, - Index: attempt, - Error: err, - }) - if !retry { - return injectCancelReader(res, cancel), err - } - - if br != nil { - // Per Go's doc: "RoundTrip should not modify the request, - // except for consuming and closing the Body", so the only thing - // to reset on the request is the body, if any. - if _, serr := br.Seek(0, 0); serr != nil { - // failed to retry, return the results - return injectCancelReader(res, cancel), err - } - reqWithTimeout.Body = ioutil.NopCloser(br) - } - // close the disposed response's body, if any - if res != nil { - _, _ = io.Copy(ioutil.Discard, res.Body) - res.Body.Close() - } - cancel() // we're done with this response and won't be returning it, so it's safe to cancel immediately - - select { - case <-time.After(delay): - attempt++ - case <-done: - // request canceled by caller (post-1.7), don't retry - return nil, errors.New("net/http: request canceled") - case <-req.Cancel: - // request canceled by caller (pre-1.7), don't retry - return nil, errors.New("net/http: request canceled") - } - } -} diff --git a/vendor/github.com/PuerkitoBio/rehttp/timeouterr_post113.go b/vendor/github.com/PuerkitoBio/rehttp/timeouterr_post113.go deleted file mode 100644 index 4143d7c73..000000000 --- a/vendor/github.com/PuerkitoBio/rehttp/timeouterr_post113.go +++ /dev/null @@ -1,18 +0,0 @@ -//go:build go1.13 -// +build go1.13 - -package rehttp - -import ( - "errors" - "net" -) - -func isTimeoutErr(err error) bool { - var neterr net.Error - if errors.As(err, &neterr) && neterr.Timeout() { - return true - } - - return false -} diff --git a/vendor/github.com/PuerkitoBio/rehttp/timeouterr_pre113.go b/vendor/github.com/PuerkitoBio/rehttp/timeouterr_pre113.go deleted file mode 100644 index 4517e44e1..000000000 --- a/vendor/github.com/PuerkitoBio/rehttp/timeouterr_pre113.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !go1.13 -// +build !go1.13 - -package rehttp - -type timeouter interface { - Timeout() bool -} - -func isTimeoutErr(err error) bool { - if terr, ok := err.(timeouter); ok { - return terr.Timeout() - } - return false -} diff --git a/vendor/github.com/adjust/rmq/v5/.gitignore b/vendor/github.com/adjust/rmq/v5/.gitignore deleted file mode 100644 index 219415f07..000000000 --- a/vendor/github.com/adjust/rmq/v5/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test -/vendor - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof - -.idea \ No newline at end of file diff --git a/vendor/github.com/adjust/rmq/v5/LICENSE b/vendor/github.com/adjust/rmq/v5/LICENSE deleted file mode 100644 index 7fe0027e9..000000000 --- a/vendor/github.com/adjust/rmq/v5/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 adjust - -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/adjust/rmq/v5/README.md b/vendor/github.com/adjust/rmq/v5/README.md deleted file mode 100644 index 1fd029e94..000000000 --- a/vendor/github.com/adjust/rmq/v5/README.md +++ /dev/null @@ -1,654 +0,0 @@ -[![Build Status](https://github.com/adjust/rmq/workflows/test/badge.svg)](https://github.com/adjust/rmq/actions?query=branch%3Amaster+workflow%3Atest) -[![GoDoc](https://pkg.go.dev/badge/github.com/adjust/rmq)](https://pkg.go.dev/github.com/adjust/rmq) - -## Overview - -rmq is short for Redis message queue. It's a message queue system written in Go -and backed by Redis. - -## Basic Usage - -Let's take a look at how to use rmq. - -### Import - -Of course you need to import rmq wherever you want to use it. - -```go -import "github.com/adjust/rmq/v5" -``` - -### Connection - -Before we get to queues, we first need to establish a connection. Each rmq -connection has a name (used in statistics) and Redis connection details -including which Redis database to use. The most basic Redis connection uses a -TCP connection to a given host and a port: - -```go -connection, err := rmq.OpenConnection("my service", "tcp", "localhost:6379", 1, errChan) -``` - -It's also possible to access a Redis listening on a Unix socket: - -```go -connection, err := rmq.OpenConnection("my service", "unix", "/tmp/redis.sock", 1, errChan) -``` - -For more flexible setup you can pass Redis options or create your own Redis client: - -```go -connection, err := OpenConnectionWithRedisOptions("my service", redisOptions, errChan) -``` - -```go -connection, err := OpenConnectionWithRedisClient("my service", redisClient, errChan) -``` - -If the Redis instance can't be reached you will receive an error indicating this. - -Please also note the `errChan` parameter. There is some rmq logic running in -the background which can run into Redis errors. If you pass an error channel to -the `OpenConnection()` functions rmq will send those background errors to this -channel so you can handle them asynchronously. For more details about this and -handling suggestions see the section about handling background errors below. - -#### Connecting to a Redis cluster - -In order to connect to a Redis cluster please use `OpenClusterConnection()`: - -```go -redisClusterOptions := &redis.ClusterOptions{ /* ... */ } -redisClusterClient := redis.NewClusterClient(redisClusterOptions) -connection, err := OpenClusterConnection("my service", redisClusterClient, errChan) -``` - -Note that such an rmq cluster connection uses different Redis than rmq connections -opened by `OpenConnection()` or similar. If you have used a Redis instance -with `OpenConnection()` then it is NOT SAFE to reuse that rmq system by connecting -to it via `OpenClusterConnection()`. The cluster state won't be compatible and -this will likely lead to data loss. - -If you've previously used `OpenConnection()` or similar you should only consider -using `OpenClusterConnection()` with a fresh Redis cluster. - -### Queues - -Once we have a connection we can use it to finally access queues. Each queue -must have a unique name by which we address it. Queues are created once they -are accessed. There is no need to declare them in advance. Here we open a queue -named "tasks": - -```go -taskQueue, err := connection.OpenQueue("tasks") -``` - -Again, possibly Redis errors might be returned. - -### Producers - -An empty queue is boring, let's add some deliveries! Internally all deliveries -are saved to Redis lists as strings. This is how you can publish a string -payload to a queue: - -```go -delivery := "task payload" -err := TaskQueue.Publish(delivery) -``` - -In practice, however, it's more common to have instances of some struct that we -want to publish to a queue. Assuming `task` is of some type like `Task`, this -is how to publish the JSON representation of that task: - -```go -// create task -taskBytes, err := json.Marshal(task) -if err != nil { - // handle error -} - -err = taskQueue.PublishBytes(taskBytes) -``` - -For a full example see [`example/producer`][producer.go]. - -[producer.go]: example/producer/main.go - -### Consumers - -Now that our queue starts filling, let's add a consumer. After opening the -queue as before, we need it to start consuming before we can add consumers. - -```go -err := taskQueue.StartConsuming(10, time.Second) -``` - -This sets the prefetch limit to 10 and the poll duration to one second. This -means the queue will fetch up to 10 deliveries at a time before giving them to -the consumers. To avoid idling consumers while the queues are full, the -prefetch limit should always be greater than the number of consumers you are -going to add. If the queue gets empty, the poll duration sets how long rmq will -wait before checking for new deliveries in Redis. - -Once this is set up, we can actually add consumers to the consuming queue. - -```go -taskConsumer := &TaskConsumer{} -name, err := taskQueue.AddConsumer("task-consumer", taskConsumer) -``` - -To uniquely identify each consumer internally rmq creates a random name with -the given prefix. For example in this case `name` might be -`task-consumer-WB1zaq`. This name is only used in statistics. - -In our example above the injected `taskConsumer` (of type `*TaskConsumer`) must -implement the `rmq.Consumer` interface. For example: - -```go -func (consumer *TaskConsumer) Consume(delivery rmq.Delivery) { - var task Task - if err = json.Unmarshal([]byte(delivery.Payload()), &task); err != nil { - // handle json error - if err := delivery.Reject(); err != nil { - // handle reject error - } - return - } - - // perform task - log.Printf("performing task %s", task) - if err := delivery.Ack(); err != nil { - // handle ack error - } -} -``` - -First we unmarshal the JSON package found in the delivery payload. If this -fails we reject the delivery. Otherwise we perform the task and ack the -delivery. - -If you don't actually need a consumer struct you can use `AddConsumerFunc` -instead and pass a consumer function which handles an `rmq.Delivery`: - -```go -name, err := taskQueue.AddConsumerFunc(func(delivery rmq.Delivery) { - // handle delivery and call Ack() or Reject() on it -}) -``` - -Please note that `delivery.Ack()` and similar functions have a built-in retry -mechanism which will block your consumers in some cases. This is because -because failing to acknowledge a delivery is potentially dangerous. For details -see the section about background errors below. - -For a full example see [`example/consumer`][consumer.go]. - -#### Consumer Lifecycle - -As described above you can add consumers to a queue. For each consumer rmq -takes one of the prefetched unacked deliveries from the delivery channel and -passes it to the consumer's `Consume()` function. The next delivery will only -be passed to the same consumer once the prior `Consume()` call returns. So each -consumer will only be consuming a single delivery at any given time. - -Furthermore each `Consume()` call is expected to call either `delivery.Ack()`, -`delivery.Reject()` or `delivery.Push()` (see below). If that's not the case -these deliveries will remain unacked and the prefetch goroutine won't make -progress after a while. So make sure you always call exactly one of those -functions in your `Consume()` implementations. - -[consumer.go]: example/consumer/main.go - -## Background Errors - -It's recommended to inject an error channel into the `OpenConnection()` -functions. This section describes it's purpose and how you might use it to -monitor rmq background Redis errors. - -There are three sources of background errors which rmq detects (and handles -internally): - -1. The `OpenConnection()` functions spawn a goroutine which keeps a heartbeat - Redis key alive. This is important so that the cleaner (see below) can tell - which connections are still alive and must not be cleaned yet. If the - heartbeat goroutine fails to update the heartbeat Redis key repeatedly foo - too long the cleaner might clean up the connection prematurely. To avoid - this the connection will automatically stop all consumers after 45 - consecutive heartbeat errors. This magic number is based on the details of - the heartbeat key: The heartbeat tries to update the key every second with a - TTL of one minute. So only after 60 failed attempts the heartbeat key would - be dead. - - Every time this goroutine runs into a Redis error it gets send to the error - channel as `HeartbeatError`. - -2. The `StartConsuming()` function spawns a goroutine which is responsible for - prefetching deliveries from the Redis `ready` list and moving them into a - delivery channel. This delivery channels feeds into your consumers - `Consume()` functions. If the prefetch goroutine runs into Redis errors this - basically means that there won't be new deliveries being sent to your - consumers until it can fetch new ones. So these Redis errors are not - dangerous, it just means that your consumers will start idling until the - Redis connection recovers. - - Every time this goroutine runs into a Redis error it gets send to the error - channel as `ConsumeError`. - -3. The delivery functions `Ack()`, `Reject()` and `Push()` have a built-in - retry mechanism. This is because failing to acknowledge a delivery - is potentially dangerous. The consumer has already handled the delivery, so - if it can't ack it the cleaner might end up moving it back to the ready list - so another consumer might end up consuming it again in the future, leading - to double delivery. - - So if a delivery failed to be acked because of a Redis error the `Ack()` - call will block and retry once a second until it either succeeds or until - consuming gets stopped (see below). In the latter case the `Ack()` call will - return `rmq.ErrorConsumingStopped` which you should handle in your consume - function. For example you might want to log about the delivery so you can - manually remove it from the unacked or ready list before you start new - consumers. Or at least you can know which deliveries might end up being - consumed twice. - - Every time these functions runs into a Redis error it gets send to the error - channel as `DeliveryError`. - -Each of those error types has a field `Count` which tells you how often the -operation failed consecutively. This indicates for how long the affected Redis -instance has been unavailable. One general way of using this information might -be to have metrics about the error types including the error count so you can -keep track of how stable your Redis instances and connections are. By -monitoring this you might learn about instabilities before they affect your -services in significant ways. - -Below is some more specific advice on handling the different error cases -outlined above. Keep in mind though that all of those errors are likely to -happen at the same time, as Redis tends to be up or down completely. But if -you're using multi Redis instance setup like [nutcracker][nutcracker] you might -see some of them in isolation from the others. - -1. `HeartbeatErrors`: Once `err.Count` equals `HeartbeatErrorLimit` you should - know that the consumers of this connection will stop consuming. And they - won't restart consuming on their own. This is a condition you should closely - monitor because this means you will have to restart your service in order to - resume consuming. Before restarting you should check your Redis instance. - -2. `ConsumeError`: These are mostly informational. As long as those errors keep - happening the consumers will effectively be paused. But once these - operations start succeeding again the consumers will resume consumers on - their own. - -3. `DeliveryError`: When you see deliveries failing to ack repeatedly this also - means your consumers won't make progress as they will keep retrying to ack - pending deliveries before starting to consume new ones. As long as this - keeps happening you should avoid stopping the service if you can. That is - because the already consumed by not yet unacked deliveries will be returned - to `ready` be the cleaner afterwards, which leads to double delivery. So - ideally you try to get Redis connection up again as long as the deliveries - are still trying to ack. Once acking works again it's safe to restart again. - - More realistically, if you still need to stop the service when Redis is - down, keep in mind that calling `StopConsuming()` will make the blocking - `Ack()` calls return with `ErrorConsumingStopped`, so you can handle that - case to make an attempt to either avoid the double delivery or at least - track it for future investigation. - -[nutcracker]: https://github.com/twitter/twemproxy - -## Advanced Usage - -### Batch Consumers - -Sometimes it's useful to have consumers work on batches of deliveries instead -of individual ones. For example for bulk database inserts. In those cases you -can use `AddBatchConsumer()`: - -```go -batchConsumer := &MyBatchConsumer{} -name, err := taskQueue.AddBatchConsumer("my-consumer", 100, time.Second, batchConsumer) -``` - -In this example we create a batch consumer which will receive batches of up to -100 deliveries. We set the `batchTimeout` to one second, so if there are less -than 100 deliveries per second we will still consume at least one batch per -second (which would contain less than 100 deliveries). - -The `rmq.BatchConsumer` interface is very similar to `rmq.Consumer`. - -```go -func (consumer *MyBatchConsumer) Consume(batch rmq.Deliveries) { - payloads := batch.Payloads() - // handle payloads - if errors := batch.Ack(); len(errors) > 0 { - // handle ack errors - } -} -``` - -Note that `batch.Ack()` acknowledges all deliveries in the batch. It's also -possible to ack some of the deliveries and reject the rest. It uses the same -retry mechanism per delivery as discussed above. If some of the deliveries -continue to fail to ack when consuming gets stopped (see below), then -`batch.Ack()` will return an error map `map[int]error`. For each entry in this -map the key will be the index of the delivery which failed to ack and the value -will be the error it ran into. That way you can map the errors back to the -deliveries to know which deliveries are at risk of being consumed again in the -future as discussed above. - -For a full example see [`example/batch_consumer`][batch_consumer.go]. - -[batch_consumer.go]: example/batch_consumer/main.go - -### Push Queues - -Another thing which can be useful is a mechanism for retries. Let's say you -have tasks which can fail for external reasons but you'd like to retry them a -few times after a while before you give up. In that case you can set up a chain -of push queues like this: - -``` -incomingQ -> pushQ1 -> pushQ2 -``` - -In the queue setup code it would look like this (error handling omitted for -brevity): - -```go -incomingQ, err := connection.OpenQueue("incomingQ") -pushQ1, err := connection.OpenQueue("pushQ1") -pushQ2, err := connection.OpenQueue("pushQ2") -incomingQ.SetPushQueue(pushQ1) -pushQ1.SetPushQueue(pushQ2) -_, err := incomingQ.AddConsumer("incomingQ", NewConsumer()) -_, err := pushQ1.AddConsumer("pushQ1", NewConsumer()) -_, err := pushQ2.AddConsumer("pushQ2", NewConsumer()) -``` - -If you have set up your queues like this, you can now call `delivery.Push()` in -your `Consume()` function to push the delivery from the consuming queue to the -associated push queue. So if consumption fails on `incomingQ`, then the -delivery would be moved to `pushQ1` and so on. If you have the consumers wait -until the deliveries have a certain age you can use this pattern to retry after -certain durations. - -Note that `delivery.Push()` has the same affect as `delivery.Reject()` if the -queue has no push queue set up. So in our example above, if the delivery fails -in the consumer on `pushQ2`, then the `Push()` call will reject the delivery. - -### Stop Consuming - -If you want to stop consuming from the queue, you can call `StopConsuming()`: - -```go -finishedChan := taskQueue.StopConsuming() -``` - -When `StopConsuming()` is called, it will immediately stop fetching more -deliveries from Redis and won't send any more of the already prefetched -deliveries to consumers. - -In the background it will make pending `Ack()` calls return -`rmq.ErrorConsumingStopped` if they still run into Redis errors (see above) and -wait for all consumers to finish consuming their current delivery before -closing the returned `finishedChan`. So while `StopConsuming()` returns -immediately, you can wait on the returned channel until all consumers are done: - -```go -<-finishedChan -``` - -You can also stop consuming on all queues in your connection: - -```go -finishedChan := connection.StopAllConsuming() -``` - -Wait on the `finishedChan` to wait for all consumers on all queues to finish. - -This is useful to implement a graceful shutdown of a consumer service. Please -note that after calling `StopConsuming()` the queue might not be in a state -where you can add consumers and call `StartConsuming()` again. If you have a -use case where you actually need that sort of flexibility, please let us know. -Currently for each queue you are only supposed to call `StartConsuming()` and -`StopConsuming()` at most once. - -### Return Rejected Deliveries - -Even if you don't have a push queue setup there are cases where you need to -consume previously failed deliveries again. For example an external dependency -might have an issue or you might have deployed a broken consumer service which -rejects all deliveries for some reason. - -In those cases you would wait for the external party to recover or fix your -mistake to get ready to reprocess the deliveries again. Now you can return the -deliveries by opening affected queue and call `ReturnRejected()`: - -```go -returned, err := queue.ReturnRejected(10000) -``` - -In this case we ask rmq to return up to 10k deliveries from the `rejected` list -to the `ready` list. To return all of them you can pass `math.MaxInt64`. - -If there was no error it returns the number of deliveries that were moved. - -If you find yourself doing this regularly on some queues consider setting up a -push queue to automatically retry failed deliveries regularly. - -See [`example/returner`][returner.go] - -[returner.go]: example/returner/main.go - -### Purge Rejected Deliveries - -You might run into the case where you have rejected deliveries which you don't -intend to retry again for one reason or another. In those cases you can clear -the full `rejected` list by calling `PurgeRejected()`: - -```go -count, err := queue.PurgeRejected() -``` - -It returns the number of purged deliveries. - -Similarly, there's a function to clear the `ready` list of deliveries: - -```go -count, err := queue.PurgeReady() -``` - -See [`example/purger`][purger.go]. - -[purger.go]: example/purger/main.go - -### Cleaner - -You should regularly run a queue cleaner to make sure no unacked deliveries are -stuck in the queue system. The background is that a consumer service prefetches -deliveries by moving them from the `ready` list to an `unacked` list associated -with the queue connection. If the consumer dies by crashing or even by being -gracefully shut down by calling `StopConsuming()`, the unacked deliveries will -remain in that Redis list. - -If you run a queue cleaner regularly it will detect queue connections whose -heartbeat expired and will clean up all their consumer queues by moving their -unacked deliveries back to the `ready` list. - -Although it should be safe to run multiple cleaners, it's recommended to run -exactly one instance per queue system and have it trigger the cleaning process -regularly, like once a minute. - -See [`example/cleaner`][cleaner.go]. - -[cleaner.go]: example/cleaner/main.go - -### Header - -Redis protocol does not define a specific way to pass additional data like header. -However, there is often need to pass them (for example for traces propagation). - -This implementation injects optional header values marked with a signature into -payload body during publishing. When message is consumed, if signature is present, -header and original payload are extracted from augmented payload. - -Header is defined as `http.Header` for better interoperability with existing libraries, -for example with [`propagation.HeaderCarrier`](https://pkg.go.dev/go.opentelemetry.io/otel/propagation#HeaderCarrier). - -```go - // .... - - h := make(http.Header) - h.Set("X-Baz", "quux") - - // You can add header to your payload during publish. - _ = pub.Publish(rmq.PayloadWithHeader(`{"foo":"bar"}`, h)) - - // .... - - _, _ = con.AddConsumerFunc("tag", func(delivery rmq.Delivery) { - // And receive header back in consumer. - delivery.(rmq.WithHeader).Header().Get("X-Baz") // "quux" - - // .... - }) -``` - -Adding a header is an explicit opt-in operation and so it does not affect library's -backwards compatibility by default (when not used). - -Please note that adding header may lead to compatibility issues if: -* consumer is built with older version of `rmq` when publisher has already - started using header, this can be avoided by upgrading consumers before publishers; -* consumer is not using `rmq` (other libs, low level tools like `redis-cli`) and is - not aware of payload format extension. - -## Testing Included - -To simplify testing of queue producers and consumers we include test mocks. - -### Test Connection - -As before, we first need a queue connection, but this time we use a -`rmq.TestConnection` that doesn't need any connection settings. - -```go -testConn := rmq.NewTestConnection() -``` - -If you are using a testing framework that uses test suites, you can reuse that -test connection by setting it up once for the suite and resetting it with -`testConn.Reset()` before each test. - -### Producer Tests - -Now let's say we want to test the function `publishTask()` that creates a task -and publishes it to a queue from that connection. - -```go -// call the function that should publish a task -publishTask(testConn) - -// check that the task is published -assert.Equal(t, "task payload", suite.testConn.GetDelivery("tasks", 0)) -``` - -The `assert.Equal` part is from [testify][testify], but it will look similar -for other testing frameworks. Given a `rmq.TestConnection`, we can check the -deliveries that were published to its queues (since the last `Reset()` call) -with `GetDelivery(queueName, index)`. In this case we want to extract the first -(and possibly only) delivery that was published to queue `tasks` and just check -the payload string. - -If the payload is JSON again, the unmarshalling and check might look like this: - -```go -var task Task -err := json.Unmarshal([]byte(suite.testConn.GetDelivery("tasks", 0)), &task) -assert.NoError(t, err) -assert.NotNil(t, task) -assert.Equal(t, "value", task.Property) -``` - -If you expect a producer to create multiple deliveries you can use different -indexes to access them all. - -```go -assert.Equal(t, "task1", suite.testConn.GetDelivery("tasks", 0)) -assert.Equal(t, "task2", suite.testConn.GetDelivery("tasks", 1)) -``` - -For convenience there's also a function `GetDeliveries` that returns all -published deliveries to a queue as string array. - -```go -assert.Equal(t, []string{"task1", "task2"}, suite.testConn.GetDeliveries("tasks")) -``` - -These examples assume that you inject the `rmq.Connection` into your testable -functions. If you inject instances of `rmq.Queue` instead, you can use -`rmq.TestQueue` instances in tests and access their `LastDeliveries` (since -`Reset()`) directly. - -[testify]: https://github.com/stretchr/testify - -### Consumer Tests - -Testing consumers is a bit easier because consumers must implement the -`rmq.Consumer` interface. In the tests just create an `rmq.TestDelivery` and -pass it to your `Consume()` function. This example creates a test delivery from -a string and then checks that the delivery was acked. - -```go -consumer := &TaskConsumer{} -delivery := rmq.NewTestDeliveryString("task payload") - -consumer.Consume(delivery) - -assert.Equal(t, rmq.Acked, delivery.State) -``` - -The `State` field will always be one of these values: - -- `rmq.Acked`: The delivery was acked -- `rmq.Rejected`: The delivery was rejected -- `rmq.Pushed`: The delivery was pushed (see below) -- `rmq.Unacked`: Nothing of the above - -If your packages are JSON marshalled objects, then you can create test -deliveries out of those like this: - -```go -task := Task{Property: "bad value"} -delivery := rmq.NewTestDelivery(task) -``` - -### Integration Tests - -If you want to write integration tests which exercise both producers and -consumers at the same time, you can use the -`rmq.OpenConnectionWithTestRedisClient` constructor. It returns a real -`rmq.Connection` instance which is backed by an in-memory Redis client -implementation. That way it behaves exactly as in production, just without the -durability of a real Redis client. Don't use this in production! - -## Statistics - -Given a connection, you can call `connection.CollectStats()` to receive -`rmq.Stats` about all open queues, connections and consumers. If you run -[`example/handler`][handler.go] you can see what's available: - - - -In this example you see 5 connections consuming `task_kind1`, each wich 5 -consumers each. They have a total of 1007 packages unacked. Below the marker you see -connections which are not consuming. One of the handler connections died -because I stopped the handler. Running the cleaner would clean that up (see -below). - -[handler.go]: example/handler/main.go - -### Prometheus - -If you are using Prometheus, [rmqprom](https://github.com/pffreitas/rmqprom) -collects statistics about all open queues and exposes them as Prometheus -metrics. diff --git a/vendor/github.com/adjust/rmq/v5/batch_consumer.go b/vendor/github.com/adjust/rmq/v5/batch_consumer.go deleted file mode 100644 index e257b0564..000000000 --- a/vendor/github.com/adjust/rmq/v5/batch_consumer.go +++ /dev/null @@ -1,11 +0,0 @@ -package rmq - -type BatchConsumer interface { - Consume(batch Deliveries) -} - -type BatchConsumerFunc func(Deliveries) - -func (batchConsumerFunc BatchConsumerFunc) Consume(batch Deliveries) { - batchConsumerFunc(batch) -} diff --git a/vendor/github.com/adjust/rmq/v5/cleaner.go b/vendor/github.com/adjust/rmq/v5/cleaner.go deleted file mode 100644 index 6b575eaf8..000000000 --- a/vendor/github.com/adjust/rmq/v5/cleaner.go +++ /dev/null @@ -1,83 +0,0 @@ -package rmq - -import "math" - -type Cleaner struct { - connection Connection -} - -func NewCleaner(connection Connection) *Cleaner { - return &Cleaner{connection: connection} -} - -// Clean cleans the connection of the cleaner. This is useful to make sure no -// deliveries get lost. The main use case is if your consumers get restarted -// there will be unacked deliveries assigned to the connection. Once the -// heartbeat of that connection dies the cleaner can recognize that and remove -// those unacked deliveries back to the ready list. If there was no error it -// returns the number of deliveries which have been returned from unacked lists -// to ready lists across all cleaned connections and queues. -func (cleaner *Cleaner) Clean() (returned int64, err error) { - connectionNames, err := cleaner.connection.getConnections() - if err != nil { - return 0, err - } - - for _, connectionName := range connectionNames { - hijackedConnection := cleaner.connection.hijackConnection(connectionName) - switch err := hijackedConnection.checkHeartbeat(); err { - case nil: // active connection - continue - case ErrorNotFound: - n, err := cleanStaleConnection(hijackedConnection) - if err != nil { - return 0, err - } - returned += n - default: - return 0, err - } - } - - return returned, nil -} - -func cleanStaleConnection(staleConnection Connection) (returned int64, err error) { - queueNames, err := staleConnection.getConsumingQueues() - if err != nil { - return 0, err - } - - for _, queueName := range queueNames { - queue, err := staleConnection.OpenQueue(queueName) - if err != nil { - return 0, err - } - - n, err := cleanQueue(queue) - if err != nil { - return 0, err - } - - returned += n - } - - if err := staleConnection.closeStaleConnection(); err != nil { - return 0, err - } - - // log.Printf("rmq cleaner cleaned connection %s", staleConnection) - return returned, nil -} - -func cleanQueue(queue Queue) (returned int64, err error) { - returned, err = queue.ReturnUnacked(math.MaxInt64) - if err != nil { - return 0, err - } - if err := queue.closeInStaleConnection(); err != nil { - return 0, err - } - // log.Printf("rmq cleaner cleaned queue %s %d", queue, returned) - return returned, nil -} diff --git a/vendor/github.com/adjust/rmq/v5/connection.go b/vendor/github.com/adjust/rmq/v5/connection.go deleted file mode 100644 index 055be0f94..000000000 --- a/vendor/github.com/adjust/rmq/v5/connection.go +++ /dev/null @@ -1,351 +0,0 @@ -package rmq - -import ( - "fmt" - "strings" - "sync" - "time" - - "github.com/redis/go-redis/v9" -) - -const ( - // NOTE: Be careful when changing any of these values. - // Currently we update the heartbeat every second with a TTL of a minute. - // This means that if we fail to update the heartbeat 60 times in a row - // the connection might get cleaned up by a cleaner. So we want to set the - // error limit to a value lower like this (like 45) to make sure we stop - // all consuming before that happens. - heartbeatDuration = time.Minute // TTL of heartbeat key - heartbeatInterval = time.Second // how often we update the heartbeat key - HeartbeatErrorLimit = 45 // stop consuming after this many heartbeat errors -) - -// Connection is an interface that can be used to test publishing -type Connection interface { - OpenQueue(name string) (Queue, error) - CollectStats(queueList []string) (Stats, error) - GetOpenQueues() ([]string, error) - StopAllConsuming() <-chan struct{} - - // internals - // used in cleaner - checkHeartbeat() error - getConnections() ([]string, error) - hijackConnection(name string) Connection - closeStaleConnection() error - getConsumingQueues() ([]string, error) - // used for stats - openQueue(name string) Queue - // used in tests - stopHeartbeat() error - flushDb() error - unlistAllQueues() error -} - -// Connection is the entry point. Use a connection to access queues, consumers and deliveries -// Each connection has a single heartbeat shared among all consumers -type redisConnection struct { - Name string - heartbeatKey string // key to keep alive - queuesKey string // key to list of queues consumed by this connection - - consumersTemplate string - unackedTemplate string - readyTemplate string - rejectedTemplate string - - redisClient RedisClient - errChan chan<- error - heartbeatStop chan chan struct{} - - lock sync.Mutex - stopped bool - // list of all queues that have been opened in this connection - // this is used to handle heartbeat errors without relying on the redis connection - openQueues []Queue -} - -// OpenConnection opens and returns a new connection -func OpenConnection(tag string, network string, address string, db int, errChan chan<- error) (Connection, error) { - return OpenConnectionWithRedisOptions(tag, &redis.Options{Network: network, Addr: address, DB: db}, errChan) -} - -// OpenConnectionWithRedisOptions allows you to pass more flexible options -func OpenConnectionWithRedisOptions(tag string, redisOption *redis.Options, errChan chan<- error) (Connection, error) { - return OpenConnectionWithRedisClient(tag, redis.NewClient(redisOption), errChan) -} - -// OpenConnectionWithRedisClient opens and returns a new connection -// This can be used to passa redis.ClusterClient. -func OpenConnectionWithRedisClient(tag string, redisClient redis.Cmdable, errChan chan<- error) (Connection, error) { - return OpenConnectionWithRmqRedisClient(tag, RedisWrapper{redisClient}, errChan) -} - -// OpenConnectionWithTestRedisClient opens and returns a new connection which -// uses a test redis client internally. This is useful in integration tests. -func OpenConnectionWithTestRedisClient(tag string, errChan chan<- error) (Connection, error) { - return OpenConnectionWithRmqRedisClient(tag, NewTestRedisClient(), errChan) -} - -// OpenConnectionWithRmqRedisClient: If you would like to use a redis client other than the ones -// supported in the constructors above, you can implement the RedisClient interface yourself -func OpenConnectionWithRmqRedisClient(tag string, redisClient RedisClient, errChan chan<- error) (Connection, error) { - return openConnection(tag, redisClient, false, errChan) -} - -// OpenClusterConnection: Same as OpenConnectionWithRedisClient, but using Redis hash tags {} instead of []. -func OpenClusterConnection(tag string, redisClient redis.Cmdable, errChan chan<- error) (Connection, error) { - return openConnection(tag, RedisWrapper{redisClient}, true, errChan) -} - -func openConnection(tag string, redisClient RedisClient, useRedisHashTags bool, errChan chan<- error) (Connection, error) { - name := fmt.Sprintf("%s-%s", tag, RandomString(6)) - - connection := &redisConnection{ - Name: name, - heartbeatKey: strings.Replace(connectionHeartbeatTemplate, phConnection, name, 1), - queuesKey: strings.Replace(connectionQueuesTemplate, phConnection, name, 1), - consumersTemplate: getTemplate(connectionQueueConsumersBaseTemplate, useRedisHashTags), - unackedTemplate: getTemplate(connectionQueueUnackedBaseTemplate, useRedisHashTags), - readyTemplate: getTemplate(queueReadyBaseTemplate, useRedisHashTags), - rejectedTemplate: getTemplate(queueRejectedBaseTemplate, useRedisHashTags), - redisClient: redisClient, - errChan: errChan, - heartbeatStop: make(chan chan struct{}, 1), - } - - if err := connection.updateHeartbeat(); err != nil { // checks the connection - return nil, err - } - - // add to connection set after setting heartbeat to avoid race with cleaner - if _, err := redisClient.SAdd(connectionsKey, name); err != nil { - return nil, err - } - - go connection.heartbeat(errChan) - // log.Printf("rmq connection connected to %s %s:%s %d", name, network, address, db) - return connection, nil -} - -func (connection *redisConnection) updateHeartbeat() error { - return connection.redisClient.Set(connection.heartbeatKey, "1", heartbeatDuration) -} - -// heartbeat keeps the heartbeat key alive -func (connection *redisConnection) heartbeat(errChan chan<- error) { - errorCount := 0 // number of consecutive errors - - ticker := time.NewTicker(heartbeatInterval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: - // continue below - case c := <-connection.heartbeatStop: - close(c) - return - } - - err := connection.updateHeartbeat() - if err == nil { // success - errorCount = 0 - continue - } - // unexpected redis error - - errorCount++ - - if errorCount >= HeartbeatErrorLimit { - // reached error limit - connection.StopAllConsuming() - // Clients reading from errChan need to see this error - // This allows them to shut themselves down - // Therefore we block adding it to errChan to ensure delivery - errChan <- &HeartbeatError{RedisErr: err, Count: errorCount} - return - } else { - select { // try to add error to channel, but don't block - case errChan <- &HeartbeatError{RedisErr: err, Count: errorCount}: - default: - } - } - // keep trying until we hit the limit - } -} - -func (connection *redisConnection) String() string { - return connection.Name -} - -// OpenQueue opens and returns the queue with a given name -func (connection *redisConnection) OpenQueue(name string) (Queue, error) { - connection.lock.Lock() - defer connection.lock.Unlock() - - if connection.stopped { - return nil, ErrorConsumingStopped - } - - if _, err := connection.redisClient.SAdd(queuesKey, name); err != nil { - return nil, err - } - - queue := connection.openQueue(name) - connection.openQueues = append(connection.openQueues, queue) - - return queue, nil -} - -// CollectStats collects and returns stats -func (connection *redisConnection) CollectStats(queueList []string) (Stats, error) { - return CollectStats(queueList, connection) -} - -// GetOpenQueues returns a list of all open queues -func (connection *redisConnection) GetOpenQueues() ([]string, error) { - return connection.redisClient.SMembers(queuesKey) -} - -// StopAllConsuming stops consuming on all queues opened in this connection. -// It returns a channel which can be used to wait for all active consumers to -// finish their current Consume() call. This is useful to implement graceful -// shutdown. -func (connection *redisConnection) StopAllConsuming() <-chan struct{} { - connection.lock.Lock() - defer func() { - // regardless of how we exit this method, the connection is always stopped when we return - connection.stopped = true - connection.lock.Unlock() - }() - - finishedChan := make(chan struct{}) - - // If we are already stopped or there are no open queues, then there is nothing to do - if connection.stopped || len(connection.openQueues) == 0 { - close(finishedChan) - return finishedChan - } - - chans := make([]<-chan struct{}, 0, len(connection.openQueues)) - for _, queue := range connection.openQueues { - chans = append(chans, queue.StopConsuming()) - } - - go func() { - // wait for all channels to be closed - for _, c := range chans { - <-c - } - close(finishedChan) - // log.Printf("rmq connection stopped consuming %s", queue) - }() - - return finishedChan -} - -// checkHeartbeat retuns true if the connection is currently active in terms of heartbeat -func (connection *redisConnection) checkHeartbeat() error { - heartbeatKey := strings.Replace(connectionHeartbeatTemplate, phConnection, connection.Name, 1) - ttl, err := connection.redisClient.TTL(heartbeatKey) - if err != nil { - return err - } - if ttl <= 0 { - return ErrorNotFound - } - return nil -} - -// getConnections returns a list of all open connections -func (connection *redisConnection) getConnections() ([]string, error) { - return connection.redisClient.SMembers(connectionsKey) -} - -// hijackConnection reopens an existing connection for inspection purposes without starting a heartbeat -func (connection *redisConnection) hijackConnection(name string) Connection { - return &redisConnection{ - Name: name, - heartbeatKey: strings.Replace(connectionHeartbeatTemplate, phConnection, name, 1), - queuesKey: strings.Replace(connectionQueuesTemplate, phConnection, name, 1), - consumersTemplate: connection.consumersTemplate, - unackedTemplate: connection.unackedTemplate, - readyTemplate: connection.readyTemplate, - rejectedTemplate: connection.rejectedTemplate, - redisClient: connection.redisClient, - } -} - -// closes a stale connection. not to be called on an active connection -func (connection *redisConnection) closeStaleConnection() error { - count, err := connection.redisClient.SRem(connectionsKey, connection.Name) - if err != nil { - return err - } - if count == 0 { - return ErrorNotFound - } - - // NOTE: we're not checking count here because stale connection might not - // have been consuming from any queue, in which case this key doesn't exist - if _, err = connection.redisClient.Del(connection.queuesKey); err != nil { - return err - } - - return nil -} - -// getConsumingQueues returns a list of all queues consumed by this connection -func (connection *redisConnection) getConsumingQueues() ([]string, error) { - return connection.redisClient.SMembers(connection.queuesKey) -} - -// openQueue opens a queue without adding it to the set of queues -func (connection *redisConnection) openQueue(name string) Queue { - return newQueue( - name, - connection.Name, - connection.queuesKey, - connection.consumersTemplate, - connection.unackedTemplate, - connection.readyTemplate, - connection.rejectedTemplate, - connection.redisClient, - connection.errChan, - ) -} - -// stopHeartbeat stops the heartbeat of the connection -// it does not remove it from the list of connections so it can later be found by the cleaner -func (connection *redisConnection) stopHeartbeat() error { - if connection.heartbeatStop == nil { - return ErrorNotFound - } - - heartbeatStopped := make(chan struct{}) - connection.heartbeatStop <- heartbeatStopped - <-heartbeatStopped - connection.heartbeatStop = nil // avoid stopping twice - - count, err := connection.redisClient.Del(connection.heartbeatKey) - if err != nil { - return err - } - if count == 0 { - return ErrorNotFound - } - return nil -} - -// flushDb flushes the redis database to reset everything, used in tests -func (connection *redisConnection) flushDb() error { - return connection.redisClient.FlushDb() -} - -// unlistAllQueues closes all queues by removing them from the global list -func (connection *redisConnection) unlistAllQueues() error { - _, err := connection.redisClient.Del(queuesKey) - return err -} diff --git a/vendor/github.com/adjust/rmq/v5/consumer.go b/vendor/github.com/adjust/rmq/v5/consumer.go deleted file mode 100644 index 9263419aa..000000000 --- a/vendor/github.com/adjust/rmq/v5/consumer.go +++ /dev/null @@ -1,11 +0,0 @@ -package rmq - -type Consumer interface { - Consume(delivery Delivery) -} - -type ConsumerFunc func(Delivery) - -func (consumerFunc ConsumerFunc) Consume(delivery Delivery) { - consumerFunc(delivery) -} diff --git a/vendor/github.com/adjust/rmq/v5/deliveries.go b/vendor/github.com/adjust/rmq/v5/deliveries.go deleted file mode 100644 index 8225462e9..000000000 --- a/vendor/github.com/adjust/rmq/v5/deliveries.go +++ /dev/null @@ -1,46 +0,0 @@ -package rmq - -type Deliveries []Delivery - -func (deliveries Deliveries) Payloads() []string { - payloads := make([]string, len(deliveries)) - for i, delivery := range deliveries { - payloads[i] = delivery.Payload() - } - return payloads -} - -// NOTE: The returned error map maps delivery indexes to errors. So if the -// error map is non empty you can use the indexes in the map to look up which -// of the deliveries ran into the corresponding error. See -// example/batch_consumer. - -// functions with retry, see comments in delivery.go (recommended) - -func (deliveries Deliveries) Ack() (errMap map[int]error) { - return deliveries.each(Delivery.Ack) -} - -func (deliveries Deliveries) Reject() (errMap map[int]error) { - return deliveries.each(Delivery.Reject) -} - -func (deliveries Deliveries) Push() (errMap map[int]error) { - return deliveries.each(Delivery.Push) -} - -// helper functions - -func (deliveries Deliveries) each( - f func(Delivery) error, -) (errMap map[int]error) { - for i, delivery := range deliveries { - if err := f(delivery); err != nil { - if errMap == nil { // create error map lazily on demand - errMap = map[int]error{} - } - errMap[i] = err - } - } - return errMap -} diff --git a/vendor/github.com/adjust/rmq/v5/delivery.go b/vendor/github.com/adjust/rmq/v5/delivery.go deleted file mode 100644 index 4b94f49ce..000000000 --- a/vendor/github.com/adjust/rmq/v5/delivery.go +++ /dev/null @@ -1,118 +0,0 @@ -package rmq - -import ( - "context" - "fmt" - "net/http" - "time" -) - -type Delivery interface { - Payload() string - - Ack() error - Reject() error - Push() error -} - -var ( - _ Delivery = &redisDelivery{} - _ WithHeader = &redisDelivery{} -) - -type redisDelivery struct { - ctx context.Context - payload string - clearPayload string - header http.Header - unackedKey string - rejectedKey string - pushKey string - redisClient RedisClient - errChan chan<- error -} - -func (delivery *redisDelivery) Header() http.Header { - return delivery.header -} - -func (delivery *redisDelivery) String() string { - return fmt.Sprintf("[%s %s]", delivery.clearPayload, delivery.unackedKey) -} - -func (delivery *redisDelivery) Payload() string { - return delivery.clearPayload -} - -// blocking versions of the functions below with the following behavior: -// 1. return immediately if the operation succeeded or failed with ErrorNotFound -// 2. in case of other redis errors, send them to the errors chan and retry after a sleep -// 3. if redis errors occur after StopConsuming() has been called, ErrorConsumingStopped will be returned - -func (delivery *redisDelivery) Ack() error { - errorCount := 0 - for { - count, err := delivery.redisClient.LRem(delivery.unackedKey, 1, delivery.payload) - if err == nil { // no redis error - if count == 0 { - return ErrorNotFound - } - return nil - } - - // redis error - - errorCount++ - - select { // try to add error to channel, but don't block - case delivery.errChan <- &DeliveryError{Delivery: delivery, RedisErr: err, Count: errorCount}: - default: - } - - if err := delivery.ctx.Err(); err != nil { - return ErrorConsumingStopped - } - - time.Sleep(time.Second) - } -} - -func (delivery *redisDelivery) Reject() error { - return delivery.move(delivery.rejectedKey) -} - -func (delivery *redisDelivery) Push() error { - if delivery.pushKey == "" { - return delivery.Reject() // fall back to rejecting - } - - return delivery.move(delivery.pushKey) -} - -func (delivery *redisDelivery) move(key string) error { - errorCount := 0 - for { - _, err := delivery.redisClient.LPush(key, delivery.payload) - if err == nil { // success - break - } - // error - - errorCount++ - - select { // try to add error to channel, but don't block - case delivery.errChan <- &DeliveryError{Delivery: delivery, RedisErr: err, Count: errorCount}: - default: - } - - if err := delivery.ctx.Err(); err != nil { - return ErrorConsumingStopped - } - - time.Sleep(time.Second) - } - - return delivery.Ack() -} - -// lower level functions which don't retry but just return the first error diff --git a/vendor/github.com/adjust/rmq/v5/errors.go b/vendor/github.com/adjust/rmq/v5/errors.go deleted file mode 100644 index d0c92f8fe..000000000 --- a/vendor/github.com/adjust/rmq/v5/errors.go +++ /dev/null @@ -1,53 +0,0 @@ -package rmq - -import ( - "errors" - "fmt" -) - -var ( - ErrorNotFound = errors.New("entity not found") // entitify being connection/queue/delivery - ErrorAlreadyConsuming = errors.New("must not call StartConsuming() multiple times") - ErrorNotConsuming = errors.New("must call StartConsuming() before adding consumers") - ErrorConsumingStopped = errors.New("consuming stopped") -) - -type ConsumeError struct { - RedisErr error - Count int // number of consecutive errors -} - -func (e *ConsumeError) Error() string { - return fmt.Sprintf("rmq.ConsumeError (%d): %s", e.Count, e.RedisErr.Error()) -} - -func (e *ConsumeError) Unwrap() error { - return e.RedisErr -} - -type HeartbeatError struct { - RedisErr error - Count int // number of consecutive errors -} - -func (e *HeartbeatError) Error() string { - return fmt.Sprintf("rmq.HeartbeatError (%d): %s", e.Count, e.RedisErr.Error()) -} - -func (e *HeartbeatError) Unwrap() error { - return e.RedisErr -} - -type DeliveryError struct { - Delivery Delivery - RedisErr error - Count int // number of consecutive errors -} - -func (e *DeliveryError) Error() string { - return fmt.Sprintf("rmq.DeliveryError (%d): %s", e.Count, e.RedisErr.Error()) -} - -func (e *DeliveryError) Unwrap() error { - return e.RedisErr -} diff --git a/vendor/github.com/adjust/rmq/v5/header.go b/vendor/github.com/adjust/rmq/v5/header.go deleted file mode 100644 index 93c345353..000000000 --- a/vendor/github.com/adjust/rmq/v5/header.go +++ /dev/null @@ -1,79 +0,0 @@ -package rmq - -import ( - "encoding/json" - "errors" - "fmt" - "net/http" - "strings" -) - -// Redis protocol does not define a specific way to pass additional data like header. -// However, there is often need to pass them (for example for traces propagation). -// -// This implementation injects optional header values marked with a signature into payload body -// during publishing. When message is consumed, if signature is present, header and original payload -// are extracted from augmented payload. -// -// Header is defined as http.Header for better interoperability with existing libraries, -// for example with go.opentelemetry.io/otel/propagation.HeaderCarrier. - -// PayloadWithHeader creates a payload string with header. -func PayloadWithHeader(payload string, header http.Header) string { - if len(header) == 0 { - return payload - } - - hd, _ := json.Marshal(header) // String map never fails marshaling. - - return jsonHeaderSignature + string(hd) + "\n" + payload -} - -// PayloadBytesWithHeader creates payload bytes slice with header. -func PayloadBytesWithHeader(payload []byte, header http.Header) []byte { - if len(header) == 0 { - return payload - } - - hd, _ := json.Marshal(header) // String map never fails marshaling. - - res := make([]byte, 0, len(jsonHeaderSignature)+len(hd)+1+len(payload)) - res = append(res, []byte(jsonHeaderSignature)...) - res = append(res, hd...) - res = append(res, '\n') - res = append(res, payload...) - - return res -} - -// ExtractHeaderAndPayload splits augmented payload into header and original payload if specific signature is present. -func ExtractHeaderAndPayload(payload string) (http.Header, string, error) { - if !strings.HasPrefix(payload, jsonHeaderSignature) { - return nil, payload, nil - } - - lineEnd := strings.Index(payload, "\n") - if lineEnd == -1 { - return nil, "", errors.New("missing line separator") - } - - first := payload[len(jsonHeaderSignature):lineEnd] - rest := payload[lineEnd+1:] - - header := make(http.Header) - - if err := json.Unmarshal([]byte(first), &header); err != nil { - return nil, "", fmt.Errorf("parsing header: %w", err) - } - - return header, rest, nil -} - -// WithHeader is a Delivery with Header. -type WithHeader interface { - Header() http.Header -} - -// jsonHeaderSignature is a signature marker to indicate JSON header presence. -// Do not change the value. -const jsonHeaderSignature = "\xFF\x00\xBE\xBEJ" diff --git a/vendor/github.com/adjust/rmq/v5/queue.go b/vendor/github.com/adjust/rmq/v5/queue.go deleted file mode 100644 index c246ead95..000000000 --- a/vendor/github.com/adjust/rmq/v5/queue.go +++ /dev/null @@ -1,589 +0,0 @@ -package rmq - -import ( - "context" - "fmt" - "math/rand" - "strings" - "sync" - "time" -) - -const ( - defaultBatchTimeout = time.Second - purgeBatchSize = int64(100) -) - -type Queue interface { - Publish(payload ...string) error - PublishBytes(payload ...[]byte) error - SetPushQueue(pushQueue Queue) - StartConsuming(prefetchLimit int64, pollDuration time.Duration) error - StopConsuming() <-chan struct{} - AddConsumer(tag string, consumer Consumer) (string, error) - AddConsumerFunc(tag string, consumerFunc ConsumerFunc) (string, error) - AddBatchConsumer(tag string, batchSize int64, timeout time.Duration, consumer BatchConsumer) (string, error) - AddBatchConsumerFunc(tag string, batchSize int64, timeout time.Duration, batchConsumerFunc BatchConsumerFunc) (string, error) - PurgeReady() (int64, error) - PurgeRejected() (int64, error) - ReturnUnacked(max int64) (int64, error) - ReturnRejected(max int64) (int64, error) - Destroy() (readyCount, rejectedCount int64, err error) - Drain(count int64) ([]string, error) - - // internals - // used in cleaner - closeInStaleConnection() error - // used for stats - readyCount() (int64, error) - unackedCount() (int64, error) - rejectedCount() (int64, error) - getConsumers() ([]string, error) -} - -type redisQueue struct { - name string - connectionName string - queuesKey string // key to list of queues consumed by this connection - consumersKey string // key to set of consumers using this connection - unackedKey string // key to list of currently consuming deliveries - readyKey string // key to list of ready deliveries - rejectedKey string // key to list of rejected deliveries - pushKey string // key to list of pushed deliveries - redisClient RedisClient - errChan chan<- error - prefetchLimit int64 // max number of prefetched deliveries number of unacked can go up to prefetchLimit + numConsumers - pollDuration time.Duration - - lock sync.Mutex // protects the fields below related to starting and stopping this queue - consumingStopped chan struct{} // this chan gets closed when consuming on this queue has stopped - stopWg sync.WaitGroup - ackCtx context.Context - ackCancel context.CancelFunc - deliveryChan chan Delivery // nil for publish channels, not nil for consuming channels -} - -func newQueue( - name, connectionName, queuesKey string, - consumersTemplate, unackedTemplate, readyTemplate, rejectedTemplate string, - redisClient RedisClient, - errChan chan<- error, -) *redisQueue { - - consumersKey := strings.Replace(consumersTemplate, phConnection, connectionName, 1) - consumersKey = strings.Replace(consumersKey, phQueue, name, 1) - - unackedKey := strings.Replace(unackedTemplate, phConnection, connectionName, 1) - unackedKey = strings.Replace(unackedKey, phQueue, name, 1) - - readyKey := strings.Replace(readyTemplate, phQueue, name, 1) - rejectedKey := strings.Replace(rejectedTemplate, phQueue, name, 1) - - consumingStopped := make(chan struct{}) - ackCtx, ackCancel := context.WithCancel(context.Background()) - - queue := &redisQueue{ - name: name, - connectionName: connectionName, - queuesKey: queuesKey, - consumersKey: consumersKey, - unackedKey: unackedKey, - readyKey: readyKey, - rejectedKey: rejectedKey, - redisClient: redisClient, - errChan: errChan, - consumingStopped: consumingStopped, - ackCtx: ackCtx, - ackCancel: ackCancel, - } - return queue -} - -func (queue *redisQueue) String() string { - return fmt.Sprintf("[%s conn:%s]", queue.name, queue.connectionName) -} - -// Publish adds a delivery with the given payload to the queue -// returns how many deliveries are in the queue afterwards -func (queue *redisQueue) Publish(payload ...string) error { - _, err := queue.redisClient.LPush(queue.readyKey, payload...) - return err -} - -// PublishBytes just casts the bytes and calls Publish -func (queue *redisQueue) PublishBytes(payload ...[]byte) error { - stringifiedBytes := make([]string, len(payload)) - for i, b := range payload { - stringifiedBytes[i] = string(b) - } - return queue.Publish(stringifiedBytes...) -} - -// SetPushQueue sets a push queue. In the consumer function you can call -// delivery.Push(). If a push queue is set the delivery then gets moved from -// the original queue to the push queue. If no push queue is set it's -// equivalent to calling delivery.Reject(). -// NOTE: panics if pushQueue is not a *redisQueue -func (queue *redisQueue) SetPushQueue(pushQueue Queue) { - queue.pushKey = pushQueue.(*redisQueue).readyKey -} - -// StartConsuming starts consuming into a channel of size prefetchLimit -// must be called before consumers can be added! -// pollDuration is the duration the queue sleeps before checking for new deliveries -func (queue *redisQueue) StartConsuming(prefetchLimit int64, pollDuration time.Duration) error { - queue.lock.Lock() - defer queue.lock.Unlock() - - // If deliveryChan is set, then we are already consuming - if queue.deliveryChan != nil { - return ErrorAlreadyConsuming - } - select { - case <-queue.consumingStopped: - // If consuming is stopped then we must not try to - return ErrorConsumingStopped - default: - } - - // add queue to list of queues consumed on this connection - if _, err := queue.redisClient.SAdd(queue.queuesKey, queue.name); err != nil { - return err - } - - queue.prefetchLimit = prefetchLimit - queue.pollDuration = pollDuration - queue.deliveryChan = make(chan Delivery, prefetchLimit) - // log.Printf("rmq queue started consuming %s %d %s", queue, prefetchLimit, pollDuration) - go queue.consume() - return nil -} - -func (queue *redisQueue) consume() { - errorCount := 0 // number of consecutive batch errors - - for { - switch err := queue.consumeBatch(); err { - case nil: // success - errorCount = 0 - - case ErrorConsumingStopped: - close(queue.deliveryChan) - return - - default: // redis error - errorCount++ - select { // try to add error to channel, but don't block - case queue.errChan <- &ConsumeError{RedisErr: err, Count: errorCount}: - default: - } - } - time.Sleep(jitteredDuration(queue.pollDuration)) - } -} - -func (queue *redisQueue) consumeBatch() error { - select { - case <-queue.consumingStopped: - return ErrorConsumingStopped - default: - } - - // unackedCount == + - unackedCount, err := queue.unackedCount() - if err != nil { - return err - } - - batchSize := queue.prefetchLimit - unackedCount - if batchSize <= 0 { - return nil - } - - for i := int64(0); i < batchSize; i++ { - select { - case <-queue.consumingStopped: - return ErrorConsumingStopped - default: - } - - payload, err := queue.redisClient.RPopLPush(queue.readyKey, queue.unackedKey) - if err == ErrorNotFound { - return nil - } - if err != nil { - return err - } - - d, err := queue.newDelivery(payload) - if err != nil { - return fmt.Errorf("create new delivery: %w", err) - } - - queue.deliveryChan <- d - } - - return nil -} - -func (queue *redisQueue) newDelivery(payload string) (Delivery, error) { - rd := &redisDelivery{ - ctx: queue.ackCtx, - payload: payload, - unackedKey: queue.unackedKey, - rejectedKey: queue.rejectedKey, - pushKey: queue.pushKey, - redisClient: queue.redisClient, - errChan: queue.errChan, - } - - var err error - rd.header, rd.clearPayload, err = ExtractHeaderAndPayload(payload) - if err == nil { - return rd, nil - } - - // we need to reject a delivery here to move the delivery from the unacked to the rejected list. - rejectErr := rd.Reject() - if rejectErr != nil { - return nil, fmt.Errorf("%s, reject faulty delivery: %w", err, rejectErr) - } - - return nil, err -} - -// StopConsuming can be used to stop all consumers on this queue. It returns a -// channel which can be used to wait for all active consumers to finish their -// current Consume() call. This is useful to implement graceful shutdown. -func (queue *redisQueue) StopConsuming() <-chan struct{} { - finishedChan := make(chan struct{}) - // We only stop consuming once - // This function returns immediately, while the work of actually stopping runs in a separate goroutine - go func() { - queue.lock.Lock() - defer queue.lock.Unlock() - - select { - case <-queue.consumingStopped: - // already stopped, nothing to do - close(finishedChan) - return - default: - close(queue.consumingStopped) - queue.ackCancel() - queue.stopWg.Wait() - close(finishedChan) - } - }() - - return finishedChan -} - -// AddConsumer adds a consumer to the queue and returns its internal name -func (queue *redisQueue) AddConsumer(tag string, consumer Consumer) (name string, err error) { - name, err = queue.addConsumer(tag) - if err != nil { - return "", err - } - go queue.consumerConsume(consumer) - return name, nil -} - -func (queue *redisQueue) consumerConsume(consumer Consumer) { - defer func() { - queue.stopWg.Done() - }() - for { - select { - case <-queue.consumingStopped: // prefer this case - return - default: - } - - select { - case <-queue.consumingStopped: - return - - case delivery, ok := <-queue.deliveryChan: - if !ok { // deliveryChan closed - return - } - - consumer.Consume(delivery) - } - } -} - -// AddConsumerFunc adds a consumer which is defined only by a function. This is -// similar to http.HandlerFunc and useful if your consumers don't need any -// state. -func (queue *redisQueue) AddConsumerFunc(tag string, consumerFunc ConsumerFunc) (string, error) { - return queue.AddConsumer(tag, consumerFunc) -} - -// AddBatchConsumer is similar to AddConsumer, but for batches of deliveries -// timeout limits the amount of time waiting to fill an entire batch -// The timer is only started when the first message in a batch is received -func (queue *redisQueue) AddBatchConsumer(tag string, batchSize int64, timeout time.Duration, consumer BatchConsumer) (string, error) { - name, err := queue.addConsumer(tag) - if err != nil { - return "", err - } - go queue.consumerBatchConsume(batchSize, timeout, consumer) - return name, nil -} - -// AddBatchConsumerFunc is similar to AddConsumerFunc, but for batches of deliveries -// timeout limits the amount of time waiting to fill an entire batch -// The timer is only started when the first message in a batch is received -func (queue *redisQueue) AddBatchConsumerFunc(tag string, batchSize int64, timeout time.Duration, batchConsumerFunc BatchConsumerFunc) (string, error) { - name, err := queue.addConsumer(tag) - if err != nil { - return "", err - } - go queue.consumerBatchConsume(batchSize, timeout, batchConsumerFunc) - return name, nil -} - -func (queue *redisQueue) consumerBatchConsume(batchSize int64, timeout time.Duration, consumer BatchConsumer) { - defer func() { - queue.stopWg.Done() - }() - batch := []Delivery{} - for { - select { - case <-queue.consumingStopped: // prefer this case - return - default: - } - - select { - case <-queue.consumingStopped: - return - - case delivery, ok := <-queue.deliveryChan: // Wait for first delivery - if !ok { // deliveryChan closed - return - } - - batch = append(batch, delivery) - batch, ok = queue.batchTimeout(batchSize, batch, timeout) - if !ok { - return - } - - consumer.Consume(batch) - batch = batch[:0] // reset batch - } - } -} - -func (queue *redisQueue) batchTimeout(batchSize int64, batch []Delivery, timeout time.Duration) (fullBatch []Delivery, ok bool) { - timer := time.NewTimer(timeout) - defer timer.Stop() - for { - select { - case <-queue.consumingStopped: // prefer this case - return nil, false - default: - } - - select { - case <-queue.consumingStopped: // consuming stopped: abort batch - return nil, false - - case <-timer.C: // timeout: submit batch - return batch, true - - case delivery, ok := <-queue.deliveryChan: - if !ok { // deliveryChan closed: abort batch - return nil, false - } - - batch = append(batch, delivery) - if int64(len(batch)) >= batchSize { - return batch, true // once big enough: submit batch - } - } - } -} - -func (queue *redisQueue) addConsumer(tag string) (name string, err error) { - queue.lock.Lock() - defer queue.lock.Unlock() - - if err := queue.ensureConsuming(); err != nil { - return "", err - } - - name = fmt.Sprintf("%s-%s", tag, RandomString(6)) - - // add consumer to list of consumers of this queue - if _, err := queue.redisClient.SAdd(queue.consumersKey, name); err != nil { - return "", err - } - - queue.stopWg.Add(1) - // log.Printf("rmq queue added consumer %s %s", queue, name) - return name, nil -} - -// PurgeReady removes all ready deliveries from the queue and returns the number of purged deliveries -func (queue *redisQueue) PurgeReady() (int64, error) { - return queue.deleteRedisList(queue.readyKey) -} - -// PurgeRejected removes all rejected deliveries from the queue and returns the number of purged deliveries -func (queue *redisQueue) PurgeRejected() (int64, error) { - return queue.deleteRedisList(queue.rejectedKey) -} - -// return number of deleted list items -// https://www.redisgreen.net/blog/deleting-large-lists -func (queue *redisQueue) deleteRedisList(key string) (int64, error) { - total, err := queue.redisClient.LLen(key) - if total == 0 { - return 0, err // nothing to do - } - - // delete elements without blocking - for todo := total; todo > 0; todo -= purgeBatchSize { - // minimum of purgeBatchSize and todo - batchSize := purgeBatchSize - if batchSize > todo { - batchSize = todo - } - - // remove one batch - err := queue.redisClient.LTrim(key, 0, -1-batchSize) - if err != nil { - return 0, err - } - } - - return total, nil -} - -// ReturnUnacked tries to return max unacked deliveries back to -// the ready queue and returns the number of returned deliveries -func (queue *redisQueue) ReturnUnacked(max int64) (count int64, error error) { - return queue.move(queue.unackedKey, queue.readyKey, max) -} - -// ReturnRejected tries to return max rejected deliveries back to -// the ready queue and returns the number of returned deliveries -func (queue *redisQueue) ReturnRejected(max int64) (count int64, err error) { - return queue.move(queue.rejectedKey, queue.readyKey, max) -} - -func (queue *redisQueue) move(from, to string, max int64) (n int64, error error) { - for n = 0; n < max; n++ { - switch _, err := queue.redisClient.RPopLPush(from, to); err { - case nil: // moved one - continue - case ErrorNotFound: // nothing left - return n, nil - default: // error - return 0, err - } - } - return n, nil -} - -// Drain removes and returns 'count' elements from the queue. In case of an error, -// Drain return all elements removed until the error occurred and the error itself. -func (queue *redisQueue) Drain(count int64) ([]string, error) { - var ( - n int64 - err error - ) - out := make([]string, 0, count) - - for n = 0; n < count; n++ { - val, err := queue.redisClient.RPop(queue.readyKey) - if err != nil { - return out, err - } - out = append(out, val) - } - - return out, err -} - -// Destroy purges and removes the queue from the list of queues -func (queue *redisQueue) Destroy() (readyCount, rejectedCount int64, err error) { - readyCount, err = queue.PurgeReady() - if err != nil { - return 0, 0, err - } - rejectedCount, err = queue.PurgeRejected() - if err != nil { - return 0, 0, err - } - - count, err := queue.redisClient.SRem(queuesKey, queue.name) - if err != nil { - return 0, 0, err - } - if count == 0 { - return 0, 0, ErrorNotFound - } - - return readyCount, rejectedCount, nil -} - -// closeInStaleConnection closes the queue in the associated connection by removing all related keys -// not supposed to be called on queues in active sessions -func (queue *redisQueue) closeInStaleConnection() error { - if _, err := queue.redisClient.Del(queue.unackedKey); err != nil { - return err - } - if _, err := queue.redisClient.Del(queue.consumersKey); err != nil { - return err - } - - count, err := queue.redisClient.SRem(queue.queuesKey, queue.name) - if err != nil { - return err - } - if count == 0 { - return ErrorNotFound - } - - return nil -} - -func (queue *redisQueue) readyCount() (int64, error) { - return queue.redisClient.LLen(queue.readyKey) -} - -func (queue *redisQueue) unackedCount() (int64, error) { - return queue.redisClient.LLen(queue.unackedKey) -} - -func (queue *redisQueue) rejectedCount() (int64, error) { - return queue.redisClient.LLen(queue.rejectedKey) -} - -func (queue *redisQueue) getConsumers() ([]string, error) { - return queue.redisClient.SMembers(queue.consumersKey) -} - -// The caller of this method should be holding the queue.lock mutex -func (queue *redisQueue) ensureConsuming() error { - if queue.deliveryChan == nil { - return ErrorNotConsuming - } - select { - case <-queue.consumingStopped: - return ErrorConsumingStopped - default: - return nil - } -} - -// jitteredDuration calculates and returns a value that is +/-10% the input duration -func jitteredDuration(duration time.Duration) time.Duration { - factor := 0.9 + rand.Float64()*0.2 // a jitter factor between 0.9 and 1.1 (+-10%) - return time.Duration(float64(duration) * factor) -} diff --git a/vendor/github.com/adjust/rmq/v5/rand.go b/vendor/github.com/adjust/rmq/v5/rand.go deleted file mode 100644 index 9cd5beb2d..000000000 --- a/vendor/github.com/adjust/rmq/v5/rand.go +++ /dev/null @@ -1,22 +0,0 @@ -package rmq - -import ( - "math/rand" - "time" -) - -func init() { - rand.Seed(time.Now().UnixNano()) -} - -// standard characters used by uniuri -const letterBytes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" - -// from https://stackoverflow.com/a/31832326 -func RandomString(n int) string { - b := make([]byte, n) - for i := range b { - b[i] = letterBytes[rand.Intn(len(letterBytes))] - } - return string(b) -} diff --git a/vendor/github.com/adjust/rmq/v5/redis_client.go b/vendor/github.com/adjust/rmq/v5/redis_client.go deleted file mode 100644 index c1d031c4b..000000000 --- a/vendor/github.com/adjust/rmq/v5/redis_client.go +++ /dev/null @@ -1,26 +0,0 @@ -package rmq - -import "time" - -type RedisClient interface { - // simple keys - Set(key string, value string, expiration time.Duration) error - Del(key string) (affected int64, err error) - TTL(key string) (ttl time.Duration, err error) - - // lists - LPush(key string, value ...string) (total int64, err error) - LLen(key string) (affected int64, err error) - LRem(key string, count int64, value string) (affected int64, err error) - LTrim(key string, start, stop int64) error - RPopLPush(source, destination string) (value string, err error) - RPop(key string) (value string, err error) - - // sets - SAdd(key, value string) (total int64, err error) - SMembers(key string) (members []string, err error) - SRem(key, value string) (affected int64, err error) - - // special - FlushDb() error -} diff --git a/vendor/github.com/adjust/rmq/v5/redis_keys.go b/vendor/github.com/adjust/rmq/v5/redis_keys.go deleted file mode 100644 index db4e7823e..000000000 --- a/vendor/github.com/adjust/rmq/v5/redis_keys.go +++ /dev/null @@ -1,27 +0,0 @@ -package rmq - -import "strings" - -const ( - connectionsKey = "rmq::connections" // Set of connection names - connectionHeartbeatTemplate = "rmq::connection::{connection}::heartbeat" // expires after {connection} died - connectionQueuesTemplate = "rmq::connection::{connection}::queues" // Set of queues consumers of {connection} are consuming - connectionQueueConsumersBaseTemplate = "rmq::connection::{connection}::queue::[{queue}]::consumers" // Set of all consumers from {connection} consuming from {queue} - connectionQueueUnackedBaseTemplate = "rmq::connection::{connection}::queue::[{queue}]::unacked" // List of deliveries consumers of {connection} are currently consuming - - queuesKey = "rmq::queues" // Set of all open queues - queueReadyBaseTemplate = "rmq::queue::[{queue}]::ready" // List of deliveries in that {queue} (right is first and oldest, left is last and youngest) - queueRejectedBaseTemplate = "rmq::queue::[{queue}]::rejected" // List of rejected deliveries from that {queue} - - phConnection = "{connection}" // connection name - phQueue = "{queue}" // queue name - phConsumer = "{consumer}" // consumer name (consisting of tag and token) -) - -func getTemplate(baseTemplate string, useRedisHashTags bool) string { - if !useRedisHashTags { - return baseTemplate - } - - return strings.Replace(baseTemplate, "[{queue}]", "{{queue}}", 1) -} diff --git a/vendor/github.com/adjust/rmq/v5/redis_wrapper.go b/vendor/github.com/adjust/rmq/v5/redis_wrapper.go deleted file mode 100644 index 9550d58e6..000000000 --- a/vendor/github.com/adjust/rmq/v5/redis_wrapper.go +++ /dev/null @@ -1,76 +0,0 @@ -package rmq - -import ( - "context" - "time" - - "github.com/redis/go-redis/v9" -) - -type RedisWrapper struct { - rawClient redis.Cmdable -} - -func (wrapper RedisWrapper) Set(key string, value string, expiration time.Duration) error { - // NOTE: using Err() here because Result() string is always "OK" - return wrapper.rawClient.Set(context.TODO(), key, value, expiration).Err() -} - -func (wrapper RedisWrapper) Del(key string) (affected int64, err error) { - return wrapper.rawClient.Del(context.TODO(), key).Result() -} - -func (wrapper RedisWrapper) TTL(key string) (ttl time.Duration, err error) { - return wrapper.rawClient.TTL(context.TODO(), key).Result() -} - -func (wrapper RedisWrapper) LPush(key string, value ...string) (total int64, err error) { - return wrapper.rawClient.LPush(context.TODO(), key, value).Result() -} - -func (wrapper RedisWrapper) LLen(key string) (affected int64, err error) { - return wrapper.rawClient.LLen(context.TODO(), key).Result() -} - -func (wrapper RedisWrapper) LRem(key string, count int64, value string) (affected int64, err error) { - return wrapper.rawClient.LRem(context.TODO(), key, int64(count), value).Result() -} - -func (wrapper RedisWrapper) LTrim(key string, start, stop int64) error { - // NOTE: using Err() here because Result() string is always "OK" - return wrapper.rawClient.LTrim(context.TODO(), key, int64(start), int64(stop)).Err() -} - -func (wrapper RedisWrapper) RPop(key string) (value string, err error) { - return wrapper.rawClient.RPop(context.TODO(), key).Result() -} - -func (wrapper RedisWrapper) RPopLPush(source, destination string) (value string, err error) { - value, err = wrapper.rawClient.RPopLPush(context.TODO(), source, destination).Result() - // println("RPopLPush", source, destination, value, err) - switch err { - case nil: - return value, nil - case redis.Nil: - return value, ErrorNotFound - default: - return value, err - } -} - -func (wrapper RedisWrapper) SAdd(key, value string) (total int64, err error) { - return wrapper.rawClient.SAdd(context.TODO(), key, value).Result() -} - -func (wrapper RedisWrapper) SMembers(key string) (members []string, err error) { - return wrapper.rawClient.SMembers(context.TODO(), key).Result() -} - -func (wrapper RedisWrapper) SRem(key, value string) (affected int64, err error) { - return wrapper.rawClient.SRem(context.TODO(), key, value).Result() -} - -func (wrapper RedisWrapper) FlushDb() error { - // NOTE: using Err() here because Result() string is always "OK" - return wrapper.rawClient.FlushDB(context.TODO()).Err() -} diff --git a/vendor/github.com/adjust/rmq/v5/state.go b/vendor/github.com/adjust/rmq/v5/state.go deleted file mode 100644 index 06bdd24a5..000000000 --- a/vendor/github.com/adjust/rmq/v5/state.go +++ /dev/null @@ -1,12 +0,0 @@ -package rmq - -//go:generate stringer -type=State - -type State int - -const ( - Unacked State = iota - Acked - Rejected - Pushed -) diff --git a/vendor/github.com/adjust/rmq/v5/state_string.go b/vendor/github.com/adjust/rmq/v5/state_string.go deleted file mode 100644 index 6840c553c..000000000 --- a/vendor/github.com/adjust/rmq/v5/state_string.go +++ /dev/null @@ -1,16 +0,0 @@ -// generated by stringer -type=State; DO NOT EDIT - -package rmq - -import "fmt" - -const _State_name = "UnackedAckedRejectedPushed" - -var _State_index = [...]uint8{0, 7, 12, 20, 26} - -func (i State) String() string { - if i < 0 || i >= State(len(_State_index)-1) { - return fmt.Sprintf("State(%d)", i) - } - return _State_name[_State_index[i]:_State_index[i+1]] -} diff --git a/vendor/github.com/adjust/rmq/v5/stats.go b/vendor/github.com/adjust/rmq/v5/stats.go deleted file mode 100644 index dff6de10b..000000000 --- a/vendor/github.com/adjust/rmq/v5/stats.go +++ /dev/null @@ -1,273 +0,0 @@ -package rmq - -import ( - "bytes" - "fmt" - "sort" -) - -type ConnectionStat struct { - active bool - unackedCount int64 - consumers []string -} - -func (stat ConnectionStat) String() string { - return fmt.Sprintf("[unacked:%d consumers:%d]", - stat.unackedCount, - len(stat.consumers), - ) -} - -type ConnectionStats map[string]ConnectionStat - -type QueueStat struct { - ReadyCount int64 `json:"ready"` - RejectedCount int64 `json:"rejected"` - connectionStats ConnectionStats -} - -func NewQueueStat(readyCount, rejectedCount int64) QueueStat { - return QueueStat{ - ReadyCount: readyCount, - RejectedCount: rejectedCount, - connectionStats: ConnectionStats{}, - } -} - -func (stat QueueStat) String() string { - return fmt.Sprintf("[ready:%d rejected:%d conn:%s", - stat.ReadyCount, - stat.RejectedCount, - stat.connectionStats, - ) -} - -func (stat QueueStat) UnackedCount() int64 { - unacked := int64(0) - for _, connectionStat := range stat.connectionStats { - unacked += connectionStat.unackedCount - } - return unacked -} - -func (stat QueueStat) ConsumerCount() int64 { - consumer := int64(0) - for _, connectionStat := range stat.connectionStats { - consumer += int64(len(connectionStat.consumers)) - } - return consumer -} - -func (stat QueueStat) ConnectionCount() int64 { - return int64(len(stat.connectionStats)) -} - -type QueueStats map[string]QueueStat - -type Stats struct { - QueueStats QueueStats `json:"queues"` - otherConnections map[string]bool // non consuming connections, active or not -} - -func NewStats() Stats { - return Stats{ - QueueStats: QueueStats{}, - otherConnections: map[string]bool{}, - } -} - -func CollectStats(queueList []string, mainConnection Connection) (Stats, error) { - stats := NewStats() - for _, queueName := range queueList { - queue := mainConnection.openQueue(queueName) - readyCount, err := queue.readyCount() - if err != nil { - return stats, err - } - rejectedCount, err := queue.rejectedCount() - if err != nil { - return stats, err - } - stats.QueueStats[queueName] = NewQueueStat(readyCount, rejectedCount) - } - - connectionNames, err := mainConnection.getConnections() - if err != nil { - return stats, err - } - - for _, connectionName := range connectionNames { - hijackedConnection := mainConnection.hijackConnection(connectionName) - - var connectionActive bool - switch err := hijackedConnection.checkHeartbeat(); err { - case nil: - connectionActive = true - case ErrorNotFound: - connectionActive = false - default: - return stats, err - } - - queueNames, err := hijackedConnection.getConsumingQueues() - if err != nil { - return stats, err - } - if len(queueNames) == 0 { - stats.otherConnections[connectionName] = connectionActive - continue - } - - for _, queueName := range queueNames { - queue := hijackedConnection.openQueue(queueName) - consumers, err := queue.getConsumers() - if err != nil { - return stats, err - } - openQueueStat, ok := stats.QueueStats[queueName] - if !ok { - continue - } - unackedCount, err := queue.unackedCount() - if err != nil { - return stats, err - } - openQueueStat.connectionStats[connectionName] = ConnectionStat{ - active: connectionActive, - unackedCount: unackedCount, - consumers: consumers, - } - } - } - - return stats, nil -} - -func (stats Stats) String() string { - var buffer bytes.Buffer - - for queueName, queueStat := range stats.QueueStats { - buffer.WriteString(fmt.Sprintf(" queue:%s ready:%d rejected:%d unacked:%d consumers:%d\n", - queueName, queueStat.ReadyCount, queueStat.RejectedCount, queueStat.UnackedCount(), queueStat.ConsumerCount(), - )) - - for connectionName, connectionStat := range queueStat.connectionStats { - buffer.WriteString(fmt.Sprintf(" connection:%s unacked:%d consumers:%d active:%t\n", - connectionName, connectionStat.unackedCount, len(connectionStat.consumers), connectionStat.active, - )) - } - } - - for connectionName, active := range stats.otherConnections { - buffer.WriteString(fmt.Sprintf(" connection:%s active:%t\n", - connectionName, active, - )) - } - - return buffer.String() -} - -func (stats Stats) GetHtml(layout, refresh string) string { - buffer := bytes.NewBufferString("") - - if refresh != "" { - buffer.WriteString(fmt.Sprintf(``, refresh)) - } - - buffer.WriteString(``) - buffer.WriteString(``, - ) - - for _, queueName := range stats.sortedQueueNames() { - queueStat := stats.QueueStats[queueName] - connectionNames := queueStat.connectionStats.sortedNames() - buffer.WriteString(fmt.Sprintf(``, - queueName, queueStat.ReadyCount, queueStat.RejectedCount, "", len(connectionNames), queueStat.UnackedCount(), queueStat.ConsumerCount(), - )) - - if layout != "condensed" { - for _, connectionName := range connectionNames { - connectionStat := queueStat.connectionStats[connectionName] - buffer.WriteString(fmt.Sprintf(``, - "", "", "", ActiveSign(connectionStat.active), connectionName, connectionStat.unackedCount, len(connectionStat.consumers), - )) - } - } - } - - if layout != "condensed" { - buffer.WriteString(``) - for _, connectionName := range stats.sortedConnectionNames() { - active := stats.otherConnections[connectionName] - buffer.WriteString(fmt.Sprintf(``, - "", "", "", ActiveSign(active), connectionName, "", "", - )) - } - } - - buffer.WriteString(`
` + - `queue` + - `ready` + - `rejected` + - `` + - `connections` + - `unacked` + - `consumers
`+ - `%s`+ - `%d`+ - `%d`+ - `%s`+ - `%d`+ - `%d`+ - `%d
`+ - `%s`+ - `%s`+ - `%s`+ - `%s`+ - `%s`+ - `%d`+ - `%d
-----
`+ - `%s`+ - `%s`+ - `%s`+ - `%s`+ - `%s`+ - `%s`+ - `%s
`) - return buffer.String() -} - -func (stats ConnectionStats) sortedNames() []string { - var keys []string - for key := range stats { - keys = append(keys, key) - } - sort.Strings(keys) - return keys -} - -func (stats Stats) sortedQueueNames() []string { - var keys []string - for key := range stats.QueueStats { - keys = append(keys, key) - } - sort.Strings(keys) - return keys -} - -func (stats Stats) sortedConnectionNames() []string { - var keys []string - for key := range stats.otherConnections { - keys = append(keys, key) - } - sort.Strings(keys) - return keys -} - -func ActiveSign(active bool) string { - if active { - return "✓" - } - return "✗" -} diff --git a/vendor/github.com/adjust/rmq/v5/test_batch_consumer.go b/vendor/github.com/adjust/rmq/v5/test_batch_consumer.go deleted file mode 100644 index 5ae560eeb..000000000 --- a/vendor/github.com/adjust/rmq/v5/test_batch_consumer.go +++ /dev/null @@ -1,57 +0,0 @@ -package rmq - -import "sync" - -type TestBatchConsumer struct { - mu sync.Mutex - // Deprecated: use Last() to avoid data races. - LastBatch Deliveries - // Deprecated use Consumed() to avoid data races. - ConsumedCount int64 - AutoFinish bool - - finish chan int -} - -func NewTestBatchConsumer() *TestBatchConsumer { - return &TestBatchConsumer{ - finish: make(chan int), - } -} - -func (consumer *TestBatchConsumer) Last() Deliveries { - consumer.mu.Lock() - defer consumer.mu.Unlock() - - return consumer.LastBatch -} - -func (consumer *TestBatchConsumer) Consumed() int64 { - consumer.mu.Lock() - defer consumer.mu.Unlock() - - return consumer.ConsumedCount -} - -func (consumer *TestBatchConsumer) Consume(batch Deliveries) { - consumer.mu.Lock() - consumer.LastBatch = batch - consumer.ConsumedCount += int64(len(batch)) - consumer.mu.Unlock() - - if consumer.AutoFinish { - batch.Ack() - } else { - <-consumer.finish - // log.Printf("TestBatchConsumer.Consume() finished") - } -} - -func (consumer *TestBatchConsumer) Finish() { - // log.Printf("TestBatchConsumer.Finish()") - consumer.mu.Lock() - consumer.LastBatch = nil - consumer.mu.Unlock() - - consumer.finish <- 1 -} diff --git a/vendor/github.com/adjust/rmq/v5/test_connection.go b/vendor/github.com/adjust/rmq/v5/test_connection.go deleted file mode 100644 index 0dbd3703a..000000000 --- a/vendor/github.com/adjust/rmq/v5/test_connection.go +++ /dev/null @@ -1,64 +0,0 @@ -package rmq - -import ( - "errors" - "fmt" - "sync" -) - -var errorNotSupported = errors.New("not supported") - -type TestConnection struct { - queues *sync.Map -} - -func NewTestConnection() TestConnection { - return TestConnection{ - queues: &sync.Map{}, - } -} - -func (connection TestConnection) OpenQueue(name string) (Queue, error) { - queue, _ := connection.queues.LoadOrStore(name, NewTestQueue(name)) - return queue.(*TestQueue), nil -} - -func (TestConnection) CollectStats([]string) (Stats, error) { panic(errorNotSupported) } -func (TestConnection) GetOpenQueues() ([]string, error) { panic(errorNotSupported) } -func (TestConnection) StopAllConsuming() <-chan struct{} { panic(errorNotSupported) } -func (TestConnection) checkHeartbeat() error { panic(errorNotSupported) } -func (TestConnection) getConnections() ([]string, error) { panic(errorNotSupported) } -func (TestConnection) hijackConnection(string) Connection { panic(errorNotSupported) } -func (TestConnection) closeStaleConnection() error { panic(errorNotSupported) } -func (TestConnection) getConsumingQueues() ([]string, error) { panic(errorNotSupported) } -func (TestConnection) unlistAllQueues() error { panic(errorNotSupported) } -func (TestConnection) openQueue(string) Queue { panic(errorNotSupported) } -func (TestConnection) stopHeartbeat() error { panic(errorNotSupported) } -func (TestConnection) flushDb() error { panic(errorNotSupported) } - -// test helpers for test inspection and similar - -func (connection TestConnection) GetDeliveries(queueName string) []string { - queue, ok := connection.queues.Load(queueName) - if !ok { - return []string{} - } - - return queue.(*TestQueue).LastDeliveries -} - -func (connection TestConnection) GetDelivery(queueName string, index int) string { - queue, ok := connection.queues.Load(queueName) - if !ok || index < 0 || index >= len(queue.(*TestQueue).LastDeliveries) { - return fmt.Sprintf("rmq.TestConnection: delivery not found: %s[%d]", queueName, index) - } - - return queue.(*TestQueue).LastDeliveries[index] -} - -func (connection TestConnection) Reset() { - connection.queues.Range(func(_, v interface{}) bool { - v.(*TestQueue).Reset() - return true - }) -} diff --git a/vendor/github.com/adjust/rmq/v5/test_consumer.go b/vendor/github.com/adjust/rmq/v5/test_consumer.go deleted file mode 100644 index 8fbdcf904..000000000 --- a/vendor/github.com/adjust/rmq/v5/test_consumer.go +++ /dev/null @@ -1,75 +0,0 @@ -package rmq - -import ( - "sync" - "time" -) - -type TestConsumer struct { - name string - AutoAck bool - AutoFinish bool - SleepDuration time.Duration - - mu sync.Mutex - // Deprecated: use Last() to avoid data races. - LastDelivery Delivery - // Deprecated: use Deliveries() to avoid data races. - LastDeliveries []Delivery - - finish chan int -} - -func NewTestConsumer(name string) *TestConsumer { - return &TestConsumer{ - name: name, - AutoAck: true, - AutoFinish: true, - finish: make(chan int), - } -} - -func (consumer *TestConsumer) String() string { - return consumer.name -} - -func (consumer *TestConsumer) Last() Delivery { - consumer.mu.Lock() - defer consumer.mu.Unlock() - - return consumer.LastDelivery -} - -func (consumer *TestConsumer) Deliveries() []Delivery { - consumer.mu.Lock() - defer consumer.mu.Unlock() - - return consumer.LastDeliveries -} - -func (consumer *TestConsumer) Consume(delivery Delivery) { - consumer.mu.Lock() - consumer.LastDelivery = delivery - consumer.LastDeliveries = append(consumer.LastDeliveries, delivery) - consumer.mu.Unlock() - - if consumer.SleepDuration > 0 { - time.Sleep(consumer.SleepDuration) - } - if consumer.AutoAck { - if err := delivery.Ack(); err != nil { - panic(err) - } - } - if !consumer.AutoFinish { - <-consumer.finish - } -} - -func (consumer *TestConsumer) Finish() { - consumer.finish <- 1 -} - -func (consumer *TestConsumer) FinishAll() { - close(consumer.finish) -} diff --git a/vendor/github.com/adjust/rmq/v5/test_delivery.go b/vendor/github.com/adjust/rmq/v5/test_delivery.go deleted file mode 100644 index 17f3f1c6f..000000000 --- a/vendor/github.com/adjust/rmq/v5/test_delivery.go +++ /dev/null @@ -1,58 +0,0 @@ -package rmq - -import ( - "encoding/json" - "log" -) - -type TestDelivery struct { - State State - payload string -} - -func NewTestDelivery(content interface{}) *TestDelivery { - if payload, ok := content.(string); ok { - return NewTestDeliveryString(payload) - } - - bytes, err := json.Marshal(content) - if err != nil { - log.Panic("rmq.NewTestDelivery failed to marshal") - } - - return NewTestDeliveryString(string(bytes)) -} - -func NewTestDeliveryString(payload string) *TestDelivery { - return &TestDelivery{ - payload: payload, - } -} - -func (delivery *TestDelivery) Payload() string { - return delivery.payload -} - -func (delivery *TestDelivery) Ack() error { - if delivery.State != Unacked { - return ErrorNotFound - } - delivery.State = Acked - return nil -} - -func (delivery *TestDelivery) Reject() error { - if delivery.State != Unacked { - return ErrorNotFound - } - delivery.State = Rejected - return nil -} - -func (delivery *TestDelivery) Push() error { - if delivery.State != Unacked { - return ErrorNotFound - } - delivery.State = Pushed - return nil -} diff --git a/vendor/github.com/adjust/rmq/v5/test_queue.go b/vendor/github.com/adjust/rmq/v5/test_queue.go deleted file mode 100644 index b4664c4eb..000000000 --- a/vendor/github.com/adjust/rmq/v5/test_queue.go +++ /dev/null @@ -1,60 +0,0 @@ -package rmq - -import "time" - -type TestQueue struct { - name string - LastDeliveries []string -} - -func NewTestQueue(name string) *TestQueue { - queue := &TestQueue{name: name} - queue.Reset() - return queue -} - -func (queue *TestQueue) String() string { - return queue.name -} - -func (queue *TestQueue) Publish(payload ...string) error { - queue.LastDeliveries = append(queue.LastDeliveries, payload...) - return nil -} - -func (queue *TestQueue) PublishBytes(payload ...[]byte) error { - stringifiedBytes := make([]string, len(payload)) - for i, b := range payload { - stringifiedBytes[i] = string(b) - } - return queue.Publish(stringifiedBytes...) -} - -func (*TestQueue) SetPushQueue(Queue) { panic(errorNotSupported) } -func (*TestQueue) StartConsuming(int64, time.Duration) error { panic(errorNotSupported) } -func (*TestQueue) StopConsuming() <-chan struct{} { panic(errorNotSupported) } -func (*TestQueue) AddConsumer(string, Consumer) (string, error) { panic(errorNotSupported) } -func (*TestQueue) AddConsumerFunc(string, ConsumerFunc) (string, error) { panic(errorNotSupported) } -func (*TestQueue) AddBatchConsumer(string, int64, time.Duration, BatchConsumer) (string, error) { - panic(errorNotSupported) -} -func (*TestQueue) AddBatchConsumerFunc(string, int64, time.Duration, BatchConsumerFunc) (string, error) { - panic(errorNotSupported) -} -func (*TestQueue) ReturnUnacked(int64) (int64, error) { panic(errorNotSupported) } -func (*TestQueue) ReturnRejected(int64) (int64, error) { panic(errorNotSupported) } -func (*TestQueue) PurgeReady() (int64, error) { panic(errorNotSupported) } -func (*TestQueue) PurgeRejected() (int64, error) { panic(errorNotSupported) } -func (*TestQueue) Destroy() (int64, int64, error) { panic(errorNotSupported) } -func (*TestQueue) Drain(count int64) ([]string, error) { panic(errorNotSupported) } -func (*TestQueue) closeInStaleConnection() error { panic(errorNotSupported) } -func (*TestQueue) readyCount() (int64, error) { panic(errorNotSupported) } -func (*TestQueue) unackedCount() (int64, error) { panic(errorNotSupported) } -func (*TestQueue) rejectedCount() (int64, error) { panic(errorNotSupported) } -func (*TestQueue) getConsumers() ([]string, error) { panic(errorNotSupported) } - -// test helper - -func (queue *TestQueue) Reset() { - queue.LastDeliveries = []string{} -} diff --git a/vendor/github.com/adjust/rmq/v5/test_redis_client.go b/vendor/github.com/adjust/rmq/v5/test_redis_client.go deleted file mode 100644 index a1841eedb..000000000 --- a/vendor/github.com/adjust/rmq/v5/test_redis_client.go +++ /dev/null @@ -1,435 +0,0 @@ -package rmq - -import ( - "errors" - "strings" - "sync" - "time" - - "github.com/redis/go-redis/v9" -) - -// TestRedisClient is a mock for redis -type TestRedisClient struct { - store sync.Map - ttl sync.Map - mx sync.Mutex -} - -// NewTestRedisClient returns a NewTestRedisClient - -func NewTestRedisClient() *TestRedisClient { - return &TestRedisClient{} -} - -// Set sets key to hold the string value. -// If key already holds a value, it is overwritten, regardless of its type. -// Any previous time to live associated with the key is discarded on successful SET operation. -func (client *TestRedisClient) Set(key string, value string, expiration time.Duration) error { - - client.mx.Lock() - defer client.mx.Unlock() - - client.store.Store(key, value) - // Delete any previous time to live associated with the key - client.ttl.Delete(key) - - // 0.0 expiration means that the value won't expire - if expiration.Seconds() != 0.0 { - // Store the unix time at which we should delete this - client.ttl.Store(key, time.Now().Add(expiration).Unix()) - } - - return nil -} - -// Get the value of key. -// If the key does not exist or isn't a string -// the special value nil is returned. -func (client *TestRedisClient) Get(key string) (string, error) { - - value, found := client.store.Load(key) - - if found { - if stringValue, casted := value.(string); casted { - return stringValue, nil - } - } - - return "nil", nil -} - -// Del removes the specified key. A key is ignored if it does not exist. -func (client *TestRedisClient) Del(key string) (affected int64, err error) { - - _, found := client.store.Load(key) - client.store.Delete(key) - client.ttl.Delete(key) - - if found { - return 1, nil - } - return 0, nil - -} - -// TTL returns the remaining time to live of a key that has a timeout. -// This introspection capability allows a Redis client to check how many seconds a given key will continue to be part of the dataset. -// In Redis 2.6 or older the command returns -1 if the key does not exist or if the key exist but has no associated expire. -// Starting with Redis 2.8 the return value in case of error changed: -// The command returns -2 if the key does not exist. -// The command returns -1 if the key exists but has no associated expire. -func (client *TestRedisClient) TTL(key string) (ttl time.Duration, err error) { - - // Lookup the expiration map - expiration, found := client.ttl.Load(key) - - // Found an expiration time - if found { - - // It was there, but it expired; removing it now - if expiration.(int64) < time.Now().Unix() { - client.ttl.Delete(key) - return -2, nil - } - - ttl = time.Duration(expiration.(int64) - time.Now().Unix()) - return ttl, nil - } - - // Lookup the store in case this key exists but don't have an expiration - // date - _, found = client.store.Load(key) - - // The key was in store but didn't have an expiration associated - // to it. - if found { - return -1, nil - } - - return -2, nil -} - -// LPush inserts the specified value at the head of the list stored at key. -// If key does not exist, it is created as empty list before performing the push operations. -// When key holds a value that is not a list, an error is returned. -// It is possible to push multiple elements using a single command call just specifying multiple arguments -// at the end of the command. Elements are inserted one after the other to the head of the list, -// from the leftmost element to the rightmost element. -func (client *TestRedisClient) LPush(key string, values ...string) (total int64, err error) { - - client.mx.Lock() - defer client.mx.Unlock() - - list, err := client.findList(key) - - if err != nil { - return 0, nil - } - - newList := append(values, list...) - client.storeList(key, newList) - return int64(len(newList)), nil -} - -// RPop removes and returns one value from the tail of the list stored at key. -// When key holds a value that is not a list, an error is returned. -func (client *TestRedisClient) RPop(key string) (value string, err error) { - - client.mx.Lock() - defer client.mx.Unlock() - - list, err := client.findList(key) - // not a list - if err != nil { - return "", err - } - // list is empty - if len(list) == 0 { - return "", redis.Nil - } - - // Remove the last element of source (tail) - client.storeList(key, list[0:len(list)-1]) - - return list[len(list)-1], nil -} - -// LLen returns the length of the list stored at key. -// If key does not exist, it is interpreted as an empty list and 0 is returned. -// An error is returned when the value stored at key is not a list. -func (client *TestRedisClient) LLen(key string) (affected int64, err error) { - list, err := client.findList(key) - - if err != nil { - return 0, nil - } - return int64(len(list)), nil -} - -// LRem removes the first count occurrences of elements equal to -// value from the list stored at key. The count argument influences -// the operation in the following ways: -// count > 0: Remove elements equal to value moving from head to tail. -// count < 0: Remove elements equal to value moving from tail to head. -// count = 0: Remove all elements equal to value. For example, -// LREM list -2 "hello" will remove the last two occurrences of "hello" in -// the list stored at list. Note that non-existing keys are treated like empty -// lists, so when key does not exist, the command will always return 0. -func (client *TestRedisClient) LRem(key string, count int64, value string) (affected int64, err error) { - - client.mx.Lock() - defer client.mx.Unlock() - - list, err := client.findList(key) - - // Wasn't a list, or is empty - if err != nil || len(list) == 0 { - return 0, nil - } - - // Create a list that have the capacity to store - // the old one - // This will be much more performant in case of - // very long list - newList := make([]string, 0, len(list)) - - if err != nil { - return 0, nil - } - - // left to right removal of count elements - if count >= 0 { - - // All the elements are to be removed. - // Set count to max possible elements - if count == 0 { - count = int64(len(list)) - } - // left to right traversal - for index := 0; index < len(list); index++ { - - // isn't what we look for or we found enough element already - if strings.Compare(list[index], value) != 0 || affected > count { - newList = append(newList, list[index]) - } else { - affected++ - } - } - // right to left removal of count elements - } else if count < 0 { - - // right to left traversal - for index := len(list) - 1; index >= 0; index-- { - - // isn't what we look for or we found enough element already - if strings.Compare(list[index], value) != 0 || affected > count { - // prepend instead of append to keep the order - newList = append([]string{list[index]}, newList...) - } else { - affected++ - } - } - } - - // store the updated list - client.storeList(key, newList) - - return affected, nil -} - -// LTrim trims an existing list so that it will contain only the specified range of elements specified. -// Both start and stop are zero-based indexes, where 0 is the first element of the list (the head), -// 1 the next element and so on. For example: LTRIM foobar 0 2 will modify the list stored -// at foobar so that only the first three elements of the list will remain. -// start and end can also be negative numbers indicating offsets from the end of the list, -// where -1 is the last element of the list, -2 the penultimate element and so on. -// Out of range indexes will not produce an error: if start is larger than the end of the list, -// or start > end, the result will be an empty list (which causes key to be removed). -// If end is larger than the end of the list, Redis will treat it like the last element of the list -func (client *TestRedisClient) LTrim(key string, start, stop int64) error { - - client.mx.Lock() - defer client.mx.Unlock() - - list, err := client.findList(key) - - // Wasn't a list, or is empty - if err != nil || len(list) == 0 { - return nil - } - - if start < 0 { - start += int64(len(list)) - } - if stop < 0 { - stop += int64(len(list)) - } - - // invalid values cause the remove of the key - if start > stop { - client.store.Delete(key) - return nil - } - - client.storeList(key, list[start:stop]) - return nil -} - -// RPopLPush atomically returns and removes the last element (tail) of the list stored at source, -// and pushes the element at the first element (head) of the list stored at destination. -// For example: consider source holding the list a,b,c, and destination holding the list x,y,z. -// Executing RPOPLPUSH results in source holding a,b and destination holding c,x,y,z. -// If source does not exist, the value nil is returned and no operation is performed. -// If source and destination are the same, the operation is equivalent to removing the -// last element from the list and pushing it as first element of the list, -// so it can be considered as a list rotation command. -func (client *TestRedisClient) RPopLPush(source, destination string) (value string, err error) { - - client.mx.Lock() - defer client.mx.Unlock() - - sourceList, sourceErr := client.findList(source) - destList, destErr := client.findList(destination) - - // One of the two isn't a list - if sourceErr != nil || destErr != nil { - return "", ErrorNotFound - } - // we have nothing to move - if len(sourceList) == 0 { - return "", ErrorNotFound - } - - // Remove the last element of source (tail) - client.storeList(source, sourceList[0:len(sourceList)-1]) - // Put the last element of source (tail) and prepend it to dest - client.storeList(destination, append([]string{sourceList[len(sourceList)-1]}, destList...)) - - return sourceList[len(sourceList)-1], nil -} - -// SAdd adds the specified members to the set stored at key. -// Specified members that are already a member of this set are ignored. -// If key does not exist, a new set is created before adding the specified members. -// An error is returned when the value stored at key is not a set. -func (client *TestRedisClient) SAdd(key, value string) (total int64, err error) { - - client.mx.Lock() - defer client.mx.Unlock() - - set, err := client.findSet(key) - if err != nil { - return 0, err - } - - set[value] = struct{}{} - client.storeSet(key, set) - return int64(len(set)), nil -} - -// SMembers returns all the members of the set value stored at key. -// This has the same effect as running SINTER with one argument key. -func (client *TestRedisClient) SMembers(key string) (members []string, err error) { - set, err := client.findSet(key) - if err != nil { - return members, nil - } - - members = make([]string, 0, len(set)) - for k := range set { - members = append(members, k) - } - - return members, nil -} - -// SRem removes the specified members from the set stored at key. -// Specified members that are not a member of this set are ignored. -// If key does not exist, it is treated as an empty set and this command returns 0. -// An error is returned when the value stored at key is not a set. -func (client *TestRedisClient) SRem(key, value string) (affected int64, err error) { - - client.mx.Lock() - defer client.mx.Unlock() - - set, err := client.findSet(key) - if err != nil || len(set) == 0 { - return 0, nil - } - - if _, found := set[value]; found != false { - delete(set, value) - return 1, nil - } - - return 0, nil -} - -// FlushDb delete all the keys of the currently selected DB. This command never fails. -func (client *TestRedisClient) FlushDb() error { - client.store = *new(sync.Map) - client.ttl = *new(sync.Map) - return nil -} - -// storeSet stores a set -func (client *TestRedisClient) storeSet(key string, set map[string]struct{}) { - client.store.Store(key, set) -} - -// findSet finds a set -func (client *TestRedisClient) findSet(key string) (map[string]struct{}, error) { - // Lookup the store for the list - storedValue, found := client.store.Load(key) - if found { - // list are stored as pointer to []string - set, casted := storedValue.(map[string]struct{}) - - if casted { - return set, nil - } - - return nil, errors.New("Stored value wasn't a set") - } - - // return an empty set if not found - return make(map[string]struct{}), nil -} - -// storeList is an helper function so others don't have to deal with pointers -func (client *TestRedisClient) storeList(key string, list []string) { - client.store.Store(key, &list) -} - -// findList returns the list stored at key. -// if key doesn't exist, an empty list is returned -// an error is returned when the value at key isn't a list -func (client *TestRedisClient) findList(key string) ([]string, error) { - // Lookup the store for the list - storedValue, found := client.store.Load(key) - if found { - - // list are stored as pointer to []string - list, casted := storedValue.(*[]string) - - // Successful cass from interface{} to *[]string - // Preprend the new key - if casted { - - // This mock use sync.Map to be thread safe. - // sync.Map only accepts interface{} as values and - // in order to store an array as interface{}, you need - // to use a pointer to it. - // We could return the pointer instead of the value - // and gain some performances here. Returning the pointer, - // however, will open us up to race conditions. - return *list, nil - } - - return nil, errors.New("Stored value wasn't a list") - } - - // return an empty list if not found - return []string{}, nil -} diff --git a/vendor/github.com/adjust/rmq/v5/test_util.go b/vendor/github.com/adjust/rmq/v5/test_util.go deleted file mode 100644 index e1eb74016..000000000 --- a/vendor/github.com/adjust/rmq/v5/test_util.go +++ /dev/null @@ -1,89 +0,0 @@ -package rmq - -import ( - "os" - "strings" - "testing" - "time" - - "github.com/alicebob/miniredis/v2" - "github.com/redis/go-redis/v9" - "github.com/stretchr/testify/assert" -) - -func testRedis(t testing.TB) (options *redis.Options, close func()) { - t.Helper() - - if redisAddr, ok := os.LookupEnv("REDIS_ADDR"); ok { - return &redis.Options{Addr: redisAddr}, func() {} - } - - mr := miniredis.RunT(t) - return &redis.Options{Addr: mr.Addr()}, mr.Close -} - -func testClusterRedis(t testing.TB) (options *redis.ClusterOptions, close func()) { - t.Helper() - - // Follow these steps to set up a local redis cluster: - // https://github.com/redis/redis/tree/unstable/utils/create-cluster - // Then run the tests like this: - // REDIS_CLUSTER_ADDR="localhost:30001,localhost:30002,localhost:30003,localhost:30004,localhost:30005,localhost:30006" go test - if redisAddrs, ok := os.LookupEnv("REDIS_CLUSTER_ADDR"); ok { - addrs := strings.Split(redisAddrs, ",") - return &redis.ClusterOptions{Addrs: addrs}, func() {} - } - - mr1 := miniredis.RunT(t) - mr2 := miniredis.RunT(t) - mr3 := miniredis.RunT(t) - - options = &redis.ClusterOptions{ - Addrs: []string{ - mr1.Addr(), - mr2.Addr(), - mr3.Addr(), - }, - } - - closeFunc := func() { - mr1.Close() - mr2.Close() - mr3.Close() - } - - return options, closeFunc -} - -func eventuallyReady(t *testing.T, queue Queue, expectedReady int64) { - t.Helper() - assert.Eventually(t, func() bool { - count, err := queue.readyCount() - if err != nil { - return false - } - return count == expectedReady - }, 1*time.Second, 2*time.Millisecond) -} - -func eventuallyUnacked(t *testing.T, queue Queue, expectedUnacked int64) { - t.Helper() - assert.Eventually(t, func() bool { - count, err := queue.unackedCount() - if err != nil { - return false - } - return count == expectedUnacked - }, 1*time.Second, 2*time.Millisecond) -} - -func eventuallyRejected(t *testing.T, queue Queue, expectedRejected int64) { - t.Helper() - assert.Eventually(t, func() bool { - count, err := queue.rejectedCount() - if err != nil { - return false - } - return count == expectedRejected - }, 1*time.Second, 2*time.Millisecond) -} 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 33bd03d06..000000000 --- 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 bb9c20a09..000000000 --- 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 3b0a5dc09..000000000 --- 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 36614ef40..000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/README.md +++ /dev/null @@ -1,120 +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. - -As a special case, if the type switch statement contains a `default` clause -that always panics, then exhaustiveness checks are still performed. - -## 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 68a49daad..000000000 --- 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 21d751af4..000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/check.go +++ /dev/null @@ -1,184 +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 { - var list []string - 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) []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); 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, -) error { - def, missing := missingVariantsInSwitch(pkg, defs, swtch) - 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, -) (*sumTypeDef, []types.Object) { - asserted := findTypeAssertExpr(swtch) - ty := pkg.TypesInfo.TypeOf(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 hasDefault && !defaultClauseAlwaysPanics(swtch) { - // A catch-all case defeats all exhaustiveness checks. - return def, nil - } - var variantTypes []types.Type - for _, expr := range variantExprs { - variantTypes = append(variantTypes, pkg.TypesInfo.TypeOf(expr)) - } - return def, def.missing(variantTypes) -} - -// 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/decl.go b/vendor/github.com/alecthomas/go-check-sumtype/decl.go deleted file mode 100644 index 9dec9eefd..000000000 --- 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 24729ac01..000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/def.go +++ /dev/null @@ -1,173 +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) { - var defs []sumTypeDef - 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 := 0; i < iface.NumMethods(); i++ { - 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) []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 - } - } - if !found { - missing = append(missing, v) - } - } - return missing -} - -// 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 -} 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 2b6e86764..000000000 --- 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/run.go b/vendor/github.com/alecthomas/go-check-sumtype/run.go deleted file mode 100644 index fdcb643c5..000000000 --- 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) []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); 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 b4822913a..000000000 --- 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 9310fbcff..000000000 --- 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 e30a0cde7..000000000 --- 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/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 dea842333..000000000 --- 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 f78bb8cb6..000000000 --- a/vendor/github.com/alexkohler/nakedret/v2/nakedret.go +++ /dev/null @@ -1,309 +0,0 @@ -package nakedret - -import ( - "bytes" - "errors" - "flag" - "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(defaultLines uint) *analysis.Analyzer { - nakedRet := &NakedReturnRunner{} - flags := flag.NewFlagSet("nakedret", flag.ExitOnError) - flags.UintVar(&nakedRet.MaxLength, "l", defaultLines, "maximum number of lines for a naked return function") - var analyzer = &analysis.Analyzer{ - Name: "nakedret", - Doc: "Checks that functions with naked returns are not longer than a maximum size (can be zero).", - Run: nakedRet.run, - Flags: *flags, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } - return analyzer -} - -type NakedReturnRunner struct { - MaxLength uint -} - -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, - } - inspector.Nodes(nodeFilter, retVis.NodesVisit) - return nil, nil -} - -type returnsVisitor struct { - pass *analysis.Pass - f *token.FileSet - maxLength uint - - // 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, 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(*maxLength) - 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()) - 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 9310fbcff..000000000 --- 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 72d8b95f7..000000000 --- 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/alicebob/gopher-json/LICENSE b/vendor/github.com/alicebob/gopher-json/LICENSE deleted file mode 100644 index 68a49daad..000000000 --- a/vendor/github.com/alicebob/gopher-json/LICENSE +++ /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/alicebob/gopher-json/README.md b/vendor/github.com/alicebob/gopher-json/README.md deleted file mode 100644 index 84fe1bdf9..000000000 --- a/vendor/github.com/alicebob/gopher-json/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# gopher-json [![GoDoc](https://godoc.org/layeh.com/gopher-json?status.svg)](https://godoc.org/layeh.com/gopher-json) - -Package json is a simple JSON encoder/decoder for [gopher-lua](https://github.com/yuin/gopher-lua). - -## License - -Public domain diff --git a/vendor/github.com/alicebob/gopher-json/doc.go b/vendor/github.com/alicebob/gopher-json/doc.go deleted file mode 100644 index 8cf73d45a..000000000 --- a/vendor/github.com/alicebob/gopher-json/doc.go +++ /dev/null @@ -1,35 +0,0 @@ -// Package json is a simple JSON encoder/decoder for gopher-lua. -// -// # Documentation -// -// The following functions are exposed by the library: -// -// decode(string): Decodes a JSON string. Returns nil and an error string if -// the string could not be decoded. -// encode(value): Encodes a value into a JSON string. Returns nil and an error -// string if the value could not be encoded. -// -// The following types are supported: -// -// Lua | JSON -// ---------+----- -// nil | null -// number | number -// string | string -// table | object: when table is non-empty and has only string keys -// | array: when table is empty, or has only sequential numeric keys -// | starting from 1 -// -// Attempting to encode any other Lua type will result in an error. -// -// # Example -// -// Below is an example usage of the library: -// -// import ( -// luajson "layeh.com/gopher-json" -// ) -// -// L := lua.NewState() -// luajson.Preload(L) -package json diff --git a/vendor/github.com/alicebob/gopher-json/json.go b/vendor/github.com/alicebob/gopher-json/json.go deleted file mode 100644 index 11561333d..000000000 --- a/vendor/github.com/alicebob/gopher-json/json.go +++ /dev/null @@ -1,189 +0,0 @@ -package json - -import ( - "encoding/json" - "errors" - - "github.com/yuin/gopher-lua" -) - -// Preload adds json to the given Lua state's package.preload table. After it -// has been preloaded, it can be loaded using require: -// -// local json = require("json") -func Preload(L *lua.LState) { - L.PreloadModule("json", Loader) -} - -// Loader is the module loader function. -func Loader(L *lua.LState) int { - t := L.NewTable() - L.SetFuncs(t, api) - L.Push(t) - return 1 -} - -var api = map[string]lua.LGFunction{ - "decode": apiDecode, - "encode": apiEncode, -} - -func apiDecode(L *lua.LState) int { - if L.GetTop() != 1 { - L.Error(lua.LString("bad argument #1 to decode"), 1) - return 0 - } - str := L.CheckString(1) - - value, err := Decode(L, []byte(str)) - if err != nil { - L.Push(lua.LNil) - L.Push(lua.LString(err.Error())) - return 2 - } - L.Push(value) - return 1 -} - -func apiEncode(L *lua.LState) int { - if L.GetTop() != 1 { - L.Error(lua.LString("bad argument #1 to encode"), 1) - return 0 - } - value := L.CheckAny(1) - - data, err := Encode(value) - if err != nil { - L.Push(lua.LNil) - L.Push(lua.LString(err.Error())) - return 2 - } - L.Push(lua.LString(string(data))) - return 1 -} - -var ( - errNested = errors.New("cannot encode recursively nested tables to JSON") - errSparseArray = errors.New("cannot encode sparse array") - errInvalidKeys = errors.New("cannot encode mixed or invalid key types") -) - -type invalidTypeError lua.LValueType - -func (i invalidTypeError) Error() string { - return `cannot encode ` + lua.LValueType(i).String() + ` to JSON` -} - -// Encode returns the JSON encoding of value. -func Encode(value lua.LValue) ([]byte, error) { - return json.Marshal(jsonValue{ - LValue: value, - visited: make(map[*lua.LTable]bool), - }) -} - -type jsonValue struct { - lua.LValue - visited map[*lua.LTable]bool -} - -func (j jsonValue) MarshalJSON() (data []byte, err error) { - switch converted := j.LValue.(type) { - case lua.LBool: - data, err = json.Marshal(bool(converted)) - case lua.LNumber: - data, err = json.Marshal(float64(converted)) - case *lua.LNilType: - data = []byte(`null`) - case lua.LString: - data, err = json.Marshal(string(converted)) - case *lua.LTable: - if j.visited[converted] { - return nil, errNested - } - j.visited[converted] = true - - key, value := converted.Next(lua.LNil) - - switch key.Type() { - case lua.LTNil: // empty table - data = []byte(`[]`) - case lua.LTNumber: - arr := make([]jsonValue, 0, converted.Len()) - expectedKey := lua.LNumber(1) - for key != lua.LNil { - if key.Type() != lua.LTNumber { - err = errInvalidKeys - return - } - if expectedKey != key { - err = errSparseArray - return - } - arr = append(arr, jsonValue{value, j.visited}) - expectedKey++ - key, value = converted.Next(key) - } - data, err = json.Marshal(arr) - case lua.LTString: - obj := make(map[string]jsonValue) - for key != lua.LNil { - if key.Type() != lua.LTString { - err = errInvalidKeys - return - } - obj[key.String()] = jsonValue{value, j.visited} - key, value = converted.Next(key) - } - data, err = json.Marshal(obj) - default: - err = errInvalidKeys - } - default: - err = invalidTypeError(j.LValue.Type()) - } - return -} - -// Decode converts the JSON encoded data to Lua values. -func Decode(L *lua.LState, data []byte) (lua.LValue, error) { - var value interface{} - err := json.Unmarshal(data, &value) - if err != nil { - return nil, err - } - return DecodeValue(L, value), nil -} - -// DecodeValue converts the value to a Lua value. -// -// This function only converts values that the encoding/json package decodes to. -// All other values will return lua.LNil. -func DecodeValue(L *lua.LState, value interface{}) lua.LValue { - switch converted := value.(type) { - case bool: - return lua.LBool(converted) - case float64: - return lua.LNumber(converted) - case string: - return lua.LString(converted) - case json.Number: - return lua.LString(converted) - case []interface{}: - arr := L.CreateTable(len(converted), 0) - for _, item := range converted { - arr.Append(DecodeValue(L, item)) - } - return arr - case map[string]interface{}: - tbl := L.CreateTable(0, len(converted)) - for key, item := range converted { - tbl.RawSetH(lua.LString(key), DecodeValue(L, item)) - } - return tbl - case nil: - return lua.LNil - } - - return lua.LNil -} diff --git a/vendor/github.com/alicebob/miniredis/v2/.gitignore b/vendor/github.com/alicebob/miniredis/v2/.gitignore deleted file mode 100644 index 8016b4be3..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/integration/redis_src/ -/integration/dump.rdb -*.swp -/integration/nodes.conf -.idea/ -miniredis.iml diff --git a/vendor/github.com/alicebob/miniredis/v2/CHANGELOG.md b/vendor/github.com/alicebob/miniredis/v2/CHANGELOG.md deleted file mode 100644 index ba690a2d1..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/CHANGELOG.md +++ /dev/null @@ -1,270 +0,0 @@ -## Changelog - - -### v2.30.4 - -- fix ZADD LT/LG (thanks @sejin-P) -- fix COPY (thanks @jerargus) -- quicker SPOP - - -### v2.30.3 - -- fix lua error_reply (thanks @pkierski) -- fix use of blocking functions in lua -- support for ZMSCORE (thanks @lsgndln) -- lua cache (thanks @tonyhb) - - -### v2.30.2 - -- support MINID in XADD (thanks @nathan-cormier) -- support BLMOVE (thanks @sevein) -- fix COMMAND (thanks @pje) -- fix 'XREAD ... $' on a non-existing stream - - -### v2.30.1 - -- support SET NX GET special case - - -### v2.30.0 - -- implement redis 7.0.x (from 6.X). Main changes: - - test against 7.0.7 - - update error messages - - support nx|xx|gt|lt options in [P]EXPIRE[AT] - - update how deleted items are processed in pending queues in streams - - -### v2.23.1 - -- resolve $ to latest ID in XREAD (thanks @josh-hook) -- handle disconnect in blocking functions (thanks @jgirtakovskis) -- fix type conversion bug in redisToLua (thanks Sandy Harvie) -- BRPOP{LPUSH} timeout can be float since 6.0 - - -### v2.23.0 - -- basic INFO support (thanks @kirill-a-belov) -- support COUNT in SSCAN (thanks @Abdi-dd) -- test and support Go 1.19 -- support LPOS (thanks @ianstarz) -- support XPENDING, XGROUP {CREATECONSUMER,DESTROY,DELCONSUMER}, XINFO {CONSUMERS,GROUPS}, XCLAIM (thanks @sandyharvie) - - -### v2.22.0 - -- set miniredis.DumpMaxLineLen to get more Dump() info (thanks @afjoseph) -- fix invalid resposne of COMMAND (thanks @zsh1995) -- fix possibility to generate duplicate IDs in XADD (thanks @readams) -- adds support for XAUTOCLAIM min-idle parameter (thanks @readams) - - -### v2.21.0 - -- support for GETEX (thanks @dntj) -- support for GT and LT in ZADD (thanks @lsgndln) -- support for XAUTOCLAIM (thanks @randall-fulton) - - -### v2.20.0 - -- back to support Go >= 1.14 (thanks @ajatprabha and @marcind) - - -### v2.19.0 - -- support for TYPE in SCAN (thanks @0xDiddi) -- update BITPOS (thanks @dirkm) -- fix a lua redis.call() return value (thanks @mpetronic) -- update ZRANGE (thanks @valdemarpereira) - - -### v2.18.0 - -- support for ZUNION (thanks @propan) -- support for COPY (thanks @matiasinsaurralde and @rockitbaby) -- support for LMOVE (thanks @btwear) - - -### v2.17.0 - -- added miniredis.RunT(t) - - -### v2.16.1 - -- fix ZINTERSTORE with wets (thanks @lingjl2010 and @okhowang) -- fix exclusive ranges in XRANGE (thanks @joseotoro) - - -### v2.16.0 - -- simplify some code (thanks @zonque) -- support for EXAT/PXAT in SET -- support for XTRIM (thanks @joseotoro) -- support for ZRANDMEMBER -- support for redis.log() in lua (thanks @dirkm) - - -### v2.15.2 - -- Fix race condition in blocking code (thanks @zonque and @robx) -- XREAD accepts '$' as ID (thanks @bradengroom) - - -### v2.15.1 - -- EVAL should cache the script (thanks @guoshimin) - - -### v2.15.0 - -- target redis 6.2 and added new args to various commands -- support for all hyperlog commands (thanks @ilbaktin) -- support for GETDEL (thanks @wszaranski) - - -### v2.14.5 - -- added XPENDING -- support for BLOCK option in XREAD and XREADGROUP - - -### v2.14.4 - -- fix BITPOS error (thanks @xiaoyuzdy) -- small fixes for XREAD, XACK, and XDEL. Mostly error cases. -- fix empty EXEC return type (thanks @ashanbrown) -- fix XDEL (thanks @svakili and @yvesf) -- fix FLUSHALL for streams (thanks @svakili) - - -### v2.14.3 - -- fix problem where Lua code didn't set the selected DB -- update to redis 6.0.10 (thanks @lazappa) - - -### v2.14.2 - -- update LUA dependency -- deal with (p)unsubscribe when there are no channels - - -### v2.14.1 - -- mod tidy - - -### v2.14.0 - -- support for HELLO and the RESP3 protocol -- KEEPTTL in SET (thanks @johnpena) - - -### v2.13.3 - -- support Go 1.14 and 1.15 -- update the `Check...()` methods -- support for XREAD (thanks @pieterlexis) - - -### v2.13.2 - -- Use SAN instead of CN in self signed cert for testing (thanks @johejo) -- Travis CI now tests against the most recent two versions of Go (thanks @johejo) -- changed unit and integration tests to compare raw payloads, not parsed payloads -- remove "redigo" dependency - - -### v2.13.1 - -- added HSTRLEN -- minimal support for ACL users in AUTH - - -### v2.13.0 - -- added RunTLS(...) -- added SetError(...) - - -### v2.12.0 - -- redis 6 -- Lua json update (thanks @gsmith85) -- CLUSTER commands (thanks @kratisto) -- fix TOUCH -- fix a shutdown race condition - - -### v2.11.4 - -- ZUNIONSTORE now supports standard set types (thanks @wshirey) - - -### v2.11.3 - -- support for TOUCH (thanks @cleroux) -- support for cluster and stream commands (thanks @kak-tus) - - -### v2.11.2 - -- make sure Lua code is executed concurrently -- add command GEORADIUSBYMEMBER (thanks @kyeett) - - -### v2.11.1 - -- globals protection for Lua code (thanks @vk-outreach) -- HSET update (thanks @carlgreen) -- fix BLPOP block on shutdown (thanks @Asalle) - - -### v2.11.0 - -- added XRANGE/XREVRANGE, XADD, and XLEN (thanks @skateinmars) -- added GEODIST -- improved precision for geohashes, closer to what real redis does -- use 128bit floats internally for INCRBYFLOAT and related (thanks @timnd) - - -### v2.10.1 - -- added m.Server() - - -### v2.10.0 - -- added UNLINK -- fix DEL zero-argument case -- cleanup some direct access commands -- added GEOADD, GEOPOS, GEORADIUS, and GEORADIUS_RO - - -### v2.9.1 - -- fix issue with ZRANGEBYLEX -- fix issue with BRPOPLPUSH and direct access - - -### v2.9.0 - -- proper versioned import of github.com/gomodule/redigo (thanks @yfei1) -- fix messages generated by PSUBSCRIBE -- optional internal seed (thanks @zikaeroh) - - -### v2.8.0 - -Proper `v2` in go.mod. - - -### older - -See https://github.com/alicebob/miniredis/releases for the full changelog diff --git a/vendor/github.com/alicebob/miniredis/v2/LICENSE b/vendor/github.com/alicebob/miniredis/v2/LICENSE deleted file mode 100644 index bb02657ca..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Harmen - -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/alicebob/miniredis/v2/Makefile b/vendor/github.com/alicebob/miniredis/v2/Makefile deleted file mode 100644 index 125f574cf..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -.PHONY: all test testrace int - -all: test - -test: - go test ./... - -testrace: - go test -race ./... - -int: - INT=1 go test ./... diff --git a/vendor/github.com/alicebob/miniredis/v2/README.md b/vendor/github.com/alicebob/miniredis/v2/README.md deleted file mode 100644 index 3ec7ea284..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/README.md +++ /dev/null @@ -1,334 +0,0 @@ -# Miniredis - -Pure Go Redis test server, used in Go unittests. - - -## - -Sometimes you want to test code which uses Redis, without making it a full-blown -integration test. -Miniredis implements (parts of) the Redis server, to be used in unittests. It -enables a simple, cheap, in-memory, Redis replacement, with a real TCP interface. Think of it as the Redis version of `net/http/httptest`. - -It saves you from using mock code, and since the redis server lives in the -test process you can query for values directly, without going through the server -stack. - -There are no dependencies on external binaries, so you can easily integrate it in automated build processes. - -Be sure to import v2: -``` -import "github.com/alicebob/miniredis/v2" -``` - -## Commands - -Implemented commands: - - - Connection (complete) - - AUTH -- see RequireAuth() - - ECHO - - HELLO -- see RequireUserAuth() - - PING - - SELECT - - SWAPDB - - QUIT - - Key - - COPY - - DEL - - EXISTS - - EXPIRE - - EXPIREAT - - KEYS - - MOVE - - PERSIST - - PEXPIRE - - PEXPIREAT - - PTTL - - RENAME - - RENAMENX - - RANDOMKEY -- see m.Seed(...) - - SCAN - - TOUCH - - TTL - - TYPE - - UNLINK - - Transactions (complete) - - DISCARD - - EXEC - - MULTI - - UNWATCH - - WATCH - - Server - - DBSIZE - - FLUSHALL - - FLUSHDB - - TIME -- returns time.Now() or value set by SetTime() - - COMMAND -- partly - - INFO -- partly, returns only "clients" section with one field "connected_clients" - - String keys (complete) - - APPEND - - BITCOUNT - - BITOP - - BITPOS - - DECR - - DECRBY - - GET - - GETBIT - - GETRANGE - - GETSET - - GETDEL - - GETEX - - INCR - - INCRBY - - INCRBYFLOAT - - MGET - - MSET - - MSETNX - - PSETEX - - SET - - SETBIT - - SETEX - - SETNX - - SETRANGE - - STRLEN - - Hash keys (complete) - - HDEL - - HEXISTS - - HGET - - HGETALL - - HINCRBY - - HINCRBYFLOAT - - HKEYS - - HLEN - - HMGET - - HMSET - - HSET - - HSETNX - - HSTRLEN - - HVALS - - HSCAN - - List keys (complete) - - BLPOP - - BRPOP - - BRPOPLPUSH - - LINDEX - - LINSERT - - LLEN - - LPOP - - LPUSH - - LPUSHX - - LRANGE - - LREM - - LSET - - LTRIM - - RPOP - - RPOPLPUSH - - RPUSH - - RPUSHX - - LMOVE - - BLMOVE - - Pub/Sub (complete) - - PSUBSCRIBE - - PUBLISH - - PUBSUB - - PUNSUBSCRIBE - - SUBSCRIBE - - UNSUBSCRIBE - - Set keys (complete) - - SADD - - SCARD - - SDIFF - - SDIFFSTORE - - SINTER - - SINTERSTORE - - SISMEMBER - - SMEMBERS - - SMOVE - - SPOP -- see m.Seed(...) - - SRANDMEMBER -- see m.Seed(...) - - SREM - - SUNION - - SUNIONSTORE - - SSCAN - - Sorted Set keys (complete) - - ZADD - - ZCARD - - ZCOUNT - - ZINCRBY - - ZINTERSTORE - - ZLEXCOUNT - - ZPOPMIN - - ZPOPMAX - - ZRANDMEMBER - - ZRANGE - - ZRANGEBYLEX - - ZRANGEBYSCORE - - ZRANK - - ZREM - - ZREMRANGEBYLEX - - ZREMRANGEBYRANK - - ZREMRANGEBYSCORE - - ZREVRANGE - - ZREVRANGEBYLEX - - ZREVRANGEBYSCORE - - ZREVRANK - - ZSCORE - - ZUNION - - ZUNIONSTORE - - ZSCAN - - Stream keys - - XACK - - XADD - - XAUTOCLAIM - - XCLAIM - - XDEL - - XGROUP CREATE - - XGROUP CREATECONSUMER - - XGROUP DESTROY - - XGROUP DELCONSUMER - - XINFO STREAM -- partly - - XINFO GROUPS - - XINFO CONSUMERS -- partly - - XLEN - - XRANGE - - XREAD - - XREADGROUP - - XREVRANGE - - XPENDING - - XTRIM - - Scripting - - EVAL - - EVALSHA - - SCRIPT LOAD - - SCRIPT EXISTS - - SCRIPT FLUSH - - GEO - - GEOADD - - GEODIST - - ~~GEOHASH~~ - - GEOPOS - - GEORADIUS - - GEORADIUS_RO - - GEORADIUSBYMEMBER - - GEORADIUSBYMEMBER_RO - - Cluster - - CLUSTER SLOTS - - CLUSTER KEYSLOT - - CLUSTER NODES - - HyperLogLog (complete) - - PFADD - - PFCOUNT - - PFMERGE - - -## TTLs, key expiration, and time - -Since miniredis is intended to be used in unittests TTLs don't decrease -automatically. You can use `TTL()` to get the TTL (as a time.Duration) of a -key. It will return 0 when no TTL is set. - -`m.FastForward(d)` can be used to decrement all TTLs. All TTLs which become <= -0 will be removed. - -EXPIREAT and PEXPIREAT values will be -converted to a duration. For that you can either set m.SetTime(t) to use that -time as the base for the (P)EXPIREAT conversion, or don't call SetTime(), in -which case time.Now() will be used. - -SetTime() also sets the value returned by TIME, which defaults to time.Now(). -It is not updated by FastForward, only by SetTime. - -## Randomness and Seed() - -Miniredis will use `math/rand`'s global RNG for randomness unless a seed is -provided by calling `m.Seed(...)`. If a seed is provided, then miniredis will -use its own RNG based on that seed. - -Commands which use randomness are: RANDOMKEY, SPOP, and SRANDMEMBER. - -## Example - -``` Go - -import ( - ... - "github.com/alicebob/miniredis/v2" - ... -) - -func TestSomething(t *testing.T) { - s := miniredis.RunT(t) - - // Optionally set some keys your code expects: - s.Set("foo", "bar") - s.HSet("some", "other", "key") - - // Run your code and see if it behaves. - // An example using the redigo library from "github.com/gomodule/redigo/redis": - c, err := redis.Dial("tcp", s.Addr()) - _, err = c.Do("SET", "foo", "bar") - - // Optionally check values in redis... - if got, err := s.Get("foo"); err != nil || got != "bar" { - t.Error("'foo' has the wrong value") - } - // ... or use a helper for that: - s.CheckGet(t, "foo", "bar") - - // TTL and expiration: - s.Set("foo", "bar") - s.SetTTL("foo", 10*time.Second) - s.FastForward(11 * time.Second) - if s.Exists("foo") { - t.Fatal("'foo' should not have existed anymore") - } -} -``` - -## Not supported - -Commands which will probably not be implemented: - - - CLUSTER (all) - - ~~CLUSTER *~~ - - ~~READONLY~~ - - ~~READWRITE~~ - - Key - - ~~DUMP~~ - - ~~MIGRATE~~ - - ~~OBJECT~~ - - ~~RESTORE~~ - - ~~WAIT~~ - - Scripting - - ~~SCRIPT DEBUG~~ - - ~~SCRIPT KILL~~ - - Server - - ~~BGSAVE~~ - - ~~BGWRITEAOF~~ - - ~~CLIENT *~~ - - ~~CONFIG *~~ - - ~~DEBUG *~~ - - ~~LASTSAVE~~ - - ~~MONITOR~~ - - ~~ROLE~~ - - ~~SAVE~~ - - ~~SHUTDOWN~~ - - ~~SLAVEOF~~ - - ~~SLOWLOG~~ - - ~~SYNC~~ - - -## &c. - -Integration tests are run against Redis 7.0.7. The [./integration](./integration/) subdir -compares miniredis against a real redis instance. - -The Redis 6 RESP3 protocol is supported. If there are problems, please open -an issue. - -If you want to test Redis Sentinel have a look at [minisentinel](https://github.com/Bose/minisentinel). - -A changelog is kept at [CHANGELOG.md](https://github.com/alicebob/miniredis/blob/master/CHANGELOG.md). - -[![Go Reference](https://pkg.go.dev/badge/github.com/alicebob/miniredis/v2.svg)](https://pkg.go.dev/github.com/alicebob/miniredis/v2) diff --git a/vendor/github.com/alicebob/miniredis/v2/check.go b/vendor/github.com/alicebob/miniredis/v2/check.go deleted file mode 100644 index acd0d5539..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/check.go +++ /dev/null @@ -1,63 +0,0 @@ -package miniredis - -import ( - "reflect" - "sort" -) - -// T is implemented by Testing.T -type T interface { - Helper() - Errorf(string, ...interface{}) -} - -// CheckGet does not call Errorf() iff there is a string key with the -// expected value. Normal use case is `m.CheckGet(t, "username", "theking")`. -func (m *Miniredis) CheckGet(t T, key, expected string) { - t.Helper() - - found, err := m.Get(key) - if err != nil { - t.Errorf("GET error, key %#v: %v", key, err) - return - } - if found != expected { - t.Errorf("GET error, key %#v: Expected %#v, got %#v", key, expected, found) - return - } -} - -// CheckList does not call Errorf() iff there is a list key with the -// expected values. -// Normal use case is `m.CheckGet(t, "favorite_colors", "red", "green", "infrared")`. -func (m *Miniredis) CheckList(t T, key string, expected ...string) { - t.Helper() - - found, err := m.List(key) - if err != nil { - t.Errorf("List error, key %#v: %v", key, err) - return - } - if !reflect.DeepEqual(expected, found) { - t.Errorf("List error, key %#v: Expected %#v, got %#v", key, expected, found) - return - } -} - -// CheckSet does not call Errorf() iff there is a set key with the -// expected values. -// Normal use case is `m.CheckSet(t, "visited", "Rome", "Stockholm", "Dublin")`. -func (m *Miniredis) CheckSet(t T, key string, expected ...string) { - t.Helper() - - found, err := m.Members(key) - if err != nil { - t.Errorf("Set error, key %#v: %v", key, err) - return - } - sort.Strings(expected) - if !reflect.DeepEqual(expected, found) { - t.Errorf("Set error, key %#v: Expected %#v, got %#v", key, expected, found) - return - } -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_cluster.go b/vendor/github.com/alicebob/miniredis/v2/cmd_cluster.go deleted file mode 100644 index 9951f3dd3..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_cluster.go +++ /dev/null @@ -1,67 +0,0 @@ -// Commands from https://redis.io/commands#cluster - -package miniredis - -import ( - "fmt" - "strings" - - "github.com/alicebob/miniredis/v2/server" -) - -// commandsCluster handles some cluster operations. -func commandsCluster(m *Miniredis) { - m.srv.Register("CLUSTER", m.cmdCluster) -} - -func (m *Miniredis) cmdCluster(c *server.Peer, cmd string, args []string) { - if !m.handleAuth(c) { - return - } - - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - switch strings.ToUpper(args[0]) { - case "SLOTS": - m.cmdClusterSlots(c, cmd, args) - case "KEYSLOT": - m.cmdClusterKeySlot(c, cmd, args) - case "NODES": - m.cmdClusterNodes(c, cmd, args) - default: - setDirty(c) - c.WriteError(fmt.Sprintf("ERR 'CLUSTER %s' not supported", strings.Join(args, " "))) - return - } -} - -// CLUSTER SLOTS -func (m *Miniredis) cmdClusterSlots(c *server.Peer, cmd string, args []string) { - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - c.WriteLen(1) - c.WriteLen(3) - c.WriteInt(0) - c.WriteInt(16383) - c.WriteLen(3) - c.WriteBulk(m.srv.Addr().IP.String()) - c.WriteInt(m.srv.Addr().Port) - c.WriteBulk("09dbe9720cda62f7865eabc5fd8857c5d2678366") - }) -} - -// CLUSTER KEYSLOT -func (m *Miniredis) cmdClusterKeySlot(c *server.Peer, cmd string, args []string) { - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - c.WriteInt(163) - }) -} - -// CLUSTER NODES -func (m *Miniredis) cmdClusterNodes(c *server.Peer, cmd string, args []string) { - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - c.WriteBulk("e7d1eecce10fd6bb5eb35b9f99a514335d9ba9ca 127.0.0.1:7000@7000 myself,master - 0 0 1 connected 0-16383") - }) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_command.go b/vendor/github.com/alicebob/miniredis/v2/cmd_command.go deleted file mode 100644 index 8f73b2bac..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_command.go +++ /dev/null @@ -1,14 +0,0 @@ -// Command 'COMMAND' from https://redis.io/commands#server - -package miniredis - -import "github.com/alicebob/miniredis/v2/server" - -func (m *Miniredis) cmdCommand(c *server.Peer, cmd string, args []string) { - // Got from redis 5.0.7 with - // echo 'COMMAND' | nc redis_addr redis_port - - res := "*200\r\n*6\r\n$12\r\nhincrbyfloat\r\n:4\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$10\r\nxreadgroup\r\n:-7\r\n*3\r\n+write\r\n+noscript\r\n+movablekeys\r\n:1\r\n:1\r\n:1\r\n*6\r\n$10\r\nsdiffstore\r\n:-3\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$8\r\nlastsave\r\n:1\r\n*2\r\n+random\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\nsetnx\r\n:3\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$8\r\nbzpopmax\r\n:-3\r\n*3\r\n+write\r\n+noscript\r\n+fast\r\n:1\r\n:-2\r\n:1\r\n*6\r\n$12\r\npunsubscribe\r\n:-1\r\n*4\r\n+pubsub\r\n+noscript\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\nxack\r\n:-4\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$10\r\npfselftest\r\n:1\r\n*1\r\n+admin\r\n:0\r\n:0\r\n:0\r\n*6\r\n$6\r\nsubstr\r\n:4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$8\r\nsmembers\r\n:2\r\n*2\r\n+readonly\r\n+sort_for_script\r\n:1\r\n:1\r\n:1\r\n*6\r\n$11\r\nunsubscribe\r\n:-1\r\n*4\r\n+pubsub\r\n+noscript\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$11\r\nzinterstore\r\n:-4\r\n*3\r\n+write\r\n+denyoom\r\n+movablekeys\r\n:0\r\n:0\r\n:0\r\n*6\r\n$6\r\nstrlen\r\n:2\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\npfmerge\r\n:-2\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$9\r\nrandomkey\r\n:1\r\n*2\r\n+readonly\r\n+random\r\n:0\r\n:0\r\n:0\r\n*6\r\n$6\r\nlolwut\r\n:-1\r\n*1\r\n+readonly\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\nrpop\r\n:2\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nhkeys\r\n:2\r\n*2\r\n+readonly\r\n+sort_for_script\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nclient\r\n:-2\r\n*2\r\n+admin\r\n+noscript\r\n:0\r\n:0\r\n:0\r\n*6\r\n$6\r\nmodule\r\n:-2\r\n*2\r\n+admin\r\n+noscript\r\n:0\r\n:0\r\n:0\r\n*6\r\n$7\r\nslowlog\r\n:-2\r\n*2\r\n+admin\r\n+random\r\n:0\r\n:0\r\n:0\r\n*6\r\n$7\r\ngeohash\r\n:-2\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nlrange\r\n:4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nping\r\n:-1\r\n*2\r\n+stale\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$8\r\nbitcount\r\n:-2\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\npubsub\r\n:-2\r\n*4\r\n+pubsub\r\n+random\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\nrole\r\n:1\r\n*3\r\n+noscript\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\nhget\r\n:3\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nobject\r\n:-2\r\n*2\r\n+readonly\r\n+random\r\n:2\r\n:2\r\n:1\r\n*6\r\n$9\r\nzrevrange\r\n:-4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\nhincrby\r\n:4\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$9\r\nzlexcount\r\n:4\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nscard\r\n:2\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nappend\r\n:3\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\nhstrlen\r\n:3\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nconfig\r\n:-2\r\n*4\r\n+admin\r\n+noscript\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\nhset\r\n:-4\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$16\r\nzrevrangebyscore\r\n:-4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nincr\r\n:2\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nsetbit\r\n:4\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$9\r\nrpoplpush\r\n:3\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:2\r\n:1\r\n*6\r\n$6\r\nxclaim\r\n:-6\r\n*3\r\n+write\r\n+random\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$11\r\nsinterstore\r\n:-3\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$7\r\npublish\r\n:3\r\n*4\r\n+pubsub\r\n+loading\r\n+stale\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\nhscan\r\n:-3\r\n*2\r\n+readonly\r\n+random\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nmulti\r\n:1\r\n*2\r\n+noscript\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$3\r\nset\r\n:-3\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nlpushx\r\n:-3\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$16\r\nzremrangebyscore\r\n:4\r\n*1\r\n+write\r\n:1\r\n:1\r\n:1\r\n*6\r\n$9\r\npexpireat\r\n:3\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nhdel\r\n:-3\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$12\r\nbgrewriteaof\r\n:1\r\n*2\r\n+admin\r\n+noscript\r\n:0\r\n:0\r\n:0\r\n*6\r\n$7\r\nmigrate\r\n:-6\r\n*3\r\n+write\r\n+random\r\n+movablekeys\r\n:0\r\n:0\r\n:0\r\n*6\r\n$9\r\nreplicaof\r\n:3\r\n*3\r\n+admin\r\n+noscript\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\ntouch\r\n:-2\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nxsetid\r\n:3\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nbitop\r\n:-4\r\n*2\r\n+write\r\n+denyoom\r\n:2\r\n:-1\r\n:1\r\n*6\r\n$6\r\nswapdb\r\n:3\r\n*2\r\n+write\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\nsdiff\r\n:-2\r\n*2\r\n+readonly\r\n+sort_for_script\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$6\r\nlindex\r\n:3\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nwait\r\n:3\r\n*1\r\n+noscript\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\nlrem\r\n:4\r\n*1\r\n+write\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nhsetnx\r\n:4\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$8\r\ngetrange\r\n:4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nhlen\r\n:2\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\npost\r\n:-1\r\n*2\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$9\r\nsismember\r\n:3\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\nunwatch\r\n:1\r\n*2\r\n+noscript\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\nlpush\r\n:-3\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nscan\r\n:-2\r\n*2\r\n+readonly\r\n+random\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\nsmove\r\n:4\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:2\r\n:1\r\n*6\r\n$7\r\ncluster\r\n:-2\r\n*1\r\n+admin\r\n:0\r\n:0\r\n:0\r\n*6\r\n$6\r\nbgsave\r\n:-1\r\n*2\r\n+admin\r\n+noscript\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\ndump\r\n:2\r\n*2\r\n+readonly\r\n+random\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\nlatency\r\n:-2\r\n*4\r\n+admin\r\n+noscript\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$8\r\nbzpopmin\r\n:-3\r\n*3\r\n+write\r\n+noscript\r\n+fast\r\n:1\r\n:-2\r\n:1\r\n*6\r\n$6\r\ngetbit\r\n:3\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\nhgetall\r\n:2\r\n*2\r\n+readonly\r\n+random\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nrename\r\n:3\r\n*1\r\n+write\r\n:1\r\n:2\r\n:1\r\n*6\r\n$9\r\nsubscribe\r\n:-2\r\n*4\r\n+pubsub\r\n+noscript\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\nxdel\r\n:-3\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$15\r\nzremrangebyrank\r\n:4\r\n*1\r\n+write\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\ntype\r\n:2\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nscript\r\n:-2\r\n*1\r\n+noscript\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\nhmset\r\n:-4\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nsunion\r\n:-2\r\n*2\r\n+readonly\r\n+sort_for_script\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$4\r\nmget\r\n:-2\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$10\r\nbrpoplpush\r\n:4\r\n*3\r\n+write\r\n+denyoom\r\n+noscript\r\n:1\r\n:2\r\n:1\r\n*6\r\n$6\r\ngeoadd\r\n:-5\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\ndecrby\r\n:3\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\necho\r\n:2\r\n*1\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$6\r\ndbsize\r\n:1\r\n*2\r\n+readonly\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\nzcard\r\n:2\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nselect\r\n:2\r\n*2\r\n+loading\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\nsadd\r\n:-3\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nhost:\r\n:-1\r\n*2\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\nsscan\r\n:-3\r\n*2\r\n+readonly\r\n+random\r\n:1\r\n:1\r\n:1\r\n*6\r\n$12\r\ngeoradius_ro\r\n:-6\r\n*2\r\n+readonly\r\n+movablekeys\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\nmonitor\r\n:1\r\n*2\r\n+admin\r\n+noscript\r\n:0\r\n:0\r\n:0\r\n*6\r\n$14\r\nzremrangebylex\r\n:4\r\n*1\r\n+write\r\n:1\r\n:1\r\n:1\r\n*6\r\n$11\r\nsunionstore\r\n:-3\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$5\r\nzscan\r\n:-3\r\n*2\r\n+readonly\r\n+random\r\n:1\r\n:1\r\n:1\r\n*6\r\n$9\r\nreadwrite\r\n:1\r\n*1\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$6\r\nxgroup\r\n:-2\r\n*2\r\n+write\r\n+denyoom\r\n:2\r\n:2\r\n:1\r\n*6\r\n$5\r\nsetex\r\n:4\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nsave\r\n:1\r\n*2\r\n+admin\r\n+noscript\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\nhvals\r\n:2\r\n*2\r\n+readonly\r\n+sort_for_script\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nwatch\r\n:-2\r\n*2\r\n+noscript\r\n+fast\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$7\r\nhexists\r\n:3\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\ninfo\r\n:-1\r\n*3\r\n+random\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\npsync\r\n:3\r\n*3\r\n+readonly\r\n+admin\r\n+noscript\r\n:0\r\n:0\r\n:0\r\n*6\r\n$11\r\nzrangebylex\r\n:-4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nzadd\r\n:-4\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nxlen\r\n:2\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nauth\r\n:2\r\n*4\r\n+noscript\r\n+loading\r\n+stale\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\nsrem\r\n:-3\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$9\r\ngeoradius\r\n:-6\r\n*2\r\n+write\r\n+movablekeys\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nexec\r\n:1\r\n*2\r\n+noscript\r\n+skip_monitor\r\n:0\r\n:0\r\n:0\r\n*6\r\n$7\r\npfcount\r\n:-2\r\n*1\r\n+readonly\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$7\r\nzpopmin\r\n:-2\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nmove\r\n:3\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nxtrim\r\n:-2\r\n*3\r\n+write\r\n+random\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nasking\r\n:1\r\n*1\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\npttl\r\n:2\r\n*3\r\n+readonly\r\n+random\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$11\r\nsrandmember\r\n:-2\r\n*2\r\n+readonly\r\n+random\r\n:1\r\n:1\r\n:1\r\n*6\r\n$8\r\nflushall\r\n:-1\r\n*1\r\n+write\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\nsort\r\n:-2\r\n*3\r\n+write\r\n+denyoom\r\n+movablekeys\r\n:1\r\n:1\r\n:1\r\n*6\r\n$3\r\ndel\r\n:-2\r\n*1\r\n+write\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$14\r\nrestore-asking\r\n:-4\r\n*3\r\n+write\r\n+denyoom\r\n+asking\r\n:1\r\n:1\r\n:1\r\n*6\r\n$10\r\npsubscribe\r\n:-2\r\n*4\r\n+pubsub\r\n+noscript\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\ndecr\r\n:2\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nincrby\r\n:3\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$14\r\nzrevrangebylex\r\n:-4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$8\r\nbitfield\r\n:-2\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nexists\r\n:-2\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$8\r\nreplconf\r\n:-1\r\n*4\r\n+admin\r\n+noscript\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$7\r\nzincrby\r\n:4\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nblpop\r\n:-3\r\n*2\r\n+write\r\n+noscript\r\n:1\r\n:-2\r\n:1\r\n*6\r\n$4\r\nlpop\r\n:2\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$3\r\nttl\r\n:2\r\n*3\r\n+readonly\r\n+random\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nxread\r\n:-4\r\n*3\r\n+readonly\r\n+noscript\r\n+movablekeys\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nrpush\r\n:-3\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$8\r\nzrevrank\r\n:3\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$11\r\nincrbyfloat\r\n:3\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nbrpop\r\n:-3\r\n*2\r\n+write\r\n+noscript\r\n:1\r\n:-2\r\n:1\r\n*6\r\n$4\r\nxadd\r\n:-5\r\n*4\r\n+write\r\n+denyoom\r\n+random\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$8\r\nsetrange\r\n:4\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$17\r\ngeoradiusbymember\r\n:-5\r\n*2\r\n+write\r\n+movablekeys\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nunlink\r\n:-2\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$8\r\nexpireat\r\n:3\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\ndebug\r\n:-2\r\n*2\r\n+admin\r\n+noscript\r\n:0\r\n:0\r\n:0\r\n*6\r\n$20\r\ngeoradiusbymember_ro\r\n:-5\r\n*2\r\n+readonly\r\n+movablekeys\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nlset\r\n:4\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nzscore\r\n:3\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nllen\r\n:2\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\ntime\r\n:1\r\n*2\r\n+random\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$8\r\nshutdown\r\n:-1\r\n*4\r\n+admin\r\n+noscript\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$7\r\nevalsha\r\n:-3\r\n*2\r\n+noscript\r\n+movablekeys\r\n:0\r\n:0\r\n:0\r\n*6\r\n$6\r\nzcount\r\n:4\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nmemory\r\n:-2\r\n*2\r\n+readonly\r\n+random\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\nxinfo\r\n:-2\r\n*2\r\n+readonly\r\n+random\r\n:2\r\n:2\r\n:1\r\n*6\r\n$8\r\nxpending\r\n:-3\r\n*2\r\n+readonly\r\n+random\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\neval\r\n:-3\r\n*2\r\n+noscript\r\n+movablekeys\r\n:0\r\n:0\r\n:0\r\n*6\r\n$6\r\nxrange\r\n:-4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\nrestore\r\n:-4\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\nzpopmax\r\n:-2\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nmset\r\n:-3\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:-1\r\n:2\r\n*6\r\n$4\r\nspop\r\n:-2\r\n*3\r\n+write\r\n+random\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nltrim\r\n:4\r\n*1\r\n+write\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\nzrank\r\n:3\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$9\r\nxrevrange\r\n:-4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$3\r\nget\r\n:2\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\nflushdb\r\n:-1\r\n*1\r\n+write\r\n:0\r\n:0\r\n:0\r\n*6\r\n$5\r\nhmget\r\n:-3\r\n*2\r\n+readonly\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nmsetnx\r\n:-3\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:-1\r\n:2\r\n*6\r\n$7\r\npersist\r\n:2\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$11\r\nzunionstore\r\n:-4\r\n*3\r\n+write\r\n+denyoom\r\n+movablekeys\r\n:0\r\n:0\r\n:0\r\n*6\r\n$7\r\ncommand\r\n:0\r\n*3\r\n+random\r\n+loading\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$8\r\nrenamenx\r\n:3\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:2\r\n:1\r\n*6\r\n$6\r\nzrange\r\n:-4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\npexpire\r\n:3\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nkeys\r\n:2\r\n*2\r\n+readonly\r\n+sort_for_script\r\n:0\r\n:0\r\n:0\r\n*6\r\n$4\r\nzrem\r\n:-3\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$5\r\npfadd\r\n:-2\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\npsetex\r\n:4\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$13\r\nzrangebyscore\r\n:-4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$4\r\nsync\r\n:1\r\n*3\r\n+readonly\r\n+admin\r\n+noscript\r\n:0\r\n:0\r\n:0\r\n*6\r\n$7\r\npfdebug\r\n:-3\r\n*1\r\n+write\r\n:0\r\n:0\r\n:0\r\n*6\r\n$7\r\ndiscard\r\n:1\r\n*2\r\n+noscript\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$8\r\nreadonly\r\n:1\r\n*1\r\n+fast\r\n:0\r\n:0\r\n:0\r\n*6\r\n$7\r\ngeodist\r\n:-4\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\ngeopos\r\n:-2\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nbitpos\r\n:-3\r\n*1\r\n+readonly\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nsinter\r\n:-2\r\n*2\r\n+readonly\r\n+sort_for_script\r\n:1\r\n:-1\r\n:1\r\n*6\r\n$6\r\ngetset\r\n:3\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\nslaveof\r\n:3\r\n*3\r\n+admin\r\n+noscript\r\n+stale\r\n:0\r\n:0\r\n:0\r\n*6\r\n$6\r\nrpushx\r\n:-3\r\n*3\r\n+write\r\n+denyoom\r\n+fast\r\n:1\r\n:1\r\n:1\r\n*6\r\n$7\r\nlinsert\r\n:5\r\n*2\r\n+write\r\n+denyoom\r\n:1\r\n:1\r\n:1\r\n*6\r\n$6\r\nexpire\r\n:3\r\n*2\r\n+write\r\n+fast\r\n:1\r\n:1\r\n:1\r\n" - - c.WriteRaw(res) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_connection.go b/vendor/github.com/alicebob/miniredis/v2/cmd_connection.go deleted file mode 100644 index 1afb5cea1..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_connection.go +++ /dev/null @@ -1,285 +0,0 @@ -// Commands from https://redis.io/commands#connection - -package miniredis - -import ( - "fmt" - "strings" - - "github.com/alicebob/miniredis/v2/server" -) - -func commandsConnection(m *Miniredis) { - m.srv.Register("AUTH", m.cmdAuth) - m.srv.Register("ECHO", m.cmdEcho) - m.srv.Register("HELLO", m.cmdHello) - m.srv.Register("PING", m.cmdPing) - m.srv.Register("QUIT", m.cmdQuit) - m.srv.Register("SELECT", m.cmdSelect) - m.srv.Register("SWAPDB", m.cmdSwapdb) -} - -// PING -func (m *Miniredis) cmdPing(c *server.Peer, cmd string, args []string) { - if !m.handleAuth(c) { - return - } - - if len(args) > 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - payload := "" - if len(args) > 0 { - payload = args[0] - } - - // PING is allowed in subscribed state - if sub := getCtx(c).subscriber; sub != nil { - c.Block(func(c *server.Writer) { - c.WriteLen(2) - c.WriteBulk("pong") - c.WriteBulk(payload) - }) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - if payload == "" { - c.WriteInline("PONG") - return - } - c.WriteBulk(payload) - }) -} - -// AUTH -func (m *Miniredis) cmdAuth(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - if len(args) > 2 { - c.WriteError(msgSyntaxError) - return - } - if m.checkPubsub(c, cmd) { - return - } - ctx := getCtx(c) - if ctx.nested { - c.WriteError(msgNotFromScripts(ctx.nestedSHA)) - return - } - - var opts = struct { - username string - password string - }{ - username: "default", - password: args[0], - } - if len(args) == 2 { - opts.username, opts.password = args[0], args[1] - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - if len(m.passwords) == 0 && opts.username == "default" { - c.WriteError("ERR AUTH called without any password configured for the default user. Are you sure your configuration is correct?") - return - } - setPW, ok := m.passwords[opts.username] - if !ok { - c.WriteError("WRONGPASS invalid username-password pair") - return - } - if setPW != opts.password { - c.WriteError("WRONGPASS invalid username-password pair") - return - } - - ctx.authenticated = true - c.WriteOK() - }) -} - -// HELLO -func (m *Miniredis) cmdHello(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - c.WriteError(errWrongNumber(cmd)) - return - } - - var opts struct { - version int - username string - password string - } - - if ok := optIntErr(c, args[0], &opts.version, "ERR Protocol version is not an integer or out of range"); !ok { - return - } - args = args[1:] - - switch opts.version { - case 2, 3: - default: - c.WriteError("NOPROTO unsupported protocol version") - return - } - - var checkAuth bool - for len(args) > 0 { - switch strings.ToUpper(args[0]) { - case "AUTH": - if len(args) < 3 { - c.WriteError(fmt.Sprintf("ERR Syntax error in HELLO option '%s'", args[0])) - return - } - opts.username, opts.password, args = args[1], args[2], args[3:] - checkAuth = true - case "SETNAME": - if len(args) < 2 { - c.WriteError(fmt.Sprintf("ERR Syntax error in HELLO option '%s'", args[0])) - return - } - _, args = args[1], args[2:] - default: - c.WriteError(fmt.Sprintf("ERR Syntax error in HELLO option '%s'", args[0])) - return - } - } - - if len(m.passwords) == 0 && opts.username == "default" { - // redis ignores legacy "AUTH" if it's not enabled. - checkAuth = false - } - if checkAuth { - setPW, ok := m.passwords[opts.username] - if !ok { - c.WriteError("WRONGPASS invalid username-password pair") - return - } - if setPW != opts.password { - c.WriteError("WRONGPASS invalid username-password pair") - return - } - getCtx(c).authenticated = true - } - - c.Resp3 = opts.version == 3 - - c.WriteMapLen(7) - c.WriteBulk("server") - c.WriteBulk("miniredis") - c.WriteBulk("version") - c.WriteBulk("6.0.5") - c.WriteBulk("proto") - c.WriteInt(opts.version) - c.WriteBulk("id") - c.WriteInt(42) - c.WriteBulk("mode") - c.WriteBulk("standalone") - c.WriteBulk("role") - c.WriteBulk("master") - c.WriteBulk("modules") - c.WriteLen(0) -} - -// ECHO -func (m *Miniredis) cmdEcho(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - msg := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - c.WriteBulk(msg) - }) -} - -// SELECT -func (m *Miniredis) cmdSelect(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.isValidCMD(c, cmd) { - return - } - - var opts struct { - id int - } - if ok := optInt(c, args[0], &opts.id); !ok { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - if opts.id < 0 { - c.WriteError(msgDBIndexOutOfRange) - setDirty(c) - return - } - - ctx.selectedDB = opts.id - c.WriteOK() - }) -} - -// SWAPDB -func (m *Miniredis) cmdSwapdb(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - - var opts struct { - id1 int - id2 int - } - - if ok := optIntErr(c, args[0], &opts.id1, "ERR invalid first DB index"); !ok { - return - } - if ok := optIntErr(c, args[1], &opts.id2, "ERR invalid second DB index"); !ok { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - if opts.id1 < 0 || opts.id2 < 0 { - c.WriteError(msgDBIndexOutOfRange) - setDirty(c) - return - } - - m.swapDB(opts.id1, opts.id2) - - c.WriteOK() - }) -} - -// QUIT -func (m *Miniredis) cmdQuit(c *server.Peer, cmd string, args []string) { - // QUIT isn't transactionfied and accepts any arguments. - c.WriteOK() - c.Close() -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_generic.go b/vendor/github.com/alicebob/miniredis/v2/cmd_generic.go deleted file mode 100644 index 55e208971..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_generic.go +++ /dev/null @@ -1,729 +0,0 @@ -// Commands from https://redis.io/commands#generic - -package miniredis - -import ( - "fmt" - "sort" - "strconv" - "strings" - "time" - - "github.com/alicebob/miniredis/v2/server" -) - -// commandsGeneric handles EXPIRE, TTL, PERSIST, &c. -func commandsGeneric(m *Miniredis) { - m.srv.Register("COPY", m.cmdCopy) - m.srv.Register("DEL", m.cmdDel) - // DUMP - m.srv.Register("EXISTS", m.cmdExists) - m.srv.Register("EXPIRE", makeCmdExpire(m, false, time.Second)) - m.srv.Register("EXPIREAT", makeCmdExpire(m, true, time.Second)) - m.srv.Register("KEYS", m.cmdKeys) - // MIGRATE - m.srv.Register("MOVE", m.cmdMove) - // OBJECT - m.srv.Register("PERSIST", m.cmdPersist) - m.srv.Register("PEXPIRE", makeCmdExpire(m, false, time.Millisecond)) - m.srv.Register("PEXPIREAT", makeCmdExpire(m, true, time.Millisecond)) - m.srv.Register("PTTL", m.cmdPTTL) - m.srv.Register("RANDOMKEY", m.cmdRandomkey) - m.srv.Register("RENAME", m.cmdRename) - m.srv.Register("RENAMENX", m.cmdRenamenx) - // RESTORE - m.srv.Register("TOUCH", m.cmdTouch) - m.srv.Register("TTL", m.cmdTTL) - m.srv.Register("TYPE", m.cmdType) - m.srv.Register("SCAN", m.cmdScan) - // SORT - m.srv.Register("UNLINK", m.cmdDel) -} - -// generic expire command for EXPIRE, PEXPIRE, EXPIREAT, PEXPIREAT -// d is the time unit. If unix is set it'll be seen as a unixtimestamp and -// converted to a duration. -func makeCmdExpire(m *Miniredis, unix bool, d time.Duration) func(*server.Peer, string, []string) { - return func(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - value int - nx bool - xx bool - gt bool - lt bool - } - opts.key = args[0] - if ok := optInt(c, args[1], &opts.value); !ok { - return - } - args = args[2:] - for len(args) > 0 { - switch strings.ToLower(args[0]) { - case "nx": - opts.nx = true - case "xx": - opts.xx = true - case "gt": - opts.gt = true - case "lt": - opts.lt = true - default: - setDirty(c) - c.WriteError(fmt.Sprintf("ERR Unsupported option %s", args[0])) - return - } - args = args[1:] - } - if opts.gt && opts.lt { - setDirty(c) - c.WriteError("ERR GT and LT options at the same time are not compatible") - return - } - if opts.nx && (opts.xx || opts.gt || opts.lt) { - setDirty(c) - c.WriteError("ERR NX and XX, GT or LT options at the same time are not compatible") - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - // Key must be present. - if _, ok := db.keys[opts.key]; !ok { - c.WriteInt(0) - return - } - - oldTTL, ok := db.ttl[opts.key] - - var newTTL time.Duration - if unix { - newTTL = m.at(opts.value, d) - } else { - newTTL = time.Duration(opts.value) * d - } - - // > NX -- Set expiry only when the key has no expiry - if opts.nx && ok { - c.WriteInt(0) - return - } - // > XX -- Set expiry only when the key has an existing expiry - if opts.xx && !ok { - c.WriteInt(0) - return - } - // > GT -- Set expiry only when the new expiry is greater than current one - // (no exp == infinity) - if opts.gt && (!ok || newTTL <= oldTTL) { - c.WriteInt(0) - return - } - // > LT -- Set expiry only when the new expiry is less than current one - if opts.lt && ok && newTTL > oldTTL { - c.WriteInt(0) - return - } - db.ttl[opts.key] = newTTL - db.keyVersion[opts.key]++ - db.checkTTL(opts.key) - c.WriteInt(1) - }) - } -} - -// TOUCH -func (m *Miniredis) cmdTouch(c *server.Peer, cmd string, args []string) { - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - if len(args) == 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - count := 0 - for _, key := range args { - if db.exists(key) { - count++ - } - } - c.WriteInt(count) - }) -} - -// TTL -func (m *Miniredis) cmdTTL(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if _, ok := db.keys[key]; !ok { - // No such key - c.WriteInt(-2) - return - } - - v, ok := db.ttl[key] - if !ok { - // no expire value - c.WriteInt(-1) - return - } - c.WriteInt(int(v.Seconds())) - }) -} - -// PTTL -func (m *Miniredis) cmdPTTL(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if _, ok := db.keys[key]; !ok { - // no such key - c.WriteInt(-2) - return - } - - v, ok := db.ttl[key] - if !ok { - // no expire value - c.WriteInt(-1) - return - } - c.WriteInt(int(v.Nanoseconds() / 1000000)) - }) -} - -// PERSIST -func (m *Miniredis) cmdPersist(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if _, ok := db.keys[key]; !ok { - // no such key - c.WriteInt(0) - return - } - - if _, ok := db.ttl[key]; !ok { - // no expire value - c.WriteInt(0) - return - } - delete(db.ttl, key) - db.keyVersion[key]++ - c.WriteInt(1) - }) -} - -// DEL and UNLINK -func (m *Miniredis) cmdDel(c *server.Peer, cmd string, args []string) { - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - if len(args) == 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - count := 0 - for _, key := range args { - if db.exists(key) { - count++ - } - db.del(key, true) // delete expire - } - c.WriteInt(count) - }) -} - -// TYPE -func (m *Miniredis) cmdType(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError("usage error") - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[key] - if !ok { - c.WriteInline("none") - return - } - - c.WriteInline(t) - }) -} - -// EXISTS -func (m *Miniredis) cmdExists(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - found := 0 - for _, k := range args { - if db.exists(k) { - found++ - } - } - c.WriteInt(found) - }) -} - -// MOVE -func (m *Miniredis) cmdMove(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - targetDB int - } - - opts.key = args[0] - opts.targetDB, _ = strconv.Atoi(args[1]) - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - if ctx.selectedDB == opts.targetDB { - c.WriteError("ERR source and destination objects are the same") - return - } - db := m.db(ctx.selectedDB) - targetDB := m.db(opts.targetDB) - - if !db.move(opts.key, targetDB) { - c.WriteInt(0) - return - } - c.WriteInt(1) - }) -} - -// KEYS -func (m *Miniredis) cmdKeys(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - keys, _ := matchKeys(db.allKeys(), key) - c.WriteLen(len(keys)) - for _, s := range keys { - c.WriteBulk(s) - } - }) -} - -// RANDOMKEY -func (m *Miniredis) cmdRandomkey(c *server.Peer, cmd string, args []string) { - if len(args) != 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if len(db.keys) == 0 { - c.WriteNull() - return - } - nr := m.randIntn(len(db.keys)) - for k := range db.keys { - if nr == 0 { - c.WriteBulk(k) - return - } - nr-- - } - }) -} - -// RENAME -func (m *Miniredis) cmdRename(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - from string - to string - }{ - from: args[0], - to: args[1], - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.from) { - c.WriteError(msgKeyNotFound) - return - } - - db.rename(opts.from, opts.to) - c.WriteOK() - }) -} - -// RENAMENX -func (m *Miniredis) cmdRenamenx(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - from string - to string - }{ - from: args[0], - to: args[1], - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.from) { - c.WriteError(msgKeyNotFound) - return - } - - if db.exists(opts.to) { - c.WriteInt(0) - return - } - - db.rename(opts.from, opts.to) - c.WriteInt(1) - }) -} - -// SCAN -func (m *Miniredis) cmdScan(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - cursor int - withMatch bool - match string - withType bool - _type string - } - - if ok := optIntErr(c, args[0], &opts.cursor, msgInvalidCursor); !ok { - return - } - args = args[1:] - - // MATCH, COUNT and TYPE options - for len(args) > 0 { - if strings.ToLower(args[0]) == "count" { - // we do nothing with count - if len(args) < 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - if _, err := strconv.Atoi(args[1]); err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - args = args[2:] - continue - } - if strings.ToLower(args[0]) == "match" { - if len(args) < 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - opts.withMatch = true - opts.match, args = args[1], args[2:] - continue - } - if strings.ToLower(args[0]) == "type" { - if len(args) < 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - opts.withType = true - opts._type, args = strings.ToLower(args[1]), args[2:] - continue - } - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - // We return _all_ (matched) keys every time. - - if opts.cursor != 0 { - // Invalid cursor. - c.WriteLen(2) - c.WriteBulk("0") // no next cursor - c.WriteLen(0) // no elements - return - } - - var keys []string - - if opts.withType { - keys = make([]string, 0) - for k, t := range db.keys { - // type must be given exactly; no pattern matching is performed - if t == opts._type { - keys = append(keys, k) - } - } - sort.Strings(keys) // To make things deterministic. - } else { - keys = db.allKeys() - } - - if opts.withMatch { - keys, _ = matchKeys(keys, opts.match) - } - - c.WriteLen(2) - c.WriteBulk("0") // no next cursor - c.WriteLen(len(keys)) - for _, k := range keys { - c.WriteBulk(k) - } - }) -} - -// COPY -func (m *Miniredis) cmdCopy(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts = struct { - from string - to string - destinationDB int - replace bool - }{ - destinationDB: -1, - } - - opts.from, opts.to, args = args[0], args[1], args[2:] - for len(args) > 0 { - switch strings.ToLower(args[0]) { - case "db": - if len(args) < 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - db, err := strconv.Atoi(args[1]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - if db < 0 { - setDirty(c) - c.WriteError(msgDBIndexOutOfRange) - return - } - opts.destinationDB = db - args = args[2:] - case "replace": - opts.replace = true - args = args[1:] - default: - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - fromDB, toDB := ctx.selectedDB, opts.destinationDB - if toDB == -1 { - toDB = fromDB - } - - if fromDB == toDB && opts.from == opts.to { - c.WriteError("ERR source and destination objects are the same") - return - } - - if !m.db(fromDB).exists(opts.from) { - c.WriteInt(0) - return - } - - if !opts.replace { - if m.db(toDB).exists(opts.to) { - c.WriteInt(0) - return - } - } - - m.copy(m.db(fromDB), opts.from, m.db(toDB), opts.to) - c.WriteInt(1) - }) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_geo.go b/vendor/github.com/alicebob/miniredis/v2/cmd_geo.go deleted file mode 100644 index 29a92d550..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_geo.go +++ /dev/null @@ -1,609 +0,0 @@ -// Commands from https://redis.io/commands#geo - -package miniredis - -import ( - "fmt" - "sort" - "strconv" - "strings" - - "github.com/alicebob/miniredis/v2/server" -) - -// commandsGeo handles GEOADD, GEORADIUS etc. -func commandsGeo(m *Miniredis) { - m.srv.Register("GEOADD", m.cmdGeoadd) - m.srv.Register("GEODIST", m.cmdGeodist) - m.srv.Register("GEOPOS", m.cmdGeopos) - m.srv.Register("GEORADIUS", m.cmdGeoradius) - m.srv.Register("GEORADIUS_RO", m.cmdGeoradius) - m.srv.Register("GEORADIUSBYMEMBER", m.cmdGeoradiusbymember) - m.srv.Register("GEORADIUSBYMEMBER_RO", m.cmdGeoradiusbymember) -} - -// GEOADD -func (m *Miniredis) cmdGeoadd(c *server.Peer, cmd string, args []string) { - if len(args) < 3 || len(args[1:])%3 != 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - key, args := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if db.exists(key) && db.t(key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - toSet := map[string]float64{} - for len(args) > 2 { - rawLong, rawLat, name := args[0], args[1], args[2] - args = args[3:] - longitude, err := strconv.ParseFloat(rawLong, 64) - if err != nil { - c.WriteError("ERR value is not a valid float") - return - } - latitude, err := strconv.ParseFloat(rawLat, 64) - if err != nil { - c.WriteError("ERR value is not a valid float") - return - } - - if latitude < -85.05112878 || - latitude > 85.05112878 || - longitude < -180 || - longitude > 180 { - c.WriteError(fmt.Sprintf("ERR invalid longitude,latitude pair %.6f,%.6f", longitude, latitude)) - return - } - - toSet[name] = float64(toGeohash(longitude, latitude)) - } - - set := 0 - for name, score := range toSet { - if db.ssetAdd(key, score, name) { - set++ - } - } - c.WriteInt(set) - }) -} - -// GEODIST -func (m *Miniredis) cmdGeodist(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, from, to, args := args[0], args[1], args[2], args[3:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - if !db.exists(key) { - c.WriteNull() - return - } - if db.t(key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - unit := "m" - if len(args) > 0 { - unit, args = args[0], args[1:] - } - if len(args) > 0 { - c.WriteError(msgSyntaxError) - return - } - - toMeter := parseUnit(unit) - if toMeter == 0 { - c.WriteError(msgUnsupportedUnit) - return - } - - members := db.sortedsetKeys[key] - fromD, okFrom := members.get(from) - toD, okTo := members.get(to) - if !okFrom || !okTo { - c.WriteNull() - return - } - - fromLo, fromLat := fromGeohash(uint64(fromD)) - toLo, toLat := fromGeohash(uint64(toD)) - - dist := distance(fromLat, fromLo, toLat, toLo) / toMeter - c.WriteBulk(fmt.Sprintf("%.4f", dist)) - }) -} - -// GEOPOS -func (m *Miniredis) cmdGeopos(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - key, args := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if db.exists(key) && db.t(key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - c.WriteLen(len(args)) - for _, l := range args { - if !db.ssetExists(key, l) { - c.WriteLen(-1) - continue - } - score := db.ssetScore(key, l) - c.WriteLen(2) - long, lat := fromGeohash(uint64(score)) - c.WriteBulk(fmt.Sprintf("%f", long)) - c.WriteBulk(fmt.Sprintf("%f", lat)) - } - }) -} - -type geoDistance struct { - Name string - Score float64 - Distance float64 - Longitude float64 - Latitude float64 -} - -// GEORADIUS and GEORADIUS_RO -func (m *Miniredis) cmdGeoradius(c *server.Peer, cmd string, args []string) { - if len(args) < 5 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - longitude, err := strconv.ParseFloat(args[1], 64) - if err != nil { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - latitude, err := strconv.ParseFloat(args[2], 64) - if err != nil { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - radius, err := strconv.ParseFloat(args[3], 64) - if err != nil || radius < 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - toMeter := parseUnit(args[4]) - if toMeter == 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - args = args[5:] - - var opts struct { - withDist bool - withCoord bool - direction direction // unsorted - count int - withStore bool - storeKey string - withStoredist bool - storedistKey string - } - for len(args) > 0 { - arg := args[0] - args = args[1:] - switch strings.ToUpper(arg) { - case "WITHCOORD": - opts.withCoord = true - case "WITHDIST": - opts.withDist = true - case "ASC": - opts.direction = asc - case "DESC": - opts.direction = desc - case "COUNT": - if len(args) == 0 { - setDirty(c) - c.WriteError("ERR syntax error") - return - } - n, err := strconv.Atoi(args[0]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - if n <= 0 { - setDirty(c) - c.WriteError("ERR COUNT must be > 0") - return - } - args = args[1:] - opts.count = n - case "STORE": - if len(args) == 0 { - setDirty(c) - c.WriteError("ERR syntax error") - return - } - opts.withStore = true - opts.storeKey = args[0] - args = args[1:] - case "STOREDIST": - if len(args) == 0 { - setDirty(c) - c.WriteError("ERR syntax error") - return - } - opts.withStoredist = true - opts.storedistKey = args[0] - args = args[1:] - default: - setDirty(c) - c.WriteError("ERR syntax error") - return - } - } - - if strings.ToUpper(cmd) == "GEORADIUS_RO" && (opts.withStore || opts.withStoredist) { - setDirty(c) - c.WriteError("ERR syntax error") - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - if (opts.withStore || opts.withStoredist) && (opts.withDist || opts.withCoord) { - c.WriteError("ERR STORE option in GEORADIUS is not compatible with WITHDIST, WITHHASH and WITHCOORDS options") - return - } - - db := m.db(ctx.selectedDB) - members := db.ssetElements(key) - - matches := withinRadius(members, longitude, latitude, radius*toMeter) - - // deal with ASC/DESC - if opts.direction != unsorted { - sort.Slice(matches, func(i, j int) bool { - if opts.direction == desc { - return matches[i].Distance > matches[j].Distance - } - return matches[i].Distance < matches[j].Distance - }) - } - - // deal with COUNT - if opts.count > 0 && len(matches) > opts.count { - matches = matches[:opts.count] - } - - // deal with "STORE x" - if opts.withStore { - db.del(opts.storeKey, true) - for _, member := range matches { - db.ssetAdd(opts.storeKey, member.Score, member.Name) - } - c.WriteInt(len(matches)) - return - } - - // deal with "STOREDIST x" - if opts.withStoredist { - db.del(opts.storedistKey, true) - for _, member := range matches { - db.ssetAdd(opts.storedistKey, member.Distance/toMeter, member.Name) - } - c.WriteInt(len(matches)) - return - } - - c.WriteLen(len(matches)) - for _, member := range matches { - if !opts.withDist && !opts.withCoord { - c.WriteBulk(member.Name) - continue - } - - len := 1 - if opts.withDist { - len++ - } - if opts.withCoord { - len++ - } - c.WriteLen(len) - c.WriteBulk(member.Name) - if opts.withDist { - c.WriteBulk(fmt.Sprintf("%.4f", member.Distance/toMeter)) - } - if opts.withCoord { - c.WriteLen(2) - c.WriteBulk(fmt.Sprintf("%f", member.Longitude)) - c.WriteBulk(fmt.Sprintf("%f", member.Latitude)) - } - } - }) -} - -// GEORADIUSBYMEMBER and GEORADIUSBYMEMBER_RO -func (m *Miniredis) cmdGeoradiusbymember(c *server.Peer, cmd string, args []string) { - if len(args) < 4 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - key string - member string - radius float64 - toMeter float64 - - withDist bool - withCoord bool - direction direction // unsorted - count int - withStore bool - storeKey string - withStoredist bool - storedistKey string - }{ - key: args[0], - member: args[1], - } - - r, err := strconv.ParseFloat(args[2], 64) - if err != nil || r < 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - opts.radius = r - - opts.toMeter = parseUnit(args[3]) - if opts.toMeter == 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - args = args[4:] - - for len(args) > 0 { - arg := args[0] - args = args[1:] - switch strings.ToUpper(arg) { - case "WITHCOORD": - opts.withCoord = true - case "WITHDIST": - opts.withDist = true - case "ASC": - opts.direction = asc - case "DESC": - opts.direction = desc - case "COUNT": - if len(args) == 0 { - setDirty(c) - c.WriteError("ERR syntax error") - return - } - n, err := strconv.Atoi(args[0]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - if n <= 0 { - setDirty(c) - c.WriteError("ERR COUNT must be > 0") - return - } - args = args[1:] - opts.count = n - case "STORE": - if len(args) == 0 { - setDirty(c) - c.WriteError("ERR syntax error") - return - } - opts.withStore = true - opts.storeKey = args[0] - args = args[1:] - case "STOREDIST": - if len(args) == 0 { - setDirty(c) - c.WriteError("ERR syntax error") - return - } - opts.withStoredist = true - opts.storedistKey = args[0] - args = args[1:] - default: - setDirty(c) - c.WriteError("ERR syntax error") - return - } - } - - if strings.ToUpper(cmd) == "GEORADIUSBYMEMBER_RO" && (opts.withStore || opts.withStoredist) { - setDirty(c) - c.WriteError("ERR syntax error") - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - if (opts.withStore || opts.withStoredist) && (opts.withDist || opts.withCoord) { - c.WriteError("ERR STORE option in GEORADIUS is not compatible with WITHDIST, WITHHASH and WITHCOORDS options") - return - } - - db := m.db(ctx.selectedDB) - if !db.exists(opts.key) { - c.WriteNull() - return - } - - if db.t(opts.key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - // get position of member - if !db.ssetExists(opts.key, opts.member) { - c.WriteError("ERR could not decode requested zset member") - return - } - score := db.ssetScore(opts.key, opts.member) - longitude, latitude := fromGeohash(uint64(score)) - - members := db.ssetElements(opts.key) - matches := withinRadius(members, longitude, latitude, opts.radius*opts.toMeter) - - // deal with ASC/DESC - if opts.direction != unsorted { - sort.Slice(matches, func(i, j int) bool { - if opts.direction == desc { - return matches[i].Distance > matches[j].Distance - } - return matches[i].Distance < matches[j].Distance - }) - } - - // deal with COUNT - if opts.count > 0 && len(matches) > opts.count { - matches = matches[:opts.count] - } - - // deal with "STORE x" - if opts.withStore { - db.del(opts.storeKey, true) - for _, member := range matches { - db.ssetAdd(opts.storeKey, member.Score, member.Name) - } - c.WriteInt(len(matches)) - return - } - - // deal with "STOREDIST x" - if opts.withStoredist { - db.del(opts.storedistKey, true) - for _, member := range matches { - db.ssetAdd(opts.storedistKey, member.Distance/opts.toMeter, member.Name) - } - c.WriteInt(len(matches)) - return - } - - c.WriteLen(len(matches)) - for _, member := range matches { - if !opts.withDist && !opts.withCoord { - c.WriteBulk(member.Name) - continue - } - - len := 1 - if opts.withDist { - len++ - } - if opts.withCoord { - len++ - } - c.WriteLen(len) - c.WriteBulk(member.Name) - if opts.withDist { - c.WriteBulk(fmt.Sprintf("%.4f", member.Distance/opts.toMeter)) - } - if opts.withCoord { - c.WriteLen(2) - c.WriteBulk(fmt.Sprintf("%f", member.Longitude)) - c.WriteBulk(fmt.Sprintf("%f", member.Latitude)) - } - } - }) -} - -func withinRadius(members []ssElem, longitude, latitude, radius float64) []geoDistance { - matches := []geoDistance{} - for _, el := range members { - elLo, elLat := fromGeohash(uint64(el.score)) - distanceInMeter := distance(latitude, longitude, elLat, elLo) - - if distanceInMeter <= radius { - matches = append(matches, geoDistance{ - Name: el.member, - Score: el.score, - Distance: distanceInMeter, - Longitude: elLo, - Latitude: elLat, - }) - } - } - return matches -} - -func parseUnit(u string) float64 { - switch u { - case "m": - return 1 - case "km": - return 1000 - case "mi": - return 1609.34 - case "ft": - return 0.3048 - default: - return 0 - } -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_hash.go b/vendor/github.com/alicebob/miniredis/v2/cmd_hash.go deleted file mode 100644 index 09fa4522f..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_hash.go +++ /dev/null @@ -1,683 +0,0 @@ -// Commands from https://redis.io/commands#hash - -package miniredis - -import ( - "math/big" - "strconv" - "strings" - - "github.com/alicebob/miniredis/v2/server" -) - -// commandsHash handles all hash value operations. -func commandsHash(m *Miniredis) { - m.srv.Register("HDEL", m.cmdHdel) - m.srv.Register("HEXISTS", m.cmdHexists) - m.srv.Register("HGET", m.cmdHget) - m.srv.Register("HGETALL", m.cmdHgetall) - m.srv.Register("HINCRBY", m.cmdHincrby) - m.srv.Register("HINCRBYFLOAT", m.cmdHincrbyfloat) - m.srv.Register("HKEYS", m.cmdHkeys) - m.srv.Register("HLEN", m.cmdHlen) - m.srv.Register("HMGET", m.cmdHmget) - m.srv.Register("HMSET", m.cmdHmset) - m.srv.Register("HSET", m.cmdHset) - m.srv.Register("HSETNX", m.cmdHsetnx) - m.srv.Register("HSTRLEN", m.cmdHstrlen) - m.srv.Register("HVALS", m.cmdHvals) - m.srv.Register("HSCAN", m.cmdHscan) -} - -// HSET -func (m *Miniredis) cmdHset(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, pairs := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if len(pairs)%2 == 1 { - c.WriteError(errWrongNumber(cmd)) - return - } - - if t, ok := db.keys[key]; ok && t != "hash" { - c.WriteError(msgWrongType) - return - } - - new := db.hashSet(key, pairs...) - c.WriteInt(new) - }) -} - -// HSETNX -func (m *Miniredis) cmdHsetnx(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - key string - field string - value string - }{ - key: args[0], - field: args[1], - value: args[2], - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[opts.key]; ok && t != "hash" { - c.WriteError(msgWrongType) - return - } - - if _, ok := db.hashKeys[opts.key]; !ok { - db.hashKeys[opts.key] = map[string]string{} - db.keys[opts.key] = "hash" - } - _, ok := db.hashKeys[opts.key][opts.field] - if ok { - c.WriteInt(0) - return - } - db.hashKeys[opts.key][opts.field] = opts.value - db.keyVersion[opts.key]++ - c.WriteInt(1) - }) -} - -// HMSET -func (m *Miniredis) cmdHmset(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, args := args[0], args[1:] - if len(args)%2 != 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[key]; ok && t != "hash" { - c.WriteError(msgWrongType) - return - } - - for len(args) > 0 { - field, value := args[0], args[1] - args = args[2:] - db.hashSet(key, field, value) - } - c.WriteOK() - }) -} - -// HGET -func (m *Miniredis) cmdHget(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, field := args[0], args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[key] - if !ok { - c.WriteNull() - return - } - if t != "hash" { - c.WriteError(msgWrongType) - return - } - value, ok := db.hashKeys[key][field] - if !ok { - c.WriteNull() - return - } - c.WriteBulk(value) - }) -} - -// HDEL -func (m *Miniredis) cmdHdel(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - key string - fields []string - }{ - key: args[0], - fields: args[1:], - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[opts.key] - if !ok { - // No key is zero deleted - c.WriteInt(0) - return - } - if t != "hash" { - c.WriteError(msgWrongType) - return - } - - deleted := 0 - for _, f := range opts.fields { - _, ok := db.hashKeys[opts.key][f] - if !ok { - continue - } - delete(db.hashKeys[opts.key], f) - deleted++ - } - c.WriteInt(deleted) - - // Nothing left. Remove the whole key. - if len(db.hashKeys[opts.key]) == 0 { - db.del(opts.key, true) - } - }) -} - -// HEXISTS -func (m *Miniredis) cmdHexists(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - key string - field string - }{ - key: args[0], - field: args[1], - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[opts.key] - if !ok { - c.WriteInt(0) - return - } - if t != "hash" { - c.WriteError(msgWrongType) - return - } - - if _, ok := db.hashKeys[opts.key][opts.field]; !ok { - c.WriteInt(0) - return - } - c.WriteInt(1) - }) -} - -// HGETALL -func (m *Miniredis) cmdHgetall(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[key] - if !ok { - c.WriteMapLen(0) - return - } - if t != "hash" { - c.WriteError(msgWrongType) - return - } - - c.WriteMapLen(len(db.hashKeys[key])) - for _, k := range db.hashFields(key) { - c.WriteBulk(k) - c.WriteBulk(db.hashGet(key, k)) - } - }) -} - -// HKEYS -func (m *Miniredis) cmdHkeys(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteLen(0) - return - } - if db.t(key) != "hash" { - c.WriteError(msgWrongType) - return - } - - fields := db.hashFields(key) - c.WriteLen(len(fields)) - for _, f := range fields { - c.WriteBulk(f) - } - }) -} - -// HSTRLEN -func (m *Miniredis) cmdHstrlen(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - hash, key := args[0], args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[hash] - if !ok { - c.WriteInt(0) - return - } - if t != "hash" { - c.WriteError(msgWrongType) - return - } - - keys := db.hashKeys[hash] - c.WriteInt(len(keys[key])) - }) -} - -// HVALS -func (m *Miniredis) cmdHvals(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[key] - if !ok { - c.WriteLen(0) - return - } - if t != "hash" { - c.WriteError(msgWrongType) - return - } - - vals := db.hashValues(key) - c.WriteLen(len(vals)) - for _, v := range vals { - c.WriteBulk(v) - } - }) -} - -// HLEN -func (m *Miniredis) cmdHlen(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[key] - if !ok { - c.WriteInt(0) - return - } - if t != "hash" { - c.WriteError(msgWrongType) - return - } - - c.WriteInt(len(db.hashKeys[key])) - }) -} - -// HMGET -func (m *Miniredis) cmdHmget(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[key]; ok && t != "hash" { - c.WriteError(msgWrongType) - return - } - - f, ok := db.hashKeys[key] - if !ok { - f = map[string]string{} - } - - c.WriteLen(len(args) - 1) - for _, k := range args[1:] { - v, ok := f[k] - if !ok { - c.WriteNull() - continue - } - c.WriteBulk(v) - } - }) -} - -// HINCRBY -func (m *Miniredis) cmdHincrby(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - key string - field string - delta int - }{ - key: args[0], - field: args[1], - } - if ok := optInt(c, args[2], &opts.delta); !ok { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[opts.key]; ok && t != "hash" { - c.WriteError(msgWrongType) - return - } - - v, err := db.hashIncr(opts.key, opts.field, opts.delta) - if err != nil { - c.WriteError(err.Error()) - return - } - c.WriteInt(v) - }) -} - -// HINCRBYFLOAT -func (m *Miniredis) cmdHincrbyfloat(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - key string - field string - delta *big.Float - }{ - key: args[0], - field: args[1], - } - delta, _, err := big.ParseFloat(args[2], 10, 128, 0) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidFloat) - return - } - opts.delta = delta - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[opts.key]; ok && t != "hash" { - c.WriteError(msgWrongType) - return - } - - v, err := db.hashIncrfloat(opts.key, opts.field, opts.delta) - if err != nil { - c.WriteError(err.Error()) - return - } - c.WriteBulk(formatBig(v)) - }) -} - -// HSCAN -func (m *Miniredis) cmdHscan(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - key string - cursor int - withMatch bool - match string - }{ - key: args[0], - } - if ok := optIntErr(c, args[1], &opts.cursor, msgInvalidCursor); !ok { - return - } - args = args[2:] - - // MATCH and COUNT options - for len(args) > 0 { - if strings.ToLower(args[0]) == "count" { - // we do nothing with count - if len(args) < 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - _, err := strconv.Atoi(args[1]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - args = args[2:] - continue - } - if strings.ToLower(args[0]) == "match" { - if len(args) < 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - opts.withMatch = true - opts.match, args = args[1], args[2:] - continue - } - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - // return _all_ (matched) keys every time - - if opts.cursor != 0 { - // Invalid cursor. - c.WriteLen(2) - c.WriteBulk("0") // no next cursor - c.WriteLen(0) // no elements - return - } - if db.exists(opts.key) && db.t(opts.key) != "hash" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.hashFields(opts.key) - if opts.withMatch { - members, _ = matchKeys(members, opts.match) - } - - c.WriteLen(2) - c.WriteBulk("0") // no next cursor - // HSCAN gives key, values. - c.WriteLen(len(members) * 2) - for _, k := range members { - c.WriteBulk(k) - c.WriteBulk(db.hashGet(opts.key, k)) - } - }) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_hll.go b/vendor/github.com/alicebob/miniredis/v2/cmd_hll.go deleted file mode 100644 index a7b483673..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_hll.go +++ /dev/null @@ -1,95 +0,0 @@ -package miniredis - -import "github.com/alicebob/miniredis/v2/server" - -// commandsHll handles all hll related operations. -func commandsHll(m *Miniredis) { - m.srv.Register("PFADD", m.cmdPfadd) - m.srv.Register("PFCOUNT", m.cmdPfcount) - m.srv.Register("PFMERGE", m.cmdPfmerge) -} - -// PFADD -func (m *Miniredis) cmdPfadd(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, items := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if db.exists(key) && db.t(key) != "hll" { - c.WriteError(ErrNotValidHllValue.Error()) - return - } - - altered := db.hllAdd(key, items...) - c.WriteInt(altered) - }) -} - -// PFCOUNT -func (m *Miniredis) cmdPfcount(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - keys := args - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - count, err := db.hllCount(keys) - if err != nil { - c.WriteError(err.Error()) - return - } - - c.WriteInt(count) - }) -} - -// PFMERGE -func (m *Miniredis) cmdPfmerge(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - keys := args - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if err := db.hllMerge(keys); err != nil { - c.WriteError(err.Error()) - return - } - c.WriteOK() - }) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_info.go b/vendor/github.com/alicebob/miniredis/v2/cmd_info.go deleted file mode 100644 index e5984a9b2..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_info.go +++ /dev/null @@ -1,40 +0,0 @@ -package miniredis - -import ( - "fmt" - - "github.com/alicebob/miniredis/v2/server" -) - -// Command 'INFO' from https://redis.io/commands/info/ -func (m *Miniredis) cmdInfo(c *server.Peer, cmd string, args []string) { - if !m.isValidCMD(c, cmd) { - return - } - - if len(args) > 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - const ( - clientsSectionName = "clients" - clientsSectionContent = "# Clients\nconnected_clients:%d\r\n" - ) - - var result string - - for _, key := range args { - if key != clientsSectionName { - setDirty(c) - c.WriteError(fmt.Sprintf("section (%s) is not supported", key)) - return - } - } - result = fmt.Sprintf(clientsSectionContent, m.Server().ClientsLen()) - - c.WriteBulk(result) - }) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_list.go b/vendor/github.com/alicebob/miniredis/v2/cmd_list.go deleted file mode 100644 index 3d1cd02ea..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_list.go +++ /dev/null @@ -1,1054 +0,0 @@ -// Commands from https://redis.io/commands#list - -package miniredis - -import ( - "strconv" - "strings" - "time" - - "github.com/alicebob/miniredis/v2/server" -) - -type leftright int - -const ( - left leftright = iota - right -) - -// commandsList handles list commands (mostly L*) -func commandsList(m *Miniredis) { - m.srv.Register("BLPOP", m.cmdBlpop) - m.srv.Register("BRPOP", m.cmdBrpop) - m.srv.Register("BRPOPLPUSH", m.cmdBrpoplpush) - m.srv.Register("LINDEX", m.cmdLindex) - m.srv.Register("LPOS", m.cmdLpos) - m.srv.Register("LINSERT", m.cmdLinsert) - m.srv.Register("LLEN", m.cmdLlen) - m.srv.Register("LPOP", m.cmdLpop) - m.srv.Register("LPUSH", m.cmdLpush) - m.srv.Register("LPUSHX", m.cmdLpushx) - m.srv.Register("LRANGE", m.cmdLrange) - m.srv.Register("LREM", m.cmdLrem) - m.srv.Register("LSET", m.cmdLset) - m.srv.Register("LTRIM", m.cmdLtrim) - m.srv.Register("RPOP", m.cmdRpop) - m.srv.Register("RPOPLPUSH", m.cmdRpoplpush) - m.srv.Register("RPUSH", m.cmdRpush) - m.srv.Register("RPUSHX", m.cmdRpushx) - m.srv.Register("LMOVE", m.cmdLmove) - m.srv.Register("BLMOVE", m.cmdBlmove) -} - -// BLPOP -func (m *Miniredis) cmdBlpop(c *server.Peer, cmd string, args []string) { - m.cmdBXpop(c, cmd, args, left) -} - -// BRPOP -func (m *Miniredis) cmdBrpop(c *server.Peer, cmd string, args []string) { - m.cmdBXpop(c, cmd, args, right) -} - -func (m *Miniredis) cmdBXpop(c *server.Peer, cmd string, args []string, lr leftright) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - keys []string - timeout time.Duration - } - - if ok := optDuration(c, args[len(args)-1], &opts.timeout); !ok { - return - } - opts.keys = args[:len(args)-1] - - blocking( - m, - c, - opts.timeout, - func(c *server.Peer, ctx *connCtx) bool { - db := m.db(ctx.selectedDB) - for _, key := range opts.keys { - if !db.exists(key) { - continue - } - if db.t(key) != "list" { - c.WriteError(msgWrongType) - return true - } - - if len(db.listKeys[key]) == 0 { - continue - } - c.WriteLen(2) - c.WriteBulk(key) - var v string - switch lr { - case left: - v = db.listLpop(key) - case right: - v = db.listPop(key) - } - c.WriteBulk(v) - return true - } - return false - }, - func(c *server.Peer) { - // timeout - c.WriteLen(-1) - }, - ) -} - -// LINDEX -func (m *Miniredis) cmdLindex(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, offsets := args[0], args[1] - - offset, err := strconv.Atoi(offsets) - if err != nil || offsets == "-0" { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[key] - if !ok { - // No such key - c.WriteNull() - return - } - if t != "list" { - c.WriteError(msgWrongType) - return - } - - l := db.listKeys[key] - if offset < 0 { - offset = len(l) + offset - } - if offset < 0 || offset > len(l)-1 { - c.WriteNull() - return - } - c.WriteBulk(l[offset]) - }) -} - -// LPOS key element [RANK rank] [COUNT num-matches] [MAXLEN len] -func (m *Miniredis) cmdLpos(c *server.Peer, cmd string, args []string) { - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - if len(args) == 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - // Extract options from arguments if present. - // - // Redis allows duplicate options and uses the last specified. - // `LPOS key term RANK 1 RANK 2` is effectively the same as - // `LPOS key term RANK 2` - if len(args)%2 == 1 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - rank, count := 1, 1 // Default values - var maxlen int // Default value is the list length (see below) - var countSpecified, maxlenSpecified bool - if len(args) > 2 { - for i := 2; i < len(args); i++ { - if i%2 == 0 { - val := args[i+1] - var err error - switch strings.ToLower(args[i]) { - case "rank": - if rank, err = strconv.Atoi(val); err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - if rank == 0 { - setDirty(c) - c.WriteError(msgRankIsZero) - return - } - case "count": - countSpecified = true - if count, err = strconv.Atoi(val); err != nil || count < 0 { - setDirty(c) - c.WriteError(msgCountIsNegative) - return - } - case "maxlen": - maxlenSpecified = true - if maxlen, err = strconv.Atoi(val); err != nil || maxlen < 0 { - setDirty(c) - c.WriteError(msgMaxLengthIsNegative) - return - } - default: - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - } - } - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - key, element := args[0], args[1] - t, ok := db.keys[key] - if !ok { - // No such key - c.WriteNull() - return - } - if t != "list" { - c.WriteError(msgWrongType) - return - } - l := db.listKeys[key] - - // RANK cannot be zero (see above). - // If RANK is positive search forward (left to right). - // If RANK is negative search backward (right to left). - // Iterator returns true to continue iterating. - iterate := func(iterator func(i int, e string) bool) { - comparisons := len(l) - // Only use max length if specified, not zero, and less than total length. - // When max length is specified, but is zero, this means "unlimited". - if maxlenSpecified && maxlen != 0 && maxlen < len(l) { - comparisons = maxlen - } - if rank > 0 { - for i := 0; i < comparisons; i++ { - if resume := iterator(i, l[i]); !resume { - return - } - } - } else if rank < 0 { - start := len(l) - 1 - end := len(l) - comparisons - for i := start; i >= end; i-- { - if resume := iterator(i, l[i]); !resume { - return - } - } - } - } - - var currentRank, currentCount int - vals := make([]int, 0, count) - iterate(func(i int, e string) bool { - if e == element { - currentRank++ - // Only collect values only after surpassing the absolute value of rank. - if rank > 0 && currentRank < rank { - return true - } - if rank < 0 && currentRank < -rank { - return true - } - vals = append(vals, i) - currentCount++ - if currentCount == count { - return false - } - } - return true - }) - - if !countSpecified && len(vals) == 0 { - c.WriteNull() - return - } - if !countSpecified && len(vals) == 1 { - c.WriteInt(vals[0]) - return - } - c.WriteLen(len(vals)) - for _, val := range vals { - c.WriteInt(val) - } - }) -} - -// LINSERT -func (m *Miniredis) cmdLinsert(c *server.Peer, cmd string, args []string) { - if len(args) != 4 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - where := 0 - switch strings.ToLower(args[1]) { - case "before": - where = -1 - case "after": - where = +1 - default: - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - pivot := args[2] - value := args[3] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[key] - if !ok { - // No such key - c.WriteInt(0) - return - } - if t != "list" { - c.WriteError(msgWrongType) - return - } - - l := db.listKeys[key] - for i, el := range l { - if el != pivot { - continue - } - - if where < 0 { - l = append(l[:i], append(listKey{value}, l[i:]...)...) - } else { - if i == len(l)-1 { - l = append(l, value) - } else { - l = append(l[:i+1], append(listKey{value}, l[i+1:]...)...) - } - } - db.listKeys[key] = l - db.keyVersion[key]++ - c.WriteInt(len(l)) - return - } - c.WriteInt(-1) - }) -} - -// LLEN -func (m *Miniredis) cmdLlen(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[key] - if !ok { - // No such key. That's zero length. - c.WriteInt(0) - return - } - if t != "list" { - c.WriteError(msgWrongType) - return - } - - c.WriteInt(len(db.listKeys[key])) - }) -} - -// LPOP -func (m *Miniredis) cmdLpop(c *server.Peer, cmd string, args []string) { - m.cmdXpop(c, cmd, args, left) -} - -// RPOP -func (m *Miniredis) cmdRpop(c *server.Peer, cmd string, args []string) { - m.cmdXpop(c, cmd, args, right) -} - -func (m *Miniredis) cmdXpop(c *server.Peer, cmd string, args []string, lr leftright) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - withCount bool - count int - } - - opts.key, args = args[0], args[1:] - if len(args) > 0 { - if ok := optInt(c, args[0], &opts.count); !ok { - return - } - if opts.count < 0 { - setDirty(c) - c.WriteError(msgOutOfRange) - return - } - opts.withCount = true - args = args[1:] - } - if len(args) > 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.key) { - // non-existing key is fine - if opts.withCount && !c.Resp3 { - // zero-length list in this specific case. Looks like a redis bug to me. - c.WriteLen(-1) - return - } - c.WriteNull() - return - } - if db.t(opts.key) != "list" { - c.WriteError(msgWrongType) - return - } - - if opts.withCount { - var popped []string - for opts.count > 0 && len(db.listKeys[opts.key]) > 0 { - switch lr { - case left: - popped = append(popped, db.listLpop(opts.key)) - case right: - popped = append(popped, db.listPop(opts.key)) - } - opts.count -= 1 - } - c.WriteStrings(popped) - return - } - - var elem string - switch lr { - case left: - elem = db.listLpop(opts.key) - case right: - elem = db.listPop(opts.key) - } - c.WriteBulk(elem) - }) -} - -// LPUSH -func (m *Miniredis) cmdLpush(c *server.Peer, cmd string, args []string) { - m.cmdXpush(c, cmd, args, left) -} - -// RPUSH -func (m *Miniredis) cmdRpush(c *server.Peer, cmd string, args []string) { - m.cmdXpush(c, cmd, args, right) -} - -func (m *Miniredis) cmdXpush(c *server.Peer, cmd string, args []string, lr leftright) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, args := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if db.exists(key) && db.t(key) != "list" { - c.WriteError(msgWrongType) - return - } - - var newLen int - for _, value := range args { - switch lr { - case left: - newLen = db.listLpush(key, value) - case right: - newLen = db.listPush(key, value) - } - } - c.WriteInt(newLen) - }) -} - -// LPUSHX -func (m *Miniredis) cmdLpushx(c *server.Peer, cmd string, args []string) { - m.cmdXpushx(c, cmd, args, left) -} - -// RPUSHX -func (m *Miniredis) cmdRpushx(c *server.Peer, cmd string, args []string) { - m.cmdXpushx(c, cmd, args, right) -} - -func (m *Miniredis) cmdXpushx(c *server.Peer, cmd string, args []string, lr leftright) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, args := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteInt(0) - return - } - if db.t(key) != "list" { - c.WriteError(msgWrongType) - return - } - - var newLen int - for _, value := range args { - switch lr { - case left: - newLen = db.listLpush(key, value) - case right: - newLen = db.listPush(key, value) - } - } - c.WriteInt(newLen) - }) -} - -// LRANGE -func (m *Miniredis) cmdLrange(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - key string - start int - end int - }{ - key: args[0], - } - if ok := optInt(c, args[1], &opts.start); !ok { - return - } - if ok := optInt(c, args[2], &opts.end); !ok { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[opts.key]; ok && t != "list" { - c.WriteError(msgWrongType) - return - } - - l := db.listKeys[opts.key] - if len(l) == 0 { - c.WriteLen(0) - return - } - - rs, re := redisRange(len(l), opts.start, opts.end, false) - c.WriteLen(re - rs) - for _, el := range l[rs:re] { - c.WriteBulk(el) - } - }) -} - -// LREM -func (m *Miniredis) cmdLrem(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - count int - value string - } - opts.key = args[0] - if ok := optInt(c, args[1], &opts.count); !ok { - return - } - opts.value = args[2] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.key) { - c.WriteInt(0) - return - } - if db.t(opts.key) != "list" { - c.WriteError(msgWrongType) - return - } - - l := db.listKeys[opts.key] - if opts.count < 0 { - reverseSlice(l) - } - deleted := 0 - newL := []string{} - toDelete := len(l) - if opts.count < 0 { - toDelete = -opts.count - } - if opts.count > 0 { - toDelete = opts.count - } - for _, el := range l { - if el == opts.value { - if toDelete > 0 { - deleted++ - toDelete-- - continue - } - } - newL = append(newL, el) - } - if opts.count < 0 { - reverseSlice(newL) - } - if len(newL) == 0 { - db.del(opts.key, true) - } else { - db.listKeys[opts.key] = newL - db.keyVersion[opts.key]++ - } - - c.WriteInt(deleted) - }) -} - -// LSET -func (m *Miniredis) cmdLset(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - index int - value string - } - opts.key = args[0] - if ok := optInt(c, args[1], &opts.index); !ok { - return - } - opts.value = args[2] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.key) { - c.WriteError(msgKeyNotFound) - return - } - if db.t(opts.key) != "list" { - c.WriteError(msgWrongType) - return - } - - l := db.listKeys[opts.key] - index := opts.index - if index < 0 { - index = len(l) + index - } - if index < 0 || index > len(l)-1 { - c.WriteError(msgOutOfRange) - return - } - l[index] = opts.value - db.keyVersion[opts.key]++ - - c.WriteOK() - }) -} - -// LTRIM -func (m *Miniredis) cmdLtrim(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - start int - end int - } - - opts.key = args[0] - if ok := optInt(c, args[1], &opts.start); !ok { - return - } - if ok := optInt(c, args[2], &opts.end); !ok { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - t, ok := db.keys[opts.key] - if !ok { - c.WriteOK() - return - } - if t != "list" { - c.WriteError(msgWrongType) - return - } - - l := db.listKeys[opts.key] - rs, re := redisRange(len(l), opts.start, opts.end, false) - l = l[rs:re] - if len(l) == 0 { - db.del(opts.key, true) - } else { - db.listKeys[opts.key] = l - db.keyVersion[opts.key]++ - } - c.WriteOK() - }) -} - -// RPOPLPUSH -func (m *Miniredis) cmdRpoplpush(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - src, dst := args[0], args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(src) { - c.WriteNull() - return - } - if db.t(src) != "list" || (db.exists(dst) && db.t(dst) != "list") { - c.WriteError(msgWrongType) - return - } - elem := db.listPop(src) - db.listLpush(dst, elem) - c.WriteBulk(elem) - }) -} - -// BRPOPLPUSH -func (m *Miniredis) cmdBrpoplpush(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - src string - dst string - timeout time.Duration - } - opts.src = args[0] - opts.dst = args[1] - if ok := optDuration(c, args[2], &opts.timeout); !ok { - return - } - - blocking( - m, - c, - opts.timeout, - func(c *server.Peer, ctx *connCtx) bool { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.src) { - return false - } - if db.t(opts.src) != "list" || (db.exists(opts.dst) && db.t(opts.dst) != "list") { - c.WriteError(msgWrongType) - return true - } - if len(db.listKeys[opts.src]) == 0 { - return false - } - elem := db.listPop(opts.src) - db.listLpush(opts.dst, elem) - c.WriteBulk(elem) - return true - }, - func(c *server.Peer) { - // timeout - c.WriteLen(-1) - }, - ) -} - -// LMOVE -func (m *Miniredis) cmdLmove(c *server.Peer, cmd string, args []string) { - if len(args) != 4 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - src string - dst string - srcDir string - dstDir string - }{ - src: args[0], - dst: args[1], - srcDir: strings.ToLower(args[2]), - dstDir: strings.ToLower(args[3]), - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.src) { - c.WriteNull() - return - } - if db.t(opts.src) != "list" || (db.exists(opts.dst) && db.t(opts.dst) != "list") { - c.WriteError(msgWrongType) - return - } - var elem string - switch opts.srcDir { - case "left": - elem = db.listLpop(opts.src) - case "right": - elem = db.listPop(opts.src) - default: - c.WriteError(msgSyntaxError) - return - } - - switch opts.dstDir { - case "left": - db.listLpush(opts.dst, elem) - case "right": - db.listPush(opts.dst, elem) - default: - c.WriteError(msgSyntaxError) - return - } - c.WriteBulk(elem) - }) -} - -// BLMOVE -func (m *Miniredis) cmdBlmove(c *server.Peer, cmd string, args []string) { - if len(args) != 5 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - src string - dst string - srcDir string - dstDir string - timeout time.Duration - }{ - src: args[0], - dst: args[1], - srcDir: strings.ToLower(args[2]), - dstDir: strings.ToLower(args[3]), - } - if ok := optDuration(c, args[len(args)-1], &opts.timeout); !ok { - return - } - - blocking( - m, - c, - opts.timeout, - func(c *server.Peer, ctx *connCtx) bool { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.src) { - return false - } - if db.t(opts.src) != "list" || (db.exists(opts.dst) && db.t(opts.dst) != "list") { - c.WriteError(msgWrongType) - return true - } - - var elem string - switch opts.srcDir { - case "left": - elem = db.listLpop(opts.src) - case "right": - elem = db.listPop(opts.src) - default: - c.WriteError(msgSyntaxError) - return true - } - - switch opts.dstDir { - case "left": - db.listLpush(opts.dst, elem) - case "right": - db.listPush(opts.dst, elem) - default: - c.WriteError(msgSyntaxError) - return true - } - - c.WriteBulk(elem) - return true - }, - func(c *server.Peer) { - // timeout - c.WriteLen(-1) - }, - ) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_pubsub.go b/vendor/github.com/alicebob/miniredis/v2/cmd_pubsub.go deleted file mode 100644 index 0fc9f0de3..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_pubsub.go +++ /dev/null @@ -1,262 +0,0 @@ -// Commands from https://redis.io/commands#pubsub - -package miniredis - -import ( - "fmt" - "strings" - - "github.com/alicebob/miniredis/v2/server" -) - -// commandsPubsub handles all PUB/SUB operations. -func commandsPubsub(m *Miniredis) { - m.srv.Register("SUBSCRIBE", m.cmdSubscribe) - m.srv.Register("UNSUBSCRIBE", m.cmdUnsubscribe) - m.srv.Register("PSUBSCRIBE", m.cmdPsubscribe) - m.srv.Register("PUNSUBSCRIBE", m.cmdPunsubscribe) - m.srv.Register("PUBLISH", m.cmdPublish) - m.srv.Register("PUBSUB", m.cmdPubSub) -} - -// SUBSCRIBE -func (m *Miniredis) cmdSubscribe(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - ctx := getCtx(c) - if ctx.nested { - c.WriteError(msgNotFromScripts(ctx.nestedSHA)) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - sub := m.subscribedState(c) - for _, channel := range args { - n := sub.Subscribe(channel) - c.Block(func(w *server.Writer) { - w.WritePushLen(3) - w.WriteBulk("subscribe") - w.WriteBulk(channel) - w.WriteInt(n) - }) - } - }) -} - -// UNSUBSCRIBE -func (m *Miniredis) cmdUnsubscribe(c *server.Peer, cmd string, args []string) { - if !m.handleAuth(c) { - return - } - ctx := getCtx(c) - if ctx.nested { - c.WriteError(msgNotFromScripts(ctx.nestedSHA)) - return - } - - channels := args - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - sub := m.subscribedState(c) - - if len(channels) == 0 { - channels = sub.Channels() - } - - // there is no de-duplication - for _, channel := range channels { - n := sub.Unsubscribe(channel) - c.Block(func(w *server.Writer) { - w.WritePushLen(3) - w.WriteBulk("unsubscribe") - w.WriteBulk(channel) - w.WriteInt(n) - }) - } - if len(channels) == 0 { - // special case: there is always a reply - c.Block(func(w *server.Writer) { - w.WritePushLen(3) - w.WriteBulk("unsubscribe") - w.WriteNull() - w.WriteInt(0) - }) - } - - if sub.Count() == 0 { - endSubscriber(m, c) - } - }) -} - -// PSUBSCRIBE -func (m *Miniredis) cmdPsubscribe(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - ctx := getCtx(c) - if ctx.nested { - c.WriteError(msgNotFromScripts(ctx.nestedSHA)) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - sub := m.subscribedState(c) - for _, pat := range args { - n := sub.Psubscribe(pat) - c.Block(func(w *server.Writer) { - w.WritePushLen(3) - w.WriteBulk("psubscribe") - w.WriteBulk(pat) - w.WriteInt(n) - }) - } - }) -} - -// PUNSUBSCRIBE -func (m *Miniredis) cmdPunsubscribe(c *server.Peer, cmd string, args []string) { - if !m.handleAuth(c) { - return - } - ctx := getCtx(c) - if ctx.nested { - c.WriteError(msgNotFromScripts(ctx.nestedSHA)) - return - } - - patterns := args - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - sub := m.subscribedState(c) - - if len(patterns) == 0 { - patterns = sub.Patterns() - } - - // there is no de-duplication - for _, pat := range patterns { - n := sub.Punsubscribe(pat) - c.Block(func(w *server.Writer) { - w.WritePushLen(3) - w.WriteBulk("punsubscribe") - w.WriteBulk(pat) - w.WriteInt(n) - }) - } - if len(patterns) == 0 { - // special case: there is always a reply - c.Block(func(w *server.Writer) { - w.WritePushLen(3) - w.WriteBulk("punsubscribe") - w.WriteNull() - w.WriteInt(0) - }) - } - - if sub.Count() == 0 { - endSubscriber(m, c) - } - }) -} - -// PUBLISH -func (m *Miniredis) cmdPublish(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - channel, mesg := args[0], args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - c.WriteInt(m.publish(channel, mesg)) - }) -} - -// PUBSUB -func (m *Miniredis) cmdPubSub(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - if m.checkPubsub(c, cmd) { - return - } - - subcommand := strings.ToUpper(args[0]) - subargs := args[1:] - var argsOk bool - - switch subcommand { - case "CHANNELS": - argsOk = len(subargs) < 2 - case "NUMSUB": - argsOk = true - case "NUMPAT": - argsOk = len(subargs) == 0 - default: - setDirty(c) - c.WriteError(fmt.Sprintf(msgFPubsubUsageSimple, subcommand)) - return - } - - if !argsOk { - setDirty(c) - c.WriteError(fmt.Sprintf(msgFPubsubUsage, subcommand)) - return - } - - if !m.handleAuth(c) { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - switch subcommand { - case "CHANNELS": - pat := "" - if len(subargs) == 1 { - pat = subargs[0] - } - - allsubs := m.allSubscribers() - channels := activeChannels(allsubs, pat) - - c.WriteLen(len(channels)) - for _, channel := range channels { - c.WriteBulk(channel) - } - - case "NUMSUB": - subs := m.allSubscribers() - c.WriteLen(len(subargs) * 2) - for _, channel := range subargs { - c.WriteBulk(channel) - c.WriteInt(countSubs(subs, channel)) - } - - case "NUMPAT": - c.WriteInt(countPsubs(m.allSubscribers())) - } - }) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_scripting.go b/vendor/github.com/alicebob/miniredis/v2/cmd_scripting.go deleted file mode 100644 index 5a48f8b7f..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_scripting.go +++ /dev/null @@ -1,343 +0,0 @@ -package miniredis - -import ( - "crypto/sha1" - "encoding/hex" - "fmt" - "io" - "strconv" - "strings" - "sync" - - luajson "github.com/alicebob/gopher-json" - lua "github.com/yuin/gopher-lua" - "github.com/yuin/gopher-lua/parse" - - "github.com/alicebob/miniredis/v2/server" -) - -func commandsScripting(m *Miniredis) { - m.srv.Register("EVAL", m.cmdEval) - m.srv.Register("EVALSHA", m.cmdEvalsha) - m.srv.Register("SCRIPT", m.cmdScript) -} - -var ( - parsedScripts = sync.Map{} -) - -// Execute lua. Needs to run m.Lock()ed, from within withTx(). -// Returns true if the lua was OK (and hence should be cached). -func (m *Miniredis) runLuaScript(c *server.Peer, sha, script string, args []string) bool { - l := lua.NewState(lua.Options{SkipOpenLibs: true}) - defer l.Close() - - // Taken from the go-lua manual - for _, pair := range []struct { - n string - f lua.LGFunction - }{ - {lua.LoadLibName, lua.OpenPackage}, - {lua.BaseLibName, lua.OpenBase}, - {lua.CoroutineLibName, lua.OpenCoroutine}, - {lua.TabLibName, lua.OpenTable}, - {lua.StringLibName, lua.OpenString}, - {lua.MathLibName, lua.OpenMath}, - {lua.DebugLibName, lua.OpenDebug}, - } { - if err := l.CallByParam(lua.P{ - Fn: l.NewFunction(pair.f), - NRet: 0, - Protect: true, - }, lua.LString(pair.n)); err != nil { - panic(err) - } - } - - luajson.Preload(l) - requireGlobal(l, "cjson", "json") - - // set global variable KEYS - keysTable := l.NewTable() - keysS, args := args[0], args[1:] - keysLen, err := strconv.Atoi(keysS) - if err != nil { - c.WriteError(msgInvalidInt) - return false - } - if keysLen < 0 { - c.WriteError(msgNegativeKeysNumber) - return false - } - if keysLen > len(args) { - c.WriteError(msgInvalidKeysNumber) - return false - } - keys, args := args[:keysLen], args[keysLen:] - for i, k := range keys { - l.RawSet(keysTable, lua.LNumber(i+1), lua.LString(k)) - } - l.SetGlobal("KEYS", keysTable) - - argvTable := l.NewTable() - for i, a := range args { - l.RawSet(argvTable, lua.LNumber(i+1), lua.LString(a)) - } - l.SetGlobal("ARGV", argvTable) - - redisFuncs, redisConstants := mkLua(m.srv, c, sha) - // Register command handlers - l.Push(l.NewFunction(func(l *lua.LState) int { - mod := l.RegisterModule("redis", redisFuncs).(*lua.LTable) - for k, v := range redisConstants { - mod.RawSetString(k, v) - } - l.Push(mod) - return 1 - })) - - _ = doScript(l, protectGlobals) - - l.Push(lua.LString("redis")) - l.Call(1, 0) - - if err := doScript(l, script); err != nil { - c.WriteError(err.Error()) - return false - } - - luaToRedis(l, c, l.Get(1)) - return true -} - -// doScript pre-compiiles the given script into a Lua prototype, -// then executes the pre-compiled function against the given lua state. -// -// This is thread-safe. -func doScript(l *lua.LState, script string) error { - proto, err := compile(script) - if err != nil { - return fmt.Errorf(errLuaParseError(err)) - } - - lfunc := l.NewFunctionFromProto(proto) - l.Push(lfunc) - if err := l.PCall(0, lua.MultRet, nil); err != nil { - // ensure we wrap with the correct format. - return fmt.Errorf(errLuaParseError(err)) - } - - return nil -} - -func compile(script string) (*lua.FunctionProto, error) { - if val, ok := parsedScripts.Load(script); ok { - return val.(*lua.FunctionProto), nil - } - chunk, err := parse.Parse(strings.NewReader(script), "") - if err != nil { - return nil, err - } - proto, err := lua.Compile(chunk, "") - if err != nil { - return nil, err - } - parsedScripts.Store(script, proto) - return proto, nil -} - -func (m *Miniredis) cmdEval(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - ctx := getCtx(c) - if ctx.nested { - c.WriteError(msgNotFromScripts(ctx.nestedSHA)) - return - } - - script, args := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - sha := sha1Hex(script) - ok := m.runLuaScript(c, sha, script, args) - if ok { - m.scripts[sha] = script - } - }) -} - -func (m *Miniredis) cmdEvalsha(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - ctx := getCtx(c) - if ctx.nested { - c.WriteError(msgNotFromScripts(ctx.nestedSHA)) - return - } - - sha, args := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - script, ok := m.scripts[sha] - if !ok { - c.WriteError(msgNoScriptFound) - return - } - - m.runLuaScript(c, sha, script, args) - }) -} - -func (m *Miniredis) cmdScript(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - ctx := getCtx(c) - if ctx.nested { - c.WriteError(msgNotFromScripts(ctx.nestedSHA)) - return - } - - var opts struct { - subcmd string - script string - } - - opts.subcmd, args = args[0], args[1:] - - switch strings.ToLower(opts.subcmd) { - case "load": - if len(args) != 1 { - setDirty(c) - c.WriteError(fmt.Sprintf(msgFScriptUsage, "LOAD")) - return - } - opts.script = args[0] - case "exists": - if len(args) == 0 { - setDirty(c) - c.WriteError(errWrongNumber("script|exists")) - return - } - case "flush": - if len(args) == 1 { - switch strings.ToUpper(args[0]) { - case "SYNC", "ASYNC": - args = args[1:] - default: - } - } - if len(args) != 0 { - setDirty(c) - c.WriteError(msgScriptFlush) - return - } - - default: - setDirty(c) - c.WriteError(fmt.Sprintf(msgFScriptUsageSimple, strings.ToUpper(opts.subcmd))) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - switch strings.ToLower(opts.subcmd) { - case "load": - if _, err := parse.Parse(strings.NewReader(opts.script), "user_script"); err != nil { - c.WriteError(errLuaParseError(err)) - return - } - sha := sha1Hex(opts.script) - m.scripts[sha] = opts.script - c.WriteBulk(sha) - - case "exists": - c.WriteLen(len(args)) - for _, arg := range args { - if _, ok := m.scripts[arg]; ok { - c.WriteInt(1) - } else { - c.WriteInt(0) - } - } - - case "flush": - m.scripts = map[string]string{} - c.WriteOK() - - } - }) -} - -func sha1Hex(s string) string { - h := sha1.New() - io.WriteString(h, s) - return hex.EncodeToString(h.Sum(nil)) -} - -// requireGlobal imports module modName into the global namespace with the -// identifier id. panics if an error results from the function execution -func requireGlobal(l *lua.LState, id, modName string) { - if err := l.CallByParam(lua.P{ - Fn: l.GetGlobal("require"), - NRet: 1, - Protect: true, - }, lua.LString(modName)); err != nil { - panic(err) - } - mod := l.Get(-1) - l.Pop(1) - - l.SetGlobal(id, mod) -} - -// the following script protects globals -// it is based on: http://metalua.luaforge.net/src/lib/strict.lua.html -var protectGlobals = ` -local dbg=debug -local mt = {} -setmetatable(_G, mt) -mt.__newindex = function (t, n, v) - if dbg.getinfo(2) then - local w = dbg.getinfo(2, "S").what - if w ~= "C" then - error("Script attempted to create global variable '"..tostring(n).."'", 2) - end - end - rawset(t, n, v) -end -mt.__index = function (t, n) - if dbg.getinfo(2) and dbg.getinfo(2, "S").what ~= "C" then - error("Script attempted to access nonexistent global variable '"..tostring(n).."'", 2) - end - return rawget(t, n) -end -debug = nil - -` diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_server.go b/vendor/github.com/alicebob/miniredis/v2/cmd_server.go deleted file mode 100644 index 6e51727ba..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_server.go +++ /dev/null @@ -1,112 +0,0 @@ -// Commands from https://redis.io/commands#server - -package miniredis - -import ( - "strconv" - "strings" - - "github.com/alicebob/miniredis/v2/server" -) - -func commandsServer(m *Miniredis) { - m.srv.Register("COMMAND", m.cmdCommand) - m.srv.Register("DBSIZE", m.cmdDbsize) - m.srv.Register("FLUSHALL", m.cmdFlushall) - m.srv.Register("FLUSHDB", m.cmdFlushdb) - m.srv.Register("INFO", m.cmdInfo) - m.srv.Register("TIME", m.cmdTime) -} - -// DBSIZE -func (m *Miniredis) cmdDbsize(c *server.Peer, cmd string, args []string) { - if len(args) > 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - c.WriteInt(len(db.keys)) - }) -} - -// FLUSHALL -func (m *Miniredis) cmdFlushall(c *server.Peer, cmd string, args []string) { - if len(args) > 0 && strings.ToLower(args[0]) == "async" { - args = args[1:] - } - if len(args) > 0 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - m.flushAll() - c.WriteOK() - }) -} - -// FLUSHDB -func (m *Miniredis) cmdFlushdb(c *server.Peer, cmd string, args []string) { - if len(args) > 0 && strings.ToLower(args[0]) == "async" { - args = args[1:] - } - if len(args) > 0 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - m.db(ctx.selectedDB).flush() - c.WriteOK() - }) -} - -// TIME -func (m *Miniredis) cmdTime(c *server.Peer, cmd string, args []string) { - if len(args) > 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - now := m.effectiveNow() - nanos := now.UnixNano() - seconds := nanos / 1_000_000_000 - microseconds := (nanos / 1_000) % 1_000_000 - - c.WriteLen(2) - c.WriteBulk(strconv.FormatInt(seconds, 10)) - c.WriteBulk(strconv.FormatInt(microseconds, 10)) - }) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_set.go b/vendor/github.com/alicebob/miniredis/v2/cmd_set.go deleted file mode 100644 index 056a3093e..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_set.go +++ /dev/null @@ -1,715 +0,0 @@ -// Commands from https://redis.io/commands#set - -package miniredis - -import ( - "fmt" - "strconv" - "strings" - - "github.com/alicebob/miniredis/v2/server" -) - -// commandsSet handles all set value operations. -func commandsSet(m *Miniredis) { - m.srv.Register("SADD", m.cmdSadd) - m.srv.Register("SCARD", m.cmdScard) - m.srv.Register("SDIFF", m.cmdSdiff) - m.srv.Register("SDIFFSTORE", m.cmdSdiffstore) - m.srv.Register("SINTER", m.cmdSinter) - m.srv.Register("SINTERSTORE", m.cmdSinterstore) - m.srv.Register("SISMEMBER", m.cmdSismember) - m.srv.Register("SMEMBERS", m.cmdSmembers) - m.srv.Register("SMOVE", m.cmdSmove) - m.srv.Register("SPOP", m.cmdSpop) - m.srv.Register("SRANDMEMBER", m.cmdSrandmember) - m.srv.Register("SREM", m.cmdSrem) - m.srv.Register("SUNION", m.cmdSunion) - m.srv.Register("SUNIONSTORE", m.cmdSunionstore) - m.srv.Register("SSCAN", m.cmdSscan) -} - -// SADD -func (m *Miniredis) cmdSadd(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, elems := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if db.exists(key) && db.t(key) != "set" { - c.WriteError(ErrWrongType.Error()) - return - } - - added := db.setAdd(key, elems...) - c.WriteInt(added) - }) -} - -// SCARD -func (m *Miniredis) cmdScard(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteInt(0) - return - } - - if db.t(key) != "set" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.setMembers(key) - c.WriteInt(len(members)) - }) -} - -// SDIFF -func (m *Miniredis) cmdSdiff(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - keys := args - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - set, err := db.setDiff(keys) - if err != nil { - c.WriteError(err.Error()) - return - } - - c.WriteSetLen(len(set)) - for k := range set { - c.WriteBulk(k) - } - }) -} - -// SDIFFSTORE -func (m *Miniredis) cmdSdiffstore(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - dest, keys := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - set, err := db.setDiff(keys) - if err != nil { - c.WriteError(err.Error()) - return - } - - db.del(dest, true) - db.setSet(dest, set) - c.WriteInt(len(set)) - }) -} - -// SINTER -func (m *Miniredis) cmdSinter(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - keys := args - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - set, err := db.setInter(keys) - if err != nil { - c.WriteError(err.Error()) - return - } - - c.WriteLen(len(set)) - for k := range set { - c.WriteBulk(k) - } - }) -} - -// SINTERSTORE -func (m *Miniredis) cmdSinterstore(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - dest, keys := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - set, err := db.setInter(keys) - if err != nil { - c.WriteError(err.Error()) - return - } - - db.del(dest, true) - db.setSet(dest, set) - c.WriteInt(len(set)) - }) -} - -// SISMEMBER -func (m *Miniredis) cmdSismember(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, value := args[0], args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteInt(0) - return - } - - if db.t(key) != "set" { - c.WriteError(ErrWrongType.Error()) - return - } - - if db.setIsMember(key, value) { - c.WriteInt(1) - return - } - c.WriteInt(0) - }) -} - -// SMEMBERS -func (m *Miniredis) cmdSmembers(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteSetLen(0) - return - } - - if db.t(key) != "set" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.setMembers(key) - - c.WriteSetLen(len(members)) - for _, elem := range members { - c.WriteBulk(elem) - } - }) -} - -// SMOVE -func (m *Miniredis) cmdSmove(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - src, dst, member := args[0], args[1], args[2] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(src) { - c.WriteInt(0) - return - } - - if db.t(src) != "set" { - c.WriteError(ErrWrongType.Error()) - return - } - - if db.exists(dst) && db.t(dst) != "set" { - c.WriteError(ErrWrongType.Error()) - return - } - - if !db.setIsMember(src, member) { - c.WriteInt(0) - return - } - db.setRem(src, member) - db.setAdd(dst, member) - c.WriteInt(1) - }) -} - -// SPOP -func (m *Miniredis) cmdSpop(c *server.Peer, cmd string, args []string) { - if len(args) == 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - key string - withCount bool - count int - }{ - count: 1, - } - opts.key, args = args[0], args[1:] - - if len(args) > 0 { - v, err := strconv.Atoi(args[0]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - if v < 0 { - setDirty(c) - c.WriteError(msgOutOfRange) - return - } - opts.count = v - opts.withCount = true - args = args[1:] - } - if len(args) > 0 { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.key) { - if !opts.withCount { - c.WriteNull() - return - } - c.WriteLen(0) - return - } - - if db.t(opts.key) != "set" { - c.WriteError(ErrWrongType.Error()) - return - } - - var deleted []string - members := db.setMembers(opts.key) - for i := 0; i < opts.count; i++ { - if len(members) == 0 { - break - } - i := m.randIntn(len(members)) - member := members[i] - members = delElem(members, i) - db.setRem(opts.key, member) - deleted = append(deleted, member) - } - // without `count` return a single value - if !opts.withCount { - if len(deleted) == 0 { - c.WriteNull() - return - } - c.WriteBulk(deleted[0]) - return - } - // with `count` return a list - c.WriteLen(len(deleted)) - for _, v := range deleted { - c.WriteBulk(v) - } - }) -} - -// SRANDMEMBER -func (m *Miniredis) cmdSrandmember(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if len(args) > 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - count := 0 - withCount := false - if len(args) == 2 { - var err error - count, err = strconv.Atoi(args[1]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - withCount = true - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteNull() - return - } - - if db.t(key) != "set" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.setMembers(key) - if count < 0 { - // Non-unique elements is allowed with negative count. - c.WriteLen(-count) - for count != 0 { - member := members[m.randIntn(len(members))] - c.WriteBulk(member) - count++ - } - return - } - - // Must be unique elements. - m.shuffle(members) - if count > len(members) { - count = len(members) - } - if !withCount { - c.WriteBulk(members[0]) - return - } - c.WriteLen(count) - for i := range make([]struct{}, count) { - c.WriteBulk(members[i]) - } - }) -} - -// SREM -func (m *Miniredis) cmdSrem(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, fields := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteInt(0) - return - } - - if db.t(key) != "set" { - c.WriteError(ErrWrongType.Error()) - return - } - - c.WriteInt(db.setRem(key, fields...)) - }) -} - -// SUNION -func (m *Miniredis) cmdSunion(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - keys := args - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - set, err := db.setUnion(keys) - if err != nil { - c.WriteError(err.Error()) - return - } - - c.WriteLen(len(set)) - for k := range set { - c.WriteBulk(k) - } - }) -} - -// SUNIONSTORE -func (m *Miniredis) cmdSunionstore(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - dest, keys := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - set, err := db.setUnion(keys) - if err != nil { - c.WriteError(err.Error()) - return - } - - db.del(dest, true) - db.setSet(dest, set) - c.WriteInt(len(set)) - }) -} - -// SSCAN -func (m *Miniredis) cmdSscan(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - value int - cursor int - count int - withMatch bool - match string - } - - opts.key = args[0] - if ok := optIntErr(c, args[1], &opts.cursor, msgInvalidCursor); !ok { - return - } - args = args[2:] - - // MATCH and COUNT options - for len(args) > 0 { - if strings.ToLower(args[0]) == "count" { - if len(args) < 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - count, err := strconv.Atoi(args[1]) - if err != nil || count < 0 { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - if count == 0 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - opts.count = count - args = args[2:] - continue - } - if strings.ToLower(args[0]) == "match" { - if len(args) < 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - opts.withMatch = true - opts.match = args[1] - args = args[2:] - continue - } - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - // return _all_ (matched) keys every time - if db.exists(opts.key) && db.t(opts.key) != "set" { - c.WriteError(ErrWrongType.Error()) - return - } - members := db.setMembers(opts.key) - if opts.withMatch { - members, _ = matchKeys(members, opts.match) - } - low := opts.cursor - high := low + opts.count - // validate high is correct - if high > len(members) || high == 0 { - high = len(members) - } - if opts.cursor > high { - // invalid cursor - c.WriteLen(2) - c.WriteBulk("0") // no next cursor - c.WriteLen(0) // no elements - return - } - cursorValue := low + opts.count - if cursorValue > len(members) { - cursorValue = 0 // no next cursor - } - members = members[low:high] - c.WriteLen(2) - c.WriteBulk(fmt.Sprintf("%d", cursorValue)) - c.WriteLen(len(members)) - for _, k := range members { - c.WriteBulk(k) - } - - }) -} - -func delElem(ls []string, i int) []string { - // this swap+truncate is faster but changes behaviour: - // ls[i] = ls[len(ls)-1] - // ls = ls[:len(ls)-1] - // so we do the dumb thing: - ls = append(ls[:i], ls[i+1:]...) - return ls -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_sorted_set.go b/vendor/github.com/alicebob/miniredis/v2/cmd_sorted_set.go deleted file mode 100644 index e7164e048..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_sorted_set.go +++ /dev/null @@ -1,1924 +0,0 @@ -// Commands from https://redis.io/commands#sorted_set - -package miniredis - -import ( - "errors" - "math" - "sort" - "strconv" - "strings" - - "github.com/alicebob/miniredis/v2/server" -) - -// commandsSortedSet handles all sorted set operations. -func commandsSortedSet(m *Miniredis) { - m.srv.Register("ZADD", m.cmdZadd) - m.srv.Register("ZCARD", m.cmdZcard) - m.srv.Register("ZCOUNT", m.cmdZcount) - m.srv.Register("ZINCRBY", m.cmdZincrby) - m.srv.Register("ZINTERSTORE", m.cmdZinterstore) - m.srv.Register("ZLEXCOUNT", m.cmdZlexcount) - m.srv.Register("ZRANGE", m.cmdZrange) - m.srv.Register("ZRANGEBYLEX", m.makeCmdZrangebylex(false)) - m.srv.Register("ZRANGEBYSCORE", m.makeCmdZrangebyscore(false)) - m.srv.Register("ZRANK", m.makeCmdZrank(false)) - m.srv.Register("ZREM", m.cmdZrem) - m.srv.Register("ZREMRANGEBYLEX", m.cmdZremrangebylex) - m.srv.Register("ZREMRANGEBYRANK", m.cmdZremrangebyrank) - m.srv.Register("ZREMRANGEBYSCORE", m.cmdZremrangebyscore) - m.srv.Register("ZREVRANGE", m.cmdZrevrange) - m.srv.Register("ZREVRANGEBYLEX", m.makeCmdZrangebylex(true)) - m.srv.Register("ZREVRANGEBYSCORE", m.makeCmdZrangebyscore(true)) - m.srv.Register("ZREVRANK", m.makeCmdZrank(true)) - m.srv.Register("ZSCORE", m.cmdZscore) - m.srv.Register("ZMSCORE", m.cmdZMscore) - m.srv.Register("ZUNION", m.cmdZunion) - m.srv.Register("ZUNIONSTORE", m.cmdZunionstore) - m.srv.Register("ZSCAN", m.cmdZscan) - m.srv.Register("ZPOPMAX", m.cmdZpopmax(true)) - m.srv.Register("ZPOPMIN", m.cmdZpopmax(false)) - m.srv.Register("ZRANDMEMBER", m.cmdZrandmember) -} - -// ZADD -func (m *Miniredis) cmdZadd(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - nx bool - xx bool - gt bool - lt bool - ch bool - incr bool - } - elems := map[string]float64{} - - opts.key = args[0] - args = args[1:] -outer: - for len(args) > 0 { - switch strings.ToUpper(args[0]) { - case "NX": - opts.nx = true - args = args[1:] - continue - case "XX": - opts.xx = true - args = args[1:] - continue - case "GT": - opts.gt = true - args = args[1:] - continue - case "LT": - opts.lt = true - args = args[1:] - continue - case "CH": - opts.ch = true - args = args[1:] - continue - case "INCR": - opts.incr = true - args = args[1:] - continue - default: - break outer - } - } - - if len(args) == 0 || len(args)%2 != 0 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - for len(args) > 0 { - score, err := strconv.ParseFloat(args[0], 64) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidFloat) - return - } - elems[args[1]] = score - args = args[2:] - } - - if opts.xx && opts.nx { - setDirty(c) - c.WriteError(msgXXandNX) - return - } - - if opts.gt && opts.lt || - opts.gt && opts.nx || - opts.lt && opts.nx { - setDirty(c) - c.WriteError(msgGTLTandNX) - return - } - - if opts.incr && len(elems) > 1 { - setDirty(c) - c.WriteError(msgSingleElementPair) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if db.exists(opts.key) && db.t(opts.key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - if opts.incr { - for member, delta := range elems { - if opts.nx && db.ssetExists(opts.key, member) { - c.WriteNull() - return - } - if opts.xx && !db.ssetExists(opts.key, member) { - c.WriteNull() - return - } - newScore := db.ssetIncrby(opts.key, member, delta) - c.WriteFloat(newScore) - } - return - } - - res := 0 - for member, score := range elems { - exists := db.ssetExists(opts.key, member) - if opts.nx && exists { - continue - } - if opts.xx && !exists { - continue - } - old := db.ssetScore(opts.key, member) - if opts.gt && exists && score <= old { - continue - } - if opts.lt && exists && score >= old { - continue - } - if db.ssetAdd(opts.key, score, member) { - res++ - } else { - if opts.ch && old != score { - // if 'CH' is specified, only count changed keys - res++ - } - } - } - c.WriteInt(res) - }) -} - -// ZCARD -func (m *Miniredis) cmdZcard(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteInt(0) - return - } - - if db.t(key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - c.WriteInt(db.ssetCard(key)) - }) -} - -// ZCOUNT -func (m *Miniredis) cmdZcount(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var ( - opts struct { - key string - min float64 - minIncl bool - max float64 - maxIncl bool - } - err error - ) - - opts.key = args[0] - opts.min, opts.minIncl, err = parseFloatRange(args[1]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidMinMax) - return - } - opts.max, opts.maxIncl, err = parseFloatRange(args[2]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidMinMax) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.key) { - c.WriteInt(0) - return - } - - if db.t(opts.key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.ssetElements(opts.key) - members = withSSRange(members, opts.min, opts.minIncl, opts.max, opts.maxIncl) - c.WriteInt(len(members)) - }) -} - -// ZINCRBY -func (m *Miniredis) cmdZincrby(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - delta float64 - member string - } - - opts.key = args[0] - d, err := strconv.ParseFloat(args[1], 64) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidFloat) - return - } - opts.delta = d - opts.member = args[2] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if db.exists(opts.key) && db.t(opts.key) != "zset" { - c.WriteError(msgWrongType) - return - } - newScore := db.ssetIncrby(opts.key, opts.member, opts.delta) - c.WriteFloat(newScore) - }) -} - -// ZINTERSTORE -func (m *Miniredis) cmdZinterstore(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - destination := args[0] - numKeys, err := strconv.Atoi(args[1]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - args = args[2:] - if len(args) < numKeys { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - if numKeys <= 0 { - setDirty(c) - c.WriteError("ERR at least 1 input key is needed for ZUNIONSTORE/ZINTERSTORE") - return - } - keys := args[:numKeys] - args = args[numKeys:] - - withWeights := false - weights := []float64{} - aggregate := "sum" - for len(args) > 0 { - switch strings.ToLower(args[0]) { - case "weights": - if len(args) < numKeys+1 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - for i := 0; i < numKeys; i++ { - f, err := strconv.ParseFloat(args[i+1], 64) - if err != nil { - setDirty(c) - c.WriteError("ERR weight value is not a float") - return - } - weights = append(weights, f) - } - withWeights = true - args = args[numKeys+1:] - case "aggregate": - if len(args) < 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - aggregate = strings.ToLower(args[1]) - switch aggregate { - case "sum", "min", "max": - default: - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - args = args[2:] - default: - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - db.del(destination, true) - - // We collect everything and remove all keys which turned out not to be - // present in every set. - sset := map[string]float64{} - counts := map[string]int{} - for i, key := range keys { - if !db.exists(key) { - continue - } - - var set map[string]float64 - switch db.t(key) { - case "set": - set = map[string]float64{} - for elem := range db.setKeys[key] { - set[elem] = 1.0 - } - case "zset": - set = db.sortedSet(key) - default: - c.WriteError(msgWrongType) - return - } - for member, score := range set { - if withWeights { - score *= weights[i] - } - counts[member]++ - old, ok := sset[member] - if !ok { - sset[member] = score - continue - } - switch aggregate { - default: - panic("Invalid aggregate") - case "sum": - sset[member] += score - case "min": - if score < old { - sset[member] = score - } - case "max": - if score > old { - sset[member] = score - } - } - } - } - for key, count := range counts { - if count != numKeys { - delete(sset, key) - } - } - db.ssetSet(destination, sset) - c.WriteInt(len(sset)) - }) -} - -// ZLEXCOUNT -func (m *Miniredis) cmdZlexcount(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts = struct { - Key string - Min string - Max string - }{ - Key: args[0], - Min: args[1], - Max: args[2], - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - min, minIncl, minErr := parseLexrange(opts.Min) - max, maxIncl, maxErr := parseLexrange(opts.Max) - if minErr != nil || maxErr != nil { - c.WriteError(msgInvalidRangeItem) - return - } - - db := m.db(ctx.selectedDB) - - if !db.exists(opts.Key) { - c.WriteInt(0) - return - } - - if db.t(opts.Key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.ssetMembers(opts.Key) - // Just key sort. If scores are not the same we don't care. - sort.Strings(members) - members = withLexRange(members, min, minIncl, max, maxIncl) - - c.WriteInt(len(members)) - }) -} - -// ZRANGE -func (m *Miniredis) cmdZrange(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - Key string - Min string - Max string - WithScores bool - ByScore bool - ByLex bool - Reverse bool - WithLimit bool - Offset string - Count string - } - - opts.Key, opts.Min, opts.Max = args[0], args[1], args[2] - args = args[3:] - - for len(args) > 0 { - switch strings.ToLower(args[0]) { - case "byscore": - opts.ByScore = true - args = args[1:] - case "bylex": - opts.ByLex = true - args = args[1:] - case "rev": - opts.Reverse = true - args = args[1:] - case "limit": - opts.WithLimit = true - args = args[1:] - if len(args) < 2 { - c.WriteError(msgSyntaxError) - return - } - opts.Offset = args[0] - opts.Count = args[1] - args = args[2:] - case "withscores": - opts.WithScores = true - args = args[1:] - default: - c.WriteError(msgSyntaxError) - return - } - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - switch { - case opts.ByScore && opts.ByLex: - c.WriteError(msgSyntaxError) - case opts.ByScore: - runRangeByScore(m, c, ctx, optsRangeByScore{ - Key: opts.Key, - Min: opts.Min, - Max: opts.Max, - Reverse: opts.Reverse, - WithLimit: opts.WithLimit, - Offset: opts.Offset, - Count: opts.Count, - WithScores: opts.WithScores, - }) - case opts.ByLex: - runRangeByLex(m, c, ctx, optsRangeByLex{ - Key: opts.Key, - Min: opts.Min, - Max: opts.Max, - Reverse: opts.Reverse, - WithLimit: opts.WithLimit, - Offset: opts.Offset, - Count: opts.Count, - WithScores: opts.WithScores, - }) - default: - if opts.WithLimit { - c.WriteError(msgLimitCombination) - return - } - runRange(m, c, ctx, optsRange{ - Key: opts.Key, - Min: opts.Min, - Max: opts.Max, - Reverse: opts.Reverse, - WithScores: opts.WithScores, - }) - } - }) -} - -// ZREVRANGE -func (m *Miniredis) cmdZrevrange(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts = optsRange{ - Reverse: true, - Key: args[0], - Min: args[1], - Max: args[2], - } - args = args[3:] - - for len(args) > 0 { - switch strings.ToLower(args[0]) { - case "withscores": - opts.WithScores = true - args = args[1:] - default: - c.WriteError(msgSyntaxError) - return - } - } - - withTx(m, c, func(c *server.Peer, cctx *connCtx) { - runRange(m, c, cctx, opts) - }) -} - -// ZRANGEBYLEX and ZREVRANGEBYLEX -func (m *Miniredis) makeCmdZrangebylex(reverse bool) server.Cmd { - return func(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - opts := optsRangeByLex{ - Reverse: reverse, - Key: args[0], - Min: args[1], - Max: args[2], - } - args = args[3:] - - for len(args) > 0 { - switch strings.ToLower(args[0]) { - case "limit": - opts.WithLimit = true - args = args[1:] - if len(args) < 2 { - c.WriteError(msgSyntaxError) - return - } - opts.Offset = args[0] - opts.Count = args[1] - args = args[2:] - continue - default: - // Syntax error - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - } - - withTx(m, c, func(c *server.Peer, cctx *connCtx) { - runRangeByLex(m, c, cctx, opts) - }) - } -} - -// ZRANGEBYSCORE and ZREVRANGEBYSCORE -func (m *Miniredis) makeCmdZrangebyscore(reverse bool) server.Cmd { - return func(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts = optsRangeByScore{ - Reverse: reverse, - Key: args[0], - Min: args[1], - Max: args[2], - } - args = args[3:] - - for len(args) > 0 { - if strings.ToLower(args[0]) == "limit" { - opts.WithLimit = true - args = args[1:] - if len(args) < 2 { - c.WriteError(msgSyntaxError) - return - } - opts.Offset = args[0] - opts.Count = args[1] - args = args[2:] - continue - } - if strings.ToLower(args[0]) == "withscores" { - opts.WithScores = true - args = args[1:] - continue - } - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - - withTx(m, c, func(c *server.Peer, cctx *connCtx) { - runRangeByScore(m, c, cctx, opts) - }) - } -} - -// ZRANK and ZREVRANK -func (m *Miniredis) makeCmdZrank(reverse bool) server.Cmd { - return func(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, member := args[0], args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteNull() - return - } - - if db.t(key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - direction := asc - if reverse { - direction = desc - } - rank, ok := db.ssetRank(key, member, direction) - if !ok { - c.WriteNull() - return - } - c.WriteInt(rank) - }) - } -} - -// ZREM -func (m *Miniredis) cmdZrem(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, members := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteInt(0) - return - } - - if db.t(key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - deleted := 0 - for _, member := range members { - if db.ssetRem(key, member) { - deleted++ - } - } - c.WriteInt(deleted) - }) -} - -// ZREMRANGEBYLEX -func (m *Miniredis) cmdZremrangebylex(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts = struct { - Key string - Min string - Max string - }{ - Key: args[0], - Min: args[1], - Max: args[2], - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - min, minIncl, minErr := parseLexrange(opts.Min) - max, maxIncl, maxErr := parseLexrange(opts.Max) - if minErr != nil || maxErr != nil { - c.WriteError(msgInvalidRangeItem) - return - } - - db := m.db(ctx.selectedDB) - - if !db.exists(opts.Key) { - c.WriteInt(0) - return - } - - if db.t(opts.Key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.ssetMembers(opts.Key) - // Just key sort. If scores are not the same we don't care. - sort.Strings(members) - members = withLexRange(members, min, minIncl, max, maxIncl) - - for _, el := range members { - db.ssetRem(opts.Key, el) - } - c.WriteInt(len(members)) - }) -} - -// ZREMRANGEBYRANK -func (m *Miniredis) cmdZremrangebyrank(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - start int - end int - } - - opts.key = args[0] - if ok := optInt(c, args[1], &opts.start); !ok { - return - } - if ok := optInt(c, args[2], &opts.end); !ok { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.key) { - c.WriteInt(0) - return - } - - if db.t(opts.key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.ssetMembers(opts.key) - rs, re := redisRange(len(members), opts.start, opts.end, false) - for _, el := range members[rs:re] { - db.ssetRem(opts.key, el) - } - c.WriteInt(re - rs) - }) -} - -// ZREMRANGEBYSCORE -func (m *Miniredis) cmdZremrangebyscore(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var ( - opts struct { - key string - min float64 - minIncl bool - max float64 - maxIncl bool - } - err error - ) - opts.key = args[0] - opts.min, opts.minIncl, err = parseFloatRange(args[1]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidMinMax) - return - } - opts.max, opts.maxIncl, err = parseFloatRange(args[2]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidMinMax) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.key) { - c.WriteInt(0) - return - } - - if db.t(opts.key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.ssetElements(opts.key) - members = withSSRange(members, opts.min, opts.minIncl, opts.max, opts.maxIncl) - - for _, el := range members { - db.ssetRem(opts.key, el.member) - } - c.WriteInt(len(members)) - }) -} - -// ZSCORE -func (m *Miniredis) cmdZscore(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, member := args[0], args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteNull() - return - } - - if db.t(key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - if !db.ssetExists(key, member) { - c.WriteNull() - return - } - - c.WriteFloat(db.ssetScore(key, member)) - }) -} - -// ZMSCORE -func (m *Miniredis) cmdZMscore(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, members := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteLen(len(members)) - for range members { - c.WriteNull() - } - return - } - - if db.t(key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - c.WriteLen(len(members)) - for _, member := range members { - if !db.ssetExists(key, member) { - c.WriteNull() - continue - } - c.WriteFloat(db.ssetScore(key, member)) - } - }) -} - -// parseFloatRange handles ZRANGEBYSCORE floats. They are inclusive unless the -// string starts with '(' -func parseFloatRange(s string) (float64, bool, error) { - if len(s) == 0 { - return 0, false, nil - } - inclusive := true - if s[0] == '(' { - s = s[1:] - inclusive = false - } - switch strings.ToLower(s) { - case "+inf": - return math.Inf(+1), true, nil - case "-inf": - return math.Inf(-1), true, nil - default: - f, err := strconv.ParseFloat(s, 64) - return f, inclusive, err - } -} - -// withSSRange limits a list of sorted set elements by the ZRANGEBYSCORE range -// logic. -func withSSRange(members ssElems, min float64, minIncl bool, max float64, maxIncl bool) ssElems { - gt := func(a, b float64) bool { return a > b } - gteq := func(a, b float64) bool { return a >= b } - - mincmp := gt - if minIncl { - mincmp = gteq - } - for i, m := range members { - if mincmp(m.score, min) { - members = members[i:] - goto checkmax - } - } - // all elements were smaller - return nil - -checkmax: - maxcmp := gteq - if maxIncl { - maxcmp = gt - } - for i, m := range members { - if maxcmp(m.score, max) { - members = members[:i] - break - } - } - - return members -} - -// withLexRange limits a list of sorted set elements. -func withLexRange(members []string, min string, minIncl bool, max string, maxIncl bool) []string { - if max == "-" || min == "+" { - return nil - } - if min != "-" { - found := false - if minIncl { - for i, m := range members { - if m >= min { - members = members[i:] - found = true - break - } - } - } else { - // Excluding min - for i, m := range members { - if m > min { - members = members[i:] - found = true - break - } - } - } - if !found { - return nil - } - } - if max != "+" { - if maxIncl { - for i, m := range members { - if m > max { - members = members[:i] - break - } - } - } else { - // Excluding max - for i, m := range members { - if m >= max { - members = members[:i] - break - } - } - } - } - return members -} - -// ZUNION -func (m *Miniredis) cmdZunion(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - numKeys, err := strconv.Atoi(args[0]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - args = args[1:] - if len(args) < numKeys { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - if numKeys <= 0 { - setDirty(c) - c.WriteError("ERR at least 1 input key is needed for ZUNION") - return - } - keys := args[:numKeys] - args = args[numKeys:] - - withScores := false - if len(args) > 0 && strings.ToUpper(args[len(args)-1]) == "WITHSCORES" { - withScores = true - args = args[:len(args)-1] - } - - opts := zunionOptions{ - Keys: keys, - WithWeights: false, - Weights: []float64{}, - Aggregate: "sum", - } - - if err := opts.parseArgs(args, numKeys); err != nil { - setDirty(c) - c.WriteError(err.Error()) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - sset, err := executeZUnion(db, opts) - if err != nil { - c.WriteError(err.Error()) - return - } - - if withScores { - c.WriteLen(len(sset) * 2) - } else { - c.WriteLen(len(sset)) - } - for _, el := range sset.byScore(asc) { - c.WriteBulk(el.member) - if withScores { - c.WriteFloat(el.score) - } - } - }) -} - -// ZUNIONSTORE -func (m *Miniredis) cmdZunionstore(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - destination := args[0] - numKeys, err := strconv.Atoi(args[1]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - args = args[2:] - if len(args) < numKeys { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - if numKeys <= 0 { - setDirty(c) - c.WriteError("ERR at least 1 input key is needed for ZUNIONSTORE/ZINTERSTORE") - return - } - keys := args[:numKeys] - args = args[numKeys:] - - opts := zunionOptions{ - Keys: keys, - WithWeights: false, - Weights: []float64{}, - Aggregate: "sum", - } - - if err := opts.parseArgs(args, numKeys); err != nil { - setDirty(c) - c.WriteError(err.Error()) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - deleteDest := true - for _, key := range keys { - if destination == key { - deleteDest = false - } - } - if deleteDest { - db.del(destination, true) - } - - sset, err := executeZUnion(db, opts) - if err != nil { - c.WriteError(err.Error()) - return - } - db.ssetSet(destination, sset) - c.WriteInt(sset.card()) - }) -} - -type zunionOptions struct { - Keys []string - WithWeights bool - Weights []float64 - Aggregate string -} - -func (opts *zunionOptions) parseArgs(args []string, numKeys int) error { - for len(args) > 0 { - switch strings.ToLower(args[0]) { - case "weights": - if len(args) < numKeys+1 { - return errors.New(msgSyntaxError) - } - for i := 0; i < numKeys; i++ { - f, err := strconv.ParseFloat(args[i+1], 64) - if err != nil { - return errors.New("ERR weight value is not a float") - } - opts.Weights = append(opts.Weights, f) - } - opts.WithWeights = true - args = args[numKeys+1:] - case "aggregate": - if len(args) < 2 { - return errors.New(msgSyntaxError) - } - opts.Aggregate = strings.ToLower(args[1]) - switch opts.Aggregate { - default: - return errors.New(msgSyntaxError) - case "sum", "min", "max": - } - args = args[2:] - default: - return errors.New(msgSyntaxError) - } - } - return nil -} - -func executeZUnion(db *RedisDB, opts zunionOptions) (sortedSet, error) { - sset := sortedSet{} - for i, key := range opts.Keys { - if !db.exists(key) { - continue - } - - var set map[string]float64 - switch db.t(key) { - case "set": - set = map[string]float64{} - for elem := range db.setKeys[key] { - set[elem] = 1.0 - } - case "zset": - set = db.sortedSet(key) - default: - return nil, errors.New(msgWrongType) - } - - for member, score := range set { - if opts.WithWeights { - score *= opts.Weights[i] - } - old, ok := sset[member] - if !ok { - sset[member] = score - continue - } - switch opts.Aggregate { - default: - panic("Invalid aggregate") - case "sum": - sset[member] += score - case "min": - if score < old { - sset[member] = score - } - case "max": - if score > old { - sset[member] = score - } - } - } - } - - return sset, nil -} - -// ZSCAN -func (m *Miniredis) cmdZscan(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - cursor int - withMatch bool - match string - } - - opts.key = args[0] - if ok := optIntErr(c, args[1], &opts.cursor, msgInvalidCursor); !ok { - return - } - args = args[2:] - // MATCH and COUNT options - for len(args) > 0 { - if strings.ToLower(args[0]) == "count" { - if len(args) < 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - if _, err := strconv.Atoi(args[1]); err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - // We do nothing with count. - args = args[2:] - continue - } - if strings.ToLower(args[0]) == "match" { - if len(args) < 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - opts.withMatch = true - opts.match = args[1] - args = args[2:] - continue - } - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - // Paging is not implementend, all results are returned for cursor 0. - if opts.cursor != 0 { - // Invalid cursor. - c.WriteLen(2) - c.WriteBulk("0") // no next cursor - c.WriteLen(0) // no elements - return - } - if db.exists(opts.key) && db.t(opts.key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.ssetMembers(opts.key) - if opts.withMatch { - members, _ = matchKeys(members, opts.match) - } - - c.WriteLen(2) - c.WriteBulk("0") // no next cursor - // HSCAN gives key, values. - c.WriteLen(len(members) * 2) - for _, k := range members { - c.WriteBulk(k) - c.WriteFloat(db.ssetScore(opts.key, k)) - } - }) -} - -// ZPOPMAX and ZPOPMIN -func (m *Miniredis) cmdZpopmax(reverse bool) server.Cmd { - return func(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - - key := args[0] - count := 1 - var err error - if len(args) > 1 { - count, err = strconv.Atoi(args[1]) - if err != nil || count < 0 { - setDirty(c) - c.WriteError(msgInvalidRange) - return - } - } - - withScores := true - if len(args) > 2 { - c.WriteError(msgSyntaxError) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteLen(0) - return - } - - if db.t(key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.ssetMembers(key) - if reverse { - reverseSlice(members) - } - rs, re := redisRange(len(members), 0, count-1, false) - if withScores { - c.WriteLen((re - rs) * 2) - } else { - c.WriteLen(re - rs) - } - for _, el := range members[rs:re] { - c.WriteBulk(el) - if withScores { - c.WriteFloat(db.ssetScore(key, el)) - } - db.ssetRem(key, el) - } - }) - } -} - -// ZRANDMEMBER -func (m *Miniredis) cmdZrandmember(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - withCount bool - count int - withScores bool - } - - opts.key = args[0] - args = args[1:] - - if len(args) > 0 { - // can be negative - if ok := optInt(c, args[0], &opts.count); !ok { - return - } - opts.withCount = true - args = args[1:] - } - - if len(args) > 0 && strings.ToUpper(args[0]) == "WITHSCORES" { - opts.withScores = true - args = args[1:] - } - - if len(args) > 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.key) { - if opts.withCount { - c.WriteLen(0) - } else { - c.WriteNull() - } - return - } - - if db.t(opts.key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - if !opts.withCount { - member := db.ssetRandomMember(opts.key) - if member == "" { - c.WriteNull() - return - } - c.WriteBulk(member) - return - } - - var members []string - switch { - case opts.count == 0: - c.WriteStrings(nil) - return - case opts.count > 0: - allMembers := db.ssetMembers(opts.key) - db.master.shuffle(allMembers) - if len(allMembers) > opts.count { - allMembers = allMembers[:opts.count] - } - members = allMembers - case opts.count < 0: - for i := 0; i < -opts.count; i++ { - members = append(members, db.ssetRandomMember(opts.key)) - } - } - if opts.withScores { - c.WriteLen(len(members) * 2) - for _, m := range members { - c.WriteBulk(m) - c.WriteFloat(db.ssetScore(opts.key, m)) - } - return - } - c.WriteStrings(members) - }) -} - -type optsRange struct { - Key string - Min string - Max string - Reverse bool - WithScores bool -} - -func runRange(m *Miniredis, c *server.Peer, cctx *connCtx, opts optsRange) { - min, minErr := strconv.Atoi(opts.Min) - max, maxErr := strconv.Atoi(opts.Max) - if minErr != nil || maxErr != nil { - c.WriteError(msgInvalidInt) - return - } - - db := m.db(cctx.selectedDB) - - if !db.exists(opts.Key) { - c.WriteLen(0) - return - } - - if db.t(opts.Key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.ssetMembers(opts.Key) - if opts.Reverse { - reverseSlice(members) - } - rs, re := redisRange(len(members), min, max, false) - if opts.WithScores { - c.WriteLen((re - rs) * 2) - } else { - c.WriteLen(re - rs) - } - for _, el := range members[rs:re] { - c.WriteBulk(el) - if opts.WithScores { - c.WriteFloat(db.ssetScore(opts.Key, el)) - } - } -} - -type optsRangeByScore struct { - Key string - Min string - Max string - Reverse bool - WithLimit bool - Offset string - Count string - WithScores bool -} - -func runRangeByScore(m *Miniredis, c *server.Peer, cctx *connCtx, opts optsRangeByScore) { - var limitOffset, limitCount int - var err error - if opts.WithLimit { - limitOffset, err = strconv.Atoi(opts.Offset) - if err != nil { - c.WriteError(msgInvalidInt) - return - } - limitCount, err = strconv.Atoi(opts.Count) - if err != nil { - c.WriteError(msgInvalidInt) - return - } - } - min, minIncl, minErr := parseFloatRange(opts.Min) - max, maxIncl, maxErr := parseFloatRange(opts.Max) - if minErr != nil || maxErr != nil { - c.WriteError(msgInvalidMinMax) - return - } - - db := m.db(cctx.selectedDB) - - if !db.exists(opts.Key) { - c.WriteLen(0) - return - } - - if db.t(opts.Key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.ssetElements(opts.Key) - if opts.Reverse { - min, max = max, min - minIncl, maxIncl = maxIncl, minIncl - } - members = withSSRange(members, min, minIncl, max, maxIncl) - if opts.Reverse { - reverseElems(members) - } - - // Apply LIMIT ranges. That's . Unlike RANGE. - if opts.WithLimit { - if limitOffset < 0 { - members = ssElems{} - } else { - if limitOffset < len(members) { - members = members[limitOffset:] - } else { - // out of range - members = ssElems{} - } - if limitCount >= 0 { - if len(members) > limitCount { - members = members[:limitCount] - } - } - } - } - - if opts.WithScores { - c.WriteLen(len(members) * 2) - } else { - c.WriteLen(len(members)) - } - for _, el := range members { - c.WriteBulk(el.member) - if opts.WithScores { - c.WriteFloat(el.score) - } - } -} - -type optsRangeByLex struct { - Key string - Min string - Max string - Reverse bool - WithLimit bool - Offset string - Count string - WithScores bool -} - -func runRangeByLex(m *Miniredis, c *server.Peer, cctx *connCtx, opts optsRangeByLex) { - var limitOffset, limitCount int - var err error - if opts.WithLimit { - limitOffset, err = strconv.Atoi(opts.Offset) - if err != nil { - c.WriteError(msgInvalidInt) - return - } - limitCount, err = strconv.Atoi(opts.Count) - if err != nil { - c.WriteError(msgInvalidInt) - return - } - } - min, minIncl, minErr := parseLexrange(opts.Min) - max, maxIncl, maxErr := parseLexrange(opts.Max) - if minErr != nil || maxErr != nil { - c.WriteError(msgInvalidRangeItem) - return - } - - db := m.db(cctx.selectedDB) - - if !db.exists(opts.Key) { - c.WriteLen(0) - return - } - - if db.t(opts.Key) != "zset" { - c.WriteError(ErrWrongType.Error()) - return - } - - members := db.ssetMembers(opts.Key) - // Just key sort. If scores are not the same we don't care. - sort.Strings(members) - if opts.Reverse { - min, max = max, min - minIncl, maxIncl = maxIncl, minIncl - } - members = withLexRange(members, min, minIncl, max, maxIncl) - if opts.Reverse { - reverseSlice(members) - } - - // Apply LIMIT ranges. That's . Unlike RANGE. - if opts.WithLimit { - if limitOffset < 0 { - members = nil - } else { - if limitOffset < len(members) { - members = members[limitOffset:] - } else { - // out of range - members = nil - } - if limitCount >= 0 { - if len(members) > limitCount { - members = members[:limitCount] - } - } - } - } - - c.WriteLen(len(members)) - for _, el := range members { - c.WriteBulk(el) - } -} - -// optLexrange handles ZRANGE{,BYLEX} ranges. They start with '[', '(', or are -// '+' or '-'. -// Sets destValue and destInclusive. destValue can be '+' or '-'. -func parseLexrange(s string) (string, bool, error) { - if len(s) == 0 { - return "", false, errors.New(msgInvalidRangeItem) - } - - if s == "+" || s == "-" { - return s, false, nil - } - - switch s[0] { - case '(': - return s[1:], false, nil - case '[': - return s[1:], true, nil - default: - return "", false, errors.New(msgInvalidRangeItem) - } -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_stream.go b/vendor/github.com/alicebob/miniredis/v2/cmd_stream.go deleted file mode 100644 index 9e7613814..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_stream.go +++ /dev/null @@ -1,1798 +0,0 @@ -// Commands from https://redis.io/commands#stream - -package miniredis - -import ( - "errors" - "fmt" - "sort" - "strconv" - "strings" - "time" - - "github.com/alicebob/miniredis/v2/server" -) - -// commandsStream handles all stream operations. -func commandsStream(m *Miniredis) { - m.srv.Register("XADD", m.cmdXadd) - m.srv.Register("XLEN", m.cmdXlen) - m.srv.Register("XREAD", m.cmdXread) - m.srv.Register("XRANGE", m.makeCmdXrange(false)) - m.srv.Register("XREVRANGE", m.makeCmdXrange(true)) - m.srv.Register("XGROUP", m.cmdXgroup) - m.srv.Register("XINFO", m.cmdXinfo) - m.srv.Register("XREADGROUP", m.cmdXreadgroup) - m.srv.Register("XACK", m.cmdXack) - m.srv.Register("XDEL", m.cmdXdel) - m.srv.Register("XPENDING", m.cmdXpending) - m.srv.Register("XTRIM", m.cmdXtrim) - m.srv.Register("XAUTOCLAIM", m.cmdXautoclaim) - m.srv.Register("XCLAIM", m.cmdXclaim) -} - -// XADD -func (m *Miniredis) cmdXadd(c *server.Peer, cmd string, args []string) { - if len(args) < 4 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, args := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - maxlen := -1 - minID := "" - if strings.ToLower(args[0]) == "maxlen" { - args = args[1:] - // we don't treat "~" special - if args[0] == "~" { - args = args[1:] - } - n, err := strconv.Atoi(args[0]) - if err != nil { - c.WriteError(msgInvalidInt) - return - } - if n < 0 { - c.WriteError("ERR The MAXLEN argument must be >= 0.") - return - } - maxlen = n - args = args[1:] - } else if strings.ToLower(args[0]) == "minid" { - args = args[1:] - // we don't treat "~" special - if args[0] == "~" { - args = args[1:] - } - minID = args[0] - args = args[1:] - } - if len(args) < 1 { - c.WriteError(errWrongNumber(cmd)) - return - } - entryID, args := args[0], args[1:] - - // args must be composed of field/value pairs. - if len(args) == 0 || len(args)%2 != 0 { - c.WriteError("ERR wrong number of arguments for XADD") // non-default message - return - } - - var values []string - for len(args) > 0 { - values = append(values, args[0], args[1]) - args = args[2:] - } - - db := m.db(ctx.selectedDB) - s, err := db.stream(key) - if err != nil { - c.WriteError(err.Error()) - return - } - if s == nil { - // TODO: NOMKSTREAM - s, _ = db.newStream(key) - } - - newID, err := s.add(entryID, values, m.effectiveNow()) - if err != nil { - switch err { - case errInvalidEntryID: - c.WriteError(msgInvalidStreamID) - default: - c.WriteError(err.Error()) - } - return - } - if maxlen >= 0 { - s.trim(maxlen) - } - if minID != "" { - s.trimBefore(minID) - } - db.keyVersion[key]++ - - c.WriteBulk(newID) - }) -} - -// XLEN -func (m *Miniredis) cmdXlen(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - s, err := db.stream(key) - if err != nil { - c.WriteError(err.Error()) - } - if s == nil { - // No such key. That's zero length. - c.WriteInt(0) - return - } - - c.WriteInt(len(s.entries)) - }) -} - -// XRANGE and XREVRANGE -func (m *Miniredis) makeCmdXrange(reverse bool) server.Cmd { - return func(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if len(args) == 4 || len(args) > 5 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - opts := struct { - key string - startKey string - startExclusive bool - endKey string - endExclusive bool - }{ - key: args[0], - startKey: args[1], - endKey: args[2], - } - if strings.HasPrefix(opts.startKey, "(") { - opts.startExclusive = true - opts.startKey = opts.startKey[1:] - if opts.startKey == "-" || opts.startKey == "+" { - setDirty(c) - c.WriteError(msgInvalidStreamID) - return - } - } - if strings.HasPrefix(opts.endKey, "(") { - opts.endExclusive = true - opts.endKey = opts.endKey[1:] - if opts.endKey == "-" || opts.endKey == "+" { - setDirty(c) - c.WriteError(msgInvalidStreamID) - return - } - } - - countArg := "0" - if len(args) == 5 { - if strings.ToLower(args[3]) != "count" { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - countArg = args[4] - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - start, err := formatStreamRangeBound(opts.startKey, true, reverse) - if err != nil { - c.WriteError(msgInvalidStreamID) - return - } - end, err := formatStreamRangeBound(opts.endKey, false, reverse) - if err != nil { - c.WriteError(msgInvalidStreamID) - return - } - count, err := strconv.Atoi(countArg) - if err != nil { - c.WriteError(msgInvalidInt) - return - } - - db := m.db(ctx.selectedDB) - - if !db.exists(opts.key) { - c.WriteLen(0) - return - } - - if db.t(opts.key) != "stream" { - c.WriteError(ErrWrongType.Error()) - return - } - - var entries = db.streamKeys[opts.key].entries - if reverse { - entries = reversedStreamEntries(entries) - } - if count == 0 { - count = len(entries) - } - - var returnedEntries []StreamEntry - for _, entry := range entries { - if len(returnedEntries) == count { - break - } - - if !reverse { - // Break if entry ID > end - if streamCmp(entry.ID, end) == 1 { - break - } - - // Continue if entry ID < start - if streamCmp(entry.ID, start) == -1 { - continue - } - } else { - // Break if entry iD < end - if streamCmp(entry.ID, end) == -1 { - break - } - - // Continue if entry ID > start. - if streamCmp(entry.ID, start) == 1 { - continue - } - } - - // Continue if start exclusive and entry ID == start - if opts.startExclusive && streamCmp(entry.ID, start) == 0 { - continue - } - // Continue if end exclusive and entry ID == end - if opts.endExclusive && streamCmp(entry.ID, end) == 0 { - continue - } - - returnedEntries = append(returnedEntries, entry) - } - - c.WriteLen(len(returnedEntries)) - for _, entry := range returnedEntries { - c.WriteLen(2) - c.WriteBulk(entry.ID) - c.WriteLen(len(entry.Values)) - for _, v := range entry.Values { - c.WriteBulk(v) - } - } - }) - } -} - -// XGROUP -func (m *Miniredis) cmdXgroup(c *server.Peer, cmd string, args []string) { - if len(args) == 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - subCmd, args := strings.ToLower(args[0]), args[1:] - switch subCmd { - case "create": - m.cmdXgroupCreate(c, cmd, args) - case "destroy": - m.cmdXgroupDestroy(c, cmd, args) - case "createconsumer": - m.cmdXgroupCreateconsumer(c, cmd, args) - case "delconsumer": - m.cmdXgroupDelconsumer(c, cmd, args) - case "help", - "setid": - err := fmt.Sprintf("ERR 'XGROUP %s' not supported", subCmd) - setDirty(c) - c.WriteError(err) - default: - setDirty(c) - c.WriteError(fmt.Sprintf( - "ERR unknown subcommand '%s'. Try XGROUP HELP.", - subCmd, - )) - } -} - -// XGROUP CREATE -func (m *Miniredis) cmdXgroupCreate(c *server.Peer, cmd string, args []string) { - if len(args) != 3 && len(args) != 4 { - setDirty(c) - c.WriteError(errWrongNumber("CREATE")) - return - } - stream, group, id := args[0], args[1], args[2] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - s, err := db.stream(stream) - if err != nil { - c.WriteError(err.Error()) - return - } - if s == nil && len(args) == 4 && strings.ToUpper(args[3]) == "MKSTREAM" { - if s, err = db.newStream(stream); err != nil { - c.WriteError(err.Error()) - return - } - } - if s == nil { - c.WriteError(msgXgroupKeyNotFound) - return - } - - if err := s.createGroup(group, id); err != nil { - c.WriteError(err.Error()) - return - } - - c.WriteOK() - }) -} - -// XGROUP DESTROY -func (m *Miniredis) cmdXgroupDestroy(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber("DESTROY")) - return - } - stream, groupName := args[0], args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - s, err := db.stream(stream) - if err != nil { - c.WriteError(err.Error()) - return - } - if s == nil { - c.WriteError(msgXgroupKeyNotFound) - return - } - - if _, ok := s.groups[groupName]; !ok { - c.WriteInt(0) - return - } - delete(s.groups, groupName) - c.WriteInt(1) - }) -} - -// XGROUP CREATECONSUMER -func (m *Miniredis) cmdXgroupCreateconsumer(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber("CREATECONSUMER")) - return - } - key, groupName, consumerName := args[0], args[1], args[2] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - s, err := db.stream(key) - if err != nil { - c.WriteError(err.Error()) - return - } - if s == nil { - c.WriteError(msgXgroupKeyNotFound) - return - } - - g, ok := s.groups[groupName] - if !ok { - err := fmt.Sprintf("NOGROUP No such consumer group '%s' for key name '%s'", groupName, key) - c.WriteError(err) - return - } - - if _, ok = g.consumers[consumerName]; ok { - c.WriteInt(0) - return - } - g.consumers[consumerName] = &consumer{} - c.WriteInt(1) - }) -} - -// XGROUP DELCONSUMER -func (m *Miniredis) cmdXgroupDelconsumer(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber("DELCONSUMER")) - return - } - key, groupName, consumerName := args[0], args[1], args[2] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - s, err := db.stream(key) - if err != nil { - c.WriteError(err.Error()) - return - } - if s == nil { - c.WriteError(msgXgroupKeyNotFound) - return - } - - g, ok := s.groups[groupName] - if !ok { - err := fmt.Sprintf("NOGROUP No such consumer group '%s' for key name '%s'", groupName, key) - c.WriteError(err) - return - } - - consumer, ok := g.consumers[consumerName] - if !ok { - c.WriteInt(0) - return - } - defer delete(g.consumers, consumerName) - - if consumer.numPendingEntries > 0 { - newPending := make([]pendingEntry, 0) - for _, entry := range g.pending { - if entry.consumer != consumerName { - newPending = append(newPending, entry) - } - } - g.pending = newPending - } - c.WriteInt(consumer.numPendingEntries) - }) -} - -// XINFO -func (m *Miniredis) cmdXinfo(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - subCmd, args := strings.ToUpper(args[0]), args[1:] - switch subCmd { - case "STREAM": - m.cmdXinfoStream(c, args) - case "CONSUMERS": - m.cmdXinfoConsumers(c, args) - case "GROUPS": - m.cmdXinfoGroups(c, args) - case "HELP": - err := fmt.Sprintf("'XINFO %s' not supported", strings.Join(args, " ")) - setDirty(c) - c.WriteError(err) - default: - setDirty(c) - c.WriteError(fmt.Sprintf( - "ERR unknown subcommand or wrong number of arguments for '%s'. Try XINFO HELP.", - subCmd, - )) - } -} - -// XINFO STREAM -// Produces only part of full command output -func (m *Miniredis) cmdXinfoStream(c *server.Peer, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber("STREAM")) - return - } - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - s, err := db.stream(key) - if err != nil { - c.WriteError(err.Error()) - return - } - if s == nil { - c.WriteError(msgKeyNotFound) - return - } - - c.WriteMapLen(1) - c.WriteBulk("length") - c.WriteInt(len(s.entries)) - }) -} - -// XINFO GROUPS -func (m *Miniredis) cmdXinfoGroups(c *server.Peer, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber("GROUPS")) - return - } - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - s, err := db.stream(key) - if err != nil { - c.WriteError(err.Error()) - return - } - if s == nil { - c.WriteError(msgKeyNotFound) - return - } - - c.WriteLen(len(s.groups)) - for name, g := range s.groups { - c.WriteMapLen(6) - - c.WriteBulk("name") - c.WriteBulk(name) - c.WriteBulk("consumers") - c.WriteInt(len(g.consumers)) - c.WriteBulk("pending") - c.WriteInt(len(g.activePending())) - c.WriteBulk("last-delivered-id") - c.WriteBulk(g.lastID) - c.WriteBulk("entries-read") - c.WriteNull() - c.WriteBulk("lag") - c.WriteInt(len(g.stream.entries)) - } - }) -} - -// XINFO CONSUMERS -// Please note that this is only a partial implementation, for it does not -// return each consumer's "idle" value, which indicates "the number of -// milliseconds that have passed since the consumer last interacted with the -// server." -func (m *Miniredis) cmdXinfoConsumers(c *server.Peer, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber("CONSUMERS")) - return - } - key := args[0] - groupName := args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - s, err := db.stream(key) - if err != nil { - c.WriteError(err.Error()) - return - } - if s == nil { - c.WriteError(msgKeyNotFound) - return - } - - g, ok := s.groups[groupName] - if !ok { - err := fmt.Sprintf("NOGROUP No such consumer group '%s' for key name '%s'", groupName, key) - c.WriteError(err) - return - } - - consumerNames := make([]string, 0) - for name := range g.consumers { - consumerNames = append(consumerNames, name) - } - sort.Strings(consumerNames) - - c.WriteLen(len(consumerNames)) - for _, name := range consumerNames { - c.WriteMapLen(2) - - c.WriteBulk("name") - c.WriteBulk(name) - - c.WriteBulk("pending") - c.WriteInt(g.consumers[name].numPendingEntries) - } - }) -} - -// XREADGROUP -func (m *Miniredis) cmdXreadgroup(c *server.Peer, cmd string, args []string) { - // XREADGROUP GROUP group consumer STREAMS key ID - if len(args) < 6 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - group string - consumer string - count int - noack bool - streams []string - ids []string - block bool - blockTimeout time.Duration - } - - if strings.ToUpper(args[0]) != "GROUP" { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - - opts.group, opts.consumer, args = args[1], args[2], args[3:] - - var err error -parsing: - for len(args) > 0 { - switch strings.ToUpper(args[0]) { - case "COUNT": - if len(args) < 2 { - err = errors.New(errWrongNumber(cmd)) - break parsing - } - - opts.count, err = strconv.Atoi(args[1]) - if err != nil { - break parsing - } - - args = args[2:] - case "BLOCK": - err = parseBlock(cmd, args, &opts.block, &opts.blockTimeout) - if err != nil { - break parsing - } - args = args[2:] - case "NOACK": - args = args[1:] - opts.noack = true - case "STREAMS": - args = args[1:] - - if len(args)%2 != 0 { - err = errors.New(msgXreadUnbalanced) - break parsing - } - - opts.streams, opts.ids = args[0:len(args)/2], args[len(args)/2:] - break parsing - default: - err = fmt.Errorf("ERR incorrect argument %s", args[0]) - break parsing - } - } - - if err != nil { - setDirty(c) - c.WriteError(err.Error()) - return - } - - if len(opts.streams) == 0 || len(opts.ids) == 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - - for _, id := range opts.ids { - if id != `>` { - opts.block = false - } - } - - if !opts.block { - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - res, err := xreadgroup( - db, - opts.group, - opts.consumer, - opts.noack, - opts.streams, - opts.ids, - opts.count, - m.effectiveNow(), - ) - if err != nil { - c.WriteError(err.Error()) - return - } - writeXread(c, opts.streams, res) - }) - return - } - - blocking( - m, - c, - opts.blockTimeout, - func(c *server.Peer, ctx *connCtx) bool { - if ctx.nested { - setDirty(c) - c.WriteError("ERR XREADGROUP command is not allowed with BLOCK option from scripts") - return false - } - - db := m.db(ctx.selectedDB) - res, err := xreadgroup( - db, - opts.group, - opts.consumer, - opts.noack, - opts.streams, - opts.ids, - opts.count, - m.effectiveNow(), - ) - if err != nil { - c.WriteError(err.Error()) - return true - } - if len(res) == 0 { - return false - } - writeXread(c, opts.streams, res) - return true - }, - func(c *server.Peer) { // timeout - c.WriteLen(-1) - }, - ) -} - -func xreadgroup( - db *RedisDB, - group, - consumer string, - noack bool, - streams []string, - ids []string, - count int, - now time.Time, -) (map[string][]StreamEntry, error) { - res := map[string][]StreamEntry{} - for i, key := range streams { - id := ids[i] - - g, err := db.streamGroup(key, group) - if err != nil { - return nil, err - } - if g == nil { - return nil, errXreadgroup(key, group) - } - - if _, err := parseStreamID(id); id != `>` && err != nil { - return nil, err - } - entries := g.readGroup(now, consumer, id, count, noack) - if id == `>` && len(entries) == 0 { - continue - } - - res[key] = entries - } - return res, nil -} - -// XACK -func (m *Miniredis) cmdXack(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, group, ids := args[0], args[1], args[2:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - g, err := db.streamGroup(key, group) - if err != nil { - c.WriteError(err.Error()) - return - } - if g == nil { - c.WriteInt(0) - return - } - - cnt, err := g.ack(ids) - if err != nil { - c.WriteError(err.Error()) - return - } - c.WriteInt(cnt) - }) -} - -// XDEL -func (m *Miniredis) cmdXdel(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - stream, ids := args[0], args[1:] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - s, err := db.stream(stream) - if err != nil { - c.WriteError(err.Error()) - return - } - if s == nil { - c.WriteInt(0) - return - } - - n, err := s.delete(ids) - if err != nil { - c.WriteError(err.Error()) - return - } - db.keyVersion[stream]++ - c.WriteInt(n) - }) -} - -// XREAD -func (m *Miniredis) cmdXread(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var ( - opts struct { - count int - streams []string - ids []string - block bool - blockTimeout time.Duration - } - err error - ) - -parsing: - for len(args) > 0 { - switch strings.ToUpper(args[0]) { - case "COUNT": - if len(args) < 2 { - err = errors.New(errWrongNumber(cmd)) - break parsing - } - - opts.count, err = strconv.Atoi(args[1]) - if err != nil { - break parsing - } - args = args[2:] - case "BLOCK": - err = parseBlock(cmd, args, &opts.block, &opts.blockTimeout) - if err != nil { - break parsing - } - args = args[2:] - case "STREAMS": - args = args[1:] - - if len(args)%2 != 0 { - err = errors.New(msgXreadUnbalanced) - break parsing - } - - opts.streams, opts.ids = args[0:len(args)/2], args[len(args)/2:] - for i, id := range opts.ids { - if _, err := parseStreamID(id); id != `$` && err != nil { - setDirty(c) - c.WriteError(msgInvalidStreamID) - return - } else if id == "$" { - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(getCtx(c).selectedDB) - stream, ok := db.streamKeys[opts.streams[i]] - if ok { - opts.ids[i] = stream.lastID() - } else { - opts.ids[i] = "0-0" - } - }) - } - } - args = nil - break parsing - default: - err = fmt.Errorf("ERR incorrect argument %s", args[0]) - break parsing - } - } - if err != nil { - setDirty(c) - c.WriteError(err.Error()) - return - } - - if !opts.block { - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - res := xread(db, opts.streams, opts.ids, opts.count) - writeXread(c, opts.streams, res) - }) - return - } - blocking( - m, - c, - opts.blockTimeout, - func(c *server.Peer, ctx *connCtx) bool { - if ctx.nested { - setDirty(c) - c.WriteError("ERR XREAD command is not allowed with BLOCK option from scripts") - return false - } - - db := m.db(ctx.selectedDB) - res := xread(db, opts.streams, opts.ids, opts.count) - if len(res) == 0 { - return false - } - writeXread(c, opts.streams, res) - return true - }, - func(c *server.Peer) { // timeout - c.WriteLen(-1) - }, - ) -} - -func xread(db *RedisDB, streams []string, ids []string, count int) map[string][]StreamEntry { - res := map[string][]StreamEntry{} - for i := range streams { - stream := streams[i] - id := ids[i] - - var s, ok = db.streamKeys[stream] - if !ok { - continue - } - entries := s.entries - if len(entries) == 0 { - continue - } - - entryCount := count - if entryCount == 0 { - entryCount = len(entries) - } - - var returnedEntries []StreamEntry - for _, entry := range entries { - if len(returnedEntries) == entryCount { - break - } - if id == "$" { - id = s.lastID() - } - if streamCmp(entry.ID, id) <= 0 { - continue - } - returnedEntries = append(returnedEntries, entry) - } - if len(returnedEntries) > 0 { - res[stream] = returnedEntries - } - } - return res -} - -func writeXread(c *server.Peer, streams []string, res map[string][]StreamEntry) { - if len(res) == 0 { - c.WriteLen(-1) - return - } - c.WriteLen(len(res)) - for _, stream := range streams { - entries, ok := res[stream] - if !ok { - continue - } - c.WriteLen(2) - c.WriteBulk(stream) - c.WriteLen(len(entries)) - for _, entry := range entries { - c.WriteLen(2) - c.WriteBulk(entry.ID) - c.WriteLen(len(entry.Values)) - for _, v := range entry.Values { - c.WriteBulk(v) - } - } - } -} - -// XPENDING -func (m *Miniredis) cmdXpending(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - group string - summary bool - idle time.Duration - start, end string - count int - consumer *string - } - - opts.key, opts.group, args = args[0], args[1], args[2:] - opts.summary = true - if len(args) >= 3 { - opts.summary = false - - if strings.ToUpper(args[0]) == "IDLE" { - idleMs, err := strconv.ParseInt(args[1], 10, 64) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - opts.idle = time.Duration(idleMs) * time.Millisecond - - args = args[2:] - if len(args) < 3 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - } - - var err error - opts.start, err = formatStreamRangeBound(args[0], true, false) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidStreamID) - return - } - opts.end, err = formatStreamRangeBound(args[1], false, false) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidStreamID) - return - } - opts.count, err = strconv.Atoi(args[2]) // negative is allowed - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - args = args[3:] - - if len(args) == 1 { - opts.consumer, args = &args[0], args[1:] - } - } - if len(args) != 0 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - g, err := db.streamGroup(opts.key, opts.group) - if err != nil { - c.WriteError(err.Error()) - return - } - if g == nil { - c.WriteError(errReadgroup(opts.key, opts.group).Error()) - return - } - - if opts.summary { - writeXpendingSummary(c, *g) - return - } - writeXpending(m.effectiveNow(), c, *g, opts.idle, opts.start, opts.end, opts.count, opts.consumer) - }) -} - -func writeXpendingSummary(c *server.Peer, g streamGroup) { - pend := g.activePending() - if len(pend) == 0 { - c.WriteLen(4) - c.WriteInt(0) - c.WriteNull() - c.WriteNull() - c.WriteLen(-1) - return - } - - // format: - // - number of pending - // - smallest ID - // - highest ID - // - all consumers with > 0 pending items - c.WriteLen(4) - c.WriteInt(len(pend)) - c.WriteBulk(pend[0].id) - c.WriteBulk(pend[len(pend)-1].id) - cons := map[string]int{} - for id := range g.consumers { - cnt := g.pendingCount(id) - if cnt > 0 { - cons[id] = cnt - } - } - c.WriteLen(len(cons)) - var ids []string - for id := range cons { - ids = append(ids, id) - } - sort.Strings(ids) // be predicatable - for _, id := range ids { - c.WriteLen(2) - c.WriteBulk(id) - c.WriteBulk(strconv.Itoa(cons[id])) - } -} - -func writeXpending( - now time.Time, - c *server.Peer, - g streamGroup, - idle time.Duration, - start, - end string, - count int, - consumer *string, -) { - if len(g.pending) == 0 || count < 0 { - c.WriteLen(-1) - return - } - - // format, list of: - // - message ID - // - consumer - // - milliseconds since delivery - // - delivery count - type entry struct { - id string - consumer string - millis int - count int - } - var res []entry - for _, p := range g.pending { - if len(res) >= count { - break - } - if consumer != nil && p.consumer != *consumer { - continue - } - if streamCmp(p.id, start) < 0 { - continue - } - if streamCmp(p.id, end) > 0 { - continue - } - timeSinceLastDelivery := now.Sub(p.lastDelivery) - if timeSinceLastDelivery >= idle { - res = append(res, entry{ - id: p.id, - consumer: p.consumer, - millis: int(timeSinceLastDelivery.Milliseconds()), - count: p.deliveryCount, - }) - } - } - if len(res) == 0 { - c.WriteLen(-1) - return - } - c.WriteLen(len(res)) - for _, e := range res { - c.WriteLen(4) - c.WriteBulk(e.id) - c.WriteBulk(e.consumer) - c.WriteInt(e.millis) - c.WriteInt(e.count) - } -} - -// XTRIM -func (m *Miniredis) cmdXtrim(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - stream string - strategy string - maxLen int // for MAXLEN - threshold string // for MINID - withLimit bool // "LIMIT" - withExact bool // "=" - withNearly bool // "~" - } - - opts.stream, opts.strategy, args = args[0], strings.ToUpper(args[1]), args[2:] - - if opts.strategy != "MAXLEN" && opts.strategy != "MINID" { - setDirty(c) - c.WriteError(msgXtrimInvalidStrategy) - return - } - - // Ignore nearly exact trimming parameters. - switch args[0] { - case "=": - opts.withExact = true - args = args[1:] - case "~": - opts.withNearly = true - args = args[1:] - } - - switch opts.strategy { - case "MAXLEN": - maxLen, err := strconv.Atoi(args[0]) - if err != nil { - setDirty(c) - c.WriteError(msgXtrimInvalidMaxLen) - return - } - opts.maxLen = maxLen - case "MINID": - opts.threshold = args[0] - } - args = args[1:] - - if len(args) == 2 && strings.ToUpper(args[0]) == "LIMIT" { - // Ignore LIMIT. - opts.withLimit = true - if _, err := strconv.Atoi(args[1]); err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - - args = args[2:] - } - - if len(args) != 0 { - setDirty(c) - c.WriteError(fmt.Sprintf("ERR incorrect argument %s", args[0])) - return - } - - if opts.withLimit && !opts.withNearly { - setDirty(c) - c.WriteError(fmt.Sprintf(msgXtrimInvalidLimit)) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - s, err := db.stream(opts.stream) - if err != nil { - setDirty(c) - c.WriteError(err.Error()) - return - } - if s == nil { - c.WriteInt(0) - return - } - - switch opts.strategy { - case "MAXLEN": - entriesBefore := len(s.entries) - s.trim(opts.maxLen) - c.WriteInt(entriesBefore - len(s.entries)) - case "MINID": - n := s.trimBefore(opts.threshold) - c.WriteInt(n) - } - }) -} - -// XAUTOCLAIM -func (m *Miniredis) cmdXautoclaim(c *server.Peer, cmd string, args []string) { - // XAUTOCLAIM key group consumer min-idle-time start - if len(args) < 5 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - group string - consumer string - minIdleTime time.Duration - start string - justId bool - count int - } - - opts.key, opts.group, opts.consumer = args[0], args[1], args[2] - n, err := strconv.Atoi(args[3]) - if err != nil { - setDirty(c) - c.WriteError("ERR Invalid min-idle-time argument for XAUTOCLAIM") - return - } - opts.minIdleTime = time.Millisecond * time.Duration(n) - - start_, err := formatStreamRangeBound(args[4], true, false) - if err != nil { - c.WriteError(msgInvalidStreamID) - return - } - opts.start = start_ - - args = args[5:] - - opts.count = 100 -parsing: - for len(args) > 0 { - switch strings.ToUpper(args[0]) { - case "COUNT": - if len(args) < 2 { - err = errors.New(errWrongNumber(cmd)) - break parsing - } - - opts.count, err = strconv.Atoi(args[1]) - if err != nil { - break parsing - } - - args = args[2:] - case "JUSTID": - args = args[1:] - opts.justId = true - default: - err = errors.New(msgSyntaxError) - break parsing - } - } - - if err != nil { - setDirty(c) - c.WriteError(err.Error()) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - g, err := db.streamGroup(opts.key, opts.group) - if err != nil { - c.WriteError(err.Error()) - return - } - if g == nil { - c.WriteError(errReadgroup(opts.key, opts.group).Error()) - return - } - - nextCallId, entries := xautoclaim(m.effectiveNow(), *g, opts.minIdleTime, opts.start, opts.count, opts.consumer) - writeXautoclaim(c, nextCallId, entries, opts.justId) - }) -} - -func xautoclaim( - now time.Time, - g streamGroup, - minIdleTime time.Duration, - start string, - count int, - consumerID string, -) (string, []StreamEntry) { - nextCallId := "0-0" - if len(g.pending) == 0 || count < 0 { - return nextCallId, nil - } - - msgs := g.pendingAfter(start) - var res []StreamEntry - for i, p := range msgs { - if minIdleTime > 0 && now.Before(p.lastDelivery.Add(minIdleTime)) { - continue - } - - prevConsumerID := p.consumer - if _, ok := g.consumers[consumerID]; !ok { - g.consumers[consumerID] = &consumer{} - } - p.consumer = consumerID - - _, entry := g.stream.get(p.id) - // not found. Weird? - if entry == nil { - // TODO: support third element of return from XAUTOCLAIM, which - // should delete entries not found in the PEL during XAUTOCLAIM. - // (Introduced in Redis 7.0) - continue - } - - p.deliveryCount += 1 - p.lastDelivery = now - - g.consumers[prevConsumerID].numPendingEntries-- - g.consumers[consumerID].numPendingEntries++ - - msgs[i] = p - res = append(res, *entry) - - if len(res) >= count { - if len(msgs) > i+1 { - nextCallId = msgs[i+1].id - } - break - } - } - return nextCallId, res -} - -func writeXautoclaim(c *server.Peer, nextCallId string, res []StreamEntry, justId bool) { - c.WriteLen(3) - c.WriteBulk(nextCallId) - c.WriteLen(len(res)) - for _, entry := range res { - if justId { - c.WriteBulk(entry.ID) - continue - } - - c.WriteLen(2) - c.WriteBulk(entry.ID) - c.WriteLen(len(entry.Values)) - for _, v := range entry.Values { - c.WriteBulk(v) - } - } - // TODO: see "Redis 7" note - c.WriteLen(0) -} - -// XCLAIM -func (m *Miniredis) cmdXclaim(c *server.Peer, cmd string, args []string) { - if len(args) < 5 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - groupName string - consumerName string - minIdleTime time.Duration - newLastDelivery time.Time - ids []string - retryCount *int - force bool - justId bool - } - - opts.key, opts.groupName, opts.consumerName = args[0], args[1], args[2] - - minIdleTimeMillis, err := strconv.Atoi(args[3]) - if err != nil { - setDirty(c) - c.WriteError("ERR Invalid min-idle-time argument for XCLAIM") - return - } - opts.minIdleTime = time.Millisecond * time.Duration(minIdleTimeMillis) - - opts.newLastDelivery = m.effectiveNow() - opts.ids = append(opts.ids, args[4]) - - args = args[5:] - for len(args) > 0 { - arg := strings.ToUpper(args[0]) - if arg == "IDLE" || - arg == "TIME" || - arg == "RETRYCOUNT" || - arg == "FORCE" || - arg == "JUSTID" { - break - } - opts.ids = append(opts.ids, arg) - args = args[1:] - } - - for len(args) > 0 { - arg := strings.ToUpper(args[0]) - switch arg { - case "IDLE": - idleMs, err := strconv.ParseInt(args[1], 10, 64) - if err != nil { - setDirty(c) - c.WriteError("ERR Invalid IDLE option argument for XCLAIM") - return - } - if idleMs < 0 { - idleMs = 0 - } - opts.newLastDelivery = m.effectiveNow().Add(time.Millisecond * time.Duration(-idleMs)) - args = args[2:] - case "TIME": - timeMs, err := strconv.ParseInt(args[1], 10, 64) - if err != nil { - setDirty(c) - c.WriteError("ERR Invalid TIME option argument for XCLAIM") - return - } - opts.newLastDelivery = unixMilli(timeMs) - args = args[2:] - case "RETRYCOUNT": - retryCount, err := strconv.Atoi(args[1]) - if err != nil { - setDirty(c) - c.WriteError("ERR Invalid RETRYCOUNT option argument for XCLAIM") - return - } - opts.retryCount = &retryCount - args = args[2:] - case "FORCE": - opts.force = true - args = args[1:] - case "JUSTID": - opts.justId = true - args = args[1:] - default: - setDirty(c) - c.WriteError(fmt.Sprintf("ERR Unrecognized XCLAIM option '%s'", args[0])) - return - } - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - g, err := db.streamGroup(opts.key, opts.groupName) - if err != nil { - c.WriteError(err.Error()) - return - } - if g == nil { - c.WriteError(errReadgroup(opts.key, opts.groupName).Error()) - return - } - - claimedEntryIDs := m.xclaim(g, opts.consumerName, opts.minIdleTime, opts.newLastDelivery, opts.ids, opts.retryCount, opts.force) - writeXclaim(c, g.stream, claimedEntryIDs, opts.justId) - }) -} - -func (m *Miniredis) xclaim( - group *streamGroup, - consumerName string, - minIdleTime time.Duration, - newLastDelivery time.Time, - ids []string, - retryCount *int, - force bool, -) (claimedEntryIDs []string) { - for _, id := range ids { - pelPos, pelEntry := group.searchPending(id) - if pelEntry == nil { - if !force { - continue - } - - if pelPos < len(group.pending) { - group.pending = append(group.pending[:pelPos+1], group.pending[pelPos:]...) - } else { - group.pending = append(group.pending, pendingEntry{}) - } - pelEntry = &group.pending[pelPos] - - *pelEntry = pendingEntry{ - id: id, - consumer: consumerName, - deliveryCount: 1, - } - } else { - group.consumers[pelEntry.consumer].numPendingEntries-- - pelEntry.consumer = consumerName - } - - if retryCount != nil { - pelEntry.deliveryCount = *retryCount - } else { - pelEntry.deliveryCount++ - } - pelEntry.lastDelivery = newLastDelivery - - // redis7: don't report entries which are deleted by now - if _, e := group.stream.get(id); e == nil { - continue - } - - claimedEntryIDs = append(claimedEntryIDs, id) - } - if len(claimedEntryIDs) == 0 { - return - } - - if _, ok := group.consumers[consumerName]; !ok { - group.consumers[consumerName] = &consumer{} - } - consumer := group.consumers[consumerName] - consumer.numPendingEntries += len(claimedEntryIDs) - - return -} - -func writeXclaim(c *server.Peer, stream *streamKey, claimedEntryIDs []string, justId bool) { - c.WriteLen(len(claimedEntryIDs)) - for _, id := range claimedEntryIDs { - if justId { - c.WriteBulk(id) - continue - } - - _, entry := stream.get(id) - if entry == nil { - c.WriteNull() - continue - } - - c.WriteLen(2) - c.WriteBulk(entry.ID) - c.WriteStrings(entry.Values) - } -} - -func parseBlock(cmd string, args []string, block *bool, timeout *time.Duration) error { - if len(args) < 2 { - return errors.New(errWrongNumber(cmd)) - } - (*block) = true - ms, err := strconv.Atoi(args[1]) - if err != nil { - return errors.New(msgInvalidInt) - } - if ms < 0 { - return errors.New("ERR timeout is negative") - } - (*timeout) = time.Millisecond * time.Duration(ms) - return nil -} - -// taken from Go's time package. Can be dropped if miniredis supports >= 1.17 -func unixMilli(msec int64) time.Time { - return time.Unix(msec/1e3, (msec%1e3)*1e6) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/cmd_string.go b/vendor/github.com/alicebob/miniredis/v2/cmd_string.go deleted file mode 100644 index b8013f281..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/cmd_string.go +++ /dev/null @@ -1,1364 +0,0 @@ -// Commands from https://redis.io/commands#string - -package miniredis - -import ( - "math/big" - "strconv" - "strings" - "time" - - "github.com/alicebob/miniredis/v2/server" -) - -// commandsString handles all string value operations. -func commandsString(m *Miniredis) { - m.srv.Register("APPEND", m.cmdAppend) - m.srv.Register("BITCOUNT", m.cmdBitcount) - m.srv.Register("BITOP", m.cmdBitop) - m.srv.Register("BITPOS", m.cmdBitpos) - m.srv.Register("DECRBY", m.cmdDecrby) - m.srv.Register("DECR", m.cmdDecr) - m.srv.Register("GETBIT", m.cmdGetbit) - m.srv.Register("GET", m.cmdGet) - m.srv.Register("GETEX", m.cmdGetex) - m.srv.Register("GETRANGE", m.cmdGetrange) - m.srv.Register("GETSET", m.cmdGetset) - m.srv.Register("GETDEL", m.cmdGetdel) - m.srv.Register("INCRBYFLOAT", m.cmdIncrbyfloat) - m.srv.Register("INCRBY", m.cmdIncrby) - m.srv.Register("INCR", m.cmdIncr) - m.srv.Register("MGET", m.cmdMget) - m.srv.Register("MSET", m.cmdMset) - m.srv.Register("MSETNX", m.cmdMsetnx) - m.srv.Register("PSETEX", m.cmdPsetex) - m.srv.Register("SETBIT", m.cmdSetbit) - m.srv.Register("SETEX", m.cmdSetex) - m.srv.Register("SET", m.cmdSet) - m.srv.Register("SETNX", m.cmdSetnx) - m.srv.Register("SETRANGE", m.cmdSetrange) - m.srv.Register("STRLEN", m.cmdStrlen) -} - -// SET -func (m *Miniredis) cmdSet(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - value string - nx bool // set iff not exists - xx bool // set iff exists - keepttl bool // set keepttl - ttlSet bool - ttl time.Duration - get bool - } - - opts.key, opts.value, args = args[0], args[1], args[2:] - for len(args) > 0 { - timeUnit := time.Second - switch arg := strings.ToUpper(args[0]); arg { - case "NX": - opts.nx = true - args = args[1:] - continue - case "XX": - opts.xx = true - args = args[1:] - continue - case "KEEPTTL": - opts.keepttl = true - args = args[1:] - continue - case "PX", "PXAT": - timeUnit = time.Millisecond - fallthrough - case "EX", "EXAT": - if len(args) < 2 { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - if opts.ttlSet { - // multiple ex/exat/px/pxat options set - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - expire, err := strconv.Atoi(args[1]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - if expire <= 0 { - setDirty(c) - c.WriteError(msgInvalidSETime) - return - } - - if arg == "PXAT" || arg == "EXAT" { - opts.ttl = m.at(expire, timeUnit) - } else { - opts.ttl = time.Duration(expire) * timeUnit - } - opts.ttlSet = true - - args = args[2:] - continue - case "GET": - opts.get = true - args = args[1:] - continue - default: - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - readonly := false - if opts.nx { - if db.exists(opts.key) { - if opts.get { - // special case for SET NX GET - readonly = true - } else { - c.WriteNull() - return - } - } - } - if opts.xx { - if !db.exists(opts.key) { - if opts.get { - // special case for SET XX GET - readonly = true - } else { - c.WriteNull() - return - } - } - } - if opts.keepttl { - if val, ok := db.ttl[opts.key]; ok { - opts.ttl = val - } - } - if opts.get { - if t, ok := db.keys[opts.key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - } - - old, existed := db.stringKeys[opts.key] - if !readonly { - db.del(opts.key, true) // be sure to remove existing values of other type keys. - // a vanilla SET clears the expire - if opts.ttl >= 0 { // EXAT/PXAT can expire right away - db.stringSet(opts.key, opts.value) - } - if opts.ttl != 0 { - db.ttl[opts.key] = opts.ttl - } - } - if opts.get { - if !existed { - c.WriteNull() - } else { - c.WriteBulk(old) - } - return - } - c.WriteOK() - }) -} - -// SETEX -func (m *Miniredis) cmdSetex(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - ttl, err := strconv.Atoi(args[1]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - if ttl <= 0 { - setDirty(c) - c.WriteError(msgInvalidSETEXTime) - return - } - value := args[2] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - db.del(key, true) // Clear any existing keys. - db.stringSet(key, value) - db.ttl[key] = time.Duration(ttl) * time.Second - c.WriteOK() - }) -} - -// PSETEX -func (m *Miniredis) cmdPsetex(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - ttl int - value string - } - - opts.key = args[0] - if ok := optInt(c, args[1], &opts.ttl); !ok { - return - } - if opts.ttl <= 0 { - setDirty(c) - c.WriteError(msgInvalidPSETEXTime) - return - } - opts.value = args[2] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - db.del(opts.key, true) // Clear any existing keys. - db.stringSet(opts.key, opts.value) - db.ttl[opts.key] = time.Duration(opts.ttl) * time.Millisecond - c.WriteOK() - }) -} - -// SETNX -func (m *Miniredis) cmdSetnx(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, value := args[0], args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if _, ok := db.keys[key]; ok { - c.WriteInt(0) - return - } - - db.stringSet(key, value) - c.WriteInt(1) - }) -} - -// MSET -func (m *Miniredis) cmdMset(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - if len(args)%2 != 0 { - setDirty(c) - // non-default error message - c.WriteError("ERR wrong number of arguments for MSET") - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - for len(args) > 0 { - key, value := args[0], args[1] - args = args[2:] - - db.del(key, true) // clear TTL - db.stringSet(key, value) - } - c.WriteOK() - }) -} - -// MSETNX -func (m *Miniredis) cmdMsetnx(c *server.Peer, cmd string, args []string) { - if len(args) < 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - if len(args)%2 != 0 { - setDirty(c) - // non-default error message (yes, with 'MSET'). - c.WriteError("ERR wrong number of arguments for MSET") - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - keys := map[string]string{} - existing := false - for len(args) > 0 { - key := args[0] - value := args[1] - args = args[2:] - keys[key] = value - if _, ok := db.keys[key]; ok { - existing = true - } - } - - res := 0 - if !existing { - res = 1 - for k, v := range keys { - // Nothing to delete. That's the whole point. - db.stringSet(k, v) - } - } - c.WriteInt(res) - }) -} - -// GET -func (m *Miniredis) cmdGet(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(key) { - c.WriteNull() - return - } - if db.t(key) != "string" { - c.WriteError(msgWrongType) - return - } - - c.WriteBulk(db.stringGet(key)) - }) -} - -// GETEX -func (m *Miniredis) cmdGetex(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - ttl time.Duration - persist bool // remove existing TTL on the key. - } - - opts.key, args = args[0], args[1:] - if len(args) > 0 { - timeUnit := time.Second - switch arg := strings.ToUpper(args[0]); arg { - case "PERSIST": - if len(args) > 1 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - opts.persist = true - case "PX", "PXAT": - timeUnit = time.Millisecond - fallthrough - case "EX", "EXAT": - if len(args) != 2 { - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - expire, err := strconv.Atoi(args[1]) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidInt) - return - } - if expire <= 0 { - setDirty(c) - c.WriteError(msgInvalidSETime) - return - } - - if arg == "PXAT" || arg == "EXAT" { - opts.ttl = m.at(expire, timeUnit) - } else { - opts.ttl = time.Duration(expire) * timeUnit - } - default: - setDirty(c) - c.WriteError(msgSyntaxError) - return - } - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.key) { - c.WriteNull() - return - } - switch { - case opts.persist: - delete(db.ttl, opts.key) - case opts.ttl != 0: - db.ttl[opts.key] = opts.ttl - } - - if db.t(opts.key) != "string" { - c.WriteError(msgWrongType) - return - } - - c.WriteBulk(db.stringGet(opts.key)) - }) -} - -// GETSET -func (m *Miniredis) cmdGetset(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, value := args[0], args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - - old, ok := db.stringKeys[key] - db.stringSet(key, value) - // a GETSET clears the ttl - delete(db.ttl, key) - - if !ok { - c.WriteNull() - return - } - c.WriteBulk(old) - }) -} - -// GETDEL -func (m *Miniredis) cmdGetdel(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - key := args[0] - - if !db.exists(key) { - c.WriteNull() - return - } - - if db.t(key) != "string" { - c.WriteError(msgWrongType) - return - } - - v := db.stringGet(key) - db.del(key, true) - c.WriteBulk(v) - }) -} - -// MGET -func (m *Miniredis) cmdMget(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - c.WriteLen(len(args)) - for _, k := range args { - if t, ok := db.keys[k]; !ok || t != "string" { - c.WriteNull() - continue - } - v, ok := db.stringKeys[k] - if !ok { - // Should not happen, we just checked keys[] - c.WriteNull() - continue - } - c.WriteBulk(v) - } - }) -} - -// INCR -func (m *Miniredis) cmdIncr(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - key := args[0] - if t, ok := db.keys[key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - v, err := db.stringIncr(key, +1) - if err != nil { - c.WriteError(err.Error()) - return - } - // Don't touch TTL - c.WriteInt(v) - }) -} - -// INCRBY -func (m *Miniredis) cmdIncrby(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - delta int - } - opts.key = args[0] - if ok := optInt(c, args[1], &opts.delta); !ok { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[opts.key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - - v, err := db.stringIncr(opts.key, opts.delta) - if err != nil { - c.WriteError(err.Error()) - return - } - // Don't touch TTL - c.WriteInt(v) - }) -} - -// INCRBYFLOAT -func (m *Miniredis) cmdIncrbyfloat(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - delta, _, err := big.ParseFloat(args[1], 10, 128, 0) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidFloat) - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - - v, err := db.stringIncrfloat(key, delta) - if err != nil { - c.WriteError(err.Error()) - return - } - // Don't touch TTL - c.WriteBulk(formatBig(v)) - }) -} - -// DECR -func (m *Miniredis) cmdDecr(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - key := args[0] - if t, ok := db.keys[key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - v, err := db.stringIncr(key, -1) - if err != nil { - c.WriteError(err.Error()) - return - } - // Don't touch TTL - c.WriteInt(v) - }) -} - -// DECRBY -func (m *Miniredis) cmdDecrby(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - delta int - } - opts.key = args[0] - if ok := optInt(c, args[1], &opts.delta); !ok { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[opts.key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - - v, err := db.stringIncr(opts.key, -opts.delta) - if err != nil { - c.WriteError(err.Error()) - return - } - // Don't touch TTL - c.WriteInt(v) - }) -} - -// STRLEN -func (m *Miniredis) cmdStrlen(c *server.Peer, cmd string, args []string) { - if len(args) != 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key := args[0] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - - c.WriteInt(len(db.stringKeys[key])) - }) -} - -// APPEND -func (m *Miniredis) cmdAppend(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - key, value := args[0], args[1] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - - newValue := db.stringKeys[key] + value - db.stringSet(key, newValue) - - c.WriteInt(len(newValue)) - }) -} - -// GETRANGE -func (m *Miniredis) cmdGetrange(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - start int - end int - } - opts.key = args[0] - if ok := optInt(c, args[1], &opts.start); !ok { - return - } - if ok := optInt(c, args[2], &opts.end); !ok { - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[opts.key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - - v := db.stringKeys[opts.key] - c.WriteBulk(withRange(v, opts.start, opts.end)) - }) -} - -// SETRANGE -func (m *Miniredis) cmdSetrange(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - pos int - subst string - } - opts.key = args[0] - if ok := optInt(c, args[1], &opts.pos); !ok { - return - } - if opts.pos < 0 { - setDirty(c) - c.WriteError("ERR offset is out of range") - return - } - opts.subst = args[2] - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[opts.key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - - v := []byte(db.stringKeys[opts.key]) - end := opts.pos + len(opts.subst) - if len(v) < end { - newV := make([]byte, end) - copy(newV, v) - v = newV - } - copy(v[opts.pos:end], opts.subst) - db.stringSet(opts.key, string(v)) - c.WriteInt(len(v)) - }) -} - -// BITCOUNT -func (m *Miniredis) cmdBitcount(c *server.Peer, cmd string, args []string) { - if len(args) < 1 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - useRange bool - start int - end int - key string - } - opts.key, args = args[0], args[1:] - if len(args) >= 2 { - opts.useRange = true - if ok := optInt(c, args[0], &opts.start); !ok { - return - } - if ok := optInt(c, args[1], &opts.end); !ok { - return - } - args = args[2:] - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if !db.exists(opts.key) { - c.WriteInt(0) - return - } - if db.t(opts.key) != "string" { - c.WriteError(msgWrongType) - return - } - - // Real redis only checks after it knows the key is there and a string. - if len(args) != 0 { - c.WriteError(msgSyntaxError) - return - } - - v := db.stringKeys[opts.key] - if opts.useRange { - v = withRange(v, opts.start, opts.end) - } - - c.WriteInt(countBits([]byte(v))) - }) -} - -// BITOP -func (m *Miniredis) cmdBitop(c *server.Peer, cmd string, args []string) { - if len(args) < 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - op string - target string - input []string - } - opts.op = strings.ToUpper(args[0]) - opts.target = args[1] - opts.input = args[2:] - - // 'op' is tested when the transaction is executed. - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - switch opts.op { - case "AND", "OR", "XOR": - first := opts.input[0] - if t, ok := db.keys[first]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - res := []byte(db.stringKeys[first]) - for _, vk := range opts.input[1:] { - if t, ok := db.keys[vk]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - v := db.stringKeys[vk] - cb := map[string]func(byte, byte) byte{ - "AND": func(a, b byte) byte { return a & b }, - "OR": func(a, b byte) byte { return a | b }, - "XOR": func(a, b byte) byte { return a ^ b }, - }[opts.op] - res = sliceBinOp(cb, res, []byte(v)) - } - db.del(opts.target, false) // Keep TTL - if len(res) == 0 { - db.del(opts.target, true) - } else { - db.stringSet(opts.target, string(res)) - } - c.WriteInt(len(res)) - case "NOT": - // NOT only takes a single argument. - if len(opts.input) != 1 { - c.WriteError("ERR BITOP NOT must be called with a single source key.") - return - } - key := opts.input[0] - if t, ok := db.keys[key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - value := []byte(db.stringKeys[key]) - for i := range value { - value[i] = ^value[i] - } - db.del(opts.target, false) // Keep TTL - if len(value) == 0 { - db.del(opts.target, true) - } else { - db.stringSet(opts.target, string(value)) - } - c.WriteInt(len(value)) - default: - c.WriteError(msgSyntaxError) - } - }) -} - -// BITPOS -func (m *Miniredis) cmdBitpos(c *server.Peer, cmd string, args []string) { - if len(args) < 2 || len(args) > 4 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - Key string - Bit int - Start int - End int - WithEnd bool - } - - opts.Key = args[0] - if ok := optInt(c, args[1], &opts.Bit); !ok { - return - } - if len(args) > 2 { - if ok := optInt(c, args[2], &opts.Start); !ok { - return - } - } - if len(args) > 3 { - if ok := optInt(c, args[3], &opts.End); !ok { - return - } - opts.WithEnd = true - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[opts.Key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } else if !ok { - // non-existing key behaves differently - if opts.Bit == 0 { - c.WriteInt(0) - } else { - c.WriteInt(-1) - } - return - } - value := db.stringKeys[opts.Key] - start := opts.Start - end := opts.End - if start < 0 { - start += len(value) - if start < 0 { - start = 0 - } - } - if start > len(value) { - start = len(value) - } - - if opts.WithEnd { - if end < 0 { - end += len(value) - } - if end < 0 { - end = 0 - } - end++ // +1 for redis end semantics - if end > len(value) { - end = len(value) - } - } else { - end = len(value) - } - - if start != 0 || opts.WithEnd { - if end < start { - value = "" - } else { - value = value[start:end] - } - } - pos := bitPos([]byte(value), opts.Bit == 1) - if pos >= 0 { - pos += start * 8 - } - // Special case when looking for 0, but not when start and end are - // given. - if opts.Bit == 0 && pos == -1 && !opts.WithEnd && len(value) > 0 { - pos = start*8 + len(value)*8 - } - c.WriteInt(pos) - }) -} - -// GETBIT -func (m *Miniredis) cmdGetbit(c *server.Peer, cmd string, args []string) { - if len(args) != 2 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - bit int - } - opts.key = args[0] - if ok := optIntErr(c, args[1], &opts.bit, "ERR bit offset is not an integer or out of range"); !ok { - return - } - if opts.bit < 0 { - setDirty(c) - c.WriteError("ERR bit offset is not an integer or out of range") - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[opts.key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - value := db.stringKeys[opts.key] - - ourByteNr := opts.bit / 8 - var ourByte byte - if ourByteNr > len(value)-1 { - ourByte = '\x00' - } else { - ourByte = value[ourByteNr] - } - res := 0 - if toBits(ourByte)[opts.bit%8] { - res = 1 - } - c.WriteInt(res) - }) -} - -// SETBIT -func (m *Miniredis) cmdSetbit(c *server.Peer, cmd string, args []string) { - if len(args) != 3 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - var opts struct { - key string - bit int - newBit int - } - opts.key = args[0] - if ok := optIntErr(c, args[1], &opts.bit, "ERR bit offset is not an integer or out of range"); !ok { - return - } - if opts.bit < 0 { - setDirty(c) - c.WriteError("ERR bit offset is not an integer or out of range") - return - } - if ok := optIntErr(c, args[2], &opts.newBit, "ERR bit is not an integer or out of range"); !ok { - return - } - if opts.newBit != 0 && opts.newBit != 1 { - setDirty(c) - c.WriteError("ERR bit is not an integer or out of range") - return - } - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - db := m.db(ctx.selectedDB) - - if t, ok := db.keys[opts.key]; ok && t != "string" { - c.WriteError(msgWrongType) - return - } - value := []byte(db.stringKeys[opts.key]) - - ourByteNr := opts.bit / 8 - ourBitNr := opts.bit % 8 - if ourByteNr > len(value)-1 { - // Too short. Expand. - newValue := make([]byte, ourByteNr+1) - copy(newValue, value) - value = newValue - } - old := 0 - if toBits(value[ourByteNr])[ourBitNr] { - old = 1 - } - if opts.newBit == 0 { - value[ourByteNr] &^= 1 << uint8(7-ourBitNr) - } else { - value[ourByteNr] |= 1 << uint8(7-ourBitNr) - } - db.stringSet(opts.key, string(value)) - - c.WriteInt(old) - }) -} - -// Redis range. both start and end can be negative. -func withRange(v string, start, end int) string { - s, e := redisRange(len(v), start, end, true /* string getrange symantics */) - return v[s:e] -} - -func countBits(v []byte) int { - count := 0 - for _, b := range []byte(v) { - for b > 0 { - count += int((b % uint8(2))) - b = b >> 1 - } - } - return count -} - -// sliceBinOp applies an operator to all slice elements, with Redis string -// padding logic. -func sliceBinOp(f func(a, b byte) byte, a, b []byte) []byte { - maxl := len(a) - if len(b) > maxl { - maxl = len(b) - } - lA := make([]byte, maxl) - copy(lA, a) - lB := make([]byte, maxl) - copy(lB, b) - res := make([]byte, maxl) - for i := range res { - res[i] = f(lA[i], lB[i]) - } - return res -} - -// Return the number of the first bit set/unset. -func bitPos(s []byte, bit bool) int { - for i, b := range s { - for j, set := range toBits(b) { - if set == bit { - return i*8 + j - } - } - } - return -1 -} - -// toBits changes a byte in 8 bools. -func toBits(s byte) [8]bool { - r := [8]bool{} - for i := range r { - if s&(uint8(1)< version { - // Abort! Abort! - stopTx(ctx) - c.WriteLen(-1) - return - } - } - - c.WriteLen(len(ctx.transaction)) - for _, cb := range ctx.transaction { - cb(c, ctx) - } - // wake up anyone who waits on anything. - m.signal.Broadcast() - - stopTx(ctx) -} - -// DISCARD -func (m *Miniredis) cmdDiscard(c *server.Peer, cmd string, args []string) { - if len(args) != 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - ctx := getCtx(c) - if !inTx(ctx) { - c.WriteError("ERR DISCARD without MULTI") - return - } - - stopTx(ctx) - c.WriteOK() -} - -// WATCH -func (m *Miniredis) cmdWatch(c *server.Peer, cmd string, args []string) { - if len(args) == 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - ctx := getCtx(c) - if ctx.nested { - c.WriteError(msgNotFromScripts(ctx.nestedSHA)) - return - } - if inTx(ctx) { - c.WriteError("ERR WATCH in MULTI") - return - } - - m.Lock() - defer m.Unlock() - db := m.db(ctx.selectedDB) - - for _, key := range args { - watch(db, ctx, key) - } - c.WriteOK() -} - -// UNWATCH -func (m *Miniredis) cmdUnwatch(c *server.Peer, cmd string, args []string) { - if len(args) != 0 { - setDirty(c) - c.WriteError(errWrongNumber(cmd)) - return - } - if !m.handleAuth(c) { - return - } - if m.checkPubsub(c, cmd) { - return - } - - // Doesn't matter if UNWATCH is in a TX or not. Looks like a Redis bug to me. - unwatch(getCtx(c)) - - withTx(m, c, func(c *server.Peer, ctx *connCtx) { - // Do nothing if it's called in a transaction. - c.WriteOK() - }) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/db.go b/vendor/github.com/alicebob/miniredis/v2/db.go deleted file mode 100644 index 388d5fbbd..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/db.go +++ /dev/null @@ -1,718 +0,0 @@ -package miniredis - -import ( - "errors" - "fmt" - "math/big" - "sort" - "strconv" - "time" -) - -var ( - errInvalidEntryID = errors.New("stream ID is invalid") -) - -func (db *RedisDB) exists(k string) bool { - _, ok := db.keys[k] - return ok -} - -// t gives the type of a key, or "" -func (db *RedisDB) t(k string) string { - return db.keys[k] -} - -// allKeys returns all keys. Sorted. -func (db *RedisDB) allKeys() []string { - res := make([]string, 0, len(db.keys)) - for k := range db.keys { - res = append(res, k) - } - sort.Strings(res) // To make things deterministic. - return res -} - -// flush removes all keys and values. -func (db *RedisDB) flush() { - db.keys = map[string]string{} - db.stringKeys = map[string]string{} - db.hashKeys = map[string]hashKey{} - db.listKeys = map[string]listKey{} - db.setKeys = map[string]setKey{} - db.hllKeys = map[string]*hll{} - db.sortedsetKeys = map[string]sortedSet{} - db.ttl = map[string]time.Duration{} - db.streamKeys = map[string]*streamKey{} -} - -// move something to another db. Will return ok. Or not. -func (db *RedisDB) move(key string, to *RedisDB) bool { - if _, ok := to.keys[key]; ok { - return false - } - - t, ok := db.keys[key] - if !ok { - return false - } - to.keys[key] = db.keys[key] - switch t { - case "string": - to.stringKeys[key] = db.stringKeys[key] - case "hash": - to.hashKeys[key] = db.hashKeys[key] - case "list": - to.listKeys[key] = db.listKeys[key] - case "set": - to.setKeys[key] = db.setKeys[key] - case "zset": - to.sortedsetKeys[key] = db.sortedsetKeys[key] - case "stream": - to.streamKeys[key] = db.streamKeys[key] - case "hll": - to.hllKeys[key] = db.hllKeys[key] - default: - panic("unhandled key type") - } - to.keyVersion[key]++ - if v, ok := db.ttl[key]; ok { - to.ttl[key] = v - } - db.del(key, true) - return true -} - -func (db *RedisDB) rename(from, to string) { - db.del(to, true) - switch db.t(from) { - case "string": - db.stringKeys[to] = db.stringKeys[from] - case "hash": - db.hashKeys[to] = db.hashKeys[from] - case "list": - db.listKeys[to] = db.listKeys[from] - case "set": - db.setKeys[to] = db.setKeys[from] - case "zset": - db.sortedsetKeys[to] = db.sortedsetKeys[from] - case "stream": - db.streamKeys[to] = db.streamKeys[from] - case "hll": - db.hllKeys[to] = db.hllKeys[from] - default: - panic("missing case") - } - db.keys[to] = db.keys[from] - db.keyVersion[to]++ - if v, ok := db.ttl[from]; ok { - db.ttl[to] = v - } - - db.del(from, true) -} - -func (db *RedisDB) del(k string, delTTL bool) { - if !db.exists(k) { - return - } - t := db.t(k) - delete(db.keys, k) - db.keyVersion[k]++ - if delTTL { - delete(db.ttl, k) - } - switch t { - case "string": - delete(db.stringKeys, k) - case "hash": - delete(db.hashKeys, k) - case "list": - delete(db.listKeys, k) - case "set": - delete(db.setKeys, k) - case "zset": - delete(db.sortedsetKeys, k) - case "stream": - delete(db.streamKeys, k) - case "hll": - delete(db.hllKeys, k) - default: - panic("Unknown key type: " + t) - } -} - -// stringGet returns the string key or "" on error/nonexists. -func (db *RedisDB) stringGet(k string) string { - if t, ok := db.keys[k]; !ok || t != "string" { - return "" - } - return db.stringKeys[k] -} - -// stringSet force set()s a key. Does not touch expire. -func (db *RedisDB) stringSet(k, v string) { - db.del(k, false) - db.keys[k] = "string" - db.stringKeys[k] = v - db.keyVersion[k]++ -} - -// change int key value -func (db *RedisDB) stringIncr(k string, delta int) (int, error) { - v := 0 - if sv, ok := db.stringKeys[k]; ok { - var err error - v, err = strconv.Atoi(sv) - if err != nil { - return 0, ErrIntValueError - } - } - v += delta - db.stringSet(k, strconv.Itoa(v)) - return v, nil -} - -// change float key value -func (db *RedisDB) stringIncrfloat(k string, delta *big.Float) (*big.Float, error) { - v := big.NewFloat(0.0) - v.SetPrec(128) - if sv, ok := db.stringKeys[k]; ok { - var err error - v, _, err = big.ParseFloat(sv, 10, 128, 0) - if err != nil { - return nil, ErrFloatValueError - } - } - v.Add(v, delta) - db.stringSet(k, formatBig(v)) - return v, nil -} - -// listLpush is 'left push', aka unshift. Returns the new length. -func (db *RedisDB) listLpush(k, v string) int { - l, ok := db.listKeys[k] - if !ok { - db.keys[k] = "list" - } - l = append([]string{v}, l...) - db.listKeys[k] = l - db.keyVersion[k]++ - return len(l) -} - -// 'left pop', aka shift. -func (db *RedisDB) listLpop(k string) string { - l := db.listKeys[k] - el := l[0] - l = l[1:] - if len(l) == 0 { - db.del(k, true) - } else { - db.listKeys[k] = l - } - db.keyVersion[k]++ - return el -} - -func (db *RedisDB) listPush(k string, v ...string) int { - l, ok := db.listKeys[k] - if !ok { - db.keys[k] = "list" - } - l = append(l, v...) - db.listKeys[k] = l - db.keyVersion[k]++ - return len(l) -} - -func (db *RedisDB) listPop(k string) string { - l := db.listKeys[k] - el := l[len(l)-1] - l = l[:len(l)-1] - if len(l) == 0 { - db.del(k, true) - } else { - db.listKeys[k] = l - db.keyVersion[k]++ - } - return el -} - -// setset replaces a whole set. -func (db *RedisDB) setSet(k string, set setKey) { - db.keys[k] = "set" - db.setKeys[k] = set - db.keyVersion[k]++ -} - -// setadd adds members to a set. Returns nr of new keys. -func (db *RedisDB) setAdd(k string, elems ...string) int { - s, ok := db.setKeys[k] - if !ok { - s = setKey{} - db.keys[k] = "set" - } - added := 0 - for _, e := range elems { - if _, ok := s[e]; !ok { - added++ - } - s[e] = struct{}{} - } - db.setKeys[k] = s - db.keyVersion[k]++ - return added -} - -// setrem removes members from a set. Returns nr of deleted keys. -func (db *RedisDB) setRem(k string, fields ...string) int { - s, ok := db.setKeys[k] - if !ok { - return 0 - } - removed := 0 - for _, f := range fields { - if _, ok := s[f]; ok { - removed++ - delete(s, f) - } - } - if len(s) == 0 { - db.del(k, true) - } else { - db.setKeys[k] = s - } - db.keyVersion[k]++ - return removed -} - -// All members of a set. -func (db *RedisDB) setMembers(k string) []string { - set := db.setKeys[k] - members := make([]string, 0, len(set)) - for k := range set { - members = append(members, k) - } - sort.Strings(members) - return members -} - -// Is a SET value present? -func (db *RedisDB) setIsMember(k, v string) bool { - set, ok := db.setKeys[k] - if !ok { - return false - } - _, ok = set[v] - return ok -} - -// hashFields returns all (sorted) keys ('fields') for a hash key. -func (db *RedisDB) hashFields(k string) []string { - v := db.hashKeys[k] - var r []string - for k := range v { - r = append(r, k) - } - sort.Strings(r) - return r -} - -// hashValues returns all (sorted) values a hash key. -func (db *RedisDB) hashValues(k string) []string { - h := db.hashKeys[k] - var r []string - for _, v := range h { - r = append(r, v) - } - sort.Strings(r) - return r -} - -// hashGet a value -func (db *RedisDB) hashGet(key, field string) string { - return db.hashKeys[key][field] -} - -// hashSet returns the number of new keys -func (db *RedisDB) hashSet(k string, fv ...string) int { - if t, ok := db.keys[k]; ok && t != "hash" { - db.del(k, true) - } - db.keys[k] = "hash" - if _, ok := db.hashKeys[k]; !ok { - db.hashKeys[k] = map[string]string{} - } - new := 0 - for idx := 0; idx < len(fv)-1; idx = idx + 2 { - f, v := fv[idx], fv[idx+1] - _, ok := db.hashKeys[k][f] - db.hashKeys[k][f] = v - db.keyVersion[k]++ - if !ok { - new++ - } - } - return new -} - -// hashIncr changes int key value -func (db *RedisDB) hashIncr(key, field string, delta int) (int, error) { - v := 0 - if h, ok := db.hashKeys[key]; ok { - if f, ok := h[field]; ok { - var err error - v, err = strconv.Atoi(f) - if err != nil { - return 0, ErrIntValueError - } - } - } - v += delta - db.hashSet(key, field, strconv.Itoa(v)) - return v, nil -} - -// hashIncrfloat changes float key value -func (db *RedisDB) hashIncrfloat(key, field string, delta *big.Float) (*big.Float, error) { - v := big.NewFloat(0.0) - v.SetPrec(128) - if h, ok := db.hashKeys[key]; ok { - if f, ok := h[field]; ok { - var err error - v, _, err = big.ParseFloat(f, 10, 128, 0) - if err != nil { - return nil, ErrFloatValueError - } - } - } - v.Add(v, delta) - db.hashSet(key, field, formatBig(v)) - return v, nil -} - -// sortedSet set returns a sortedSet as map -func (db *RedisDB) sortedSet(key string) map[string]float64 { - ss := db.sortedsetKeys[key] - return map[string]float64(ss) -} - -// ssetSet sets a complete sorted set. -func (db *RedisDB) ssetSet(key string, sset sortedSet) { - db.keys[key] = "zset" - db.keyVersion[key]++ - db.sortedsetKeys[key] = sset -} - -// ssetAdd adds member to a sorted set. Returns whether this was a new member. -func (db *RedisDB) ssetAdd(key string, score float64, member string) bool { - ss, ok := db.sortedsetKeys[key] - if !ok { - ss = newSortedSet() - db.keys[key] = "zset" - } - _, ok = ss[member] - ss[member] = score - db.sortedsetKeys[key] = ss - db.keyVersion[key]++ - return !ok -} - -// All members from a sorted set, ordered by score. -func (db *RedisDB) ssetMembers(key string) []string { - ss, ok := db.sortedsetKeys[key] - if !ok { - return nil - } - elems := ss.byScore(asc) - members := make([]string, 0, len(elems)) - for _, e := range elems { - members = append(members, e.member) - } - return members -} - -// All members+scores from a sorted set, ordered by score. -func (db *RedisDB) ssetElements(key string) ssElems { - ss, ok := db.sortedsetKeys[key] - if !ok { - return nil - } - return ss.byScore(asc) -} - -func (db *RedisDB) ssetRandomMember(key string) string { - elems := db.ssetElements(key) - if len(elems) == 0 { - return "" - } - return elems[db.master.randIntn(len(elems))].member -} - -// ssetCard is the sorted set cardinality. -func (db *RedisDB) ssetCard(key string) int { - ss := db.sortedsetKeys[key] - return ss.card() -} - -// ssetRank is the sorted set rank. -func (db *RedisDB) ssetRank(key, member string, d direction) (int, bool) { - ss := db.sortedsetKeys[key] - return ss.rankByScore(member, d) -} - -// ssetScore is sorted set score. -func (db *RedisDB) ssetScore(key, member string) float64 { - ss := db.sortedsetKeys[key] - return ss[member] -} - -// ssetMScore returns multiple scores of a list of members in a sorted set. -func (db *RedisDB) ssetMScore(key string, members []string) []float64 { - scores := make([]float64, 0, len(members)) - ss := db.sortedsetKeys[key] - for _, member := range members { - scores = append(scores, ss[member]) - } - return scores -} - -// ssetRem is sorted set key delete. -func (db *RedisDB) ssetRem(key, member string) bool { - ss := db.sortedsetKeys[key] - _, ok := ss[member] - delete(ss, member) - if len(ss) == 0 { - // Delete key on removal of last member - db.del(key, true) - } - return ok -} - -// ssetExists tells if a member exists in a sorted set. -func (db *RedisDB) ssetExists(key, member string) bool { - ss := db.sortedsetKeys[key] - _, ok := ss[member] - return ok -} - -// ssetIncrby changes float sorted set score. -func (db *RedisDB) ssetIncrby(k, m string, delta float64) float64 { - ss, ok := db.sortedsetKeys[k] - if !ok { - ss = newSortedSet() - db.keys[k] = "zset" - db.sortedsetKeys[k] = ss - } - - v, _ := ss.get(m) - v += delta - ss.set(v, m) - db.keyVersion[k]++ - return v -} - -// setDiff implements the logic behind SDIFF* -func (db *RedisDB) setDiff(keys []string) (setKey, error) { - key := keys[0] - keys = keys[1:] - if db.exists(key) && db.t(key) != "set" { - return nil, ErrWrongType - } - s := setKey{} - for k := range db.setKeys[key] { - s[k] = struct{}{} - } - for _, sk := range keys { - if !db.exists(sk) { - continue - } - if db.t(sk) != "set" { - return nil, ErrWrongType - } - for e := range db.setKeys[sk] { - delete(s, e) - } - } - return s, nil -} - -// setInter implements the logic behind SINTER* -// len keys needs to be > 0 -func (db *RedisDB) setInter(keys []string) (setKey, error) { - // all keys must either not exist, or be of type "set". - for _, key := range keys { - if db.exists(key) && db.t(key) != "set" { - return nil, ErrWrongType - } - } - - key := keys[0] - keys = keys[1:] - if !db.exists(key) { - return nil, nil - } - if db.t(key) != "set" { - return nil, ErrWrongType - } - s := setKey{} - for k := range db.setKeys[key] { - s[k] = struct{}{} - } - for _, sk := range keys { - if !db.exists(sk) { - return setKey{}, nil - } - if db.t(sk) != "set" { - return nil, ErrWrongType - } - other := db.setKeys[sk] - for e := range s { - if _, ok := other[e]; ok { - continue - } - delete(s, e) - } - } - return s, nil -} - -// setUnion implements the logic behind SUNION* -func (db *RedisDB) setUnion(keys []string) (setKey, error) { - key := keys[0] - keys = keys[1:] - if db.exists(key) && db.t(key) != "set" { - return nil, ErrWrongType - } - s := setKey{} - for k := range db.setKeys[key] { - s[k] = struct{}{} - } - for _, sk := range keys { - if !db.exists(sk) { - continue - } - if db.t(sk) != "set" { - return nil, ErrWrongType - } - for e := range db.setKeys[sk] { - s[e] = struct{}{} - } - } - return s, nil -} - -func (db *RedisDB) newStream(key string) (*streamKey, error) { - if s, err := db.stream(key); err != nil { - return nil, err - } else if s != nil { - return nil, fmt.Errorf("ErrAlreadyExists") - } - - db.keys[key] = "stream" - s := newStreamKey() - db.streamKeys[key] = s - db.keyVersion[key]++ - return s, nil -} - -// return existing stream, or nil. -func (db *RedisDB) stream(key string) (*streamKey, error) { - if db.exists(key) && db.t(key) != "stream" { - return nil, ErrWrongType - } - - return db.streamKeys[key], nil -} - -// return existing stream group, or nil. -func (db *RedisDB) streamGroup(key, group string) (*streamGroup, error) { - s, err := db.stream(key) - if err != nil || s == nil { - return nil, err - } - return s.groups[group], nil -} - -// fastForward proceeds the current timestamp with duration, works as a time machine -func (db *RedisDB) fastForward(duration time.Duration) { - for _, key := range db.allKeys() { - if value, ok := db.ttl[key]; ok { - db.ttl[key] = value - duration - db.checkTTL(key) - } - } -} - -func (db *RedisDB) checkTTL(key string) { - if v, ok := db.ttl[key]; ok && v <= 0 { - db.del(key, true) - } -} - -// hllAdd adds members to a hll. Returns 1 if at least 1 if internal HyperLogLog was altered, otherwise 0 -func (db *RedisDB) hllAdd(k string, elems ...string) int { - s, ok := db.hllKeys[k] - if !ok { - s = newHll() - db.keys[k] = "hll" - } - hllAltered := 0 - for _, e := range elems { - if s.Add([]byte(e)) { - hllAltered = 1 - } - } - db.hllKeys[k] = s - db.keyVersion[k]++ - return hllAltered -} - -// hllCount estimates the amount of members added to hll by hllAdd. If called with several arguments, hllCount returns a sum of estimations -func (db *RedisDB) hllCount(keys []string) (int, error) { - countOverall := 0 - for _, key := range keys { - if db.exists(key) && db.t(key) != "hll" { - return 0, ErrNotValidHllValue - } - if !db.exists(key) { - continue - } - countOverall += db.hllKeys[key].Count() - } - - return countOverall, nil -} - -// hllMerge merges all the hlls provided as keys to the first key. Creates a new hll in the first key if it contains nothing -func (db *RedisDB) hllMerge(keys []string) error { - for _, key := range keys { - if db.exists(key) && db.t(key) != "hll" { - return ErrNotValidHllValue - } - } - - destKey := keys[0] - restKeys := keys[1:] - - var destHll *hll - if db.exists(destKey) { - destHll = db.hllKeys[destKey] - } else { - destHll = newHll() - } - - for _, key := range restKeys { - if !db.exists(key) { - continue - } - destHll.Merge(db.hllKeys[key]) - } - - db.hllKeys[destKey] = destHll - db.keys[destKey] = "hll" - db.keyVersion[destKey]++ - - return nil -} diff --git a/vendor/github.com/alicebob/miniredis/v2/direct.go b/vendor/github.com/alicebob/miniredis/v2/direct.go deleted file mode 100644 index 607c4e088..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/direct.go +++ /dev/null @@ -1,821 +0,0 @@ -package miniredis - -// Commands to modify and query our databases directly. - -import ( - "errors" - "math/big" - "time" -) - -var ( - // ErrKeyNotFound is returned when a key doesn't exist. - ErrKeyNotFound = errors.New(msgKeyNotFound) - - // ErrWrongType when a key is not the right type. - ErrWrongType = errors.New(msgWrongType) - - // ErrNotValidHllValue when a key is not a valid HyperLogLog string value. - ErrNotValidHllValue = errors.New(msgNotValidHllValue) - - // ErrIntValueError can returned by INCRBY - ErrIntValueError = errors.New(msgInvalidInt) - - // ErrFloatValueError can returned by INCRBYFLOAT - ErrFloatValueError = errors.New(msgInvalidFloat) -) - -// Select sets the DB id for all direct commands. -func (m *Miniredis) Select(i int) { - m.Lock() - defer m.Unlock() - m.selectedDB = i -} - -// Keys returns all keys from the selected database, sorted. -func (m *Miniredis) Keys() []string { - return m.DB(m.selectedDB).Keys() -} - -// Keys returns all keys, sorted. -func (db *RedisDB) Keys() []string { - db.master.Lock() - defer db.master.Unlock() - - return db.allKeys() -} - -// FlushAll removes all keys from all databases. -func (m *Miniredis) FlushAll() { - m.Lock() - defer m.Unlock() - defer m.signal.Broadcast() - - m.flushAll() -} - -func (m *Miniredis) flushAll() { - for _, db := range m.dbs { - db.flush() - } -} - -// FlushDB removes all keys from the selected database. -func (m *Miniredis) FlushDB() { - m.DB(m.selectedDB).FlushDB() -} - -// FlushDB removes all keys. -func (db *RedisDB) FlushDB() { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - db.flush() -} - -// Get returns string keys added with SET. -func (m *Miniredis) Get(k string) (string, error) { - return m.DB(m.selectedDB).Get(k) -} - -// Get returns a string key. -func (db *RedisDB) Get(k string) (string, error) { - db.master.Lock() - defer db.master.Unlock() - - if !db.exists(k) { - return "", ErrKeyNotFound - } - if db.t(k) != "string" { - return "", ErrWrongType - } - return db.stringGet(k), nil -} - -// Set sets a string key. Removes expire. -func (m *Miniredis) Set(k, v string) error { - return m.DB(m.selectedDB).Set(k, v) -} - -// Set sets a string key. Removes expire. -// Unlike redis the key can't be an existing non-string key. -func (db *RedisDB) Set(k, v string) error { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if db.exists(k) && db.t(k) != "string" { - return ErrWrongType - } - db.del(k, true) // Remove expire - db.stringSet(k, v) - return nil -} - -// Incr changes a int string value by delta. -func (m *Miniredis) Incr(k string, delta int) (int, error) { - return m.DB(m.selectedDB).Incr(k, delta) -} - -// Incr changes a int string value by delta. -func (db *RedisDB) Incr(k string, delta int) (int, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if db.exists(k) && db.t(k) != "string" { - return 0, ErrWrongType - } - - return db.stringIncr(k, delta) -} - -// IncrByFloat increments the float value of a key by the given delta. -// is an alias for Miniredis.Incrfloat -func (m *Miniredis) IncrByFloat(k string, delta float64) (float64, error) { - return m.Incrfloat(k, delta) -} - -// Incrfloat changes a float string value by delta. -func (m *Miniredis) Incrfloat(k string, delta float64) (float64, error) { - return m.DB(m.selectedDB).Incrfloat(k, delta) -} - -// Incrfloat changes a float string value by delta. -func (db *RedisDB) Incrfloat(k string, delta float64) (float64, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if db.exists(k) && db.t(k) != "string" { - return 0, ErrWrongType - } - - v, err := db.stringIncrfloat(k, big.NewFloat(delta)) - if err != nil { - return 0, err - } - vf, _ := v.Float64() - return vf, nil -} - -// List returns the list k, or an error if it's not there or something else. -// This is the same as the Redis command `LRANGE 0 -1`, but you can do your own -// range-ing. -func (m *Miniredis) List(k string) ([]string, error) { - return m.DB(m.selectedDB).List(k) -} - -// List returns the list k, or an error if it's not there or something else. -// This is the same as the Redis command `LRANGE 0 -1`, but you can do your own -// range-ing. -func (db *RedisDB) List(k string) ([]string, error) { - db.master.Lock() - defer db.master.Unlock() - - if !db.exists(k) { - return nil, ErrKeyNotFound - } - if db.t(k) != "list" { - return nil, ErrWrongType - } - return db.listKeys[k], nil -} - -// Lpush prepends one value to a list. Returns the new length. -func (m *Miniredis) Lpush(k, v string) (int, error) { - return m.DB(m.selectedDB).Lpush(k, v) -} - -// Lpush prepends one value to a list. Returns the new length. -func (db *RedisDB) Lpush(k, v string) (int, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if db.exists(k) && db.t(k) != "list" { - return 0, ErrWrongType - } - return db.listLpush(k, v), nil -} - -// Lpop removes and returns the last element in a list. -func (m *Miniredis) Lpop(k string) (string, error) { - return m.DB(m.selectedDB).Lpop(k) -} - -// Lpop removes and returns the last element in a list. -func (db *RedisDB) Lpop(k string) (string, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if !db.exists(k) { - return "", ErrKeyNotFound - } - if db.t(k) != "list" { - return "", ErrWrongType - } - return db.listLpop(k), nil -} - -// RPush appends one or multiple values to a list. Returns the new length. -// An alias for Push -func (m *Miniredis) RPush(k string, v ...string) (int, error) { - return m.Push(k, v...) -} - -// Push add element at the end. Returns the new length. -func (m *Miniredis) Push(k string, v ...string) (int, error) { - return m.DB(m.selectedDB).Push(k, v...) -} - -// Push add element at the end. Is called RPUSH in redis. Returns the new length. -func (db *RedisDB) Push(k string, v ...string) (int, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if db.exists(k) && db.t(k) != "list" { - return 0, ErrWrongType - } - return db.listPush(k, v...), nil -} - -// RPop is an alias for Pop -func (m *Miniredis) RPop(k string) (string, error) { - return m.Pop(k) -} - -// Pop removes and returns the last element. Is called RPOP in Redis. -func (m *Miniredis) Pop(k string) (string, error) { - return m.DB(m.selectedDB).Pop(k) -} - -// Pop removes and returns the last element. Is called RPOP in Redis. -func (db *RedisDB) Pop(k string) (string, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if !db.exists(k) { - return "", ErrKeyNotFound - } - if db.t(k) != "list" { - return "", ErrWrongType - } - - return db.listPop(k), nil -} - -// SAdd adds keys to a set. Returns the number of new keys. -// Alias for SetAdd -func (m *Miniredis) SAdd(k string, elems ...string) (int, error) { - return m.SetAdd(k, elems...) -} - -// SetAdd adds keys to a set. Returns the number of new keys. -func (m *Miniredis) SetAdd(k string, elems ...string) (int, error) { - return m.DB(m.selectedDB).SetAdd(k, elems...) -} - -// SetAdd adds keys to a set. Returns the number of new keys. -func (db *RedisDB) SetAdd(k string, elems ...string) (int, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if db.exists(k) && db.t(k) != "set" { - return 0, ErrWrongType - } - return db.setAdd(k, elems...), nil -} - -// SMembers returns all keys in a set, sorted. -// Alias for Members. -func (m *Miniredis) SMembers(k string) ([]string, error) { - return m.Members(k) -} - -// Members returns all keys in a set, sorted. -func (m *Miniredis) Members(k string) ([]string, error) { - return m.DB(m.selectedDB).Members(k) -} - -// Members gives all set keys. Sorted. -func (db *RedisDB) Members(k string) ([]string, error) { - db.master.Lock() - defer db.master.Unlock() - - if !db.exists(k) { - return nil, ErrKeyNotFound - } - if db.t(k) != "set" { - return nil, ErrWrongType - } - return db.setMembers(k), nil -} - -// SIsMember tells if value is in the set. -// Alias for IsMember -func (m *Miniredis) SIsMember(k, v string) (bool, error) { - return m.IsMember(k, v) -} - -// IsMember tells if value is in the set. -func (m *Miniredis) IsMember(k, v string) (bool, error) { - return m.DB(m.selectedDB).IsMember(k, v) -} - -// IsMember tells if value is in the set. -func (db *RedisDB) IsMember(k, v string) (bool, error) { - db.master.Lock() - defer db.master.Unlock() - - if !db.exists(k) { - return false, ErrKeyNotFound - } - if db.t(k) != "set" { - return false, ErrWrongType - } - return db.setIsMember(k, v), nil -} - -// HKeys returns all (sorted) keys ('fields') for a hash key. -func (m *Miniredis) HKeys(k string) ([]string, error) { - return m.DB(m.selectedDB).HKeys(k) -} - -// HKeys returns all (sorted) keys ('fields') for a hash key. -func (db *RedisDB) HKeys(key string) ([]string, error) { - db.master.Lock() - defer db.master.Unlock() - - if !db.exists(key) { - return nil, ErrKeyNotFound - } - if db.t(key) != "hash" { - return nil, ErrWrongType - } - return db.hashFields(key), nil -} - -// Del deletes a key and any expiration value. Returns whether there was a key. -func (m *Miniredis) Del(k string) bool { - return m.DB(m.selectedDB).Del(k) -} - -// Del deletes a key and any expiration value. Returns whether there was a key. -func (db *RedisDB) Del(k string) bool { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if !db.exists(k) { - return false - } - db.del(k, true) - return true -} - -// Unlink deletes a key and any expiration value. Returns where there was a key. -// It's exactly the same as Del() and is not async. It is here for the consistency. -func (m *Miniredis) Unlink(k string) bool { - return m.Del(k) -} - -// Unlink deletes a key and any expiration value. Returns where there was a key. -// It's exactly the same as Del() and is not async. It is here for the consistency. -func (db *RedisDB) Unlink(k string) bool { - return db.Del(k) -} - -// TTL is the left over time to live. As set via EXPIRE, PEXPIRE, EXPIREAT, -// PEXPIREAT. -// Note: this direct function returns 0 if there is no TTL set, unlike redis, -// which returns -1. -func (m *Miniredis) TTL(k string) time.Duration { - return m.DB(m.selectedDB).TTL(k) -} - -// TTL is the left over time to live. As set via EXPIRE, PEXPIRE, EXPIREAT, -// PEXPIREAT. -// 0 if not set. -func (db *RedisDB) TTL(k string) time.Duration { - db.master.Lock() - defer db.master.Unlock() - - return db.ttl[k] -} - -// SetTTL sets the TTL of a key. -func (m *Miniredis) SetTTL(k string, ttl time.Duration) { - m.DB(m.selectedDB).SetTTL(k, ttl) -} - -// SetTTL sets the time to live of a key. -func (db *RedisDB) SetTTL(k string, ttl time.Duration) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - db.ttl[k] = ttl - db.keyVersion[k]++ -} - -// Type gives the type of a key, or "" -func (m *Miniredis) Type(k string) string { - return m.DB(m.selectedDB).Type(k) -} - -// Type gives the type of a key, or "" -func (db *RedisDB) Type(k string) string { - db.master.Lock() - defer db.master.Unlock() - - return db.t(k) -} - -// Exists tells whether a key exists. -func (m *Miniredis) Exists(k string) bool { - return m.DB(m.selectedDB).Exists(k) -} - -// Exists tells whether a key exists. -func (db *RedisDB) Exists(k string) bool { - db.master.Lock() - defer db.master.Unlock() - - return db.exists(k) -} - -// HGet returns hash keys added with HSET. -// This will return an empty string if the key is not set. Redis would return -// a nil. -// Returns empty string when the key is of a different type. -func (m *Miniredis) HGet(k, f string) string { - return m.DB(m.selectedDB).HGet(k, f) -} - -// HGet returns hash keys added with HSET. -// Returns empty string when the key is of a different type. -func (db *RedisDB) HGet(k, f string) string { - db.master.Lock() - defer db.master.Unlock() - - h, ok := db.hashKeys[k] - if !ok { - return "" - } - return h[f] -} - -// HSet sets hash keys. -// If there is another key by the same name it will be gone. -func (m *Miniredis) HSet(k string, fv ...string) { - m.DB(m.selectedDB).HSet(k, fv...) -} - -// HSet sets hash keys. -// If there is another key by the same name it will be gone. -func (db *RedisDB) HSet(k string, fv ...string) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - db.hashSet(k, fv...) -} - -// HDel deletes a hash key. -func (m *Miniredis) HDel(k, f string) { - m.DB(m.selectedDB).HDel(k, f) -} - -// HDel deletes a hash key. -func (db *RedisDB) HDel(k, f string) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - db.hdel(k, f) -} - -func (db *RedisDB) hdel(k, f string) { - if _, ok := db.hashKeys[k]; !ok { - return - } - delete(db.hashKeys[k], f) - db.keyVersion[k]++ -} - -// HIncrBy increases the integer value of a hash field by delta (int). -func (m *Miniredis) HIncrBy(k, f string, delta int) (int, error) { - return m.HIncr(k, f, delta) -} - -// HIncr increases a key/field by delta (int). -func (m *Miniredis) HIncr(k, f string, delta int) (int, error) { - return m.DB(m.selectedDB).HIncr(k, f, delta) -} - -// HIncr increases a key/field by delta (int). -func (db *RedisDB) HIncr(k, f string, delta int) (int, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - return db.hashIncr(k, f, delta) -} - -// HIncrByFloat increases a key/field by delta (float). -func (m *Miniredis) HIncrByFloat(k, f string, delta float64) (float64, error) { - return m.HIncrfloat(k, f, delta) -} - -// HIncrfloat increases a key/field by delta (float). -func (m *Miniredis) HIncrfloat(k, f string, delta float64) (float64, error) { - return m.DB(m.selectedDB).HIncrfloat(k, f, delta) -} - -// HIncrfloat increases a key/field by delta (float). -func (db *RedisDB) HIncrfloat(k, f string, delta float64) (float64, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - v, err := db.hashIncrfloat(k, f, big.NewFloat(delta)) - if err != nil { - return 0, err - } - vf, _ := v.Float64() - return vf, nil -} - -// SRem removes fields from a set. Returns number of deleted fields. -func (m *Miniredis) SRem(k string, fields ...string) (int, error) { - return m.DB(m.selectedDB).SRem(k, fields...) -} - -// SRem removes fields from a set. Returns number of deleted fields. -func (db *RedisDB) SRem(k string, fields ...string) (int, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if !db.exists(k) { - return 0, ErrKeyNotFound - } - if db.t(k) != "set" { - return 0, ErrWrongType - } - return db.setRem(k, fields...), nil -} - -// ZAdd adds a score,member to a sorted set. -func (m *Miniredis) ZAdd(k string, score float64, member string) (bool, error) { - return m.DB(m.selectedDB).ZAdd(k, score, member) -} - -// ZAdd adds a score,member to a sorted set. -func (db *RedisDB) ZAdd(k string, score float64, member string) (bool, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if db.exists(k) && db.t(k) != "zset" { - return false, ErrWrongType - } - return db.ssetAdd(k, score, member), nil -} - -// ZMembers returns all members of a sorted set by score -func (m *Miniredis) ZMembers(k string) ([]string, error) { - return m.DB(m.selectedDB).ZMembers(k) -} - -// ZMembers returns all members of a sorted set by score -func (db *RedisDB) ZMembers(k string) ([]string, error) { - db.master.Lock() - defer db.master.Unlock() - - if !db.exists(k) { - return nil, ErrKeyNotFound - } - if db.t(k) != "zset" { - return nil, ErrWrongType - } - return db.ssetMembers(k), nil -} - -// SortedSet returns a raw string->float64 map. -func (m *Miniredis) SortedSet(k string) (map[string]float64, error) { - return m.DB(m.selectedDB).SortedSet(k) -} - -// SortedSet returns a raw string->float64 map. -func (db *RedisDB) SortedSet(k string) (map[string]float64, error) { - db.master.Lock() - defer db.master.Unlock() - - if !db.exists(k) { - return nil, ErrKeyNotFound - } - if db.t(k) != "zset" { - return nil, ErrWrongType - } - return db.sortedSet(k), nil -} - -// ZRem deletes a member. Returns whether the was a key. -func (m *Miniredis) ZRem(k, member string) (bool, error) { - return m.DB(m.selectedDB).ZRem(k, member) -} - -// ZRem deletes a member. Returns whether the was a key. -func (db *RedisDB) ZRem(k, member string) (bool, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - if !db.exists(k) { - return false, ErrKeyNotFound - } - if db.t(k) != "zset" { - return false, ErrWrongType - } - return db.ssetRem(k, member), nil -} - -// ZScore gives the score of a sorted set member. -func (m *Miniredis) ZScore(k, member string) (float64, error) { - return m.DB(m.selectedDB).ZScore(k, member) -} - -// ZScore gives the score of a sorted set member. -func (db *RedisDB) ZScore(k, member string) (float64, error) { - db.master.Lock() - defer db.master.Unlock() - - if !db.exists(k) { - return 0, ErrKeyNotFound - } - if db.t(k) != "zset" { - return 0, ErrWrongType - } - return db.ssetScore(k, member), nil -} - -// ZScore gives scores of a list of members in a sorted set. -func (m *Miniredis) ZMScore(k string, members ...string) ([]float64, error) { - return m.DB(m.selectedDB).ZMScore(k, members) -} - -func (db *RedisDB) ZMScore(k string, members []string) ([]float64, error) { - db.master.Lock() - defer db.master.Unlock() - - if !db.exists(k) { - return nil, ErrKeyNotFound - } - if db.t(k) != "zset" { - return nil, ErrWrongType - } - return db.ssetMScore(k, members), nil -} - -// XAdd adds an entry to a stream. `id` can be left empty or be '*'. -// If a value is given normal XADD rules apply. Values should be an even -// length. -func (m *Miniredis) XAdd(k string, id string, values []string) (string, error) { - return m.DB(m.selectedDB).XAdd(k, id, values) -} - -// XAdd adds an entry to a stream. `id` can be left empty or be '*'. -// If a value is given normal XADD rules apply. Values should be an even -// length. -func (db *RedisDB) XAdd(k string, id string, values []string) (string, error) { - db.master.Lock() - defer db.master.Unlock() - defer db.master.signal.Broadcast() - - s, err := db.stream(k) - if err != nil { - return "", err - } - if s == nil { - s, _ = db.newStream(k) - } - - return s.add(id, values, db.master.effectiveNow()) -} - -// Stream returns a slice of stream entries. Oldest first. -func (m *Miniredis) Stream(k string) ([]StreamEntry, error) { - return m.DB(m.selectedDB).Stream(k) -} - -// Stream returns a slice of stream entries. Oldest first. -func (db *RedisDB) Stream(key string) ([]StreamEntry, error) { - db.master.Lock() - defer db.master.Unlock() - - s, err := db.stream(key) - if err != nil { - return nil, err - } - if s == nil { - return nil, nil - } - return s.entries, nil -} - -// Publish a message to subscribers. Returns the number of receivers. -func (m *Miniredis) Publish(channel, message string) int { - m.Lock() - defer m.Unlock() - - return m.publish(channel, message) -} - -// PubSubChannels is "PUBSUB CHANNELS ". An empty pattern is fine -// (meaning all channels). -// Returned channels will be ordered alphabetically. -func (m *Miniredis) PubSubChannels(pattern string) []string { - m.Lock() - defer m.Unlock() - - return activeChannels(m.allSubscribers(), pattern) -} - -// PubSubNumSub is "PUBSUB NUMSUB [channels]". It returns all channels with their -// subscriber count. -func (m *Miniredis) PubSubNumSub(channels ...string) map[string]int { - m.Lock() - defer m.Unlock() - - subs := m.allSubscribers() - res := map[string]int{} - for _, channel := range channels { - res[channel] = countSubs(subs, channel) - } - return res -} - -// PubSubNumPat is "PUBSUB NUMPAT" -func (m *Miniredis) PubSubNumPat() int { - m.Lock() - defer m.Unlock() - - return countPsubs(m.allSubscribers()) -} - -// PfAdd adds keys to a hll. Returns the flag which equals to 1 if the inner hll value has been changed. -func (m *Miniredis) PfAdd(k string, elems ...string) (int, error) { - return m.DB(m.selectedDB).HllAdd(k, elems...) -} - -// HllAdd adds keys to a hll. Returns the flag which equals to true if the inner hll value has been changed. -func (db *RedisDB) HllAdd(k string, elems ...string) (int, error) { - db.master.Lock() - defer db.master.Unlock() - - if db.exists(k) && db.t(k) != "hll" { - return 0, ErrWrongType - } - return db.hllAdd(k, elems...), nil -} - -// PfCount returns an estimation of the amount of elements previously added to a hll. -func (m *Miniredis) PfCount(keys ...string) (int, error) { - return m.DB(m.selectedDB).HllCount(keys...) -} - -// HllCount returns an estimation of the amount of elements previously added to a hll. -func (db *RedisDB) HllCount(keys ...string) (int, error) { - db.master.Lock() - defer db.master.Unlock() - - return db.hllCount(keys) -} - -// PfMerge merges all the input hlls into a hll under destKey key. -func (m *Miniredis) PfMerge(destKey string, sourceKeys ...string) error { - return m.DB(m.selectedDB).HllMerge(destKey, sourceKeys...) -} - -// HllMerge merges all the input hlls into a hll under destKey key. -func (db *RedisDB) HllMerge(destKey string, sourceKeys ...string) error { - db.master.Lock() - defer db.master.Unlock() - - return db.hllMerge(append([]string{destKey}, sourceKeys...)) -} - -// Copy a value. -// Needs the IDs of both the source and dest DBs (which can differ). -// Returns ErrKeyNotFound if src does not exist. -// Overwrites dest if it already exists (unlike the redis command, which needs a flag to allow that). -func (m *Miniredis) Copy(srcDB int, src string, destDB int, dest string) error { - return m.copy(m.DB(srcDB), src, m.DB(destDB), dest) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/geo.go b/vendor/github.com/alicebob/miniredis/v2/geo.go deleted file mode 100644 index 3028a1670..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/geo.go +++ /dev/null @@ -1,46 +0,0 @@ -package miniredis - -import ( - "math" - - "github.com/alicebob/miniredis/v2/geohash" -) - -func toGeohash(long, lat float64) uint64 { - return geohash.EncodeIntWithPrecision(lat, long, 52) -} - -func fromGeohash(score uint64) (float64, float64) { - lat, long := geohash.DecodeIntWithPrecision(score, 52) - return long, lat -} - -// haversin(θ) function -func hsin(theta float64) float64 { - return math.Pow(math.Sin(theta/2), 2) -} - -// distance function returns the distance (in meters) between two points of -// a given longitude and latitude relatively accurately (using a spherical -// approximation of the Earth) through the Haversin Distance Formula for -// great arc distance on a sphere with accuracy for small distances -// point coordinates are supplied in degrees and converted into rad. in the func -// distance returned is meters -// http://en.wikipedia.org/wiki/Haversine_formula -// Source: https://gist.github.com/cdipaolo/d3f8db3848278b49db68 -func distance(lat1, lon1, lat2, lon2 float64) float64 { - // convert to radians - // must cast radius as float to multiply later - var la1, lo1, la2, lo2 float64 - la1 = lat1 * math.Pi / 180 - lo1 = lon1 * math.Pi / 180 - la2 = lat2 * math.Pi / 180 - lo2 = lon2 * math.Pi / 180 - - earth := 6372797.560856 // Earth radius in METERS, according to src/geohash_helper.c - - // calculate - h := hsin(la2-la1) + math.Cos(la1)*math.Cos(la2)*hsin(lo2-lo1) - - return 2 * earth * math.Asin(math.Sqrt(h)) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/geohash/LICENSE b/vendor/github.com/alicebob/miniredis/v2/geohash/LICENSE deleted file mode 100644 index c0190c9a6..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/geohash/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Michael McLoughlin - -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/alicebob/miniredis/v2/geohash/README.md b/vendor/github.com/alicebob/miniredis/v2/geohash/README.md deleted file mode 100644 index c1a12d144..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/geohash/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This is a (selected) copy of github.com/mmcloughlin/geohash with the latitude -range changed from 90 to ~85, to align with the algorithm use by Redis. diff --git a/vendor/github.com/alicebob/miniredis/v2/geohash/base32.go b/vendor/github.com/alicebob/miniredis/v2/geohash/base32.go deleted file mode 100644 index 916b272b9..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/geohash/base32.go +++ /dev/null @@ -1,44 +0,0 @@ -package geohash - -// encoding encapsulates an encoding defined by a given base32 alphabet. -type encoding struct { - encode string - decode [256]byte -} - -// newEncoding constructs a new encoding defined by the given alphabet, -// which must be a 32-byte string. -func newEncoding(encoder string) *encoding { - e := new(encoding) - e.encode = encoder - for i := 0; i < len(e.decode); i++ { - e.decode[i] = 0xff - } - for i := 0; i < len(encoder); i++ { - e.decode[encoder[i]] = byte(i) - } - return e -} - -// Decode string into bits of a 64-bit word. The string s may be at most 12 -// characters. -func (e *encoding) Decode(s string) uint64 { - x := uint64(0) - for i := 0; i < len(s); i++ { - x = (x << 5) | uint64(e.decode[s[i]]) - } - return x -} - -// Encode bits of 64-bit word into a string. -func (e *encoding) Encode(x uint64) string { - b := [12]byte{} - for i := 0; i < 12; i++ { - b[11-i] = e.encode[x&0x1f] - x >>= 5 - } - return string(b[:]) -} - -// Base32Encoding with the Geohash alphabet. -var base32encoding = newEncoding("0123456789bcdefghjkmnpqrstuvwxyz") diff --git a/vendor/github.com/alicebob/miniredis/v2/geohash/geohash.go b/vendor/github.com/alicebob/miniredis/v2/geohash/geohash.go deleted file mode 100644 index 0e0ca2b28..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/geohash/geohash.go +++ /dev/null @@ -1,269 +0,0 @@ -// Package geohash provides encoding and decoding of string and integer -// geohashes. -package geohash - -import ( - "math" -) - -const ( - ENC_LAT = 85.05112878 - ENC_LONG = 180.0 -) - -// Direction represents directions in the latitute/longitude space. -type Direction int - -// Cardinal and intercardinal directions -const ( - North Direction = iota - NorthEast - East - SouthEast - South - SouthWest - West - NorthWest -) - -// Encode the point (lat, lng) as a string geohash with the standard 12 -// characters of precision. -func Encode(lat, lng float64) string { - return EncodeWithPrecision(lat, lng, 12) -} - -// EncodeWithPrecision encodes the point (lat, lng) as a string geohash with -// the specified number of characters of precision (max 12). -func EncodeWithPrecision(lat, lng float64, chars uint) string { - bits := 5 * chars - inthash := EncodeIntWithPrecision(lat, lng, bits) - enc := base32encoding.Encode(inthash) - return enc[12-chars:] -} - -// encodeInt provides a Go implementation of integer geohash. This is the -// default implementation of EncodeInt, but optimized versions are provided -// for certain architectures. -func EncodeInt(lat, lng float64) uint64 { - latInt := encodeRange(lat, ENC_LAT) - lngInt := encodeRange(lng, ENC_LONG) - return interleave(latInt, lngInt) -} - -// EncodeIntWithPrecision encodes the point (lat, lng) to an integer with the -// specified number of bits. -func EncodeIntWithPrecision(lat, lng float64, bits uint) uint64 { - hash := EncodeInt(lat, lng) - return hash >> (64 - bits) -} - -// Box represents a rectangle in latitude/longitude space. -type Box struct { - MinLat float64 - MaxLat float64 - MinLng float64 - MaxLng float64 -} - -// Center returns the center of the box. -func (b Box) Center() (lat, lng float64) { - lat = (b.MinLat + b.MaxLat) / 2.0 - lng = (b.MinLng + b.MaxLng) / 2.0 - return -} - -// Contains decides whether (lat, lng) is contained in the box. The -// containment test is inclusive of the edges and corners. -func (b Box) Contains(lat, lng float64) bool { - return (b.MinLat <= lat && lat <= b.MaxLat && - b.MinLng <= lng && lng <= b.MaxLng) -} - -// errorWithPrecision returns the error range in latitude and longitude for in -// integer geohash with bits of precision. -func errorWithPrecision(bits uint) (latErr, lngErr float64) { - b := int(bits) - latBits := b / 2 - lngBits := b - latBits - latErr = math.Ldexp(180.0, -latBits) - lngErr = math.Ldexp(360.0, -lngBits) - return -} - -// BoundingBox returns the region encoded by the given string geohash. -func BoundingBox(hash string) Box { - bits := uint(5 * len(hash)) - inthash := base32encoding.Decode(hash) - return BoundingBoxIntWithPrecision(inthash, bits) -} - -// BoundingBoxIntWithPrecision returns the region encoded by the integer -// geohash with the specified precision. -func BoundingBoxIntWithPrecision(hash uint64, bits uint) Box { - fullHash := hash << (64 - bits) - latInt, lngInt := deinterleave(fullHash) - lat := decodeRange(latInt, ENC_LAT) - lng := decodeRange(lngInt, ENC_LONG) - latErr, lngErr := errorWithPrecision(bits) - return Box{ - MinLat: lat, - MaxLat: lat + latErr, - MinLng: lng, - MaxLng: lng + lngErr, - } -} - -// BoundingBoxInt returns the region encoded by the given 64-bit integer -// geohash. -func BoundingBoxInt(hash uint64) Box { - return BoundingBoxIntWithPrecision(hash, 64) -} - -// DecodeCenter decodes the string geohash to the central point of the bounding box. -func DecodeCenter(hash string) (lat, lng float64) { - box := BoundingBox(hash) - return box.Center() -} - -// DecodeIntWithPrecision decodes the provided integer geohash with bits of -// precision to a (lat, lng) point. -func DecodeIntWithPrecision(hash uint64, bits uint) (lat, lng float64) { - box := BoundingBoxIntWithPrecision(hash, bits) - return box.Center() -} - -// DecodeInt decodes the provided 64-bit integer geohash to a (lat, lng) point. -func DecodeInt(hash uint64) (lat, lng float64) { - return DecodeIntWithPrecision(hash, 64) -} - -// Neighbors returns a slice of geohash strings that correspond to the provided -// geohash's neighbors. -func Neighbors(hash string) []string { - box := BoundingBox(hash) - lat, lng := box.Center() - latDelta := box.MaxLat - box.MinLat - lngDelta := box.MaxLng - box.MinLng - precision := uint(len(hash)) - return []string{ - // N - EncodeWithPrecision(lat+latDelta, lng, precision), - // NE, - EncodeWithPrecision(lat+latDelta, lng+lngDelta, precision), - // E, - EncodeWithPrecision(lat, lng+lngDelta, precision), - // SE, - EncodeWithPrecision(lat-latDelta, lng+lngDelta, precision), - // S, - EncodeWithPrecision(lat-latDelta, lng, precision), - // SW, - EncodeWithPrecision(lat-latDelta, lng-lngDelta, precision), - // W, - EncodeWithPrecision(lat, lng-lngDelta, precision), - // NW - EncodeWithPrecision(lat+latDelta, lng-lngDelta, precision), - } -} - -// NeighborsInt returns a slice of uint64s that correspond to the provided hash's -// neighbors at 64-bit precision. -func NeighborsInt(hash uint64) []uint64 { - return NeighborsIntWithPrecision(hash, 64) -} - -// NeighborsIntWithPrecision returns a slice of uint64s that correspond to the -// provided hash's neighbors at the given precision. -func NeighborsIntWithPrecision(hash uint64, bits uint) []uint64 { - box := BoundingBoxIntWithPrecision(hash, bits) - lat, lng := box.Center() - latDelta := box.MaxLat - box.MinLat - lngDelta := box.MaxLng - box.MinLng - return []uint64{ - // N - EncodeIntWithPrecision(lat+latDelta, lng, bits), - // NE, - EncodeIntWithPrecision(lat+latDelta, lng+lngDelta, bits), - // E, - EncodeIntWithPrecision(lat, lng+lngDelta, bits), - // SE, - EncodeIntWithPrecision(lat-latDelta, lng+lngDelta, bits), - // S, - EncodeIntWithPrecision(lat-latDelta, lng, bits), - // SW, - EncodeIntWithPrecision(lat-latDelta, lng-lngDelta, bits), - // W, - EncodeIntWithPrecision(lat, lng-lngDelta, bits), - // NW - EncodeIntWithPrecision(lat+latDelta, lng-lngDelta, bits), - } -} - -// Neighbor returns a geohash string that corresponds to the provided -// geohash's neighbor in the provided direction -func Neighbor(hash string, direction Direction) string { - return Neighbors(hash)[direction] -} - -// NeighborInt returns a uint64 that corresponds to the provided hash's -// neighbor in the provided direction at 64-bit precision. -func NeighborInt(hash uint64, direction Direction) uint64 { - return NeighborsIntWithPrecision(hash, 64)[direction] -} - -// NeighborIntWithPrecision returns a uint64s that corresponds to the -// provided hash's neighbor in the provided direction at the given precision. -func NeighborIntWithPrecision(hash uint64, bits uint, direction Direction) uint64 { - return NeighborsIntWithPrecision(hash, bits)[direction] -} - -// precalculated for performance -var exp232 = math.Exp2(32) - -// Encode the position of x within the range -r to +r as a 32-bit integer. -func encodeRange(x, r float64) uint32 { - p := (x + r) / (2 * r) - return uint32(p * exp232) -} - -// Decode the 32-bit range encoding X back to a value in the range -r to +r. -func decodeRange(X uint32, r float64) float64 { - p := float64(X) / exp232 - x := 2*r*p - r - return x -} - -// Spread out the 32 bits of x into 64 bits, where the bits of x occupy even -// bit positions. -func spread(x uint32) uint64 { - X := uint64(x) - X = (X | (X << 16)) & 0x0000ffff0000ffff - X = (X | (X << 8)) & 0x00ff00ff00ff00ff - X = (X | (X << 4)) & 0x0f0f0f0f0f0f0f0f - X = (X | (X << 2)) & 0x3333333333333333 - X = (X | (X << 1)) & 0x5555555555555555 - return X -} - -// Interleave the bits of x and y. In the result, x and y occupy even and odd -// bitlevels, respectively. -func interleave(x, y uint32) uint64 { - return spread(x) | (spread(y) << 1) -} - -// Squash the even bitlevels of X into a 32-bit word. Odd bitlevels of X are -// ignored, and may take any value. -func squash(X uint64) uint32 { - X &= 0x5555555555555555 - X = (X | (X >> 1)) & 0x3333333333333333 - X = (X | (X >> 2)) & 0x0f0f0f0f0f0f0f0f - X = (X | (X >> 4)) & 0x00ff00ff00ff00ff - X = (X | (X >> 8)) & 0x0000ffff0000ffff - X = (X | (X >> 16)) & 0x00000000ffffffff - return uint32(X) -} - -// Deinterleave the bits of X into 32-bit words containing the even and odd -// bitlevels of X, respectively. -func deinterleave(X uint64) (uint32, uint32) { - return squash(X), squash(X >> 1) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/hll.go b/vendor/github.com/alicebob/miniredis/v2/hll.go deleted file mode 100644 index d00ad78a2..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/hll.go +++ /dev/null @@ -1,42 +0,0 @@ -package miniredis - -import ( - "github.com/alicebob/miniredis/v2/hyperloglog" -) - -type hll struct { - inner *hyperloglog.Sketch -} - -func newHll() *hll { - return &hll{ - inner: hyperloglog.New14(), - } -} - -// Add returns true if cardinality has been changed, or false otherwise. -func (h *hll) Add(item []byte) bool { - return h.inner.Insert(item) -} - -// Count returns the estimation of a set cardinality. -func (h *hll) Count() int { - return int(h.inner.Estimate()) -} - -// Merge merges the other hll into original one (not making a copy but doing this in place). -func (h *hll) Merge(other *hll) { - _ = h.inner.Merge(other.inner) -} - -// Bytes returns raw-bytes representation of hll data structure. -func (h *hll) Bytes() []byte { - dataBytes, _ := h.inner.MarshalBinary() - return dataBytes -} - -func (h *hll) copy() *hll { - return &hll{ - inner: h.inner.Clone(), - } -} diff --git a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/LICENSE b/vendor/github.com/alicebob/miniredis/v2/hyperloglog/LICENSE deleted file mode 100644 index 8436fdb43..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Axiom 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/alicebob/miniredis/v2/hyperloglog/README.md b/vendor/github.com/alicebob/miniredis/v2/hyperloglog/README.md deleted file mode 100644 index 0fac68df2..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/README.md +++ /dev/null @@ -1 +0,0 @@ -This is a copy of github.com/axiomhq/hyperloglog. \ No newline at end of file diff --git a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/compressed.go b/vendor/github.com/alicebob/miniredis/v2/hyperloglog/compressed.go deleted file mode 100644 index 4b908be46..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/compressed.go +++ /dev/null @@ -1,180 +0,0 @@ -package hyperloglog - -import "encoding/binary" - -// Original author of this file is github.com/clarkduvall/hyperloglog -type iterable interface { - decode(i int, last uint32) (uint32, int) - Len() int - Iter() *iterator -} - -type iterator struct { - i int - last uint32 - v iterable -} - -func (iter *iterator) Next() uint32 { - n, i := iter.v.decode(iter.i, iter.last) - iter.last = n - iter.i = i - return n -} - -func (iter *iterator) Peek() uint32 { - n, _ := iter.v.decode(iter.i, iter.last) - return n -} - -func (iter iterator) HasNext() bool { - return iter.i < iter.v.Len() -} - -type compressedList struct { - count uint32 - last uint32 - b variableLengthList -} - -func (v *compressedList) Clone() *compressedList { - if v == nil { - return nil - } - - newV := &compressedList{ - count: v.count, - last: v.last, - } - - newV.b = make(variableLengthList, len(v.b)) - copy(newV.b, v.b) - return newV -} - -func (v *compressedList) MarshalBinary() (data []byte, err error) { - // Marshal the variableLengthList - bdata, err := v.b.MarshalBinary() - if err != nil { - return nil, err - } - - // At least 4 bytes for the two fixed sized values plus the size of bdata. - data = make([]byte, 0, 4+4+len(bdata)) - - // Marshal the count and last values. - data = append(data, []byte{ - // Number of items in the list. - byte(v.count >> 24), - byte(v.count >> 16), - byte(v.count >> 8), - byte(v.count), - // The last item in the list. - byte(v.last >> 24), - byte(v.last >> 16), - byte(v.last >> 8), - byte(v.last), - }...) - - // Append the list - return append(data, bdata...), nil -} - -func (v *compressedList) UnmarshalBinary(data []byte) error { - if len(data) < 12 { - return ErrorTooShort - } - - // Set the count. - v.count, data = binary.BigEndian.Uint32(data[:4]), data[4:] - - // Set the last value. - v.last, data = binary.BigEndian.Uint32(data[:4]), data[4:] - - // Set the list. - sz, data := binary.BigEndian.Uint32(data[:4]), data[4:] - v.b = make([]uint8, sz) - if uint32(len(data)) < sz { - return ErrorTooShort - } - for i := uint32(0); i < sz; i++ { - v.b[i] = data[i] - } - return nil -} - -func newCompressedList() *compressedList { - v := &compressedList{} - v.b = make(variableLengthList, 0) - return v -} - -func (v *compressedList) Len() int { - return len(v.b) -} - -func (v *compressedList) decode(i int, last uint32) (uint32, int) { - n, i := v.b.decode(i, last) - return n + last, i -} - -func (v *compressedList) Append(x uint32) { - v.count++ - v.b = v.b.Append(x - v.last) - v.last = x -} - -func (v *compressedList) Iter() *iterator { - return &iterator{0, 0, v} -} - -type variableLengthList []uint8 - -func (v variableLengthList) MarshalBinary() (data []byte, err error) { - // 4 bytes for the size of the list, and a byte for each element in the - // list. - data = make([]byte, 0, 4+v.Len()) - - // Length of the list. We only need 32 bits because the size of the set - // couldn't exceed that on 32 bit architectures. - sz := v.Len() - data = append(data, []byte{ - byte(sz >> 24), - byte(sz >> 16), - byte(sz >> 8), - byte(sz), - }...) - - // Marshal each element in the list. - for i := 0; i < sz; i++ { - data = append(data, v[i]) - } - - return data, nil -} - -func (v variableLengthList) Len() int { - return len(v) -} - -func (v *variableLengthList) Iter() *iterator { - return &iterator{0, 0, v} -} - -func (v variableLengthList) decode(i int, last uint32) (uint32, int) { - var x uint32 - j := i - for ; v[j]&0x80 != 0; j++ { - x |= uint32(v[j]&0x7f) << (uint(j-i) * 7) - } - x |= uint32(v[j]) << (uint(j-i) * 7) - return x, j + 1 -} - -func (v variableLengthList) Append(x uint32) variableLengthList { - for x&0xffffff80 != 0 { - v = append(v, uint8((x&0x7f)|0x80)) - x >>= 7 - } - return append(v, uint8(x&0x7f)) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/hyperloglog.go b/vendor/github.com/alicebob/miniredis/v2/hyperloglog/hyperloglog.go deleted file mode 100644 index 826639158..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/hyperloglog.go +++ /dev/null @@ -1,424 +0,0 @@ -package hyperloglog - -import ( - "encoding/binary" - "errors" - "fmt" - "math" - "sort" -) - -const ( - capacity = uint8(16) - pp = uint8(25) - mp = uint32(1) << pp - version = 1 -) - -// Sketch is a HyperLogLog data-structure for the count-distinct problem, -// approximating the number of distinct elements in a multiset. -type Sketch struct { - p uint8 - b uint8 - m uint32 - alpha float64 - tmpSet set - sparseList *compressedList - regs *registers -} - -// New returns a HyperLogLog Sketch with 2^14 registers (precision 14) -func New() *Sketch { - return New14() -} - -// New14 returns a HyperLogLog Sketch with 2^14 registers (precision 14) -func New14() *Sketch { - sk, _ := newSketch(14, true) - return sk -} - -// New16 returns a HyperLogLog Sketch with 2^16 registers (precision 16) -func New16() *Sketch { - sk, _ := newSketch(16, true) - return sk -} - -// NewNoSparse returns a HyperLogLog Sketch with 2^14 registers (precision 14) -// that will not use a sparse representation -func NewNoSparse() *Sketch { - sk, _ := newSketch(14, false) - return sk -} - -// New16NoSparse returns a HyperLogLog Sketch with 2^16 registers (precision 16) -// that will not use a sparse representation -func New16NoSparse() *Sketch { - sk, _ := newSketch(16, false) - return sk -} - -// newSketch returns a HyperLogLog Sketch with 2^precision registers -func newSketch(precision uint8, sparse bool) (*Sketch, error) { - if precision < 4 || precision > 18 { - return nil, fmt.Errorf("p has to be >= 4 and <= 18") - } - m := uint32(math.Pow(2, float64(precision))) - s := &Sketch{ - m: m, - p: precision, - alpha: alpha(float64(m)), - } - if sparse { - s.tmpSet = set{} - s.sparseList = newCompressedList() - } else { - s.regs = newRegisters(m) - } - return s, nil -} - -func (sk *Sketch) sparse() bool { - return sk.sparseList != nil -} - -// Clone returns a deep copy of sk. -func (sk *Sketch) Clone() *Sketch { - return &Sketch{ - b: sk.b, - p: sk.p, - m: sk.m, - alpha: sk.alpha, - tmpSet: sk.tmpSet.Clone(), - sparseList: sk.sparseList.Clone(), - regs: sk.regs.clone(), - } -} - -// Converts to normal if the sparse list is too large. -func (sk *Sketch) maybeToNormal() { - if uint32(len(sk.tmpSet))*100 > sk.m { - sk.mergeSparse() - if uint32(sk.sparseList.Len()) > sk.m { - sk.toNormal() - } - } -} - -// Merge takes another Sketch and combines it with Sketch h. -// If Sketch h is using the sparse Sketch, it will be converted -// to the normal Sketch. -func (sk *Sketch) Merge(other *Sketch) error { - if other == nil { - // Nothing to do - return nil - } - cpOther := other.Clone() - - if sk.p != cpOther.p { - return errors.New("precisions must be equal") - } - - if sk.sparse() && other.sparse() { - for k := range other.tmpSet { - sk.tmpSet.add(k) - } - for iter := other.sparseList.Iter(); iter.HasNext(); { - sk.tmpSet.add(iter.Next()) - } - sk.maybeToNormal() - return nil - } - - if sk.sparse() { - sk.toNormal() - } - - if cpOther.sparse() { - for k := range cpOther.tmpSet { - i, r := decodeHash(k, cpOther.p, pp) - sk.insert(i, r) - } - - for iter := cpOther.sparseList.Iter(); iter.HasNext(); { - i, r := decodeHash(iter.Next(), cpOther.p, pp) - sk.insert(i, r) - } - } else { - if sk.b < cpOther.b { - sk.regs.rebase(cpOther.b - sk.b) - sk.b = cpOther.b - } else { - cpOther.regs.rebase(sk.b - cpOther.b) - cpOther.b = sk.b - } - - for i, v := range cpOther.regs.tailcuts { - v1 := v.get(0) - if v1 > sk.regs.get(uint32(i)*2) { - sk.regs.set(uint32(i)*2, v1) - } - v2 := v.get(1) - if v2 > sk.regs.get(1+uint32(i)*2) { - sk.regs.set(1+uint32(i)*2, v2) - } - } - } - return nil -} - -// Convert from sparse Sketch to dense Sketch. -func (sk *Sketch) toNormal() { - if len(sk.tmpSet) > 0 { - sk.mergeSparse() - } - - sk.regs = newRegisters(sk.m) - for iter := sk.sparseList.Iter(); iter.HasNext(); { - i, r := decodeHash(iter.Next(), sk.p, pp) - sk.insert(i, r) - } - - sk.tmpSet = nil - sk.sparseList = nil -} - -func (sk *Sketch) insert(i uint32, r uint8) bool { - changed := false - if r-sk.b >= capacity { - //overflow - db := sk.regs.min() - if db > 0 { - sk.b += db - sk.regs.rebase(db) - changed = true - } - } - if r > sk.b { - val := r - sk.b - if c1 := capacity - 1; c1 < val { - val = c1 - } - - if val > sk.regs.get(i) { - sk.regs.set(i, val) - changed = true - } - } - return changed -} - -// Insert adds element e to sketch -func (sk *Sketch) Insert(e []byte) bool { - x := hash(e) - return sk.InsertHash(x) -} - -// InsertHash adds hash x to sketch -func (sk *Sketch) InsertHash(x uint64) bool { - if sk.sparse() { - changed := sk.tmpSet.add(encodeHash(x, sk.p, pp)) - if !changed { - return false - } - if uint32(len(sk.tmpSet))*100 > sk.m/2 { - sk.mergeSparse() - if uint32(sk.sparseList.Len()) > sk.m/2 { - sk.toNormal() - } - } - return true - } else { - i, r := getPosVal(x, sk.p) - return sk.insert(uint32(i), r) - } -} - -// Estimate returns the cardinality of the Sketch -func (sk *Sketch) Estimate() uint64 { - if sk.sparse() { - sk.mergeSparse() - return uint64(linearCount(mp, mp-sk.sparseList.count)) - } - - sum, ez := sk.regs.sumAndZeros(sk.b) - m := float64(sk.m) - var est float64 - - var beta func(float64) float64 - if sk.p < 16 { - beta = beta14 - } else { - beta = beta16 - } - - if sk.b == 0 { - est = (sk.alpha * m * (m - ez) / (sum + beta(ez))) - } else { - est = (sk.alpha * m * m / sum) - } - - return uint64(est + 0.5) -} - -func (sk *Sketch) mergeSparse() { - if len(sk.tmpSet) == 0 { - return - } - - keys := make(uint64Slice, 0, len(sk.tmpSet)) - for k := range sk.tmpSet { - keys = append(keys, k) - } - sort.Sort(keys) - - newList := newCompressedList() - for iter, i := sk.sparseList.Iter(), 0; iter.HasNext() || i < len(keys); { - if !iter.HasNext() { - newList.Append(keys[i]) - i++ - continue - } - - if i >= len(keys) { - newList.Append(iter.Next()) - continue - } - - x1, x2 := iter.Peek(), keys[i] - if x1 == x2 { - newList.Append(iter.Next()) - i++ - } else if x1 > x2 { - newList.Append(x2) - i++ - } else { - newList.Append(iter.Next()) - } - } - - sk.sparseList = newList - sk.tmpSet = set{} -} - -// MarshalBinary implements the encoding.BinaryMarshaler interface. -func (sk *Sketch) MarshalBinary() (data []byte, err error) { - // Marshal a version marker. - data = append(data, version) - // Marshal p. - data = append(data, sk.p) - // Marshal b - data = append(data, sk.b) - - if sk.sparse() { - // It's using the sparse Sketch. - data = append(data, byte(1)) - - // Add the tmp_set - tsdata, err := sk.tmpSet.MarshalBinary() - if err != nil { - return nil, err - } - data = append(data, tsdata...) - - // Add the sparse Sketch - sdata, err := sk.sparseList.MarshalBinary() - if err != nil { - return nil, err - } - return append(data, sdata...), nil - } - - // It's using the dense Sketch. - data = append(data, byte(0)) - - // Add the dense sketch Sketch. - sz := len(sk.regs.tailcuts) - data = append(data, []byte{ - byte(sz >> 24), - byte(sz >> 16), - byte(sz >> 8), - byte(sz), - }...) - - // Marshal each element in the list. - for i := 0; i < len(sk.regs.tailcuts); i++ { - data = append(data, byte(sk.regs.tailcuts[i])) - } - - return data, nil -} - -// ErrorTooShort is an error that UnmarshalBinary try to parse too short -// binary. -var ErrorTooShort = errors.New("too short binary") - -// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. -func (sk *Sketch) UnmarshalBinary(data []byte) error { - if len(data) < 8 { - return ErrorTooShort - } - - // Unmarshal version. We may need this in the future if we make - // non-compatible changes. - _ = data[0] - - // Unmarshal p. - p := data[1] - - // Unmarshal b. - sk.b = data[2] - - // Determine if we need a sparse Sketch - sparse := data[3] == byte(1) - - // Make a newSketch Sketch if the precision doesn't match or if the Sketch was used - if sk.p != p || sk.regs != nil || len(sk.tmpSet) > 0 || (sk.sparseList != nil && sk.sparseList.Len() > 0) { - newh, err := newSketch(p, sparse) - if err != nil { - return err - } - newh.b = sk.b - *sk = *newh - } - - // h is now initialised with the correct p. We just need to fill the - // rest of the details out. - if sparse { - // Using the sparse Sketch. - - // Unmarshal the tmp_set. - tssz := binary.BigEndian.Uint32(data[4:8]) - sk.tmpSet = make(map[uint32]struct{}, tssz) - - // We need to unmarshal tssz values in total, and each value requires us - // to read 4 bytes. - tsLastByte := int((tssz * 4) + 8) - for i := 8; i < tsLastByte; i += 4 { - k := binary.BigEndian.Uint32(data[i : i+4]) - sk.tmpSet[k] = struct{}{} - } - - // Unmarshal the sparse Sketch. - return sk.sparseList.UnmarshalBinary(data[tsLastByte:]) - } - - // Using the dense Sketch. - sk.sparseList = nil - sk.tmpSet = nil - dsz := binary.BigEndian.Uint32(data[4:8]) - sk.regs = newRegisters(dsz * 2) - data = data[8:] - - for i, val := range data { - sk.regs.tailcuts[i] = reg(val) - if uint8(sk.regs.tailcuts[i]<<4>>4) > 0 { - sk.regs.nz-- - } - if uint8(sk.regs.tailcuts[i]>>4) > 0 { - sk.regs.nz-- - } - } - - return nil -} diff --git a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/registers.go b/vendor/github.com/alicebob/miniredis/v2/hyperloglog/registers.go deleted file mode 100644 index 19bb5d47f..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/registers.go +++ /dev/null @@ -1,114 +0,0 @@ -package hyperloglog - -import ( - "math" -) - -type reg uint8 -type tailcuts []reg - -type registers struct { - tailcuts - nz uint32 -} - -func (r *reg) set(offset, val uint8) bool { - var isZero bool - if offset == 0 { - isZero = *r < 16 - tmpVal := uint8((*r) << 4 >> 4) - *r = reg(tmpVal | (val << 4)) - } else { - isZero = *r&0x0f == 0 - tmpVal := uint8((*r) >> 4 << 4) - *r = reg(tmpVal | val) - } - return isZero -} - -func (r *reg) get(offset uint8) uint8 { - if offset == 0 { - return uint8((*r) >> 4) - } - return uint8((*r) << 4 >> 4) -} - -func newRegisters(size uint32) *registers { - return ®isters{ - tailcuts: make(tailcuts, size/2), - nz: size, - } -} - -func (rs *registers) clone() *registers { - if rs == nil { - return nil - } - tc := make([]reg, len(rs.tailcuts)) - copy(tc, rs.tailcuts) - return ®isters{ - tailcuts: tc, - nz: rs.nz, - } -} - -func (rs *registers) rebase(delta uint8) { - nz := uint32(len(rs.tailcuts)) * 2 - for i := range rs.tailcuts { - for j := uint8(0); j < 2; j++ { - val := rs.tailcuts[i].get(j) - if val >= delta { - rs.tailcuts[i].set(j, val-delta) - if val-delta > 0 { - nz-- - } - } - } - } - rs.nz = nz -} - -func (rs *registers) set(i uint32, val uint8) { - offset, index := uint8(i)&1, i/2 - if rs.tailcuts[index].set(offset, val) { - rs.nz-- - } -} - -func (rs *registers) get(i uint32) uint8 { - offset, index := uint8(i)&1, i/2 - return rs.tailcuts[index].get(offset) -} - -func (rs *registers) sumAndZeros(base uint8) (res, ez float64) { - for _, r := range rs.tailcuts { - for j := uint8(0); j < 2; j++ { - v := float64(base + r.get(j)) - if v == 0 { - ez++ - } - res += 1.0 / math.Pow(2.0, v) - } - } - rs.nz = uint32(ez) - return res, ez -} - -func (rs *registers) min() uint8 { - if rs.nz > 0 { - return 0 - } - min := uint8(math.MaxUint8) - for _, r := range rs.tailcuts { - if r == 0 || min == 0 { - return 0 - } - if val := uint8(r << 4 >> 4); val < min { - min = val - } - if val := uint8(r >> 4); val < min { - min = val - } - } - return min -} diff --git a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/sparse.go b/vendor/github.com/alicebob/miniredis/v2/hyperloglog/sparse.go deleted file mode 100644 index 8c457d327..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/sparse.go +++ /dev/null @@ -1,92 +0,0 @@ -package hyperloglog - -import ( - "math/bits" -) - -func getIndex(k uint32, p, pp uint8) uint32 { - if k&1 == 1 { - return bextr32(k, 32-p, p) - } - return bextr32(k, pp-p+1, p) -} - -// Encode a hash to be used in the sparse representation. -func encodeHash(x uint64, p, pp uint8) uint32 { - idx := uint32(bextr(x, 64-pp, pp)) - if bextr(x, 64-pp, pp-p) == 0 { - zeros := bits.LeadingZeros64((bextr(x, 0, 64-pp)<> 24), - byte(sl >> 16), - byte(sl >> 8), - byte(sl), - }...) - - // Marshal each element in the set. - for k := range s { - data = append(data, []byte{ - byte(k >> 24), - byte(k >> 16), - byte(k >> 8), - byte(k), - }...) - } - - return data, nil -} - -type uint64Slice []uint32 - -func (p uint64Slice) Len() int { return len(p) } -func (p uint64Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/utils.go b/vendor/github.com/alicebob/miniredis/v2/hyperloglog/utils.go deleted file mode 100644 index 896bf7e74..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/hyperloglog/utils.go +++ /dev/null @@ -1,69 +0,0 @@ -package hyperloglog - -import ( - "github.com/alicebob/miniredis/v2/metro" - "math" - "math/bits" -) - -var hash = hashFunc - -func beta14(ez float64) float64 { - zl := math.Log(ez + 1) - return -0.370393911*ez + - 0.070471823*zl + - 0.17393686*math.Pow(zl, 2) + - 0.16339839*math.Pow(zl, 3) + - -0.09237745*math.Pow(zl, 4) + - 0.03738027*math.Pow(zl, 5) + - -0.005384159*math.Pow(zl, 6) + - 0.00042419*math.Pow(zl, 7) -} - -func beta16(ez float64) float64 { - zl := math.Log(ez + 1) - return -0.37331876643753059*ez + - -1.41704077448122989*zl + - 0.40729184796612533*math.Pow(zl, 2) + - 1.56152033906584164*math.Pow(zl, 3) + - -0.99242233534286128*math.Pow(zl, 4) + - 0.26064681399483092*math.Pow(zl, 5) + - -0.03053811369682807*math.Pow(zl, 6) + - 0.00155770210179105*math.Pow(zl, 7) -} - -func alpha(m float64) float64 { - switch m { - case 16: - return 0.673 - case 32: - return 0.697 - case 64: - return 0.709 - } - return 0.7213 / (1 + 1.079/m) -} - -func getPosVal(x uint64, p uint8) (uint64, uint8) { - i := bextr(x, 64-p, p) // {x63,...,x64-p} - w := x<

> start) & ((1 << length) - 1) -} - -func bextr32(v uint32, start, length uint8) uint32 { - return (v >> start) & ((1 << length) - 1) -} - -func hashFunc(e []byte) uint64 { - return metro.Hash64(e, 1337) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/keys.go b/vendor/github.com/alicebob/miniredis/v2/keys.go deleted file mode 100644 index 058e0a79a..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/keys.go +++ /dev/null @@ -1,83 +0,0 @@ -package miniredis - -// Translate the 'KEYS' or 'PSUBSCRIBE' argument ('foo*', 'f??', &c.) into a regexp. - -import ( - "bytes" - "regexp" -) - -// patternRE compiles a glob to a regexp. Returns nil if the given -// pattern will never match anything. -// The general strategy is to sandwich all non-meta characters between \Q...\E. -func patternRE(k string) *regexp.Regexp { - re := bytes.Buffer{} - re.WriteString(`(?s)^\Q`) - for i := 0; i < len(k); i++ { - p := k[i] - switch p { - case '*': - re.WriteString(`\E.*\Q`) - case '?': - re.WriteString(`\E.\Q`) - case '[': - charClass := bytes.Buffer{} - i++ - for ; i < len(k); i++ { - if k[i] == ']' { - break - } - if k[i] == '\\' { - if i == len(k)-1 { - // Ends with a '\'. U-huh. - return nil - } - charClass.WriteByte(k[i]) - i++ - charClass.WriteByte(k[i]) - continue - } - charClass.WriteByte(k[i]) - } - if charClass.Len() == 0 { - // '[]' is valid in Redis, but matches nothing. - return nil - } - re.WriteString(`\E[`) - re.Write(charClass.Bytes()) - re.WriteString(`]\Q`) - - case '\\': - if i == len(k)-1 { - // Ends with a '\'. U-huh. - return nil - } - // Forget the \, keep the next char. - i++ - re.WriteByte(k[i]) - continue - default: - re.WriteByte(p) - } - } - re.WriteString(`\E$`) - return regexp.MustCompile(re.String()) -} - -// matchKeys filters only matching keys. -// The returned boolean is whether the match pattern was valid -func matchKeys(keys []string, match string) ([]string, bool) { - re := patternRE(match) - if re == nil { - // Special case: the given pattern won't match anything or is invalid. - return nil, false - } - var res []string - for _, k := range keys { - if !re.MatchString(k) { - continue - } - res = append(res, k) - } - return res, true -} diff --git a/vendor/github.com/alicebob/miniredis/v2/lua.go b/vendor/github.com/alicebob/miniredis/v2/lua.go deleted file mode 100644 index 7c7298cf2..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/lua.go +++ /dev/null @@ -1,256 +0,0 @@ -package miniredis - -import ( - "bufio" - "bytes" - "fmt" - "strings" - - lua "github.com/yuin/gopher-lua" - - "github.com/alicebob/miniredis/v2/server" -) - -var luaRedisConstants = map[string]lua.LValue{ - "LOG_DEBUG": lua.LNumber(0), - "LOG_VERBOSE": lua.LNumber(1), - "LOG_NOTICE": lua.LNumber(2), - "LOG_WARNING": lua.LNumber(3), -} - -func mkLua(srv *server.Server, c *server.Peer, sha string) (map[string]lua.LGFunction, map[string]lua.LValue) { - mkCall := func(failFast bool) func(l *lua.LState) int { - // one server.Ctx for a single Lua run - pCtx := &connCtx{} - if getCtx(c).authenticated { - pCtx.authenticated = true - } - pCtx.nested = true - pCtx.nestedSHA = sha - pCtx.selectedDB = getCtx(c).selectedDB - - return func(l *lua.LState) int { - top := l.GetTop() - if top == 0 { - l.Error(lua.LString(fmt.Sprintf("Please specify at least one argument for this redis lib call script: %s, &c.", sha)), 1) - return 0 - } - var args []string - for i := 1; i <= top; i++ { - switch a := l.Get(i).(type) { - case lua.LNumber: - args = append(args, a.String()) - case lua.LString: - args = append(args, string(a)) - default: - l.Error(lua.LString(fmt.Sprintf("Lua redis lib command arguments must be strings or integers script: %s, &c.", sha)), 1) - return 0 - } - } - if len(args) == 0 { - l.Error(lua.LString(msgNotFromScripts(sha)), 1) - return 0 - } - - buf := &bytes.Buffer{} - wr := bufio.NewWriter(buf) - peer := server.NewPeer(wr) - peer.Ctx = pCtx - srv.Dispatch(peer, args) - wr.Flush() - - res, err := server.ParseReply(bufio.NewReader(buf)) - if err != nil { - if failFast { - // call() mode - if strings.Contains(err.Error(), "ERR unknown command") { - l.Error(lua.LString(fmt.Sprintf("Unknown Redis command called from script script: %s, &c.", sha)), 1) - } else { - l.Error(lua.LString(err.Error()), 1) - } - return 0 - } - // pcall() mode - l.Push(lua.LNil) - return 1 - } - - if res == nil { - l.Push(lua.LFalse) - } else { - switch r := res.(type) { - case int64: - l.Push(lua.LNumber(r)) - case int: - l.Push(lua.LNumber(r)) - case []uint8: - l.Push(lua.LString(string(r))) - case []interface{}: - l.Push(redisToLua(l, r)) - case server.Simple: - l.Push(luaStatusReply(string(r))) - case string: - l.Push(lua.LString(r)) - case error: - l.Error(lua.LString(r.Error()), 1) - return 0 - default: - panic(fmt.Sprintf("type not handled (%T)", r)) - } - } - return 1 - } - } - - return map[string]lua.LGFunction{ - "call": mkCall(true), - "pcall": mkCall(false), - "error_reply": func(l *lua.LState) int { - v := l.Get(1) - msg, ok := v.(lua.LString) - if !ok { - l.Error(lua.LString("wrong number or type of arguments"), 1) - return 0 - } - res := &lua.LTable{} - parts := strings.SplitN(msg.String(), " ", 2) - // '-' at the beginging will be added as a part of error response - if parts[0] != "" && parts[0][0] == '-' { - parts[0] = parts[0][1:] - } - var final_msg string - if len(parts) == 2 { - final_msg = fmt.Sprintf("%s %s", parts[0], parts[1]) - } else { - final_msg = fmt.Sprintf("ERR %s", parts[0]) - } - res.RawSetString("err", lua.LString(final_msg)) - l.Push(res) - return 1 - }, - "log": func(l *lua.LState) int { - level := l.CheckInt(1) - msg := l.CheckString(2) - _, _ = level, msg - // do nothing by default. To see logs uncomment: - // fmt.Printf("%v: %v", level, msg) - return 0 - }, - "status_reply": func(l *lua.LState) int { - v := l.Get(1) - msg, ok := v.(lua.LString) - if !ok { - l.Error(lua.LString("wrong number or type of arguments"), 1) - return 0 - } - res := luaStatusReply(string(msg)) - l.Push(res) - return 1 - }, - "sha1hex": func(l *lua.LState) int { - top := l.GetTop() - if top != 1 { - l.Error(lua.LString("wrong number of arguments"), 1) - return 0 - } - msg := lua.LVAsString(l.Get(1)) - l.Push(lua.LString(sha1Hex(msg))) - return 1 - }, - "replicate_commands": func(l *lua.LState) int { - // ignored - return 1 - }, - }, luaRedisConstants -} - -func luaToRedis(l *lua.LState, c *server.Peer, value lua.LValue) { - if value == nil { - c.WriteNull() - return - } - - switch t := value.(type) { - case *lua.LNilType: - c.WriteNull() - case lua.LBool: - if lua.LVAsBool(value) { - c.WriteInt(1) - } else { - c.WriteNull() - } - case lua.LNumber: - c.WriteInt(int(lua.LVAsNumber(value))) - case lua.LString: - s := lua.LVAsString(value) - c.WriteBulk(s) - case *lua.LTable: - // special case for tables with an 'err' or 'ok' field - // note: according to the docs this only counts when 'err' or 'ok' is - // the only field. - if s := t.RawGetString("err"); s.Type() != lua.LTNil { - c.WriteError(s.String()) - return - } - if s := t.RawGetString("ok"); s.Type() != lua.LTNil { - c.WriteInline(s.String()) - return - } - - result := []lua.LValue{} - for j := 1; true; j++ { - val := l.GetTable(value, lua.LNumber(j)) - if val == nil { - result = append(result, val) - continue - } - - if val.Type() == lua.LTNil { - break - } - - result = append(result, val) - } - - c.WriteLen(len(result)) - for _, r := range result { - luaToRedis(l, c, r) - } - default: - panic("....") - } -} - -func redisToLua(l *lua.LState, res []interface{}) *lua.LTable { - rettb := l.NewTable() - for _, e := range res { - var v lua.LValue - if e == nil { - v = lua.LFalse - } else { - switch et := e.(type) { - case int: - v = lua.LNumber(et) - case int64: - v = lua.LNumber(et) - case []uint8: - v = lua.LString(string(et)) - case []interface{}: - v = redisToLua(l, et) - case string: - v = lua.LString(et) - default: - // TODO: oops? - v = lua.LString(e.(string)) - } - } - l.RawSet(rettb, lua.LNumber(rettb.Len()+1), v) - } - return rettb -} - -func luaStatusReply(msg string) *lua.LTable { - tab := &lua.LTable{} - tab.RawSetString("ok", lua.LString(msg)) - return tab -} diff --git a/vendor/github.com/alicebob/miniredis/v2/metro/LICENSE b/vendor/github.com/alicebob/miniredis/v2/metro/LICENSE deleted file mode 100644 index 6243b617c..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/metro/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -This package is a mechanical translation of the reference C++ code for -MetroHash, available at https://github.com/jandrewrogers/MetroHash - -The MIT License (MIT) - -Copyright (c) 2016 Damian Gryski - -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/alicebob/miniredis/v2/metro/README.md b/vendor/github.com/alicebob/miniredis/v2/metro/README.md deleted file mode 100644 index 07e4ee9f7..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/metro/README.md +++ /dev/null @@ -1 +0,0 @@ -This is a partial copy of github.com/dgryski/go-metro. \ No newline at end of file diff --git a/vendor/github.com/alicebob/miniredis/v2/metro/metro64.go b/vendor/github.com/alicebob/miniredis/v2/metro/metro64.go deleted file mode 100644 index 5b3db9a90..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/metro/metro64.go +++ /dev/null @@ -1,87 +0,0 @@ -package metro - -import "encoding/binary" - -func Hash64(buffer []byte, seed uint64) uint64 { - - const ( - k0 = 0xD6D018F5 - k1 = 0xA2AA033B - k2 = 0x62992FC1 - k3 = 0x30BC5B29 - ) - - ptr := buffer - - hash := (seed + k2) * k0 - - if len(ptr) >= 32 { - v := [4]uint64{hash, hash, hash, hash} - - for len(ptr) >= 32 { - v[0] += binary.LittleEndian.Uint64(ptr[:8]) * k0 - v[0] = rotate_right(v[0], 29) + v[2] - v[1] += binary.LittleEndian.Uint64(ptr[8:16]) * k1 - v[1] = rotate_right(v[1], 29) + v[3] - v[2] += binary.LittleEndian.Uint64(ptr[16:24]) * k2 - v[2] = rotate_right(v[2], 29) + v[0] - v[3] += binary.LittleEndian.Uint64(ptr[24:32]) * k3 - v[3] = rotate_right(v[3], 29) + v[1] - ptr = ptr[32:] - } - - v[2] ^= rotate_right(((v[0]+v[3])*k0)+v[1], 37) * k1 - v[3] ^= rotate_right(((v[1]+v[2])*k1)+v[0], 37) * k0 - v[0] ^= rotate_right(((v[0]+v[2])*k0)+v[3], 37) * k1 - v[1] ^= rotate_right(((v[1]+v[3])*k1)+v[2], 37) * k0 - hash += v[0] ^ v[1] - } - - if len(ptr) >= 16 { - v0 := hash + (binary.LittleEndian.Uint64(ptr[:8]) * k2) - v0 = rotate_right(v0, 29) * k3 - v1 := hash + (binary.LittleEndian.Uint64(ptr[8:16]) * k2) - v1 = rotate_right(v1, 29) * k3 - v0 ^= rotate_right(v0*k0, 21) + v1 - v1 ^= rotate_right(v1*k3, 21) + v0 - hash += v1 - ptr = ptr[16:] - } - - if len(ptr) >= 8 { - hash += binary.LittleEndian.Uint64(ptr[:8]) * k3 - ptr = ptr[8:] - hash ^= rotate_right(hash, 55) * k1 - } - - if len(ptr) >= 4 { - hash += uint64(binary.LittleEndian.Uint32(ptr[:4])) * k3 - hash ^= rotate_right(hash, 26) * k1 - ptr = ptr[4:] - } - - if len(ptr) >= 2 { - hash += uint64(binary.LittleEndian.Uint16(ptr[:2])) * k3 - ptr = ptr[2:] - hash ^= rotate_right(hash, 48) * k1 - } - - if len(ptr) >= 1 { - hash += uint64(ptr[0]) * k3 - hash ^= rotate_right(hash, 37) * k1 - } - - hash ^= rotate_right(hash, 28) - hash *= k0 - hash ^= rotate_right(hash, 29) - - return hash -} - -func Hash64Str(buffer string, seed uint64) uint64 { - return Hash64([]byte(buffer), seed) -} - -func rotate_right(v uint64, k uint) uint64 { - return (v >> k) | (v << (64 - k)) -} diff --git a/vendor/github.com/alicebob/miniredis/v2/miniredis.go b/vendor/github.com/alicebob/miniredis/v2/miniredis.go deleted file mode 100644 index 490446d47..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/miniredis.go +++ /dev/null @@ -1,728 +0,0 @@ -// Package miniredis is a pure Go Redis test server, for use in Go unittests. -// There are no dependencies on system binaries, and every server you start -// will be empty. -// -// import "github.com/alicebob/miniredis/v2" -// -// Start a server with `s := miniredis.RunT(t)`, it'll be shutdown via a t.Cleanup(). -// Or do everything manual: `s, err := miniredis.Run(); defer s.Close()` -// -// Point your Redis client to `s.Addr()` or `s.Host(), s.Port()`. -// -// Set keys directly via s.Set(...) and similar commands, or use a Redis client. -// -// For direct use you can select a Redis database with either `s.Select(12); -// s.Get("foo")` or `s.DB(12).Get("foo")`. -package miniredis - -import ( - "context" - "crypto/tls" - "fmt" - "math/rand" - "strconv" - "strings" - "sync" - "time" - - "github.com/alicebob/miniredis/v2/server" -) - -var DumpMaxLineLen = 60 - -type hashKey map[string]string -type listKey []string -type setKey map[string]struct{} - -// RedisDB holds a single (numbered) Redis database. -type RedisDB struct { - master *Miniredis // pointer to the lock in Miniredis - id int // db id - keys map[string]string // Master map of keys with their type - stringKeys map[string]string // GET/SET &c. keys - hashKeys map[string]hashKey // MGET/MSET &c. keys - listKeys map[string]listKey // LPUSH &c. keys - setKeys map[string]setKey // SADD &c. keys - hllKeys map[string]*hll // PFADD &c. keys - sortedsetKeys map[string]sortedSet // ZADD &c. keys - streamKeys map[string]*streamKey // XADD &c. keys - ttl map[string]time.Duration // effective TTL values - keyVersion map[string]uint // used to watch values -} - -// Miniredis is a Redis server implementation. -type Miniredis struct { - sync.Mutex - srv *server.Server - port int - passwords map[string]string // username password - dbs map[int]*RedisDB - selectedDB int // DB id used in the direct Get(), Set() &c. - scripts map[string]string // sha1 -> lua src - signal *sync.Cond - now time.Time // time.Now() if not set. - subscribers map[*Subscriber]struct{} - rand *rand.Rand - Ctx context.Context - CtxCancel context.CancelFunc -} - -type txCmd func(*server.Peer, *connCtx) - -// database id + key combo -type dbKey struct { - db int - key string -} - -// connCtx has all state for a single connection. -// (this struct was named before context.Context existed) -type connCtx struct { - selectedDB int // selected DB - authenticated bool // auth enabled and a valid AUTH seen - transaction []txCmd // transaction callbacks. Or nil. - dirtyTransaction bool // any error during QUEUEing - watch map[dbKey]uint // WATCHed keys - subscriber *Subscriber // client is in PUBSUB mode if not nil - nested bool // this is called via Lua - nestedSHA string // set to the SHA of the nesting function -} - -// NewMiniRedis makes a new, non-started, Miniredis object. -func NewMiniRedis() *Miniredis { - m := Miniredis{ - dbs: map[int]*RedisDB{}, - scripts: map[string]string{}, - subscribers: map[*Subscriber]struct{}{}, - } - m.Ctx, m.CtxCancel = context.WithCancel(context.Background()) - m.signal = sync.NewCond(&m) - return &m -} - -func newRedisDB(id int, m *Miniredis) RedisDB { - return RedisDB{ - id: id, - master: m, - keys: map[string]string{}, - stringKeys: map[string]string{}, - hashKeys: map[string]hashKey{}, - listKeys: map[string]listKey{}, - setKeys: map[string]setKey{}, - hllKeys: map[string]*hll{}, - sortedsetKeys: map[string]sortedSet{}, - streamKeys: map[string]*streamKey{}, - ttl: map[string]time.Duration{}, - keyVersion: map[string]uint{}, - } -} - -// Run creates and Start()s a Miniredis. -func Run() (*Miniredis, error) { - m := NewMiniRedis() - return m, m.Start() -} - -// Run creates and Start()s a Miniredis, TLS version. -func RunTLS(cfg *tls.Config) (*Miniredis, error) { - m := NewMiniRedis() - return m, m.StartTLS(cfg) -} - -// Tester is a minimal version of a testing.T -type Tester interface { - Fatalf(string, ...interface{}) - Cleanup(func()) -} - -// RunT start a new miniredis, pass it a testing.T. It also registers the cleanup after your test is done. -func RunT(t Tester) *Miniredis { - m := NewMiniRedis() - if err := m.Start(); err != nil { - t.Fatalf("could not start miniredis: %s", err) - // not reached - } - t.Cleanup(m.Close) - return m -} - -// Start starts a server. It listens on a random port on localhost. See also -// Addr(). -func (m *Miniredis) Start() error { - s, err := server.NewServer(fmt.Sprintf("127.0.0.1:%d", m.port)) - if err != nil { - return err - } - return m.start(s) -} - -// Start starts a server, TLS version. -func (m *Miniredis) StartTLS(cfg *tls.Config) error { - s, err := server.NewServerTLS(fmt.Sprintf("127.0.0.1:%d", m.port), cfg) - if err != nil { - return err - } - return m.start(s) -} - -// StartAddr runs miniredis with a given addr. Examples: "127.0.0.1:6379", -// ":6379", or "127.0.0.1:0" -func (m *Miniredis) StartAddr(addr string) error { - s, err := server.NewServer(addr) - if err != nil { - return err - } - return m.start(s) -} - -func (m *Miniredis) start(s *server.Server) error { - m.Lock() - defer m.Unlock() - m.srv = s - m.port = s.Addr().Port - - commandsConnection(m) - commandsGeneric(m) - commandsServer(m) - commandsString(m) - commandsHash(m) - commandsList(m) - commandsPubsub(m) - commandsSet(m) - commandsSortedSet(m) - commandsStream(m) - commandsTransaction(m) - commandsScripting(m) - commandsGeo(m) - commandsCluster(m) - commandsHll(m) - - return nil -} - -// Restart restarts a Close()d server on the same port. Values will be -// preserved. -func (m *Miniredis) Restart() error { - return m.Start() -} - -// Close shuts down a Miniredis. -func (m *Miniredis) Close() { - m.Lock() - - if m.srv == nil { - m.Unlock() - return - } - srv := m.srv - m.srv = nil - m.CtxCancel() - m.Unlock() - - // the OnDisconnect callbacks can lock m, so run Close() outside the lock. - srv.Close() - -} - -// RequireAuth makes every connection need to AUTH first. This is the old 'AUTH [password] command. -// Remove it by setting an empty string. -func (m *Miniredis) RequireAuth(pw string) { - m.RequireUserAuth("default", pw) -} - -// Add a username/password, for use with 'AUTH [username] [password]'. -// There are currently no access controls for commands implemented. -// Disable access for the user with an empty password. -func (m *Miniredis) RequireUserAuth(username, pw string) { - m.Lock() - defer m.Unlock() - if m.passwords == nil { - m.passwords = map[string]string{} - } - if pw == "" { - delete(m.passwords, username) - return - } - m.passwords[username] = pw -} - -// DB returns a DB by ID. -func (m *Miniredis) DB(i int) *RedisDB { - m.Lock() - defer m.Unlock() - return m.db(i) -} - -// get DB. No locks! -func (m *Miniredis) db(i int) *RedisDB { - if db, ok := m.dbs[i]; ok { - return db - } - db := newRedisDB(i, m) // main miniredis has our mutex. - m.dbs[i] = &db - return &db -} - -// SwapDB swaps DBs by IDs. -func (m *Miniredis) SwapDB(i, j int) bool { - m.Lock() - defer m.Unlock() - return m.swapDB(i, j) -} - -// swap DB. No locks! -func (m *Miniredis) swapDB(i, j int) bool { - db1 := m.db(i) - db2 := m.db(j) - - db1.id = j - db2.id = i - - m.dbs[i] = db2 - m.dbs[j] = db1 - - return true -} - -// Addr returns '127.0.0.1:12345'. Can be given to a Dial(). See also Host() -// and Port(), which return the same things. -func (m *Miniredis) Addr() string { - m.Lock() - defer m.Unlock() - return m.srv.Addr().String() -} - -// Host returns the host part of Addr(). -func (m *Miniredis) Host() string { - m.Lock() - defer m.Unlock() - return m.srv.Addr().IP.String() -} - -// Port returns the (random) port part of Addr(). -func (m *Miniredis) Port() string { - m.Lock() - defer m.Unlock() - return strconv.Itoa(m.srv.Addr().Port) -} - -// CommandCount returns the number of processed commands. -func (m *Miniredis) CommandCount() int { - m.Lock() - defer m.Unlock() - return int(m.srv.TotalCommands()) -} - -// CurrentConnectionCount returns the number of currently connected clients. -func (m *Miniredis) CurrentConnectionCount() int { - m.Lock() - defer m.Unlock() - return m.srv.ClientsLen() -} - -// TotalConnectionCount returns the number of client connections since server start. -func (m *Miniredis) TotalConnectionCount() int { - m.Lock() - defer m.Unlock() - return int(m.srv.TotalConnections()) -} - -// FastForward decreases all TTLs by the given duration. All TTLs <= 0 will be -// expired. -func (m *Miniredis) FastForward(duration time.Duration) { - m.Lock() - defer m.Unlock() - for _, db := range m.dbs { - db.fastForward(duration) - } -} - -// Server returns the underlying server to allow custom commands to be implemented -func (m *Miniredis) Server() *server.Server { - return m.srv -} - -// Dump returns a text version of the selected DB, usable for debugging. -// -// Dump limits the maximum length of each key:value to "DumpMaxLineLen" characters. -// To increase that, call something like: -// -// miniredis.DumpMaxLineLen = 1024 -// mr, _ = miniredis.Run() -// mr.Dump() -func (m *Miniredis) Dump() string { - m.Lock() - defer m.Unlock() - - var ( - maxLen = DumpMaxLineLen - indent = " " - db = m.db(m.selectedDB) - r = "" - v = func(s string) string { - suffix := "" - if len(s) > maxLen { - suffix = fmt.Sprintf("...(%d)", len(s)) - s = s[:maxLen-len(suffix)] - } - return fmt.Sprintf("%q%s", s, suffix) - } - ) - - for _, k := range db.allKeys() { - r += fmt.Sprintf("- %s\n", k) - t := db.t(k) - switch t { - case "string": - r += fmt.Sprintf("%s%s\n", indent, v(db.stringKeys[k])) - case "hash": - for _, hk := range db.hashFields(k) { - r += fmt.Sprintf("%s%s: %s\n", indent, hk, v(db.hashGet(k, hk))) - } - case "list": - for _, lk := range db.listKeys[k] { - r += fmt.Sprintf("%s%s\n", indent, v(lk)) - } - case "set": - for _, mk := range db.setMembers(k) { - r += fmt.Sprintf("%s%s\n", indent, v(mk)) - } - case "zset": - for _, el := range db.ssetElements(k) { - r += fmt.Sprintf("%s%f: %s\n", indent, el.score, v(el.member)) - } - case "stream": - for _, entry := range db.streamKeys[k].entries { - r += fmt.Sprintf("%s%s\n", indent, entry.ID) - ev := entry.Values - for i := 0; i < len(ev)/2; i++ { - r += fmt.Sprintf("%s%s%s: %s\n", indent, indent, v(ev[2*i]), v(ev[2*i+1])) - } - } - case "hll": - for _, entry := range db.hllKeys { - r += fmt.Sprintf("%s%s\n", indent, v(string(entry.Bytes()))) - } - default: - r += fmt.Sprintf("%s(a %s, fixme!)\n", indent, t) - } - } - return r -} - -// SetTime sets the time against which EXPIREAT values are compared, and the -// time used in stream entry IDs. Will use time.Now() if this is not set. -func (m *Miniredis) SetTime(t time.Time) { - m.Lock() - defer m.Unlock() - m.now = t -} - -// make every command return this message. For example: -// -// LOADING Redis is loading the dataset in memory -// MASTERDOWN Link with MASTER is down and replica-serve-stale-data is set to 'no'. -// -// Clear it with an empty string. Don't add newlines. -func (m *Miniredis) SetError(msg string) { - cb := server.Hook(nil) - if msg != "" { - cb = func(c *server.Peer, cmd string, args ...string) bool { - c.WriteError(msg) - return true - } - } - m.srv.SetPreHook(cb) -} - -// isValidCMD returns true if command is valid and can be executed. -func (m *Miniredis) isValidCMD(c *server.Peer, cmd string) bool { - if !m.handleAuth(c) { - return false - } - if m.checkPubsub(c, cmd) { - return false - } - - return true -} - -// handleAuth returns false if connection has no access. It sends the reply. -func (m *Miniredis) handleAuth(c *server.Peer) bool { - if getCtx(c).nested { - return true - } - - m.Lock() - defer m.Unlock() - if len(m.passwords) == 0 { - return true - } - if !getCtx(c).authenticated { - c.WriteError("NOAUTH Authentication required.") - return false - } - return true -} - -// handlePubsub sends an error to the user if the connection is in PUBSUB mode. -// It'll return true if it did. -func (m *Miniredis) checkPubsub(c *server.Peer, cmd string) bool { - if getCtx(c).nested { - return false - } - - m.Lock() - defer m.Unlock() - - ctx := getCtx(c) - if ctx.subscriber == nil { - return false - } - - prefix := "ERR " - if strings.ToLower(cmd) == "exec" { - prefix = "EXECABORT Transaction discarded because of: " - } - c.WriteError(fmt.Sprintf( - "%sCan't execute '%s': only (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT are allowed in this context", - prefix, - strings.ToLower(cmd), - )) - return true -} - -func getCtx(c *server.Peer) *connCtx { - if c.Ctx == nil { - c.Ctx = &connCtx{} - } - return c.Ctx.(*connCtx) -} - -func startTx(ctx *connCtx) { - ctx.transaction = []txCmd{} - ctx.dirtyTransaction = false -} - -func stopTx(ctx *connCtx) { - ctx.transaction = nil - unwatch(ctx) -} - -func inTx(ctx *connCtx) bool { - return ctx.transaction != nil -} - -func addTxCmd(ctx *connCtx, cb txCmd) { - ctx.transaction = append(ctx.transaction, cb) -} - -func watch(db *RedisDB, ctx *connCtx, key string) { - if ctx.watch == nil { - ctx.watch = map[dbKey]uint{} - } - ctx.watch[dbKey{db: db.id, key: key}] = db.keyVersion[key] // Can be 0. -} - -func unwatch(ctx *connCtx) { - ctx.watch = nil -} - -// setDirty can be called even when not in an tx. Is an no-op then. -func setDirty(c *server.Peer) { - if c.Ctx == nil { - // No transaction. Not relevant. - return - } - getCtx(c).dirtyTransaction = true -} - -func (m *Miniredis) addSubscriber(s *Subscriber) { - m.subscribers[s] = struct{}{} -} - -// closes and remove the subscriber. -func (m *Miniredis) removeSubscriber(s *Subscriber) { - _, ok := m.subscribers[s] - delete(m.subscribers, s) - if ok { - s.Close() - } -} - -func (m *Miniredis) publish(c, msg string) int { - n := 0 - for s := range m.subscribers { - n += s.Publish(c, msg) - } - return n -} - -// enter 'subscribed state', or return the existing one. -func (m *Miniredis) subscribedState(c *server.Peer) *Subscriber { - ctx := getCtx(c) - sub := ctx.subscriber - if sub != nil { - return sub - } - - sub = newSubscriber() - m.addSubscriber(sub) - - c.OnDisconnect(func() { - m.Lock() - m.removeSubscriber(sub) - m.Unlock() - }) - - ctx.subscriber = sub - - go monitorPublish(c, sub.publish) - go monitorPpublish(c, sub.ppublish) - - return sub -} - -// whenever the p?sub count drops to 0 subscribed state should be stopped, and -// all redis commands are allowed again. -func endSubscriber(m *Miniredis, c *server.Peer) { - ctx := getCtx(c) - if sub := ctx.subscriber; sub != nil { - m.removeSubscriber(sub) // will Close() the sub - } - ctx.subscriber = nil -} - -// Start a new pubsub subscriber. It can (un) subscribe to channels and -// patterns, and has a channel to get published messages. Close it with -// Close(). -// Does not close itself when there are no subscriptions left. -func (m *Miniredis) NewSubscriber() *Subscriber { - sub := newSubscriber() - - m.Lock() - m.addSubscriber(sub) - m.Unlock() - - return sub -} - -func (m *Miniredis) allSubscribers() []*Subscriber { - var subs []*Subscriber - for s := range m.subscribers { - subs = append(subs, s) - } - return subs -} - -func (m *Miniredis) Seed(seed int) { - m.Lock() - defer m.Unlock() - - // m.rand is not safe for concurrent use. - m.rand = rand.New(rand.NewSource(int64(seed))) -} - -func (m *Miniredis) randIntn(n int) int { - if m.rand == nil { - return rand.Intn(n) - } - return m.rand.Intn(n) -} - -// shuffle shuffles a list of strings. Kinda. -func (m *Miniredis) shuffle(l []string) { - for range l { - i := m.randIntn(len(l)) - j := m.randIntn(len(l)) - l[i], l[j] = l[j], l[i] - } -} - -func (m *Miniredis) effectiveNow() time.Time { - if !m.now.IsZero() { - return m.now - } - return time.Now().UTC() -} - -// convert a unixtimestamp to a duration, to use an absolute time as TTL. -// d can be either time.Second or time.Millisecond. -func (m *Miniredis) at(i int, d time.Duration) time.Duration { - var ts time.Time - switch d { - case time.Millisecond: - ts = time.Unix(int64(i/1000), 1000000*int64(i%1000)) - case time.Second: - ts = time.Unix(int64(i), 0) - default: - panic("invalid time unit (d). Fixme!") - } - now := m.effectiveNow() - return ts.Sub(now) -} - -// copy does not mind if dst already exists. -func (m *Miniredis) copy( - srcDB *RedisDB, src string, - destDB *RedisDB, dst string, -) error { - if !srcDB.exists(src) { - return ErrKeyNotFound - } - - switch srcDB.t(src) { - case "string": - destDB.stringKeys[dst] = srcDB.stringKeys[src] - case "hash": - destDB.hashKeys[dst] = copyHashKey(srcDB.hashKeys[src]) - case "list": - destDB.listKeys[dst] = copyListKey(srcDB.listKeys[src]) - case "set": - destDB.setKeys[dst] = copySetKey(srcDB.setKeys[src]) - case "zset": - destDB.sortedsetKeys[dst] = copySortedSet(srcDB.sortedsetKeys[src]) - case "stream": - destDB.streamKeys[dst] = srcDB.streamKeys[src].copy() - case "hll": - destDB.hllKeys[dst] = srcDB.hllKeys[src].copy() - default: - panic("missing case") - } - destDB.keys[dst] = srcDB.keys[src] - destDB.keyVersion[dst]++ - if v, ok := srcDB.ttl[src]; ok { - destDB.ttl[dst] = v - } - return nil -} - -func copyHashKey(orig hashKey) hashKey { - cpy := hashKey{} - for k, v := range orig { - cpy[k] = v - } - return cpy -} - -func copyListKey(orig listKey) listKey { - cpy := make(listKey, len(orig)) - copy(cpy, orig) - return cpy -} - -func copySetKey(orig setKey) setKey { - cpy := setKey{} - for k, v := range orig { - cpy[k] = v - } - return cpy -} - -func copySortedSet(orig sortedSet) sortedSet { - cpy := sortedSet{} - for k, v := range orig { - cpy[k] = v - } - return cpy -} diff --git a/vendor/github.com/alicebob/miniredis/v2/opts.go b/vendor/github.com/alicebob/miniredis/v2/opts.go deleted file mode 100644 index de9138601..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/opts.go +++ /dev/null @@ -1,44 +0,0 @@ -package miniredis - -import ( - "math" - "strconv" - "time" - - "github.com/alicebob/miniredis/v2/server" -) - -// optInt parses an int option in a command. -// Writes "invalid integer" error to c if it's not a valid integer. Returns -// whether or not things were okay. -func optInt(c *server.Peer, src string, dest *int) bool { - return optIntErr(c, src, dest, msgInvalidInt) -} - -func optIntErr(c *server.Peer, src string, dest *int, errMsg string) bool { - n, err := strconv.Atoi(src) - if err != nil { - setDirty(c) - c.WriteError(errMsg) - return false - } - *dest = n - return true -} - -func optDuration(c *server.Peer, src string, dest *time.Duration) bool { - n, err := strconv.ParseFloat(src, 64) - if err != nil { - setDirty(c) - c.WriteError(msgInvalidTimeout) - return false - } - if n < 0 || math.IsInf(n, 0) { - setDirty(c) - c.WriteError(msgNegTimeout) - return false - } - - *dest = time.Duration(n*1_000_000) * time.Microsecond - return true -} diff --git a/vendor/github.com/alicebob/miniredis/v2/pubsub.go b/vendor/github.com/alicebob/miniredis/v2/pubsub.go deleted file mode 100644 index bb31f80a8..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/pubsub.go +++ /dev/null @@ -1,240 +0,0 @@ -package miniredis - -import ( - "regexp" - "sort" - "sync" - - "github.com/alicebob/miniredis/v2/server" -) - -// PubsubMessage is what gets broadcasted over pubsub channels. -type PubsubMessage struct { - Channel string - Message string -} - -type PubsubPmessage struct { - Pattern string - Channel string - Message string -} - -// Subscriber has the (p)subscriptions. -type Subscriber struct { - publish chan PubsubMessage - ppublish chan PubsubPmessage - channels map[string]struct{} - patterns map[string]*regexp.Regexp - mu sync.Mutex -} - -// Make a new subscriber. The channel is not buffered, so you will need to keep -// reading using Messages(). Use Close() when done, or unsubscribe. -func newSubscriber() *Subscriber { - return &Subscriber{ - publish: make(chan PubsubMessage), - ppublish: make(chan PubsubPmessage), - channels: map[string]struct{}{}, - patterns: map[string]*regexp.Regexp{}, - } -} - -// Close the listening channel -func (s *Subscriber) Close() { - close(s.publish) - close(s.ppublish) -} - -// Count the total number of channels and patterns -func (s *Subscriber) Count() int { - s.mu.Lock() - defer s.mu.Unlock() - return s.count() -} - -func (s *Subscriber) count() int { - return len(s.channels) + len(s.patterns) -} - -// Subscribe to a channel. Returns the total number of (p)subscriptions after -// subscribing. -func (s *Subscriber) Subscribe(c string) int { - s.mu.Lock() - defer s.mu.Unlock() - - s.channels[c] = struct{}{} - return s.count() -} - -// Unsubscribe a channel. Returns the total number of (p)subscriptions after -// unsubscribing. -func (s *Subscriber) Unsubscribe(c string) int { - s.mu.Lock() - defer s.mu.Unlock() - - delete(s.channels, c) - return s.count() -} - -// Subscribe to a pattern. Returns the total number of (p)subscriptions after -// subscribing. -func (s *Subscriber) Psubscribe(pat string) int { - s.mu.Lock() - defer s.mu.Unlock() - - s.patterns[pat] = patternRE(pat) - return s.count() -} - -// Unsubscribe a pattern. Returns the total number of (p)subscriptions after -// unsubscribing. -func (s *Subscriber) Punsubscribe(pat string) int { - s.mu.Lock() - defer s.mu.Unlock() - - delete(s.patterns, pat) - return s.count() -} - -// List all subscribed channels, in alphabetical order -func (s *Subscriber) Channels() []string { - s.mu.Lock() - defer s.mu.Unlock() - - var cs []string - for c := range s.channels { - cs = append(cs, c) - } - sort.Strings(cs) - return cs -} - -// List all subscribed patterns, in alphabetical order -func (s *Subscriber) Patterns() []string { - s.mu.Lock() - defer s.mu.Unlock() - - var ps []string - for p := range s.patterns { - ps = append(ps, p) - } - sort.Strings(ps) - return ps -} - -// Publish a message. Will return return how often we sent the message (can be -// a match for a subscription and for a psubscription. -func (s *Subscriber) Publish(c, msg string) int { - s.mu.Lock() - defer s.mu.Unlock() - - found := 0 - -subs: - for sub := range s.channels { - if sub == c { - s.publish <- PubsubMessage{c, msg} - found++ - break subs - } - } - -pats: - for orig, pat := range s.patterns { - if pat != nil && pat.MatchString(c) { - s.ppublish <- PubsubPmessage{orig, c, msg} - found++ - break pats - } - } - - return found -} - -// The channel to read messages for this subscriber. Only for messages matching -// a SUBSCRIBE. -func (s *Subscriber) Messages() <-chan PubsubMessage { - return s.publish -} - -// The channel to read messages for this subscriber. Only for messages matching -// a PSUBSCRIBE. -func (s *Subscriber) Pmessages() <-chan PubsubPmessage { - return s.ppublish -} - -// List all pubsub channels. If `pat` isn't empty channels names must match the -// pattern. Channels are returned alphabetically. -func activeChannels(subs []*Subscriber, pat string) []string { - channels := map[string]struct{}{} - for _, s := range subs { - for c := range s.channels { - channels[c] = struct{}{} - } - } - - var cpat *regexp.Regexp - if pat != "" { - cpat = patternRE(pat) - } - - var cs []string - for k := range channels { - if cpat != nil && !cpat.MatchString(k) { - continue - } - cs = append(cs, k) - } - sort.Strings(cs) - return cs -} - -// Count all subscribed (not psubscribed) clients for the given channel -// pattern. Channels are returned alphabetically. -func countSubs(subs []*Subscriber, channel string) int { - n := 0 - for _, p := range subs { - for c := range p.channels { - if c == channel { - n++ - break - } - } - } - return n -} - -// Count the total of all client psubscriptions. -func countPsubs(subs []*Subscriber) int { - n := 0 - for _, p := range subs { - n += len(p.patterns) - } - return n -} - -func monitorPublish(conn *server.Peer, msgs <-chan PubsubMessage) { - for msg := range msgs { - conn.Block(func(c *server.Writer) { - c.WritePushLen(3) - c.WriteBulk("message") - c.WriteBulk(msg.Channel) - c.WriteBulk(msg.Message) - c.Flush() - }) - } -} - -func monitorPpublish(conn *server.Peer, msgs <-chan PubsubPmessage) { - for msg := range msgs { - conn.Block(func(c *server.Writer) { - c.WritePushLen(4) - c.WriteBulk("pmessage") - c.WriteBulk(msg.Pattern) - c.WriteBulk(msg.Channel) - c.WriteBulk(msg.Message) - c.Flush() - }) - } -} diff --git a/vendor/github.com/alicebob/miniredis/v2/redis.go b/vendor/github.com/alicebob/miniredis/v2/redis.go deleted file mode 100644 index 6cc52db0a..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/redis.go +++ /dev/null @@ -1,249 +0,0 @@ -package miniredis - -import ( - "context" - "fmt" - "math" - "math/big" - "strings" - "sync" - "time" - - "github.com/alicebob/miniredis/v2/server" -) - -const ( - msgWrongType = "WRONGTYPE Operation against a key holding the wrong kind of value" - msgNotValidHllValue = "WRONGTYPE Key is not a valid HyperLogLog string value." - msgInvalidInt = "ERR value is not an integer or out of range" - msgInvalidFloat = "ERR value is not a valid float" - msgInvalidMinMax = "ERR min or max is not a float" - msgInvalidRangeItem = "ERR min or max not valid string range item" - msgInvalidTimeout = "ERR timeout is not a float or out of range" - msgInvalidRange = "ERR value is out of range, must be positive" - msgSyntaxError = "ERR syntax error" - msgKeyNotFound = "ERR no such key" - msgOutOfRange = "ERR index out of range" - msgInvalidCursor = "ERR invalid cursor" - msgXXandNX = "ERR XX and NX options at the same time are not compatible" - msgNegTimeout = "ERR timeout is negative" - msgInvalidSETime = "ERR invalid expire time in set" - msgInvalidSETEXTime = "ERR invalid expire time in setex" - msgInvalidPSETEXTime = "ERR invalid expire time in psetex" - msgInvalidKeysNumber = "ERR Number of keys can't be greater than number of args" - msgNegativeKeysNumber = "ERR Number of keys can't be negative" - msgFScriptUsage = "ERR unknown subcommand or wrong number of arguments for '%s'. Try SCRIPT HELP." - msgFScriptUsageSimple = "ERR unknown subcommand '%s'. Try SCRIPT HELP." - msgFPubsubUsage = "ERR unknown subcommand or wrong number of arguments for '%s'. Try PUBSUB HELP." - msgFPubsubUsageSimple = "ERR unknown subcommand '%s'. Try PUBSUB HELP." - msgScriptFlush = "ERR SCRIPT FLUSH only support SYNC|ASYNC option" - msgSingleElementPair = "ERR INCR option supports a single increment-element pair" - msgGTLTandNX = "ERR GT, LT, and/or NX options at the same time are not compatible" - msgInvalidStreamID = "ERR Invalid stream ID specified as stream command argument" - msgStreamIDTooSmall = "ERR The ID specified in XADD is equal or smaller than the target stream top item" - msgStreamIDZero = "ERR The ID specified in XADD must be greater than 0-0" - msgNoScriptFound = "NOSCRIPT No matching script. Please use EVAL." - msgUnsupportedUnit = "ERR unsupported unit provided. please use m, km, ft, mi" - msgXreadUnbalanced = "ERR Unbalanced XREAD list of streams: for each stream key an ID or '$' must be specified." - msgXgroupKeyNotFound = "ERR The XGROUP subcommand requires the key to exist. Note that for CREATE you may want to use the MKSTREAM option to create an empty stream automatically." - msgXtrimInvalidStrategy = "ERR unsupported XTRIM strategy. Please use MAXLEN, MINID" - msgXtrimInvalidMaxLen = "ERR value is not an integer or out of range" - msgXtrimInvalidLimit = "ERR syntax error, LIMIT cannot be used without the special ~ option" - msgDBIndexOutOfRange = "ERR DB index is out of range" - msgLimitCombination = "ERR syntax error, LIMIT is only supported in combination with either BYSCORE or BYLEX" - msgRankIsZero = "ERR RANK can't be zero: use 1 to start from the first match, 2 from the second ... or use negative to start from the end of the list" - msgCountIsNegative = "ERR COUNT can't be negative" - msgMaxLengthIsNegative = "ERR MAXLEN can't be negative" -) - -func errWrongNumber(cmd string) string { - return fmt.Sprintf("ERR wrong number of arguments for '%s' command", strings.ToLower(cmd)) -} - -func errLuaParseError(err error) string { - return fmt.Sprintf("ERR Error compiling script (new function): %s", err.Error()) -} - -func errReadgroup(key, group string) error { - return fmt.Errorf("NOGROUP No such key '%s' or consumer group '%s'", key, group) -} - -func errXreadgroup(key, group string) error { - return fmt.Errorf("NOGROUP No such key '%s' or consumer group '%s' in XREADGROUP with GROUP option", key, group) -} - -func msgNotFromScripts(sha string) string { - return fmt.Sprintf("This Redis command is not allowed from script script: %s, &c", sha) -} - -// withTx wraps the non-argument-checking part of command handling code in -// transaction logic. -func withTx( - m *Miniredis, - c *server.Peer, - cb txCmd, -) { - ctx := getCtx(c) - - if ctx.nested { - // this is a call via Lua's .call(). It's already locked. - cb(c, ctx) - m.signal.Broadcast() - return - } - - if inTx(ctx) { - addTxCmd(ctx, cb) - c.WriteInline("QUEUED") - return - } - m.Lock() - cb(c, ctx) - // done, wake up anyone who waits on anything. - m.signal.Broadcast() - m.Unlock() -} - -// blockCmd is executed returns whether it is done -type blockCmd func(*server.Peer, *connCtx) bool - -// blocking keeps trying a command until the callback returns true. Calls -// onTimeout after the timeout (or when we call this in a transaction). -func blocking( - m *Miniredis, - c *server.Peer, - timeout time.Duration, - cb blockCmd, - onTimeout func(*server.Peer), -) { - var ( - ctx = getCtx(c) - ) - if inTx(ctx) { - addTxCmd(ctx, func(c *server.Peer, ctx *connCtx) { - if !cb(c, ctx) { - onTimeout(c) - } - }) - c.WriteInline("QUEUED") - return - } - - localCtx, cancel := context.WithCancel(m.Ctx) - defer cancel() - timedOut := false - if timeout != 0 { - go setCondTimer(localCtx, m.signal, &timedOut, timeout) - } - go func() { - <-localCtx.Done() - m.signal.Broadcast() // main loop might miss this signal - }() - - if !ctx.nested { - // this is a call via Lua's .call(). It's already locked. - m.Lock() - defer m.Unlock() - } - for { - if c.Closed() { - return - } - - if m.Ctx.Err() != nil { - return - } - - done := cb(c, ctx) - if done { - return - } - - if timedOut { - onTimeout(c) - return - } - - m.signal.Wait() - } -} - -func setCondTimer(ctx context.Context, sig *sync.Cond, timedOut *bool, timeout time.Duration) { - dl := time.NewTimer(timeout) - defer dl.Stop() - select { - case <-dl.C: - sig.L.Lock() // for timedOut - *timedOut = true - sig.Broadcast() // main loop might miss this signal - sig.L.Unlock() - case <-ctx.Done(): - } -} - -// formatBig formats a float the way redis does -func formatBig(v *big.Float) string { - // Format with %f and strip trailing 0s. - if v.IsInf() { - return "inf" - } - // if math.IsInf(v, -1) { - // return "-inf" - // } - return stripZeros(fmt.Sprintf("%.17f", v)) -} - -func stripZeros(sv string) string { - for strings.Contains(sv, ".") { - if sv[len(sv)-1] != '0' { - break - } - // Remove trailing 0s. - sv = sv[:len(sv)-1] - // Ends with a '.'. - if sv[len(sv)-1] == '.' { - sv = sv[:len(sv)-1] - break - } - } - return sv -} - -// redisRange gives Go offsets for something l long with start/end in -// Redis semantics. Both start and end can be negative. -// Used for string range and list range things. -// The results can be used as: v[start:end] -// Note that GETRANGE (on a string key) never returns an empty string when end -// is a large negative number. -func redisRange(l, start, end int, stringSymantics bool) (int, int) { - if start < 0 { - start = l + start - if start < 0 { - start = 0 - } - } - if start > l { - start = l - } - - if end < 0 { - end = l + end - if end < 0 { - end = -1 - if stringSymantics { - end = 0 - } - } - } - if end < math.MaxInt32 { - end++ // end argument is inclusive in Redis. - } - if end > l { - end = l - } - - if end < start { - return 0, 0 - } - return start, end -} diff --git a/vendor/github.com/alicebob/miniredis/v2/server/Makefile b/vendor/github.com/alicebob/miniredis/v2/server/Makefile deleted file mode 100644 index c82e336f9..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/server/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -.PHONY: all build test - -all: build test - -build: - go build - -test: - go test diff --git a/vendor/github.com/alicebob/miniredis/v2/server/proto.go b/vendor/github.com/alicebob/miniredis/v2/server/proto.go deleted file mode 100644 index f62e1d73f..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/server/proto.go +++ /dev/null @@ -1,157 +0,0 @@ -package server - -import ( - "bufio" - "errors" - "strconv" -) - -type Simple string - -// ErrProtocol is the general error for unexpected input -var ErrProtocol = errors.New("invalid request") - -// client always sends arrays with bulk strings -func readArray(rd *bufio.Reader) ([]string, error) { - line, err := rd.ReadString('\n') - if err != nil { - return nil, err - } - if len(line) < 3 { - return nil, ErrProtocol - } - - switch line[0] { - default: - return nil, ErrProtocol - case '*': - l, err := strconv.Atoi(line[1 : len(line)-2]) - if err != nil { - return nil, err - } - // l can be -1 - var fields []string - for ; l > 0; l-- { - s, err := readString(rd) - if err != nil { - return nil, err - } - fields = append(fields, s) - } - return fields, nil - } -} - -func readString(rd *bufio.Reader) (string, error) { - line, err := rd.ReadString('\n') - if err != nil { - return "", err - } - if len(line) < 3 { - return "", ErrProtocol - } - - switch line[0] { - default: - return "", ErrProtocol - case '+', '-', ':': - // +: simple string - // -: errors - // :: integer - // Simple line based replies. - return string(line[1 : len(line)-2]), nil - case '$': - // bulk strings are: `$5\r\nhello\r\n` - length, err := strconv.Atoi(line[1 : len(line)-2]) - if err != nil { - return "", err - } - if length < 0 { - // -1 is a nil response - return "", nil - } - var ( - buf = make([]byte, length+2) - pos = 0 - ) - for pos < length+2 { - n, err := rd.Read(buf[pos:]) - if err != nil { - return "", err - } - pos += n - } - return string(buf[:length]), nil - } -} - -// parse a reply -func ParseReply(rd *bufio.Reader) (interface{}, error) { - line, err := rd.ReadString('\n') - if err != nil { - return nil, err - } - if len(line) < 3 { - return nil, ErrProtocol - } - - switch line[0] { - default: - return nil, ErrProtocol - case '+': - // +: simple string - return Simple(line[1 : len(line)-2]), nil - case '-': - // -: errors - return nil, errors.New(string(line[1 : len(line)-2])) - case ':': - // :: integer - v := line[1 : len(line)-2] - if v == "" { - return 0, nil - } - n, err := strconv.Atoi(v) - if err != nil { - return nil, ErrProtocol - } - return n, nil - case '$': - // bulk strings are: `$5\r\nhello\r\n` - length, err := strconv.Atoi(line[1 : len(line)-2]) - if err != nil { - return "", err - } - if length < 0 { - // -1 is a nil response - return nil, nil - } - var ( - buf = make([]byte, length+2) - pos = 0 - ) - for pos < length+2 { - n, err := rd.Read(buf[pos:]) - if err != nil { - return "", err - } - pos += n - } - return string(buf[:length]), nil - case '*': - // array - l, err := strconv.Atoi(line[1 : len(line)-2]) - if err != nil { - return nil, ErrProtocol - } - // l can be -1 - var fields []interface{} - for ; l > 0; l-- { - s, err := ParseReply(rd) - if err != nil { - return nil, err - } - fields = append(fields, s) - } - return fields, nil - } -} diff --git a/vendor/github.com/alicebob/miniredis/v2/server/server.go b/vendor/github.com/alicebob/miniredis/v2/server/server.go deleted file mode 100644 index ee4f04c21..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/server/server.go +++ /dev/null @@ -1,504 +0,0 @@ -package server - -import ( - "bufio" - "crypto/tls" - "fmt" - "math" - "net" - "strings" - "sync" - "unicode" -) - -func errUnknownCommand(cmd string, args []string) string { - s := fmt.Sprintf("ERR unknown command `%s`, with args beginning with: ", cmd) - if len(args) > 20 { - args = args[:20] - } - for _, a := range args { - s += fmt.Sprintf("`%s`, ", a) - } - return s -} - -// Cmd is what Register expects -type Cmd func(c *Peer, cmd string, args []string) - -type DisconnectHandler func(c *Peer) - -// Hook is can be added to run before every cmd. Return true if the command is done. -type Hook func(*Peer, string, ...string) bool - -// Server is a simple redis server -type Server struct { - l net.Listener - cmds map[string]Cmd - preHook Hook - peers map[net.Conn]struct{} - mu sync.Mutex - wg sync.WaitGroup - infoConns int - infoCmds int -} - -// NewServer makes a server listening on addr. Close with .Close(). -func NewServer(addr string) (*Server, error) { - l, err := net.Listen("tcp", addr) - if err != nil { - return nil, err - } - return newServer(l), nil -} - -func NewServerTLS(addr string, cfg *tls.Config) (*Server, error) { - l, err := tls.Listen("tcp", addr, cfg) - if err != nil { - return nil, err - } - return newServer(l), nil -} - -func newServer(l net.Listener) *Server { - s := Server{ - cmds: map[string]Cmd{}, - peers: map[net.Conn]struct{}{}, - l: l, - } - - s.wg.Add(1) - go func() { - defer s.wg.Done() - s.serve(l) - - s.mu.Lock() - for c := range s.peers { - c.Close() - } - s.mu.Unlock() - }() - return &s -} - -// (un)set a hook which is ran before every call. It returns true if the command is done. -func (s *Server) SetPreHook(h Hook) { - s.mu.Lock() - s.preHook = h - s.mu.Unlock() -} - -func (s *Server) serve(l net.Listener) { - for { - conn, err := l.Accept() - if err != nil { - return - } - s.ServeConn(conn) - } -} - -// ServeConn handles a net.Conn. Nice with net.Pipe() -func (s *Server) ServeConn(conn net.Conn) { - s.wg.Add(1) - s.mu.Lock() - s.peers[conn] = struct{}{} - s.infoConns++ - s.mu.Unlock() - - go func() { - defer s.wg.Done() - defer conn.Close() - - s.servePeer(conn) - - s.mu.Lock() - delete(s.peers, conn) - s.mu.Unlock() - }() -} - -// Addr has the net.Addr struct -func (s *Server) Addr() *net.TCPAddr { - s.mu.Lock() - defer s.mu.Unlock() - if s.l == nil { - return nil - } - return s.l.Addr().(*net.TCPAddr) -} - -// Close a server started with NewServer. It will wait until all clients are -// closed. -func (s *Server) Close() { - s.mu.Lock() - if s.l != nil { - s.l.Close() - } - s.l = nil - s.mu.Unlock() - - s.wg.Wait() -} - -// Register a command. It can't have been registered before. Safe to call on a -// running server. -func (s *Server) Register(cmd string, f Cmd) error { - s.mu.Lock() - defer s.mu.Unlock() - cmd = strings.ToUpper(cmd) - if _, ok := s.cmds[cmd]; ok { - return fmt.Errorf("command already registered: %s", cmd) - } - s.cmds[cmd] = f - return nil -} - -func (s *Server) servePeer(c net.Conn) { - r := bufio.NewReader(c) - peer := &Peer{ - w: bufio.NewWriter(c), - } - - defer func() { - for _, f := range peer.onDisconnect { - f() - } - }() - - readCh := make(chan []string) - - go func() { - defer close(readCh) - - for { - args, err := readArray(r) - if err != nil { - peer.Close() - return - } - - readCh <- args - } - }() - - for args := range readCh { - s.Dispatch(peer, args) - peer.Flush() - - if peer.Closed() { - c.Close() - } - } -} - -func (s *Server) Dispatch(c *Peer, args []string) { - cmd, args := args[0], args[1:] - cmdUp := strings.ToUpper(cmd) - s.mu.Lock() - h := s.preHook - s.mu.Unlock() - if h != nil { - if h(c, cmdUp, args...) { - return - } - } - - s.mu.Lock() - cb, ok := s.cmds[cmdUp] - s.mu.Unlock() - if !ok { - c.WriteError(errUnknownCommand(cmd, args)) - return - } - - s.mu.Lock() - s.infoCmds++ - s.mu.Unlock() - cb(c, cmdUp, args) -} - -// TotalCommands is total (known) commands since this the server started -func (s *Server) TotalCommands() int { - s.mu.Lock() - defer s.mu.Unlock() - return s.infoCmds -} - -// ClientsLen gives the number of connected clients right now -func (s *Server) ClientsLen() int { - s.mu.Lock() - defer s.mu.Unlock() - return len(s.peers) -} - -// TotalConnections give the number of clients connected since the server -// started, including the currently connected ones -func (s *Server) TotalConnections() int { - s.mu.Lock() - defer s.mu.Unlock() - return s.infoConns -} - -// Peer is a client connected to the server -type Peer struct { - w *bufio.Writer - closed bool - Resp3 bool - Ctx interface{} // anything goes, server won't touch this - onDisconnect []func() // list of callbacks - mu sync.Mutex // for Block() -} - -func NewPeer(w *bufio.Writer) *Peer { - return &Peer{ - w: w, - } -} - -// Flush the write buffer. Called automatically after every redis command -func (c *Peer) Flush() { - c.mu.Lock() - defer c.mu.Unlock() - c.w.Flush() -} - -// Close the client connection after the current command is done. -func (c *Peer) Close() { - c.mu.Lock() - defer c.mu.Unlock() - c.closed = true -} - -// Return true if the peer connection closed. -func (c *Peer) Closed() bool { - c.mu.Lock() - defer c.mu.Unlock() - return c.closed -} - -// Register a function to execute on disconnect. There can be multiple -// functions registered. -func (c *Peer) OnDisconnect(f func()) { - c.onDisconnect = append(c.onDisconnect, f) -} - -// issue multiple calls, guarded with a mutex -func (c *Peer) Block(f func(*Writer)) { - c.mu.Lock() - defer c.mu.Unlock() - f(&Writer{c.w, c.Resp3}) -} - -// WriteError writes a redis 'Error' -func (c *Peer) WriteError(e string) { - c.Block(func(w *Writer) { - w.WriteError(e) - }) -} - -// WriteInline writes a redis inline string -func (c *Peer) WriteInline(s string) { - c.Block(func(w *Writer) { - w.WriteInline(s) - }) -} - -// WriteOK write the inline string `OK` -func (c *Peer) WriteOK() { - c.WriteInline("OK") -} - -// WriteBulk writes a bulk string -func (c *Peer) WriteBulk(s string) { - c.Block(func(w *Writer) { - w.WriteBulk(s) - }) -} - -// WriteNull writes a redis Null element -func (c *Peer) WriteNull() { - c.Block(func(w *Writer) { - w.WriteNull() - }) -} - -// WriteLen starts an array with the given length -func (c *Peer) WriteLen(n int) { - c.Block(func(w *Writer) { - w.WriteLen(n) - }) -} - -// WriteMapLen starts a map with the given length (number of keys) -func (c *Peer) WriteMapLen(n int) { - c.Block(func(w *Writer) { - w.WriteMapLen(n) - }) -} - -// WriteSetLen starts a set with the given length (number of elements) -func (c *Peer) WriteSetLen(n int) { - c.Block(func(w *Writer) { - w.WriteSetLen(n) - }) -} - -// WritePushLen starts a push-data array with the given length -func (c *Peer) WritePushLen(n int) { - c.Block(func(w *Writer) { - w.WritePushLen(n) - }) -} - -// WriteInt writes an integer -func (c *Peer) WriteInt(n int) { - c.Block(func(w *Writer) { - w.WriteInt(n) - }) -} - -// WriteFloat writes a float -func (c *Peer) WriteFloat(n float64) { - c.Block(func(w *Writer) { - w.WriteFloat(n) - }) -} - -// WriteRaw writes a raw redis response -func (c *Peer) WriteRaw(s string) { - c.Block(func(w *Writer) { - w.WriteRaw(s) - }) -} - -// WriteStrings is a helper to (bulk)write a string list -func (c *Peer) WriteStrings(strs []string) { - c.Block(func(w *Writer) { - w.WriteStrings(strs) - }) -} - -func toInline(s string) string { - return strings.Map(func(r rune) rune { - if unicode.IsSpace(r) { - return ' ' - } - return r - }, s) -} - -// A Writer is given to the callback in Block() -type Writer struct { - w *bufio.Writer - resp3 bool -} - -// WriteError writes a redis 'Error' -func (w *Writer) WriteError(e string) { - fmt.Fprintf(w.w, "-%s\r\n", toInline(e)) -} - -func (w *Writer) WriteLen(n int) { - fmt.Fprintf(w.w, "*%d\r\n", n) -} - -func (w *Writer) WriteMapLen(n int) { - if w.resp3 { - fmt.Fprintf(w.w, "%%%d\r\n", n) - return - } - w.WriteLen(n * 2) -} - -func (w *Writer) WriteSetLen(n int) { - if w.resp3 { - fmt.Fprintf(w.w, "~%d\r\n", n) - return - } - w.WriteLen(n) -} - -func (w *Writer) WritePushLen(n int) { - if w.resp3 { - fmt.Fprintf(w.w, ">%d\r\n", n) - return - } - w.WriteLen(n) -} - -// WriteBulk writes a bulk string -func (w *Writer) WriteBulk(s string) { - fmt.Fprintf(w.w, "$%d\r\n%s\r\n", len(s), s) -} - -// WriteStrings writes a list of strings (bulk) -func (w *Writer) WriteStrings(strs []string) { - w.WriteLen(len(strs)) - for _, s := range strs { - w.WriteBulk(s) - } -} - -// WriteInt writes an integer -func (w *Writer) WriteInt(n int) { - fmt.Fprintf(w.w, ":%d\r\n", n) -} - -// WriteFloat writes a float -func (w *Writer) WriteFloat(n float64) { - if w.resp3 { - fmt.Fprintf(w.w, ",%s\r\n", formatFloat(n)) - return - } - w.WriteBulk(formatFloat(n)) -} - -// WriteNull writes a redis Null element -func (w *Writer) WriteNull() { - if w.resp3 { - fmt.Fprint(w.w, "_\r\n") - return - } - fmt.Fprintf(w.w, "$-1\r\n") -} - -// WriteInline writes a redis inline string -func (w *Writer) WriteInline(s string) { - fmt.Fprintf(w.w, "+%s\r\n", toInline(s)) -} - -// WriteRaw writes a raw redis response -func (w *Writer) WriteRaw(s string) { - fmt.Fprint(w.w, s) -} - -func (w *Writer) Flush() { - w.w.Flush() -} - -// formatFloat formats a float the way redis does (sort-of) -func formatFloat(v float64) string { - if math.IsInf(v, 1) { - return "inf" - } - if math.IsInf(v, -1) { - return "-inf" - } - return stripZeros(fmt.Sprintf("%.12f", v)) -} - -func stripZeros(sv string) string { - for strings.Contains(sv, ".") { - if sv[len(sv)-1] != '0' { - break - } - // Remove trailing 0s. - sv = sv[:len(sv)-1] - // Ends with a '.'. - if sv[len(sv)-1] == '.' { - sv = sv[:len(sv)-1] - break - } - } - return sv -} diff --git a/vendor/github.com/alicebob/miniredis/v2/sorted_set.go b/vendor/github.com/alicebob/miniredis/v2/sorted_set.go deleted file mode 100644 index 96ebd5d71..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/sorted_set.go +++ /dev/null @@ -1,98 +0,0 @@ -package miniredis - -// The most KISS way to implement a sorted set. Luckily we don't care about -// performance that much. - -import ( - "sort" -) - -type direction int - -const ( - unsorted direction = iota - asc - desc -) - -type sortedSet map[string]float64 - -type ssElem struct { - score float64 - member string -} -type ssElems []ssElem - -type byScore ssElems - -func (sse byScore) Len() int { return len(sse) } -func (sse byScore) Swap(i, j int) { sse[i], sse[j] = sse[j], sse[i] } -func (sse byScore) Less(i, j int) bool { - if sse[i].score != sse[j].score { - return sse[i].score < sse[j].score - } - return sse[i].member < sse[j].member -} - -func newSortedSet() sortedSet { - return sortedSet{} -} - -func (ss *sortedSet) card() int { - return len(*ss) -} - -func (ss *sortedSet) set(score float64, member string) { - (*ss)[member] = score -} - -func (ss *sortedSet) get(member string) (float64, bool) { - v, ok := (*ss)[member] - return v, ok -} - -// elems gives the list of ssElem, ready to sort. -func (ss *sortedSet) elems() ssElems { - elems := make(ssElems, 0, len(*ss)) - for e, s := range *ss { - elems = append(elems, ssElem{s, e}) - } - return elems -} - -func (ss *sortedSet) byScore(d direction) ssElems { - elems := ss.elems() - sort.Sort(byScore(elems)) - if d == desc { - reverseElems(elems) - } - return ssElems(elems) -} - -// rankByScore gives the (0-based) index of member, or returns false. -func (ss *sortedSet) rankByScore(member string, d direction) (int, bool) { - if _, ok := (*ss)[member]; !ok { - return 0, false - } - for i, e := range ss.byScore(d) { - if e.member == member { - return i, true - } - } - // Can't happen - return 0, false -} - -func reverseSlice(o []string) { - for i := range make([]struct{}, len(o)/2) { - other := len(o) - 1 - i - o[i], o[other] = o[other], o[i] - } -} - -func reverseElems(o ssElems) { - for i := range make([]struct{}, len(o)/2) { - other := len(o) - 1 - i - o[i], o[other] = o[other], o[i] - } -} diff --git a/vendor/github.com/alicebob/miniredis/v2/stream.go b/vendor/github.com/alicebob/miniredis/v2/stream.go deleted file mode 100644 index 9e04aa170..000000000 --- a/vendor/github.com/alicebob/miniredis/v2/stream.go +++ /dev/null @@ -1,484 +0,0 @@ -// Basic stream implementation. - -package miniredis - -import ( - "errors" - "fmt" - "math" - "sort" - "strconv" - "strings" - "sync" - "time" -) - -// a Stream is a list of entries, lowest ID (oldest) first, and all "groups". -type streamKey struct { - entries []StreamEntry - groups map[string]*streamGroup - lastAllocatedID string - mu sync.Mutex -} - -// a StreamEntry is an entry in a stream. The ID is always of the form -// "123-123". -// Values is an ordered list of key-value pairs. -type StreamEntry struct { - ID string - Values []string -} - -type streamGroup struct { - stream *streamKey - lastID string - pending []pendingEntry - consumers map[string]*consumer -} - -type consumer struct { - numPendingEntries int - // TODO: "last seen" timestamp -} - -type pendingEntry struct { - id string - consumer string - deliveryCount int - lastDelivery time.Time -} - -func newStreamKey() *streamKey { - return &streamKey{ - groups: map[string]*streamGroup{}, - } -} - -// generateID doesn't lock the mutex -func (s *streamKey) generateID(now time.Time) string { - ts := uint64(now.UnixNano()) / 1_000_000 - - next := fmt.Sprintf("%d-%d", ts, 0) - if s.lastAllocatedID != "" && streamCmp(s.lastAllocatedID, next) >= 0 { - last, _ := parseStreamID(s.lastAllocatedID) - next = fmt.Sprintf("%d-%d", last[0], last[1]+1) - } - - lastID := s.lastIDUnlocked() - if streamCmp(lastID, next) >= 0 { - last, _ := parseStreamID(lastID) - next = fmt.Sprintf("%d-%d", last[0], last[1]+1) - } - - s.lastAllocatedID = next - return next -} - -// lastID locks the mutex -func (s *streamKey) lastID() string { - s.mu.Lock() - defer s.mu.Unlock() - - return s.lastIDUnlocked() -} - -// lastID doesn't lock the mutex -func (s *streamKey) lastIDUnlocked() string { - if len(s.entries) == 0 { - return "0-0" - } - - return s.entries[len(s.entries)-1].ID -} - -func (s *streamKey) copy() *streamKey { - s.mu.Lock() - defer s.mu.Unlock() - - cpy := &streamKey{ - entries: s.entries, - } - groups := map[string]*streamGroup{} - for k, v := range s.groups { - gr := v.copy() - gr.stream = cpy - groups[k] = gr - } - cpy.groups = groups - return cpy -} - -func parseStreamID(id string) ([2]uint64, error) { - var ( - res [2]uint64 - err error - ) - parts := strings.SplitN(id, "-", 2) - res[0], err = strconv.ParseUint(parts[0], 10, 64) - if err != nil { - return res, errors.New(msgInvalidStreamID) - } - if len(parts) == 2 { - res[1], err = strconv.ParseUint(parts[1], 10, 64) - if err != nil { - return res, errors.New(msgInvalidStreamID) - } - } - return res, nil -} - -// compares two stream IDs (of the full format: "123-123"). Returns: -1, 0, 1 -// The given IDs should be valid stream IDs. -func streamCmp(a, b string) int { - ap, _ := parseStreamID(a) - bp, _ := parseStreamID(b) - - switch { - case ap[0] < bp[0]: - return -1 - case ap[0] > bp[0]: - return 1 - case ap[1] < bp[1]: - return -1 - case ap[1] > bp[1]: - return 1 - default: - return 0 - } -} - -// formatStreamID makes a full id ("42-42") out of a partial one ("42") -func formatStreamID(id string) (string, error) { - var ts [2]uint64 - parts := strings.SplitN(id, "-", 2) - - if len(parts) > 0 { - p, err := strconv.ParseUint(parts[0], 10, 64) - if err != nil { - return "", errInvalidEntryID - } - ts[0] = p - } - if len(parts) > 1 { - p, err := strconv.ParseUint(parts[1], 10, 64) - if err != nil { - return "", errInvalidEntryID - } - ts[1] = p - } - return fmt.Sprintf("%d-%d", ts[0], ts[1]), nil -} - -func formatStreamRangeBound(id string, start bool, reverse bool) (string, error) { - if id == "-" { - return "0-0", nil - } - - if id == "+" { - return fmt.Sprintf("%d-%d", uint64(math.MaxUint64), uint64(math.MaxUint64)), nil - } - - if id == "0" { - return "0-0", nil - } - - parts := strings.Split(id, "-") - if len(parts) == 2 { - return formatStreamID(id) - } - - // Incomplete IDs case - ts, err := strconv.ParseUint(parts[0], 10, 64) - if err != nil { - return "", errInvalidEntryID - } - - if (!start && !reverse) || (start && reverse) { - return fmt.Sprintf("%d-%d", ts, uint64(math.MaxUint64)), nil - } - - return fmt.Sprintf("%d-%d", ts, 0), nil -} - -func reversedStreamEntries(o []StreamEntry) []StreamEntry { - newStream := make([]StreamEntry, len(o)) - for i, e := range o { - newStream[len(o)-i-1] = e - } - return newStream -} - -func (s *streamKey) createGroup(group, id string) error { - s.mu.Lock() - defer s.mu.Unlock() - - if _, ok := s.groups[group]; ok { - return errors.New("BUSYGROUP Consumer Group name already exists") - } - - if id == "$" { - id = s.lastIDUnlocked() - } - s.groups[group] = &streamGroup{ - stream: s, - lastID: id, - consumers: map[string]*consumer{}, - } - return nil -} - -// streamAdd adds an entry to a stream. Returns the new entry ID. -// If id is empty or "*" the ID will be generated automatically. -// `values` should have an even length. -func (s *streamKey) add(entryID string, values []string, now time.Time) (string, error) { - s.mu.Lock() - defer s.mu.Unlock() - - if entryID == "" || entryID == "*" { - entryID = s.generateID(now) - } - - entryID, err := formatStreamID(entryID) - if err != nil { - return "", err - } - if entryID == "0-0" { - return "", errors.New(msgStreamIDZero) - } - if streamCmp(s.lastIDUnlocked(), entryID) != -1 { - return "", errors.New(msgStreamIDTooSmall) - } - - s.entries = append(s.entries, StreamEntry{ - ID: entryID, - Values: values, - }) - return entryID, nil -} - -func (s *streamKey) trim(n int) { - s.mu.Lock() - defer s.mu.Unlock() - - if len(s.entries) > n { - s.entries = s.entries[len(s.entries)-n:] - } -} - -// trimBefore deletes entries with an id less than the provided id -// and returns the number of entries deleted -func (s *streamKey) trimBefore(id string) int { - s.mu.Lock() - var delete []string - for _, entry := range s.entries { - if entry.ID < id { - delete = append(delete, entry.ID) - } else { - break - } - } - s.mu.Unlock() - s.delete(delete) - return len(delete) -} - -// all entries after "id" -func (s *streamKey) after(id string) []StreamEntry { - s.mu.Lock() - defer s.mu.Unlock() - - pos := sort.Search(len(s.entries), func(i int) bool { - return streamCmp(id, s.entries[i].ID) < 0 - }) - return s.entries[pos:] -} - -// get a stream entry by ID -// Also returns the position in the entries slice, if found. -func (s *streamKey) get(id string) (int, *StreamEntry) { - s.mu.Lock() - defer s.mu.Unlock() - - pos := sort.Search(len(s.entries), func(i int) bool { - return streamCmp(id, s.entries[i].ID) <= 0 - }) - if len(s.entries) <= pos || s.entries[pos].ID != id { - return 0, nil - } - return pos, &s.entries[pos] -} - -func (g *streamGroup) readGroup( - now time.Time, - consumerID, - id string, - count int, - noack bool, -) []StreamEntry { - if id == ">" { - // undelivered messages - msgs := g.stream.after(g.lastID) - if len(msgs) == 0 { - return nil - } - - if count > 0 && len(msgs) > count { - msgs = msgs[:count] - } - - if !noack { - shouldAppend := len(g.pending) == 0 - for _, msg := range msgs { - if !shouldAppend { - shouldAppend = streamCmp(msg.ID, g.pending[len(g.pending)-1].id) == 1 - } - - var entry *pendingEntry - if shouldAppend { - g.pending = append(g.pending, pendingEntry{}) - entry = &g.pending[len(g.pending)-1] - } else { - var pos int - pos, entry = g.searchPending(msg.ID) - if entry == nil { - g.pending = append(g.pending[:pos+1], g.pending[pos:]...) - entry = &g.pending[pos] - } else { - g.consumers[entry.consumer].numPendingEntries-- - } - } - - *entry = pendingEntry{ - id: msg.ID, - consumer: consumerID, - deliveryCount: 1, - lastDelivery: now, - } - } - } - if _, ok := g.consumers[consumerID]; !ok { - g.consumers[consumerID] = &consumer{} - } - g.consumers[consumerID].numPendingEntries += len(msgs) - g.lastID = msgs[len(msgs)-1].ID - return msgs - } - - // re-deliver messages from the pending list. - // con := gr.consumers[consumerID] - msgs := g.pendingAfter(id) - var res []StreamEntry - for i, p := range msgs { - if p.consumer != consumerID { - continue - } - _, entry := g.stream.get(p.id) - // not found. Weird? - if entry == nil { - continue - } - p.deliveryCount += 1 - p.lastDelivery = now - msgs[i] = p - res = append(res, *entry) - } - return res -} - -func (g *streamGroup) searchPending(id string) (int, *pendingEntry) { - pos := sort.Search(len(g.pending), func(i int) bool { - return streamCmp(id, g.pending[i].id) <= 0 - }) - if pos >= len(g.pending) || g.pending[pos].id != id { - return pos, nil - } - return pos, &g.pending[pos] -} - -func (g *streamGroup) ack(ids []string) (int, error) { - count := 0 - for _, id := range ids { - if _, err := parseStreamID(id); err != nil { - return 0, errors.New(msgInvalidStreamID) - } - - pos, entry := g.searchPending(id) - if entry == nil { - continue - } - - consumer := g.consumers[entry.consumer] - consumer.numPendingEntries-- - - g.pending = append(g.pending[:pos], g.pending[pos+1:]...) - // don't count deleted entries - if _, e := g.stream.get(id); e == nil { - continue - } - count++ - } - return count, nil -} - -func (s *streamKey) delete(ids []string) (int, error) { - count := 0 - for _, id := range ids { - if _, err := parseStreamID(id); err != nil { - return 0, errors.New(msgInvalidStreamID) - } - - i, entry := s.get(id) - if entry == nil { - continue - } - - s.entries = append(s.entries[:i], s.entries[i+1:]...) - count++ - } - return count, nil -} - -func (g *streamGroup) pendingAfter(id string) []pendingEntry { - pos := sort.Search(len(g.pending), func(i int) bool { - return streamCmp(id, g.pending[i].id) < 0 - }) - return g.pending[pos:] -} - -func (g *streamGroup) pendingCount(consumer string) int { - n := 0 - for _, p := range g.activePending() { - if p.consumer == consumer { - n++ - } - } - return n -} - -// pending entries without the entries deleted from the group -func (g *streamGroup) activePending() []pendingEntry { - var pe []pendingEntry - for _, p := range g.pending { - // drop deleted ones - if _, e := g.stream.get(p.id); e == nil { - continue - } - p := p - pe = append(pe, p) - } - return pe -} - -func (g *streamGroup) copy() *streamGroup { - cns := map[string]*consumer{} - for k, v := range g.consumers { - c := *v - cns[k] = &c - } - return &streamGroup{ - // don't copy stream - lastID: g.lastID, - pending: g.pending, - consumers: cns, - } -} diff --git a/vendor/github.com/alingse/asasalint/.gitignore b/vendor/github.com/alingse/asasalint/.gitignore deleted file mode 100644 index d0fc531c8..000000000 --- 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 e45d5860d..000000000 --- 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 a7c39f2e3..000000000 --- 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 12f8ba928..000000000 --- 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 3fa7e65b3..000000000 --- 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 f34516a46..000000000 --- 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/asaskevich/govalidator/.gitignore b/vendor/github.com/asaskevich/govalidator/.gitignore deleted file mode 100644 index 8d69a9418..000000000 --- a/vendor/github.com/asaskevich/govalidator/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -bin/ -.idea/ -# 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 - diff --git a/vendor/github.com/asaskevich/govalidator/.travis.yml b/vendor/github.com/asaskevich/govalidator/.travis.yml deleted file mode 100644 index bb83c6670..000000000 --- a/vendor/github.com/asaskevich/govalidator/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: go -dist: xenial -go: - - '1.10' - - '1.11' - - '1.12' - - '1.13' - - 'tip' - -script: - - go test -coverpkg=./... -coverprofile=coverage.info -timeout=5s - - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md b/vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md deleted file mode 100644 index 4b462b0d8..000000000 --- a/vendor/github.com/asaskevich/govalidator/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,43 +0,0 @@ -# Contributor Code of Conduct - -This project adheres to [The Code Manifesto](http://codemanifesto.com) -as its guidelines for contributor interactions. - -## The Code Manifesto - -We want to work in an ecosystem that empowers developers to reach their -potential — one that encourages growth and effective collaboration. A space -that is safe for all. - -A space such as this benefits everyone that participates in it. It encourages -new developers to enter our field. It is through discussion and collaboration -that we grow, and through growth that we improve. - -In the effort to create such a place, we hold to these values: - -1. **Discrimination limits us.** This includes discrimination on the basis of - race, gender, sexual orientation, gender identity, age, nationality, - technology and any other arbitrary exclusion of a group of people. -2. **Boundaries honor us.** Your comfort levels are not everyone’s comfort - levels. Remember that, and if brought to your attention, heed it. -3. **We are our biggest assets.** None of us were born masters of our trade. - Each of us has been helped along the way. Return that favor, when and where - you can. -4. **We are resources for the future.** As an extension of #3, share what you - know. Make yourself a resource to help those that come after you. -5. **Respect defines us.** Treat others as you wish to be treated. Make your - discussions, criticisms and debates from a position of respectfulness. Ask - yourself, is it true? Is it necessary? Is it constructive? Anything less is - unacceptable. -6. **Reactions require grace.** Angry responses are valid, but abusive language - and vindictive actions are toxic. When something happens that offends you, - handle it assertively, but be respectful. Escalate reasonably, and try to - allow the offender an opportunity to explain themselves, and possibly - correct the issue. -7. **Opinions are just that: opinions.** Each and every one of us, due to our - background and upbringing, have varying opinions. That is perfectly - acceptable. Remember this: if you respect your own opinions, you should - respect the opinions of others. -8. **To err is human.** You might not intend it, but mistakes do happen and - contribute to build experience. Tolerate honest mistakes, and don't - hesitate to apologize if you make one yourself. diff --git a/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md b/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md deleted file mode 100644 index 7ed268a1e..000000000 --- a/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md +++ /dev/null @@ -1,63 +0,0 @@ -#### Support -If you do have a contribution to the package, feel free to create a Pull Request or an Issue. - -#### What to contribute -If you don't know what to do, there are some features and functions that need to be done - -- [ ] Refactor code -- [ ] Edit docs and [README](https://github.com/asaskevich/govalidator/README.md): spellcheck, grammar and typo check -- [ ] Create actual list of contributors and projects that currently using this package -- [ ] Resolve [issues and bugs](https://github.com/asaskevich/govalidator/issues) -- [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions) -- [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new -- [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc -- [x] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224) -- [ ] Implement fuzzing testing -- [ ] Implement some struct/map/array utilities -- [ ] Implement map/array validation -- [ ] Implement benchmarking -- [ ] Implement batch of examples -- [ ] Look at forks for new features and fixes - -#### Advice -Feel free to create what you want, but keep in mind when you implement new features: -- Code must be clear and readable, names of variables/constants clearly describes what they are doing -- Public functions must be documented and described in source file and added to README.md to the list of available functions -- There are must be unit-tests for any new functions and improvements - -## Financial contributions - -We also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/govalidator). -Anyone can file an expense. If the expense makes sense for the development of the community, it will be "merged" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed. - - -## Credits - - -### Contributors - -Thank you to all the people who have already contributed to govalidator! - - - -### Backers - -Thank you to all our backers! [[Become a backer](https://opencollective.com/govalidator#backer)] - - - - -### Sponsors - -Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/govalidator#sponsor)) - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/asaskevich/govalidator/LICENSE b/vendor/github.com/asaskevich/govalidator/LICENSE deleted file mode 100644 index cacba9102..000000000 --- a/vendor/github.com/asaskevich/govalidator/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014-2020 Alex Saskevich - -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/asaskevich/govalidator/README.md b/vendor/github.com/asaskevich/govalidator/README.md deleted file mode 100644 index 2c3fc35eb..000000000 --- a/vendor/github.com/asaskevich/govalidator/README.md +++ /dev/null @@ -1,622 +0,0 @@ -govalidator -=========== -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/asaskevich/govalidator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![GoDoc](https://godoc.org/github.com/asaskevich/govalidator?status.png)](https://godoc.org/github.com/asaskevich/govalidator) -[![Build Status](https://travis-ci.org/asaskevich/govalidator.svg?branch=master)](https://travis-ci.org/asaskevich/govalidator) -[![Coverage](https://codecov.io/gh/asaskevich/govalidator/branch/master/graph/badge.svg)](https://codecov.io/gh/asaskevich/govalidator) [![Go Report Card](https://goreportcard.com/badge/github.com/asaskevich/govalidator)](https://goreportcard.com/report/github.com/asaskevich/govalidator) [![GoSearch](http://go-search.org/badge?id=github.com%2Fasaskevich%2Fgovalidator)](http://go-search.org/view?id=github.com%2Fasaskevich%2Fgovalidator) [![Backers on Open Collective](https://opencollective.com/govalidator/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/govalidator/sponsors/badge.svg)](#sponsors) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_shield) - -A package of validators and sanitizers for strings, structs and collections. Based on [validator.js](https://github.com/chriso/validator.js). - -#### Installation -Make sure that Go is installed on your computer. -Type the following command in your terminal: - - go get github.com/asaskevich/govalidator - -or you can get specified release of the package with `gopkg.in`: - - go get gopkg.in/asaskevich/govalidator.v10 - -After it the package is ready to use. - - -#### Import package in your project -Add following line in your `*.go` file: -```go -import "github.com/asaskevich/govalidator" -``` -If you are unhappy to use long `govalidator`, you can do something like this: -```go -import ( - valid "github.com/asaskevich/govalidator" -) -``` - -#### Activate behavior to require all fields have a validation tag by default -`SetFieldsRequiredByDefault` causes validation to fail when struct fields do not include validations or are not explicitly marked as exempt (using `valid:"-"` or `valid:"email,optional"`). A good place to activate this is a package init function or the main() function. - -`SetNilPtrAllowedByRequired` causes validation to pass when struct fields marked by `required` are set to nil. This is disabled by default for consistency, but some packages that need to be able to determine between `nil` and `zero value` state can use this. If disabled, both `nil` and `zero` values cause validation errors. - -```go -import "github.com/asaskevich/govalidator" - -func init() { - govalidator.SetFieldsRequiredByDefault(true) -} -``` - -Here's some code to explain it: -```go -// this struct definition will fail govalidator.ValidateStruct() (and the field values do not matter): -type exampleStruct struct { - Name string `` - Email string `valid:"email"` -} - -// this, however, will only fail when Email is empty or an invalid email address: -type exampleStruct2 struct { - Name string `valid:"-"` - Email string `valid:"email"` -} - -// lastly, this will only fail when Email is an invalid email address but not when it's empty: -type exampleStruct2 struct { - Name string `valid:"-"` - Email string `valid:"email,optional"` -} -``` - -#### Recent breaking changes (see [#123](https://github.com/asaskevich/govalidator/pull/123)) -##### Custom validator function signature -A context was added as the second parameter, for structs this is the object being validated – this makes dependent validation possible. -```go -import "github.com/asaskevich/govalidator" - -// old signature -func(i interface{}) bool - -// new signature -func(i interface{}, o interface{}) bool -``` - -##### Adding a custom validator -This was changed to prevent data races when accessing custom validators. -```go -import "github.com/asaskevich/govalidator" - -// before -govalidator.CustomTypeTagMap["customByteArrayValidator"] = func(i interface{}, o interface{}) bool { - // ... -} - -// after -govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, o interface{}) bool { - // ... -}) -``` - -#### List of functions: -```go -func Abs(value float64) float64 -func BlackList(str, chars string) string -func ByteLength(str string, params ...string) bool -func CamelCaseToUnderscore(str string) string -func Contains(str, substring string) bool -func Count(array []interface{}, iterator ConditionIterator) int -func Each(array []interface{}, iterator Iterator) -func ErrorByField(e error, field string) string -func ErrorsByField(e error) map[string]string -func Filter(array []interface{}, iterator ConditionIterator) []interface{} -func Find(array []interface{}, iterator ConditionIterator) interface{} -func GetLine(s string, index int) (string, error) -func GetLines(s string) []string -func HasLowerCase(str string) bool -func HasUpperCase(str string) bool -func HasWhitespace(str string) bool -func HasWhitespaceOnly(str string) bool -func InRange(value interface{}, left interface{}, right interface{}) bool -func InRangeFloat32(value, left, right float32) bool -func InRangeFloat64(value, left, right float64) bool -func InRangeInt(value, left, right interface{}) bool -func IsASCII(str string) bool -func IsAlpha(str string) bool -func IsAlphanumeric(str string) bool -func IsBase64(str string) bool -func IsByteLength(str string, min, max int) bool -func IsCIDR(str string) bool -func IsCRC32(str string) bool -func IsCRC32b(str string) bool -func IsCreditCard(str string) bool -func IsDNSName(str string) bool -func IsDataURI(str string) bool -func IsDialString(str string) bool -func IsDivisibleBy(str, num string) bool -func IsEmail(str string) bool -func IsExistingEmail(email string) bool -func IsFilePath(str string) (bool, int) -func IsFloat(str string) bool -func IsFullWidth(str string) bool -func IsHalfWidth(str string) bool -func IsHash(str string, algorithm string) bool -func IsHexadecimal(str string) bool -func IsHexcolor(str string) bool -func IsHost(str string) bool -func IsIP(str string) bool -func IsIPv4(str string) bool -func IsIPv6(str string) bool -func IsISBN(str string, version int) bool -func IsISBN10(str string) bool -func IsISBN13(str string) bool -func IsISO3166Alpha2(str string) bool -func IsISO3166Alpha3(str string) bool -func IsISO4217(str string) bool -func IsISO693Alpha2(str string) bool -func IsISO693Alpha3b(str string) bool -func IsIn(str string, params ...string) bool -func IsInRaw(str string, params ...string) bool -func IsInt(str string) bool -func IsJSON(str string) bool -func IsLatitude(str string) bool -func IsLongitude(str string) bool -func IsLowerCase(str string) bool -func IsMAC(str string) bool -func IsMD4(str string) bool -func IsMD5(str string) bool -func IsMagnetURI(str string) bool -func IsMongoID(str string) bool -func IsMultibyte(str string) bool -func IsNatural(value float64) bool -func IsNegative(value float64) bool -func IsNonNegative(value float64) bool -func IsNonPositive(value float64) bool -func IsNotNull(str string) bool -func IsNull(str string) bool -func IsNumeric(str string) bool -func IsPort(str string) bool -func IsPositive(value float64) bool -func IsPrintableASCII(str string) bool -func IsRFC3339(str string) bool -func IsRFC3339WithoutZone(str string) bool -func IsRGBcolor(str string) bool -func IsRegex(str string) bool -func IsRequestURI(rawurl string) bool -func IsRequestURL(rawurl string) bool -func IsRipeMD128(str string) bool -func IsRipeMD160(str string) bool -func IsRsaPub(str string, params ...string) bool -func IsRsaPublicKey(str string, keylen int) bool -func IsSHA1(str string) bool -func IsSHA256(str string) bool -func IsSHA384(str string) bool -func IsSHA512(str string) bool -func IsSSN(str string) bool -func IsSemver(str string) bool -func IsTiger128(str string) bool -func IsTiger160(str string) bool -func IsTiger192(str string) bool -func IsTime(str string, format string) bool -func IsType(v interface{}, params ...string) bool -func IsURL(str string) bool -func IsUTFDigit(str string) bool -func IsUTFLetter(str string) bool -func IsUTFLetterNumeric(str string) bool -func IsUTFNumeric(str string) bool -func IsUUID(str string) bool -func IsUUIDv3(str string) bool -func IsUUIDv4(str string) bool -func IsUUIDv5(str string) bool -func IsULID(str string) bool -func IsUnixTime(str string) bool -func IsUpperCase(str string) bool -func IsVariableWidth(str string) bool -func IsWhole(value float64) bool -func LeftTrim(str, chars string) string -func Map(array []interface{}, iterator ResultIterator) []interface{} -func Matches(str, pattern string) bool -func MaxStringLength(str string, params ...string) bool -func MinStringLength(str string, params ...string) bool -func NormalizeEmail(str string) (string, error) -func PadBoth(str string, padStr string, padLen int) string -func PadLeft(str string, padStr string, padLen int) string -func PadRight(str string, padStr string, padLen int) string -func PrependPathToErrors(err error, path string) error -func Range(str string, params ...string) bool -func RemoveTags(s string) string -func ReplacePattern(str, pattern, replace string) string -func Reverse(s string) string -func RightTrim(str, chars string) string -func RuneLength(str string, params ...string) bool -func SafeFileName(str string) string -func SetFieldsRequiredByDefault(value bool) -func SetNilPtrAllowedByRequired(value bool) -func Sign(value float64) float64 -func StringLength(str string, params ...string) bool -func StringMatches(s string, params ...string) bool -func StripLow(str string, keepNewLines bool) string -func ToBoolean(str string) (bool, error) -func ToFloat(str string) (float64, error) -func ToInt(value interface{}) (res int64, err error) -func ToJSON(obj interface{}) (string, error) -func ToString(obj interface{}) string -func Trim(str, chars string) string -func Truncate(str string, length int, ending string) string -func TruncatingErrorf(str string, args ...interface{}) error -func UnderscoreToCamelCase(s string) string -func ValidateMap(inputMap map[string]interface{}, validationMap map[string]interface{}) (bool, error) -func ValidateStruct(s interface{}) (bool, error) -func WhiteList(str, chars string) string -type ConditionIterator -type CustomTypeValidator -type Error -func (e Error) Error() string -type Errors -func (es Errors) Error() string -func (es Errors) Errors() []error -type ISO3166Entry -type ISO693Entry -type InterfaceParamValidator -type Iterator -type ParamValidator -type ResultIterator -type UnsupportedTypeError -func (e *UnsupportedTypeError) Error() string -type Validator -``` - -#### Examples -###### IsURL -```go -println(govalidator.IsURL(`http://user@pass:domain.com/path/page`)) -``` -###### IsType -```go -println(govalidator.IsType("Bob", "string")) -println(govalidator.IsType(1, "int")) -i := 1 -println(govalidator.IsType(&i, "*int")) -``` - -IsType can be used through the tag `type` which is essential for map validation: -```go -type User struct { - Name string `valid:"type(string)"` - Age int `valid:"type(int)"` - Meta interface{} `valid:"type(string)"` -} -result, err := govalidator.ValidateStruct(User{"Bob", 20, "meta"}) -if err != nil { - println("error: " + err.Error()) -} -println(result) -``` -###### ToString -```go -type User struct { - FirstName string - LastName string -} - -str := govalidator.ToString(&User{"John", "Juan"}) -println(str) -``` -###### Each, Map, Filter, Count for slices -Each iterates over the slice/array and calls Iterator for every item -```go -data := []interface{}{1, 2, 3, 4, 5} -var fn govalidator.Iterator = func(value interface{}, index int) { - println(value.(int)) -} -govalidator.Each(data, fn) -``` -```go -data := []interface{}{1, 2, 3, 4, 5} -var fn govalidator.ResultIterator = func(value interface{}, index int) interface{} { - return value.(int) * 3 -} -_ = govalidator.Map(data, fn) // result = []interface{}{1, 6, 9, 12, 15} -``` -```go -data := []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} -var fn govalidator.ConditionIterator = func(value interface{}, index int) bool { - return value.(int)%2 == 0 -} -_ = govalidator.Filter(data, fn) // result = []interface{}{2, 4, 6, 8, 10} -_ = govalidator.Count(data, fn) // result = 5 -``` -###### ValidateStruct [#2](https://github.com/asaskevich/govalidator/pull/2) -If you want to validate structs, you can use tag `valid` for any field in your structure. All validators used with this field in one tag are separated by comma. If you want to skip validation, place `-` in your tag. If you need a validator that is not on the list below, you can add it like this: -```go -govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool { - return str == "duck" -}) -``` -For completely custom validators (interface-based), see below. - -Here is a list of available validators for struct fields (validator - used function): -```go -"email": IsEmail, -"url": IsURL, -"dialstring": IsDialString, -"requrl": IsRequestURL, -"requri": IsRequestURI, -"alpha": IsAlpha, -"utfletter": IsUTFLetter, -"alphanum": IsAlphanumeric, -"utfletternum": IsUTFLetterNumeric, -"numeric": IsNumeric, -"utfnumeric": IsUTFNumeric, -"utfdigit": IsUTFDigit, -"hexadecimal": IsHexadecimal, -"hexcolor": IsHexcolor, -"rgbcolor": IsRGBcolor, -"lowercase": IsLowerCase, -"uppercase": IsUpperCase, -"int": IsInt, -"float": IsFloat, -"null": IsNull, -"uuid": IsUUID, -"uuidv3": IsUUIDv3, -"uuidv4": IsUUIDv4, -"uuidv5": IsUUIDv5, -"creditcard": IsCreditCard, -"isbn10": IsISBN10, -"isbn13": IsISBN13, -"json": IsJSON, -"multibyte": IsMultibyte, -"ascii": IsASCII, -"printableascii": IsPrintableASCII, -"fullwidth": IsFullWidth, -"halfwidth": IsHalfWidth, -"variablewidth": IsVariableWidth, -"base64": IsBase64, -"datauri": IsDataURI, -"ip": IsIP, -"port": IsPort, -"ipv4": IsIPv4, -"ipv6": IsIPv6, -"dns": IsDNSName, -"host": IsHost, -"mac": IsMAC, -"latitude": IsLatitude, -"longitude": IsLongitude, -"ssn": IsSSN, -"semver": IsSemver, -"rfc3339": IsRFC3339, -"rfc3339WithoutZone": IsRFC3339WithoutZone, -"ISO3166Alpha2": IsISO3166Alpha2, -"ISO3166Alpha3": IsISO3166Alpha3, -"ulid": IsULID, -``` -Validators with parameters - -```go -"range(min|max)": Range, -"length(min|max)": ByteLength, -"runelength(min|max)": RuneLength, -"stringlength(min|max)": StringLength, -"matches(pattern)": StringMatches, -"in(string1|string2|...|stringN)": IsIn, -"rsapub(keylength)" : IsRsaPub, -"minstringlength(int): MinStringLength, -"maxstringlength(int): MaxStringLength, -``` -Validators with parameters for any type - -```go -"type(type)": IsType, -``` - -And here is small example of usage: -```go -type Post struct { - Title string `valid:"alphanum,required"` - Message string `valid:"duck,ascii"` - Message2 string `valid:"animal(dog)"` - AuthorIP string `valid:"ipv4"` - Date string `valid:"-"` -} -post := &Post{ - Title: "My Example Post", - Message: "duck", - Message2: "dog", - AuthorIP: "123.234.54.3", -} - -// Add your own struct validation tags -govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool { - return str == "duck" -}) - -// Add your own struct validation tags with parameter -govalidator.ParamTagMap["animal"] = govalidator.ParamValidator(func(str string, params ...string) bool { - species := params[0] - return str == species -}) -govalidator.ParamTagRegexMap["animal"] = regexp.MustCompile("^animal\\((\\w+)\\)$") - -result, err := govalidator.ValidateStruct(post) -if err != nil { - println("error: " + err.Error()) -} -println(result) -``` -###### ValidateMap [#2](https://github.com/asaskevich/govalidator/pull/338) -If you want to validate maps, you can use the map to be validated and a validation map that contain the same tags used in ValidateStruct, both maps have to be in the form `map[string]interface{}` - -So here is small example of usage: -```go -var mapTemplate = map[string]interface{}{ - "name":"required,alpha", - "family":"required,alpha", - "email":"required,email", - "cell-phone":"numeric", - "address":map[string]interface{}{ - "line1":"required,alphanum", - "line2":"alphanum", - "postal-code":"numeric", - }, -} - -var inputMap = map[string]interface{}{ - "name":"Bob", - "family":"Smith", - "email":"foo@bar.baz", - "address":map[string]interface{}{ - "line1":"", - "line2":"", - "postal-code":"", - }, -} - -result, err := govalidator.ValidateMap(inputMap, mapTemplate) -if err != nil { - println("error: " + err.Error()) -} -println(result) -``` - -###### WhiteList -```go -// Remove all characters from string ignoring characters between "a" and "z" -println(govalidator.WhiteList("a3a43a5a4a3a2a23a4a5a4a3a4", "a-z") == "aaaaaaaaaaaa") -``` - -###### Custom validation functions -Custom validation using your own domain specific validators is also available - here's an example of how to use it: -```go -import "github.com/asaskevich/govalidator" - -type CustomByteArray [6]byte // custom types are supported and can be validated - -type StructWithCustomByteArray struct { - ID CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"` // multiple custom validators are possible as well and will be evaluated in sequence - Email string `valid:"email"` - CustomMinLength int `valid:"-"` -} - -govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, context interface{}) bool { - switch v := context.(type) { // you can type switch on the context interface being validated - case StructWithCustomByteArray: - // you can check and validate against some other field in the context, - // return early or not validate against the context at all – your choice - case SomeOtherType: - // ... - default: - // expecting some other type? Throw/panic here or continue - } - - switch v := i.(type) { // type switch on the struct field being validated - case CustomByteArray: - for _, e := range v { // this validator checks that the byte array is not empty, i.e. not all zeroes - if e != 0 { - return true - } - } - } - return false -}) -govalidator.CustomTypeTagMap.Set("customMinLengthValidator", func(i interface{}, context interface{}) bool { - switch v := context.(type) { // this validates a field against the value in another field, i.e. dependent validation - case StructWithCustomByteArray: - return len(v.ID) >= v.CustomMinLength - } - return false -}) -``` - -###### Loop over Error() -By default .Error() returns all errors in a single String. To access each error you can do this: -```go - if err != nil { - errs := err.(govalidator.Errors).Errors() - for _, e := range errs { - fmt.Println(e.Error()) - } - } -``` - -###### Custom error messages -Custom error messages are supported via annotations by adding the `~` separator - here's an example of how to use it: -```go -type Ticket struct { - Id int64 `json:"id"` - FirstName string `json:"firstname" valid:"required~First name is blank"` -} -``` - -#### Notes -Documentation is available here: [godoc.org](https://godoc.org/github.com/asaskevich/govalidator). -Full information about code coverage is also available here: [govalidator on gocover.io](http://gocover.io/github.com/asaskevich/govalidator). - -#### Support -If you do have a contribution to the package, feel free to create a Pull Request or an Issue. - -#### What to contribute -If you don't know what to do, there are some features and functions that need to be done - -- [ ] Refactor code -- [ ] Edit docs and [README](https://github.com/asaskevich/govalidator/README.md): spellcheck, grammar and typo check -- [ ] Create actual list of contributors and projects that currently using this package -- [ ] Resolve [issues and bugs](https://github.com/asaskevich/govalidator/issues) -- [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions) -- [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new -- [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc -- [x] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224) -- [ ] Implement fuzzing testing -- [ ] Implement some struct/map/array utilities -- [ ] Implement map/array validation -- [ ] Implement benchmarking -- [ ] Implement batch of examples -- [ ] Look at forks for new features and fixes - -#### Advice -Feel free to create what you want, but keep in mind when you implement new features: -- Code must be clear and readable, names of variables/constants clearly describes what they are doing -- Public functions must be documented and described in source file and added to README.md to the list of available functions -- There are must be unit-tests for any new functions and improvements - -## Credits -### Contributors - -This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. - -#### Special thanks to [contributors](https://github.com/asaskevich/govalidator/graphs/contributors) -* [Daniel Lohse](https://github.com/annismckenzie) -* [Attila Oláh](https://github.com/attilaolah) -* [Daniel Korner](https://github.com/Dadie) -* [Steven Wilkin](https://github.com/stevenwilkin) -* [Deiwin Sarjas](https://github.com/deiwin) -* [Noah Shibley](https://github.com/slugmobile) -* [Nathan Davies](https://github.com/nathj07) -* [Matt Sanford](https://github.com/mzsanford) -* [Simon ccl1115](https://github.com/ccl1115) - - - - -### Backers - -Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/govalidator#backer)] - - - - -### Sponsors - -Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/govalidator#sponsor)] - - - - - - - - - - - - - - - -## License -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_large) diff --git a/vendor/github.com/asaskevich/govalidator/arrays.go b/vendor/github.com/asaskevich/govalidator/arrays.go deleted file mode 100644 index 3e1da7cb4..000000000 --- a/vendor/github.com/asaskevich/govalidator/arrays.go +++ /dev/null @@ -1,87 +0,0 @@ -package govalidator - -// Iterator is the function that accepts element of slice/array and its index -type Iterator func(interface{}, int) - -// ResultIterator is the function that accepts element of slice/array and its index and returns any result -type ResultIterator func(interface{}, int) interface{} - -// ConditionIterator is the function that accepts element of slice/array and its index and returns boolean -type ConditionIterator func(interface{}, int) bool - -// ReduceIterator is the function that accepts two element of slice/array and returns result of merging those values -type ReduceIterator func(interface{}, interface{}) interface{} - -// Some validates that any item of array corresponds to ConditionIterator. Returns boolean. -func Some(array []interface{}, iterator ConditionIterator) bool { - res := false - for index, data := range array { - res = res || iterator(data, index) - } - return res -} - -// Every validates that every item of array corresponds to ConditionIterator. Returns boolean. -func Every(array []interface{}, iterator ConditionIterator) bool { - res := true - for index, data := range array { - res = res && iterator(data, index) - } - return res -} - -// Reduce boils down a list of values into a single value by ReduceIterator -func Reduce(array []interface{}, iterator ReduceIterator, initialValue interface{}) interface{} { - for _, data := range array { - initialValue = iterator(initialValue, data) - } - return initialValue -} - -// Each iterates over the slice and apply Iterator to every item -func Each(array []interface{}, iterator Iterator) { - for index, data := range array { - iterator(data, index) - } -} - -// Map iterates over the slice and apply ResultIterator to every item. Returns new slice as a result. -func Map(array []interface{}, iterator ResultIterator) []interface{} { - var result = make([]interface{}, len(array)) - for index, data := range array { - result[index] = iterator(data, index) - } - return result -} - -// Find iterates over the slice and apply ConditionIterator to every item. Returns first item that meet ConditionIterator or nil otherwise. -func Find(array []interface{}, iterator ConditionIterator) interface{} { - for index, data := range array { - if iterator(data, index) { - return data - } - } - return nil -} - -// Filter iterates over the slice and apply ConditionIterator to every item. Returns new slice. -func Filter(array []interface{}, iterator ConditionIterator) []interface{} { - var result = make([]interface{}, 0) - for index, data := range array { - if iterator(data, index) { - result = append(result, data) - } - } - return result -} - -// Count iterates over the slice and apply ConditionIterator to every item. Returns count of items that meets ConditionIterator. -func Count(array []interface{}, iterator ConditionIterator) int { - count := 0 - for index, data := range array { - if iterator(data, index) { - count = count + 1 - } - } - return count -} diff --git a/vendor/github.com/asaskevich/govalidator/converter.go b/vendor/github.com/asaskevich/govalidator/converter.go deleted file mode 100644 index d68e990fc..000000000 --- a/vendor/github.com/asaskevich/govalidator/converter.go +++ /dev/null @@ -1,81 +0,0 @@ -package govalidator - -import ( - "encoding/json" - "fmt" - "reflect" - "strconv" -) - -// ToString convert the input to a string. -func ToString(obj interface{}) string { - res := fmt.Sprintf("%v", obj) - return res -} - -// ToJSON convert the input to a valid JSON string -func ToJSON(obj interface{}) (string, error) { - res, err := json.Marshal(obj) - if err != nil { - res = []byte("") - } - return string(res), err -} - -// ToFloat convert the input string to a float, or 0.0 if the input is not a float. -func ToFloat(value interface{}) (res float64, err error) { - val := reflect.ValueOf(value) - - switch value.(type) { - case int, int8, int16, int32, int64: - res = float64(val.Int()) - case uint, uint8, uint16, uint32, uint64: - res = float64(val.Uint()) - case float32, float64: - res = val.Float() - case string: - res, err = strconv.ParseFloat(val.String(), 64) - if err != nil { - res = 0 - } - default: - err = fmt.Errorf("ToInt: unknown interface type %T", value) - res = 0 - } - - return -} - -// ToInt convert the input string or any int type to an integer type 64, or 0 if the input is not an integer. -func ToInt(value interface{}) (res int64, err error) { - val := reflect.ValueOf(value) - - switch value.(type) { - case int, int8, int16, int32, int64: - res = val.Int() - case uint, uint8, uint16, uint32, uint64: - res = int64(val.Uint()) - case float32, float64: - res = int64(val.Float()) - case string: - if IsInt(val.String()) { - res, err = strconv.ParseInt(val.String(), 0, 64) - if err != nil { - res = 0 - } - } else { - err = fmt.Errorf("ToInt: invalid numeric format %g", value) - res = 0 - } - default: - err = fmt.Errorf("ToInt: unknown interface type %T", value) - res = 0 - } - - return -} - -// ToBoolean convert the input string to a boolean. -func ToBoolean(str string) (bool, error) { - return strconv.ParseBool(str) -} diff --git a/vendor/github.com/asaskevich/govalidator/doc.go b/vendor/github.com/asaskevich/govalidator/doc.go deleted file mode 100644 index 55dce62dc..000000000 --- a/vendor/github.com/asaskevich/govalidator/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -package govalidator - -// A package of validators and sanitizers for strings, structures and collections. diff --git a/vendor/github.com/asaskevich/govalidator/error.go b/vendor/github.com/asaskevich/govalidator/error.go deleted file mode 100644 index 1da2336f4..000000000 --- a/vendor/github.com/asaskevich/govalidator/error.go +++ /dev/null @@ -1,47 +0,0 @@ -package govalidator - -import ( - "sort" - "strings" -) - -// Errors is an array of multiple errors and conforms to the error interface. -type Errors []error - -// Errors returns itself. -func (es Errors) Errors() []error { - return es -} - -func (es Errors) Error() string { - var errs []string - for _, e := range es { - errs = append(errs, e.Error()) - } - sort.Strings(errs) - return strings.Join(errs, ";") -} - -// Error encapsulates a name, an error and whether there's a custom error message or not. -type Error struct { - Name string - Err error - CustomErrorMessageExists bool - - // Validator indicates the name of the validator that failed - Validator string - Path []string -} - -func (e Error) Error() string { - if e.CustomErrorMessageExists { - return e.Err.Error() - } - - errName := e.Name - if len(e.Path) > 0 { - errName = strings.Join(append(e.Path, e.Name), ".") - } - - return errName + ": " + e.Err.Error() -} diff --git a/vendor/github.com/asaskevich/govalidator/numerics.go b/vendor/github.com/asaskevich/govalidator/numerics.go deleted file mode 100644 index 5041d9e86..000000000 --- a/vendor/github.com/asaskevich/govalidator/numerics.go +++ /dev/null @@ -1,100 +0,0 @@ -package govalidator - -import ( - "math" -) - -// Abs returns absolute value of number -func Abs(value float64) float64 { - return math.Abs(value) -} - -// Sign returns signum of number: 1 in case of value > 0, -1 in case of value < 0, 0 otherwise -func Sign(value float64) float64 { - if value > 0 { - return 1 - } else if value < 0 { - return -1 - } else { - return 0 - } -} - -// IsNegative returns true if value < 0 -func IsNegative(value float64) bool { - return value < 0 -} - -// IsPositive returns true if value > 0 -func IsPositive(value float64) bool { - return value > 0 -} - -// IsNonNegative returns true if value >= 0 -func IsNonNegative(value float64) bool { - return value >= 0 -} - -// IsNonPositive returns true if value <= 0 -func IsNonPositive(value float64) bool { - return value <= 0 -} - -// InRangeInt returns true if value lies between left and right border -func InRangeInt(value, left, right interface{}) bool { - value64, _ := ToInt(value) - left64, _ := ToInt(left) - right64, _ := ToInt(right) - if left64 > right64 { - left64, right64 = right64, left64 - } - return value64 >= left64 && value64 <= right64 -} - -// InRangeFloat32 returns true if value lies between left and right border -func InRangeFloat32(value, left, right float32) bool { - if left > right { - left, right = right, left - } - return value >= left && value <= right -} - -// InRangeFloat64 returns true if value lies between left and right border -func InRangeFloat64(value, left, right float64) bool { - if left > right { - left, right = right, left - } - return value >= left && value <= right -} - -// InRange returns true if value lies between left and right border, generic type to handle int, float32, float64 and string. -// All types must the same type. -// False if value doesn't lie in range or if it incompatible or not comparable -func InRange(value interface{}, left interface{}, right interface{}) bool { - switch value.(type) { - case int: - intValue, _ := ToInt(value) - intLeft, _ := ToInt(left) - intRight, _ := ToInt(right) - return InRangeInt(intValue, intLeft, intRight) - case float32, float64: - intValue, _ := ToFloat(value) - intLeft, _ := ToFloat(left) - intRight, _ := ToFloat(right) - return InRangeFloat64(intValue, intLeft, intRight) - case string: - return value.(string) >= left.(string) && value.(string) <= right.(string) - default: - return false - } -} - -// IsWhole returns true if value is whole number -func IsWhole(value float64) bool { - return math.Remainder(value, 1) == 0 -} - -// IsNatural returns true if value is natural number (positive and whole) -func IsNatural(value float64) bool { - return IsWhole(value) && IsPositive(value) -} diff --git a/vendor/github.com/asaskevich/govalidator/patterns.go b/vendor/github.com/asaskevich/govalidator/patterns.go deleted file mode 100644 index 916f50b89..000000000 --- a/vendor/github.com/asaskevich/govalidator/patterns.go +++ /dev/null @@ -1,113 +0,0 @@ -package govalidator - -import "regexp" - -// Basic regular expressions for validating strings -const ( - Email string = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$" - CreditCard string = "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$" - ISBN10 string = "^(?:[0-9]{9}X|[0-9]{10})$" - ISBN13 string = "^(?:[0-9]{13})$" - UUID3 string = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-3[0-9a-fA-F]{3}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" - UUID4 string = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" - UUID5 string = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" - UUID string = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" - Alpha string = "^[a-zA-Z]+$" - Alphanumeric string = "^[a-zA-Z0-9]+$" - Numeric string = "^[0-9]+$" - Int string = "^(?:[-+]?(?:0|[1-9][0-9]*))$" - Float string = "^(?:[-+]?(?:[0-9]+))?(?:\\.[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$" - Hexadecimal string = "^[0-9a-fA-F]+$" - Hexcolor string = "^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" - RGBcolor string = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*\\)$" - ASCII string = "^[\x00-\x7F]+$" - Multibyte string = "[^\x00-\x7F]" - FullWidth string = "[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]" - HalfWidth string = "[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]" - Base64 string = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$" - PrintableASCII string = "^[\x20-\x7E]+$" - DataURI string = "^data:.+\\/(.+);base64$" - MagnetURI string = "^magnet:\\?xt=urn:[a-zA-Z0-9]+:[a-zA-Z0-9]{32,40}&dn=.+&tr=.+$" - Latitude string = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$" - Longitude string = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$" - DNSName string = `^([a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*[\._]?$` - IP string = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))` - URLSchema string = `((ftp|tcp|udp|wss?|https?):\/\/)` - URLUsername string = `(\S+(:\S*)?@)` - URLPath string = `((\/|\?|#)[^\s]*)` - URLPort string = `(:(\d{1,5}))` - URLIP string = `([1-9]\d?|1\d\d|2[01]\d|22[0-3]|24\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-5]))` - URLSubdomain string = `((www\.)|([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[a-zA-Z0-9]\.[a-zA-Z0-9]+))` - URL = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$` - SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$` - WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$` - UnixPath string = `^(/[^/\x00]*)+/?$` - WinARPath string = `^(?:(?:[a-zA-Z]:|\\\\[a-z0-9_.$●-]+\\[a-z0-9_.$●-]+)\\|\\?[^\\/:*?"<>|\r\n]+\\?)(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$` - UnixARPath string = `^((\.{0,2}/)?([^/\x00]*))+/?$` - Semver 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-]+)*)?$" - tagName string = "valid" - hasLowerCase string = ".*[[:lower:]]" - hasUpperCase string = ".*[[:upper:]]" - hasWhitespace string = ".*[[:space:]]" - hasWhitespaceOnly string = "^[[:space:]]+$" - IMEI string = "^[0-9a-f]{14}$|^\\d{15}$|^\\d{18}$" - IMSI string = "^\\d{14,15}$" - E164 string = `^\+?[1-9]\d{1,14}$` -) - -// Used by IsFilePath func -const ( - // Unknown is unresolved OS type - Unknown = iota - // Win is Windows type - Win - // Unix is *nix OS types - Unix -) - -var ( - userRegexp = regexp.MustCompile("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+$") - hostRegexp = regexp.MustCompile("^[^\\s]+\\.[^\\s]+$") - userDotRegexp = regexp.MustCompile("(^[.]{1})|([.]{1}$)|([.]{2,})") - rxEmail = regexp.MustCompile(Email) - rxCreditCard = regexp.MustCompile(CreditCard) - rxISBN10 = regexp.MustCompile(ISBN10) - rxISBN13 = regexp.MustCompile(ISBN13) - rxUUID3 = regexp.MustCompile(UUID3) - rxUUID4 = regexp.MustCompile(UUID4) - rxUUID5 = regexp.MustCompile(UUID5) - rxUUID = regexp.MustCompile(UUID) - rxAlpha = regexp.MustCompile(Alpha) - rxAlphanumeric = regexp.MustCompile(Alphanumeric) - rxNumeric = regexp.MustCompile(Numeric) - rxInt = regexp.MustCompile(Int) - rxFloat = regexp.MustCompile(Float) - rxHexadecimal = regexp.MustCompile(Hexadecimal) - rxHexcolor = regexp.MustCompile(Hexcolor) - rxRGBcolor = regexp.MustCompile(RGBcolor) - rxASCII = regexp.MustCompile(ASCII) - rxPrintableASCII = regexp.MustCompile(PrintableASCII) - rxMultibyte = regexp.MustCompile(Multibyte) - rxFullWidth = regexp.MustCompile(FullWidth) - rxHalfWidth = regexp.MustCompile(HalfWidth) - rxBase64 = regexp.MustCompile(Base64) - rxDataURI = regexp.MustCompile(DataURI) - rxMagnetURI = regexp.MustCompile(MagnetURI) - rxLatitude = regexp.MustCompile(Latitude) - rxLongitude = regexp.MustCompile(Longitude) - rxDNSName = regexp.MustCompile(DNSName) - rxURL = regexp.MustCompile(URL) - rxSSN = regexp.MustCompile(SSN) - rxWinPath = regexp.MustCompile(WinPath) - rxUnixPath = regexp.MustCompile(UnixPath) - rxARWinPath = regexp.MustCompile(WinARPath) - rxARUnixPath = regexp.MustCompile(UnixARPath) - rxSemver = regexp.MustCompile(Semver) - rxHasLowerCase = regexp.MustCompile(hasLowerCase) - rxHasUpperCase = regexp.MustCompile(hasUpperCase) - rxHasWhitespace = regexp.MustCompile(hasWhitespace) - rxHasWhitespaceOnly = regexp.MustCompile(hasWhitespaceOnly) - rxIMEI = regexp.MustCompile(IMEI) - rxIMSI = regexp.MustCompile(IMSI) - rxE164 = regexp.MustCompile(E164) -) diff --git a/vendor/github.com/asaskevich/govalidator/types.go b/vendor/github.com/asaskevich/govalidator/types.go deleted file mode 100644 index c573abb51..000000000 --- a/vendor/github.com/asaskevich/govalidator/types.go +++ /dev/null @@ -1,656 +0,0 @@ -package govalidator - -import ( - "reflect" - "regexp" - "sort" - "sync" -) - -// Validator is a wrapper for a validator function that returns bool and accepts string. -type Validator func(str string) bool - -// CustomTypeValidator is a wrapper for validator functions that returns bool and accepts any type. -// The second parameter should be the context (in the case of validating a struct: the whole object being validated). -type CustomTypeValidator func(i interface{}, o interface{}) bool - -// ParamValidator is a wrapper for validator functions that accept additional parameters. -type ParamValidator func(str string, params ...string) bool - -// InterfaceParamValidator is a wrapper for functions that accept variants parameters for an interface value -type InterfaceParamValidator func(in interface{}, params ...string) bool -type tagOptionsMap map[string]tagOption - -func (t tagOptionsMap) orderedKeys() []string { - var keys []string - for k := range t { - keys = append(keys, k) - } - - sort.Slice(keys, func(a, b int) bool { - return t[keys[a]].order < t[keys[b]].order - }) - - return keys -} - -type tagOption struct { - name string - customErrorMessage string - order int -} - -// UnsupportedTypeError is a wrapper for reflect.Type -type UnsupportedTypeError struct { - Type reflect.Type -} - -// stringValues is a slice of reflect.Value holding *reflect.StringValue. -// It implements the methods to sort by string. -type stringValues []reflect.Value - -// InterfaceParamTagMap is a map of functions accept variants parameters for an interface value -var InterfaceParamTagMap = map[string]InterfaceParamValidator{ - "type": IsType, -} - -// InterfaceParamTagRegexMap maps interface param tags to their respective regexes. -var InterfaceParamTagRegexMap = map[string]*regexp.Regexp{ - "type": regexp.MustCompile(`^type\((.*)\)$`), -} - -// ParamTagMap is a map of functions accept variants parameters -var ParamTagMap = map[string]ParamValidator{ - "length": ByteLength, - "range": Range, - "runelength": RuneLength, - "stringlength": StringLength, - "matches": StringMatches, - "in": IsInRaw, - "rsapub": IsRsaPub, - "minstringlength": MinStringLength, - "maxstringlength": MaxStringLength, -} - -// ParamTagRegexMap maps param tags to their respective regexes. -var ParamTagRegexMap = map[string]*regexp.Regexp{ - "range": regexp.MustCompile("^range\\((\\d+)\\|(\\d+)\\)$"), - "length": regexp.MustCompile("^length\\((\\d+)\\|(\\d+)\\)$"), - "runelength": regexp.MustCompile("^runelength\\((\\d+)\\|(\\d+)\\)$"), - "stringlength": regexp.MustCompile("^stringlength\\((\\d+)\\|(\\d+)\\)$"), - "in": regexp.MustCompile(`^in\((.*)\)`), - "matches": regexp.MustCompile(`^matches\((.+)\)$`), - "rsapub": regexp.MustCompile("^rsapub\\((\\d+)\\)$"), - "minstringlength": regexp.MustCompile("^minstringlength\\((\\d+)\\)$"), - "maxstringlength": regexp.MustCompile("^maxstringlength\\((\\d+)\\)$"), -} - -type customTypeTagMap struct { - validators map[string]CustomTypeValidator - - sync.RWMutex -} - -func (tm *customTypeTagMap) Get(name string) (CustomTypeValidator, bool) { - tm.RLock() - defer tm.RUnlock() - v, ok := tm.validators[name] - return v, ok -} - -func (tm *customTypeTagMap) Set(name string, ctv CustomTypeValidator) { - tm.Lock() - defer tm.Unlock() - tm.validators[name] = ctv -} - -// CustomTypeTagMap is a map of functions that can be used as tags for ValidateStruct function. -// Use this to validate compound or custom types that need to be handled as a whole, e.g. -// `type UUID [16]byte` (this would be handled as an array of bytes). -var CustomTypeTagMap = &customTypeTagMap{validators: make(map[string]CustomTypeValidator)} - -// TagMap is a map of functions, that can be used as tags for ValidateStruct function. -var TagMap = map[string]Validator{ - "email": IsEmail, - "url": IsURL, - "dialstring": IsDialString, - "requrl": IsRequestURL, - "requri": IsRequestURI, - "alpha": IsAlpha, - "utfletter": IsUTFLetter, - "alphanum": IsAlphanumeric, - "utfletternum": IsUTFLetterNumeric, - "numeric": IsNumeric, - "utfnumeric": IsUTFNumeric, - "utfdigit": IsUTFDigit, - "hexadecimal": IsHexadecimal, - "hexcolor": IsHexcolor, - "rgbcolor": IsRGBcolor, - "lowercase": IsLowerCase, - "uppercase": IsUpperCase, - "int": IsInt, - "float": IsFloat, - "null": IsNull, - "notnull": IsNotNull, - "uuid": IsUUID, - "uuidv3": IsUUIDv3, - "uuidv4": IsUUIDv4, - "uuidv5": IsUUIDv5, - "creditcard": IsCreditCard, - "isbn10": IsISBN10, - "isbn13": IsISBN13, - "json": IsJSON, - "multibyte": IsMultibyte, - "ascii": IsASCII, - "printableascii": IsPrintableASCII, - "fullwidth": IsFullWidth, - "halfwidth": IsHalfWidth, - "variablewidth": IsVariableWidth, - "base64": IsBase64, - "datauri": IsDataURI, - "ip": IsIP, - "port": IsPort, - "ipv4": IsIPv4, - "ipv6": IsIPv6, - "dns": IsDNSName, - "host": IsHost, - "mac": IsMAC, - "latitude": IsLatitude, - "longitude": IsLongitude, - "ssn": IsSSN, - "semver": IsSemver, - "rfc3339": IsRFC3339, - "rfc3339WithoutZone": IsRFC3339WithoutZone, - "ISO3166Alpha2": IsISO3166Alpha2, - "ISO3166Alpha3": IsISO3166Alpha3, - "ISO4217": IsISO4217, - "IMEI": IsIMEI, - "ulid": IsULID, -} - -// ISO3166Entry stores country codes -type ISO3166Entry struct { - EnglishShortName string - FrenchShortName string - Alpha2Code string - Alpha3Code string - Numeric string -} - -//ISO3166List based on https://www.iso.org/obp/ui/#search/code/ Code Type "Officially Assigned Codes" -var ISO3166List = []ISO3166Entry{ - {"Afghanistan", "Afghanistan (l')", "AF", "AFG", "004"}, - {"Albania", "Albanie (l')", "AL", "ALB", "008"}, - {"Antarctica", "Antarctique (l')", "AQ", "ATA", "010"}, - {"Algeria", "Algérie (l')", "DZ", "DZA", "012"}, - {"American Samoa", "Samoa américaines (les)", "AS", "ASM", "016"}, - {"Andorra", "Andorre (l')", "AD", "AND", "020"}, - {"Angola", "Angola (l')", "AO", "AGO", "024"}, - {"Antigua and Barbuda", "Antigua-et-Barbuda", "AG", "ATG", "028"}, - {"Azerbaijan", "Azerbaïdjan (l')", "AZ", "AZE", "031"}, - {"Argentina", "Argentine (l')", "AR", "ARG", "032"}, - {"Australia", "Australie (l')", "AU", "AUS", "036"}, - {"Austria", "Autriche (l')", "AT", "AUT", "040"}, - {"Bahamas (the)", "Bahamas (les)", "BS", "BHS", "044"}, - {"Bahrain", "Bahreïn", "BH", "BHR", "048"}, - {"Bangladesh", "Bangladesh (le)", "BD", "BGD", "050"}, - {"Armenia", "Arménie (l')", "AM", "ARM", "051"}, - {"Barbados", "Barbade (la)", "BB", "BRB", "052"}, - {"Belgium", "Belgique (la)", "BE", "BEL", "056"}, - {"Bermuda", "Bermudes (les)", "BM", "BMU", "060"}, - {"Bhutan", "Bhoutan (le)", "BT", "BTN", "064"}, - {"Bolivia (Plurinational State of)", "Bolivie (État plurinational de)", "BO", "BOL", "068"}, - {"Bosnia and Herzegovina", "Bosnie-Herzégovine (la)", "BA", "BIH", "070"}, - {"Botswana", "Botswana (le)", "BW", "BWA", "072"}, - {"Bouvet Island", "Bouvet (l'Île)", "BV", "BVT", "074"}, - {"Brazil", "Brésil (le)", "BR", "BRA", "076"}, - {"Belize", "Belize (le)", "BZ", "BLZ", "084"}, - {"British Indian Ocean Territory (the)", "Indien (le Territoire britannique de l'océan)", "IO", "IOT", "086"}, - {"Solomon Islands", "Salomon (Îles)", "SB", "SLB", "090"}, - {"Virgin Islands (British)", "Vierges britanniques (les Îles)", "VG", "VGB", "092"}, - {"Brunei Darussalam", "Brunéi Darussalam (le)", "BN", "BRN", "096"}, - {"Bulgaria", "Bulgarie (la)", "BG", "BGR", "100"}, - {"Myanmar", "Myanmar (le)", "MM", "MMR", "104"}, - {"Burundi", "Burundi (le)", "BI", "BDI", "108"}, - {"Belarus", "Bélarus (le)", "BY", "BLR", "112"}, - {"Cambodia", "Cambodge (le)", "KH", "KHM", "116"}, - {"Cameroon", "Cameroun (le)", "CM", "CMR", "120"}, - {"Canada", "Canada (le)", "CA", "CAN", "124"}, - {"Cabo Verde", "Cabo Verde", "CV", "CPV", "132"}, - {"Cayman Islands (the)", "Caïmans (les Îles)", "KY", "CYM", "136"}, - {"Central African Republic (the)", "République centrafricaine (la)", "CF", "CAF", "140"}, - {"Sri Lanka", "Sri Lanka", "LK", "LKA", "144"}, - {"Chad", "Tchad (le)", "TD", "TCD", "148"}, - {"Chile", "Chili (le)", "CL", "CHL", "152"}, - {"China", "Chine (la)", "CN", "CHN", "156"}, - {"Taiwan (Province of China)", "Taïwan (Province de Chine)", "TW", "TWN", "158"}, - {"Christmas Island", "Christmas (l'Île)", "CX", "CXR", "162"}, - {"Cocos (Keeling) Islands (the)", "Cocos (les Îles)/ Keeling (les Îles)", "CC", "CCK", "166"}, - {"Colombia", "Colombie (la)", "CO", "COL", "170"}, - {"Comoros (the)", "Comores (les)", "KM", "COM", "174"}, - {"Mayotte", "Mayotte", "YT", "MYT", "175"}, - {"Congo (the)", "Congo (le)", "CG", "COG", "178"}, - {"Congo (the Democratic Republic of the)", "Congo (la République démocratique du)", "CD", "COD", "180"}, - {"Cook Islands (the)", "Cook (les Îles)", "CK", "COK", "184"}, - {"Costa Rica", "Costa Rica (le)", "CR", "CRI", "188"}, - {"Croatia", "Croatie (la)", "HR", "HRV", "191"}, - {"Cuba", "Cuba", "CU", "CUB", "192"}, - {"Cyprus", "Chypre", "CY", "CYP", "196"}, - {"Czech Republic (the)", "tchèque (la République)", "CZ", "CZE", "203"}, - {"Benin", "Bénin (le)", "BJ", "BEN", "204"}, - {"Denmark", "Danemark (le)", "DK", "DNK", "208"}, - {"Dominica", "Dominique (la)", "DM", "DMA", "212"}, - {"Dominican Republic (the)", "dominicaine (la République)", "DO", "DOM", "214"}, - {"Ecuador", "Équateur (l')", "EC", "ECU", "218"}, - {"El Salvador", "El Salvador", "SV", "SLV", "222"}, - {"Equatorial Guinea", "Guinée équatoriale (la)", "GQ", "GNQ", "226"}, - {"Ethiopia", "Éthiopie (l')", "ET", "ETH", "231"}, - {"Eritrea", "Érythrée (l')", "ER", "ERI", "232"}, - {"Estonia", "Estonie (l')", "EE", "EST", "233"}, - {"Faroe Islands (the)", "Féroé (les Îles)", "FO", "FRO", "234"}, - {"Falkland Islands (the) [Malvinas]", "Falkland (les Îles)/Malouines (les Îles)", "FK", "FLK", "238"}, - {"South Georgia and the South Sandwich Islands", "Géorgie du Sud-et-les Îles Sandwich du Sud (la)", "GS", "SGS", "239"}, - {"Fiji", "Fidji (les)", "FJ", "FJI", "242"}, - {"Finland", "Finlande (la)", "FI", "FIN", "246"}, - {"Åland Islands", "Åland(les Îles)", "AX", "ALA", "248"}, - {"France", "France (la)", "FR", "FRA", "250"}, - {"French Guiana", "Guyane française (la )", "GF", "GUF", "254"}, - {"French Polynesia", "Polynésie française (la)", "PF", "PYF", "258"}, - {"French Southern Territories (the)", "Terres australes françaises (les)", "TF", "ATF", "260"}, - {"Djibouti", "Djibouti", "DJ", "DJI", "262"}, - {"Gabon", "Gabon (le)", "GA", "GAB", "266"}, - {"Georgia", "Géorgie (la)", "GE", "GEO", "268"}, - {"Gambia (the)", "Gambie (la)", "GM", "GMB", "270"}, - {"Palestine, State of", "Palestine, État de", "PS", "PSE", "275"}, - {"Germany", "Allemagne (l')", "DE", "DEU", "276"}, - {"Ghana", "Ghana (le)", "GH", "GHA", "288"}, - {"Gibraltar", "Gibraltar", "GI", "GIB", "292"}, - {"Kiribati", "Kiribati", "KI", "KIR", "296"}, - {"Greece", "Grèce (la)", "GR", "GRC", "300"}, - {"Greenland", "Groenland (le)", "GL", "GRL", "304"}, - {"Grenada", "Grenade (la)", "GD", "GRD", "308"}, - {"Guadeloupe", "Guadeloupe (la)", "GP", "GLP", "312"}, - {"Guam", "Guam", "GU", "GUM", "316"}, - {"Guatemala", "Guatemala (le)", "GT", "GTM", "320"}, - {"Guinea", "Guinée (la)", "GN", "GIN", "324"}, - {"Guyana", "Guyana (le)", "GY", "GUY", "328"}, - {"Haiti", "Haïti", "HT", "HTI", "332"}, - {"Heard Island and McDonald Islands", "Heard-et-Îles MacDonald (l'Île)", "HM", "HMD", "334"}, - {"Holy See (the)", "Saint-Siège (le)", "VA", "VAT", "336"}, - {"Honduras", "Honduras (le)", "HN", "HND", "340"}, - {"Hong Kong", "Hong Kong", "HK", "HKG", "344"}, - {"Hungary", "Hongrie (la)", "HU", "HUN", "348"}, - {"Iceland", "Islande (l')", "IS", "ISL", "352"}, - {"India", "Inde (l')", "IN", "IND", "356"}, - {"Indonesia", "Indonésie (l')", "ID", "IDN", "360"}, - {"Iran (Islamic Republic of)", "Iran (République Islamique d')", "IR", "IRN", "364"}, - {"Iraq", "Iraq (l')", "IQ", "IRQ", "368"}, - {"Ireland", "Irlande (l')", "IE", "IRL", "372"}, - {"Israel", "Israël", "IL", "ISR", "376"}, - {"Italy", "Italie (l')", "IT", "ITA", "380"}, - {"Côte d'Ivoire", "Côte d'Ivoire (la)", "CI", "CIV", "384"}, - {"Jamaica", "Jamaïque (la)", "JM", "JAM", "388"}, - {"Japan", "Japon (le)", "JP", "JPN", "392"}, - {"Kazakhstan", "Kazakhstan (le)", "KZ", "KAZ", "398"}, - {"Jordan", "Jordanie (la)", "JO", "JOR", "400"}, - {"Kenya", "Kenya (le)", "KE", "KEN", "404"}, - {"Korea (the Democratic People's Republic of)", "Corée (la République populaire démocratique de)", "KP", "PRK", "408"}, - {"Korea (the Republic of)", "Corée (la République de)", "KR", "KOR", "410"}, - {"Kuwait", "Koweït (le)", "KW", "KWT", "414"}, - {"Kyrgyzstan", "Kirghizistan (le)", "KG", "KGZ", "417"}, - {"Lao People's Democratic Republic (the)", "Lao, République démocratique populaire", "LA", "LAO", "418"}, - {"Lebanon", "Liban (le)", "LB", "LBN", "422"}, - {"Lesotho", "Lesotho (le)", "LS", "LSO", "426"}, - {"Latvia", "Lettonie (la)", "LV", "LVA", "428"}, - {"Liberia", "Libéria (le)", "LR", "LBR", "430"}, - {"Libya", "Libye (la)", "LY", "LBY", "434"}, - {"Liechtenstein", "Liechtenstein (le)", "LI", "LIE", "438"}, - {"Lithuania", "Lituanie (la)", "LT", "LTU", "440"}, - {"Luxembourg", "Luxembourg (le)", "LU", "LUX", "442"}, - {"Macao", "Macao", "MO", "MAC", "446"}, - {"Madagascar", "Madagascar", "MG", "MDG", "450"}, - {"Malawi", "Malawi (le)", "MW", "MWI", "454"}, - {"Malaysia", "Malaisie (la)", "MY", "MYS", "458"}, - {"Maldives", "Maldives (les)", "MV", "MDV", "462"}, - {"Mali", "Mali (le)", "ML", "MLI", "466"}, - {"Malta", "Malte", "MT", "MLT", "470"}, - {"Martinique", "Martinique (la)", "MQ", "MTQ", "474"}, - {"Mauritania", "Mauritanie (la)", "MR", "MRT", "478"}, - {"Mauritius", "Maurice", "MU", "MUS", "480"}, - {"Mexico", "Mexique (le)", "MX", "MEX", "484"}, - {"Monaco", "Monaco", "MC", "MCO", "492"}, - {"Mongolia", "Mongolie (la)", "MN", "MNG", "496"}, - {"Moldova (the Republic of)", "Moldova , République de", "MD", "MDA", "498"}, - {"Montenegro", "Monténégro (le)", "ME", "MNE", "499"}, - {"Montserrat", "Montserrat", "MS", "MSR", "500"}, - {"Morocco", "Maroc (le)", "MA", "MAR", "504"}, - {"Mozambique", "Mozambique (le)", "MZ", "MOZ", "508"}, - {"Oman", "Oman", "OM", "OMN", "512"}, - {"Namibia", "Namibie (la)", "NA", "NAM", "516"}, - {"Nauru", "Nauru", "NR", "NRU", "520"}, - {"Nepal", "Népal (le)", "NP", "NPL", "524"}, - {"Netherlands (the)", "Pays-Bas (les)", "NL", "NLD", "528"}, - {"Curaçao", "Curaçao", "CW", "CUW", "531"}, - {"Aruba", "Aruba", "AW", "ABW", "533"}, - {"Sint Maarten (Dutch part)", "Saint-Martin (partie néerlandaise)", "SX", "SXM", "534"}, - {"Bonaire, Sint Eustatius and Saba", "Bonaire, Saint-Eustache et Saba", "BQ", "BES", "535"}, - {"New Caledonia", "Nouvelle-Calédonie (la)", "NC", "NCL", "540"}, - {"Vanuatu", "Vanuatu (le)", "VU", "VUT", "548"}, - {"New Zealand", "Nouvelle-Zélande (la)", "NZ", "NZL", "554"}, - {"Nicaragua", "Nicaragua (le)", "NI", "NIC", "558"}, - {"Niger (the)", "Niger (le)", "NE", "NER", "562"}, - {"Nigeria", "Nigéria (le)", "NG", "NGA", "566"}, - {"Niue", "Niue", "NU", "NIU", "570"}, - {"Norfolk Island", "Norfolk (l'Île)", "NF", "NFK", "574"}, - {"Norway", "Norvège (la)", "NO", "NOR", "578"}, - {"Northern Mariana Islands (the)", "Mariannes du Nord (les Îles)", "MP", "MNP", "580"}, - {"United States Minor Outlying Islands (the)", "Îles mineures éloignées des États-Unis (les)", "UM", "UMI", "581"}, - {"Micronesia (Federated States of)", "Micronésie (États fédérés de)", "FM", "FSM", "583"}, - {"Marshall Islands (the)", "Marshall (Îles)", "MH", "MHL", "584"}, - {"Palau", "Palaos (les)", "PW", "PLW", "585"}, - {"Pakistan", "Pakistan (le)", "PK", "PAK", "586"}, - {"Panama", "Panama (le)", "PA", "PAN", "591"}, - {"Papua New Guinea", "Papouasie-Nouvelle-Guinée (la)", "PG", "PNG", "598"}, - {"Paraguay", "Paraguay (le)", "PY", "PRY", "600"}, - {"Peru", "Pérou (le)", "PE", "PER", "604"}, - {"Philippines (the)", "Philippines (les)", "PH", "PHL", "608"}, - {"Pitcairn", "Pitcairn", "PN", "PCN", "612"}, - {"Poland", "Pologne (la)", "PL", "POL", "616"}, - {"Portugal", "Portugal (le)", "PT", "PRT", "620"}, - {"Guinea-Bissau", "Guinée-Bissau (la)", "GW", "GNB", "624"}, - {"Timor-Leste", "Timor-Leste (le)", "TL", "TLS", "626"}, - {"Puerto Rico", "Porto Rico", "PR", "PRI", "630"}, - {"Qatar", "Qatar (le)", "QA", "QAT", "634"}, - {"Réunion", "Réunion (La)", "RE", "REU", "638"}, - {"Romania", "Roumanie (la)", "RO", "ROU", "642"}, - {"Russian Federation (the)", "Russie (la Fédération de)", "RU", "RUS", "643"}, - {"Rwanda", "Rwanda (le)", "RW", "RWA", "646"}, - {"Saint Barthélemy", "Saint-Barthélemy", "BL", "BLM", "652"}, - {"Saint Helena, Ascension and Tristan da Cunha", "Sainte-Hélène, Ascension et Tristan da Cunha", "SH", "SHN", "654"}, - {"Saint Kitts and Nevis", "Saint-Kitts-et-Nevis", "KN", "KNA", "659"}, - {"Anguilla", "Anguilla", "AI", "AIA", "660"}, - {"Saint Lucia", "Sainte-Lucie", "LC", "LCA", "662"}, - {"Saint Martin (French part)", "Saint-Martin (partie française)", "MF", "MAF", "663"}, - {"Saint Pierre and Miquelon", "Saint-Pierre-et-Miquelon", "PM", "SPM", "666"}, - {"Saint Vincent and the Grenadines", "Saint-Vincent-et-les Grenadines", "VC", "VCT", "670"}, - {"San Marino", "Saint-Marin", "SM", "SMR", "674"}, - {"Sao Tome and Principe", "Sao Tomé-et-Principe", "ST", "STP", "678"}, - {"Saudi Arabia", "Arabie saoudite (l')", "SA", "SAU", "682"}, - {"Senegal", "Sénégal (le)", "SN", "SEN", "686"}, - {"Serbia", "Serbie (la)", "RS", "SRB", "688"}, - {"Seychelles", "Seychelles (les)", "SC", "SYC", "690"}, - {"Sierra Leone", "Sierra Leone (la)", "SL", "SLE", "694"}, - {"Singapore", "Singapour", "SG", "SGP", "702"}, - {"Slovakia", "Slovaquie (la)", "SK", "SVK", "703"}, - {"Viet Nam", "Viet Nam (le)", "VN", "VNM", "704"}, - {"Slovenia", "Slovénie (la)", "SI", "SVN", "705"}, - {"Somalia", "Somalie (la)", "SO", "SOM", "706"}, - {"South Africa", "Afrique du Sud (l')", "ZA", "ZAF", "710"}, - {"Zimbabwe", "Zimbabwe (le)", "ZW", "ZWE", "716"}, - {"Spain", "Espagne (l')", "ES", "ESP", "724"}, - {"South Sudan", "Soudan du Sud (le)", "SS", "SSD", "728"}, - {"Sudan (the)", "Soudan (le)", "SD", "SDN", "729"}, - {"Western Sahara*", "Sahara occidental (le)*", "EH", "ESH", "732"}, - {"Suriname", "Suriname (le)", "SR", "SUR", "740"}, - {"Svalbard and Jan Mayen", "Svalbard et l'Île Jan Mayen (le)", "SJ", "SJM", "744"}, - {"Swaziland", "Swaziland (le)", "SZ", "SWZ", "748"}, - {"Sweden", "Suède (la)", "SE", "SWE", "752"}, - {"Switzerland", "Suisse (la)", "CH", "CHE", "756"}, - {"Syrian Arab Republic", "République arabe syrienne (la)", "SY", "SYR", "760"}, - {"Tajikistan", "Tadjikistan (le)", "TJ", "TJK", "762"}, - {"Thailand", "Thaïlande (la)", "TH", "THA", "764"}, - {"Togo", "Togo (le)", "TG", "TGO", "768"}, - {"Tokelau", "Tokelau (les)", "TK", "TKL", "772"}, - {"Tonga", "Tonga (les)", "TO", "TON", "776"}, - {"Trinidad and Tobago", "Trinité-et-Tobago (la)", "TT", "TTO", "780"}, - {"United Arab Emirates (the)", "Émirats arabes unis (les)", "AE", "ARE", "784"}, - {"Tunisia", "Tunisie (la)", "TN", "TUN", "788"}, - {"Turkey", "Turquie (la)", "TR", "TUR", "792"}, - {"Turkmenistan", "Turkménistan (le)", "TM", "TKM", "795"}, - {"Turks and Caicos Islands (the)", "Turks-et-Caïcos (les Îles)", "TC", "TCA", "796"}, - {"Tuvalu", "Tuvalu (les)", "TV", "TUV", "798"}, - {"Uganda", "Ouganda (l')", "UG", "UGA", "800"}, - {"Ukraine", "Ukraine (l')", "UA", "UKR", "804"}, - {"Macedonia (the former Yugoslav Republic of)", "Macédoine (l'ex‑République yougoslave de)", "MK", "MKD", "807"}, - {"Egypt", "Égypte (l')", "EG", "EGY", "818"}, - {"United Kingdom of Great Britain and Northern Ireland (the)", "Royaume-Uni de Grande-Bretagne et d'Irlande du Nord (le)", "GB", "GBR", "826"}, - {"Guernsey", "Guernesey", "GG", "GGY", "831"}, - {"Jersey", "Jersey", "JE", "JEY", "832"}, - {"Isle of Man", "Île de Man", "IM", "IMN", "833"}, - {"Tanzania, United Republic of", "Tanzanie, République-Unie de", "TZ", "TZA", "834"}, - {"United States of America (the)", "États-Unis d'Amérique (les)", "US", "USA", "840"}, - {"Virgin Islands (U.S.)", "Vierges des États-Unis (les Îles)", "VI", "VIR", "850"}, - {"Burkina Faso", "Burkina Faso (le)", "BF", "BFA", "854"}, - {"Uruguay", "Uruguay (l')", "UY", "URY", "858"}, - {"Uzbekistan", "Ouzbékistan (l')", "UZ", "UZB", "860"}, - {"Venezuela (Bolivarian Republic of)", "Venezuela (République bolivarienne du)", "VE", "VEN", "862"}, - {"Wallis and Futuna", "Wallis-et-Futuna", "WF", "WLF", "876"}, - {"Samoa", "Samoa (le)", "WS", "WSM", "882"}, - {"Yemen", "Yémen (le)", "YE", "YEM", "887"}, - {"Zambia", "Zambie (la)", "ZM", "ZMB", "894"}, -} - -// ISO4217List is the list of ISO currency codes -var ISO4217List = []string{ - "AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN", - "BAM", "BBD", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYN", "BZD", - "CAD", "CDF", "CHE", "CHF", "CHW", "CLF", "CLP", "CNY", "COP", "COU", "CRC", "CUC", "CUP", "CVE", "CZK", - "DJF", "DKK", "DOP", "DZD", - "EGP", "ERN", "ETB", "EUR", - "FJD", "FKP", - "GBP", "GEL", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD", - "HKD", "HNL", "HRK", "HTG", "HUF", - "IDR", "ILS", "INR", "IQD", "IRR", "ISK", - "JMD", "JOD", "JPY", - "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", - "LAK", "LBP", "LKR", "LRD", "LSL", "LYD", - "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP", "MRO", "MUR", "MVR", "MWK", "MXN", "MXV", "MYR", "MZN", - "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", - "OMR", - "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", - "QAR", - "RON", "RSD", "RUB", "RWF", - "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STD", "STN", "SVC", "SYP", "SZL", - "THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS", - "UAH", "UGX", "USD", "USN", "UYI", "UYU", "UYW", "UZS", - "VEF", "VES", "VND", "VUV", - "WST", - "XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "XSU", "XTS", "XUA", "XXX", - "YER", - "ZAR", "ZMW", "ZWL", -} - -// ISO693Entry stores ISO language codes -type ISO693Entry struct { - Alpha3bCode string - Alpha2Code string - English string -} - -//ISO693List based on http://data.okfn.org/data/core/language-codes/r/language-codes-3b2.json -var ISO693List = []ISO693Entry{ - {Alpha3bCode: "aar", Alpha2Code: "aa", English: "Afar"}, - {Alpha3bCode: "abk", Alpha2Code: "ab", English: "Abkhazian"}, - {Alpha3bCode: "afr", Alpha2Code: "af", English: "Afrikaans"}, - {Alpha3bCode: "aka", Alpha2Code: "ak", English: "Akan"}, - {Alpha3bCode: "alb", Alpha2Code: "sq", English: "Albanian"}, - {Alpha3bCode: "amh", Alpha2Code: "am", English: "Amharic"}, - {Alpha3bCode: "ara", Alpha2Code: "ar", English: "Arabic"}, - {Alpha3bCode: "arg", Alpha2Code: "an", English: "Aragonese"}, - {Alpha3bCode: "arm", Alpha2Code: "hy", English: "Armenian"}, - {Alpha3bCode: "asm", Alpha2Code: "as", English: "Assamese"}, - {Alpha3bCode: "ava", Alpha2Code: "av", English: "Avaric"}, - {Alpha3bCode: "ave", Alpha2Code: "ae", English: "Avestan"}, - {Alpha3bCode: "aym", Alpha2Code: "ay", English: "Aymara"}, - {Alpha3bCode: "aze", Alpha2Code: "az", English: "Azerbaijani"}, - {Alpha3bCode: "bak", Alpha2Code: "ba", English: "Bashkir"}, - {Alpha3bCode: "bam", Alpha2Code: "bm", English: "Bambara"}, - {Alpha3bCode: "baq", Alpha2Code: "eu", English: "Basque"}, - {Alpha3bCode: "bel", Alpha2Code: "be", English: "Belarusian"}, - {Alpha3bCode: "ben", Alpha2Code: "bn", English: "Bengali"}, - {Alpha3bCode: "bih", Alpha2Code: "bh", English: "Bihari languages"}, - {Alpha3bCode: "bis", Alpha2Code: "bi", English: "Bislama"}, - {Alpha3bCode: "bos", Alpha2Code: "bs", English: "Bosnian"}, - {Alpha3bCode: "bre", Alpha2Code: "br", English: "Breton"}, - {Alpha3bCode: "bul", Alpha2Code: "bg", English: "Bulgarian"}, - {Alpha3bCode: "bur", Alpha2Code: "my", English: "Burmese"}, - {Alpha3bCode: "cat", Alpha2Code: "ca", English: "Catalan; Valencian"}, - {Alpha3bCode: "cha", Alpha2Code: "ch", English: "Chamorro"}, - {Alpha3bCode: "che", Alpha2Code: "ce", English: "Chechen"}, - {Alpha3bCode: "chi", Alpha2Code: "zh", English: "Chinese"}, - {Alpha3bCode: "chu", Alpha2Code: "cu", English: "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic"}, - {Alpha3bCode: "chv", Alpha2Code: "cv", English: "Chuvash"}, - {Alpha3bCode: "cor", Alpha2Code: "kw", English: "Cornish"}, - {Alpha3bCode: "cos", Alpha2Code: "co", English: "Corsican"}, - {Alpha3bCode: "cre", Alpha2Code: "cr", English: "Cree"}, - {Alpha3bCode: "cze", Alpha2Code: "cs", English: "Czech"}, - {Alpha3bCode: "dan", Alpha2Code: "da", English: "Danish"}, - {Alpha3bCode: "div", Alpha2Code: "dv", English: "Divehi; Dhivehi; Maldivian"}, - {Alpha3bCode: "dut", Alpha2Code: "nl", English: "Dutch; Flemish"}, - {Alpha3bCode: "dzo", Alpha2Code: "dz", English: "Dzongkha"}, - {Alpha3bCode: "eng", Alpha2Code: "en", English: "English"}, - {Alpha3bCode: "epo", Alpha2Code: "eo", English: "Esperanto"}, - {Alpha3bCode: "est", Alpha2Code: "et", English: "Estonian"}, - {Alpha3bCode: "ewe", Alpha2Code: "ee", English: "Ewe"}, - {Alpha3bCode: "fao", Alpha2Code: "fo", English: "Faroese"}, - {Alpha3bCode: "fij", Alpha2Code: "fj", English: "Fijian"}, - {Alpha3bCode: "fin", Alpha2Code: "fi", English: "Finnish"}, - {Alpha3bCode: "fre", Alpha2Code: "fr", English: "French"}, - {Alpha3bCode: "fry", Alpha2Code: "fy", English: "Western Frisian"}, - {Alpha3bCode: "ful", Alpha2Code: "ff", English: "Fulah"}, - {Alpha3bCode: "geo", Alpha2Code: "ka", English: "Georgian"}, - {Alpha3bCode: "ger", Alpha2Code: "de", English: "German"}, - {Alpha3bCode: "gla", Alpha2Code: "gd", English: "Gaelic; Scottish Gaelic"}, - {Alpha3bCode: "gle", Alpha2Code: "ga", English: "Irish"}, - {Alpha3bCode: "glg", Alpha2Code: "gl", English: "Galician"}, - {Alpha3bCode: "glv", Alpha2Code: "gv", English: "Manx"}, - {Alpha3bCode: "gre", Alpha2Code: "el", English: "Greek, Modern (1453-)"}, - {Alpha3bCode: "grn", Alpha2Code: "gn", English: "Guarani"}, - {Alpha3bCode: "guj", Alpha2Code: "gu", English: "Gujarati"}, - {Alpha3bCode: "hat", Alpha2Code: "ht", English: "Haitian; Haitian Creole"}, - {Alpha3bCode: "hau", Alpha2Code: "ha", English: "Hausa"}, - {Alpha3bCode: "heb", Alpha2Code: "he", English: "Hebrew"}, - {Alpha3bCode: "her", Alpha2Code: "hz", English: "Herero"}, - {Alpha3bCode: "hin", Alpha2Code: "hi", English: "Hindi"}, - {Alpha3bCode: "hmo", Alpha2Code: "ho", English: "Hiri Motu"}, - {Alpha3bCode: "hrv", Alpha2Code: "hr", English: "Croatian"}, - {Alpha3bCode: "hun", Alpha2Code: "hu", English: "Hungarian"}, - {Alpha3bCode: "ibo", Alpha2Code: "ig", English: "Igbo"}, - {Alpha3bCode: "ice", Alpha2Code: "is", English: "Icelandic"}, - {Alpha3bCode: "ido", Alpha2Code: "io", English: "Ido"}, - {Alpha3bCode: "iii", Alpha2Code: "ii", English: "Sichuan Yi; Nuosu"}, - {Alpha3bCode: "iku", Alpha2Code: "iu", English: "Inuktitut"}, - {Alpha3bCode: "ile", Alpha2Code: "ie", English: "Interlingue; Occidental"}, - {Alpha3bCode: "ina", Alpha2Code: "ia", English: "Interlingua (International Auxiliary Language Association)"}, - {Alpha3bCode: "ind", Alpha2Code: "id", English: "Indonesian"}, - {Alpha3bCode: "ipk", Alpha2Code: "ik", English: "Inupiaq"}, - {Alpha3bCode: "ita", Alpha2Code: "it", English: "Italian"}, - {Alpha3bCode: "jav", Alpha2Code: "jv", English: "Javanese"}, - {Alpha3bCode: "jpn", Alpha2Code: "ja", English: "Japanese"}, - {Alpha3bCode: "kal", Alpha2Code: "kl", English: "Kalaallisut; Greenlandic"}, - {Alpha3bCode: "kan", Alpha2Code: "kn", English: "Kannada"}, - {Alpha3bCode: "kas", Alpha2Code: "ks", English: "Kashmiri"}, - {Alpha3bCode: "kau", Alpha2Code: "kr", English: "Kanuri"}, - {Alpha3bCode: "kaz", Alpha2Code: "kk", English: "Kazakh"}, - {Alpha3bCode: "khm", Alpha2Code: "km", English: "Central Khmer"}, - {Alpha3bCode: "kik", Alpha2Code: "ki", English: "Kikuyu; Gikuyu"}, - {Alpha3bCode: "kin", Alpha2Code: "rw", English: "Kinyarwanda"}, - {Alpha3bCode: "kir", Alpha2Code: "ky", English: "Kirghiz; Kyrgyz"}, - {Alpha3bCode: "kom", Alpha2Code: "kv", English: "Komi"}, - {Alpha3bCode: "kon", Alpha2Code: "kg", English: "Kongo"}, - {Alpha3bCode: "kor", Alpha2Code: "ko", English: "Korean"}, - {Alpha3bCode: "kua", Alpha2Code: "kj", English: "Kuanyama; Kwanyama"}, - {Alpha3bCode: "kur", Alpha2Code: "ku", English: "Kurdish"}, - {Alpha3bCode: "lao", Alpha2Code: "lo", English: "Lao"}, - {Alpha3bCode: "lat", Alpha2Code: "la", English: "Latin"}, - {Alpha3bCode: "lav", Alpha2Code: "lv", English: "Latvian"}, - {Alpha3bCode: "lim", Alpha2Code: "li", English: "Limburgan; Limburger; Limburgish"}, - {Alpha3bCode: "lin", Alpha2Code: "ln", English: "Lingala"}, - {Alpha3bCode: "lit", Alpha2Code: "lt", English: "Lithuanian"}, - {Alpha3bCode: "ltz", Alpha2Code: "lb", English: "Luxembourgish; Letzeburgesch"}, - {Alpha3bCode: "lub", Alpha2Code: "lu", English: "Luba-Katanga"}, - {Alpha3bCode: "lug", Alpha2Code: "lg", English: "Ganda"}, - {Alpha3bCode: "mac", Alpha2Code: "mk", English: "Macedonian"}, - {Alpha3bCode: "mah", Alpha2Code: "mh", English: "Marshallese"}, - {Alpha3bCode: "mal", Alpha2Code: "ml", English: "Malayalam"}, - {Alpha3bCode: "mao", Alpha2Code: "mi", English: "Maori"}, - {Alpha3bCode: "mar", Alpha2Code: "mr", English: "Marathi"}, - {Alpha3bCode: "may", Alpha2Code: "ms", English: "Malay"}, - {Alpha3bCode: "mlg", Alpha2Code: "mg", English: "Malagasy"}, - {Alpha3bCode: "mlt", Alpha2Code: "mt", English: "Maltese"}, - {Alpha3bCode: "mon", Alpha2Code: "mn", English: "Mongolian"}, - {Alpha3bCode: "nau", Alpha2Code: "na", English: "Nauru"}, - {Alpha3bCode: "nav", Alpha2Code: "nv", English: "Navajo; Navaho"}, - {Alpha3bCode: "nbl", Alpha2Code: "nr", English: "Ndebele, South; South Ndebele"}, - {Alpha3bCode: "nde", Alpha2Code: "nd", English: "Ndebele, North; North Ndebele"}, - {Alpha3bCode: "ndo", Alpha2Code: "ng", English: "Ndonga"}, - {Alpha3bCode: "nep", Alpha2Code: "ne", English: "Nepali"}, - {Alpha3bCode: "nno", Alpha2Code: "nn", English: "Norwegian Nynorsk; Nynorsk, Norwegian"}, - {Alpha3bCode: "nob", Alpha2Code: "nb", English: "Bokmål, Norwegian; Norwegian Bokmål"}, - {Alpha3bCode: "nor", Alpha2Code: "no", English: "Norwegian"}, - {Alpha3bCode: "nya", Alpha2Code: "ny", English: "Chichewa; Chewa; Nyanja"}, - {Alpha3bCode: "oci", Alpha2Code: "oc", English: "Occitan (post 1500); Provençal"}, - {Alpha3bCode: "oji", Alpha2Code: "oj", English: "Ojibwa"}, - {Alpha3bCode: "ori", Alpha2Code: "or", English: "Oriya"}, - {Alpha3bCode: "orm", Alpha2Code: "om", English: "Oromo"}, - {Alpha3bCode: "oss", Alpha2Code: "os", English: "Ossetian; Ossetic"}, - {Alpha3bCode: "pan", Alpha2Code: "pa", English: "Panjabi; Punjabi"}, - {Alpha3bCode: "per", Alpha2Code: "fa", English: "Persian"}, - {Alpha3bCode: "pli", Alpha2Code: "pi", English: "Pali"}, - {Alpha3bCode: "pol", Alpha2Code: "pl", English: "Polish"}, - {Alpha3bCode: "por", Alpha2Code: "pt", English: "Portuguese"}, - {Alpha3bCode: "pus", Alpha2Code: "ps", English: "Pushto; Pashto"}, - {Alpha3bCode: "que", Alpha2Code: "qu", English: "Quechua"}, - {Alpha3bCode: "roh", Alpha2Code: "rm", English: "Romansh"}, - {Alpha3bCode: "rum", Alpha2Code: "ro", English: "Romanian; Moldavian; Moldovan"}, - {Alpha3bCode: "run", Alpha2Code: "rn", English: "Rundi"}, - {Alpha3bCode: "rus", Alpha2Code: "ru", English: "Russian"}, - {Alpha3bCode: "sag", Alpha2Code: "sg", English: "Sango"}, - {Alpha3bCode: "san", Alpha2Code: "sa", English: "Sanskrit"}, - {Alpha3bCode: "sin", Alpha2Code: "si", English: "Sinhala; Sinhalese"}, - {Alpha3bCode: "slo", Alpha2Code: "sk", English: "Slovak"}, - {Alpha3bCode: "slv", Alpha2Code: "sl", English: "Slovenian"}, - {Alpha3bCode: "sme", Alpha2Code: "se", English: "Northern Sami"}, - {Alpha3bCode: "smo", Alpha2Code: "sm", English: "Samoan"}, - {Alpha3bCode: "sna", Alpha2Code: "sn", English: "Shona"}, - {Alpha3bCode: "snd", Alpha2Code: "sd", English: "Sindhi"}, - {Alpha3bCode: "som", Alpha2Code: "so", English: "Somali"}, - {Alpha3bCode: "sot", Alpha2Code: "st", English: "Sotho, Southern"}, - {Alpha3bCode: "spa", Alpha2Code: "es", English: "Spanish; Castilian"}, - {Alpha3bCode: "srd", Alpha2Code: "sc", English: "Sardinian"}, - {Alpha3bCode: "srp", Alpha2Code: "sr", English: "Serbian"}, - {Alpha3bCode: "ssw", Alpha2Code: "ss", English: "Swati"}, - {Alpha3bCode: "sun", Alpha2Code: "su", English: "Sundanese"}, - {Alpha3bCode: "swa", Alpha2Code: "sw", English: "Swahili"}, - {Alpha3bCode: "swe", Alpha2Code: "sv", English: "Swedish"}, - {Alpha3bCode: "tah", Alpha2Code: "ty", English: "Tahitian"}, - {Alpha3bCode: "tam", Alpha2Code: "ta", English: "Tamil"}, - {Alpha3bCode: "tat", Alpha2Code: "tt", English: "Tatar"}, - {Alpha3bCode: "tel", Alpha2Code: "te", English: "Telugu"}, - {Alpha3bCode: "tgk", Alpha2Code: "tg", English: "Tajik"}, - {Alpha3bCode: "tgl", Alpha2Code: "tl", English: "Tagalog"}, - {Alpha3bCode: "tha", Alpha2Code: "th", English: "Thai"}, - {Alpha3bCode: "tib", Alpha2Code: "bo", English: "Tibetan"}, - {Alpha3bCode: "tir", Alpha2Code: "ti", English: "Tigrinya"}, - {Alpha3bCode: "ton", Alpha2Code: "to", English: "Tonga (Tonga Islands)"}, - {Alpha3bCode: "tsn", Alpha2Code: "tn", English: "Tswana"}, - {Alpha3bCode: "tso", Alpha2Code: "ts", English: "Tsonga"}, - {Alpha3bCode: "tuk", Alpha2Code: "tk", English: "Turkmen"}, - {Alpha3bCode: "tur", Alpha2Code: "tr", English: "Turkish"}, - {Alpha3bCode: "twi", Alpha2Code: "tw", English: "Twi"}, - {Alpha3bCode: "uig", Alpha2Code: "ug", English: "Uighur; Uyghur"}, - {Alpha3bCode: "ukr", Alpha2Code: "uk", English: "Ukrainian"}, - {Alpha3bCode: "urd", Alpha2Code: "ur", English: "Urdu"}, - {Alpha3bCode: "uzb", Alpha2Code: "uz", English: "Uzbek"}, - {Alpha3bCode: "ven", Alpha2Code: "ve", English: "Venda"}, - {Alpha3bCode: "vie", Alpha2Code: "vi", English: "Vietnamese"}, - {Alpha3bCode: "vol", Alpha2Code: "vo", English: "Volapük"}, - {Alpha3bCode: "wel", Alpha2Code: "cy", English: "Welsh"}, - {Alpha3bCode: "wln", Alpha2Code: "wa", English: "Walloon"}, - {Alpha3bCode: "wol", Alpha2Code: "wo", English: "Wolof"}, - {Alpha3bCode: "xho", Alpha2Code: "xh", English: "Xhosa"}, - {Alpha3bCode: "yid", Alpha2Code: "yi", English: "Yiddish"}, - {Alpha3bCode: "yor", Alpha2Code: "yo", English: "Yoruba"}, - {Alpha3bCode: "zha", Alpha2Code: "za", English: "Zhuang; Chuang"}, - {Alpha3bCode: "zul", Alpha2Code: "zu", English: "Zulu"}, -} diff --git a/vendor/github.com/asaskevich/govalidator/utils.go b/vendor/github.com/asaskevich/govalidator/utils.go deleted file mode 100644 index f4c30f824..000000000 --- a/vendor/github.com/asaskevich/govalidator/utils.go +++ /dev/null @@ -1,270 +0,0 @@ -package govalidator - -import ( - "errors" - "fmt" - "html" - "math" - "path" - "regexp" - "strings" - "unicode" - "unicode/utf8" -) - -// Contains checks if the string contains the substring. -func Contains(str, substring string) bool { - return strings.Contains(str, substring) -} - -// Matches checks if string matches the pattern (pattern is regular expression) -// In case of error return false -func Matches(str, pattern string) bool { - match, _ := regexp.MatchString(pattern, str) - return match -} - -// LeftTrim trims characters from the left side of the input. -// If second argument is empty, it will remove leading spaces. -func LeftTrim(str, chars string) string { - if chars == "" { - return strings.TrimLeftFunc(str, unicode.IsSpace) - } - r, _ := regexp.Compile("^[" + chars + "]+") - return r.ReplaceAllString(str, "") -} - -// RightTrim trims characters from the right side of the input. -// If second argument is empty, it will remove trailing spaces. -func RightTrim(str, chars string) string { - if chars == "" { - return strings.TrimRightFunc(str, unicode.IsSpace) - } - r, _ := regexp.Compile("[" + chars + "]+$") - return r.ReplaceAllString(str, "") -} - -// Trim trims characters from both sides of the input. -// If second argument is empty, it will remove spaces. -func Trim(str, chars string) string { - return LeftTrim(RightTrim(str, chars), chars) -} - -// WhiteList removes characters that do not appear in the whitelist. -func WhiteList(str, chars string) string { - pattern := "[^" + chars + "]+" - r, _ := regexp.Compile(pattern) - return r.ReplaceAllString(str, "") -} - -// BlackList removes characters that appear in the blacklist. -func BlackList(str, chars string) string { - pattern := "[" + chars + "]+" - r, _ := regexp.Compile(pattern) - return r.ReplaceAllString(str, "") -} - -// StripLow removes characters with a numerical value < 32 and 127, mostly control characters. -// If keep_new_lines is true, newline characters are preserved (\n and \r, hex 0xA and 0xD). -func StripLow(str string, keepNewLines bool) string { - chars := "" - if keepNewLines { - chars = "\x00-\x09\x0B\x0C\x0E-\x1F\x7F" - } else { - chars = "\x00-\x1F\x7F" - } - return BlackList(str, chars) -} - -// ReplacePattern replaces regular expression pattern in string -func ReplacePattern(str, pattern, replace string) string { - r, _ := regexp.Compile(pattern) - return r.ReplaceAllString(str, replace) -} - -// Escape replaces <, >, & and " with HTML entities. -var Escape = html.EscapeString - -func addSegment(inrune, segment []rune) []rune { - if len(segment) == 0 { - return inrune - } - if len(inrune) != 0 { - inrune = append(inrune, '_') - } - inrune = append(inrune, segment...) - return inrune -} - -// UnderscoreToCamelCase converts from underscore separated form to camel case form. -// Ex.: my_func => MyFunc -func UnderscoreToCamelCase(s string) string { - return strings.Replace(strings.Title(strings.Replace(strings.ToLower(s), "_", " ", -1)), " ", "", -1) -} - -// CamelCaseToUnderscore converts from camel case form to underscore separated form. -// Ex.: MyFunc => my_func -func CamelCaseToUnderscore(str string) string { - var output []rune - var segment []rune - for _, r := range str { - - // not treat number as separate segment - if !unicode.IsLower(r) && string(r) != "_" && !unicode.IsNumber(r) { - output = addSegment(output, segment) - segment = nil - } - segment = append(segment, unicode.ToLower(r)) - } - output = addSegment(output, segment) - return string(output) -} - -// Reverse returns reversed string -func Reverse(s string) string { - r := []rune(s) - for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 { - r[i], r[j] = r[j], r[i] - } - return string(r) -} - -// GetLines splits string by "\n" and return array of lines -func GetLines(s string) []string { - return strings.Split(s, "\n") -} - -// GetLine returns specified line of multiline string -func GetLine(s string, index int) (string, error) { - lines := GetLines(s) - if index < 0 || index >= len(lines) { - return "", errors.New("line index out of bounds") - } - return lines[index], nil -} - -// RemoveTags removes all tags from HTML string -func RemoveTags(s string) string { - return ReplacePattern(s, "<[^>]*>", "") -} - -// SafeFileName returns safe string that can be used in file names -func SafeFileName(str string) string { - name := strings.ToLower(str) - name = path.Clean(path.Base(name)) - name = strings.Trim(name, " ") - separators, err := regexp.Compile(`[ &_=+:]`) - if err == nil { - name = separators.ReplaceAllString(name, "-") - } - legal, err := regexp.Compile(`[^[:alnum:]-.]`) - if err == nil { - name = legal.ReplaceAllString(name, "") - } - for strings.Contains(name, "--") { - name = strings.Replace(name, "--", "-", -1) - } - return name -} - -// NormalizeEmail canonicalize an email address. -// The local part of the email address is lowercased for all domains; the hostname is always lowercased and -// the local part of the email address is always lowercased for hosts that are known to be case-insensitive (currently only GMail). -// Normalization follows special rules for known providers: currently, GMail addresses have dots removed in the local part and -// are stripped of tags (e.g. some.one+tag@gmail.com becomes someone@gmail.com) and all @googlemail.com addresses are -// normalized to @gmail.com. -func NormalizeEmail(str string) (string, error) { - if !IsEmail(str) { - return "", fmt.Errorf("%s is not an email", str) - } - parts := strings.Split(str, "@") - parts[0] = strings.ToLower(parts[0]) - parts[1] = strings.ToLower(parts[1]) - if parts[1] == "gmail.com" || parts[1] == "googlemail.com" { - parts[1] = "gmail.com" - parts[0] = strings.Split(ReplacePattern(parts[0], `\.`, ""), "+")[0] - } - return strings.Join(parts, "@"), nil -} - -// Truncate a string to the closest length without breaking words. -func Truncate(str string, length int, ending string) string { - var aftstr, befstr string - if len(str) > length { - words := strings.Fields(str) - before, present := 0, 0 - for i := range words { - befstr = aftstr - before = present - aftstr = aftstr + words[i] + " " - present = len(aftstr) - if present > length && i != 0 { - if (length - before) < (present - length) { - return Trim(befstr, " /\\.,\"'#!?&@+-") + ending - } - return Trim(aftstr, " /\\.,\"'#!?&@+-") + ending - } - } - } - - return str -} - -// PadLeft pads left side of a string if size of string is less then indicated pad length -func PadLeft(str string, padStr string, padLen int) string { - return buildPadStr(str, padStr, padLen, true, false) -} - -// PadRight pads right side of a string if size of string is less then indicated pad length -func PadRight(str string, padStr string, padLen int) string { - return buildPadStr(str, padStr, padLen, false, true) -} - -// PadBoth pads both sides of a string if size of string is less then indicated pad length -func PadBoth(str string, padStr string, padLen int) string { - return buildPadStr(str, padStr, padLen, true, true) -} - -// PadString either left, right or both sides. -// Note that padding string can be unicode and more then one character -func buildPadStr(str string, padStr string, padLen int, padLeft bool, padRight bool) string { - - // When padded length is less then the current string size - if padLen < utf8.RuneCountInString(str) { - return str - } - - padLen -= utf8.RuneCountInString(str) - - targetLen := padLen - - targetLenLeft := targetLen - targetLenRight := targetLen - if padLeft && padRight { - targetLenLeft = padLen / 2 - targetLenRight = padLen - targetLenLeft - } - - strToRepeatLen := utf8.RuneCountInString(padStr) - - repeatTimes := int(math.Ceil(float64(targetLen) / float64(strToRepeatLen))) - repeatedString := strings.Repeat(padStr, repeatTimes) - - leftSide := "" - if padLeft { - leftSide = repeatedString[0:targetLenLeft] - } - - rightSide := "" - if padRight { - rightSide = repeatedString[0:targetLenRight] - } - - return leftSide + str + rightSide -} - -// TruncatingErrorf removes extra args from fmt.Errorf if not formatted in the str object -func TruncatingErrorf(str string, args ...interface{}) error { - n := strings.Count(str, "%s") - return fmt.Errorf(str, args[:n]...) -} diff --git a/vendor/github.com/asaskevich/govalidator/validator.go b/vendor/github.com/asaskevich/govalidator/validator.go deleted file mode 100644 index c9c4fac06..000000000 --- a/vendor/github.com/asaskevich/govalidator/validator.go +++ /dev/null @@ -1,1768 +0,0 @@ -// Package govalidator is package of validators and sanitizers for strings, structs and collections. -package govalidator - -import ( - "bytes" - "crypto/rsa" - "crypto/x509" - "encoding/base64" - "encoding/json" - "encoding/pem" - "fmt" - "io/ioutil" - "net" - "net/url" - "reflect" - "regexp" - "sort" - "strconv" - "strings" - "time" - "unicode" - "unicode/utf8" -) - -var ( - fieldsRequiredByDefault bool - nilPtrAllowedByRequired = false - notNumberRegexp = regexp.MustCompile("[^0-9]+") - whiteSpacesAndMinus = regexp.MustCompile(`[\s-]+`) - paramsRegexp = regexp.MustCompile(`\(.*\)$`) -) - -const maxURLRuneCount = 2083 -const minURLRuneCount = 3 -const rfc3339WithoutZone = "2006-01-02T15:04:05" - -// SetFieldsRequiredByDefault causes validation to fail when struct fields -// do not include validations or are not explicitly marked as exempt (using `valid:"-"` or `valid:"email,optional"`). -// This struct definition will fail govalidator.ValidateStruct() (and the field values do not matter): -// type exampleStruct struct { -// Name string `` -// Email string `valid:"email"` -// This, however, will only fail when Email is empty or an invalid email address: -// type exampleStruct2 struct { -// Name string `valid:"-"` -// Email string `valid:"email"` -// Lastly, this will only fail when Email is an invalid email address but not when it's empty: -// type exampleStruct2 struct { -// Name string `valid:"-"` -// Email string `valid:"email,optional"` -func SetFieldsRequiredByDefault(value bool) { - fieldsRequiredByDefault = value -} - -// SetNilPtrAllowedByRequired causes validation to pass for nil ptrs when a field is set to required. -// The validation will still reject ptr fields in their zero value state. Example with this enabled: -// type exampleStruct struct { -// Name *string `valid:"required"` -// With `Name` set to "", this will be considered invalid input and will cause a validation error. -// With `Name` set to nil, this will be considered valid by validation. -// By default this is disabled. -func SetNilPtrAllowedByRequired(value bool) { - nilPtrAllowedByRequired = value -} - -// IsEmail checks if the string is an email. -func IsEmail(str string) bool { - // TODO uppercase letters are not supported - return rxEmail.MatchString(str) -} - -// IsExistingEmail checks if the string is an email of existing domain -func IsExistingEmail(email string) bool { - - if len(email) < 6 || len(email) > 254 { - return false - } - at := strings.LastIndex(email, "@") - if at <= 0 || at > len(email)-3 { - return false - } - user := email[:at] - host := email[at+1:] - if len(user) > 64 { - return false - } - switch host { - case "localhost", "example.com": - return true - } - if userDotRegexp.MatchString(user) || !userRegexp.MatchString(user) || !hostRegexp.MatchString(host) { - return false - } - if _, err := net.LookupMX(host); err != nil { - if _, err := net.LookupIP(host); err != nil { - return false - } - } - - return true -} - -// IsURL checks if the string is an URL. -func IsURL(str string) bool { - if str == "" || utf8.RuneCountInString(str) >= maxURLRuneCount || len(str) <= minURLRuneCount || strings.HasPrefix(str, ".") { - return false - } - strTemp := str - if strings.Contains(str, ":") && !strings.Contains(str, "://") { - // support no indicated urlscheme but with colon for port number - // http:// is appended so url.Parse will succeed, strTemp used so it does not impact rxURL.MatchString - strTemp = "http://" + str - } - u, err := url.Parse(strTemp) - if err != nil { - return false - } - if strings.HasPrefix(u.Host, ".") { - return false - } - if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) { - return false - } - return rxURL.MatchString(str) -} - -// IsRequestURL checks if the string rawurl, assuming -// it was received in an HTTP request, is a valid -// URL confirm to RFC 3986 -func IsRequestURL(rawurl string) bool { - url, err := url.ParseRequestURI(rawurl) - if err != nil { - return false //Couldn't even parse the rawurl - } - if len(url.Scheme) == 0 { - return false //No Scheme found - } - return true -} - -// IsRequestURI checks if the string rawurl, assuming -// it was received in an HTTP request, is an -// absolute URI or an absolute path. -func IsRequestURI(rawurl string) bool { - _, err := url.ParseRequestURI(rawurl) - return err == nil -} - -// IsAlpha checks if the string contains only letters (a-zA-Z). Empty string is valid. -func IsAlpha(str string) bool { - if IsNull(str) { - return true - } - return rxAlpha.MatchString(str) -} - -//IsUTFLetter checks if the string contains only unicode letter characters. -//Similar to IsAlpha but for all languages. Empty string is valid. -func IsUTFLetter(str string) bool { - if IsNull(str) { - return true - } - - for _, c := range str { - if !unicode.IsLetter(c) { - return false - } - } - return true - -} - -// IsAlphanumeric checks if the string contains only letters and numbers. Empty string is valid. -func IsAlphanumeric(str string) bool { - if IsNull(str) { - return true - } - return rxAlphanumeric.MatchString(str) -} - -// IsUTFLetterNumeric checks if the string contains only unicode letters and numbers. Empty string is valid. -func IsUTFLetterNumeric(str string) bool { - if IsNull(str) { - return true - } - for _, c := range str { - if !unicode.IsLetter(c) && !unicode.IsNumber(c) { //letters && numbers are ok - return false - } - } - return true - -} - -// IsNumeric checks if the string contains only numbers. Empty string is valid. -func IsNumeric(str string) bool { - if IsNull(str) { - return true - } - return rxNumeric.MatchString(str) -} - -// IsUTFNumeric checks if the string contains only unicode numbers of any kind. -// Numbers can be 0-9 but also Fractions ¾,Roman Ⅸ and Hangzhou 〩. Empty string is valid. -func IsUTFNumeric(str string) bool { - if IsNull(str) { - return true - } - if strings.IndexAny(str, "+-") > 0 { - return false - } - if len(str) > 1 { - str = strings.TrimPrefix(str, "-") - str = strings.TrimPrefix(str, "+") - } - for _, c := range str { - if !unicode.IsNumber(c) { //numbers && minus sign are ok - return false - } - } - return true - -} - -// IsUTFDigit checks if the string contains only unicode radix-10 decimal digits. Empty string is valid. -func IsUTFDigit(str string) bool { - if IsNull(str) { - return true - } - if strings.IndexAny(str, "+-") > 0 { - return false - } - if len(str) > 1 { - str = strings.TrimPrefix(str, "-") - str = strings.TrimPrefix(str, "+") - } - for _, c := range str { - if !unicode.IsDigit(c) { //digits && minus sign are ok - return false - } - } - return true - -} - -// IsHexadecimal checks if the string is a hexadecimal number. -func IsHexadecimal(str string) bool { - return rxHexadecimal.MatchString(str) -} - -// IsHexcolor checks if the string is a hexadecimal color. -func IsHexcolor(str string) bool { - return rxHexcolor.MatchString(str) -} - -// IsRGBcolor checks if the string is a valid RGB color in form rgb(RRR, GGG, BBB). -func IsRGBcolor(str string) bool { - return rxRGBcolor.MatchString(str) -} - -// IsLowerCase checks if the string is lowercase. Empty string is valid. -func IsLowerCase(str string) bool { - if IsNull(str) { - return true - } - return str == strings.ToLower(str) -} - -// IsUpperCase checks if the string is uppercase. Empty string is valid. -func IsUpperCase(str string) bool { - if IsNull(str) { - return true - } - return str == strings.ToUpper(str) -} - -// HasLowerCase checks if the string contains at least 1 lowercase. Empty string is valid. -func HasLowerCase(str string) bool { - if IsNull(str) { - return true - } - return rxHasLowerCase.MatchString(str) -} - -// HasUpperCase checks if the string contains as least 1 uppercase. Empty string is valid. -func HasUpperCase(str string) bool { - if IsNull(str) { - return true - } - return rxHasUpperCase.MatchString(str) -} - -// IsInt checks if the string is an integer. Empty string is valid. -func IsInt(str string) bool { - if IsNull(str) { - return true - } - return rxInt.MatchString(str) -} - -// IsFloat checks if the string is a float. -func IsFloat(str string) bool { - return str != "" && rxFloat.MatchString(str) -} - -// IsDivisibleBy checks if the string is a number that's divisible by another. -// If second argument is not valid integer or zero, it's return false. -// Otherwise, if first argument is not valid integer or zero, it's return true (Invalid string converts to zero). -func IsDivisibleBy(str, num string) bool { - f, _ := ToFloat(str) - p := int64(f) - q, _ := ToInt(num) - if q == 0 { - return false - } - return (p == 0) || (p%q == 0) -} - -// IsNull checks if the string is null. -func IsNull(str string) bool { - return len(str) == 0 -} - -// IsNotNull checks if the string is not null. -func IsNotNull(str string) bool { - return !IsNull(str) -} - -// HasWhitespaceOnly checks the string only contains whitespace -func HasWhitespaceOnly(str string) bool { - return len(str) > 0 && rxHasWhitespaceOnly.MatchString(str) -} - -// HasWhitespace checks if the string contains any whitespace -func HasWhitespace(str string) bool { - return len(str) > 0 && rxHasWhitespace.MatchString(str) -} - -// IsByteLength checks if the string's length (in bytes) falls in a range. -func IsByteLength(str string, min, max int) bool { - return len(str) >= min && len(str) <= max -} - -// IsUUIDv3 checks if the string is a UUID version 3. -func IsUUIDv3(str string) bool { - return rxUUID3.MatchString(str) -} - -// IsUUIDv4 checks if the string is a UUID version 4. -func IsUUIDv4(str string) bool { - return rxUUID4.MatchString(str) -} - -// IsUUIDv5 checks if the string is a UUID version 5. -func IsUUIDv5(str string) bool { - return rxUUID5.MatchString(str) -} - -// IsUUID checks if the string is a UUID (version 3, 4 or 5). -func IsUUID(str string) bool { - return rxUUID.MatchString(str) -} - -// Byte to index table for O(1) lookups when unmarshaling. -// We use 0xFF as sentinel value for invalid indexes. -var ulidDec = [...]byte{ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14, 0x15, 0xFF, - 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C, 0x1D, 0x1E, - 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14, - 0x15, 0xFF, 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C, - 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -} - -// EncodedSize is the length of a text encoded ULID. -const ulidEncodedSize = 26 - -// IsULID checks if the string is a ULID. -// -// Implementation got from: -// https://github.com/oklog/ulid (Apache-2.0 License) -// -func IsULID(str string) bool { - // Check if a base32 encoded ULID is the right length. - if len(str) != ulidEncodedSize { - return false - } - - // Check if all the characters in a base32 encoded ULID are part of the - // expected base32 character set. - if ulidDec[str[0]] == 0xFF || - ulidDec[str[1]] == 0xFF || - ulidDec[str[2]] == 0xFF || - ulidDec[str[3]] == 0xFF || - ulidDec[str[4]] == 0xFF || - ulidDec[str[5]] == 0xFF || - ulidDec[str[6]] == 0xFF || - ulidDec[str[7]] == 0xFF || - ulidDec[str[8]] == 0xFF || - ulidDec[str[9]] == 0xFF || - ulidDec[str[10]] == 0xFF || - ulidDec[str[11]] == 0xFF || - ulidDec[str[12]] == 0xFF || - ulidDec[str[13]] == 0xFF || - ulidDec[str[14]] == 0xFF || - ulidDec[str[15]] == 0xFF || - ulidDec[str[16]] == 0xFF || - ulidDec[str[17]] == 0xFF || - ulidDec[str[18]] == 0xFF || - ulidDec[str[19]] == 0xFF || - ulidDec[str[20]] == 0xFF || - ulidDec[str[21]] == 0xFF || - ulidDec[str[22]] == 0xFF || - ulidDec[str[23]] == 0xFF || - ulidDec[str[24]] == 0xFF || - ulidDec[str[25]] == 0xFF { - return false - } - - // Check if the first character in a base32 encoded ULID will overflow. This - // happens because the base32 representation encodes 130 bits, while the - // ULID is only 128 bits. - // - // See https://github.com/oklog/ulid/issues/9 for details. - if str[0] > '7' { - return false - } - return true -} - -// IsCreditCard checks if the string is a credit card. -func IsCreditCard(str string) bool { - sanitized := whiteSpacesAndMinus.ReplaceAllString(str, "") - if !rxCreditCard.MatchString(sanitized) { - return false - } - - number, _ := ToInt(sanitized) - number, lastDigit := number / 10, number % 10 - - var sum int64 - for i:=0; number > 0; i++ { - digit := number % 10 - - if i % 2 == 0 { - digit *= 2 - if digit > 9 { - digit -= 9 - } - } - - sum += digit - number = number / 10 - } - - return (sum + lastDigit) % 10 == 0 -} - -// IsISBN10 checks if the string is an ISBN version 10. -func IsISBN10(str string) bool { - return IsISBN(str, 10) -} - -// IsISBN13 checks if the string is an ISBN version 13. -func IsISBN13(str string) bool { - return IsISBN(str, 13) -} - -// IsISBN checks if the string is an ISBN (version 10 or 13). -// If version value is not equal to 10 or 13, it will be checks both variants. -func IsISBN(str string, version int) bool { - sanitized := whiteSpacesAndMinus.ReplaceAllString(str, "") - var checksum int32 - var i int32 - if version == 10 { - if !rxISBN10.MatchString(sanitized) { - return false - } - for i = 0; i < 9; i++ { - checksum += (i + 1) * int32(sanitized[i]-'0') - } - if sanitized[9] == 'X' { - checksum += 10 * 10 - } else { - checksum += 10 * int32(sanitized[9]-'0') - } - if checksum%11 == 0 { - return true - } - return false - } else if version == 13 { - if !rxISBN13.MatchString(sanitized) { - return false - } - factor := []int32{1, 3} - for i = 0; i < 12; i++ { - checksum += factor[i%2] * int32(sanitized[i]-'0') - } - return (int32(sanitized[12]-'0'))-((10-(checksum%10))%10) == 0 - } - return IsISBN(str, 10) || IsISBN(str, 13) -} - -// IsJSON checks if the string is valid JSON (note: uses json.Unmarshal). -func IsJSON(str string) bool { - var js json.RawMessage - return json.Unmarshal([]byte(str), &js) == nil -} - -// IsMultibyte checks if the string contains one or more multibyte chars. Empty string is valid. -func IsMultibyte(str string) bool { - if IsNull(str) { - return true - } - return rxMultibyte.MatchString(str) -} - -// IsASCII checks if the string contains ASCII chars only. Empty string is valid. -func IsASCII(str string) bool { - if IsNull(str) { - return true - } - return rxASCII.MatchString(str) -} - -// IsPrintableASCII checks if the string contains printable ASCII chars only. Empty string is valid. -func IsPrintableASCII(str string) bool { - if IsNull(str) { - return true - } - return rxPrintableASCII.MatchString(str) -} - -// IsFullWidth checks if the string contains any full-width chars. Empty string is valid. -func IsFullWidth(str string) bool { - if IsNull(str) { - return true - } - return rxFullWidth.MatchString(str) -} - -// IsHalfWidth checks if the string contains any half-width chars. Empty string is valid. -func IsHalfWidth(str string) bool { - if IsNull(str) { - return true - } - return rxHalfWidth.MatchString(str) -} - -// IsVariableWidth checks if the string contains a mixture of full and half-width chars. Empty string is valid. -func IsVariableWidth(str string) bool { - if IsNull(str) { - return true - } - return rxHalfWidth.MatchString(str) && rxFullWidth.MatchString(str) -} - -// IsBase64 checks if a string is base64 encoded. -func IsBase64(str string) bool { - return rxBase64.MatchString(str) -} - -// IsFilePath checks is a string is Win or Unix file path and returns it's type. -func IsFilePath(str string) (bool, int) { - if rxWinPath.MatchString(str) { - //check windows path limit see: - // http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath - if len(str[3:]) > 32767 { - return false, Win - } - return true, Win - } else if rxUnixPath.MatchString(str) { - return true, Unix - } - return false, Unknown -} - -//IsWinFilePath checks both relative & absolute paths in Windows -func IsWinFilePath(str string) bool { - if rxARWinPath.MatchString(str) { - //check windows path limit see: - // http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath - if len(str[3:]) > 32767 { - return false - } - return true - } - return false -} - -//IsUnixFilePath checks both relative & absolute paths in Unix -func IsUnixFilePath(str string) bool { - if rxARUnixPath.MatchString(str) { - return true - } - return false -} - -// IsDataURI checks if a string is base64 encoded data URI such as an image -func IsDataURI(str string) bool { - dataURI := strings.Split(str, ",") - if !rxDataURI.MatchString(dataURI[0]) { - return false - } - return IsBase64(dataURI[1]) -} - -// IsMagnetURI checks if a string is valid magnet URI -func IsMagnetURI(str string) bool { - return rxMagnetURI.MatchString(str) -} - -// IsISO3166Alpha2 checks if a string is valid two-letter country code -func IsISO3166Alpha2(str string) bool { - for _, entry := range ISO3166List { - if str == entry.Alpha2Code { - return true - } - } - return false -} - -// IsISO3166Alpha3 checks if a string is valid three-letter country code -func IsISO3166Alpha3(str string) bool { - for _, entry := range ISO3166List { - if str == entry.Alpha3Code { - return true - } - } - return false -} - -// IsISO693Alpha2 checks if a string is valid two-letter language code -func IsISO693Alpha2(str string) bool { - for _, entry := range ISO693List { - if str == entry.Alpha2Code { - return true - } - } - return false -} - -// IsISO693Alpha3b checks if a string is valid three-letter language code -func IsISO693Alpha3b(str string) bool { - for _, entry := range ISO693List { - if str == entry.Alpha3bCode { - return true - } - } - return false -} - -// IsDNSName will validate the given string as a DNS name -func IsDNSName(str string) bool { - if str == "" || len(strings.Replace(str, ".", "", -1)) > 255 { - // constraints already violated - return false - } - return !IsIP(str) && rxDNSName.MatchString(str) -} - -// IsHash checks if a string is a hash of type algorithm. -// Algorithm is one of ['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b'] -func IsHash(str string, algorithm string) bool { - var len string - algo := strings.ToLower(algorithm) - - if algo == "crc32" || algo == "crc32b" { - len = "8" - } else if algo == "md5" || algo == "md4" || algo == "ripemd128" || algo == "tiger128" { - len = "32" - } else if algo == "sha1" || algo == "ripemd160" || algo == "tiger160" { - len = "40" - } else if algo == "tiger192" { - len = "48" - } else if algo == "sha3-224" { - len = "56" - } else if algo == "sha256" || algo == "sha3-256" { - len = "64" - } else if algo == "sha384" || algo == "sha3-384" { - len = "96" - } else if algo == "sha512" || algo == "sha3-512" { - len = "128" - } else { - return false - } - - return Matches(str, "^[a-f0-9]{"+len+"}$") -} - -// IsSHA3224 checks is a string is a SHA3-224 hash. Alias for `IsHash(str, "sha3-224")` -func IsSHA3224(str string) bool { - return IsHash(str, "sha3-224") -} - -// IsSHA3256 checks is a string is a SHA3-256 hash. Alias for `IsHash(str, "sha3-256")` -func IsSHA3256(str string) bool { - return IsHash(str, "sha3-256") -} - -// IsSHA3384 checks is a string is a SHA3-384 hash. Alias for `IsHash(str, "sha3-384")` -func IsSHA3384(str string) bool { - return IsHash(str, "sha3-384") -} - -// IsSHA3512 checks is a string is a SHA3-512 hash. Alias for `IsHash(str, "sha3-512")` -func IsSHA3512(str string) bool { - return IsHash(str, "sha3-512") -} - -// IsSHA512 checks is a string is a SHA512 hash. Alias for `IsHash(str, "sha512")` -func IsSHA512(str string) bool { - return IsHash(str, "sha512") -} - -// IsSHA384 checks is a string is a SHA384 hash. Alias for `IsHash(str, "sha384")` -func IsSHA384(str string) bool { - return IsHash(str, "sha384") -} - -// IsSHA256 checks is a string is a SHA256 hash. Alias for `IsHash(str, "sha256")` -func IsSHA256(str string) bool { - return IsHash(str, "sha256") -} - -// IsTiger192 checks is a string is a Tiger192 hash. Alias for `IsHash(str, "tiger192")` -func IsTiger192(str string) bool { - return IsHash(str, "tiger192") -} - -// IsTiger160 checks is a string is a Tiger160 hash. Alias for `IsHash(str, "tiger160")` -func IsTiger160(str string) bool { - return IsHash(str, "tiger160") -} - -// IsRipeMD160 checks is a string is a RipeMD160 hash. Alias for `IsHash(str, "ripemd160")` -func IsRipeMD160(str string) bool { - return IsHash(str, "ripemd160") -} - -// IsSHA1 checks is a string is a SHA-1 hash. Alias for `IsHash(str, "sha1")` -func IsSHA1(str string) bool { - return IsHash(str, "sha1") -} - -// IsTiger128 checks is a string is a Tiger128 hash. Alias for `IsHash(str, "tiger128")` -func IsTiger128(str string) bool { - return IsHash(str, "tiger128") -} - -// IsRipeMD128 checks is a string is a RipeMD128 hash. Alias for `IsHash(str, "ripemd128")` -func IsRipeMD128(str string) bool { - return IsHash(str, "ripemd128") -} - -// IsCRC32 checks is a string is a CRC32 hash. Alias for `IsHash(str, "crc32")` -func IsCRC32(str string) bool { - return IsHash(str, "crc32") -} - -// IsCRC32b checks is a string is a CRC32b hash. Alias for `IsHash(str, "crc32b")` -func IsCRC32b(str string) bool { - return IsHash(str, "crc32b") -} - -// IsMD5 checks is a string is a MD5 hash. Alias for `IsHash(str, "md5")` -func IsMD5(str string) bool { - return IsHash(str, "md5") -} - -// IsMD4 checks is a string is a MD4 hash. Alias for `IsHash(str, "md4")` -func IsMD4(str string) bool { - return IsHash(str, "md4") -} - -// IsDialString validates the given string for usage with the various Dial() functions -func IsDialString(str string) bool { - if h, p, err := net.SplitHostPort(str); err == nil && h != "" && p != "" && (IsDNSName(h) || IsIP(h)) && IsPort(p) { - return true - } - - return false -} - -// IsIP checks if a string is either IP version 4 or 6. Alias for `net.ParseIP` -func IsIP(str string) bool { - return net.ParseIP(str) != nil -} - -// IsPort checks if a string represents a valid port -func IsPort(str string) bool { - if i, err := strconv.Atoi(str); err == nil && i > 0 && i < 65536 { - return true - } - return false -} - -// IsIPv4 checks if the string is an IP version 4. -func IsIPv4(str string) bool { - ip := net.ParseIP(str) - return ip != nil && strings.Contains(str, ".") -} - -// IsIPv6 checks if the string is an IP version 6. -func IsIPv6(str string) bool { - ip := net.ParseIP(str) - return ip != nil && strings.Contains(str, ":") -} - -// IsCIDR checks if the string is an valid CIDR notiation (IPV4 & IPV6) -func IsCIDR(str string) bool { - _, _, err := net.ParseCIDR(str) - return err == nil -} - -// IsMAC checks if a string is valid MAC address. -// Possible MAC formats: -// 01:23:45:67:89:ab -// 01:23:45:67:89:ab:cd:ef -// 01-23-45-67-89-ab -// 01-23-45-67-89-ab-cd-ef -// 0123.4567.89ab -// 0123.4567.89ab.cdef -func IsMAC(str string) bool { - _, err := net.ParseMAC(str) - return err == nil -} - -// IsHost checks if the string is a valid IP (both v4 and v6) or a valid DNS name -func IsHost(str string) bool { - return IsIP(str) || IsDNSName(str) -} - -// IsMongoID checks if the string is a valid hex-encoded representation of a MongoDB ObjectId. -func IsMongoID(str string) bool { - return rxHexadecimal.MatchString(str) && (len(str) == 24) -} - -// IsLatitude checks if a string is valid latitude. -func IsLatitude(str string) bool { - return rxLatitude.MatchString(str) -} - -// IsLongitude checks if a string is valid longitude. -func IsLongitude(str string) bool { - return rxLongitude.MatchString(str) -} - -// IsIMEI checks if a string is valid IMEI -func IsIMEI(str string) bool { - return rxIMEI.MatchString(str) -} - -// IsIMSI checks if a string is valid IMSI -func IsIMSI(str string) bool { - if !rxIMSI.MatchString(str) { - return false - } - - mcc, err := strconv.ParseInt(str[0:3], 10, 32) - if err != nil { - return false - } - - switch mcc { - case 202, 204, 206, 208, 212, 213, 214, 216, 218, 219: - case 220, 221, 222, 226, 228, 230, 231, 232, 234, 235: - case 238, 240, 242, 244, 246, 247, 248, 250, 255, 257: - case 259, 260, 262, 266, 268, 270, 272, 274, 276, 278: - case 280, 282, 283, 284, 286, 288, 289, 290, 292, 293: - case 294, 295, 297, 302, 308, 310, 311, 312, 313, 314: - case 315, 316, 330, 332, 334, 338, 340, 342, 344, 346: - case 348, 350, 352, 354, 356, 358, 360, 362, 363, 364: - case 365, 366, 368, 370, 372, 374, 376, 400, 401, 402: - case 404, 405, 406, 410, 412, 413, 414, 415, 416, 417: - case 418, 419, 420, 421, 422, 424, 425, 426, 427, 428: - case 429, 430, 431, 432, 434, 436, 437, 438, 440, 441: - case 450, 452, 454, 455, 456, 457, 460, 461, 466, 467: - case 470, 472, 502, 505, 510, 514, 515, 520, 525, 528: - case 530, 536, 537, 539, 540, 541, 542, 543, 544, 545: - case 546, 547, 548, 549, 550, 551, 552, 553, 554, 555: - case 602, 603, 604, 605, 606, 607, 608, 609, 610, 611: - case 612, 613, 614, 615, 616, 617, 618, 619, 620, 621: - case 622, 623, 624, 625, 626, 627, 628, 629, 630, 631: - case 632, 633, 634, 635, 636, 637, 638, 639, 640, 641: - case 642, 643, 645, 646, 647, 648, 649, 650, 651, 652: - case 653, 654, 655, 657, 658, 659, 702, 704, 706, 708: - case 710, 712, 714, 716, 722, 724, 730, 732, 734, 736: - case 738, 740, 742, 744, 746, 748, 750, 995: - return true - default: - return false - } - return true -} - -// IsRsaPublicKey checks if a string is valid public key with provided length -func IsRsaPublicKey(str string, keylen int) bool { - bb := bytes.NewBufferString(str) - pemBytes, err := ioutil.ReadAll(bb) - if err != nil { - return false - } - block, _ := pem.Decode(pemBytes) - if block != nil && block.Type != "PUBLIC KEY" { - return false - } - var der []byte - - if block != nil { - der = block.Bytes - } else { - der, err = base64.StdEncoding.DecodeString(str) - if err != nil { - return false - } - } - - key, err := x509.ParsePKIXPublicKey(der) - if err != nil { - return false - } - pubkey, ok := key.(*rsa.PublicKey) - if !ok { - return false - } - bitlen := len(pubkey.N.Bytes()) * 8 - return bitlen == int(keylen) -} - -// IsRegex checks if a give string is a valid regex with RE2 syntax or not -func IsRegex(str string) bool { - if _, err := regexp.Compile(str); err == nil { - return true - } - return false -} - -func toJSONName(tag string) string { - if tag == "" { - return "" - } - - // JSON name always comes first. If there's no options then split[0] is - // JSON name, if JSON name is not set, then split[0] is an empty string. - split := strings.SplitN(tag, ",", 2) - - name := split[0] - - // However it is possible that the field is skipped when - // (de-)serializing from/to JSON, in which case assume that there is no - // tag name to use - if name == "-" { - return "" - } - return name -} - -func prependPathToErrors(err error, path string) error { - switch err2 := err.(type) { - case Error: - err2.Path = append([]string{path}, err2.Path...) - return err2 - case Errors: - errors := err2.Errors() - for i, err3 := range errors { - errors[i] = prependPathToErrors(err3, path) - } - return err2 - } - return err -} - -// ValidateArray performs validation according to condition iterator that validates every element of the array -func ValidateArray(array []interface{}, iterator ConditionIterator) bool { - return Every(array, iterator) -} - -// ValidateMap use validation map for fields. -// result will be equal to `false` if there are any errors. -// s is the map containing the data to be validated. -// m is the validation map in the form: -// map[string]interface{}{"name":"required,alpha","address":map[string]interface{}{"line1":"required,alphanum"}} -func ValidateMap(s map[string]interface{}, m map[string]interface{}) (bool, error) { - if s == nil { - return true, nil - } - result := true - var err error - var errs Errors - var index int - val := reflect.ValueOf(s) - for key, value := range s { - presentResult := true - validator, ok := m[key] - if !ok { - presentResult = false - var err error - err = fmt.Errorf("all map keys has to be present in the validation map; got %s", key) - err = prependPathToErrors(err, key) - errs = append(errs, err) - } - valueField := reflect.ValueOf(value) - mapResult := true - typeResult := true - structResult := true - resultField := true - switch subValidator := validator.(type) { - case map[string]interface{}: - var err error - if v, ok := value.(map[string]interface{}); !ok { - mapResult = false - err = fmt.Errorf("map validator has to be for the map type only; got %s", valueField.Type().String()) - err = prependPathToErrors(err, key) - errs = append(errs, err) - } else { - mapResult, err = ValidateMap(v, subValidator) - if err != nil { - mapResult = false - err = prependPathToErrors(err, key) - errs = append(errs, err) - } - } - case string: - if (valueField.Kind() == reflect.Struct || - (valueField.Kind() == reflect.Ptr && valueField.Elem().Kind() == reflect.Struct)) && - subValidator != "-" { - var err error - structResult, err = ValidateStruct(valueField.Interface()) - if err != nil { - err = prependPathToErrors(err, key) - errs = append(errs, err) - } - } - resultField, err = typeCheck(valueField, reflect.StructField{ - Name: key, - PkgPath: "", - Type: val.Type(), - Tag: reflect.StructTag(fmt.Sprintf("%s:%q", tagName, subValidator)), - Offset: 0, - Index: []int{index}, - Anonymous: false, - }, val, nil) - if err != nil { - errs = append(errs, err) - } - case nil: - // already handlerd when checked before - default: - typeResult = false - err = fmt.Errorf("map validator has to be either map[string]interface{} or string; got %s", valueField.Type().String()) - err = prependPathToErrors(err, key) - errs = append(errs, err) - } - result = result && presentResult && typeResult && resultField && structResult && mapResult - index++ - } - // checks required keys - requiredResult := true - for key, value := range m { - if schema, ok := value.(string); ok { - tags := parseTagIntoMap(schema) - if required, ok := tags["required"]; ok { - if _, ok := s[key]; !ok { - requiredResult = false - if required.customErrorMessage != "" { - err = Error{key, fmt.Errorf(required.customErrorMessage), true, "required", []string{}} - } else { - err = Error{key, fmt.Errorf("required field missing"), false, "required", []string{}} - } - errs = append(errs, err) - } - } - } - } - - if len(errs) > 0 { - err = errs - } - return result && requiredResult, err -} - -// ValidateStruct use tags for fields. -// result will be equal to `false` if there are any errors. -// todo currently there is no guarantee that errors will be returned in predictable order (tests may to fail) -func ValidateStruct(s interface{}) (bool, error) { - if s == nil { - return true, nil - } - result := true - var err error - val := reflect.ValueOf(s) - if val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr { - val = val.Elem() - } - // we only accept structs - if val.Kind() != reflect.Struct { - return false, fmt.Errorf("function only accepts structs; got %s", val.Kind()) - } - var errs Errors - for i := 0; i < val.NumField(); i++ { - valueField := val.Field(i) - typeField := val.Type().Field(i) - if typeField.PkgPath != "" { - continue // Private field - } - structResult := true - if valueField.Kind() == reflect.Interface { - valueField = valueField.Elem() - } - if (valueField.Kind() == reflect.Struct || - (valueField.Kind() == reflect.Ptr && valueField.Elem().Kind() == reflect.Struct)) && - typeField.Tag.Get(tagName) != "-" { - var err error - structResult, err = ValidateStruct(valueField.Interface()) - if err != nil { - err = prependPathToErrors(err, typeField.Name) - errs = append(errs, err) - } - } - resultField, err2 := typeCheck(valueField, typeField, val, nil) - if err2 != nil { - - // Replace structure name with JSON name if there is a tag on the variable - jsonTag := toJSONName(typeField.Tag.Get("json")) - if jsonTag != "" { - switch jsonError := err2.(type) { - case Error: - jsonError.Name = jsonTag - err2 = jsonError - case Errors: - for i2, err3 := range jsonError { - switch customErr := err3.(type) { - case Error: - customErr.Name = jsonTag - jsonError[i2] = customErr - } - } - - err2 = jsonError - } - } - - errs = append(errs, err2) - } - result = result && resultField && structResult - } - if len(errs) > 0 { - err = errs - } - return result, err -} - -// ValidateStructAsync performs async validation of the struct and returns results through the channels -func ValidateStructAsync(s interface{}) (<-chan bool, <-chan error) { - res := make(chan bool) - errors := make(chan error) - - go func() { - defer close(res) - defer close(errors) - - isValid, isFailed := ValidateStruct(s) - - res <- isValid - errors <- isFailed - }() - - return res, errors -} - -// ValidateMapAsync performs async validation of the map and returns results through the channels -func ValidateMapAsync(s map[string]interface{}, m map[string]interface{}) (<-chan bool, <-chan error) { - res := make(chan bool) - errors := make(chan error) - - go func() { - defer close(res) - defer close(errors) - - isValid, isFailed := ValidateMap(s, m) - - res <- isValid - errors <- isFailed - }() - - return res, errors -} - -// parseTagIntoMap parses a struct tag `valid:required~Some error message,length(2|3)` into map[string]string{"required": "Some error message", "length(2|3)": ""} -func parseTagIntoMap(tag string) tagOptionsMap { - optionsMap := make(tagOptionsMap) - options := strings.Split(tag, ",") - - for i, option := range options { - option = strings.TrimSpace(option) - - validationOptions := strings.Split(option, "~") - if !isValidTag(validationOptions[0]) { - continue - } - if len(validationOptions) == 2 { - optionsMap[validationOptions[0]] = tagOption{validationOptions[0], validationOptions[1], i} - } else { - optionsMap[validationOptions[0]] = tagOption{validationOptions[0], "", i} - } - } - return optionsMap -} - -func isValidTag(s string) bool { - if s == "" { - return false - } - for _, c := range s { - switch { - case strings.ContainsRune("\\'\"!#$%&()*+-./:<=>?@[]^_{|}~ ", c): - // Backslash and quote chars are reserved, but - // otherwise any punctuation chars are allowed - // in a tag name. - default: - if !unicode.IsLetter(c) && !unicode.IsDigit(c) { - return false - } - } - } - return true -} - -// IsSSN will validate the given string as a U.S. Social Security Number -func IsSSN(str string) bool { - if str == "" || len(str) != 11 { - return false - } - return rxSSN.MatchString(str) -} - -// IsSemver checks if string is valid semantic version -func IsSemver(str string) bool { - return rxSemver.MatchString(str) -} - -// IsType checks if interface is of some type -func IsType(v interface{}, params ...string) bool { - if len(params) == 1 { - typ := params[0] - return strings.Replace(reflect.TypeOf(v).String(), " ", "", -1) == strings.Replace(typ, " ", "", -1) - } - return false -} - -// IsTime checks if string is valid according to given format -func IsTime(str string, format string) bool { - _, err := time.Parse(format, str) - return err == nil -} - -// IsUnixTime checks if string is valid unix timestamp value -func IsUnixTime(str string) bool { - if _, err := strconv.Atoi(str); err == nil { - return true - } - return false -} - -// IsRFC3339 checks if string is valid timestamp value according to RFC3339 -func IsRFC3339(str string) bool { - return IsTime(str, time.RFC3339) -} - -// IsRFC3339WithoutZone checks if string is valid timestamp value according to RFC3339 which excludes the timezone. -func IsRFC3339WithoutZone(str string) bool { - return IsTime(str, rfc3339WithoutZone) -} - -// IsISO4217 checks if string is valid ISO currency code -func IsISO4217(str string) bool { - for _, currency := range ISO4217List { - if str == currency { - return true - } - } - - return false -} - -// ByteLength checks string's length -func ByteLength(str string, params ...string) bool { - if len(params) == 2 { - min, _ := ToInt(params[0]) - max, _ := ToInt(params[1]) - return len(str) >= int(min) && len(str) <= int(max) - } - - return false -} - -// RuneLength checks string's length -// Alias for StringLength -func RuneLength(str string, params ...string) bool { - return StringLength(str, params...) -} - -// IsRsaPub checks whether string is valid RSA key -// Alias for IsRsaPublicKey -func IsRsaPub(str string, params ...string) bool { - if len(params) == 1 { - len, _ := ToInt(params[0]) - return IsRsaPublicKey(str, int(len)) - } - - return false -} - -// StringMatches checks if a string matches a given pattern. -func StringMatches(s string, params ...string) bool { - if len(params) == 1 { - pattern := params[0] - return Matches(s, pattern) - } - return false -} - -// StringLength checks string's length (including multi byte strings) -func StringLength(str string, params ...string) bool { - - if len(params) == 2 { - strLength := utf8.RuneCountInString(str) - min, _ := ToInt(params[0]) - max, _ := ToInt(params[1]) - return strLength >= int(min) && strLength <= int(max) - } - - return false -} - -// MinStringLength checks string's minimum length (including multi byte strings) -func MinStringLength(str string, params ...string) bool { - - if len(params) == 1 { - strLength := utf8.RuneCountInString(str) - min, _ := ToInt(params[0]) - return strLength >= int(min) - } - - return false -} - -// MaxStringLength checks string's maximum length (including multi byte strings) -func MaxStringLength(str string, params ...string) bool { - - if len(params) == 1 { - strLength := utf8.RuneCountInString(str) - max, _ := ToInt(params[0]) - return strLength <= int(max) - } - - return false -} - -// Range checks string's length -func Range(str string, params ...string) bool { - if len(params) == 2 { - value, _ := ToFloat(str) - min, _ := ToFloat(params[0]) - max, _ := ToFloat(params[1]) - return InRange(value, min, max) - } - - return false -} - -// IsInRaw checks if string is in list of allowed values -func IsInRaw(str string, params ...string) bool { - if len(params) == 1 { - rawParams := params[0] - - parsedParams := strings.Split(rawParams, "|") - - return IsIn(str, parsedParams...) - } - - return false -} - -// IsIn checks if string str is a member of the set of strings params -func IsIn(str string, params ...string) bool { - for _, param := range params { - if str == param { - return true - } - } - - return false -} - -func checkRequired(v reflect.Value, t reflect.StructField, options tagOptionsMap) (bool, error) { - if nilPtrAllowedByRequired { - k := v.Kind() - if (k == reflect.Ptr || k == reflect.Interface) && v.IsNil() { - return true, nil - } - } - - if requiredOption, isRequired := options["required"]; isRequired { - if len(requiredOption.customErrorMessage) > 0 { - return false, Error{t.Name, fmt.Errorf(requiredOption.customErrorMessage), true, "required", []string{}} - } - return false, Error{t.Name, fmt.Errorf("non zero value required"), false, "required", []string{}} - } else if _, isOptional := options["optional"]; fieldsRequiredByDefault && !isOptional { - return false, Error{t.Name, fmt.Errorf("Missing required field"), false, "required", []string{}} - } - // not required and empty is valid - return true, nil -} - -func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options tagOptionsMap) (isValid bool, resultErr error) { - if !v.IsValid() { - return false, nil - } - - tag := t.Tag.Get(tagName) - - // checks if the field should be ignored - switch tag { - case "": - if v.Kind() != reflect.Slice && v.Kind() != reflect.Map { - if !fieldsRequiredByDefault { - return true, nil - } - return false, Error{t.Name, fmt.Errorf("All fields are required to at least have one validation defined"), false, "required", []string{}} - } - case "-": - return true, nil - } - - isRootType := false - if options == nil { - isRootType = true - options = parseTagIntoMap(tag) - } - - if isEmptyValue(v) { - // an empty value is not validated, checks only required - isValid, resultErr = checkRequired(v, t, options) - for key := range options { - delete(options, key) - } - return isValid, resultErr - } - - var customTypeErrors Errors - optionsOrder := options.orderedKeys() - for _, validatorName := range optionsOrder { - validatorStruct := options[validatorName] - if validatefunc, ok := CustomTypeTagMap.Get(validatorName); ok { - delete(options, validatorName) - - if result := validatefunc(v.Interface(), o.Interface()); !result { - if len(validatorStruct.customErrorMessage) > 0 { - customTypeErrors = append(customTypeErrors, Error{Name: t.Name, Err: TruncatingErrorf(validatorStruct.customErrorMessage, fmt.Sprint(v), validatorName), CustomErrorMessageExists: true, Validator: stripParams(validatorName)}) - continue - } - customTypeErrors = append(customTypeErrors, Error{Name: t.Name, Err: fmt.Errorf("%s does not validate as %s", fmt.Sprint(v), validatorName), CustomErrorMessageExists: false, Validator: stripParams(validatorName)}) - } - } - } - - if len(customTypeErrors.Errors()) > 0 { - return false, customTypeErrors - } - - if isRootType { - // Ensure that we've checked the value by all specified validators before report that the value is valid - defer func() { - delete(options, "optional") - delete(options, "required") - - if isValid && resultErr == nil && len(options) != 0 { - optionsOrder := options.orderedKeys() - for _, validator := range optionsOrder { - isValid = false - resultErr = Error{t.Name, fmt.Errorf( - "The following validator is invalid or can't be applied to the field: %q", validator), false, stripParams(validator), []string{}} - return - } - } - }() - } - - for _, validatorSpec := range optionsOrder { - validatorStruct := options[validatorSpec] - var negate bool - validator := validatorSpec - customMsgExists := len(validatorStruct.customErrorMessage) > 0 - - // checks whether the tag looks like '!something' or 'something' - if validator[0] == '!' { - validator = validator[1:] - negate = true - } - - // checks for interface param validators - for key, value := range InterfaceParamTagRegexMap { - ps := value.FindStringSubmatch(validator) - if len(ps) == 0 { - continue - } - - validatefunc, ok := InterfaceParamTagMap[key] - if !ok { - continue - } - - delete(options, validatorSpec) - - field := fmt.Sprint(v) - if result := validatefunc(v.Interface(), ps[1:]...); (!result && !negate) || (result && negate) { - if customMsgExists { - return false, Error{t.Name, TruncatingErrorf(validatorStruct.customErrorMessage, field, validator), customMsgExists, stripParams(validatorSpec), []string{}} - } - if negate { - return false, Error{t.Name, fmt.Errorf("%s does validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} - } - return false, Error{t.Name, fmt.Errorf("%s does not validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} - } - } - } - - switch v.Kind() { - case reflect.Bool, - reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, - reflect.Float32, reflect.Float64, - reflect.String: - // for each tag option checks the map of validator functions - for _, validatorSpec := range optionsOrder { - validatorStruct := options[validatorSpec] - var negate bool - validator := validatorSpec - customMsgExists := len(validatorStruct.customErrorMessage) > 0 - - // checks whether the tag looks like '!something' or 'something' - if validator[0] == '!' { - validator = validator[1:] - negate = true - } - - // checks for param validators - for key, value := range ParamTagRegexMap { - ps := value.FindStringSubmatch(validator) - if len(ps) == 0 { - continue - } - - validatefunc, ok := ParamTagMap[key] - if !ok { - continue - } - - delete(options, validatorSpec) - - switch v.Kind() { - case reflect.String, - reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, - reflect.Float32, reflect.Float64: - - field := fmt.Sprint(v) // make value into string, then validate with regex - if result := validatefunc(field, ps[1:]...); (!result && !negate) || (result && negate) { - if customMsgExists { - return false, Error{t.Name, TruncatingErrorf(validatorStruct.customErrorMessage, field, validator), customMsgExists, stripParams(validatorSpec), []string{}} - } - if negate { - return false, Error{t.Name, fmt.Errorf("%s does validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} - } - return false, Error{t.Name, fmt.Errorf("%s does not validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} - } - default: - // type not yet supported, fail - return false, Error{t.Name, fmt.Errorf("Validator %s doesn't support kind %s", validator, v.Kind()), false, stripParams(validatorSpec), []string{}} - } - } - - if validatefunc, ok := TagMap[validator]; ok { - delete(options, validatorSpec) - - switch v.Kind() { - case reflect.String, - reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, - reflect.Float32, reflect.Float64: - field := fmt.Sprint(v) // make value into string, then validate with regex - if result := validatefunc(field); !result && !negate || result && negate { - if customMsgExists { - return false, Error{t.Name, TruncatingErrorf(validatorStruct.customErrorMessage, field, validator), customMsgExists, stripParams(validatorSpec), []string{}} - } - if negate { - return false, Error{t.Name, fmt.Errorf("%s does validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} - } - return false, Error{t.Name, fmt.Errorf("%s does not validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} - } - default: - //Not Yet Supported Types (Fail here!) - err := fmt.Errorf("Validator %s doesn't support kind %s for value %v", validator, v.Kind(), v) - return false, Error{t.Name, err, false, stripParams(validatorSpec), []string{}} - } - } - } - return true, nil - case reflect.Map: - if v.Type().Key().Kind() != reflect.String { - return false, &UnsupportedTypeError{v.Type()} - } - var sv stringValues - sv = v.MapKeys() - sort.Sort(sv) - result := true - for i, k := range sv { - var resultItem bool - var err error - if v.MapIndex(k).Kind() != reflect.Struct { - resultItem, err = typeCheck(v.MapIndex(k), t, o, options) - if err != nil { - return false, err - } - } else { - resultItem, err = ValidateStruct(v.MapIndex(k).Interface()) - if err != nil { - err = prependPathToErrors(err, t.Name+"."+sv[i].Interface().(string)) - return false, err - } - } - result = result && resultItem - } - return result, nil - case reflect.Slice, reflect.Array: - result := true - for i := 0; i < v.Len(); i++ { - var resultItem bool - var err error - if v.Index(i).Kind() != reflect.Struct { - resultItem, err = typeCheck(v.Index(i), t, o, options) - if err != nil { - return false, err - } - } else { - resultItem, err = ValidateStruct(v.Index(i).Interface()) - if err != nil { - err = prependPathToErrors(err, t.Name+"."+strconv.Itoa(i)) - return false, err - } - } - result = result && resultItem - } - return result, nil - case reflect.Interface: - // If the value is an interface then encode its element - if v.IsNil() { - return true, nil - } - return ValidateStruct(v.Interface()) - case reflect.Ptr: - // If the value is a pointer then checks its element - if v.IsNil() { - return true, nil - } - return typeCheck(v.Elem(), t, o, options) - case reflect.Struct: - return true, nil - default: - return false, &UnsupportedTypeError{v.Type()} - } -} - -func stripParams(validatorString string) string { - return paramsRegexp.ReplaceAllString(validatorString, "") -} - -// isEmptyValue checks whether value empty or not -func isEmptyValue(v reflect.Value) bool { - switch v.Kind() { - case reflect.String, reflect.Array: - return v.Len() == 0 - case reflect.Map, reflect.Slice: - return v.Len() == 0 || v.IsNil() - 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 reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) -} - -// ErrorByField returns error for specified field of the struct -// validated by ValidateStruct or empty string if there are no errors -// or this field doesn't exists or doesn't have any errors. -func ErrorByField(e error, field string) string { - if e == nil { - return "" - } - return ErrorsByField(e)[field] -} - -// ErrorsByField returns map of errors of the struct validated -// by ValidateStruct or empty map if there are no errors. -func ErrorsByField(e error) map[string]string { - m := make(map[string]string) - if e == nil { - return m - } - // prototype for ValidateStruct - - switch e := e.(type) { - case Error: - m[e.Name] = e.Err.Error() - case Errors: - for _, item := range e.Errors() { - n := ErrorsByField(item) - for k, v := range n { - m[k] = v - } - } - } - - return m -} - -// Error returns string equivalent for reflect.Type -func (e *UnsupportedTypeError) Error() string { - return "validator: unsupported type: " + e.Type.String() -} - -func (sv stringValues) Len() int { return len(sv) } -func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } -func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) } -func (sv stringValues) get(i int) string { return sv[i].String() } - -func IsE164(str string) bool { - return rxE164.MatchString(str) -} diff --git a/vendor/github.com/asaskevich/govalidator/wercker.yml b/vendor/github.com/asaskevich/govalidator/wercker.yml deleted file mode 100644 index bc5f7b086..000000000 --- a/vendor/github.com/asaskevich/govalidator/wercker.yml +++ /dev/null @@ -1,15 +0,0 @@ -box: golang -build: - steps: - - setup-go-workspace - - - script: - name: go get - code: | - go version - go get -t ./... - - - script: - name: go test - code: | - go test -race -v ./... diff --git a/vendor/github.com/ashanbrown/forbidigo/LICENSE b/vendor/github.com/ashanbrown/forbidigo/LICENSE deleted file mode 100644 index dc1d47ad5..000000000 --- a/vendor/github.com/ashanbrown/forbidigo/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/forbidigo/config_options.go b/vendor/github.com/ashanbrown/forbidigo/forbidigo/config_options.go deleted file mode 100644 index 3f0ed6682..000000000 --- a/vendor/github.com/ashanbrown/forbidigo/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/forbidigo/forbidigo.go b/vendor/github.com/ashanbrown/forbidigo/forbidigo/forbidigo.go deleted file mode 100644 index a7a3ab591..000000000 --- a/vendor/github.com/ashanbrown/forbidigo/forbidigo/forbidigo.go +++ /dev/null @@ -1,398 +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 { - m, p, ok := typeNameWithPackage(typeAndValue.Type) - if !ok { - v.runConfig.DebugLog("%s: selector %q with supported type %T", location, selectorText, typeAndValue.Type) - } - matchTexts = []string{m + "." + field} - pkgText = p - v.runConfig.DebugLog("%s: selector %q with supported type %q: %q -> %q, package %q", location, selectorText, typeAndValue.Type.String(), srcText, matchTexts, pkgText) - } - // 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 { - v.runConfig.DebugLog("%s: selector %q is variable with unsupported type %T", location, selectorText, object.Type()) - } - 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.Named: - obj := t.Obj() - pkg := obj.Pkg() - if pkg == nil { - return "", "", false - } - 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/forbidigo/patterns.go b/vendor/github.com/ashanbrown/forbidigo/forbidigo/patterns.go deleted file mode 100644 index 2692dcd24..000000000 --- a/vendor/github.com/ashanbrown/forbidigo/forbidigo/patterns.go +++ /dev/null @@ -1,127 +0,0 @@ -package forbidigo - -import ( - "fmt" - "regexp" - "regexp/syntax" - "strings" - - "gopkg.in/yaml.v2" -) - -// 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(unmarshal func(interface{}) error) error { - // Try struct first. It's unlikely that a regular expression string - // is valid YAML for a struct. - var ptrn pattern - if err := unmarshal(&ptrn); err != nil { - errStr := err.Error() - // Didn't work, try plain string. - var ptrn string - if err := unmarshal(&ptrn); err != nil { - 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() -} - -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. - if err := yaml.UnmarshalStrict([]byte(ptrn), pattern); err != nil { - 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/LICENSE b/vendor/github.com/ashanbrown/makezero/LICENSE deleted file mode 100644 index dc1d47ad5..000000000 --- a/vendor/github.com/ashanbrown/makezero/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/makezero/makezero.go b/vendor/github.com/ashanbrown/makezero/makezero/makezero.go deleted file mode 100644 index 18bcad3d0..000000000 --- a/vendor/github.com/ashanbrown/makezero/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/beorn7/perks/LICENSE b/vendor/github.com/beorn7/perks/LICENSE deleted file mode 100644 index 339177be6..000000000 --- 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 1602287d7..000000000 --- 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 d7d14f8eb..000000000 --- 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 b4a776a40..000000000 --- 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 eaf408d6f..000000000 --- a/vendor/github.com/bkielbasa/cyclop/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,107 +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 -) - -//nolint:gochecknoinits -func init() { - flagSet.IntVar(&maxComplexity, "maxComplexity", 10, "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: "calculates 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 _, f := range pass.Files { - ast.Inspect(f, func(node ast.Node) bool { - f, 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(f) { - return true - } - - count++ - comp := complexity(f) - sum += float64(comp) - if comp > maxComplexity { - pass.Reportf(node.Pos(), "calculated cyclomatic complexity for function %s is %d, max is %d", f.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 7b6461545..000000000 --- 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 1a4a71669..000000000 --- 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 566572363..000000000 --- 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 c45156a2c..000000000 --- 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 02131ff29..000000000 --- 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 d63c71cfb..000000000 --- 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 ee80774f9..000000000 --- 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 a1f3de99a..000000000 --- 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 7856651b9..000000000 --- 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 68c485c96..000000000 --- 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 a5b960311..000000000 --- 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 b37c69481..000000000 --- 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 bde0ae54e..000000000 --- a/vendor/github.com/bombsimon/wsl/v4/.golangci.yml +++ /dev/null @@ -1,80 +0,0 @@ ---- -run: - timeout: 1m - issues-exit-code: 1 - tests: true - -output: - print-issued-lines: false - sort-results: true - formats: - - format: colored-line-number - -linters-settings: - gocognit: - min-complexity: 10 - - depguard: - rules: - main: - deny: - - pkg: "github.com/davecgh/go-spew/spew" - desc: not allowed - - misspell: - locale: US - - 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 - -linters: - enable-all: true - disable: - - cyclop - - deadcode - - depguard - - dupl - - dupword - - exhaustivestruct - - exhaustruct - - forbidigo - - funlen - - gci - - gocognit - - gocyclo - - godox - - golint - - gomnd - - ifshort - - interfacer - - lll - - maintidx - - maligned - - nakedret - - nestif - - nlreturn - - nosnakecase - - paralleltest - - prealloc - - rowserrcheck - - scopelint - - structcheck - - testpackage - - varcheck - - varnamelen - - wastedassign - -issues: - exclude-use-default: true - max-issues-per-linter: 0 - max-same-issues: 0 - -# 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 4dade6d1c..000000000 --- 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 c9c42341e..000000000 --- a/vendor/github.com/bombsimon/wsl/v4/README.md +++ /dev/null @@ -1,98 +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 - -> **Note**: This linter provides a fixer that can fix most issues with the -> `--fix` flag. However, currently `golangci-lint` [does not support suggested -> fixes](https://github.com/golangci/golangci-lint/issues/1779) so the `--fix` -> flag in `golangci-lint` will **not** work. - -`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 -``` - -## 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). - -> **Note**: this linter doesn't take in consideration the issues that will be -> fixed with `go fmt -s` so ensure that the code is properly formatted before -> use. - -* [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 46d5019a7..000000000 --- a/vendor/github.com/bombsimon/wsl/v4/analyzer.go +++ /dev/null @@ -1,148 +0,0 @@ -package wsl - -import ( - "flag" - "go/ast" - "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, - } -} - -// 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.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) (interface{}, error) { - for _, file := range pass.Files { - if !wa.config.IncludeGenerated && ast.IsGenerated(file) { - continue - } - - filename := pass.Fset.PositionFor(file.Pos(), false).Filename - if !strings.HasSuffix(filename, ".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 { - 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, ", ") -} 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 76f4abf61..000000000 --- a/vendor/github.com/bombsimon/wsl/v4/wsl.go +++ /dev/null @@ -1,1416 +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 -} - -// 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) - } - } - - // We could potentially have a block which require us to check the first - // argument before ruling out an allowed cuddle. - var calledOrAssignedFirstInBlock []string - - if firstBodyStatement != nil { - calledOrAssignedFirstInBlock = 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 := 0; j < n; j++ { - 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, calledOrAssignedFirstInBlock) { - // 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, calledOrAssignedFirstInBlock)) { - 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, calledOrAssignedFirstInBlock) { - 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, calledOrAssignedFirstInBlock) { - 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, calledOrAssignedFirstInBlock) { - continue - } - - if !atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) { - p.addWhitespaceBeforeError(t, reasonDeferCuddledWithOtherVar) - } - case *ast.ForStmt: - if len(rightAndLeftHandSide) == 0 { - 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, calledOrAssignedFirstInBlock) { - 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 { - 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, calledOrAssignedFirstInBlock) { - 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 -} - -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 interface{}) (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.PositionFor(blockStartPos, false).Line - blockEndLine = p.fileSet.PositionFor(blockEndPos, false).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.PositionFor(node.Pos(), false).Line -} - -func (p *processor) nodeEnd(node ast.Node) int { - line := p.fileSet.PositionFor(node.End(), false).Line - - if isEmptyLabeledStmt(node) { - return p.fileSet.PositionFor(node.Pos(), false).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 interface{}) { - position := p.fileSet.PositionFor(pos, false) - - p.warnings = append(p.warnings, - fmt.Sprintf("%s:%d: %s (%T)", position.Filename, position.Line, w, t), - ) -} diff --git a/vendor/github.com/breml/bidichk/LICENSE b/vendor/github.com/breml/bidichk/LICENSE deleted file mode 100644 index 47a8419ce..000000000 --- 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 f1bf20fab..000000000 --- a/vendor/github.com/breml/bidichk/pkg/bidichk/bidichk.go +++ /dev/null @@ -1,180 +0,0 @@ -package bidichk - -import ( - "bytes" - "flag" - "fmt" - "go/token" - "os" - "sort" - "strings" - "unicode/utf8" - - "golang.org/x/tools/go/analysis" -) - -const ( - doc = "bidichk detects 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) { - var err error - - pass.Fset.Iterate(func(f *token.File) bool { - if strings.HasPrefix(f.Name(), "$GOROOT") { - return true - } - - return b.check(f.Name(), f.Pos(0), pass) == nil - }) - - return nil, err -} - -func (b bidichk) check(filename string, pos token.Pos, pass *analysis.Pass) error { - body, err := os.ReadFile(filename) - if err != nil { - return err - } - - 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) - } - } - - return nil -} 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 4cfc57dd1..000000000 --- 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 0362de301..000000000 --- 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 a05c172cb..000000000 --- a/vendor/github.com/breml/errchkjson/.goreleaser.yml +++ /dev/null @@ -1,34 +0,0 @@ -# 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: - name_template: "{{ .Tag }}-next" -changelog: - skip: 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 08db5cb6f..000000000 --- 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 197959738..000000000 --- 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 get github.com/breml/errchkjson/cmd/errchkjson -``` - -## 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 4a23929cf..000000000 --- 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 occations, 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 07b7a07d2..000000000 --- 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 1a38c3f53..000000000 --- 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 77d8ef8bb..000000000 --- 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/bsm/redislock/.golangci.yml b/vendor/github.com/bsm/redislock/.golangci.yml deleted file mode 100644 index 32e00a257..000000000 --- a/vendor/github.com/bsm/redislock/.golangci.yml +++ /dev/null @@ -1,4 +0,0 @@ -linters-settings: - errcheck: - exclude-functions: - - (*github.com/bsm/redislock.Lock).Release diff --git a/vendor/github.com/bsm/redislock/CHANGELOG.md b/vendor/github.com/bsm/redislock/CHANGELOG.md deleted file mode 100644 index ee62aeef6..000000000 --- a/vendor/github.com/bsm/redislock/CHANGELOG.md +++ /dev/null @@ -1,51 +0,0 @@ -## v0.9.3 - -- Feature: allow custom lock tokens [#66](https://github.com/bsm/redislock/pull/66) - -## v0.9.2 - -- Feature: better handling of nil lock.Release() [#68](https://github.com/bsm/redislock/pull/68) - -## v0.9.1 - -- Fix: reset backoff ticker for exponential backoff [#58](https://github.com/bsm/redislock/pull/58) - -# v0.9.0 - -- Chore: use updated go-redis import path [#55](https://github.com/bsm/redislock/pull/55) -- Chore: use redis.v9 GA [#57](https://github.com/bsm/redislock/pull/57) - -## v0.8.2 - -- Fix: use ticker instead of resetting timer [#52](https://github.com/bsm/redislock/pull/52) - -## v0.8.1 - -- Fix: compatibility with redis.v9 [#50](https://github.com/bsm/redislock/pull/50) - -# v0.8.0 - -- Prepare for go-redis/redis v9 release [#49](https://github.com/bsm/redislock/pull/49) - -## v0.7.2 - -- Allow custom deadlines, use stdlib testing package [#35](https://github.com/bsm/redislock/pull/35) -- Reduce deps [#38](https://github.com/bsm/redislock/pull/38) - -## v0.7.1 - -- Make `RetryStrategy` thread-safe to allow re-using `Options` [#31](https://github.com/bsm/redislock/pull/31) [calvinxiao](https://github.com/calvinxiao) -- Improve test-performance, perform race testing on CI [#33](https://github.com/bsm/redislock/pull/33) - -# v0.7.0 - -- Replace Options.Context with explicit ctx parameter [#25](https://github.com/bsm/redislock/pull/25) - -# v0.6.0 - -- Allow to customise retry deadlines through context [#22](https://github.com/bsm/redislock/pull/22) -- Migrate to `github.com/go-redis/redis/v8` [#15](https://github.com/bsm/redislock/pull/15) - -# v0.5.0 - -- Migrate to `github.com/go-redis/redis/v7` [#11](https://github.com/bsm/redislock/pull/11) diff --git a/vendor/github.com/bsm/redislock/LICENSE b/vendor/github.com/bsm/redislock/LICENSE deleted file mode 100644 index aaae5148e..000000000 --- a/vendor/github.com/bsm/redislock/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (c) 2019 Black Square Media - -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/bsm/redislock/Makefile b/vendor/github.com/bsm/redislock/Makefile deleted file mode 100644 index 977292ff7..000000000 --- a/vendor/github.com/bsm/redislock/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -default: test - -test: - go test ./... - -test-race: - go test ./... -race - -lint: - golangci-lint run - -doc: README.md - -README.md: README.md.tpl $(wildcard *.go) - becca -package $(subst $(GOPATH)/src/,,$(PWD)) diff --git a/vendor/github.com/bsm/redislock/README.md b/vendor/github.com/bsm/redislock/README.md deleted file mode 100644 index e0d25bb90..000000000 --- a/vendor/github.com/bsm/redislock/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# redislock - -[![Test](https://github.com/bsm/redislock/actions/workflows/test.yml/badge.svg)](https://github.com/bsm/redislock/actions/workflows/test.yml) -[![GoDoc](https://godoc.org/github.com/bsm/redislock?status.png)](http://godoc.org/github.com/bsm/redislock) -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) - -Simplified distributed locking implementation using [Redis](http://redis.io/topics/distlock). -For more information, please see examples. - -## Examples - -```go -import ( - "context" - "fmt" - "log" - "time" - - "github.com/bsm/redislock" - "github.com/redis/go-redis/v9" -) - -func main() { - // Connect to redis. - client := redis.NewClient(&redis.Options{ - Network: "tcp", - Addr: "127.0.0.1:6379", - }) - defer client.Close() - - // Create a new lock client. - locker := redislock.New(client) - - ctx := context.Background() - - // Try to obtain lock. - lock, err := locker.Obtain(ctx, "my-key", 100*time.Millisecond, nil) - if err == redislock.ErrNotObtained { - fmt.Println("Could not obtain lock!") - } else if err != nil { - log.Fatalln(err) - } - - // Don't forget to defer Release. - defer lock.Release(ctx) - fmt.Println("I have a lock!") - - // Sleep and check the remaining TTL. - time.Sleep(50 * time.Millisecond) - if ttl, err := lock.TTL(ctx); err != nil { - log.Fatalln(err) - } else if ttl > 0 { - fmt.Println("Yay, I still have my lock!") - } - - // Extend my lock. - if err := lock.Refresh(ctx, 100*time.Millisecond, nil); err != nil { - log.Fatalln(err) - } - - // Sleep a little longer, then check. - time.Sleep(100 * time.Millisecond) - if ttl, err := lock.TTL(ctx); err != nil { - log.Fatalln(err) - } else if ttl == 0 { - fmt.Println("Now, my lock has expired!") - } - -} -``` - -## Documentation - -Full documentation is available on [GoDoc](http://godoc.org/github.com/bsm/redislock) diff --git a/vendor/github.com/bsm/redislock/README.md.tpl b/vendor/github.com/bsm/redislock/README.md.tpl deleted file mode 100644 index c29a6ca76..000000000 --- a/vendor/github.com/bsm/redislock/README.md.tpl +++ /dev/null @@ -1,28 +0,0 @@ -# redislock - -[![Test](https://github.com/bsm/redislock/actions/workflows/test.yml/badge.svg)](https://github.com/bsm/redislock/actions/workflows/test.yml) -[![GoDoc](https://godoc.org/github.com/bsm/redislock?status.png)](http://godoc.org/github.com/bsm/redislock) -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) - -Simplified distributed locking implementation using [Redis](http://redis.io/topics/distlock). -For more information, please see examples. - -## Examples - -```go -import ( - "context" - "fmt" - "log" - "time" - - "github.com/bsm/redislock" - "github.com/redis/go-redis/v9" -) - -func main() {{ "Example" | code }} -``` - -## Documentation - -Full documentation is available on [GoDoc](http://godoc.org/github.com/bsm/redislock) diff --git a/vendor/github.com/bsm/redislock/redislock.go b/vendor/github.com/bsm/redislock/redislock.go deleted file mode 100644 index 158d95479..000000000 --- a/vendor/github.com/bsm/redislock/redislock.go +++ /dev/null @@ -1,304 +0,0 @@ -package redislock - -import ( - "context" - "crypto/rand" - "encoding/base64" - "errors" - "io" - "strconv" - "sync" - "sync/atomic" - "time" - - "github.com/redis/go-redis/v9" -) - -var ( - luaRefresh = redis.NewScript(`if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("pexpire", KEYS[1], ARGV[2]) else return 0 end`) - luaRelease = redis.NewScript(`if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end`) - luaPTTL = redis.NewScript(`if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("pttl", KEYS[1]) else return -3 end`) -) - -var ( - // ErrNotObtained is returned when a lock cannot be obtained. - ErrNotObtained = errors.New("redislock: not obtained") - - // ErrLockNotHeld is returned when trying to release an inactive lock. - ErrLockNotHeld = errors.New("redislock: lock not held") -) - -// RedisClient is a minimal client interface. -type RedisClient interface { - redis.Scripter - SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.BoolCmd -} - -// Client wraps a redis client. -type Client struct { - client RedisClient - tmp []byte - tmpMu sync.Mutex -} - -// New creates a new Client instance with a custom namespace. -func New(client RedisClient) *Client { - return &Client{client: client} -} - -// Obtain tries to obtain a new lock using a key with the given TTL. -// May return ErrNotObtained if not successful. -func (c *Client) Obtain(ctx context.Context, key string, ttl time.Duration, opt *Options) (*Lock, error) { - token := opt.getToken() - - // Create a random token - if token == "" { - var err error - if token, err = c.randomToken(); err != nil { - return nil, err - } - } - - value := token + opt.getMetadata() - retry := opt.getRetryStrategy() - - // make sure we don't retry forever - if _, ok := ctx.Deadline(); !ok { - var cancel context.CancelFunc - ctx, cancel = context.WithDeadline(ctx, time.Now().Add(ttl)) - defer cancel() - } - - var ticker *time.Ticker - for { - ok, err := c.obtain(ctx, key, value, ttl) - if err != nil { - return nil, err - } else if ok { - return &Lock{Client: c, key: key, value: value, tokenLen: len(token)}, nil - } - - backoff := retry.NextBackoff() - if backoff < 1 { - return nil, ErrNotObtained - } - - if ticker == nil { - ticker = time.NewTicker(backoff) - defer ticker.Stop() - } else { - ticker.Reset(backoff) - } - - select { - case <-ctx.Done(): - return nil, ctx.Err() - case <-ticker.C: - } - } -} - -func (c *Client) obtain(ctx context.Context, key, value string, ttl time.Duration) (bool, error) { - return c.client.SetNX(ctx, key, value, ttl).Result() -} - -func (c *Client) randomToken() (string, error) { - c.tmpMu.Lock() - defer c.tmpMu.Unlock() - - if len(c.tmp) == 0 { - c.tmp = make([]byte, 16) - } - - if _, err := io.ReadFull(rand.Reader, c.tmp); err != nil { - return "", err - } - return base64.RawURLEncoding.EncodeToString(c.tmp), nil -} - -// -------------------------------------------------------------------- - -// Lock represents an obtained, distributed lock. -type Lock struct { - *Client - key string - value string - tokenLen int -} - -// Obtain is a short-cut for New(...).Obtain(...). -func Obtain(ctx context.Context, client RedisClient, key string, ttl time.Duration, opt *Options) (*Lock, error) { - return New(client).Obtain(ctx, key, ttl, opt) -} - -// Key returns the redis key used by the lock. -func (l *Lock) Key() string { - return l.key -} - -// Token returns the token value set by the lock. -func (l *Lock) Token() string { - return l.value[:l.tokenLen] -} - -// Metadata returns the metadata of the lock. -func (l *Lock) Metadata() string { - return l.value[l.tokenLen:] -} - -// TTL returns the remaining time-to-live. Returns 0 if the lock has expired. -func (l *Lock) TTL(ctx context.Context) (time.Duration, error) { - res, err := luaPTTL.Run(ctx, l.client, []string{l.key}, l.value).Result() - if err == redis.Nil { - return 0, nil - } else if err != nil { - return 0, err - } - - if num := res.(int64); num > 0 { - return time.Duration(num) * time.Millisecond, nil - } - return 0, nil -} - -// Refresh extends the lock with a new TTL. -// May return ErrNotObtained if refresh is unsuccessful. -func (l *Lock) Refresh(ctx context.Context, ttl time.Duration, opt *Options) error { - ttlVal := strconv.FormatInt(int64(ttl/time.Millisecond), 10) - status, err := luaRefresh.Run(ctx, l.client, []string{l.key}, l.value, ttlVal).Result() - if err != nil { - return err - } else if status == int64(1) { - return nil - } - return ErrNotObtained -} - -// Release manually releases the lock. -// May return ErrLockNotHeld. -func (l *Lock) Release(ctx context.Context) error { - if l == nil { - return ErrLockNotHeld - } - - res, err := luaRelease.Run(ctx, l.client, []string{l.key}, l.value).Result() - if err == redis.Nil { - return ErrLockNotHeld - } else if err != nil { - return err - } - - if i, ok := res.(int64); !ok || i != 1 { - return ErrLockNotHeld - } - return nil -} - -// -------------------------------------------------------------------- - -// Options describe the options for the lock -type Options struct { - // RetryStrategy allows to customise the lock retry strategy. - // Default: do not retry - RetryStrategy RetryStrategy - - // Metadata string. - Metadata string - - // Token is a unique value that is used to identify the lock. By default, a random tokens are generated. Use this - // option to provide a custom token instead. - Token string -} - -func (o *Options) getMetadata() string { - if o != nil { - return o.Metadata - } - return "" -} - -func (o *Options) getToken() string { - if o != nil { - return o.Token - } - return "" -} - -func (o *Options) getRetryStrategy() RetryStrategy { - if o != nil && o.RetryStrategy != nil { - return o.RetryStrategy - } - return NoRetry() -} - -// -------------------------------------------------------------------- - -// RetryStrategy allows to customise the lock retry strategy. -type RetryStrategy interface { - // NextBackoff returns the next backoff duration. - NextBackoff() time.Duration -} - -type linearBackoff time.Duration - -// LinearBackoff allows retries regularly with customized intervals -func LinearBackoff(backoff time.Duration) RetryStrategy { - return linearBackoff(backoff) -} - -// NoRetry acquire the lock only once. -func NoRetry() RetryStrategy { - return linearBackoff(0) -} - -func (r linearBackoff) NextBackoff() time.Duration { - return time.Duration(r) -} - -type limitedRetry struct { - s RetryStrategy - cnt int64 - max int64 -} - -// LimitRetry limits the number of retries to max attempts. -func LimitRetry(s RetryStrategy, max int) RetryStrategy { - return &limitedRetry{s: s, max: int64(max)} -} - -func (r *limitedRetry) NextBackoff() time.Duration { - if atomic.LoadInt64(&r.cnt) >= r.max { - return 0 - } - atomic.AddInt64(&r.cnt, 1) - return r.s.NextBackoff() -} - -type exponentialBackoff struct { - cnt uint64 - - min, max time.Duration -} - -// ExponentialBackoff strategy is an optimization strategy with a retry time of 2**n milliseconds (n means number of times). -// You can set a minimum and maximum value, the recommended minimum value is not less than 16ms. -func ExponentialBackoff(min, max time.Duration) RetryStrategy { - return &exponentialBackoff{min: min, max: max} -} - -func (r *exponentialBackoff) NextBackoff() time.Duration { - cnt := atomic.AddUint64(&r.cnt, 1) - - ms := 2 << 25 - if cnt < 25 { - ms = 2 << cnt - } - - if d := time.Duration(ms) * time.Millisecond; d < r.min { - return r.min - } else if r.max != 0 && d > r.max { - return r.max - } else { - return d - } -} diff --git a/vendor/github.com/butuzov/ireturn/LICENSE b/vendor/github.com/butuzov/ireturn/LICENSE deleted file mode 100644 index a9752e972..000000000 --- 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 f68170fb3..000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/analyzer.go +++ /dev/null @@ -1,277 +0,0 @@ -package analyzer - -import ( - "flag" - "go/ast" - gotypes "go/types" - "runtime" - "strings" - "sync" - - "github.com/butuzov/ireturn/analyzer/internal/config" - "github.com/butuzov/ireturn/analyzer/internal/types" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -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 - diabledNolint 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.diabledNolint && 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.diabledNolint = 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{} //nolint: exhaustivestruct - - 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] - } - - 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 36b6fcb4f..000000000 --- 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 6a294ca35..000000000 --- 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, patters 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 46c73170a..000000000 --- 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 6aa04e52e..000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/internal/config/new.go +++ /dev/null @@ -1,74 +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") - -// nolint: exhaustivestruct -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 bef6913bb..000000000 --- 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, patters 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 5e576374d..000000000 --- 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{ //nolint: exhaustivestruct - 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 1092c9667..000000000 --- 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 5c0bd7407..000000000 --- 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 cac464612..000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/std.go +++ /dev/null @@ -1,203 +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": {}, -} diff --git a/vendor/github.com/butuzov/mirror/.editorconfig b/vendor/github.com/butuzov/mirror/.editorconfig deleted file mode 100644 index 4d9c20d8d..000000000 --- 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 109f33b98..000000000 --- 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 fa91fa97e..000000000 --- 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 a9752e972..000000000 --- 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 3dcc01e96..000000000 --- a/vendor/github.com/butuzov/mirror/MIRROR_FUNCS.md +++ /dev/null @@ -1,201 +0,0 @@ - -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.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 ac267208f..000000000 --- a/vendor/github.com/butuzov/mirror/Makefile +++ /dev/null @@ -1,131 +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: ## 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 ./... --skip-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.55.2 (if not exists) -bin/golangci-lint: INSTALL_URL=github.com/golangci/golangci-lint@v1.55.2 -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 Mehtods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -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 "Instaling gawk using brew... " - @ brew install gawk --quiet - @ echo "done" - -_ubuntu_gawk_install: - @ echo "Instaling gawk using apt-get... " - @ apt-get -q install gawk -y - @ echo "done" - -_alpine_gawk_install: - @ echo "Instaling gawk using yum... " - @ apk add --update --no-cache gawk - @ echo "done" - -_centos_gawk_install: - @ echo "Instaling 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 4bc7cfeda..000000000 --- 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 13ded46c6..000000000 --- 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, - BufioMethods, HTTPTestMethods, - OsFileMethods, MaphashMethods, - 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 0985edad3..000000000 --- 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 b8819879c..000000000 --- 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 c28bb1ade..000000000 --- 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 0aa43ff7b..000000000 --- a/vendor/github.com/butuzov/mirror/checkers_maphash.go +++ /dev/null @@ -1,36 +0,0 @@ -package mirror - -import "github.com/butuzov/mirror/internal/checker" - -var 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 40973576b..000000000 --- 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 2cd4dc9f8..000000000 --- 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 3bd59a62f..000000000 --- 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 fd3010c37..000000000 --- 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 c1a941631..000000000 --- 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 standart 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 expresion. -} - -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 convertsion 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 4015de597..000000000 --- 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 3d8acf141..000000000 --- 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 describs 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 dont 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`, bu you can use 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 f830ea72e..000000000 --- a/vendor/github.com/butuzov/mirror/readme.md +++ /dev/null @@ -1,114 +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. - -## 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 confguration `run.skip-files`: - ```yaml - run: - skip-files: - - '(.+)_test\.go' - ``` - - yaml confguration `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) generated -# Run Tests -(task|make) tests -# Lint Code -(task|make) lints -``` diff --git a/vendor/github.com/caarlos0/env/v10/.gitignore b/vendor/github.com/caarlos0/env/v10/.gitignore deleted file mode 100644 index ca6a0ff8c..000000000 --- a/vendor/github.com/caarlos0/env/v10/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -coverage.txt -bin -card.png -dist diff --git a/vendor/github.com/caarlos0/env/v10/.golangci.yml b/vendor/github.com/caarlos0/env/v10/.golangci.yml deleted file mode 100644 index ff791f86e..000000000 --- a/vendor/github.com/caarlos0/env/v10/.golangci.yml +++ /dev/null @@ -1,8 +0,0 @@ -linters: - enable: - - thelper - - gofumpt - - tparallel - - unconvert - - unparam - - wastedassign diff --git a/vendor/github.com/caarlos0/env/v10/.goreleaser.yml b/vendor/github.com/caarlos0/env/v10/.goreleaser.yml deleted file mode 100644 index 4688983c2..000000000 --- a/vendor/github.com/caarlos0/env/v10/.goreleaser.yml +++ /dev/null @@ -1,3 +0,0 @@ -includes: - - from_url: - url: https://raw.githubusercontent.com/caarlos0/.goreleaserfiles/main/lib.yml diff --git a/vendor/github.com/caarlos0/env/v10/.mailmap b/vendor/github.com/caarlos0/env/v10/.mailmap deleted file mode 100644 index eeeee6010..000000000 --- a/vendor/github.com/caarlos0/env/v10/.mailmap +++ /dev/null @@ -1,7 +0,0 @@ -Carlos Alexandro Becker Carlos A Becker -Carlos Alexandro Becker Carlos A Becker -Carlos Alexandro Becker Carlos Alexandro Becker -Carlos Alexandro Becker Carlos Alexandro Becker -Carlos Alexandro Becker Carlos Becker -dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> -actions-user github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> diff --git a/vendor/github.com/caarlos0/env/v10/LICENSE.md b/vendor/github.com/caarlos0/env/v10/LICENSE.md deleted file mode 100644 index 3a59b6b38..000000000 --- a/vendor/github.com/caarlos0/env/v10/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015-2022 Carlos Alexandro Becker - -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/caarlos0/env/v10/Makefile b/vendor/github.com/caarlos0/env/v10/Makefile deleted file mode 100644 index da8595fb9..000000000 --- a/vendor/github.com/caarlos0/env/v10/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -SOURCE_FILES?=./... -TEST_PATTERN?=. - -export GO111MODULE := on - -setup: - go mod tidy -.PHONY: setup - -build: - go build -.PHONY: build - -test: - go test -v -failfast -race -coverpkg=./... -covermode=atomic -coverprofile=coverage.txt $(SOURCE_FILES) -run $(TEST_PATTERN) -timeout=2m -.PHONY: test - -cover: test - go tool cover -html=coverage.txt -.PHONY: cover - -fmt: - gofumpt -w -l . -.PHONY: fmt - -lint: - golangci-lint run ./... -.PHONY: lint - -ci: build test -.PHONY: ci - -card: - wget -O card.png -c "https://og.caarlos0.dev/**env**: parse envs to structs.png?theme=light&md=1&fontSize=100px&images=https://github.com/caarlos0.png" -.PHONY: card - -.DEFAULT_GOAL := ci diff --git a/vendor/github.com/caarlos0/env/v10/README.md b/vendor/github.com/caarlos0/env/v10/README.md deleted file mode 100644 index fcb6342f4..000000000 --- a/vendor/github.com/caarlos0/env/v10/README.md +++ /dev/null @@ -1,610 +0,0 @@ -# env - -[![Build Status](https://img.shields.io/github/actions/workflow/status/caarlos0/env/build.yml?branch=main&style=for-the-badge)](https://github.com/caarlos0/env/actions?workflow=build) -[![Coverage Status](https://img.shields.io/codecov/c/gh/caarlos0/env.svg?logo=codecov&style=for-the-badge)](https://codecov.io/gh/caarlos0/env) -[![](http://img.shields.io/badge/godoc-reference-5272B4.svg?style=for-the-badge)](https://pkg.go.dev/github.com/caarlos0/env/v10) - -A simple and zero-dependencies library to parse environment variables into -`struct`s. - -## Example - -Get the module with: - -```sh -go get github.com/caarlos0/env/v10 -``` - -The usage looks like this: - -```go -package main - -import ( - "fmt" - "time" - - "github.com/caarlos0/env/v10" -) - -type config struct { - Home string `env:"HOME"` - Port int `env:"PORT" envDefault:"3000"` - Password string `env:"PASSWORD,unset"` - IsProduction bool `env:"PRODUCTION"` - Duration time.Duration `env:"DURATION"` - Hosts []string `env:"HOSTS" envSeparator:":"` - TempFolder string `env:"TEMP_FOLDER,expand" envDefault:"${HOME}/tmp"` - StringInts map[string]int `env:"MAP_STRING_INT"` -} - -func main() { - cfg := config{} - if err := env.Parse(&cfg); err != nil { - fmt.Printf("%+v\n", err) - } - - fmt.Printf("%+v\n", cfg) -} -``` - -You can run it like this: - -```sh -$ PRODUCTION=true HOSTS="host1:host2:host3" DURATION=1s MAP_STRING_INT=k1:1,k2:2 go run main.go -{Home:/your/home Port:3000 IsProduction:true Hosts:[host1 host2 host3] Duration:1s StringInts:map[k1:1 k2:2]} -``` - -## Caveats - -> **Warning** -> -> **This is important!** - -- _Unexported fields_ are **ignored** - -## Supported types and defaults - -Out of the box all built-in types are supported, plus a few others that -are commonly used. - -Complete list: - -- `string` -- `bool` -- `int` -- `int8` -- `int16` -- `int32` -- `int64` -- `uint` -- `uint8` -- `uint16` -- `uint32` -- `uint64` -- `float32` -- `float64` -- `time.Duration` -- `encoding.TextUnmarshaler` -- `url.URL` - -Pointers, slices and slices of pointers, and maps of those types are also -supported. - -You can also use/define a [custom parser func](#custom-parser-funcs) for any -other type you want. - -You can also use custom keys and values in your maps, as long as you provide a -parser function for them. - -If you set the `envDefault` tag for something, this value will be used in the -case of absence of it in the environment. - -By default, slice types will split the environment value on `,`; you can change -this behavior by setting the `envSeparator` tag. For map types, the default -separator between key and value is `:` and `,` for key-value pairs. -The behavior can be changed by setting the `envKeyValSeparator` and -`envSeparator` tags accordingly. - -## Custom Parser Funcs - -If you have a type that is not supported out of the box by the lib, you are able -to use (or define) and pass custom parsers (and their associated `reflect.Type`) -to the `env.ParseWithOptions()` function. - -In addition to accepting a struct pointer (same as `Parse()`), this function -also accepts a `Options{}`, and you can set your custom parsers in the `FuncMap` -field. - -If you add a custom parser for, say `Foo`, it will also be used to parse -`*Foo` and `[]Foo` types. - -Check the examples in the [go doc](http://pkg.go.dev/github.com/caarlos0/env/v10) -for more info. - -### A note about `TextUnmarshaler` and `time.Time` - -Env supports by default anything that implements the `TextUnmarshaler` interface. -That includes things like `time.Time` for example. -The upside is that depending on the format you need, you don't need to change -anything. -The downside is that if you do need time in another format, you'll need to -create your own type. - -Its fairly straightforward: - -```go -type MyTime time.Time - -func (t *MyTime) UnmarshalText(text []byte) error { - tt, err := time.Parse("2006-01-02", string(text)) - *t = MyTime(tt) - return err -} - -type Config struct { - SomeTime MyTime `env:"SOME_TIME"` -} -``` - -And then you can parse `Config` with `env.Parse`. - -## Required fields - -The `env` tag option `required` (e.g., `env:"tagKey,required"`) can be added to -ensure that some environment variable is set. In the example above, an error is -returned if the `config` struct is changed to: - -```go -type config struct { - SecretKey string `env:"SECRET_KEY,required"` -} -``` - -> **Warning** -> -> Note that being set is not the same as being empty. -> If the variable is set, but empty, the field will have its type's default -> value. -> This also means that custom parser funcs will not be invoked. - -## Expand vars - -If you set the `expand` option, environment variables (either in `${var}` or -`$var` format) in the string will be replaced according with the actual value -of the variable. For example: - -```go -type config struct { - SecretKey string `env:"SECRET_KEY,expand"` -} -``` - -This also works with `envDefault`: - -```go -import ( - "fmt" - "github.com/caarlos0/env/v10" -) - -type config struct { - Host string `env:"HOST" envDefault:"localhost"` - Port int `env:"PORT" envDefault:"3000"` - Address string `env:"ADDRESS,expand" envDefault:"$HOST:${PORT}"` -} - -func main() { - cfg := config{} - if err := env.Parse(&cfg); err != nil { - fmt.Printf("%+v\n", err) - } - fmt.Printf("%+v\n", cfg) -} -``` - -results in this: - -```sh -$ PORT=8080 go run main.go -{Host:localhost Port:8080 Address:localhost:8080} -``` - -## Not Empty fields - -While `required` demands the environment variable to be set, it doesn't check -its value. If you want to make sure the environment is set and not empty, you -need to use the `notEmpty` tag option instead (`env:"SOME_ENV,notEmpty"`). - -Example: - -```go -type config struct { - SecretKey string `env:"SECRET_KEY,notEmpty"` -} -``` - -## Unset environment variable after reading it - -The `env` tag option `unset` (e.g., `env:"tagKey,unset"`) can be added -to ensure that some environment variable is unset after reading it. - -Example: - -```go -type config struct { - SecretKey string `env:"SECRET_KEY,unset"` -} -``` - -## From file - -The `env` tag option `file` (e.g., `env:"tagKey,file"`) can be added -in order to indicate that the value of the variable shall be loaded from a -file. -The path of that file is given by the environment variable associated with it: - -```go -package main - -import ( - "fmt" - "time" - - "github.com/caarlos0/env/v10" -) - -type config struct { - Secret string `env:"SECRET,file"` - Password string `env:"PASSWORD,file" envDefault:"/tmp/password"` - Certificate string `env:"CERTIFICATE,file,expand" envDefault:"${CERTIFICATE_FILE}"` -} - -func main() { - cfg := config{} - if err := env.Parse(&cfg); err != nil { - fmt.Printf("%+v\n", err) - } - - fmt.Printf("%+v\n", cfg) -} -``` - -```sh -$ echo qwerty > /tmp/secret -$ echo dvorak > /tmp/password -$ echo coleman > /tmp/certificate - -$ SECRET=/tmp/secret \ - CERTIFICATE_FILE=/tmp/certificate \ - go run main.go -{Secret:qwerty Password:dvorak Certificate:coleman} -``` - -## Options - -### Use field names as environment variables by default - -If you don't want to set the `env` tag on every field, you can use the -`UseFieldNameByDefault` option. - -It will use the field name as environment variable name. - -Here's an example: - -```go -package main - -import ( - "fmt" - "log" - - "github.com/caarlos0/env/v10" -) - -type Config struct { - Username string // will use $USERNAME - Password string // will use $PASSWORD - UserFullName string // will use $USER_FULL_NAME -} - -func main() { - cfg := &Config{} - opts := env.Options{UseFieldNameByDefault: true} - - // Load env vars. - if err := env.ParseWithOptions(cfg, opts); err != nil { - log.Fatal(err) - } - - // Print the loaded data. - fmt.Printf("%+v\n", cfg) -} -``` - -### Environment - -By setting the `Options.Environment` map you can tell `Parse` to add those -`keys` and `values` as `env` vars before parsing is done. -These `envs` are stored in the map and never actually set by `os.Setenv`. -This option effectively makes `env` ignore the OS environment variables: only -the ones provided in the option are used. - -This can make your testing scenarios a bit more clean and easy to handle. - -```go -package main - -import ( - "fmt" - "log" - - "github.com/caarlos0/env/v10" -) - -type Config struct { - Password string `env:"PASSWORD"` -} - -func main() { - cfg := &Config{} - opts := env.Options{Environment: map[string]string{ - "PASSWORD": "MY_PASSWORD", - }} - - // Load env vars. - if err := env.ParseWithOptions(cfg, opts); err != nil { - log.Fatal(err) - } - - // Print the loaded data. - fmt.Printf("%+v\n", cfg) -} -``` - -### Changing default tag name - -You can change what tag name to use for setting the env vars by setting the -`Options.TagName` variable. - -For example - -```go -package main - -import ( - "fmt" - "log" - - "github.com/caarlos0/env/v10" -) - -type Config struct { - Password string `json:"PASSWORD"` -} - -func main() { - cfg := &Config{} - opts := env.Options{TagName: "json"} - - // Load env vars. - if err := env.ParseWithOptions(cfg, opts); err != nil { - log.Fatal(err) - } - - // Print the loaded data. - fmt.Printf("%+v\n", cfg) -} -``` - -### Prefixes - -You can prefix sub-structs env tags, as well as a whole `env.Parse` call. - -Here's an example flexing it a bit: - -```go -package main - -import ( - "fmt" - "log" - - "github.com/caarlos0/env/v10" -) - -type Config struct { - Home string `env:"HOME"` -} - -type ComplexConfig struct { - Foo Config `envPrefix:"FOO_"` - Clean Config - Bar Config `envPrefix:"BAR_"` - Blah string `env:"BLAH"` -} - -func main() { - cfg := &ComplexConfig{} - opts := env.Options{ - Prefix: "T_", - Environment: map[string]string{ - "T_FOO_HOME": "/foo", - "T_BAR_HOME": "/bar", - "T_BLAH": "blahhh", - "T_HOME": "/clean", - }, - } - - // Load env vars. - if err := env.ParseWithOptions(cfg, opts); err != nil { - log.Fatal(err) - } - - // Print the loaded data. - fmt.Printf("%+v\n", cfg) -} -``` - -### On set hooks - -You might want to listen to value sets and, for example, log something or do -some other kind of logic. -You can do this by passing a `OnSet` option: - -```go -package main - -import ( - "fmt" - "log" - - "github.com/caarlos0/env/v10" -) - -type Config struct { - Username string `env:"USERNAME" envDefault:"admin"` - Password string `env:"PASSWORD"` -} - -func main() { - cfg := &Config{} - opts := env.Options{ - OnSet: func(tag string, value interface{}, isDefault bool) { - fmt.Printf("Set %s to %v (default? %v)\n", tag, value, isDefault) - }, - } - - // Load env vars. - if err := env.ParseWithOptions(cfg, opts); err != nil { - log.Fatal(err) - } - - // Print the loaded data. - fmt.Printf("%+v\n", cfg) -} -``` - -## Making all fields to required - -You can make all fields that don't have a default value be required by setting -the `RequiredIfNoDef: true` in the `Options`. - -For example - -```go -package main - -import ( - "fmt" - "log" - - "github.com/caarlos0/env/v10" -) - -type Config struct { - Username string `env:"USERNAME" envDefault:"admin"` - Password string `env:"PASSWORD"` -} - -func main() { - cfg := &Config{} - opts := env.Options{RequiredIfNoDef: true} - - // Load env vars. - if err := env.ParseWithOptions(cfg, opts); err != nil { - log.Fatal(err) - } - - // Print the loaded data. - fmt.Printf("%+v\n", cfg) -} -``` - -## Defaults from code - -You may define default value also in code, by initialising the config data -before it's filled by `env.Parse`. -Default values defined as struct tags will overwrite existing values during -Parse. - -```go -package main - -import ( - "fmt" - "log" - - "github.com/caarlos0/env/v10" -) - -type Config struct { - Username string `env:"USERNAME" envDefault:"admin"` - Password string `env:"PASSWORD"` -} - -func main() { - cfg := Config{ - Username: "test", - Password: "123456", - } - - if err := env.Parse(&cfg); err != nil { - fmt.Println("failed:", err) - } - - fmt.Printf("%+v", cfg) // {Username:admin Password:123456} -} -``` - -## Error handling - -You can handle the errors the library throws like so: - -```go -package main - -import ( - "fmt" - "log" - - "github.com/caarlos0/env/v10" -) - -type Config struct { - Username string `env:"USERNAME" envDefault:"admin"` - Password string `env:"PASSWORD"` -} - -func main() { - var cfg Config - err := env.Parse(&cfg) - if e, ok := err.(*env.AggregateError); ok { - for _, er := range e.Errors { - switch v := er.(type) { - case env.ParseError: - // handle it - case env.NotStructPtrError: - // handle it - case env.NoParserError: - // handle it - case env.NoSupportedTagOptionError: - // handle it - default: - fmt.Printf("Unknown error type %v", v) - } - } - } - - fmt.Printf("%+v", cfg) // {Username:admin Password:123456} -} -``` - -> **Info** -> -> If you want to check if an specific error is in the chain, you can also use -> `errors.Is()`. - -## Stargazers over time - -[![Stargazers over time](https://starchart.cc/caarlos0/env.svg)](https://starchart.cc/caarlos0/env) diff --git a/vendor/github.com/caarlos0/env/v10/env.go b/vendor/github.com/caarlos0/env/v10/env.go deleted file mode 100644 index 5c9d806c1..000000000 --- a/vendor/github.com/caarlos0/env/v10/env.go +++ /dev/null @@ -1,614 +0,0 @@ -package env - -import ( - "encoding" - "fmt" - "net/url" - "os" - "reflect" - "strconv" - "strings" - "time" - "unicode" -) - -// nolint: gochecknoglobals -var ( - defaultBuiltInParsers = map[reflect.Kind]ParserFunc{ - reflect.Bool: func(v string) (interface{}, error) { - return strconv.ParseBool(v) - }, - reflect.String: func(v string) (interface{}, error) { - return v, nil - }, - reflect.Int: func(v string) (interface{}, error) { - i, err := strconv.ParseInt(v, 10, 32) - return int(i), err - }, - reflect.Int16: func(v string) (interface{}, error) { - i, err := strconv.ParseInt(v, 10, 16) - return int16(i), err - }, - reflect.Int32: func(v string) (interface{}, error) { - i, err := strconv.ParseInt(v, 10, 32) - return int32(i), err - }, - reflect.Int64: func(v string) (interface{}, error) { - return strconv.ParseInt(v, 10, 64) - }, - reflect.Int8: func(v string) (interface{}, error) { - i, err := strconv.ParseInt(v, 10, 8) - return int8(i), err - }, - reflect.Uint: func(v string) (interface{}, error) { - i, err := strconv.ParseUint(v, 10, 32) - return uint(i), err - }, - reflect.Uint16: func(v string) (interface{}, error) { - i, err := strconv.ParseUint(v, 10, 16) - return uint16(i), err - }, - reflect.Uint32: func(v string) (interface{}, error) { - i, err := strconv.ParseUint(v, 10, 32) - return uint32(i), err - }, - reflect.Uint64: func(v string) (interface{}, error) { - i, err := strconv.ParseUint(v, 10, 64) - return i, err - }, - reflect.Uint8: func(v string) (interface{}, error) { - i, err := strconv.ParseUint(v, 10, 8) - return uint8(i), err - }, - reflect.Float64: func(v string) (interface{}, error) { - return strconv.ParseFloat(v, 64) - }, - reflect.Float32: func(v string) (interface{}, error) { - f, err := strconv.ParseFloat(v, 32) - return float32(f), err - }, - } -) - -func defaultTypeParsers() map[reflect.Type]ParserFunc { - return map[reflect.Type]ParserFunc{ - reflect.TypeOf(url.URL{}): func(v string) (interface{}, error) { - u, err := url.Parse(v) - if err != nil { - return nil, newParseValueError("unable to parse URL", err) - } - return *u, nil - }, - reflect.TypeOf(time.Nanosecond): func(v string) (interface{}, error) { - s, err := time.ParseDuration(v) - if err != nil { - return nil, newParseValueError("unable to parse duration", err) - } - return s, err - }, - } -} - -// ParserFunc defines the signature of a function that can be used within `CustomParsers`. -type ParserFunc func(v string) (interface{}, error) - -// OnSetFn is a hook that can be run when a value is set. -type OnSetFn func(tag string, value interface{}, isDefault bool) - -// processFieldFn is a function which takes all information about a field and processes it. -type processFieldFn func(refField reflect.Value, refTypeField reflect.StructField, opts Options, fieldParams FieldParams) error - -// Options for the parser. -type Options struct { - // Environment keys and values that will be accessible for the service. - Environment map[string]string - - // TagName specifies another tagname to use rather than the default env. - TagName string - - // RequiredIfNoDef automatically sets all env as required if they do not - // declare 'envDefault'. - RequiredIfNoDef bool - - // OnSet allows to run a function when a value is set. - OnSet OnSetFn - - // Prefix define a prefix for each key. - Prefix string - - // UseFieldNameByDefault defines whether or not env should use the field - // name by default if the `env` key is missing. - UseFieldNameByDefault bool - - // Custom parse functions for different types. - FuncMap map[reflect.Type]ParserFunc - - // Used internally. maps the env variable key to its resolved string value. (for env var expansion) - rawEnvVars map[string]string -} - -func (opts *Options) getRawEnv(s string) string { - val := opts.rawEnvVars[s] - if val == "" { - return opts.Environment[s] - } - return val -} - -func defaultOptions() Options { - return Options{ - TagName: "env", - Environment: toMap(os.Environ()), - FuncMap: defaultTypeParsers(), - rawEnvVars: make(map[string]string), - } -} - -func customOptions(opt Options) Options { - defOpts := defaultOptions() - if opt.TagName == "" { - opt.TagName = defOpts.TagName - } - if opt.Environment == nil { - opt.Environment = defOpts.Environment - } - if opt.FuncMap == nil { - opt.FuncMap = map[reflect.Type]ParserFunc{} - } - if opt.rawEnvVars == nil { - opt.rawEnvVars = defOpts.rawEnvVars - } - for k, v := range defOpts.FuncMap { - if _, exists := opt.FuncMap[k]; !exists { - opt.FuncMap[k] = v - } - } - return opt -} - -func optionsWithEnvPrefix(field reflect.StructField, opts Options) Options { - return Options{ - Environment: opts.Environment, - TagName: opts.TagName, - RequiredIfNoDef: opts.RequiredIfNoDef, - OnSet: opts.OnSet, - Prefix: opts.Prefix + field.Tag.Get("envPrefix"), - UseFieldNameByDefault: opts.UseFieldNameByDefault, - FuncMap: opts.FuncMap, - rawEnvVars: opts.rawEnvVars, - } -} - -// Parse parses a struct containing `env` tags and loads its values from -// environment variables. -func Parse(v interface{}) error { - return parseInternal(v, setField, defaultOptions()) -} - -// ParseWithOptions parses a struct containing `env` tags and loads its values from -// environment variables. -func ParseWithOptions(v interface{}, opts Options) error { - return parseInternal(v, setField, customOptions(opts)) -} - -// GetFieldParams parses a struct containing `env` tags and returns information about -// tags it found. -func GetFieldParams(v interface{}) ([]FieldParams, error) { - return GetFieldParamsWithOptions(v, defaultOptions()) -} - -// GetFieldParamsWithOptions parses a struct containing `env` tags and returns information about -// tags it found. -func GetFieldParamsWithOptions(v interface{}, opts Options) ([]FieldParams, error) { - var result []FieldParams - err := parseInternal( - v, - func(_ reflect.Value, _ reflect.StructField, _ Options, fieldParams FieldParams) error { - if fieldParams.OwnKey != "" { - result = append(result, fieldParams) - } - return nil - }, - customOptions(opts), - ) - if err != nil { - return nil, err - } - - return result, nil -} - -func parseInternal(v interface{}, processField processFieldFn, opts Options) error { - ptrRef := reflect.ValueOf(v) - if ptrRef.Kind() != reflect.Ptr { - return newAggregateError(NotStructPtrError{}) - } - ref := ptrRef.Elem() - if ref.Kind() != reflect.Struct { - return newAggregateError(NotStructPtrError{}) - } - - return doParse(ref, processField, opts) -} - -func doParse(ref reflect.Value, processField processFieldFn, opts Options) error { - refType := ref.Type() - - var agrErr AggregateError - - for i := 0; i < refType.NumField(); i++ { - refField := ref.Field(i) - refTypeField := refType.Field(i) - - if err := doParseField(refField, refTypeField, processField, opts); err != nil { - if val, ok := err.(AggregateError); ok { - agrErr.Errors = append(agrErr.Errors, val.Errors...) - } else { - agrErr.Errors = append(agrErr.Errors, err) - } - } - } - - if len(agrErr.Errors) == 0 { - return nil - } - - return agrErr -} - -func doParseField(refField reflect.Value, refTypeField reflect.StructField, processField processFieldFn, opts Options) error { - if !refField.CanSet() { - return nil - } - if reflect.Ptr == refField.Kind() && !refField.IsNil() { - return parseInternal(refField.Interface(), processField, optionsWithEnvPrefix(refTypeField, opts)) - } - if reflect.Struct == refField.Kind() && refField.CanAddr() && refField.Type().Name() == "" { - return parseInternal(refField.Addr().Interface(), processField, optionsWithEnvPrefix(refTypeField, opts)) - } - - params, err := parseFieldParams(refTypeField, opts) - if err != nil { - return err - } - - if err := processField(refField, refTypeField, opts, params); err != nil { - return err - } - - if reflect.Struct == refField.Kind() { - return doParse(refField, processField, optionsWithEnvPrefix(refTypeField, opts)) - } - - return nil -} - -func setField(refField reflect.Value, refTypeField reflect.StructField, opts Options, fieldParams FieldParams) error { - value, err := get(fieldParams, opts) - if err != nil { - return err - } - - if value != "" { - return set(refField, refTypeField, value, opts.FuncMap) - } - - return nil -} - -const underscore rune = '_' - -func toEnvName(input string) string { - var output []rune - for i, c := range input { - if i > 0 && output[i-1] != underscore && c != underscore && unicode.ToUpper(c) == c { - output = append(output, underscore) - } - output = append(output, unicode.ToUpper(c)) - } - return string(output) -} - -// FieldParams contains information about parsed field tags. -type FieldParams struct { - OwnKey string - Key string - DefaultValue string - HasDefaultValue bool - Required bool - LoadFile bool - Unset bool - NotEmpty bool - Expand bool -} - -func parseFieldParams(field reflect.StructField, opts Options) (FieldParams, error) { - ownKey, tags := parseKeyForOption(field.Tag.Get(opts.TagName)) - if ownKey == "" && opts.UseFieldNameByDefault { - ownKey = toEnvName(field.Name) - } - - defaultValue, hasDefaultValue := field.Tag.Lookup("envDefault") - - result := FieldParams{ - OwnKey: ownKey, - Key: opts.Prefix + ownKey, - Required: opts.RequiredIfNoDef, - DefaultValue: defaultValue, - HasDefaultValue: hasDefaultValue, - } - - for _, tag := range tags { - switch tag { - case "": - continue - case "file": - result.LoadFile = true - case "required": - result.Required = true - case "unset": - result.Unset = true - case "notEmpty": - result.NotEmpty = true - case "expand": - result.Expand = true - default: - return FieldParams{}, newNoSupportedTagOptionError(tag) - } - } - - return result, nil -} - -func get(fieldParams FieldParams, opts Options) (val string, err error) { - var exists, isDefault bool - - val, exists, isDefault = getOr(fieldParams.Key, fieldParams.DefaultValue, fieldParams.HasDefaultValue, opts.Environment) - - if fieldParams.Expand { - val = os.Expand(val, opts.getRawEnv) - } - - opts.rawEnvVars[fieldParams.OwnKey] = val - - if fieldParams.Unset { - defer os.Unsetenv(fieldParams.Key) - } - - if fieldParams.Required && !exists && len(fieldParams.OwnKey) > 0 { - return "", newEnvVarIsNotSet(fieldParams.Key) - } - - if fieldParams.NotEmpty && val == "" { - return "", newEmptyEnvVarError(fieldParams.Key) - } - - if fieldParams.LoadFile && val != "" { - filename := val - val, err = getFromFile(filename) - if err != nil { - return "", newLoadFileContentError(filename, fieldParams.Key, err) - } - } - - if opts.OnSet != nil { - if fieldParams.OwnKey != "" { - opts.OnSet(fieldParams.Key, val, isDefault) - } - } - return val, err -} - -// split the env tag's key into the expected key and desired option, if any. -func parseKeyForOption(key string) (string, []string) { - opts := strings.Split(key, ",") - return opts[0], opts[1:] -} - -func getFromFile(filename string) (value string, err error) { - b, err := os.ReadFile(filename) - return string(b), err -} - -func getOr(key, defaultValue string, defExists bool, envs map[string]string) (val string, exists bool, isDefault bool) { - value, exists := envs[key] - switch { - case (!exists || key == "") && defExists: - return defaultValue, true, true - case exists && value == "" && defExists: - return defaultValue, true, true - case !exists: - return "", false, false - } - - return value, true, false -} - -func set(field reflect.Value, sf reflect.StructField, value string, funcMap map[reflect.Type]ParserFunc) error { - if tm := asTextUnmarshaler(field); tm != nil { - if err := tm.UnmarshalText([]byte(value)); err != nil { - return newParseError(sf, err) - } - return nil - } - - typee := sf.Type - fieldee := field - if typee.Kind() == reflect.Ptr { - typee = typee.Elem() - fieldee = field.Elem() - } - - parserFunc, ok := funcMap[typee] - if ok { - val, err := parserFunc(value) - if err != nil { - return newParseError(sf, err) - } - - fieldee.Set(reflect.ValueOf(val)) - return nil - } - - parserFunc, ok = defaultBuiltInParsers[typee.Kind()] - if ok { - val, err := parserFunc(value) - if err != nil { - return newParseError(sf, err) - } - - fieldee.Set(reflect.ValueOf(val).Convert(typee)) - return nil - } - - switch field.Kind() { - case reflect.Slice: - return handleSlice(field, value, sf, funcMap) - case reflect.Map: - return handleMap(field, value, sf, funcMap) - } - - return newNoParserError(sf) -} - -func handleSlice(field reflect.Value, value string, sf reflect.StructField, funcMap map[reflect.Type]ParserFunc) error { - separator := sf.Tag.Get("envSeparator") - if separator == "" { - separator = "," - } - parts := strings.Split(value, separator) - - typee := sf.Type.Elem() - if typee.Kind() == reflect.Ptr { - typee = typee.Elem() - } - - if _, ok := reflect.New(typee).Interface().(encoding.TextUnmarshaler); ok { - return parseTextUnmarshalers(field, parts, sf) - } - - parserFunc, ok := funcMap[typee] - if !ok { - parserFunc, ok = defaultBuiltInParsers[typee.Kind()] - if !ok { - return newNoParserError(sf) - } - } - - result := reflect.MakeSlice(sf.Type, 0, len(parts)) - for _, part := range parts { - r, err := parserFunc(part) - if err != nil { - return newParseError(sf, err) - } - v := reflect.ValueOf(r).Convert(typee) - if sf.Type.Elem().Kind() == reflect.Ptr { - v = reflect.New(typee) - v.Elem().Set(reflect.ValueOf(r).Convert(typee)) - } - result = reflect.Append(result, v) - } - field.Set(result) - return nil -} - -func handleMap(field reflect.Value, value string, sf reflect.StructField, funcMap map[reflect.Type]ParserFunc) error { - keyType := sf.Type.Key() - keyParserFunc, ok := funcMap[keyType] - if !ok { - keyParserFunc, ok = defaultBuiltInParsers[keyType.Kind()] - if !ok { - return newNoParserError(sf) - } - } - - elemType := sf.Type.Elem() - elemParserFunc, ok := funcMap[elemType] - if !ok { - elemParserFunc, ok = defaultBuiltInParsers[elemType.Kind()] - if !ok { - return newNoParserError(sf) - } - } - - separator := sf.Tag.Get("envSeparator") - if separator == "" { - separator = "," - } - - keyValSeparator := sf.Tag.Get("envKeyValSeparator") - if keyValSeparator == "" { - keyValSeparator = ":" - } - - result := reflect.MakeMap(sf.Type) - for _, part := range strings.Split(value, separator) { - pairs := strings.Split(part, keyValSeparator) - if len(pairs) != 2 { - return newParseError(sf, fmt.Errorf(`%q should be in "key%svalue" format`, part, keyValSeparator)) - } - - key, err := keyParserFunc(pairs[0]) - if err != nil { - return newParseError(sf, err) - } - - elem, err := elemParserFunc(pairs[1]) - if err != nil { - return newParseError(sf, err) - } - - result.SetMapIndex(reflect.ValueOf(key).Convert(keyType), reflect.ValueOf(elem).Convert(elemType)) - } - - field.Set(result) - return nil -} - -func asTextUnmarshaler(field reflect.Value) encoding.TextUnmarshaler { - if reflect.Ptr == field.Kind() { - if field.IsNil() { - field.Set(reflect.New(field.Type().Elem())) - } - } else if field.CanAddr() { - field = field.Addr() - } - - tm, ok := field.Interface().(encoding.TextUnmarshaler) - if !ok { - return nil - } - return tm -} - -func parseTextUnmarshalers(field reflect.Value, data []string, sf reflect.StructField) error { - s := len(data) - elemType := field.Type().Elem() - slice := reflect.MakeSlice(reflect.SliceOf(elemType), s, s) - for i, v := range data { - sv := slice.Index(i) - kind := sv.Kind() - if kind == reflect.Ptr { - sv = reflect.New(elemType.Elem()) - } else { - sv = sv.Addr() - } - tm := sv.Interface().(encoding.TextUnmarshaler) - if err := tm.UnmarshalText([]byte(v)); err != nil { - return newParseError(sf, err) - } - if kind == reflect.Ptr { - slice.Index(i).Set(sv) - } - } - - field.Set(slice) - - return nil -} - -// ToMap Converts list of env vars as provided by os.Environ() to map you -// can use as Options.Environment field -func ToMap(env []string) map[string]string { - return toMap(env) -} diff --git a/vendor/github.com/caarlos0/env/v10/env_tomap.go b/vendor/github.com/caarlos0/env/v10/env_tomap.go deleted file mode 100644 index aece2ae9a..000000000 --- a/vendor/github.com/caarlos0/env/v10/env_tomap.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build !windows - -package env - -import "strings" - -func toMap(env []string) map[string]string { - r := map[string]string{} - for _, e := range env { - p := strings.SplitN(e, "=", 2) - if len(p) == 2 { - r[p[0]] = p[1] - } - } - return r -} diff --git a/vendor/github.com/caarlos0/env/v10/env_tomap_windows.go b/vendor/github.com/caarlos0/env/v10/env_tomap_windows.go deleted file mode 100644 index 04ce66f57..000000000 --- a/vendor/github.com/caarlos0/env/v10/env_tomap_windows.go +++ /dev/null @@ -1,29 +0,0 @@ -//go:build windows - -package env - -import "strings" - -func toMap(env []string) map[string]string { - r := map[string]string{} - for _, e := range env { - p := strings.SplitN(e, "=", 2) - - // On Windows, environment variables can start with '='. If so, Split at next character. - // See env_windows.go in the Go source: https://github.com/golang/go/blob/master/src/syscall/env_windows.go#L58 - prefixEqualSign := false - if len(e) > 0 && e[0] == '=' { - e = e[1:] - prefixEqualSign = true - } - p = strings.SplitN(e, "=", 2) - if prefixEqualSign { - p[0] = "=" + p[0] - } - - if len(p) == 2 { - r[p[0]] = p[1] - } - } - return r -} diff --git a/vendor/github.com/caarlos0/env/v10/error.go b/vendor/github.com/caarlos0/env/v10/error.go deleted file mode 100644 index 156ca3ec9..000000000 --- a/vendor/github.com/caarlos0/env/v10/error.go +++ /dev/null @@ -1,164 +0,0 @@ -package env - -import ( - "fmt" - "reflect" - "strings" -) - -// An aggregated error wrapper to combine gathered errors. This allows either to display all errors or convert them individually -// List of the available errors -// ParseError -// NotStructPtrError -// NoParserError -// NoSupportedTagOptionError -// EnvVarIsNotSetError -// EmptyEnvVarError -// LoadFileContentError -// ParseValueError -type AggregateError struct { - Errors []error -} - -func newAggregateError(initErr error) error { - return AggregateError{ - []error{ - initErr, - }, - } -} - -func (e AggregateError) Error() string { - var sb strings.Builder - - sb.WriteString("env:") - - for _, err := range e.Errors { - sb.WriteString(fmt.Sprintf(" %v;", err.Error())) - } - - return strings.TrimRight(sb.String(), ";") -} - -// Is conforms with errors.Is. -func (e AggregateError) Is(err error) bool { - for _, ie := range e.Errors { - if reflect.TypeOf(ie) == reflect.TypeOf(err) { - return true - } - } - return false -} - -// The error occurs when it's impossible to convert the value for given type. -type ParseError struct { - Name string - Type reflect.Type - Err error -} - -func newParseError(sf reflect.StructField, err error) error { - return ParseError{sf.Name, sf.Type, err} -} - -func (e ParseError) Error() string { - return fmt.Sprintf(`parse error on field "%s" of type "%s": %v`, e.Name, e.Type, e.Err) -} - -// The error occurs when pass something that is not a pointer to a Struct to Parse -type NotStructPtrError struct{} - -func (e NotStructPtrError) Error() string { - return "expected a pointer to a Struct" -} - -// This error occurs when there is no parser provided for given type -// Supported types and defaults: https://github.com/caarlos0/env#supported-types-and-defaults -// How to create a custom parser: https://github.com/caarlos0/env#custom-parser-funcs -type NoParserError struct { - Name string - Type reflect.Type -} - -func newNoParserError(sf reflect.StructField) error { - return NoParserError{sf.Name, sf.Type} -} - -func (e NoParserError) Error() string { - return fmt.Sprintf(`no parser found for field "%s" of type "%s"`, e.Name, e.Type) -} - -// This error occurs when the given tag is not supported -// In-built supported tags: "", "file", "required", "unset", "notEmpty", "expand", "envDefault", "envSeparator" -// How to create a custom tag: https://github.com/caarlos0/env#changing-default-tag-name -type NoSupportedTagOptionError struct { - Tag string -} - -func newNoSupportedTagOptionError(tag string) error { - return NoSupportedTagOptionError{tag} -} - -func (e NoSupportedTagOptionError) Error() string { - return fmt.Sprintf("tag option %q not supported", e.Tag) -} - -// This error occurs when the required variable is not set -// Read about required fields: https://github.com/caarlos0/env#required-fields -type EnvVarIsNotSetError struct { - Key string -} - -func newEnvVarIsNotSet(key string) error { - return EnvVarIsNotSetError{key} -} - -func (e EnvVarIsNotSetError) Error() string { - return fmt.Sprintf(`required environment variable %q is not set`, e.Key) -} - -// This error occurs when the variable which must be not empty is existing but has an empty value -// Read about not empty fields: https://github.com/caarlos0/env#not-empty-fields -type EmptyEnvVarError struct { - Key string -} - -func newEmptyEnvVarError(key string) error { - return EmptyEnvVarError{key} -} - -func (e EmptyEnvVarError) Error() string { - return fmt.Sprintf("environment variable %q should not be empty", e.Key) -} - -// This error occurs when it's impossible to load the value from the file -// Read about From file feature: https://github.com/caarlos0/env#from-file -type LoadFileContentError struct { - Filename string - Key string - Err error -} - -func newLoadFileContentError(filename, key string, err error) error { - return LoadFileContentError{filename, key, err} -} - -func (e LoadFileContentError) Error() string { - return fmt.Sprintf(`could not load content of file "%s" from variable %s: %v`, e.Filename, e.Key, e.Err) -} - -// This error occurs when it's impossible to convert value using given parser -// Supported types and defaults: https://github.com/caarlos0/env#supported-types-and-defaults -// How to create a custom parser: https://github.com/caarlos0/env#custom-parser-funcs -type ParseValueError struct { - Msg string - Err error -} - -func newParseValueError(message string, err error) error { - return ParseValueError{message, err} -} - -func (e ParseValueError) Error() string { - return fmt.Sprintf("%s: %v", e.Msg, e.Err) -} diff --git a/vendor/github.com/catenacyber/perfsprint/LICENSE b/vendor/github.com/catenacyber/perfsprint/LICENSE deleted file mode 100644 index 14c2b9e73..000000000 --- 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 543b4bdbc..000000000 --- a/vendor/github.com/catenacyber/perfsprint/analyzer/analyzer.go +++ /dev/null @@ -1,603 +0,0 @@ -package analyzer - -import ( - "bytes" - "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 perfSprint struct { - intConv bool - errError bool - errorf bool - sprintf1 bool - fiximports bool - strconcat bool -} - -func newPerfSprint() *perfSprint { - return &perfSprint{ - intConv: true, - errError: false, - errorf: true, - sprintf1: true, - fiximports: true, - strconcat: true, - } -} - -func New() *analysis.Analyzer { - n := newPerfSprint() - r := &analysis.Analyzer{ - Name: "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.intConv, "int-conversion", true, "optimizes even if it requires an int or uint type cast") - r.Flags.BoolVar(&n.errError, "err-error", false, "optimizes into err.Error() even if it is only equivalent for non-nil errors") - r.Flags.BoolVar(&n.errorf, "errorf", true, "optimizes fmt.Errorf") - r.Flags.BoolVar(&n.sprintf1, "sprintf1", true, "optimizes fmt.Sprintf with only one argument") - r.Flags.BoolVar(&n.fiximports, "fiximports", true, "fix needed imports from other fixes") - r.Flags.BoolVar(&n.strconcat, "strconcat", true, "optimizes into strings concatenation") - 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 (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) { - 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 { - return nil, nil - } - removedFmtUsages := make(map[string]int) - neededPackages := make(map[string]map[string]bool) - - 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: - if n.errorf { - fn = "fmt.Errorf" - verb = "%s" - value = call.Args[0] - } else { - return - } - - case calledObj == fmtSprintObj && len(call.Args) == 1: - fn = "fmt.Sprint" - verb = "%v" - value = call.Args[0] - - case calledObj == fmtSprintfObj && len(call.Args) == 1: - if n.sprintf1 { - fn = "fmt.Sprintf" - verb = "%s" - value = call.Args[0] - } else { - return - } - - 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.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() - _, ok := neededPackages[fname] - if !ok { - neededPackages[fname] = make(map[string]bool) - } - removedFmtUsages[fname]++ - if fn == "fmt.Errorf" { - neededPackages[fname]["errors"] = true - d = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with errors.New", - SuggestedFixes: []analysis.SuggestedFix{ - { - Message: "Use errors.New", - TextEdits: []analysis.TextEdit{{ - Pos: call.Pos(), - End: value.Pos(), - NewText: []byte("errors.New("), - }}, - }, - }, - } - } else { - d = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with just using the string", - SuggestedFixes: []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.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 = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with " + errMethodCall, - SuggestedFixes: []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"): - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - _, ok := neededPackages[fname] - if !ok { - neededPackages[fname] = make(map[string]bool) - } - neededPackages[fname]["strconv"] = true - d = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with faster strconv.FormatBool", - SuggestedFixes: []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"): - if _, ok := value.(*ast.Ident); !ok { - // Doesn't support array literals. - return - } - - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - _, ok := neededPackages[fname] - if !ok { - neededPackages[fname] = make(map[string]bool) - } - neededPackages[fname]["encoding/hex"] = true - d = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with faster hex.EncodeToString", - SuggestedFixes: []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"): - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - _, ok := neededPackages[fname] - if !ok { - neededPackages[fname] = make(map[string]bool) - } - neededPackages[fname]["encoding/hex"] = true - d = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with faster hex.EncodeToString", - SuggestedFixes: []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.intConv: - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - _, ok := neededPackages[fname] - if !ok { - neededPackages[fname] = make(map[string]bool) - } - neededPackages[fname]["strconv"] = true - d = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with faster strconv.Itoa", - SuggestedFixes: []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"): - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - _, ok := neededPackages[fname] - if !ok { - neededPackages[fname] = make(map[string]bool) - } - neededPackages[fname]["strconv"] = true - d = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with faster strconv.Itoa", - SuggestedFixes: []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"): - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - _, ok := neededPackages[fname] - if !ok { - neededPackages[fname] = make(map[string]bool) - } - neededPackages[fname]["strconv"] = true - d = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with faster strconv.FormatInt", - SuggestedFixes: []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.intConv: - base := []byte("), 10") - if verb == "%x" { - base = []byte("), 16") - } - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - _, ok := neededPackages[fname] - if !ok { - neededPackages[fname] = make(map[string]bool) - } - neededPackages[fname]["strconv"] = true - d = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with faster strconv.FormatUint", - SuggestedFixes: []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"): - base := []byte(", 10") - if verb == "%x" { - base = []byte(", 16") - } - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - _, ok := neededPackages[fname] - if !ok { - neededPackages[fname] = make(map[string]bool) - } - neededPackages[fname]["strconv"] = true - d = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with faster strconv.FormatUint", - SuggestedFixes: []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): - var fix string - if strings.HasSuffix(verb, "%s") { - fix = strconv.Quote(verb[:len(verb)-2]) + "+" + formatNode(pass.Fset, value) - } else if strings.HasSuffix(verb, "%[1]s") { - fix = strconv.Quote(verb[:len(verb)-5]) + "+" + formatNode(pass.Fset, value) - } else if strings.HasPrefix(verb, "%s") { - fix = formatNode(pass.Fset, value) + "+" + strconv.Quote(verb[2:]) - } else { - fix = formatNode(pass.Fset, value) + "+" + strconv.Quote(verb[5:]) - } - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - d = &analysis.Diagnostic{ - Pos: call.Pos(), - End: call.End(), - Message: fn + " can be replaced with string concatenation", - SuggestedFixes: []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 && n.fiximports { - 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" { - 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() - _, ok := neededPackages[fname] - if ok { - delete(neededPackages[fname], pkg.Path()) - } - } - }) - } - } - 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 == `"fmt"` { - fix := "" - fname := pass.Fset.File(gd.Pos()).Name() - if removedFmtUsages[fname] < 0 { - fix += `"fmt"` - if len(neededPackages[fname]) == 0 { - return - } - } - keys := make([]string, 0, len(neededPackages[fname])) - for k := range neededPackages[fname] { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - fix = fix + "\n\t\"" + k + `"` - } - pass.Report(analysis.Diagnostic{ - Pos: gd.Pos(), - End: gd.End(), - Message: "Fix imports", - SuggestedFixes: []analysis.SuggestedFix{ - { - Message: "Fix imports", - TextEdits: []analysis.TextEdit{{ - Pos: gd.Pos(), - End: gd.End(), - NewText: []byte(fix), - }}, - }, - }}) - } - }) - } - - 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/ccojocar/zxcvbn-go/.gitignore b/vendor/github.com/ccojocar/zxcvbn-go/.gitignore deleted file mode 100644 index e032cc2fc..000000000 --- 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 b54f70092..000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/.golangci.yml +++ /dev/null @@ -1,39 +0,0 @@ -linters: - enable: - - asciicheck - - bodyclose - - dogsled - - durationcheck - - errcheck - - errorlint - - exportloopref - - gci - - ginkgolinter - - gofmt - - gofumpt - - goimports - - gosimple - - govet - - importas - - ineffassign - - megacheck - - misspell - - nakedret - - nolintlint - - revive - - staticcheck - - typecheck - - unconvert - - unparam - - unused - - wastedassign - -linters-settings: - gci: - sections: - - standard - - default - - prefix(github.com/ccojocar) - -run: - timeout: 5m 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 2386aeee5..000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/.goreleaser.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -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 e8f59e06d..000000000 --- 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 0690f3753..000000000 --- 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 3f742a9da..000000000 --- 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 34526685c..000000000 --- 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 3db0f1b10..000000000 --- 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 80432572b..000000000 --- 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 4f51369e1..000000000 --- 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 da3e894ec..000000000 --- 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 fd7f38332..000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/matching/dateMatchers.go +++ /dev/null @@ -1,206 +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 - } - - if !((1900 <= year && year <= 2019) || (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 d0d450188..000000000 --- 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 1f303aa6e..000000000 --- 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.Replace(result, value, key, -1) - } - - 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 c6948067b..000000000 --- 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 d52ba4254..000000000 --- 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 697194583..000000000 --- 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 101ccea5e..000000000 --- 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 58ee1e0ea..000000000 --- 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 f25606a8d..000000000 --- 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 < math.Pow(10, 2) { - 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 1b989d194..000000000 --- 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 f3dc19e4c..000000000 --- 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/certifi/gocertifi/LICENSE b/vendor/github.com/certifi/gocertifi/LICENSE deleted file mode 100644 index 14e2f777f..000000000 --- a/vendor/github.com/certifi/gocertifi/LICENSE +++ /dev/null @@ -1,373 +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/certifi/gocertifi/README.md b/vendor/github.com/certifi/gocertifi/README.md deleted file mode 100644 index 9c860301d..000000000 --- a/vendor/github.com/certifi/gocertifi/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# GoCertifi: SSL Certificates for Golang - -This Go package contains a CA bundle that you can reference in your Go code. -This is useful for systems that do not have CA bundles that Golang can find -itself, or where a uniform set of CAs is valuable. - -This is the same CA bundle that ships with the -[Python Requests](https://github.com/kennethreitz/requests) library, and is a -Golang specific port of [certifi](https://github.com/kennethreitz/certifi). The -CA bundle is derived from Mozilla's canonical set. - -## Usage - -You can use the `gocertifi` package as follows: - -```go -import "github.com/certifi/gocertifi" - -certPool, err := gocertifi.CACerts() -``` - -You can use the returned `*x509.CertPool` as part of an HTTP transport, for example: - -```go -import ( - "net/http" - "crypto/tls" -) - -// Setup an HTTP client with a custom transport -transport := &http.Transport{ - Proxy: ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - }).DialContext, - ForceAttemptHTTP2: true, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, -} -// or, starting with go1.13 simply use: -// transport := http.DefaultTransport.(*http.Transport).Clone() - -transport.TLSClientConfig = &tls.Config{RootCAs: certPool} -client := &http.Client{Transport: transport} - -// Make an HTTP request using our custom transport -resp, err := client.Get("https://example.com") -``` - -## Detailed Documentation - -Import as follows: - -```go -import "github.com/certifi/gocertifi" -``` - -### Functions - -```go -func CACerts() (*x509.CertPool, error) -``` -CACerts builds an X.509 certificate pool containing the Mozilla CA Certificate -bundle. This can't actually error and always returns successfully with `nil` -as the error. This will be replaced in `v2` to only return the `CertPool`. diff --git a/vendor/github.com/certifi/gocertifi/certifi.go b/vendor/github.com/certifi/gocertifi/certifi.go deleted file mode 100644 index 70be286dc..000000000 --- a/vendor/github.com/certifi/gocertifi/certifi.go +++ /dev/null @@ -1,3219 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. -// 2021-05-07 14:14:36.874796853 -0700 PDT m=+0.476299993 -// https://mkcert.org/generate/ - -/* 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 https://mozilla.org/MPL/2.0/. */ - -package gocertifi - -//go:generate go run gen.go "https://mkcert.org/generate/" - -import "crypto/x509" - -const pemcerts string = ` ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw -MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT -aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ -jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp -xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp -1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG -snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ -U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 -9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B -AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz -yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE -38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP -AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad -DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME -HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 -MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL -v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 -eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq -tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd -C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa -zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB -mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH -V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n -bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG -3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs -J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO -291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS -ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd -AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 -MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 -LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp -YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG -A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq -K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe -sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX -MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT -XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ -HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH -4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub -j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo -U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf -zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b -u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ -bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er -fF6adulZkMV8gzURZVE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX -DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y -ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy -VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr -mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr -IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK -mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu -XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy -dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye -jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 -BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 -DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 -9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx -jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 -Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz -ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS -R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 -Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW -KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw -NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw -NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy -ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV -BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo -Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 -4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 -KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI -rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi -94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB -sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi -gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo -kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE -vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t -O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua -AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP -9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ -eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m -0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb -MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow -GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj -YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM -GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua -BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe -3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 -YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR -rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm -ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU -oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF -MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v -QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t -b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF -AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q -GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 -G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi -l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 -smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC -TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz -MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw -IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR -dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp -li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D -rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ -WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug -F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU -xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC -Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv -dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw -ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl -IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh -c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy -ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh -Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI -KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T -KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq -y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p -dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD -VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL -MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk -fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 -7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R -cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y -mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW -xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK -SnQ2+Q== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa -GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg -Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J -WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB -rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp -+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 -ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i -Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz -PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og -/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH -oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI -yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud -EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 -A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL -MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT -ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f -BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn -g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl -fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K -WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha -B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc -hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR -TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD -mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z -ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y -4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza -8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM -V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB -4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr -H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd -8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv -vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT -mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe -btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc -T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt -WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ -c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A -4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD -VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG -CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 -aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 -aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu -dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw -czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G -A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC -TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg -Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 -7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem -d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd -+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B -4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN -t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x -DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 -k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s -zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j -Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT -mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK -4SVhM7JZG+Ju1zdXtg2pEto= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY -MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t -dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 -WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD -VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 -9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ -DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 -Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N -QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ -xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G -A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG -kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr -Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 -Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU -JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot -RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP -MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx -MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV -BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o -Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt -5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s -3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej -vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu -8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw -DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG -MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil -zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ -3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD -FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 -Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 -ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB -gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk -MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY -UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx -NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 -dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy -dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 -38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP -KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q -DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 -qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa -JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi -PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P -BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs -jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 -eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR -vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa -IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy -i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ -O+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh -MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE -YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 -MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo -ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg -MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN -ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA -PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w -wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi -EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY -avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ -YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE -sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h -/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 -IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD -ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy -OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P -TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER -dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf -ReYNnyicsbkqWletNw+vHX/bvZ8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl -MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp -U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw -NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE -ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp -ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 -DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf -8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN -+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 -X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa -K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA -1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G -A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR -zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 -YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD -bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 -L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D -eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp -VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY -WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c -JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP -mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ -wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 -VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ -AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB -AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun -pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC -dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf -fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm -NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx -H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB -CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 -nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt -43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P -T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 -gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR -TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw -DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr -hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg -06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF -PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls -YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm -+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW -PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM -xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB -Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 -hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg -EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA -FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec -nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z -eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF -hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 -Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep -+OkuE6N36B9K ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ -MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT -DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow -PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD -Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O -rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq -OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b -xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw -7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD -aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG -SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 -ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr -AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz -R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 -JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo -Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln -biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF -MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT -d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 -76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ -bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c -6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE -emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd -MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt -MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y -MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y -FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi -aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM -gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB -qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 -lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn -8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov -L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 -45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO -UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 -O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC -bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv -GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a -77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC -hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 -92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp -Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w -ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt -Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE -BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu -IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow -RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY -U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv -Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br -YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF -nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH -6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt -eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ -c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ -MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH -HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf -jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 -5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB -rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU -F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c -wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 -cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB -AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp -WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 -xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ -2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ -IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 -aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X -em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR -dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ -OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ -hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy -tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz -MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv -cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz -Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO -0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao -wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj -7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS -8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT -BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg -JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 -6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ -3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm -D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS -CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx -MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg -Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ -iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa -/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ -jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI -HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 -sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w -gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw -KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG -AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L -URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO -H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm -I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY -iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB -gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV -BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw -MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl -YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P -RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 -UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI -2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 -Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp -+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ -DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O -nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW -/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g -PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u -QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY -SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv -IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 -zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd -BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB -ZQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi -MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu -MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp -dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV -UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO -ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz -c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP -OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl -mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF -BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 -qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw -gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu -bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp -dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 -6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ -h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH -/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv -wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN -pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT -IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw -MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy -ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N -T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR -FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J -cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW -BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm -fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv -GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV -BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X -DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ -BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 -QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny -gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw -zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q -130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 -JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw -ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT -AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj -AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG -9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h -bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc -fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu -HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w -t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw -WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG -A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh -bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE -ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS -b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 -7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS -J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y -HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP -t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz -FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY -XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ -MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw -hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js -MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA -A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj -Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx -XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o -omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc -A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW -WL1WMRJOEcgh4LMRkWXbtKaIOM5V ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe -MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 -ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw -IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL -SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH -SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh -ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X -DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 -TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ -fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA -sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU -WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS -nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH -dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip -NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC -AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF -MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB -uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl -PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP -JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ -gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 -j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 -5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB -o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS -/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z -Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE -W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D -hNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT -AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD -QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP -MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do -0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ -UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d -RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ -OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv -JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C -AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O -BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ -LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY -MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ -44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I -Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw -i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN -9u6wWk5JRFRYX0KD ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG -EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 -MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl -cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR -dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB -pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM -b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm -aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz -IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT -lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz -AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 -VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG -ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 -BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG -AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M -U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh -bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C -+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F -uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 -XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx -FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg -Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG -A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr -b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ -jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn -PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh -ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 -nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h -q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED -MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC -mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 -7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB -oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs -EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO -fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi -AmvZWg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr -MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG -A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 -MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp -Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD -QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz -i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 -h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV -MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 -UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni -8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC -h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD -VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB -AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm -KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ -X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr -QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 -pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN -QSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD -VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 -ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G -CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y -OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx -FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp -Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP -kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc -cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U -fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 -N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC -xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 -+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM -Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG -SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h -mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk -ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c -2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t -HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 -MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 -RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT -gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm -KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd -QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ -XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o -LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU -RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp -jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK -6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX -mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs -Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH -WD9f ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy -MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 -thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM -cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG -L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i -NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h -X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b -m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy -Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja -EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T -KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF -6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh -OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD -VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv -ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl -AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF -661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 -am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 -ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 -PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS -3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k -SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF -3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM -ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g -StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz -Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB -jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 -MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 -ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD -VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j -b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq -scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO -xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H -LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX -uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD -yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ -JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q -rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN -BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L -hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB -QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ -HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu -Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg -QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB -BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx -MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA -A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb -laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 -awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo -JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw -LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT -VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk -LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb -UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ -QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ -naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls -QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT -EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp -ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz -NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH -EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE -AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD -E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH -/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy -DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh -GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR -tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA -AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX -WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu -9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr -gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo -2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI -4uJEvlz36hz1 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs -ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw -MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj -aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp -Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg -nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 -HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N -Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN -dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 -HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G -CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU -sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 -4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg -8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 -mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs -ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD -VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy -ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy -dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p -OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 -8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K -Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe -hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk -6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q -AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI -bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB -ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z -qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn -0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN -sSi6 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP -Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr -ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL -MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 -yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr -VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ -nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG -XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj -vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt -Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g -N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC -nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y -YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua -kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL -QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp -6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG -yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i -QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO -tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu -QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ -Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u -olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 -x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz -dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG -A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U -cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf -qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ -JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ -+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS -s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 -HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 -70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG -V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S -qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S -5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia -C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX -OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE -FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 -KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B -8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ -MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc -0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ -u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF -u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH -YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 -GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO -RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e -KeC2uAloGRwYQw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC -VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ -cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ -BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt -VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D -0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 -ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G -A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs -aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I -flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM -MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D -ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU -cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 -WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg -Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw -IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH -UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM -TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU -BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM -kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x -AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV -HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y -sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL -I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 -J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY -VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES -MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU -V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz -WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO -LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE -AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH -K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX -RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z -rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx -3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq -hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC -MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls -XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D -lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn -aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ -YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl -MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe -U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX -DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy -dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj -YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV -OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr -zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM -VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ -hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO -ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw -awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs -OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 -DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF -coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc -okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 -t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy -1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ -SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB -8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy -dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 -YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 -dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh -IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD -LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG -EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g -KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD -ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu -bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg -ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R -85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm -4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV -HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd -QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t -lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB -o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 -opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo -dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW -ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN -AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y -/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k -SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy -Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS -Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl -nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix -RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p -YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw -NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK -EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl -cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz -dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ -fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns -bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD -75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP -FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV -HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp -5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu -b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA -A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p -6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 -TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 -dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys -Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI -l7WdmplNsDz4SgCbZN2fOUvRJ9e4 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE -BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w -MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 -IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC -SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 -ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv -UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX -4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 -KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ -gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb -rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ -51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F -be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe -KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F -v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn -fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 -jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz -ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt -ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL -e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 -jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz -WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V -SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j -pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX -X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok -fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R -K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU -ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU -LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT -LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF -MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL -ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx -MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc -MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ -AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH -iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj -vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA -0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB -OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ -BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E -FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 -GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW -zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 -1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE -f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F -jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN -ZetX2fNXlrtIzYE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr -6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV -L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 -1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx -MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ -QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB -arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr -Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi -FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS -P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN -9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz -uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h -9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s -A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t -OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo -+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 -KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 -DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us -H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ -I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 -5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h -3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz -Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y -ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E -N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 -tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX -0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c -/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X -KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY -zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS -O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D -34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP -K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv -Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj -QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV -cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS -IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 -HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa -O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv -033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u -dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE -kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 -3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD -u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq -4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN -8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ -RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 -hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 -ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM -EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 -A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy -WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ -1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 -6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT -91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p -TpPDpFQUWw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha -ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM -HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 -UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 -tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R -ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM -lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp -/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G -A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G -A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj -dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy -MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl -cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js -L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL -BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni -acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 -o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K -zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 -PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y -Johw1+qRzT65ysCQblrGXnRl11z+o+I= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw -NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV -BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn -ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 -3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z -qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR -p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 -HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw -ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea -HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw -Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh -c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E -RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt -dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku -Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp -3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 -nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF -CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na -xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX -KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV -BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu -MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy -MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx -EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw -ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe -NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH -PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I -x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe -QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR -yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO -QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 -H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ -QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD -i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs -nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 -rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI -hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM -tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf -GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb -lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka -+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal -TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i -nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 -gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr -G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os -zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x -L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE -AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw -CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ -BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND -VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb -qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY -HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo -G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA -lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr -IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ -0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH -k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 -4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO -m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa -cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl -uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI -KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls -ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG -AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 -VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT -VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG -CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA -cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA -QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA -7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA -cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA -QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA -czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu -aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt -aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud -DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF -BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp -D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU -JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m -AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD -vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms -tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH -7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h -I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA -h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF -d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H -pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx -EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT -VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 -NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT -B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF -10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz -0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh -MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH -zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc -46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 -yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi -laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP -oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA -BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE -qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm -4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL -1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn -LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF -H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo -RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ -nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh -15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW -6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW -nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j -wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz -aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy -KwbQBM0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw -NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv -b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD -VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F -VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 -7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X -Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ -/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs -81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm -dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe -Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu -sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 -pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs -slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ -arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD -VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG -9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl -dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx -0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj -TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed -Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 -Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI -OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 -vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW -t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn -HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx -SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC -aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV -BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 -Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz -MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ -BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp -em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY -B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH -D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF -Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo -q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D -k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH -fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut -dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM -ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 -zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX -U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 -Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 -XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF -Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR -HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY -GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c -77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 -+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK -vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 -FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl -yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P -AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD -y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d -NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd -AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC -FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi -1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq -jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ -wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ -WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy -NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC -uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw -IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 -g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN -9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP -BSeOE6Fuwg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE -AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG -EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM -FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC -REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp -Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM -VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ -SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ -4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L -cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi -eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG -A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 -DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j -vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP -DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc -maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D -lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv -KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 -MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV -wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe -rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 -68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh -4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp -UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o -abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc -3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G -KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt -hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO -Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt -zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD -ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC -MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 -cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN -qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 -YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv -b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 -8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k -NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj -ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp -q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt -nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 -MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf -qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW -n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym -c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ -O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 -o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j -IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq -IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz -8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh -vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l -7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG -cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD -ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 -AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC -roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga -W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n -lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE -+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV -csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd -dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg -KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM -HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 -WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 -MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR -/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu -FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR -U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c -ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR -FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k -A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw -eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl -sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp -VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q -A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ -ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD -ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px -KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI -FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv -oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg -u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP -0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf -3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl -8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ -DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN -PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ -ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA -n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc -biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp -EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA -bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu -YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB -AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW -BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI -QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I -0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni -lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 -B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv -ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo -IhNzbM8m9Yop5w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg -RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf -Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q -RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD -AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY -JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv -6pZjamVFkpUBtA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH -MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI -2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx -1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ -q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz -tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ -vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV -5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY -1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 -NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG -Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 -8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe -pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl -MrY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe -Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw -EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x -IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG -fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO -Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd -BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx -AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ -oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 -sycX ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg -RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y -ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If -xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV -ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO -DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ -jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ -CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi -EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM -fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY -uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK -chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t -9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD -ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 -SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd -+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc -fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa -sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N -cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N -0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie -4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI -r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 -/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm -gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB -hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV -BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT -EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR -6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X -pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC -9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV -/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf -Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z -+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w -qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah -SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC -u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf -Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq -crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E -FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl -wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM -4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV -2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna -FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ -CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK -boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke -jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL -S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb -QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl -0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB -NVOFBkpdn627G190 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB -iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl -cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV -BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw -MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV -BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B -3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY -tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ -Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 -VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT -79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 -c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT -Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l -c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee -UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE -Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF -Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO -VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 -ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs -8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR -iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze -Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ -XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ -qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB -VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB -L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG -jjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl -eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT -JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT -Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg -VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo -I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng -o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G -A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB -zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW -RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ -FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F -uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX -kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs -ewv4n4Q= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc -8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke -hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI -KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg -515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO -xwy8p2Fp8fc74SrL+SvzZpA3 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y -MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg -TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS -b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS -M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC -UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d -Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p -rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l -pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb -j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC -KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS -/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X -cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH -1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP -px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 -MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI -eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u -2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS -v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC -wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy -CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e -vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 -Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa -Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL -eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 -FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc -7uzXLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu -VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw -MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw -JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT -3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU -+ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp -S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 -bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi -T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL -vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK -Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK -dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT -c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv -l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N -iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD -ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH -6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt -LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 -nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 -+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK -W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT -AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq -l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG -4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ -mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A -7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu -VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN -MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 -MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 -ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy -RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS -bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF -/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R -3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw -EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy -9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V -GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ -2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV -WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD -W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN -AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj -t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV -DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 -TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G -lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW -mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df -WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 -+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ -tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA -GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv -8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 -cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs -IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz -dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy -NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu -dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt -dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 -aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T -RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN -cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW -wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 -U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 -jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN -BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ -jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ -Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v -1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R -nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH -VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG -A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 -d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu -dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq -RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy -MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD -VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 -L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g -Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi -A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt -ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH -Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC -R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX -hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD -TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y -aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx -MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j -aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP -T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 -sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL -TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 -/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp -7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz -EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt -hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP -a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot -aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg -TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV -PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv -cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL -tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd -BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB -ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT -ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL -jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS -ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy -P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 -xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d -Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN -5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe -/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z -AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ -5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt -MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg -Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i -YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x -CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG -b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh -bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 -HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx -WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX -1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk -u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P -99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r -M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB -BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh -cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 -gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO -ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf -aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic -Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL -BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 -ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw -NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L -cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg -Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN -QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT -3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw -3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 -3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 -BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN -XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF -AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw -8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG -nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP -oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy -d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg -LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB -gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu -QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG -A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz -OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ -VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 -b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA -DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn -0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB -OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE -fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E -Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m -o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i -sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW -OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez -Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS -adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n -3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ -F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf -CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 -XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm -djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ -WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb -AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq -P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko -b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj -XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P -5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi -DrW5viSP ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix -DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k -IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT -N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v -dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG -A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh -ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx -QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA -4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 -AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 -4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C -ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV -9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD -gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 -Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq -NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko -LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc -Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd -ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I -XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI -M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot -9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V -Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea -j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh -X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ -l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf -bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 -pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK -e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 -vm9qp/UsQu0yrbYhnr68 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN -BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl -bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv -b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ -BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj -YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 -MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 -dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg -QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa -jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi -C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep -lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof -TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx -CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ -WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ -BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG -Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ -yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf -BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz -WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF -tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z -374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC -IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL -mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 -wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS -MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 -ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet -UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H -YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 -LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD -nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 -RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM -LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf -77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N -JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm -fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp -6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp -1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B -9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok -RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv -uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj -ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM -9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw -IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 -VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L -93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm -jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA -A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI -U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs -N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv -o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU -5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy -rqXRfboQnoZsG4q5WTP468SQvvG5 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK -gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ -W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg -1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K -8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r -2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me -z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR -8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj -mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz -7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 -+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI -0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB -Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm -UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 -LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY -+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS -k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl -7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm -btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl -urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ -fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 -n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE -76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H -9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT -4PsJYGw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl -ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr -ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr -BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM -YyRIHN8wfdVoOw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi -9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk -M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB -MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw -CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW -1KyLa2tJElMzrdfkviT8tQp21KW8EA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx -GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp -bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w -KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 -BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy -dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG -EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll -IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU -QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT -TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg -LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 -a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr -LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr -N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X -YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ -iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f -AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH -V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh -AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf -IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 -lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c -8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf -lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE -BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ -IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 -MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV -BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w -HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj -Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj -TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u -KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj -qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm -MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 -ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP -zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk -L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC -jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA -HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC -AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg -p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm -DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 -COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry -L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf -JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg -IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io -2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV -09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ -XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq -T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe -MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD -VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk -MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U -cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y -IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB -pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h -IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG -A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU -cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid -RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V -seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme -9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV -EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW -hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ -DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD -ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I -/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf -ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ -yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts -L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN -zl/HHk484IkzlQsPpTLWPFp5LBk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV -BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw -IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy -dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig -Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk -MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg -Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD -VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy -dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ -QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq -1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp -2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK -DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape -az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF -3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 -oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM -g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 -mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh -8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd -BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U -nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw -DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX -dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ -MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL -/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX -CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa -ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW -2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 -N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 -Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB -As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp -5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu -1uwJ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD -VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk -MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U -cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y -IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV -BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw -IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy -dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig -RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb -3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA -BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 -3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou -owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ -wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF -ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf -BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ -MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv -civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 -AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F -hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 -soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI -WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi -tJ/X5g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE -BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK -DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz -OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv -bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R -xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX -qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC -C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 -6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh -/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF -YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E -JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc -US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 -ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm -+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi -M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G -A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV -cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc -Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs -PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ -q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 -cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr -a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I -H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y -K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu -nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf -oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY -Ic2wBlX7Jz9TkHCpBB5XJ7k= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz -WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 -b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS -b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI -7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg -CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud -EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD -VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T -kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ -gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV -BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE -CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy -MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G -A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD -DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq -M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf -OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa -4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 -HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR -aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA -b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ -Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV -PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO -pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu -UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY -MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV -HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 -9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW -s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 -Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg -cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM -79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz -/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt -ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm -Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK -QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ -w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi -S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 -mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx -NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv -bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA -VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku -WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX -5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ -ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg -h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg -MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh -bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx -MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET -MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI -xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k -ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD -aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw -LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw -1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX -k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 -SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h -bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n -WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY -rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce -MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu -bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN -nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt -Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 -55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj -vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf -cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz -oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp -nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs -pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v -JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R -8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 -5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw -CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 -bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg -Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ -BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu -ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS -b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni -eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W -p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T -rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV -57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg -Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH -MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM -QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy -MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl -cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM -f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX -mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 -zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P -fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc -vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 -Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp -zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO -Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW -k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ -DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF -lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW -Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 -d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z -XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR -gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 -d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv -J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg -DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM -+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy -F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 -SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws -E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH -MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM -QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy -MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl -cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv -CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg -GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu -XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd -re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu -PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 -mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K -8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj -x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR -nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 -kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok -twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp -8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT -vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT -z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA -pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb -pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB -R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R -RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk -0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC -5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF -izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn -yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout -736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A -DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk -fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA -njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu -hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l -xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 -CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx -sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH -bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x -CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds -b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr -b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 -kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm -VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R -VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc -C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj -tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY -D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv -j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl -NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 -iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP -O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV -ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj -L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 -1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl -1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU -b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV -PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj -y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb -EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg -DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI -+Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy -YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX -UB+K+wb1whnw0A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF -eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx -MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV -BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog -D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS -sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop -O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk -sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi -c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj -VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz -KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ -TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G -sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs -1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD -fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN -l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR -ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ -VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 -c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp -4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s -t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj -2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO -vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C -xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx -cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM -fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw -WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw -MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x -MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD -VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX -BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO -ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M -CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu -I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm -TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh -C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf -ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz -IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT -Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k -JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 -hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB -GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of -1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov -L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo -dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr -aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq -hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L -6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG -HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 -0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB -lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi -o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 -gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v -faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 -Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh -jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw -3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD -VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU -ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH -MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO -MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv -Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz -f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO -8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq -d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM -tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt -Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB -o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x -PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM -wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d -GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH -6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby -RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx -iN66zB+Afko= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG -EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo -bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g -RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ -TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s -b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 -WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS -fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB -zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq -hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB -CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD -+JbNR6iC8hZVdyR+EhCVBCyj ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG -A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg -SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw -MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln -biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v -dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ -BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ -HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH -3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH -GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c -xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 -aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq -TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 -/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 -kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG -YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT -+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo -WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG -EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx -IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw -MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln -biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND -IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci -MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti -sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O -BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB -Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c -3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J -0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL -BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ -SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n -a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 -NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT -CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u -Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO -dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI -VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV -9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY -2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY -vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt -bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb -x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ -l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK -TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj -Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e -i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw -DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG -7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk -MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr -gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk -GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS -3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm -Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ -l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c -JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP -L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa -LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG -mpv0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw -gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL -Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg -MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw -BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 -MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 -c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ -bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg -Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ -2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E -T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j -5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM -C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T -DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX -wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A -2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm -nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 -dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl -N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj -c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS -5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS -Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr -hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ -B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI -AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw -H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ -b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk -2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol -IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk -5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY -n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD -VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw -MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV -UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy -b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR -ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb -hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 -FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV -L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB -iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl -MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw -NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG -EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N -aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ -Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 -ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 -HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm -gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ -jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc -aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG -YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 -W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K -UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH -+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q -W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC -LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC -gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 -tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh -SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 -TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 -pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR -xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp -GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 -dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN -AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB -RA+GsCyRxj3qrg+E ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV -BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk -LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv -b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ -BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg -THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v -IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv -xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H -Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB -eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo -jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ -+efcMQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV -BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g -Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ -BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ -R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF -dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw -vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ -uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp -n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs -cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW -xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P -rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF -DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx -DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy -LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C -eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ -d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq -kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC -b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl -qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 -OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c -NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk -ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO -pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj -03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk -PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE -1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX -QRBdJ3NghVdJIgc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw -CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x -ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 -c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx -OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI -SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI -b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB -ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn -swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu -7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 -1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW -80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP -JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l -RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw -hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 -coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc -BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n -twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud -DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W -0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe -uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q -lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB -aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE -sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT -MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe -qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh -VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 -h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 -EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK -yeC2nOnOcXHebD8WpHk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD -VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf -BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 -YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x -NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G -A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 -d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF -Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG -SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN -FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w -DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw -CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh -DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD -VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf -BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 -YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x -NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G -A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 -d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF -Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB -BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ -j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF -1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G -A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 -AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC -MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu -Sw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM -BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG -T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx -CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD -b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA -iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH -38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE -HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz -kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP -szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq -vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf -nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG -YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo -0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a -CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K -AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I -36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB -Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN -qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj -cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm -+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL -hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe -lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 -p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 -piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR -LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX -5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO -dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul -9XXeifdy ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw -CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw -FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S -Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 -MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL -DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS -QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH -sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK -Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu -SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC -MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy -v+c= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA -MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD -VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy -MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt -c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ -OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG -vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud -316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo -0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE -y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF -zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE -+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN -I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs -x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa -ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC -4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 -7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg -JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti -2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk -pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF -FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt -rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk -ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 -u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP -4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 -N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 -vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx -CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD -ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw -MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex -HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq -R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd -yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ -7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 -+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= ------END CERTIFICATE----- - -` - -// CACerts builds an X.509 certificate pool containing the -// certificate bundle from https://mkcert.org/generate/ fetch on 2021-05-07 14:14:36.874796853 -0700 PDT m=+0.476299993. -// Will never actually return an error. -func CACerts() (*x509.CertPool, error) { - pool := x509.NewCertPool() - pool.AppendCertsFromPEM([]byte(pemcerts)) - return pool, nil -} 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 24b53065f..000000000 --- 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 33c88305c..000000000 --- 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 94b9c4439..000000000 --- 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 78bddf1ce..000000000 --- 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 3e8b13257..000000000 --- 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 7e3145a22..000000000 --- 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 78f95f256..000000000 --- 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 118e49e81..000000000 --- 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 05f5e7dfe..000000000 --- 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 cf9d42aed..000000000 --- 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 c2b126a84..000000000 --- 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 261eeb9e9..000000000 --- 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 8e2f81ae8..000000000 --- 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 6f4279bd3..000000000 --- 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.11 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 c47b3a761..000000000 --- a/vendor/github.com/charithe/durationcheck/durationcheck.go +++ /dev/null @@ -1,191 +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), - } - - 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) { - expr := node.(*ast.BinaryExpr) - // we are only interested in multiplication - if expr.Op != token.MUL { - 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/chavacava/garif/.gitignore b/vendor/github.com/chavacava/garif/.gitignore deleted file mode 100644 index 5dee1052c..000000000 --- a/vendor/github.com/chavacava/garif/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.test -*.out -.devcontainer/ \ No newline at end of file diff --git a/vendor/github.com/chavacava/garif/LICENSE b/vendor/github.com/chavacava/garif/LICENSE deleted file mode 100644 index 2bba73fb7..000000000 --- a/vendor/github.com/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/github.com/chavacava/garif/README.md b/vendor/github.com/chavacava/garif/README.md deleted file mode 100644 index 6a19c6147..000000000 --- a/vendor/github.com/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/github.com/chavacava/garif/constructors.go b/vendor/github.com/chavacava/garif/constructors.go deleted file mode 100644 index 8910e396e..000000000 --- a/vendor/github.com/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/github.com/chavacava/garif/decorators.go b/vendor/github.com/chavacava/garif/decorators.go deleted file mode 100644 index 00b599fb8..000000000 --- a/vendor/github.com/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/github.com/chavacava/garif/doc.go b/vendor/github.com/chavacava/garif/doc.go deleted file mode 100644 index 50fa6dfe5..000000000 --- a/vendor/github.com/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/github.com/chavacava/garif/enums.go b/vendor/github.com/chavacava/garif/enums.go deleted file mode 100644 index dea2daf13..000000000 --- a/vendor/github.com/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/github.com/chavacava/garif/io.go b/vendor/github.com/chavacava/garif/io.go deleted file mode 100644 index ce5719c96..000000000 --- a/vendor/github.com/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/github.com/chavacava/garif/models.go b/vendor/github.com/chavacava/garif/models.go deleted file mode 100644 index f16a86136..000000000 --- a/vendor/github.com/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 identifer 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 identifer 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 identifer 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 identifer 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 identifer 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 identifer 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 identifer for the supression 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 identifer 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/github.com/ckaznocha/intrange/.gitignore b/vendor/github.com/ckaznocha/intrange/.gitignore deleted file mode 100644 index cfcb676e1..000000000 --- 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 2ad830d1b..000000000 --- a/vendor/github.com/ckaznocha/intrange/.golangci.yml +++ /dev/null @@ -1,99 +0,0 @@ -linters-settings: - gci: - local-prefixes: github.com/ckaznocha/intrange - gocritic: - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - goimports: - local-prefixes: github.com/ckaznocha/intrange - golint: - min-confidence: 0 - govet: - check-shadowing: true - enable: - - asmdecl - - assign - - atomic - - atomicalign - - bools - - buildtag - - cgocall - - composite - - copylock - - deepequalerrors - - errorsas - - fieldalignment - - findcall - - framepointer - - httpresponse - - ifaceassert - - loopclosure - - lostcancel - - nilfunc - - nilness - - printf - - shadow - - shift - - sortslice - - stdmethods - - stringintconv - - structtag - - testinggoroutine - - tests - - unmarshal - - unreachable - - unsafeptr - - unusedresult - misspell: - locale: US -linters: - disable-all: true - enable: - - asciicheck - - dupl - - errcheck - - errorlint - - exportloopref - - gci - - gochecknoinits - - goconst - - gocritic - - godot - - godox - - goerr113 - - gofmt - - gofumpt - - goimports - - gomnd - - 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 -run: - skip-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 541cf2c54..000000000 --- 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 b68bde54b..000000000 --- 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 9cac46220..000000000 --- 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 e2c44c4e2..000000000 --- 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 3814c99f9..000000000 --- a/vendor/github.com/ckaznocha/intrange/go.work +++ /dev/null @@ -1,6 +0,0 @@ -go 1.22 - -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 33cddf303..000000000 --- a/vendor/github.com/ckaznocha/intrange/intrange.go +++ /dev/null @@ -1,471 +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 `i := 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 - } - - 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 nExpr ast.Expr - - switch cond.Op { - case token.LSS: // ;i < n; - if isBenchmark(cond.Y) { - return - } - - nExpr = findNExpr(cond.Y) - - x, ok := cond.X.(*ast.Ident) - if !ok { - return - } - - if x.Name != initIdent.Name { - return - } - case token.GTR: // ;n > i; - if isBenchmark(cond.X) { - return - } - - nExpr = findNExpr(cond.X) - - y, ok := cond.Y.(*ast.Ident) - if !ok { - return - } - - if y.Name != initIdent.Name { - return - } - 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: nExpr, - } - - ast.Inspect(forStmt.Body, bc.check) - - if bc.modified { - return - } - - pass.Report(analysis.Diagnostic{ - Pos: forStmt.Pos(), - Message: msg, - }) -} - -func checkRangeStmt(pass *analysis.Pass, rangeStmt *ast.RangeStmt) { - if rangeStmt.Key == nil { - return - } - - ident, ok := rangeStmt.Key.(*ast.Ident) - if !ok { - return - } - - if ident.Name == "_" { - return - } - - if rangeStmt.Value != nil { - return - } - - if rangeStmt.X == nil { - return - } - - x, ok := rangeStmt.X.(*ast.CallExpr) - if !ok { - return - } - - fn, ok := x.Fun.(*ast.Ident) - if !ok { - return - } - - if fn.Name != "len" || len(x.Args) != 1 { - 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 - } - - pass.Report(analysis.Diagnostic{ - Pos: ident.Pos(), - End: x.End(), - Message: fmt.Sprintf(msgLenRange, 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), - }, - }, - }, - }, - }) -} - -func findNExpr(expr ast.Expr) ast.Expr { - switch e := expr.(type) { - case *ast.CallExpr: - if fun, ok := e.Fun.(*ast.Ident); ok && fun.Name == "len" && len(e.Args) == 1 { - 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 isBenchmark(expr ast.Expr) bool { - selectorExpr, ok := expr.(*ast.SelectorExpr) - if !ok { - return false - } - - if selectorExpr.Sel.Name != "N" { - return false - } - - ident, ok := selectorExpr.X.(*ast.Ident) - if !ok { - return false - } - - if ident.Name == "b" { - return true - } - - return false -} - -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 -} - -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 - } - } - - return true -} - -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: - switch fun.Name { - case - "int", - "int8", - "int16", - "int32", - "int64", - "uint", - "uint8", - "uint16", - "uint32", - "uint64": - default: - return false - } - default: - return false - } - - if len(lit.Args) != 1 { - return false - } - - return compareNumberLit(lit.Args[0], val) - default: - return false - } -} diff --git a/vendor/github.com/curioswitch/go-reassign/.gitattributes b/vendor/github.com/curioswitch/go-reassign/.gitattributes deleted file mode 100644 index d020be8ea..000000000 --- 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 59fa33613..000000000 --- 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 e3bf79ae7..000000000 --- a/vendor/github.com/curioswitch/go-reassign/.golangci.yml +++ /dev/null @@ -1,38 +0,0 @@ -linters: - enable: - - asasalint - - bidichk - - bodyclose - - decorder - - durationcheck - - errchkjson - - errname - - errorlint - - execinquery - - exhaustive - - exportloopref - - gocritic - - goerr113 - - gofmt - - goimports - - goprintffuncname - - gosec - - importas - - misspell - - nolintlint - - nosnakecase - - 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 25f2dc0c1..000000000 --- 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 9f18bde00..000000000 --- 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 ac9c131df..000000000 --- a/vendor/github.com/curioswitch/go-reassign/README.md +++ /dev/null @@ -1,53 +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. - -## Limitations - -If a variable shadows the name of an import, an assignment of a field in the variable will trigger the linter. Shadowing -can be confusing, so it's recommended to rename the variable. 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 48707adeb..000000000 --- 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 e1b47d5b9..000000000 --- a/vendor/github.com/curioswitch/go-reassign/internal/analyzer/analyzer.go +++ /dev/null @@ -1,84 +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: - if !checkRE.MatchString(x.Sel.Name) { - return - } - - selectIdent, ok := x.X.(*ast.Ident) - if !ok { - return - } - - if selectObj, ok := pass.TypesInfo.Uses[selectIdent]; ok { - if pkg, ok := selectObj.(*types.PkgName); !ok || pkg.Imported() == pass.Pkg { - return - } - } - - 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 e1292f738..000000000 --- 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 814201a00..000000000 --- a/vendor/github.com/daixiang0/gci/pkg/config/config.go +++ /dev/null @@ -1,115 +0,0 @@ -package config - -import ( - "sort" - "strings" - - "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 || strings.Compare(sectionI, sectionJ) != 0 { - return defaultOrder[sectionI] < defaultOrder[sectionJ] - } - - return strings.Compare(sections[i].String(), sections[j].String()) < 0 - }) - } - - 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 062701d2e..000000000 --- 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 163e95a86..000000000 --- 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 866ae84c4..000000000 --- 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 79950792c..000000000 --- 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 cd821582e..000000000 --- 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 ccab2844f..000000000 --- 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 ab33739ca..000000000 --- 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 e8532f850..000000000 --- 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 423e96acf..000000000 --- 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 4a2741773..000000000 --- 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 c3ddd0824..000000000 --- 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 3af07a092..000000000 --- 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 8112eeb1d..000000000 --- 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 0a1209135..000000000 --- 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 50f41e501..000000000 --- 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 4bff91b9d..000000000 --- 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 62ed1582a..000000000 --- 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 30bdd8f4e..000000000 --- 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 cc0a43f2f..000000000 --- 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 26c7e9dc7..000000000 --- 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 5a2dcdc89..000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/standard_list.go +++ /dev/null @@ -1,175 +0,0 @@ -package section - -// Code generated based on go1.23.0 X:boringcrypto,arenas. 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/hmac": {}, - "crypto/md5": {}, - "crypto/rand": {}, - "crypto/rc4": {}, - "crypto/rsa": {}, - "crypto/sha1": {}, - "crypto/sha256": {}, - "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/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": {}, - "testing": {}, - "testing/fstest": {}, - "testing/iotest": {}, - "testing/quick": {}, - "testing/slogtest": {}, - "text/scanner": {}, - "text/tabwriter": {}, - "text/template": {}, - "text/template/parse": {}, - "time": {}, - "time/tzdata": {}, - "unicode": {}, - "unicode/utf16": {}, - "unicode/utf8": {}, - "unique": {}, - "unsafe": {}, -} 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 f7ae4b87b..000000000 --- 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 ae482fec4..000000000 --- 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 f08d2b66b..000000000 --- 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 8e8711146..000000000 --- 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 1900a0ac5..000000000 --- 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 4a188b3bb..000000000 --- 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 72ccaf7e1..000000000 --- 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 2fafbc32c..000000000 --- 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/jennifer/LICENSE b/vendor/github.com/dave/jennifer/LICENSE deleted file mode 100644 index 17ab1cede..000000000 --- a/vendor/github.com/dave/jennifer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 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. diff --git a/vendor/github.com/dave/jennifer/jen/add.go b/vendor/github.com/dave/jennifer/jen/add.go deleted file mode 100644 index 2efb3f6da..000000000 --- a/vendor/github.com/dave/jennifer/jen/add.go +++ /dev/null @@ -1,19 +0,0 @@ -package jen - -// Add appends the provided items to the statement. -func Add(code ...Code) *Statement { - return newStatement().Add(code...) -} - -// Add appends the provided items to the statement. -func (g *Group) Add(code ...Code) *Statement { - s := Add(code...) - g.items = append(g.items, s) - return s -} - -// Add appends the provided items to the statement. -func (s *Statement) Add(code ...Code) *Statement { - *s = append(*s, code...) - return s -} diff --git a/vendor/github.com/dave/jennifer/jen/comments.go b/vendor/github.com/dave/jennifer/jen/comments.go deleted file mode 100644 index 886e885b4..000000000 --- a/vendor/github.com/dave/jennifer/jen/comments.go +++ /dev/null @@ -1,108 +0,0 @@ -package jen - -import ( - "fmt" - "io" - "strings" -) - -// Comment adds a comment. If the provided string contains a newline, the -// comment is formatted in multiline style. If the comment string starts -// with "//" or "/*", the automatic formatting is disabled and the string is -// rendered directly. -func Comment(str string) *Statement { - return newStatement().Comment(str) -} - -// Comment adds a comment. If the provided string contains a newline, the -// comment is formatted in multiline style. If the comment string starts -// with "//" or "/*", the automatic formatting is disabled and the string is -// rendered directly. -func (g *Group) Comment(str string) *Statement { - s := Comment(str) - g.items = append(g.items, s) - return s -} - -// Comment adds a comment. If the provided string contains a newline, the -// comment is formatted in multiline style. If the comment string starts -// with "//" or "/*", the automatic formatting is disabled and the string is -// rendered directly. -func (s *Statement) Comment(str string) *Statement { - c := comment{ - comment: str, - } - *s = append(*s, c) - return s -} - -// Commentf adds a comment, using a format string and a list of parameters. If -// the provided string contains a newline, the comment is formatted in -// multiline style. If the comment string starts with "//" or "/*", the -// automatic formatting is disabled and the string is rendered directly. -func Commentf(format string, a ...interface{}) *Statement { - return newStatement().Commentf(format, a...) -} - -// Commentf adds a comment, using a format string and a list of parameters. If -// the provided string contains a newline, the comment is formatted in -// multiline style. If the comment string starts with "//" or "/*", the -// automatic formatting is disabled and the string is rendered directly. -func (g *Group) Commentf(format string, a ...interface{}) *Statement { - s := Commentf(format, a...) - g.items = append(g.items, s) - return s -} - -// Commentf adds a comment, using a format string and a list of parameters. If -// the provided string contains a newline, the comment is formatted in -// multiline style. If the comment string starts with "//" or "/*", the -// automatic formatting is disabled and the string is rendered directly. -func (s *Statement) Commentf(format string, a ...interface{}) *Statement { - c := comment{ - comment: fmt.Sprintf(format, a...), - } - *s = append(*s, c) - return s -} - -type comment struct { - comment string -} - -func (c comment) isNull(f *File) bool { - return false -} - -func (c comment) render(f *File, w io.Writer, s *Statement) error { - if strings.HasPrefix(c.comment, "//") || strings.HasPrefix(c.comment, "/*") { - // automatic formatting disabled. - if _, err := w.Write([]byte(c.comment)); err != nil { - return err - } - return nil - } - if strings.Contains(c.comment, "\n") { - if _, err := w.Write([]byte("/*\n")); err != nil { - return err - } - } else { - if _, err := w.Write([]byte("// ")); err != nil { - return err - } - } - if _, err := w.Write([]byte(c.comment)); err != nil { - return err - } - if strings.Contains(c.comment, "\n") { - if !strings.HasSuffix(c.comment, "\n") { - if _, err := w.Write([]byte("\n")); err != nil { - return err - } - } - if _, err := w.Write([]byte("*/")); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/dave/jennifer/jen/custom.go b/vendor/github.com/dave/jennifer/jen/custom.go deleted file mode 100644 index 4966a0702..000000000 --- a/vendor/github.com/dave/jennifer/jen/custom.go +++ /dev/null @@ -1,61 +0,0 @@ -package jen - -// Options specifies options for the Custom method -type Options struct { - Open string - Close string - Separator string - Multi bool -} - -// Custom renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator. -func Custom(options Options, statements ...Code) *Statement { - return newStatement().Custom(options, statements...) -} - -// Custom renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator. -func (g *Group) Custom(options Options, statements ...Code) *Statement { - s := Custom(options, statements...) - g.items = append(g.items, s) - return s -} - -// Custom renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator. -func (s *Statement) Custom(options Options, statements ...Code) *Statement { - g := &Group{ - close: options.Close, - items: statements, - multi: options.Multi, - name: "custom", - open: options.Open, - separator: options.Separator, - } - *s = append(*s, g) - return s -} - -// CustomFunc renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator. -func CustomFunc(options Options, f func(*Group)) *Statement { - return newStatement().CustomFunc(options, f) -} - -// CustomFunc renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator. -func (g *Group) CustomFunc(options Options, f func(*Group)) *Statement { - s := CustomFunc(options, f) - g.items = append(g.items, s) - return s -} - -// CustomFunc renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator. -func (s *Statement) CustomFunc(options Options, f func(*Group)) *Statement { - g := &Group{ - close: options.Close, - multi: options.Multi, - name: "custom", - open: options.Open, - separator: options.Separator, - } - f(g) - *s = append(*s, g) - return s -} diff --git a/vendor/github.com/dave/jennifer/jen/dict.go b/vendor/github.com/dave/jennifer/jen/dict.go deleted file mode 100644 index 260cf928a..000000000 --- a/vendor/github.com/dave/jennifer/jen/dict.go +++ /dev/null @@ -1,81 +0,0 @@ -package jen - -import ( - "bytes" - "io" - "sort" -) - -// Dict renders as key/value pairs. Use with Values for map or composite -// literals. -type Dict map[Code]Code - -// DictFunc executes a func(Dict) to generate the value. Use with Values for -// map or composite literals. -func DictFunc(f func(Dict)) Dict { - d := Dict{} - f(d) - return d -} - -func (d Dict) render(f *File, w io.Writer, s *Statement) error { - first := true - // must order keys to ensure repeatable source - type kv struct { - k Code - v Code - } - lookup := map[string]kv{} - keys := []string{} - for k, v := range d { - if k.isNull(f) || v.isNull(f) { - continue - } - buf := &bytes.Buffer{} - if err := k.render(f, buf, nil); err != nil { - return err - } - keys = append(keys, buf.String()) - lookup[buf.String()] = kv{k: k, v: v} - } - sort.Strings(keys) - for _, key := range keys { - k := lookup[key].k - v := lookup[key].v - if first && len(keys) > 1 { - if _, err := w.Write([]byte("\n")); err != nil { - return err - } - first = false - } - if err := k.render(f, w, nil); err != nil { - return err - } - if _, err := w.Write([]byte(":")); err != nil { - return err - } - if err := v.render(f, w, nil); err != nil { - return err - } - if len(keys) > 1 { - if _, err := w.Write([]byte(",\n")); err != nil { - return err - } - } - } - return nil -} - -func (d Dict) isNull(f *File) bool { - if d == nil || len(d) == 0 { - return true - } - for k, v := range d { - if !k.isNull(f) && !v.isNull(f) { - // if any of the key/value pairs are both not null, the Dict is not - // null - return false - } - } - return true -} diff --git a/vendor/github.com/dave/jennifer/jen/do.go b/vendor/github.com/dave/jennifer/jen/do.go deleted file mode 100644 index c1bceab5a..000000000 --- a/vendor/github.com/dave/jennifer/jen/do.go +++ /dev/null @@ -1,22 +0,0 @@ -package jen - -// Do calls the provided function with the statement as a parameter. Use for -// embedding logic. -func Do(f func(*Statement)) *Statement { - return newStatement().Do(f) -} - -// Do calls the provided function with the statement as a parameter. Use for -// embedding logic. -func (g *Group) Do(f func(*Statement)) *Statement { - s := Do(f) - g.items = append(g.items, s) - return s -} - -// Do calls the provided function with the statement as a parameter. Use for -// embedding logic. -func (s *Statement) Do(f func(*Statement)) *Statement { - f(s) - return s -} diff --git a/vendor/github.com/dave/jennifer/jen/file.go b/vendor/github.com/dave/jennifer/jen/file.go deleted file mode 100644 index c19f51651..000000000 --- a/vendor/github.com/dave/jennifer/jen/file.go +++ /dev/null @@ -1,256 +0,0 @@ -package jen - -import ( - "bytes" - "fmt" - "regexp" - "strings" - "unicode" - "unicode/utf8" -) - -// NewFile Creates a new file, with the specified package name. -func NewFile(packageName string) *File { - return &File{ - Group: &Group{ - multi: true, - }, - name: packageName, - imports: map[string]importdef{}, - hints: map[string]importdef{}, - } -} - -// NewFilePath creates a new file while specifying the package path - the -// package name is inferred from the path. -func NewFilePath(packagePath string) *File { - return &File{ - Group: &Group{ - multi: true, - }, - name: guessAlias(packagePath), - path: packagePath, - imports: map[string]importdef{}, - hints: map[string]importdef{}, - } -} - -// NewFilePathName creates a new file with the specified package path and name. -func NewFilePathName(packagePath, packageName string) *File { - return &File{ - Group: &Group{ - multi: true, - }, - name: packageName, - path: packagePath, - imports: map[string]importdef{}, - hints: map[string]importdef{}, - } -} - -// File represents a single source file. Package imports are managed -// automaticaly by File. -type File struct { - *Group - name string - path string - imports map[string]importdef - hints map[string]importdef - comments []string - headers []string - cgoPreamble []string - // If you're worried about generated package aliases conflicting with local variable names, you - // can set a prefix here. Package foo becomes {prefix}_foo. - PackagePrefix string - // CanonicalPath adds a canonical import path annotation to the package clause. - CanonicalPath string -} - -// importdef is used to differentiate packages where we know the package name from packages where the -// import is aliased. If alias == false, then name is the actual package name, and the import will be -// rendered without an alias. If used == false, the import has not been used in code yet and should be -// excluded from the import block. -type importdef struct { - name string - alias bool -} - -// HeaderComment adds a comment to the top of the file, above any package -// comments. A blank line is rendered below the header comments, ensuring -// header comments are not included in the package doc. -func (f *File) HeaderComment(comment string) { - f.headers = append(f.headers, comment) -} - -// PackageComment adds a comment to the top of the file, above the package -// keyword. -func (f *File) PackageComment(comment string) { - f.comments = append(f.comments, comment) -} - -// CgoPreamble adds a cgo preamble comment that is rendered directly before the "C" pseudo-package -// import. -func (f *File) CgoPreamble(comment string) { - f.cgoPreamble = append(f.cgoPreamble, comment) -} - -// Anon adds an anonymous import. -func (f *File) Anon(paths ...string) { - for _, p := range paths { - f.imports[p] = importdef{name: "_", alias: true} - } -} - -// ImportName provides the package name for a path. If specified, the alias will be omitted from the -// import block. This is optional. If not specified, a sensible package name is used based on the path -// and this is added as an alias in the import block. -func (f *File) ImportName(path, name string) { - f.hints[path] = importdef{name: name, alias: false} -} - -// ImportNames allows multiple names to be imported as a map. Use the [gennames](gennames) command to -// automatically generate a go file containing a map of a selection of package names. -func (f *File) ImportNames(names map[string]string) { - for path, name := range names { - f.hints[path] = importdef{name: name, alias: false} - } -} - -// ImportAlias provides the alias for a package path that should be used in the import block. A -// period can be used to force a dot-import. -func (f *File) ImportAlias(path, alias string) { - f.hints[path] = importdef{name: alias, alias: true} -} - -func (f *File) isLocal(path string) bool { - return f.path == path -} - -func (f *File) isValidAlias(alias string) bool { - // multiple dot-imports are ok - if alias == "." { - return true - } - // the import alias is invalid if it's a reserved word - if IsReservedWord(alias) { - return false - } - // the import alias is invalid if it's already been registered - for _, v := range f.imports { - if alias == v.name { - return false - } - } - return true -} - -func (f *File) isDotImport(path string) bool { - if id, ok := f.hints[path]; ok { - return id.name == "." && id.alias - } - return false -} - -func (f *File) register(path string) string { - if f.isLocal(path) { - // notest - // should never get here becasue in Qual the packageToken will be null, - // so render will never be called. - return "" - } - - // if the path has been registered previously, simply return the name - def := f.imports[path] - if def.name != "" && def.name != "_" { - return def.name - } - - // special case for "C" pseudo-package - if path == "C" { - f.imports["C"] = importdef{name: "C", alias: false} - return "C" - } - - var name string - var alias bool - - if hint := f.hints[path]; hint.name != "" { - // look up the path in the list of provided package names and aliases by ImportName / ImportAlias - name = hint.name - alias = hint.alias - } else if standardLibraryHints[path] != "" { - // look up the path in the list of standard library packages - name = standardLibraryHints[path] - alias = false - } else { - // if a hint is not found for the package, guess the alias from the package path - name = guessAlias(path) - alias = true - } - - // If the name is invalid or has been registered already, make it unique by appending a number - unique := name - i := 0 - for !f.isValidAlias(unique) { - i++ - unique = fmt.Sprintf("%s%d", name, i) - } - - // If we've changed the name to make it unique, it should definitely be an alias - if unique != name { - alias = true - } - - // Only add a prefix if the name is an alias - if f.PackagePrefix != "" && alias { - unique = f.PackagePrefix + "_" + unique - } - - // Register the eventual name - f.imports[path] = importdef{name: unique, alias: alias} - - return unique -} - -// GoString renders the File for testing. Any error will cause a panic. -func (f *File) GoString() string { - buf := &bytes.Buffer{} - if err := f.Render(buf); err != nil { - panic(err) - } - return buf.String() -} - -func guessAlias(path string) string { - alias := path - - if strings.HasSuffix(alias, "/") { - // training slashes are usually tolerated, so we can get rid of one if - // it exists - alias = alias[:len(alias)-1] - } - - if strings.Contains(alias, "/") { - // if the path contains a "/", use the last part - alias = alias[strings.LastIndex(alias, "/")+1:] - } - - // alias should be lower case - alias = strings.ToLower(alias) - - // alias should now only contain alphanumerics - importsRegex := regexp.MustCompile(`[^a-z0-9]`) - alias = importsRegex.ReplaceAllString(alias, "") - - // can't have a first digit, per Go identifier rules, so just skip them - for firstRune, runeLen := utf8.DecodeRuneInString(alias); unicode.IsDigit(firstRune); firstRune, runeLen = utf8.DecodeRuneInString(alias) { - alias = alias[runeLen:] - } - - // If path part was all digits, we may be left with an empty string. In this case use "pkg" as the alias. - if alias == "" { - alias = "pkg" - } - - return alias -} diff --git a/vendor/github.com/dave/jennifer/jen/generated.go b/vendor/github.com/dave/jennifer/jen/generated.go deleted file mode 100644 index 3983cf97c..000000000 --- a/vendor/github.com/dave/jennifer/jen/generated.go +++ /dev/null @@ -1,2274 +0,0 @@ -// This file is generated - do not edit. - -package jen - -// Parens renders a single item in parenthesis. Use for type conversion or to specify evaluation order. -func Parens(item Code) *Statement { - return newStatement().Parens(item) -} - -// Parens renders a single item in parenthesis. Use for type conversion or to specify evaluation order. -func (g *Group) Parens(item Code) *Statement { - s := Parens(item) - g.items = append(g.items, s) - return s -} - -// Parens renders a single item in parenthesis. Use for type conversion or to specify evaluation order. -func (s *Statement) Parens(item Code) *Statement { - g := &Group{ - close: ")", - items: []Code{item}, - multi: false, - name: "parens", - open: "(", - separator: "", - } - *s = append(*s, g) - return s -} - -// List renders a comma separated list. Use for multiple return functions. -func List(items ...Code) *Statement { - return newStatement().List(items...) -} - -// List renders a comma separated list. Use for multiple return functions. -func (g *Group) List(items ...Code) *Statement { - s := List(items...) - g.items = append(g.items, s) - return s -} - -// List renders a comma separated list. Use for multiple return functions. -func (s *Statement) List(items ...Code) *Statement { - g := &Group{ - close: "", - items: items, - multi: false, - name: "list", - open: "", - separator: ",", - } - *s = append(*s, g) - return s -} - -// ListFunc renders a comma separated list. Use for multiple return functions. -func ListFunc(f func(*Group)) *Statement { - return newStatement().ListFunc(f) -} - -// ListFunc renders a comma separated list. Use for multiple return functions. -func (g *Group) ListFunc(f func(*Group)) *Statement { - s := ListFunc(f) - g.items = append(g.items, s) - return s -} - -// ListFunc renders a comma separated list. Use for multiple return functions. -func (s *Statement) ListFunc(f func(*Group)) *Statement { - g := &Group{ - close: "", - multi: false, - name: "list", - open: "", - separator: ",", - } - f(g) - *s = append(*s, g) - return s -} - -// Values renders a comma separated list enclosed by curly braces. Use for slice or composite literals. -func Values(values ...Code) *Statement { - return newStatement().Values(values...) -} - -// Values renders a comma separated list enclosed by curly braces. Use for slice or composite literals. -func (g *Group) Values(values ...Code) *Statement { - s := Values(values...) - g.items = append(g.items, s) - return s -} - -// Values renders a comma separated list enclosed by curly braces. Use for slice or composite literals. -func (s *Statement) Values(values ...Code) *Statement { - g := &Group{ - close: "}", - items: values, - multi: false, - name: "values", - open: "{", - separator: ",", - } - *s = append(*s, g) - return s -} - -// ValuesFunc renders a comma separated list enclosed by curly braces. Use for slice or composite literals. -func ValuesFunc(f func(*Group)) *Statement { - return newStatement().ValuesFunc(f) -} - -// ValuesFunc renders a comma separated list enclosed by curly braces. Use for slice or composite literals. -func (g *Group) ValuesFunc(f func(*Group)) *Statement { - s := ValuesFunc(f) - g.items = append(g.items, s) - return s -} - -// ValuesFunc renders a comma separated list enclosed by curly braces. Use for slice or composite literals. -func (s *Statement) ValuesFunc(f func(*Group)) *Statement { - g := &Group{ - close: "}", - multi: false, - name: "values", - open: "{", - separator: ",", - } - f(g) - *s = append(*s, g) - return s -} - -// Index renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions. -func Index(items ...Code) *Statement { - return newStatement().Index(items...) -} - -// Index renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions. -func (g *Group) Index(items ...Code) *Statement { - s := Index(items...) - g.items = append(g.items, s) - return s -} - -// Index renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions. -func (s *Statement) Index(items ...Code) *Statement { - g := &Group{ - close: "]", - items: items, - multi: false, - name: "index", - open: "[", - separator: ":", - } - *s = append(*s, g) - return s -} - -// IndexFunc renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions. -func IndexFunc(f func(*Group)) *Statement { - return newStatement().IndexFunc(f) -} - -// IndexFunc renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions. -func (g *Group) IndexFunc(f func(*Group)) *Statement { - s := IndexFunc(f) - g.items = append(g.items, s) - return s -} - -// IndexFunc renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions. -func (s *Statement) IndexFunc(f func(*Group)) *Statement { - g := &Group{ - close: "]", - multi: false, - name: "index", - open: "[", - separator: ":", - } - f(g) - *s = append(*s, g) - return s -} - -// Block renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements. -func Block(statements ...Code) *Statement { - return newStatement().Block(statements...) -} - -// Block renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements. -func (g *Group) Block(statements ...Code) *Statement { - s := Block(statements...) - g.items = append(g.items, s) - return s -} - -// Block renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements. -func (s *Statement) Block(statements ...Code) *Statement { - g := &Group{ - close: "}", - items: statements, - multi: true, - name: "block", - open: "{", - separator: "", - } - *s = append(*s, g) - return s -} - -// BlockFunc renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements. -func BlockFunc(f func(*Group)) *Statement { - return newStatement().BlockFunc(f) -} - -// BlockFunc renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements. -func (g *Group) BlockFunc(f func(*Group)) *Statement { - s := BlockFunc(f) - g.items = append(g.items, s) - return s -} - -// BlockFunc renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements. -func (s *Statement) BlockFunc(f func(*Group)) *Statement { - g := &Group{ - close: "}", - multi: true, - name: "block", - open: "{", - separator: "", - } - f(g) - *s = append(*s, g) - return s -} - -// Defs renders a statement list enclosed in parenthesis. Use for definition lists. -func Defs(definitions ...Code) *Statement { - return newStatement().Defs(definitions...) -} - -// Defs renders a statement list enclosed in parenthesis. Use for definition lists. -func (g *Group) Defs(definitions ...Code) *Statement { - s := Defs(definitions...) - g.items = append(g.items, s) - return s -} - -// Defs renders a statement list enclosed in parenthesis. Use for definition lists. -func (s *Statement) Defs(definitions ...Code) *Statement { - g := &Group{ - close: ")", - items: definitions, - multi: true, - name: "defs", - open: "(", - separator: "", - } - *s = append(*s, g) - return s -} - -// DefsFunc renders a statement list enclosed in parenthesis. Use for definition lists. -func DefsFunc(f func(*Group)) *Statement { - return newStatement().DefsFunc(f) -} - -// DefsFunc renders a statement list enclosed in parenthesis. Use for definition lists. -func (g *Group) DefsFunc(f func(*Group)) *Statement { - s := DefsFunc(f) - g.items = append(g.items, s) - return s -} - -// DefsFunc renders a statement list enclosed in parenthesis. Use for definition lists. -func (s *Statement) DefsFunc(f func(*Group)) *Statement { - g := &Group{ - close: ")", - multi: true, - name: "defs", - open: "(", - separator: "", - } - f(g) - *s = append(*s, g) - return s -} - -// Call renders a comma separated list enclosed by parenthesis. Use for function calls. -func Call(params ...Code) *Statement { - return newStatement().Call(params...) -} - -// Call renders a comma separated list enclosed by parenthesis. Use for function calls. -func (g *Group) Call(params ...Code) *Statement { - s := Call(params...) - g.items = append(g.items, s) - return s -} - -// Call renders a comma separated list enclosed by parenthesis. Use for function calls. -func (s *Statement) Call(params ...Code) *Statement { - g := &Group{ - close: ")", - items: params, - multi: false, - name: "call", - open: "(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// CallFunc renders a comma separated list enclosed by parenthesis. Use for function calls. -func CallFunc(f func(*Group)) *Statement { - return newStatement().CallFunc(f) -} - -// CallFunc renders a comma separated list enclosed by parenthesis. Use for function calls. -func (g *Group) CallFunc(f func(*Group)) *Statement { - s := CallFunc(f) - g.items = append(g.items, s) - return s -} - -// CallFunc renders a comma separated list enclosed by parenthesis. Use for function calls. -func (s *Statement) CallFunc(f func(*Group)) *Statement { - g := &Group{ - close: ")", - multi: false, - name: "call", - open: "(", - separator: ",", - } - f(g) - *s = append(*s, g) - return s -} - -// Params renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers. -func Params(params ...Code) *Statement { - return newStatement().Params(params...) -} - -// Params renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers. -func (g *Group) Params(params ...Code) *Statement { - s := Params(params...) - g.items = append(g.items, s) - return s -} - -// Params renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers. -func (s *Statement) Params(params ...Code) *Statement { - g := &Group{ - close: ")", - items: params, - multi: false, - name: "params", - open: "(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// ParamsFunc renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers. -func ParamsFunc(f func(*Group)) *Statement { - return newStatement().ParamsFunc(f) -} - -// ParamsFunc renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers. -func (g *Group) ParamsFunc(f func(*Group)) *Statement { - s := ParamsFunc(f) - g.items = append(g.items, s) - return s -} - -// ParamsFunc renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers. -func (s *Statement) ParamsFunc(f func(*Group)) *Statement { - g := &Group{ - close: ")", - multi: false, - name: "params", - open: "(", - separator: ",", - } - f(g) - *s = append(*s, g) - return s -} - -// Assert renders a period followed by a single item enclosed by parenthesis. Use for type assertions. -func Assert(typ Code) *Statement { - return newStatement().Assert(typ) -} - -// Assert renders a period followed by a single item enclosed by parenthesis. Use for type assertions. -func (g *Group) Assert(typ Code) *Statement { - s := Assert(typ) - g.items = append(g.items, s) - return s -} - -// Assert renders a period followed by a single item enclosed by parenthesis. Use for type assertions. -func (s *Statement) Assert(typ Code) *Statement { - g := &Group{ - close: ")", - items: []Code{typ}, - multi: false, - name: "assert", - open: ".(", - separator: "", - } - *s = append(*s, g) - return s -} - -// Map renders the keyword followed by a single item enclosed by square brackets. Use for map definitions. -func Map(typ Code) *Statement { - return newStatement().Map(typ) -} - -// Map renders the keyword followed by a single item enclosed by square brackets. Use for map definitions. -func (g *Group) Map(typ Code) *Statement { - s := Map(typ) - g.items = append(g.items, s) - return s -} - -// Map renders the keyword followed by a single item enclosed by square brackets. Use for map definitions. -func (s *Statement) Map(typ Code) *Statement { - g := &Group{ - close: "]", - items: []Code{typ}, - multi: false, - name: "map", - open: "map[", - separator: "", - } - *s = append(*s, g) - return s -} - -// If renders the keyword followed by a semicolon separated list. -func If(conditions ...Code) *Statement { - return newStatement().If(conditions...) -} - -// If renders the keyword followed by a semicolon separated list. -func (g *Group) If(conditions ...Code) *Statement { - s := If(conditions...) - g.items = append(g.items, s) - return s -} - -// If renders the keyword followed by a semicolon separated list. -func (s *Statement) If(conditions ...Code) *Statement { - g := &Group{ - close: "", - items: conditions, - multi: false, - name: "if", - open: "if ", - separator: ";", - } - *s = append(*s, g) - return s -} - -// IfFunc renders the keyword followed by a semicolon separated list. -func IfFunc(f func(*Group)) *Statement { - return newStatement().IfFunc(f) -} - -// IfFunc renders the keyword followed by a semicolon separated list. -func (g *Group) IfFunc(f func(*Group)) *Statement { - s := IfFunc(f) - g.items = append(g.items, s) - return s -} - -// IfFunc renders the keyword followed by a semicolon separated list. -func (s *Statement) IfFunc(f func(*Group)) *Statement { - g := &Group{ - close: "", - multi: false, - name: "if", - open: "if ", - separator: ";", - } - f(g) - *s = append(*s, g) - return s -} - -// Return renders the keyword followed by a comma separated list. -func Return(results ...Code) *Statement { - return newStatement().Return(results...) -} - -// Return renders the keyword followed by a comma separated list. -func (g *Group) Return(results ...Code) *Statement { - s := Return(results...) - g.items = append(g.items, s) - return s -} - -// Return renders the keyword followed by a comma separated list. -func (s *Statement) Return(results ...Code) *Statement { - g := &Group{ - close: "", - items: results, - multi: false, - name: "return", - open: "return ", - separator: ",", - } - *s = append(*s, g) - return s -} - -// ReturnFunc renders the keyword followed by a comma separated list. -func ReturnFunc(f func(*Group)) *Statement { - return newStatement().ReturnFunc(f) -} - -// ReturnFunc renders the keyword followed by a comma separated list. -func (g *Group) ReturnFunc(f func(*Group)) *Statement { - s := ReturnFunc(f) - g.items = append(g.items, s) - return s -} - -// ReturnFunc renders the keyword followed by a comma separated list. -func (s *Statement) ReturnFunc(f func(*Group)) *Statement { - g := &Group{ - close: "", - multi: false, - name: "return", - open: "return ", - separator: ",", - } - f(g) - *s = append(*s, g) - return s -} - -// For renders the keyword followed by a semicolon separated list. -func For(conditions ...Code) *Statement { - return newStatement().For(conditions...) -} - -// For renders the keyword followed by a semicolon separated list. -func (g *Group) For(conditions ...Code) *Statement { - s := For(conditions...) - g.items = append(g.items, s) - return s -} - -// For renders the keyword followed by a semicolon separated list. -func (s *Statement) For(conditions ...Code) *Statement { - g := &Group{ - close: "", - items: conditions, - multi: false, - name: "for", - open: "for ", - separator: ";", - } - *s = append(*s, g) - return s -} - -// ForFunc renders the keyword followed by a semicolon separated list. -func ForFunc(f func(*Group)) *Statement { - return newStatement().ForFunc(f) -} - -// ForFunc renders the keyword followed by a semicolon separated list. -func (g *Group) ForFunc(f func(*Group)) *Statement { - s := ForFunc(f) - g.items = append(g.items, s) - return s -} - -// ForFunc renders the keyword followed by a semicolon separated list. -func (s *Statement) ForFunc(f func(*Group)) *Statement { - g := &Group{ - close: "", - multi: false, - name: "for", - open: "for ", - separator: ";", - } - f(g) - *s = append(*s, g) - return s -} - -// Switch renders the keyword followed by a semicolon separated list. -func Switch(conditions ...Code) *Statement { - return newStatement().Switch(conditions...) -} - -// Switch renders the keyword followed by a semicolon separated list. -func (g *Group) Switch(conditions ...Code) *Statement { - s := Switch(conditions...) - g.items = append(g.items, s) - return s -} - -// Switch renders the keyword followed by a semicolon separated list. -func (s *Statement) Switch(conditions ...Code) *Statement { - g := &Group{ - close: "", - items: conditions, - multi: false, - name: "switch", - open: "switch ", - separator: ";", - } - *s = append(*s, g) - return s -} - -// SwitchFunc renders the keyword followed by a semicolon separated list. -func SwitchFunc(f func(*Group)) *Statement { - return newStatement().SwitchFunc(f) -} - -// SwitchFunc renders the keyword followed by a semicolon separated list. -func (g *Group) SwitchFunc(f func(*Group)) *Statement { - s := SwitchFunc(f) - g.items = append(g.items, s) - return s -} - -// SwitchFunc renders the keyword followed by a semicolon separated list. -func (s *Statement) SwitchFunc(f func(*Group)) *Statement { - g := &Group{ - close: "", - multi: false, - name: "switch", - open: "switch ", - separator: ";", - } - f(g) - *s = append(*s, g) - return s -} - -// Interface renders the keyword followed by a method list enclosed by curly braces. -func Interface(methods ...Code) *Statement { - return newStatement().Interface(methods...) -} - -// Interface renders the keyword followed by a method list enclosed by curly braces. -func (g *Group) Interface(methods ...Code) *Statement { - s := Interface(methods...) - g.items = append(g.items, s) - return s -} - -// Interface renders the keyword followed by a method list enclosed by curly braces. -func (s *Statement) Interface(methods ...Code) *Statement { - g := &Group{ - close: "}", - items: methods, - multi: true, - name: "interface", - open: "interface{", - separator: "", - } - *s = append(*s, g) - return s -} - -// InterfaceFunc renders the keyword followed by a method list enclosed by curly braces. -func InterfaceFunc(f func(*Group)) *Statement { - return newStatement().InterfaceFunc(f) -} - -// InterfaceFunc renders the keyword followed by a method list enclosed by curly braces. -func (g *Group) InterfaceFunc(f func(*Group)) *Statement { - s := InterfaceFunc(f) - g.items = append(g.items, s) - return s -} - -// InterfaceFunc renders the keyword followed by a method list enclosed by curly braces. -func (s *Statement) InterfaceFunc(f func(*Group)) *Statement { - g := &Group{ - close: "}", - multi: true, - name: "interface", - open: "interface{", - separator: "", - } - f(g) - *s = append(*s, g) - return s -} - -// Struct renders the keyword followed by a field list enclosed by curly braces. -func Struct(fields ...Code) *Statement { - return newStatement().Struct(fields...) -} - -// Struct renders the keyword followed by a field list enclosed by curly braces. -func (g *Group) Struct(fields ...Code) *Statement { - s := Struct(fields...) - g.items = append(g.items, s) - return s -} - -// Struct renders the keyword followed by a field list enclosed by curly braces. -func (s *Statement) Struct(fields ...Code) *Statement { - g := &Group{ - close: "}", - items: fields, - multi: true, - name: "struct", - open: "struct{", - separator: "", - } - *s = append(*s, g) - return s -} - -// StructFunc renders the keyword followed by a field list enclosed by curly braces. -func StructFunc(f func(*Group)) *Statement { - return newStatement().StructFunc(f) -} - -// StructFunc renders the keyword followed by a field list enclosed by curly braces. -func (g *Group) StructFunc(f func(*Group)) *Statement { - s := StructFunc(f) - g.items = append(g.items, s) - return s -} - -// StructFunc renders the keyword followed by a field list enclosed by curly braces. -func (s *Statement) StructFunc(f func(*Group)) *Statement { - g := &Group{ - close: "}", - multi: true, - name: "struct", - open: "struct{", - separator: "", - } - f(g) - *s = append(*s, g) - return s -} - -// Case renders the keyword followed by a comma separated list. -func Case(cases ...Code) *Statement { - return newStatement().Case(cases...) -} - -// Case renders the keyword followed by a comma separated list. -func (g *Group) Case(cases ...Code) *Statement { - s := Case(cases...) - g.items = append(g.items, s) - return s -} - -// Case renders the keyword followed by a comma separated list. -func (s *Statement) Case(cases ...Code) *Statement { - g := &Group{ - close: ":", - items: cases, - multi: false, - name: "case", - open: "case ", - separator: ",", - } - *s = append(*s, g) - return s -} - -// CaseFunc renders the keyword followed by a comma separated list. -func CaseFunc(f func(*Group)) *Statement { - return newStatement().CaseFunc(f) -} - -// CaseFunc renders the keyword followed by a comma separated list. -func (g *Group) CaseFunc(f func(*Group)) *Statement { - s := CaseFunc(f) - g.items = append(g.items, s) - return s -} - -// CaseFunc renders the keyword followed by a comma separated list. -func (s *Statement) CaseFunc(f func(*Group)) *Statement { - g := &Group{ - close: ":", - multi: false, - name: "case", - open: "case ", - separator: ",", - } - f(g) - *s = append(*s, g) - return s -} - -// Append renders the append built-in function. -func Append(args ...Code) *Statement { - return newStatement().Append(args...) -} - -// Append renders the append built-in function. -func (g *Group) Append(args ...Code) *Statement { - s := Append(args...) - g.items = append(g.items, s) - return s -} - -// Append renders the append built-in function. -func (s *Statement) Append(args ...Code) *Statement { - g := &Group{ - close: ")", - items: args, - multi: false, - name: "append", - open: "append(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// AppendFunc renders the append built-in function. -func AppendFunc(f func(*Group)) *Statement { - return newStatement().AppendFunc(f) -} - -// AppendFunc renders the append built-in function. -func (g *Group) AppendFunc(f func(*Group)) *Statement { - s := AppendFunc(f) - g.items = append(g.items, s) - return s -} - -// AppendFunc renders the append built-in function. -func (s *Statement) AppendFunc(f func(*Group)) *Statement { - g := &Group{ - close: ")", - multi: false, - name: "append", - open: "append(", - separator: ",", - } - f(g) - *s = append(*s, g) - return s -} - -// Cap renders the cap built-in function. -func Cap(v Code) *Statement { - return newStatement().Cap(v) -} - -// Cap renders the cap built-in function. -func (g *Group) Cap(v Code) *Statement { - s := Cap(v) - g.items = append(g.items, s) - return s -} - -// Cap renders the cap built-in function. -func (s *Statement) Cap(v Code) *Statement { - g := &Group{ - close: ")", - items: []Code{v}, - multi: false, - name: "cap", - open: "cap(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// Close renders the close built-in function. -func Close(c Code) *Statement { - return newStatement().Close(c) -} - -// Close renders the close built-in function. -func (g *Group) Close(c Code) *Statement { - s := Close(c) - g.items = append(g.items, s) - return s -} - -// Close renders the close built-in function. -func (s *Statement) Close(c Code) *Statement { - g := &Group{ - close: ")", - items: []Code{c}, - multi: false, - name: "close", - open: "close(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// Complex renders the complex built-in function. -func Complex(r Code, i Code) *Statement { - return newStatement().Complex(r, i) -} - -// Complex renders the complex built-in function. -func (g *Group) Complex(r Code, i Code) *Statement { - s := Complex(r, i) - g.items = append(g.items, s) - return s -} - -// Complex renders the complex built-in function. -func (s *Statement) Complex(r Code, i Code) *Statement { - g := &Group{ - close: ")", - items: []Code{r, i}, - multi: false, - name: "complex", - open: "complex(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// Copy renders the copy built-in function. -func Copy(dst Code, src Code) *Statement { - return newStatement().Copy(dst, src) -} - -// Copy renders the copy built-in function. -func (g *Group) Copy(dst Code, src Code) *Statement { - s := Copy(dst, src) - g.items = append(g.items, s) - return s -} - -// Copy renders the copy built-in function. -func (s *Statement) Copy(dst Code, src Code) *Statement { - g := &Group{ - close: ")", - items: []Code{dst, src}, - multi: false, - name: "copy", - open: "copy(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// Delete renders the delete built-in function. -func Delete(m Code, key Code) *Statement { - return newStatement().Delete(m, key) -} - -// Delete renders the delete built-in function. -func (g *Group) Delete(m Code, key Code) *Statement { - s := Delete(m, key) - g.items = append(g.items, s) - return s -} - -// Delete renders the delete built-in function. -func (s *Statement) Delete(m Code, key Code) *Statement { - g := &Group{ - close: ")", - items: []Code{m, key}, - multi: false, - name: "delete", - open: "delete(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// Imag renders the imag built-in function. -func Imag(c Code) *Statement { - return newStatement().Imag(c) -} - -// Imag renders the imag built-in function. -func (g *Group) Imag(c Code) *Statement { - s := Imag(c) - g.items = append(g.items, s) - return s -} - -// Imag renders the imag built-in function. -func (s *Statement) Imag(c Code) *Statement { - g := &Group{ - close: ")", - items: []Code{c}, - multi: false, - name: "imag", - open: "imag(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// Len renders the len built-in function. -func Len(v Code) *Statement { - return newStatement().Len(v) -} - -// Len renders the len built-in function. -func (g *Group) Len(v Code) *Statement { - s := Len(v) - g.items = append(g.items, s) - return s -} - -// Len renders the len built-in function. -func (s *Statement) Len(v Code) *Statement { - g := &Group{ - close: ")", - items: []Code{v}, - multi: false, - name: "len", - open: "len(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// Make renders the make built-in function. The final parameter of the make function is optional, so it is represented by a variadic parameter list. -func Make(args ...Code) *Statement { - return newStatement().Make(args...) -} - -// Make renders the make built-in function. The final parameter of the make function is optional, so it is represented by a variadic parameter list. -func (g *Group) Make(args ...Code) *Statement { - s := Make(args...) - g.items = append(g.items, s) - return s -} - -// Make renders the make built-in function. The final parameter of the make function is optional, so it is represented by a variadic parameter list. -func (s *Statement) Make(args ...Code) *Statement { - g := &Group{ - close: ")", - items: args, - multi: false, - name: "make", - open: "make(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// New renders the new built-in function. -func New(typ Code) *Statement { - return newStatement().New(typ) -} - -// New renders the new built-in function. -func (g *Group) New(typ Code) *Statement { - s := New(typ) - g.items = append(g.items, s) - return s -} - -// New renders the new built-in function. -func (s *Statement) New(typ Code) *Statement { - g := &Group{ - close: ")", - items: []Code{typ}, - multi: false, - name: "new", - open: "new(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// Panic renders the panic built-in function. -func Panic(v Code) *Statement { - return newStatement().Panic(v) -} - -// Panic renders the panic built-in function. -func (g *Group) Panic(v Code) *Statement { - s := Panic(v) - g.items = append(g.items, s) - return s -} - -// Panic renders the panic built-in function. -func (s *Statement) Panic(v Code) *Statement { - g := &Group{ - close: ")", - items: []Code{v}, - multi: false, - name: "panic", - open: "panic(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// Print renders the print built-in function. -func Print(args ...Code) *Statement { - return newStatement().Print(args...) -} - -// Print renders the print built-in function. -func (g *Group) Print(args ...Code) *Statement { - s := Print(args...) - g.items = append(g.items, s) - return s -} - -// Print renders the print built-in function. -func (s *Statement) Print(args ...Code) *Statement { - g := &Group{ - close: ")", - items: args, - multi: false, - name: "print", - open: "print(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// PrintFunc renders the print built-in function. -func PrintFunc(f func(*Group)) *Statement { - return newStatement().PrintFunc(f) -} - -// PrintFunc renders the print built-in function. -func (g *Group) PrintFunc(f func(*Group)) *Statement { - s := PrintFunc(f) - g.items = append(g.items, s) - return s -} - -// PrintFunc renders the print built-in function. -func (s *Statement) PrintFunc(f func(*Group)) *Statement { - g := &Group{ - close: ")", - multi: false, - name: "print", - open: "print(", - separator: ",", - } - f(g) - *s = append(*s, g) - return s -} - -// Println renders the println built-in function. -func Println(args ...Code) *Statement { - return newStatement().Println(args...) -} - -// Println renders the println built-in function. -func (g *Group) Println(args ...Code) *Statement { - s := Println(args...) - g.items = append(g.items, s) - return s -} - -// Println renders the println built-in function. -func (s *Statement) Println(args ...Code) *Statement { - g := &Group{ - close: ")", - items: args, - multi: false, - name: "println", - open: "println(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// PrintlnFunc renders the println built-in function. -func PrintlnFunc(f func(*Group)) *Statement { - return newStatement().PrintlnFunc(f) -} - -// PrintlnFunc renders the println built-in function. -func (g *Group) PrintlnFunc(f func(*Group)) *Statement { - s := PrintlnFunc(f) - g.items = append(g.items, s) - return s -} - -// PrintlnFunc renders the println built-in function. -func (s *Statement) PrintlnFunc(f func(*Group)) *Statement { - g := &Group{ - close: ")", - multi: false, - name: "println", - open: "println(", - separator: ",", - } - f(g) - *s = append(*s, g) - return s -} - -// Real renders the real built-in function. -func Real(c Code) *Statement { - return newStatement().Real(c) -} - -// Real renders the real built-in function. -func (g *Group) Real(c Code) *Statement { - s := Real(c) - g.items = append(g.items, s) - return s -} - -// Real renders the real built-in function. -func (s *Statement) Real(c Code) *Statement { - g := &Group{ - close: ")", - items: []Code{c}, - multi: false, - name: "real", - open: "real(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// Recover renders the recover built-in function. -func Recover() *Statement { - return newStatement().Recover() -} - -// Recover renders the recover built-in function. -func (g *Group) Recover() *Statement { - s := Recover() - g.items = append(g.items, s) - return s -} - -// Recover renders the recover built-in function. -func (s *Statement) Recover() *Statement { - g := &Group{ - close: ")", - items: []Code{}, - multi: false, - name: "recover", - open: "recover(", - separator: ",", - } - *s = append(*s, g) - return s -} - -// Bool renders the bool identifier. -func Bool() *Statement { - return newStatement().Bool() -} - -// Bool renders the bool identifier. -func (g *Group) Bool() *Statement { - s := Bool() - g.items = append(g.items, s) - return s -} - -// Bool renders the bool identifier. -func (s *Statement) Bool() *Statement { - t := token{ - content: "bool", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Byte renders the byte identifier. -func Byte() *Statement { - // notest - return newStatement().Byte() -} - -// Byte renders the byte identifier. -func (g *Group) Byte() *Statement { - // notest - s := Byte() - g.items = append(g.items, s) - return s -} - -// Byte renders the byte identifier. -func (s *Statement) Byte() *Statement { - // notest - t := token{ - content: "byte", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Complex64 renders the complex64 identifier. -func Complex64() *Statement { - // notest - return newStatement().Complex64() -} - -// Complex64 renders the complex64 identifier. -func (g *Group) Complex64() *Statement { - // notest - s := Complex64() - g.items = append(g.items, s) - return s -} - -// Complex64 renders the complex64 identifier. -func (s *Statement) Complex64() *Statement { - // notest - t := token{ - content: "complex64", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Complex128 renders the complex128 identifier. -func Complex128() *Statement { - // notest - return newStatement().Complex128() -} - -// Complex128 renders the complex128 identifier. -func (g *Group) Complex128() *Statement { - // notest - s := Complex128() - g.items = append(g.items, s) - return s -} - -// Complex128 renders the complex128 identifier. -func (s *Statement) Complex128() *Statement { - // notest - t := token{ - content: "complex128", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Error renders the error identifier. -func Error() *Statement { - // notest - return newStatement().Error() -} - -// Error renders the error identifier. -func (g *Group) Error() *Statement { - // notest - s := Error() - g.items = append(g.items, s) - return s -} - -// Error renders the error identifier. -func (s *Statement) Error() *Statement { - // notest - t := token{ - content: "error", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Float32 renders the float32 identifier. -func Float32() *Statement { - // notest - return newStatement().Float32() -} - -// Float32 renders the float32 identifier. -func (g *Group) Float32() *Statement { - // notest - s := Float32() - g.items = append(g.items, s) - return s -} - -// Float32 renders the float32 identifier. -func (s *Statement) Float32() *Statement { - // notest - t := token{ - content: "float32", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Float64 renders the float64 identifier. -func Float64() *Statement { - // notest - return newStatement().Float64() -} - -// Float64 renders the float64 identifier. -func (g *Group) Float64() *Statement { - // notest - s := Float64() - g.items = append(g.items, s) - return s -} - -// Float64 renders the float64 identifier. -func (s *Statement) Float64() *Statement { - // notest - t := token{ - content: "float64", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Int renders the int identifier. -func Int() *Statement { - // notest - return newStatement().Int() -} - -// Int renders the int identifier. -func (g *Group) Int() *Statement { - // notest - s := Int() - g.items = append(g.items, s) - return s -} - -// Int renders the int identifier. -func (s *Statement) Int() *Statement { - // notest - t := token{ - content: "int", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Int8 renders the int8 identifier. -func Int8() *Statement { - // notest - return newStatement().Int8() -} - -// Int8 renders the int8 identifier. -func (g *Group) Int8() *Statement { - // notest - s := Int8() - g.items = append(g.items, s) - return s -} - -// Int8 renders the int8 identifier. -func (s *Statement) Int8() *Statement { - // notest - t := token{ - content: "int8", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Int16 renders the int16 identifier. -func Int16() *Statement { - // notest - return newStatement().Int16() -} - -// Int16 renders the int16 identifier. -func (g *Group) Int16() *Statement { - // notest - s := Int16() - g.items = append(g.items, s) - return s -} - -// Int16 renders the int16 identifier. -func (s *Statement) Int16() *Statement { - // notest - t := token{ - content: "int16", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Int32 renders the int32 identifier. -func Int32() *Statement { - // notest - return newStatement().Int32() -} - -// Int32 renders the int32 identifier. -func (g *Group) Int32() *Statement { - // notest - s := Int32() - g.items = append(g.items, s) - return s -} - -// Int32 renders the int32 identifier. -func (s *Statement) Int32() *Statement { - // notest - t := token{ - content: "int32", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Int64 renders the int64 identifier. -func Int64() *Statement { - // notest - return newStatement().Int64() -} - -// Int64 renders the int64 identifier. -func (g *Group) Int64() *Statement { - // notest - s := Int64() - g.items = append(g.items, s) - return s -} - -// Int64 renders the int64 identifier. -func (s *Statement) Int64() *Statement { - // notest - t := token{ - content: "int64", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Rune renders the rune identifier. -func Rune() *Statement { - // notest - return newStatement().Rune() -} - -// Rune renders the rune identifier. -func (g *Group) Rune() *Statement { - // notest - s := Rune() - g.items = append(g.items, s) - return s -} - -// Rune renders the rune identifier. -func (s *Statement) Rune() *Statement { - // notest - t := token{ - content: "rune", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// String renders the string identifier. -func String() *Statement { - // notest - return newStatement().String() -} - -// String renders the string identifier. -func (g *Group) String() *Statement { - // notest - s := String() - g.items = append(g.items, s) - return s -} - -// String renders the string identifier. -func (s *Statement) String() *Statement { - // notest - t := token{ - content: "string", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Uint renders the uint identifier. -func Uint() *Statement { - // notest - return newStatement().Uint() -} - -// Uint renders the uint identifier. -func (g *Group) Uint() *Statement { - // notest - s := Uint() - g.items = append(g.items, s) - return s -} - -// Uint renders the uint identifier. -func (s *Statement) Uint() *Statement { - // notest - t := token{ - content: "uint", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Uint8 renders the uint8 identifier. -func Uint8() *Statement { - // notest - return newStatement().Uint8() -} - -// Uint8 renders the uint8 identifier. -func (g *Group) Uint8() *Statement { - // notest - s := Uint8() - g.items = append(g.items, s) - return s -} - -// Uint8 renders the uint8 identifier. -func (s *Statement) Uint8() *Statement { - // notest - t := token{ - content: "uint8", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Uint16 renders the uint16 identifier. -func Uint16() *Statement { - // notest - return newStatement().Uint16() -} - -// Uint16 renders the uint16 identifier. -func (g *Group) Uint16() *Statement { - // notest - s := Uint16() - g.items = append(g.items, s) - return s -} - -// Uint16 renders the uint16 identifier. -func (s *Statement) Uint16() *Statement { - // notest - t := token{ - content: "uint16", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Uint32 renders the uint32 identifier. -func Uint32() *Statement { - // notest - return newStatement().Uint32() -} - -// Uint32 renders the uint32 identifier. -func (g *Group) Uint32() *Statement { - // notest - s := Uint32() - g.items = append(g.items, s) - return s -} - -// Uint32 renders the uint32 identifier. -func (s *Statement) Uint32() *Statement { - // notest - t := token{ - content: "uint32", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Uint64 renders the uint64 identifier. -func Uint64() *Statement { - // notest - return newStatement().Uint64() -} - -// Uint64 renders the uint64 identifier. -func (g *Group) Uint64() *Statement { - // notest - s := Uint64() - g.items = append(g.items, s) - return s -} - -// Uint64 renders the uint64 identifier. -func (s *Statement) Uint64() *Statement { - // notest - t := token{ - content: "uint64", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Uintptr renders the uintptr identifier. -func Uintptr() *Statement { - // notest - return newStatement().Uintptr() -} - -// Uintptr renders the uintptr identifier. -func (g *Group) Uintptr() *Statement { - // notest - s := Uintptr() - g.items = append(g.items, s) - return s -} - -// Uintptr renders the uintptr identifier. -func (s *Statement) Uintptr() *Statement { - // notest - t := token{ - content: "uintptr", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// True renders the true identifier. -func True() *Statement { - // notest - return newStatement().True() -} - -// True renders the true identifier. -func (g *Group) True() *Statement { - // notest - s := True() - g.items = append(g.items, s) - return s -} - -// True renders the true identifier. -func (s *Statement) True() *Statement { - // notest - t := token{ - content: "true", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// False renders the false identifier. -func False() *Statement { - // notest - return newStatement().False() -} - -// False renders the false identifier. -func (g *Group) False() *Statement { - // notest - s := False() - g.items = append(g.items, s) - return s -} - -// False renders the false identifier. -func (s *Statement) False() *Statement { - // notest - t := token{ - content: "false", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Iota renders the iota identifier. -func Iota() *Statement { - // notest - return newStatement().Iota() -} - -// Iota renders the iota identifier. -func (g *Group) Iota() *Statement { - // notest - s := Iota() - g.items = append(g.items, s) - return s -} - -// Iota renders the iota identifier. -func (s *Statement) Iota() *Statement { - // notest - t := token{ - content: "iota", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Nil renders the nil identifier. -func Nil() *Statement { - // notest - return newStatement().Nil() -} - -// Nil renders the nil identifier. -func (g *Group) Nil() *Statement { - // notest - s := Nil() - g.items = append(g.items, s) - return s -} - -// Nil renders the nil identifier. -func (s *Statement) Nil() *Statement { - // notest - t := token{ - content: "nil", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Err renders the err identifier. -func Err() *Statement { - // notest - return newStatement().Err() -} - -// Err renders the err identifier. -func (g *Group) Err() *Statement { - // notest - s := Err() - g.items = append(g.items, s) - return s -} - -// Err renders the err identifier. -func (s *Statement) Err() *Statement { - // notest - t := token{ - content: "err", - typ: identifierToken, - } - *s = append(*s, t) - return s -} - -// Break renders the break keyword. -func Break() *Statement { - // notest - return newStatement().Break() -} - -// Break renders the break keyword. -func (g *Group) Break() *Statement { - // notest - s := Break() - g.items = append(g.items, s) - return s -} - -// Break renders the break keyword. -func (s *Statement) Break() *Statement { - // notest - t := token{ - content: "break", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Default renders the default keyword. -func Default() *Statement { - // notest - return newStatement().Default() -} - -// Default renders the default keyword. -func (g *Group) Default() *Statement { - // notest - s := Default() - g.items = append(g.items, s) - return s -} - -// Default renders the default keyword. -func (s *Statement) Default() *Statement { - // notest - t := token{ - content: "default", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Func renders the func keyword. -func Func() *Statement { - // notest - return newStatement().Func() -} - -// Func renders the func keyword. -func (g *Group) Func() *Statement { - // notest - s := Func() - g.items = append(g.items, s) - return s -} - -// Func renders the func keyword. -func (s *Statement) Func() *Statement { - // notest - t := token{ - content: "func", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Select renders the select keyword. -func Select() *Statement { - // notest - return newStatement().Select() -} - -// Select renders the select keyword. -func (g *Group) Select() *Statement { - // notest - s := Select() - g.items = append(g.items, s) - return s -} - -// Select renders the select keyword. -func (s *Statement) Select() *Statement { - // notest - t := token{ - content: "select", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Chan renders the chan keyword. -func Chan() *Statement { - // notest - return newStatement().Chan() -} - -// Chan renders the chan keyword. -func (g *Group) Chan() *Statement { - // notest - s := Chan() - g.items = append(g.items, s) - return s -} - -// Chan renders the chan keyword. -func (s *Statement) Chan() *Statement { - // notest - t := token{ - content: "chan", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Else renders the else keyword. -func Else() *Statement { - // notest - return newStatement().Else() -} - -// Else renders the else keyword. -func (g *Group) Else() *Statement { - // notest - s := Else() - g.items = append(g.items, s) - return s -} - -// Else renders the else keyword. -func (s *Statement) Else() *Statement { - // notest - t := token{ - content: "else", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Const renders the const keyword. -func Const() *Statement { - // notest - return newStatement().Const() -} - -// Const renders the const keyword. -func (g *Group) Const() *Statement { - // notest - s := Const() - g.items = append(g.items, s) - return s -} - -// Const renders the const keyword. -func (s *Statement) Const() *Statement { - // notest - t := token{ - content: "const", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Fallthrough renders the fallthrough keyword. -func Fallthrough() *Statement { - // notest - return newStatement().Fallthrough() -} - -// Fallthrough renders the fallthrough keyword. -func (g *Group) Fallthrough() *Statement { - // notest - s := Fallthrough() - g.items = append(g.items, s) - return s -} - -// Fallthrough renders the fallthrough keyword. -func (s *Statement) Fallthrough() *Statement { - // notest - t := token{ - content: "fallthrough", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Type renders the type keyword. -func Type() *Statement { - // notest - return newStatement().Type() -} - -// Type renders the type keyword. -func (g *Group) Type() *Statement { - // notest - s := Type() - g.items = append(g.items, s) - return s -} - -// Type renders the type keyword. -func (s *Statement) Type() *Statement { - // notest - t := token{ - content: "type", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Continue renders the continue keyword. -func Continue() *Statement { - // notest - return newStatement().Continue() -} - -// Continue renders the continue keyword. -func (g *Group) Continue() *Statement { - // notest - s := Continue() - g.items = append(g.items, s) - return s -} - -// Continue renders the continue keyword. -func (s *Statement) Continue() *Statement { - // notest - t := token{ - content: "continue", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Var renders the var keyword. -func Var() *Statement { - // notest - return newStatement().Var() -} - -// Var renders the var keyword. -func (g *Group) Var() *Statement { - // notest - s := Var() - g.items = append(g.items, s) - return s -} - -// Var renders the var keyword. -func (s *Statement) Var() *Statement { - // notest - t := token{ - content: "var", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Goto renders the goto keyword. -func Goto() *Statement { - // notest - return newStatement().Goto() -} - -// Goto renders the goto keyword. -func (g *Group) Goto() *Statement { - // notest - s := Goto() - g.items = append(g.items, s) - return s -} - -// Goto renders the goto keyword. -func (s *Statement) Goto() *Statement { - // notest - t := token{ - content: "goto", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Defer renders the defer keyword. -func Defer() *Statement { - // notest - return newStatement().Defer() -} - -// Defer renders the defer keyword. -func (g *Group) Defer() *Statement { - // notest - s := Defer() - g.items = append(g.items, s) - return s -} - -// Defer renders the defer keyword. -func (s *Statement) Defer() *Statement { - // notest - t := token{ - content: "defer", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Go renders the go keyword. -func Go() *Statement { - // notest - return newStatement().Go() -} - -// Go renders the go keyword. -func (g *Group) Go() *Statement { - // notest - s := Go() - g.items = append(g.items, s) - return s -} - -// Go renders the go keyword. -func (s *Statement) Go() *Statement { - // notest - t := token{ - content: "go", - typ: keywordToken, - } - *s = append(*s, t) - return s -} - -// Range renders the range keyword. -func Range() *Statement { - // notest - return newStatement().Range() -} - -// Range renders the range keyword. -func (g *Group) Range() *Statement { - // notest - s := Range() - g.items = append(g.items, s) - return s -} - -// Range renders the range keyword. -func (s *Statement) Range() *Statement { - // notest - t := token{ - content: "range", - typ: keywordToken, - } - *s = append(*s, t) - return s -} diff --git a/vendor/github.com/dave/jennifer/jen/group.go b/vendor/github.com/dave/jennifer/jen/group.go deleted file mode 100644 index 0b85c9017..000000000 --- a/vendor/github.com/dave/jennifer/jen/group.go +++ /dev/null @@ -1,147 +0,0 @@ -package jen - -import ( - "bytes" - "fmt" - "go/format" - "io" -) - -// Group represents a list of Code items, separated by tokens with an optional -// open and close token. -type Group struct { - name string - items []Code - open string - close string - separator string - multi bool -} - -func (g *Group) isNull(f *File) bool { - if g == nil { - return true - } - if g.open != "" || g.close != "" { - return false - } - for _, c := range g.items { - if !c.isNull(f) { - return false - } - } - return true -} - -func (g *Group) render(f *File, w io.Writer, s *Statement) error { - if g.name == "block" && s != nil { - // Special CaseBlock format for then the previous item in the statement - // is a Case group or the default keyword. - prev := s.previous(g) - grp, isGrp := prev.(*Group) - tkn, isTkn := prev.(token) - if isGrp && grp.name == "case" || isTkn && tkn.content == "default" { - g.open = "" - g.close = "" - } - } - if g.open != "" { - if _, err := w.Write([]byte(g.open)); err != nil { - return err - } - } - isNull, err := g.renderItems(f, w) - if err != nil { - return err - } - if !isNull && g.multi && g.close != "" { - // For multi-line blocks with a closing token, we insert a new line after the last item (but - // not if all items were null). This is to ensure that if the statement finishes with a comment, - // the closing token is not commented out. - s := "\n" - if g.separator == "," { - // We also insert add trailing comma if the separator was ",". - s = ",\n" - } - if _, err := w.Write([]byte(s)); err != nil { - return err - } - } - if g.close != "" { - if _, err := w.Write([]byte(g.close)); err != nil { - return err - } - } - return nil -} - -func (g *Group) renderItems(f *File, w io.Writer) (isNull bool, err error) { - first := true - for _, code := range g.items { - if pt, ok := code.(token); ok && pt.typ == packageToken { - // Special case for package tokens in Qual groups - for dot-imports, the package token - // will be null, so will not render and will not be registered in the imports block. - // This ensures all packageTokens that are rendered are registered. - f.register(pt.content.(string)) - } - if code == nil || code.isNull(f) { - // Null() token produces no output but also - // no separator. Empty() token products no - // output but adds a separator. - continue - } - if g.name == "values" { - if _, ok := code.(Dict); ok && len(g.items) > 1 { - panic("Error in Values: if Dict is used, must be one item only") - } - } - if !first && g.separator != "" { - // The separator token is added before each non-null item, but not before the first item. - if _, err := w.Write([]byte(g.separator)); err != nil { - return false, err - } - } - if g.multi { - // For multi-line blocks, we insert a new line before each non-null item. - if _, err := w.Write([]byte("\n")); err != nil { - return false, err - } - } - if err := code.render(f, w, nil); err != nil { - return false, err - } - first = false - } - return first, nil -} - -// Render renders the Group to the provided writer. -func (g *Group) Render(writer io.Writer) error { - return g.RenderWithFile(writer, NewFile("")) -} - -// GoString renders the Group for testing. Any error will cause a panic. -func (g *Group) GoString() string { - buf := bytes.Buffer{} - if err := g.Render(&buf); err != nil { - panic(err) - } - return buf.String() -} - -// RenderWithFile renders the Group to the provided writer, using imports from the provided file. -func (g *Group) RenderWithFile(writer io.Writer, file *File) error { - buf := &bytes.Buffer{} - if err := g.render(file, buf, nil); err != nil { - return err - } - b, err := format.Source(buf.Bytes()) - if err != nil { - return fmt.Errorf("Error %s while formatting source:\n%s", err, buf.String()) - } - if _, err := writer.Write(b); err != nil { - return err - } - return nil -} - diff --git a/vendor/github.com/dave/jennifer/jen/hints.go b/vendor/github.com/dave/jennifer/jen/hints.go deleted file mode 100644 index 7bc307a65..000000000 --- a/vendor/github.com/dave/jennifer/jen/hints.go +++ /dev/null @@ -1,273 +0,0 @@ -// This file is generated - do not edit. - -package jen - -// standardLibraryHints contains package name hints -var standardLibraryHints = map[string]string{ - "archive/tar": "tar", - "archive/zip": "zip", - "bufio": "bufio", - "builtin": "builtin", - "bytes": "bytes", - "cmd/asm/internal/arch": "arch", - "cmd/asm/internal/asm": "asm", - "cmd/asm/internal/flags": "flags", - "cmd/asm/internal/lex": "lex", - "cmd/compile/internal/amd64": "amd64", - "cmd/compile/internal/arm": "arm", - "cmd/compile/internal/arm64": "arm64", - "cmd/compile/internal/gc": "gc", - "cmd/compile/internal/mips": "mips", - "cmd/compile/internal/mips64": "mips64", - "cmd/compile/internal/ppc64": "ppc64", - "cmd/compile/internal/s390x": "s390x", - "cmd/compile/internal/ssa": "ssa", - "cmd/compile/internal/syntax": "syntax", - "cmd/compile/internal/test": "test", - "cmd/compile/internal/types": "types", - "cmd/compile/internal/wasm": "wasm", - "cmd/compile/internal/x86": "x86", - "cmd/go/internal/base": "base", - "cmd/go/internal/bug": "bug", - "cmd/go/internal/cache": "cache", - "cmd/go/internal/cfg": "cfg", - "cmd/go/internal/clean": "clean", - "cmd/go/internal/cmdflag": "cmdflag", - "cmd/go/internal/dirhash": "dirhash", - "cmd/go/internal/doc": "doc", - "cmd/go/internal/envcmd": "envcmd", - "cmd/go/internal/fix": "fix", - "cmd/go/internal/fmtcmd": "fmtcmd", - "cmd/go/internal/generate": "generate", - "cmd/go/internal/get": "get", - "cmd/go/internal/help": "help", - "cmd/go/internal/imports": "imports", - "cmd/go/internal/list": "list", - "cmd/go/internal/load": "load", - "cmd/go/internal/modcmd": "modcmd", - "cmd/go/internal/modconv": "modconv", - "cmd/go/internal/modfetch": "modfetch", - "cmd/go/internal/modfetch/codehost": "codehost", - "cmd/go/internal/modfile": "modfile", - "cmd/go/internal/modget": "modget", - "cmd/go/internal/modinfo": "modinfo", - "cmd/go/internal/modload": "modload", - "cmd/go/internal/module": "module", - "cmd/go/internal/mvs": "mvs", - "cmd/go/internal/par": "par", - "cmd/go/internal/run": "run", - "cmd/go/internal/search": "search", - "cmd/go/internal/semver": "semver", - "cmd/go/internal/str": "str", - "cmd/go/internal/test": "test", - "cmd/go/internal/tool": "tool", - "cmd/go/internal/txtar": "txtar", - "cmd/go/internal/version": "version", - "cmd/go/internal/vet": "vet", - "cmd/go/internal/web": "web", - "cmd/go/internal/web2": "web2", - "cmd/go/internal/webtest": "webtest", - "cmd/go/internal/work": "work", - "cmd/internal/bio": "bio", - "cmd/internal/browser": "browser", - "cmd/internal/buildid": "buildid", - "cmd/internal/dwarf": "dwarf", - "cmd/internal/edit": "edit", - "cmd/internal/gcprog": "gcprog", - "cmd/internal/goobj": "goobj", - "cmd/internal/obj": "obj", - "cmd/internal/obj/arm": "arm", - "cmd/internal/obj/arm64": "arm64", - "cmd/internal/obj/mips": "mips", - "cmd/internal/obj/ppc64": "ppc64", - "cmd/internal/obj/s390x": "s390x", - "cmd/internal/obj/wasm": "wasm", - "cmd/internal/obj/x86": "x86", - "cmd/internal/objabi": "objabi", - "cmd/internal/objfile": "objfile", - "cmd/internal/src": "src", - "cmd/internal/sys": "sys", - "cmd/internal/test2json": "test2json", - "cmd/link/internal/amd64": "amd64", - "cmd/link/internal/arm": "arm", - "cmd/link/internal/arm64": "arm64", - "cmd/link/internal/ld": "ld", - "cmd/link/internal/loadelf": "loadelf", - "cmd/link/internal/loadmacho": "loadmacho", - "cmd/link/internal/loadpe": "loadpe", - "cmd/link/internal/mips": "mips", - "cmd/link/internal/mips64": "mips64", - "cmd/link/internal/objfile": "objfile", - "cmd/link/internal/ppc64": "ppc64", - "cmd/link/internal/s390x": "s390x", - "cmd/link/internal/sym": "sym", - "cmd/link/internal/wasm": "wasm", - "cmd/link/internal/x86": "x86", - "cmd/vet/internal/cfg": "cfg", - "cmd/vet/internal/whitelist": "whitelist", - "compress/bzip2": "bzip2", - "compress/flate": "flate", - "compress/gzip": "gzip", - "compress/lzw": "lzw", - "compress/zlib": "zlib", - "container/heap": "heap", - "container/list": "list", - "container/ring": "ring", - "context": "context", - "crypto": "crypto", - "crypto/aes": "aes", - "crypto/cipher": "cipher", - "crypto/des": "des", - "crypto/dsa": "dsa", - "crypto/ecdsa": "ecdsa", - "crypto/elliptic": "elliptic", - "crypto/hmac": "hmac", - "crypto/internal/randutil": "randutil", - "crypto/internal/subtle": "subtle", - "crypto/md5": "md5", - "crypto/rand": "rand", - "crypto/rc4": "rc4", - "crypto/rsa": "rsa", - "crypto/sha1": "sha1", - "crypto/sha256": "sha256", - "crypto/sha512": "sha512", - "crypto/subtle": "subtle", - "crypto/tls": "tls", - "crypto/x509": "x509", - "crypto/x509/pkix": "pkix", - "database/sql": "sql", - "database/sql/driver": "driver", - "debug/dwarf": "dwarf", - "debug/elf": "elf", - "debug/gosym": "gosym", - "debug/macho": "macho", - "debug/pe": "pe", - "debug/plan9obj": "plan9obj", - "encoding": "encoding", - "encoding/ascii85": "ascii85", - "encoding/asn1": "asn1", - "encoding/base32": "base32", - "encoding/base64": "base64", - "encoding/binary": "binary", - "encoding/csv": "csv", - "encoding/gob": "gob", - "encoding/hex": "hex", - "encoding/json": "json", - "encoding/pem": "pem", - "encoding/xml": "xml", - "errors": "errors", - "expvar": "expvar", - "flag": "flag", - "fmt": "fmt", - "go/ast": "ast", - "go/build": "build", - "go/constant": "constant", - "go/doc": "doc", - "go/format": "format", - "go/importer": "importer", - "go/internal/gccgoimporter": "gccgoimporter", - "go/internal/gcimporter": "gcimporter", - "go/internal/srcimporter": "srcimporter", - "go/parser": "parser", - "go/printer": "printer", - "go/scanner": "scanner", - "go/token": "token", - "go/types": "types", - "hash": "hash", - "hash/adler32": "adler32", - "hash/crc32": "crc32", - "hash/crc64": "crc64", - "hash/fnv": "fnv", - "html": "html", - "html/template": "template", - "image": "image", - "image/color": "color", - "image/color/palette": "palette", - "image/draw": "draw", - "image/gif": "gif", - "image/internal/imageutil": "imageutil", - "image/jpeg": "jpeg", - "image/png": "png", - "index/suffixarray": "suffixarray", - "internal/bytealg": "bytealg", - "internal/cpu": "cpu", - "internal/nettrace": "nettrace", - "internal/poll": "poll", - "internal/race": "race", - "internal/singleflight": "singleflight", - "internal/syscall/unix": "unix", - "internal/syscall/windows": "windows", - "internal/syscall/windows/registry": "registry", - "internal/syscall/windows/sysdll": "sysdll", - "internal/testenv": "testenv", - "internal/testlog": "testlog", - "internal/trace": "trace", - "io": "io", - "io/ioutil": "ioutil", - "log": "log", - "log/syslog": "syslog", - "math": "math", - "math/big": "big", - "math/bits": "bits", - "math/cmplx": "cmplx", - "math/rand": "rand", - "mime": "mime", - "mime/multipart": "multipart", - "mime/quotedprintable": "quotedprintable", - "net": "net", - "net/http": "http", - "net/http/cgi": "cgi", - "net/http/cookiejar": "cookiejar", - "net/http/fcgi": "fcgi", - "net/http/httptest": "httptest", - "net/http/httptrace": "httptrace", - "net/http/httputil": "httputil", - "net/http/internal": "internal", - "net/http/pprof": "pprof", - "net/internal/socktest": "socktest", - "net/mail": "mail", - "net/rpc": "rpc", - "net/rpc/jsonrpc": "jsonrpc", - "net/smtp": "smtp", - "net/textproto": "textproto", - "net/url": "url", - "os": "os", - "os/exec": "exec", - "os/signal": "signal", - "os/signal/internal/pty": "pty", - "os/user": "user", - "path": "path", - "path/filepath": "filepath", - "plugin": "plugin", - "reflect": "reflect", - "regexp": "regexp", - "regexp/syntax": "syntax", - "runtime": "runtime", - "runtime/cgo": "cgo", - "runtime/debug": "debug", - "runtime/internal/atomic": "atomic", - "runtime/internal/sys": "sys", - "runtime/pprof": "pprof", - "runtime/pprof/internal/profile": "profile", - "runtime/race": "race", - "runtime/trace": "trace", - "sort": "sort", - "strconv": "strconv", - "strings": "strings", - "sync": "sync", - "sync/atomic": "atomic", - "syscall": "syscall", - "testing": "testing", - "testing/internal/testdeps": "testdeps", - "testing/iotest": "iotest", - "testing/quick": "quick", - "text/scanner": "scanner", - "text/tabwriter": "tabwriter", - "text/template": "template", - "text/template/parse": "parse", - "time": "time", - "unicode": "unicode", - "unicode/utf16": "utf16", - "unicode/utf8": "utf8", - "unsafe": "unsafe", -} diff --git a/vendor/github.com/dave/jennifer/jen/jen.go b/vendor/github.com/dave/jennifer/jen/jen.go deleted file mode 100644 index 4cf480a14..000000000 --- a/vendor/github.com/dave/jennifer/jen/jen.go +++ /dev/null @@ -1,168 +0,0 @@ -// Package jen is a code generator for Go -package jen - -import ( - "bytes" - "fmt" - "go/format" - "io" - "io/ioutil" - "sort" - "strconv" -) - -// Code represents an item of code that can be rendered. -type Code interface { - render(f *File, w io.Writer, s *Statement) error - isNull(f *File) bool -} - -// Save renders the file and saves to the filename provided. -func (f *File) Save(filename string) error { - // notest - buf := &bytes.Buffer{} - if err := f.Render(buf); err != nil { - return err - } - if err := ioutil.WriteFile(filename, buf.Bytes(), 0644); err != nil { - return err - } - return nil -} - -// Render renders the file to the provided writer. -func (f *File) Render(w io.Writer) error { - body := &bytes.Buffer{} - if err := f.render(f, body, nil); err != nil { - return err - } - source := &bytes.Buffer{} - if len(f.headers) > 0 { - for _, c := range f.headers { - if err := Comment(c).render(f, source, nil); err != nil { - return err - } - if _, err := fmt.Fprint(source, "\n"); err != nil { - return err - } - } - // Append an extra newline so that header comments don't get lumped in - // with package comments. - if _, err := fmt.Fprint(source, "\n"); err != nil { - return err - } - } - for _, c := range f.comments { - if err := Comment(c).render(f, source, nil); err != nil { - return err - } - if _, err := fmt.Fprint(source, "\n"); err != nil { - return err - } - } - if _, err := fmt.Fprintf(source, "package %s", f.name); err != nil { - return err - } - if f.CanonicalPath != "" { - if _, err := fmt.Fprintf(source, " // import %q", f.CanonicalPath); err != nil { - return err - } - } - if _, err := fmt.Fprint(source, "\n\n"); err != nil { - return err - } - if err := f.renderImports(source); err != nil { - return err - } - if _, err := source.Write(body.Bytes()); err != nil { - return err - } - formatted, err := format.Source(source.Bytes()) - if err != nil { - return fmt.Errorf("Error %s while formatting source:\n%s", err, source.String()) - } - if _, err := w.Write(formatted); err != nil { - return err - } - return nil -} - -func (f *File) renderImports(source io.Writer) error { - - // Render the "C" import if it's been used in a `Qual`, `Anon` or if there's a preamble comment - hasCgo := f.imports["C"].name != "" || len(f.cgoPreamble) > 0 - - // Only separate the import from the main imports block if there's a preamble - separateCgo := hasCgo && len(f.cgoPreamble) > 0 - - filtered := map[string]importdef{} - for path, def := range f.imports { - // filter out the "C" pseudo-package so it's not rendered in a block with the other - // imports, but only if it is accompanied by a preamble comment - if path == "C" && separateCgo { - continue - } - filtered[path] = def - } - - if len(filtered) == 1 { - for path, def := range filtered { - if def.alias && path != "C" { - // "C" package should be rendered without alias even when used as an anonymous import - // (e.g. should never have an underscore). - if _, err := fmt.Fprintf(source, "import %s %s\n\n", def.name, strconv.Quote(path)); err != nil { - return err - } - } else { - if _, err := fmt.Fprintf(source, "import %s\n\n", strconv.Quote(path)); err != nil { - return err - } - } - } - } else if len(filtered) > 1 { - if _, err := fmt.Fprint(source, "import (\n"); err != nil { - return err - } - // We must sort the imports to ensure repeatable - // source. - paths := []string{} - for path := range filtered { - paths = append(paths, path) - } - sort.Strings(paths) - for _, path := range paths { - def := filtered[path] - if def.alias && path != "C" { - // "C" package should be rendered without alias even when used as an anonymous import - // (e.g. should never have an underscore). - if _, err := fmt.Fprintf(source, "%s %s\n", def.name, strconv.Quote(path)); err != nil { - return err - } - - } else { - if _, err := fmt.Fprintf(source, "%s\n", strconv.Quote(path)); err != nil { - return err - } - } - } - if _, err := fmt.Fprint(source, ")\n\n"); err != nil { - return err - } - } - - if separateCgo { - for _, c := range f.cgoPreamble { - if err := Comment(c).render(f, source, nil); err != nil { - return err - } - if _, err := fmt.Fprint(source, "\n"); err != nil { - return err - } - } - if _, err := fmt.Fprint(source, "import \"C\"\n\n"); err != nil { - return err - } - } - - return nil -} diff --git a/vendor/github.com/dave/jennifer/jen/lit.go b/vendor/github.com/dave/jennifer/jen/lit.go deleted file mode 100644 index 9791f1d2c..000000000 --- a/vendor/github.com/dave/jennifer/jen/lit.go +++ /dev/null @@ -1,154 +0,0 @@ -package jen - -// Lit renders a literal. Lit supports only built-in types (bool, string, int, complex128, float64, -// float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64). -// Passing any other type will panic. -func Lit(v interface{}) *Statement { - return newStatement().Lit(v) -} - -// Lit renders a literal. Lit supports only built-in types (bool, string, int, complex128, float64, -// float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64). -// Passing any other type will panic. -func (g *Group) Lit(v interface{}) *Statement { - s := Lit(v) - g.items = append(g.items, s) - return s -} - -// Lit renders a literal. Lit supports only built-in types (bool, string, int, complex128, float64, -// float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64). -// Passing any other type will panic. -func (s *Statement) Lit(v interface{}) *Statement { - t := token{ - typ: literalToken, - content: v, - } - *s = append(*s, t) - return s -} - -// LitFunc renders a literal. LitFunc generates the value to render by executing the provided -// function. LitFunc supports only built-in types (bool, string, int, complex128, float64, float32, -// int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64). -// Returning any other type will panic. -func LitFunc(f func() interface{}) *Statement { - return newStatement().LitFunc(f) -} - -// LitFunc renders a literal. LitFunc generates the value to render by executing the provided -// function. LitFunc supports only built-in types (bool, string, int, complex128, float64, float32, -// int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64). -// Returning any other type will panic. -func (g *Group) LitFunc(f func() interface{}) *Statement { - s := LitFunc(f) - g.items = append(g.items, s) - return s -} - -// LitFunc renders a literal. LitFunc generates the value to render by executing the provided -// function. LitFunc supports only built-in types (bool, string, int, complex128, float64, float32, -// int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64). -// Returning any other type will panic. -func (s *Statement) LitFunc(f func() interface{}) *Statement { - t := token{ - typ: literalToken, - content: f(), - } - *s = append(*s, t) - return s -} - -// LitRune renders a rune literal. -func LitRune(v rune) *Statement { - return newStatement().LitRune(v) -} - -// LitRune renders a rune literal. -func (g *Group) LitRune(v rune) *Statement { - s := LitRune(v) - g.items = append(g.items, s) - return s -} - -// LitRune renders a rune literal. -func (s *Statement) LitRune(v rune) *Statement { - t := token{ - typ: literalRuneToken, - content: v, - } - *s = append(*s, t) - return s -} - -// LitRuneFunc renders a rune literal. LitRuneFunc generates the value to -// render by executing the provided function. -func LitRuneFunc(f func() rune) *Statement { - return newStatement().LitRuneFunc(f) -} - -// LitRuneFunc renders a rune literal. LitRuneFunc generates the value to -// render by executing the provided function. -func (g *Group) LitRuneFunc(f func() rune) *Statement { - s := LitRuneFunc(f) - g.items = append(g.items, s) - return s -} - -// LitRuneFunc renders a rune literal. LitRuneFunc generates the value to -// render by executing the provided function. -func (s *Statement) LitRuneFunc(f func() rune) *Statement { - t := token{ - typ: literalRuneToken, - content: f(), - } - *s = append(*s, t) - return s -} - -// LitByte renders a byte literal. -func LitByte(v byte) *Statement { - return newStatement().LitByte(v) -} - -// LitByte renders a byte literal. -func (g *Group) LitByte(v byte) *Statement { - s := LitByte(v) - g.items = append(g.items, s) - return s -} - -// LitByte renders a byte literal. -func (s *Statement) LitByte(v byte) *Statement { - t := token{ - typ: literalByteToken, - content: v, - } - *s = append(*s, t) - return s -} - -// LitByteFunc renders a byte literal. LitByteFunc generates the value to -// render by executing the provided function. -func LitByteFunc(f func() byte) *Statement { - return newStatement().LitByteFunc(f) -} - -// LitByteFunc renders a byte literal. LitByteFunc generates the value to -// render by executing the provided function. -func (g *Group) LitByteFunc(f func() byte) *Statement { - s := LitByteFunc(f) - g.items = append(g.items, s) - return s -} - -// LitByteFunc renders a byte literal. LitByteFunc generates the value to -// render by executing the provided function. -func (s *Statement) LitByteFunc(f func() byte) *Statement { - t := token{ - typ: literalByteToken, - content: f(), - } - *s = append(*s, t) - return s -} diff --git a/vendor/github.com/dave/jennifer/jen/reserved.go b/vendor/github.com/dave/jennifer/jen/reserved.go deleted file mode 100644 index 457668eff..000000000 --- a/vendor/github.com/dave/jennifer/jen/reserved.go +++ /dev/null @@ -1,20 +0,0 @@ -package jen - -var reserved = []string{ - /* keywords */ - "break", "default", "func", "interface", "select", "case", "defer", "go", "map", "struct", "chan", "else", "goto", "package", "switch", "const", "fallthrough", "if", "range", "type", "continue", "for", "import", "return", "var", - /* predeclared */ - "bool", "byte", "complex64", "complex128", "error", "float32", "float64", "int", "int8", "int16", "int32", "int64", "rune", "string", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr", "true", "false", "iota", "nil", "append", "cap", "close", "complex", "copy", "delete", "imag", "len", "make", "new", "panic", "print", "println", "real", "recover", - /* common variables */ - "err", -} - -// IsReservedWord returns if this is a reserved word in go -func IsReservedWord(alias string) bool { - for _, name := range reserved { - if alias == name { - return true - } - } - return false -} diff --git a/vendor/github.com/dave/jennifer/jen/statement.go b/vendor/github.com/dave/jennifer/jen/statement.go deleted file mode 100644 index aa9ec4977..000000000 --- a/vendor/github.com/dave/jennifer/jen/statement.go +++ /dev/null @@ -1,101 +0,0 @@ -package jen - -import ( - "bytes" - "fmt" - "go/format" - "io" -) - -// Statement represents a simple list of code items. When rendered the items -// are separated by spaces. -type Statement []Code - -func newStatement() *Statement { - return &Statement{} -} - -// Clone makes a copy of the Statement, so further tokens can be appended -// without affecting the original. -func (s *Statement) Clone() *Statement { - return &Statement{s} -} - -func (s *Statement) previous(c Code) Code { - index := -1 - for i, item := range *s { - if item == c { - index = i - break - } - } - if index > 0 { - return (*s)[index-1] - } - return nil -} - -func (s *Statement) isNull(f *File) bool { - if s == nil { - return true - } - for _, c := range *s { - if !c.isNull(f) { - return false - } - } - return true -} - -func (s *Statement) render(f *File, w io.Writer, _ *Statement) error { - first := true - for _, code := range *s { - if code == nil || code.isNull(f) { - // Null() token produces no output but also - // no separator. Empty() token products no - // output but adds a separator. - continue - } - if !first { - if _, err := w.Write([]byte(" ")); err != nil { - return err - } - } - if err := code.render(f, w, s); err != nil { - return err - } - first = false - } - return nil -} - -// Render renders the Statement to the provided writer. -func (s *Statement) Render(writer io.Writer) error { - return s.RenderWithFile(writer, NewFile("")) -} - -// GoString renders the Statement for testing. Any error will cause a panic. -func (s *Statement) GoString() string { - buf := bytes.Buffer{} - if err := s.Render(&buf); err != nil { - panic(err) - } - return buf.String() -} - -// RenderWithFile renders the Statement to the provided writer, using imports from the provided file. -func (s *Statement) RenderWithFile(writer io.Writer, file *File) error { - buf := &bytes.Buffer{} - if err := s.render(file, buf, nil); err != nil { - return err - } - b, err := format.Source(buf.Bytes()) - if err != nil { - return fmt.Errorf("Error %s while formatting source:\n%s", err, buf.String()) - } - if _, err := writer.Write(b); err != nil { - return err - } - return nil -} - diff --git a/vendor/github.com/dave/jennifer/jen/tag.go b/vendor/github.com/dave/jennifer/jen/tag.go deleted file mode 100644 index ad99aafdf..000000000 --- a/vendor/github.com/dave/jennifer/jen/tag.go +++ /dev/null @@ -1,76 +0,0 @@ -package jen - -import ( - "fmt" - "io" - "sort" - "strconv" -) - -// Tag renders a struct tag -func Tag(items map[string]string) *Statement { - return newStatement().Tag(items) -} - -// Tag renders a struct tag -func (g *Group) Tag(items map[string]string) *Statement { - // notest - // don't think this can ever be used in valid code? - s := Tag(items) - g.items = append(g.items, s) - return s -} - -// Tag renders a struct tag -func (s *Statement) Tag(items map[string]string) *Statement { - c := tag{ - items: items, - } - *s = append(*s, c) - return s -} - -type tag struct { - items map[string]string -} - -func (t tag) isNull(f *File) bool { - return len(t.items) == 0 -} - -func (t tag) render(f *File, w io.Writer, s *Statement) error { - - if t.isNull(f) { - // notest - // render won't be called if t is null - return nil - } - - var str string - - var sorted []string - for k := range t.items { - sorted = append(sorted, k) - } - sort.Strings(sorted) - - for _, k := range sorted { - v := t.items[k] - if len(str) > 0 { - str += " " - } - str += fmt.Sprintf(`%s:"%s"`, k, v) - } - - if strconv.CanBackquote(str) { - str = "`" + str + "`" - } else { - str = strconv.Quote(str) - } - - if _, err := w.Write([]byte(str)); err != nil { - return err - } - - return nil -} diff --git a/vendor/github.com/dave/jennifer/jen/tokens.go b/vendor/github.com/dave/jennifer/jen/tokens.go deleted file mode 100644 index 287a3cd63..000000000 --- a/vendor/github.com/dave/jennifer/jen/tokens.go +++ /dev/null @@ -1,301 +0,0 @@ -package jen - -import ( - "fmt" - "io" - "strconv" - "strings" -) - -type tokenType string - -const ( - packageToken tokenType = "package" - identifierToken tokenType = "identifier" - qualifiedToken tokenType = "qualified" - keywordToken tokenType = "keyword" - operatorToken tokenType = "operator" - delimiterToken tokenType = "delimiter" - literalToken tokenType = "literal" - literalRuneToken tokenType = "literal_rune" - literalByteToken tokenType = "literal_byte" - nullToken tokenType = "null" - layoutToken tokenType = "layout" -) - -type token struct { - typ tokenType - content interface{} -} - -func (t token) isNull(f *File) bool { - if t.typ == packageToken { - // package token is null if the path is a dot-import or the local package path - return f.isDotImport(t.content.(string)) || f.isLocal(t.content.(string)) - } - return t.typ == nullToken -} - -func (t token) render(f *File, w io.Writer, s *Statement) error { - switch t.typ { - case literalToken: - var out string - switch t.content.(type) { - case bool, string, int, complex128: - // default constant types can be left bare - out = fmt.Sprintf("%#v", t.content) - case float64: - out = fmt.Sprintf("%#v", t.content) - if !strings.Contains(out, ".") && !strings.Contains(out, "e") { - // If the formatted value is not in scientific notation, and does not have a dot, then - // we add ".0". Otherwise it will be interpreted as an int. - // See: - // https://github.com/dave/jennifer/issues/39 - // https://github.com/golang/go/issues/26363 - out += ".0" - } - case float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr: - // other built-in types need specific type info - out = fmt.Sprintf("%T(%#v)", t.content, t.content) - case complex64: - // fmt package already renders parenthesis for complex64 - out = fmt.Sprintf("%T%#v", t.content, t.content) - default: - panic(fmt.Sprintf("unsupported type for literal: %T", t.content)) - } - if _, err := w.Write([]byte(out)); err != nil { - return err - } - case literalRuneToken: - if _, err := w.Write([]byte(strconv.QuoteRune(t.content.(rune)))); err != nil { - return err - } - case literalByteToken: - if _, err := w.Write([]byte(fmt.Sprintf("byte(%#v)", t.content))); err != nil { - return err - } - case keywordToken, operatorToken, layoutToken, delimiterToken: - if _, err := w.Write([]byte(fmt.Sprintf("%s", t.content))); err != nil { - return err - } - if t.content.(string) == "default" { - // Special case for Default, which must always be followed by a colon - if _, err := w.Write([]byte(":")); err != nil { - return err - } - } - case packageToken: - path := t.content.(string) - alias := f.register(path) - if _, err := w.Write([]byte(alias)); err != nil { - return err - } - case identifierToken: - if _, err := w.Write([]byte(t.content.(string))); err != nil { - return err - } - case nullToken: // notest - // do nothing (should never render a null token) - } - return nil -} - -// Null adds a null item. Null items render nothing and are not followed by a -// separator in lists. -func Null() *Statement { - return newStatement().Null() -} - -// Null adds a null item. Null items render nothing and are not followed by a -// separator in lists. -func (g *Group) Null() *Statement { - s := Null() - g.items = append(g.items, s) - return s -} - -// Null adds a null item. Null items render nothing and are not followed by a -// separator in lists. -func (s *Statement) Null() *Statement { - t := token{ - typ: nullToken, - } - *s = append(*s, t) - return s -} - -// Empty adds an empty item. Empty items render nothing but are followed by a -// separator in lists. -func Empty() *Statement { - return newStatement().Empty() -} - -// Empty adds an empty item. Empty items render nothing but are followed by a -// separator in lists. -func (g *Group) Empty() *Statement { - s := Empty() - g.items = append(g.items, s) - return s -} - -// Empty adds an empty item. Empty items render nothing but are followed by a -// separator in lists. -func (s *Statement) Empty() *Statement { - t := token{ - typ: operatorToken, - content: "", - } - *s = append(*s, t) - return s -} - -// Op renders the provided operator / token. -func Op(op string) *Statement { - return newStatement().Op(op) -} - -// Op renders the provided operator / token. -func (g *Group) Op(op string) *Statement { - s := Op(op) - g.items = append(g.items, s) - return s -} - -// Op renders the provided operator / token. -func (s *Statement) Op(op string) *Statement { - t := token{ - typ: operatorToken, - content: op, - } - *s = append(*s, t) - return s -} - -// Dot renders a period followed by an identifier. Use for fields and selectors. -func Dot(name string) *Statement { - // notest - // don't think this can be used in valid code? - return newStatement().Dot(name) -} - -// Dot renders a period followed by an identifier. Use for fields and selectors. -func (g *Group) Dot(name string) *Statement { - // notest - // don't think this can be used in valid code? - s := Dot(name) - g.items = append(g.items, s) - return s -} - -// Dot renders a period followed by an identifier. Use for fields and selectors. -func (s *Statement) Dot(name string) *Statement { - d := token{ - typ: delimiterToken, - content: ".", - } - t := token{ - typ: identifierToken, - content: name, - } - *s = append(*s, d, t) - return s -} - -// Id renders an identifier. -func Id(name string) *Statement { - return newStatement().Id(name) -} - -// Id renders an identifier. -func (g *Group) Id(name string) *Statement { - s := Id(name) - g.items = append(g.items, s) - return s -} - -// Id renders an identifier. -func (s *Statement) Id(name string) *Statement { - t := token{ - typ: identifierToken, - content: name, - } - *s = append(*s, t) - return s -} - -// Qual renders a qualified identifier. Imports are automatically added when -// used with a File. If the path matches the local path, the package name is -// omitted. If package names conflict they are automatically renamed. Note that -// it is not possible to reliably determine the package name given an arbitrary -// package path, so a sensible name is guessed from the path and added as an -// alias. The names of all standard library packages are known so these do not -// need to be aliased. If more control is needed of the aliases, see -// [File.ImportName](#importname) or [File.ImportAlias](#importalias). -func Qual(path, name string) *Statement { - return newStatement().Qual(path, name) -} - -// Qual renders a qualified identifier. Imports are automatically added when -// used with a File. If the path matches the local path, the package name is -// omitted. If package names conflict they are automatically renamed. Note that -// it is not possible to reliably determine the package name given an arbitrary -// package path, so a sensible name is guessed from the path and added as an -// alias. The names of all standard library packages are known so these do not -// need to be aliased. If more control is needed of the aliases, see -// [File.ImportName](#importname) or [File.ImportAlias](#importalias). -func (g *Group) Qual(path, name string) *Statement { - s := Qual(path, name) - g.items = append(g.items, s) - return s -} - -// Qual renders a qualified identifier. Imports are automatically added when -// used with a File. If the path matches the local path, the package name is -// omitted. If package names conflict they are automatically renamed. Note that -// it is not possible to reliably determine the package name given an arbitrary -// package path, so a sensible name is guessed from the path and added as an -// alias. The names of all standard library packages are known so these do not -// need to be aliased. If more control is needed of the aliases, see -// [File.ImportName](#importname) or [File.ImportAlias](#importalias). -func (s *Statement) Qual(path, name string) *Statement { - g := &Group{ - close: "", - items: []Code{ - token{ - typ: packageToken, - content: path, - }, - token{ - typ: identifierToken, - content: name, - }, - }, - name: "qual", - open: "", - separator: ".", - } - *s = append(*s, g) - return s -} - -// Line inserts a blank line. -func Line() *Statement { - return newStatement().Line() -} - -// Line inserts a blank line. -func (g *Group) Line() *Statement { - s := Line() - g.items = append(g.items, s) - return s -} - -// Line inserts a blank line. -func (s *Statement) Line() *Statement { - t := token{ - typ: layoutToken, - content: "\n", - } - *s = append(*s, t) - return s -} diff --git a/vendor/github.com/davecgh/go-spew/LICENSE b/vendor/github.com/davecgh/go-spew/LICENSE deleted file mode 100644 index bc52e96f2..000000000 --- a/vendor/github.com/davecgh/go-spew/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -ISC License - -Copyright (c) 2012-2016 Dave Collins - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go deleted file mode 100644 index 792994785..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/bypass.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) 2015-2016 Dave Collins -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -// NOTE: Due to the following build constraints, this file will only be compiled -// when the code is not running on Google App Engine, compiled by GopherJS, and -// "-tags safe" is not added to the go build command line. The "disableunsafe" -// tag is deprecated and thus should not be used. -// Go versions prior to 1.4 are disabled because they use a different layout -// for interfaces which make the implementation of unsafeReflectValue more complex. -// +build !js,!appengine,!safe,!disableunsafe,go1.4 - -package spew - -import ( - "reflect" - "unsafe" -) - -const ( - // UnsafeDisabled is a build-time constant which specifies whether or - // not access to the unsafe package is available. - UnsafeDisabled = false - - // ptrSize is the size of a pointer on the current arch. - ptrSize = unsafe.Sizeof((*byte)(nil)) -) - -type flag uintptr - -var ( - // flagRO indicates whether the value field of a reflect.Value - // is read-only. - flagRO flag - - // flagAddr indicates whether the address of the reflect.Value's - // value may be taken. - flagAddr flag -) - -// flagKindMask holds the bits that make up the kind -// part of the flags field. In all the supported versions, -// it is in the lower 5 bits. -const flagKindMask = flag(0x1f) - -// Different versions of Go have used different -// bit layouts for the flags type. This table -// records the known combinations. -var okFlags = []struct { - ro, addr flag -}{{ - // From Go 1.4 to 1.5 - ro: 1 << 5, - addr: 1 << 7, -}, { - // Up to Go tip. - ro: 1<<5 | 1<<6, - addr: 1 << 8, -}} - -var flagValOffset = func() uintptr { - field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") - if !ok { - panic("reflect.Value has no flag field") - } - return field.Offset -}() - -// flagField returns a pointer to the flag field of a reflect.Value. -func flagField(v *reflect.Value) *flag { - return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset)) -} - -// unsafeReflectValue converts the passed reflect.Value into a one that bypasses -// the typical safety restrictions preventing access to unaddressable and -// unexported data. It works by digging the raw pointer to the underlying -// value out of the protected value and generating a new unprotected (unsafe) -// reflect.Value to it. -// -// This allows us to check for implementations of the Stringer and error -// interfaces to be used for pretty printing ordinarily unaddressable and -// inaccessible values such as unexported struct fields. -func unsafeReflectValue(v reflect.Value) reflect.Value { - if !v.IsValid() || (v.CanInterface() && v.CanAddr()) { - return v - } - flagFieldPtr := flagField(&v) - *flagFieldPtr &^= flagRO - *flagFieldPtr |= flagAddr - return v -} - -// Sanity checks against future reflect package changes -// to the type or semantics of the Value.flag field. -func init() { - field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") - if !ok { - panic("reflect.Value has no flag field") - } - if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() { - panic("reflect.Value flag field has changed kind") - } - type t0 int - var t struct { - A t0 - // t0 will have flagEmbedRO set. - t0 - // a will have flagStickyRO set - a t0 - } - vA := reflect.ValueOf(t).FieldByName("A") - va := reflect.ValueOf(t).FieldByName("a") - vt0 := reflect.ValueOf(t).FieldByName("t0") - - // Infer flagRO from the difference between the flags - // for the (otherwise identical) fields in t. - flagPublic := *flagField(&vA) - flagWithRO := *flagField(&va) | *flagField(&vt0) - flagRO = flagPublic ^ flagWithRO - - // Infer flagAddr from the difference between a value - // taken from a pointer and not. - vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A") - flagNoPtr := *flagField(&vA) - flagPtr := *flagField(&vPtrA) - flagAddr = flagNoPtr ^ flagPtr - - // Check that the inferred flags tally with one of the known versions. - for _, f := range okFlags { - if flagRO == f.ro && flagAddr == f.addr { - return - } - } - panic("reflect.Value read-only flag has changed semantics") -} diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go deleted file mode 100644 index 205c28d68..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2015-2016 Dave Collins -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -// NOTE: Due to the following build constraints, this file will only be compiled -// when the code is running on Google App Engine, compiled by GopherJS, or -// "-tags safe" is added to the go build command line. The "disableunsafe" -// tag is deprecated and thus should not be used. -// +build js appengine safe disableunsafe !go1.4 - -package spew - -import "reflect" - -const ( - // UnsafeDisabled is a build-time constant which specifies whether or - // not access to the unsafe package is available. - UnsafeDisabled = true -) - -// unsafeReflectValue typically converts the passed reflect.Value into a one -// that bypasses the typical safety restrictions preventing access to -// unaddressable and unexported data. However, doing this relies on access to -// the unsafe package. This is a stub version which simply returns the passed -// reflect.Value when the unsafe package is not available. -func unsafeReflectValue(v reflect.Value) reflect.Value { - return v -} diff --git a/vendor/github.com/davecgh/go-spew/spew/common.go b/vendor/github.com/davecgh/go-spew/spew/common.go deleted file mode 100644 index 1be8ce945..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/common.go +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "io" - "reflect" - "sort" - "strconv" -) - -// Some constants in the form of bytes to avoid string overhead. This mirrors -// the technique used in the fmt package. -var ( - panicBytes = []byte("(PANIC=") - plusBytes = []byte("+") - iBytes = []byte("i") - trueBytes = []byte("true") - falseBytes = []byte("false") - interfaceBytes = []byte("(interface {})") - commaNewlineBytes = []byte(",\n") - newlineBytes = []byte("\n") - openBraceBytes = []byte("{") - openBraceNewlineBytes = []byte("{\n") - closeBraceBytes = []byte("}") - asteriskBytes = []byte("*") - colonBytes = []byte(":") - colonSpaceBytes = []byte(": ") - openParenBytes = []byte("(") - closeParenBytes = []byte(")") - spaceBytes = []byte(" ") - pointerChainBytes = []byte("->") - nilAngleBytes = []byte("") - maxNewlineBytes = []byte("\n") - maxShortBytes = []byte("") - circularBytes = []byte("") - circularShortBytes = []byte("") - invalidAngleBytes = []byte("") - openBracketBytes = []byte("[") - closeBracketBytes = []byte("]") - percentBytes = []byte("%") - precisionBytes = []byte(".") - openAngleBytes = []byte("<") - closeAngleBytes = []byte(">") - openMapBytes = []byte("map[") - closeMapBytes = []byte("]") - lenEqualsBytes = []byte("len=") - capEqualsBytes = []byte("cap=") -) - -// hexDigits is used to map a decimal value to a hex digit. -var hexDigits = "0123456789abcdef" - -// catchPanic handles any panics that might occur during the handleMethods -// calls. -func catchPanic(w io.Writer, v reflect.Value) { - if err := recover(); err != nil { - w.Write(panicBytes) - fmt.Fprintf(w, "%v", err) - w.Write(closeParenBytes) - } -} - -// handleMethods attempts to call the Error and String methods on the underlying -// type the passed reflect.Value represents and outputes the result to Writer w. -// -// It handles panics in any called methods by catching and displaying the error -// as the formatted value. -func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { - // We need an interface to check if the type implements the error or - // Stringer interface. However, the reflect package won't give us an - // interface on certain things like unexported struct fields in order - // to enforce visibility rules. We use unsafe, when it's available, - // to bypass these restrictions since this package does not mutate the - // values. - if !v.CanInterface() { - if UnsafeDisabled { - return false - } - - v = unsafeReflectValue(v) - } - - // Choose whether or not to do error and Stringer interface lookups against - // the base type or a pointer to the base type depending on settings. - // Technically calling one of these methods with a pointer receiver can - // mutate the value, however, types which choose to satisify an error or - // Stringer interface with a pointer receiver should not be mutating their - // state inside these interface methods. - if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { - v = unsafeReflectValue(v) - } - if v.CanAddr() { - v = v.Addr() - } - - // Is it an error or Stringer? - switch iface := v.Interface().(type) { - case error: - defer catchPanic(w, v) - if cs.ContinueOnMethod { - w.Write(openParenBytes) - w.Write([]byte(iface.Error())) - w.Write(closeParenBytes) - w.Write(spaceBytes) - return false - } - - w.Write([]byte(iface.Error())) - return true - - case fmt.Stringer: - defer catchPanic(w, v) - if cs.ContinueOnMethod { - w.Write(openParenBytes) - w.Write([]byte(iface.String())) - w.Write(closeParenBytes) - w.Write(spaceBytes) - return false - } - w.Write([]byte(iface.String())) - return true - } - return false -} - -// printBool outputs a boolean value as true or false to Writer w. -func printBool(w io.Writer, val bool) { - if val { - w.Write(trueBytes) - } else { - w.Write(falseBytes) - } -} - -// printInt outputs a signed integer value to Writer w. -func printInt(w io.Writer, val int64, base int) { - w.Write([]byte(strconv.FormatInt(val, base))) -} - -// printUint outputs an unsigned integer value to Writer w. -func printUint(w io.Writer, val uint64, base int) { - w.Write([]byte(strconv.FormatUint(val, base))) -} - -// printFloat outputs a floating point value using the specified precision, -// which is expected to be 32 or 64bit, to Writer w. -func printFloat(w io.Writer, val float64, precision int) { - w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) -} - -// printComplex outputs a complex value using the specified float precision -// for the real and imaginary parts to Writer w. -func printComplex(w io.Writer, c complex128, floatPrecision int) { - r := real(c) - w.Write(openParenBytes) - w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) - i := imag(c) - if i >= 0 { - w.Write(plusBytes) - } - w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) - w.Write(iBytes) - w.Write(closeParenBytes) -} - -// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x' -// prefix to Writer w. -func printHexPtr(w io.Writer, p uintptr) { - // Null pointer. - num := uint64(p) - if num == 0 { - w.Write(nilAngleBytes) - return - } - - // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix - buf := make([]byte, 18) - - // It's simpler to construct the hex string right to left. - base := uint64(16) - i := len(buf) - 1 - for num >= base { - buf[i] = hexDigits[num%base] - num /= base - i-- - } - buf[i] = hexDigits[num] - - // Add '0x' prefix. - i-- - buf[i] = 'x' - i-- - buf[i] = '0' - - // Strip unused leading bytes. - buf = buf[i:] - w.Write(buf) -} - -// valuesSorter implements sort.Interface to allow a slice of reflect.Value -// elements to be sorted. -type valuesSorter struct { - values []reflect.Value - strings []string // either nil or same len and values - cs *ConfigState -} - -// newValuesSorter initializes a valuesSorter instance, which holds a set of -// surrogate keys on which the data should be sorted. It uses flags in -// ConfigState to decide if and how to populate those surrogate keys. -func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { - vs := &valuesSorter{values: values, cs: cs} - if canSortSimply(vs.values[0].Kind()) { - return vs - } - if !cs.DisableMethods { - vs.strings = make([]string, len(values)) - for i := range vs.values { - b := bytes.Buffer{} - if !handleMethods(cs, &b, vs.values[i]) { - vs.strings = nil - break - } - vs.strings[i] = b.String() - } - } - if vs.strings == nil && cs.SpewKeys { - vs.strings = make([]string, len(values)) - for i := range vs.values { - vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) - } - } - return vs -} - -// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted -// directly, or whether it should be considered for sorting by surrogate keys -// (if the ConfigState allows it). -func canSortSimply(kind reflect.Kind) bool { - // This switch parallels valueSortLess, except for the default case. - switch kind { - case reflect.Bool: - return true - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return true - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return true - case reflect.Float32, reflect.Float64: - return true - case reflect.String: - return true - case reflect.Uintptr: - return true - case reflect.Array: - return true - } - return false -} - -// Len returns the number of values in the slice. It is part of the -// sort.Interface implementation. -func (s *valuesSorter) Len() int { - return len(s.values) -} - -// Swap swaps the values at the passed indices. It is part of the -// sort.Interface implementation. -func (s *valuesSorter) Swap(i, j int) { - s.values[i], s.values[j] = s.values[j], s.values[i] - if s.strings != nil { - s.strings[i], s.strings[j] = s.strings[j], s.strings[i] - } -} - -// valueSortLess returns whether the first value should sort before the second -// value. It is used by valueSorter.Less as part of the sort.Interface -// implementation. -func valueSortLess(a, b reflect.Value) bool { - switch a.Kind() { - case reflect.Bool: - return !a.Bool() && b.Bool() - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return a.Int() < b.Int() - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return a.Uint() < b.Uint() - case reflect.Float32, reflect.Float64: - return a.Float() < b.Float() - case reflect.String: - return a.String() < b.String() - case reflect.Uintptr: - return a.Uint() < b.Uint() - case reflect.Array: - // Compare the contents of both arrays. - l := a.Len() - for i := 0; i < l; i++ { - av := a.Index(i) - bv := b.Index(i) - if av.Interface() == bv.Interface() { - continue - } - return valueSortLess(av, bv) - } - } - return a.String() < b.String() -} - -// Less returns whether the value at index i should sort before the -// value at index j. It is part of the sort.Interface implementation. -func (s *valuesSorter) Less(i, j int) bool { - if s.strings == nil { - return valueSortLess(s.values[i], s.values[j]) - } - return s.strings[i] < s.strings[j] -} - -// sortValues is a sort function that handles both native types and any type that -// can be converted to error or Stringer. Other inputs are sorted according to -// their Value.String() value to ensure display stability. -func sortValues(values []reflect.Value, cs *ConfigState) { - if len(values) == 0 { - return - } - sort.Sort(newValuesSorter(values, cs)) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/config.go b/vendor/github.com/davecgh/go-spew/spew/config.go deleted file mode 100644 index 2e3d22f31..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/config.go +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "io" - "os" -) - -// ConfigState houses the configuration options used by spew to format and -// display values. There is a global instance, Config, that is used to control -// all top-level Formatter and Dump functionality. Each ConfigState instance -// provides methods equivalent to the top-level functions. -// -// The zero value for ConfigState provides no indentation. You would typically -// want to set it to a space or a tab. -// -// Alternatively, you can use NewDefaultConfig to get a ConfigState instance -// with default settings. See the documentation of NewDefaultConfig for default -// values. -type ConfigState struct { - // Indent specifies the string to use for each indentation level. The - // global config instance that all top-level functions use set this to a - // single space by default. If you would like more indentation, you might - // set this to a tab with "\t" or perhaps two spaces with " ". - Indent string - - // MaxDepth controls the maximum number of levels to descend into nested - // data structures. The default, 0, means there is no limit. - // - // NOTE: Circular data structures are properly detected, so it is not - // necessary to set this value unless you specifically want to limit deeply - // nested data structures. - MaxDepth int - - // DisableMethods specifies whether or not error and Stringer interfaces are - // invoked for types that implement them. - DisableMethods bool - - // DisablePointerMethods specifies whether or not to check for and invoke - // error and Stringer interfaces on types which only accept a pointer - // receiver when the current type is not a pointer. - // - // NOTE: This might be an unsafe action since calling one of these methods - // with a pointer receiver could technically mutate the value, however, - // in practice, types which choose to satisify an error or Stringer - // interface with a pointer receiver should not be mutating their state - // inside these interface methods. As a result, this option relies on - // access to the unsafe package, so it will not have any effect when - // running in environments without access to the unsafe package such as - // Google App Engine or with the "safe" build tag specified. - DisablePointerMethods bool - - // DisablePointerAddresses specifies whether to disable the printing of - // pointer addresses. This is useful when diffing data structures in tests. - DisablePointerAddresses bool - - // DisableCapacities specifies whether to disable the printing of capacities - // for arrays, slices, maps and channels. This is useful when diffing - // data structures in tests. - DisableCapacities bool - - // ContinueOnMethod specifies whether or not recursion should continue once - // a custom error or Stringer interface is invoked. The default, false, - // means it will print the results of invoking the custom error or Stringer - // interface and return immediately instead of continuing to recurse into - // the internals of the data type. - // - // NOTE: This flag does not have any effect if method invocation is disabled - // via the DisableMethods or DisablePointerMethods options. - ContinueOnMethod bool - - // SortKeys specifies map keys should be sorted before being printed. Use - // this to have a more deterministic, diffable output. Note that only - // native types (bool, int, uint, floats, uintptr and string) and types - // that support the error or Stringer interfaces (if methods are - // enabled) are supported, with other types sorted according to the - // reflect.Value.String() output which guarantees display stability. - SortKeys bool - - // SpewKeys specifies that, as a last resort attempt, map keys should - // be spewed to strings and sorted by those strings. This is only - // considered if SortKeys is true. - SpewKeys bool -} - -// Config is the active configuration of the top-level functions. -// The configuration can be changed by modifying the contents of spew.Config. -var Config = ConfigState{Indent: " "} - -// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the formatted string as a value that satisfies error. See NewFormatter -// for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) { - return fmt.Errorf(format, c.convertArgs(a)...) -} - -// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprint(w, c.convertArgs(a)...) -} - -// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - return fmt.Fprintf(w, format, c.convertArgs(a)...) -} - -// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it -// passed with a Formatter interface returned by c.NewFormatter. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprintln(w, c.convertArgs(a)...) -} - -// Print is a wrapper for fmt.Print that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Print(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Print(a ...interface{}) (n int, err error) { - return fmt.Print(c.convertArgs(a)...) -} - -// Printf is a wrapper for fmt.Printf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) { - return fmt.Printf(format, c.convertArgs(a)...) -} - -// Println is a wrapper for fmt.Println that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Println(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Println(a ...interface{}) (n int, err error) { - return fmt.Println(c.convertArgs(a)...) -} - -// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprint(a ...interface{}) string { - return fmt.Sprint(c.convertArgs(a)...) -} - -// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprintf(format string, a ...interface{}) string { - return fmt.Sprintf(format, c.convertArgs(a)...) -} - -// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it -// were passed with a Formatter interface returned by c.NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprintln(a ...interface{}) string { - return fmt.Sprintln(c.convertArgs(a)...) -} - -/* -NewFormatter returns a custom formatter that satisfies the fmt.Formatter -interface. As a result, it integrates cleanly with standard fmt package -printing functions. The formatter is useful for inline printing of smaller data -types similar to the standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Typically this function shouldn't be called directly. It is much easier to make -use of the custom formatter by calling one of the convenience functions such as -c.Printf, c.Println, or c.Printf. -*/ -func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter { - return newFormatter(c, v) -} - -// Fdump formats and displays the passed arguments to io.Writer w. It formats -// exactly the same as Dump. -func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) { - fdump(c, w, a...) -} - -/* -Dump displays the passed parameters to standard out with newlines, customizable -indentation, and additional debug information such as complete types and all -pointer addresses used to indirect to the final value. It provides the -following features over the built-in printing facilities provided by the fmt -package: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output - -The configuration options are controlled by modifying the public members -of c. See ConfigState for options documentation. - -See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to -get the formatted result as a string. -*/ -func (c *ConfigState) Dump(a ...interface{}) { - fdump(c, os.Stdout, a...) -} - -// Sdump returns a string with the passed arguments formatted exactly the same -// as Dump. -func (c *ConfigState) Sdump(a ...interface{}) string { - var buf bytes.Buffer - fdump(c, &buf, a...) - return buf.String() -} - -// convertArgs accepts a slice of arguments and returns a slice of the same -// length with each argument converted to a spew Formatter interface using -// the ConfigState associated with s. -func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) { - formatters = make([]interface{}, len(args)) - for index, arg := range args { - formatters[index] = newFormatter(c, arg) - } - return formatters -} - -// NewDefaultConfig returns a ConfigState with the following default settings. -// -// Indent: " " -// MaxDepth: 0 -// DisableMethods: false -// DisablePointerMethods: false -// ContinueOnMethod: false -// SortKeys: false -func NewDefaultConfig() *ConfigState { - return &ConfigState{Indent: " "} -} diff --git a/vendor/github.com/davecgh/go-spew/spew/doc.go b/vendor/github.com/davecgh/go-spew/spew/doc.go deleted file mode 100644 index aacaac6f1..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/doc.go +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* -Package spew implements a deep pretty printer for Go data structures to aid in -debugging. - -A quick overview of the additional features spew provides over the built-in -printing facilities for Go data types are as follows: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output (only when using - Dump style) - -There are two different approaches spew allows for dumping Go data structures: - - * Dump style which prints with newlines, customizable indentation, - and additional debug information such as types and all pointer addresses - used to indirect to the final value - * A custom Formatter interface that integrates cleanly with the standard fmt - package and replaces %v, %+v, %#v, and %#+v to provide inline printing - similar to the default %v while providing the additional functionality - outlined above and passing unsupported format verbs such as %x and %q - along to fmt - -Quick Start - -This section demonstrates how to quickly get started with spew. See the -sections below for further details on formatting and configuration options. - -To dump a variable with full newlines, indentation, type, and pointer -information use Dump, Fdump, or Sdump: - spew.Dump(myVar1, myVar2, ...) - spew.Fdump(someWriter, myVar1, myVar2, ...) - str := spew.Sdump(myVar1, myVar2, ...) - -Alternatively, if you would prefer to use format strings with a compacted inline -printing style, use the convenience wrappers Printf, Fprintf, etc with -%v (most compact), %+v (adds pointer addresses), %#v (adds types), or -%#+v (adds types and pointer addresses): - spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - -Configuration Options - -Configuration of spew is handled by fields in the ConfigState type. For -convenience, all of the top-level functions use a global state available -via the spew.Config global. - -It is also possible to create a ConfigState instance that provides methods -equivalent to the top-level functions. This allows concurrent configuration -options. See the ConfigState documentation for more details. - -The following configuration options are available: - * Indent - String to use for each indentation level for Dump functions. - It is a single space by default. A popular alternative is "\t". - - * MaxDepth - Maximum number of levels to descend into nested data structures. - There is no limit by default. - - * DisableMethods - Disables invocation of error and Stringer interface methods. - Method invocation is enabled by default. - - * DisablePointerMethods - Disables invocation of error and Stringer interface methods on types - which only accept pointer receivers from non-pointer variables. - Pointer method invocation is enabled by default. - - * DisablePointerAddresses - DisablePointerAddresses specifies whether to disable the printing of - pointer addresses. This is useful when diffing data structures in tests. - - * DisableCapacities - DisableCapacities specifies whether to disable the printing of - capacities for arrays, slices, maps and channels. This is useful when - diffing data structures in tests. - - * ContinueOnMethod - Enables recursion into types after invoking error and Stringer interface - methods. Recursion after method invocation is disabled by default. - - * SortKeys - Specifies map keys should be sorted before being printed. Use - this to have a more deterministic, diffable output. Note that - only native types (bool, int, uint, floats, uintptr and string) - and types which implement error or Stringer interfaces are - supported with other types sorted according to the - reflect.Value.String() output which guarantees display - stability. Natural map order is used by default. - - * SpewKeys - Specifies that, as a last resort attempt, map keys should be - spewed to strings and sorted by those strings. This is only - considered if SortKeys is true. - -Dump Usage - -Simply call spew.Dump with a list of variables you want to dump: - - spew.Dump(myVar1, myVar2, ...) - -You may also call spew.Fdump if you would prefer to output to an arbitrary -io.Writer. For example, to dump to standard error: - - spew.Fdump(os.Stderr, myVar1, myVar2, ...) - -A third option is to call spew.Sdump to get the formatted output as a string: - - str := spew.Sdump(myVar1, myVar2, ...) - -Sample Dump Output - -See the Dump example for details on the setup of the types and variables being -shown here. - - (main.Foo) { - unexportedField: (*main.Bar)(0xf84002e210)({ - flag: (main.Flag) flagTwo, - data: (uintptr) - }), - ExportedField: (map[interface {}]interface {}) (len=1) { - (string) (len=3) "one": (bool) true - } - } - -Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C -command as shown. - ([]uint8) (len=32 cap=32) { - 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | - 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| - 00000020 31 32 |12| - } - -Custom Formatter - -Spew provides a custom formatter that implements the fmt.Formatter interface -so that it integrates cleanly with standard fmt package printing functions. The -formatter is useful for inline printing of smaller data types similar to the -standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Custom Formatter Usage - -The simplest way to make use of the spew custom formatter is to call one of the -convenience functions such as spew.Printf, spew.Println, or spew.Printf. The -functions have syntax you are most likely already familiar with: - - spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - spew.Println(myVar, myVar2) - spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - -See the Index for the full list convenience functions. - -Sample Formatter Output - -Double pointer to a uint8: - %v: <**>5 - %+v: <**>(0xf8400420d0->0xf8400420c8)5 - %#v: (**uint8)5 - %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 - -Pointer to circular struct with a uint8 field and a pointer to itself: - %v: <*>{1 <*>} - %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} - %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} - %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} - -See the Printf example for details on the setup of variables being shown -here. - -Errors - -Since it is possible for custom Stringer/error interfaces to panic, spew -detects them and handles them internally by printing the panic information -inline with the output. Since spew is intended to provide deep pretty printing -capabilities on structures, it intentionally does not return any errors. -*/ -package spew diff --git a/vendor/github.com/davecgh/go-spew/spew/dump.go b/vendor/github.com/davecgh/go-spew/spew/dump.go deleted file mode 100644 index f78d89fc1..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/dump.go +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "encoding/hex" - "fmt" - "io" - "os" - "reflect" - "regexp" - "strconv" - "strings" -) - -var ( - // uint8Type is a reflect.Type representing a uint8. It is used to - // convert cgo types to uint8 slices for hexdumping. - uint8Type = reflect.TypeOf(uint8(0)) - - // cCharRE is a regular expression that matches a cgo char. - // It is used to detect character arrays to hexdump them. - cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`) - - // cUnsignedCharRE is a regular expression that matches a cgo unsigned - // char. It is used to detect unsigned character arrays to hexdump - // them. - cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`) - - // cUint8tCharRE is a regular expression that matches a cgo uint8_t. - // It is used to detect uint8_t arrays to hexdump them. - cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`) -) - -// dumpState contains information about the state of a dump operation. -type dumpState struct { - w io.Writer - depth int - pointers map[uintptr]int - ignoreNextType bool - ignoreNextIndent bool - cs *ConfigState -} - -// indent performs indentation according to the depth level and cs.Indent -// option. -func (d *dumpState) indent() { - if d.ignoreNextIndent { - d.ignoreNextIndent = false - return - } - d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth)) -} - -// unpackValue returns values inside of non-nil interfaces when possible. -// This is useful for data types like structs, arrays, slices, and maps which -// can contain varying types packed inside an interface. -func (d *dumpState) unpackValue(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Interface && !v.IsNil() { - v = v.Elem() - } - return v -} - -// dumpPtr handles formatting of pointers by indirecting them as necessary. -func (d *dumpState) dumpPtr(v reflect.Value) { - // Remove pointers at or below the current depth from map used to detect - // circular refs. - for k, depth := range d.pointers { - if depth >= d.depth { - delete(d.pointers, k) - } - } - - // Keep list of all dereferenced pointers to show later. - pointerChain := make([]uintptr, 0) - - // Figure out how many levels of indirection there are by dereferencing - // pointers and unpacking interfaces down the chain while detecting circular - // references. - nilFound := false - cycleFound := false - indirects := 0 - ve := v - for ve.Kind() == reflect.Ptr { - if ve.IsNil() { - nilFound = true - break - } - indirects++ - addr := ve.Pointer() - pointerChain = append(pointerChain, addr) - if pd, ok := d.pointers[addr]; ok && pd < d.depth { - cycleFound = true - indirects-- - break - } - d.pointers[addr] = d.depth - - ve = ve.Elem() - if ve.Kind() == reflect.Interface { - if ve.IsNil() { - nilFound = true - break - } - ve = ve.Elem() - } - } - - // Display type information. - d.w.Write(openParenBytes) - d.w.Write(bytes.Repeat(asteriskBytes, indirects)) - d.w.Write([]byte(ve.Type().String())) - d.w.Write(closeParenBytes) - - // Display pointer information. - if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { - d.w.Write(openParenBytes) - for i, addr := range pointerChain { - if i > 0 { - d.w.Write(pointerChainBytes) - } - printHexPtr(d.w, addr) - } - d.w.Write(closeParenBytes) - } - - // Display dereferenced value. - d.w.Write(openParenBytes) - switch { - case nilFound: - d.w.Write(nilAngleBytes) - - case cycleFound: - d.w.Write(circularBytes) - - default: - d.ignoreNextType = true - d.dump(ve) - } - d.w.Write(closeParenBytes) -} - -// dumpSlice handles formatting of arrays and slices. Byte (uint8 under -// reflection) arrays and slices are dumped in hexdump -C fashion. -func (d *dumpState) dumpSlice(v reflect.Value) { - // Determine whether this type should be hex dumped or not. Also, - // for types which should be hexdumped, try to use the underlying data - // first, then fall back to trying to convert them to a uint8 slice. - var buf []uint8 - doConvert := false - doHexDump := false - numEntries := v.Len() - if numEntries > 0 { - vt := v.Index(0).Type() - vts := vt.String() - switch { - // C types that need to be converted. - case cCharRE.MatchString(vts): - fallthrough - case cUnsignedCharRE.MatchString(vts): - fallthrough - case cUint8tCharRE.MatchString(vts): - doConvert = true - - // Try to use existing uint8 slices and fall back to converting - // and copying if that fails. - case vt.Kind() == reflect.Uint8: - // We need an addressable interface to convert the type - // to a byte slice. However, the reflect package won't - // give us an interface on certain things like - // unexported struct fields in order to enforce - // visibility rules. We use unsafe, when available, to - // bypass these restrictions since this package does not - // mutate the values. - vs := v - if !vs.CanInterface() || !vs.CanAddr() { - vs = unsafeReflectValue(vs) - } - if !UnsafeDisabled { - vs = vs.Slice(0, numEntries) - - // Use the existing uint8 slice if it can be - // type asserted. - iface := vs.Interface() - if slice, ok := iface.([]uint8); ok { - buf = slice - doHexDump = true - break - } - } - - // The underlying data needs to be converted if it can't - // be type asserted to a uint8 slice. - doConvert = true - } - - // Copy and convert the underlying type if needed. - if doConvert && vt.ConvertibleTo(uint8Type) { - // Convert and copy each element into a uint8 byte - // slice. - buf = make([]uint8, numEntries) - for i := 0; i < numEntries; i++ { - vv := v.Index(i) - buf[i] = uint8(vv.Convert(uint8Type).Uint()) - } - doHexDump = true - } - } - - // Hexdump the entire slice as needed. - if doHexDump { - indent := strings.Repeat(d.cs.Indent, d.depth) - str := indent + hex.Dump(buf) - str = strings.Replace(str, "\n", "\n"+indent, -1) - str = strings.TrimRight(str, d.cs.Indent) - d.w.Write([]byte(str)) - return - } - - // Recursively call dump for each item. - for i := 0; i < numEntries; i++ { - d.dump(d.unpackValue(v.Index(i))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } -} - -// dump is the main workhorse for dumping a value. It uses the passed reflect -// value to figure out what kind of object we are dealing with and formats it -// appropriately. It is a recursive function, however circular data structures -// are detected and handled properly. -func (d *dumpState) dump(v reflect.Value) { - // Handle invalid reflect values immediately. - kind := v.Kind() - if kind == reflect.Invalid { - d.w.Write(invalidAngleBytes) - return - } - - // Handle pointers specially. - if kind == reflect.Ptr { - d.indent() - d.dumpPtr(v) - return - } - - // Print type information unless already handled elsewhere. - if !d.ignoreNextType { - d.indent() - d.w.Write(openParenBytes) - d.w.Write([]byte(v.Type().String())) - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) - } - d.ignoreNextType = false - - // Display length and capacity if the built-in len and cap functions - // work with the value's kind and the len/cap itself is non-zero. - valueLen, valueCap := 0, 0 - switch v.Kind() { - case reflect.Array, reflect.Slice, reflect.Chan: - valueLen, valueCap = v.Len(), v.Cap() - case reflect.Map, reflect.String: - valueLen = v.Len() - } - if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { - d.w.Write(openParenBytes) - if valueLen != 0 { - d.w.Write(lenEqualsBytes) - printInt(d.w, int64(valueLen), 10) - } - if !d.cs.DisableCapacities && valueCap != 0 { - if valueLen != 0 { - d.w.Write(spaceBytes) - } - d.w.Write(capEqualsBytes) - printInt(d.w, int64(valueCap), 10) - } - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) - } - - // Call Stringer/error interfaces if they exist and the handle methods flag - // is enabled - if !d.cs.DisableMethods { - if (kind != reflect.Invalid) && (kind != reflect.Interface) { - if handled := handleMethods(d.cs, d.w, v); handled { - return - } - } - } - - switch kind { - case reflect.Invalid: - // Do nothing. We should never get here since invalid has already - // been handled above. - - case reflect.Bool: - printBool(d.w, v.Bool()) - - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - printInt(d.w, v.Int(), 10) - - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - printUint(d.w, v.Uint(), 10) - - case reflect.Float32: - printFloat(d.w, v.Float(), 32) - - case reflect.Float64: - printFloat(d.w, v.Float(), 64) - - case reflect.Complex64: - printComplex(d.w, v.Complex(), 32) - - case reflect.Complex128: - printComplex(d.w, v.Complex(), 64) - - case reflect.Slice: - if v.IsNil() { - d.w.Write(nilAngleBytes) - break - } - fallthrough - - case reflect.Array: - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - d.dumpSlice(v) - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.String: - d.w.Write([]byte(strconv.Quote(v.String()))) - - case reflect.Interface: - // The only time we should get here is for nil interfaces due to - // unpackValue calls. - if v.IsNil() { - d.w.Write(nilAngleBytes) - } - - case reflect.Ptr: - // Do nothing. We should never get here since pointers have already - // been handled above. - - case reflect.Map: - // nil maps should be indicated as different than empty maps - if v.IsNil() { - d.w.Write(nilAngleBytes) - break - } - - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - numEntries := v.Len() - keys := v.MapKeys() - if d.cs.SortKeys { - sortValues(keys, d.cs) - } - for i, key := range keys { - d.dump(d.unpackValue(key)) - d.w.Write(colonSpaceBytes) - d.ignoreNextIndent = true - d.dump(d.unpackValue(v.MapIndex(key))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.Struct: - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - vt := v.Type() - numFields := v.NumField() - for i := 0; i < numFields; i++ { - d.indent() - vtf := vt.Field(i) - d.w.Write([]byte(vtf.Name)) - d.w.Write(colonSpaceBytes) - d.ignoreNextIndent = true - d.dump(d.unpackValue(v.Field(i))) - if i < (numFields - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.Uintptr: - printHexPtr(d.w, uintptr(v.Uint())) - - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - printHexPtr(d.w, v.Pointer()) - - // There were not any other types at the time this code was written, but - // fall back to letting the default fmt package handle it in case any new - // types are added. - default: - if v.CanInterface() { - fmt.Fprintf(d.w, "%v", v.Interface()) - } else { - fmt.Fprintf(d.w, "%v", v.String()) - } - } -} - -// fdump is a helper function to consolidate the logic from the various public -// methods which take varying writers and config states. -func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { - for _, arg := range a { - if arg == nil { - w.Write(interfaceBytes) - w.Write(spaceBytes) - w.Write(nilAngleBytes) - w.Write(newlineBytes) - continue - } - - d := dumpState{w: w, cs: cs} - d.pointers = make(map[uintptr]int) - d.dump(reflect.ValueOf(arg)) - d.w.Write(newlineBytes) - } -} - -// Fdump formats and displays the passed arguments to io.Writer w. It formats -// exactly the same as Dump. -func Fdump(w io.Writer, a ...interface{}) { - fdump(&Config, w, a...) -} - -// Sdump returns a string with the passed arguments formatted exactly the same -// as Dump. -func Sdump(a ...interface{}) string { - var buf bytes.Buffer - fdump(&Config, &buf, a...) - return buf.String() -} - -/* -Dump displays the passed parameters to standard out with newlines, customizable -indentation, and additional debug information such as complete types and all -pointer addresses used to indirect to the final value. It provides the -following features over the built-in printing facilities provided by the fmt -package: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output - -The configuration options are controlled by an exported package global, -spew.Config. See ConfigState for options documentation. - -See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to -get the formatted result as a string. -*/ -func Dump(a ...interface{}) { - fdump(&Config, os.Stdout, a...) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/davecgh/go-spew/spew/format.go deleted file mode 100644 index b04edb7d7..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/format.go +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "reflect" - "strconv" - "strings" -) - -// supportedFlags is a list of all the character flags supported by fmt package. -const supportedFlags = "0-+# " - -// formatState implements the fmt.Formatter interface and contains information -// about the state of a formatting operation. The NewFormatter function can -// be used to get a new Formatter which can be used directly as arguments -// in standard fmt package printing calls. -type formatState struct { - value interface{} - fs fmt.State - depth int - pointers map[uintptr]int - ignoreNextType bool - cs *ConfigState -} - -// buildDefaultFormat recreates the original format string without precision -// and width information to pass in to fmt.Sprintf in the case of an -// unrecognized type. Unless new types are added to the language, this -// function won't ever be called. -func (f *formatState) buildDefaultFormat() (format string) { - buf := bytes.NewBuffer(percentBytes) - - for _, flag := range supportedFlags { - if f.fs.Flag(int(flag)) { - buf.WriteRune(flag) - } - } - - buf.WriteRune('v') - - format = buf.String() - return format -} - -// constructOrigFormat recreates the original format string including precision -// and width information to pass along to the standard fmt package. This allows -// automatic deferral of all format strings this package doesn't support. -func (f *formatState) constructOrigFormat(verb rune) (format string) { - buf := bytes.NewBuffer(percentBytes) - - for _, flag := range supportedFlags { - if f.fs.Flag(int(flag)) { - buf.WriteRune(flag) - } - } - - if width, ok := f.fs.Width(); ok { - buf.WriteString(strconv.Itoa(width)) - } - - if precision, ok := f.fs.Precision(); ok { - buf.Write(precisionBytes) - buf.WriteString(strconv.Itoa(precision)) - } - - buf.WriteRune(verb) - - format = buf.String() - return format -} - -// unpackValue returns values inside of non-nil interfaces when possible and -// ensures that types for values which have been unpacked from an interface -// are displayed when the show types flag is also set. -// This is useful for data types like structs, arrays, slices, and maps which -// can contain varying types packed inside an interface. -func (f *formatState) unpackValue(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Interface { - f.ignoreNextType = false - if !v.IsNil() { - v = v.Elem() - } - } - return v -} - -// formatPtr handles formatting of pointers by indirecting them as necessary. -func (f *formatState) formatPtr(v reflect.Value) { - // Display nil if top level pointer is nil. - showTypes := f.fs.Flag('#') - if v.IsNil() && (!showTypes || f.ignoreNextType) { - f.fs.Write(nilAngleBytes) - return - } - - // Remove pointers at or below the current depth from map used to detect - // circular refs. - for k, depth := range f.pointers { - if depth >= f.depth { - delete(f.pointers, k) - } - } - - // Keep list of all dereferenced pointers to possibly show later. - pointerChain := make([]uintptr, 0) - - // Figure out how many levels of indirection there are by derferencing - // pointers and unpacking interfaces down the chain while detecting circular - // references. - nilFound := false - cycleFound := false - indirects := 0 - ve := v - for ve.Kind() == reflect.Ptr { - if ve.IsNil() { - nilFound = true - break - } - indirects++ - addr := ve.Pointer() - pointerChain = append(pointerChain, addr) - if pd, ok := f.pointers[addr]; ok && pd < f.depth { - cycleFound = true - indirects-- - break - } - f.pointers[addr] = f.depth - - ve = ve.Elem() - if ve.Kind() == reflect.Interface { - if ve.IsNil() { - nilFound = true - break - } - ve = ve.Elem() - } - } - - // Display type or indirection level depending on flags. - if showTypes && !f.ignoreNextType { - f.fs.Write(openParenBytes) - f.fs.Write(bytes.Repeat(asteriskBytes, indirects)) - f.fs.Write([]byte(ve.Type().String())) - f.fs.Write(closeParenBytes) - } else { - if nilFound || cycleFound { - indirects += strings.Count(ve.Type().String(), "*") - } - f.fs.Write(openAngleBytes) - f.fs.Write([]byte(strings.Repeat("*", indirects))) - f.fs.Write(closeAngleBytes) - } - - // Display pointer information depending on flags. - if f.fs.Flag('+') && (len(pointerChain) > 0) { - f.fs.Write(openParenBytes) - for i, addr := range pointerChain { - if i > 0 { - f.fs.Write(pointerChainBytes) - } - printHexPtr(f.fs, addr) - } - f.fs.Write(closeParenBytes) - } - - // Display dereferenced value. - switch { - case nilFound: - f.fs.Write(nilAngleBytes) - - case cycleFound: - f.fs.Write(circularShortBytes) - - default: - f.ignoreNextType = true - f.format(ve) - } -} - -// format is the main workhorse for providing the Formatter interface. It -// uses the passed reflect value to figure out what kind of object we are -// dealing with and formats it appropriately. It is a recursive function, -// however circular data structures are detected and handled properly. -func (f *formatState) format(v reflect.Value) { - // Handle invalid reflect values immediately. - kind := v.Kind() - if kind == reflect.Invalid { - f.fs.Write(invalidAngleBytes) - return - } - - // Handle pointers specially. - if kind == reflect.Ptr { - f.formatPtr(v) - return - } - - // Print type information unless already handled elsewhere. - if !f.ignoreNextType && f.fs.Flag('#') { - f.fs.Write(openParenBytes) - f.fs.Write([]byte(v.Type().String())) - f.fs.Write(closeParenBytes) - } - f.ignoreNextType = false - - // Call Stringer/error interfaces if they exist and the handle methods - // flag is enabled. - if !f.cs.DisableMethods { - if (kind != reflect.Invalid) && (kind != reflect.Interface) { - if handled := handleMethods(f.cs, f.fs, v); handled { - return - } - } - } - - switch kind { - case reflect.Invalid: - // Do nothing. We should never get here since invalid has already - // been handled above. - - case reflect.Bool: - printBool(f.fs, v.Bool()) - - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - printInt(f.fs, v.Int(), 10) - - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - printUint(f.fs, v.Uint(), 10) - - case reflect.Float32: - printFloat(f.fs, v.Float(), 32) - - case reflect.Float64: - printFloat(f.fs, v.Float(), 64) - - case reflect.Complex64: - printComplex(f.fs, v.Complex(), 32) - - case reflect.Complex128: - printComplex(f.fs, v.Complex(), 64) - - case reflect.Slice: - if v.IsNil() { - f.fs.Write(nilAngleBytes) - break - } - fallthrough - - case reflect.Array: - f.fs.Write(openBracketBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - numEntries := v.Len() - for i := 0; i < numEntries; i++ { - if i > 0 { - f.fs.Write(spaceBytes) - } - f.ignoreNextType = true - f.format(f.unpackValue(v.Index(i))) - } - } - f.depth-- - f.fs.Write(closeBracketBytes) - - case reflect.String: - f.fs.Write([]byte(v.String())) - - case reflect.Interface: - // The only time we should get here is for nil interfaces due to - // unpackValue calls. - if v.IsNil() { - f.fs.Write(nilAngleBytes) - } - - case reflect.Ptr: - // Do nothing. We should never get here since pointers have already - // been handled above. - - case reflect.Map: - // nil maps should be indicated as different than empty maps - if v.IsNil() { - f.fs.Write(nilAngleBytes) - break - } - - f.fs.Write(openMapBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - keys := v.MapKeys() - if f.cs.SortKeys { - sortValues(keys, f.cs) - } - for i, key := range keys { - if i > 0 { - f.fs.Write(spaceBytes) - } - f.ignoreNextType = true - f.format(f.unpackValue(key)) - f.fs.Write(colonBytes) - f.ignoreNextType = true - f.format(f.unpackValue(v.MapIndex(key))) - } - } - f.depth-- - f.fs.Write(closeMapBytes) - - case reflect.Struct: - numFields := v.NumField() - f.fs.Write(openBraceBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - vt := v.Type() - for i := 0; i < numFields; i++ { - if i > 0 { - f.fs.Write(spaceBytes) - } - vtf := vt.Field(i) - if f.fs.Flag('+') || f.fs.Flag('#') { - f.fs.Write([]byte(vtf.Name)) - f.fs.Write(colonBytes) - } - f.format(f.unpackValue(v.Field(i))) - } - } - f.depth-- - f.fs.Write(closeBraceBytes) - - case reflect.Uintptr: - printHexPtr(f.fs, uintptr(v.Uint())) - - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - printHexPtr(f.fs, v.Pointer()) - - // There were not any other types at the time this code was written, but - // fall back to letting the default fmt package handle it if any get added. - default: - format := f.buildDefaultFormat() - if v.CanInterface() { - fmt.Fprintf(f.fs, format, v.Interface()) - } else { - fmt.Fprintf(f.fs, format, v.String()) - } - } -} - -// Format satisfies the fmt.Formatter interface. See NewFormatter for usage -// details. -func (f *formatState) Format(fs fmt.State, verb rune) { - f.fs = fs - - // Use standard formatting for verbs that are not v. - if verb != 'v' { - format := f.constructOrigFormat(verb) - fmt.Fprintf(fs, format, f.value) - return - } - - if f.value == nil { - if fs.Flag('#') { - fs.Write(interfaceBytes) - } - fs.Write(nilAngleBytes) - return - } - - f.format(reflect.ValueOf(f.value)) -} - -// newFormatter is a helper function to consolidate the logic from the various -// public methods which take varying config states. -func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter { - fs := &formatState{value: v, cs: cs} - fs.pointers = make(map[uintptr]int) - return fs -} - -/* -NewFormatter returns a custom formatter that satisfies the fmt.Formatter -interface. As a result, it integrates cleanly with standard fmt package -printing functions. The formatter is useful for inline printing of smaller data -types similar to the standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Typically this function shouldn't be called directly. It is much easier to make -use of the custom formatter by calling one of the convenience functions such as -Printf, Println, or Fprintf. -*/ -func NewFormatter(v interface{}) fmt.Formatter { - return newFormatter(&Config, v) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/spew.go b/vendor/github.com/davecgh/go-spew/spew/spew.go deleted file mode 100644 index 32c0e3388..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/spew.go +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "fmt" - "io" -) - -// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the formatted string as a value that satisfies error. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Errorf(format string, a ...interface{}) (err error) { - return fmt.Errorf(format, convertArgs(a)...) -} - -// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprint(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprint(w, convertArgs(a)...) -} - -// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - return fmt.Fprintf(w, format, convertArgs(a)...) -} - -// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it -// passed with a default Formatter interface returned by NewFormatter. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprintln(w, convertArgs(a)...) -} - -// Print is a wrapper for fmt.Print that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) -func Print(a ...interface{}) (n int, err error) { - return fmt.Print(convertArgs(a)...) -} - -// Printf is a wrapper for fmt.Printf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Printf(format string, a ...interface{}) (n int, err error) { - return fmt.Printf(format, convertArgs(a)...) -} - -// Println is a wrapper for fmt.Println that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) -func Println(a ...interface{}) (n int, err error) { - return fmt.Println(convertArgs(a)...) -} - -// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprint(a ...interface{}) string { - return fmt.Sprint(convertArgs(a)...) -} - -// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprintf(format string, a ...interface{}) string { - return fmt.Sprintf(format, convertArgs(a)...) -} - -// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it -// were passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprintln(a ...interface{}) string { - return fmt.Sprintln(convertArgs(a)...) -} - -// convertArgs accepts a slice of arguments and returns a slice of the same -// length with each argument converted to a default spew Formatter interface. -func convertArgs(args []interface{}) (formatters []interface{}) { - formatters = make([]interface{}, len(args)) - for index, arg := range args { - formatters[index] = NewFormatter(arg) - } - return formatters -} 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 62c893550..000000000 --- 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 3aa6d060d..000000000 --- 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 a2c9fda21..000000000 --- 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 fcddad1fa..000000000 --- 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 c6b361f01..000000000 --- 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 c881b63ac..000000000 --- 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 e92279793..000000000 --- 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 9f1839485..000000000 --- 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 a9689e811..000000000 --- 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 9c9e88a17..000000000 --- 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 706a84f18..000000000 --- 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/dgryski/go-rendezvous/LICENSE b/vendor/github.com/dgryski/go-rendezvous/LICENSE deleted file mode 100644 index 22080f736..000000000 --- a/vendor/github.com/dgryski/go-rendezvous/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017-2020 Damian Gryski - -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/dgryski/go-rendezvous/rdv.go b/vendor/github.com/dgryski/go-rendezvous/rdv.go deleted file mode 100644 index 7a6f8203c..000000000 --- a/vendor/github.com/dgryski/go-rendezvous/rdv.go +++ /dev/null @@ -1,79 +0,0 @@ -package rendezvous - -type Rendezvous struct { - nodes map[string]int - nstr []string - nhash []uint64 - hash Hasher -} - -type Hasher func(s string) uint64 - -func New(nodes []string, hash Hasher) *Rendezvous { - r := &Rendezvous{ - nodes: make(map[string]int, len(nodes)), - nstr: make([]string, len(nodes)), - nhash: make([]uint64, len(nodes)), - hash: hash, - } - - for i, n := range nodes { - r.nodes[n] = i - r.nstr[i] = n - r.nhash[i] = hash(n) - } - - return r -} - -func (r *Rendezvous) Lookup(k string) string { - // short-circuit if we're empty - if len(r.nodes) == 0 { - return "" - } - - khash := r.hash(k) - - var midx int - var mhash = xorshiftMult64(khash ^ r.nhash[0]) - - for i, nhash := range r.nhash[1:] { - if h := xorshiftMult64(khash ^ nhash); h > mhash { - midx = i + 1 - mhash = h - } - } - - return r.nstr[midx] -} - -func (r *Rendezvous) Add(node string) { - r.nodes[node] = len(r.nstr) - r.nstr = append(r.nstr, node) - r.nhash = append(r.nhash, r.hash(node)) -} - -func (r *Rendezvous) Remove(node string) { - // find index of node to remove - nidx := r.nodes[node] - - // remove from the slices - l := len(r.nstr) - r.nstr[nidx] = r.nstr[l] - r.nstr = r.nstr[:l] - - r.nhash[nidx] = r.nhash[l] - r.nhash = r.nhash[:l] - - // update the map - delete(r.nodes, node) - moved := r.nstr[nidx] - r.nodes[moved] = nidx -} - -func xorshiftMult64(x uint64) uint64 { - x ^= x >> 12 // a - x ^= x << 25 // b - x ^= x >> 27 // c - return x * 2685821657736338717 -} diff --git a/vendor/github.com/ettle/strcase/.gitignore b/vendor/github.com/ettle/strcase/.gitignore deleted file mode 100644 index 54bc1fbff..000000000 --- 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 b7ce85d42..000000000 --- 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 4d7a894f0..000000000 --- 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 4f0116be2..000000000 --- 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 ac98b4aa5..000000000 --- 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 a984da80d..000000000 --- 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 09344e40f..000000000 --- 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 2e7eb955b..000000000 --- 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 cb901d079..000000000 --- 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 c3bf14a8f..000000000 --- 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 3c313d3e9..000000000 --- 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 32bc29759..000000000 --- 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 46b4f7a68..000000000 --- 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 b75e25a51..000000000 --- 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/color/LICENSE.md b/vendor/github.com/fatih/color/LICENSE.md deleted file mode 100644 index 25fdaf639..000000000 --- a/vendor/github.com/fatih/color/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 Fatih Arslan - -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/fatih/color/README.md b/vendor/github.com/fatih/color/README.md deleted file mode 100644 index be82827ca..000000000 --- a/vendor/github.com/fatih/color/README.md +++ /dev/null @@ -1,176 +0,0 @@ -# color [![](https://github.com/fatih/color/workflows/build/badge.svg)](https://github.com/fatih/color/actions) [![PkgGoDev](https://pkg.go.dev/badge/github.com/fatih/color)](https://pkg.go.dev/github.com/fatih/color) - -Color lets you use colorized outputs in terms of [ANSI Escape -Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It -has support for Windows too! The API can be used in several ways, pick one that -suits you. - -![Color](https://user-images.githubusercontent.com/438920/96832689-03b3e000-13f4-11eb-9803-46f4c4de3406.jpg) - -## Install - -```bash -go get github.com/fatih/color -``` - -## Examples - -### Standard colors - -```go -// Print with default helper functions -color.Cyan("Prints text in cyan.") - -// A newline will be appended automatically -color.Blue("Prints %s in blue.", "text") - -// These are using the default foreground colors -color.Red("We have red") -color.Magenta("And many others ..") - -``` - -### Mix and reuse colors - -```go -// Create a new color object -c := color.New(color.FgCyan).Add(color.Underline) -c.Println("Prints cyan text with an underline.") - -// Or just add them to New() -d := color.New(color.FgCyan, color.Bold) -d.Printf("This prints bold cyan %s\n", "too!.") - -// Mix up foreground and background colors, create new mixes! -red := color.New(color.FgRed) - -boldRed := red.Add(color.Bold) -boldRed.Println("This will print text in bold red.") - -whiteBackground := red.Add(color.BgWhite) -whiteBackground.Println("Red text with white background.") -``` - -### Use your own output (io.Writer) - -```go -// Use your own io.Writer output -color.New(color.FgBlue).Fprintln(myWriter, "blue color!") - -blue := color.New(color.FgBlue) -blue.Fprint(writer, "This will print text in blue.") -``` - -### Custom print functions (PrintFunc) - -```go -// Create a custom print function for convenience -red := color.New(color.FgRed).PrintfFunc() -red("Warning") -red("Error: %s", err) - -// Mix up multiple attributes -notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() -notice("Don't forget this...") -``` - -### Custom fprint functions (FprintFunc) - -```go -blue := color.New(color.FgBlue).FprintfFunc() -blue(myWriter, "important notice: %s", stars) - -// Mix up with multiple attributes -success := color.New(color.Bold, color.FgGreen).FprintlnFunc() -success(myWriter, "Don't forget this...") -``` - -### Insert into noncolor strings (SprintFunc) - -```go -// Create SprintXxx functions to mix strings with other non-colorized strings: -yellow := color.New(color.FgYellow).SprintFunc() -red := color.New(color.FgRed).SprintFunc() -fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error")) - -info := color.New(color.FgWhite, color.BgGreen).SprintFunc() -fmt.Printf("This %s rocks!\n", info("package")) - -// Use helper functions -fmt.Println("This", color.RedString("warning"), "should be not neglected.") -fmt.Printf("%v %v\n", color.GreenString("Info:"), "an important message.") - -// Windows supported too! Just don't forget to change the output to color.Output -fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) -``` - -### Plug into existing code - -```go -// Use handy standard colors -color.Set(color.FgYellow) - -fmt.Println("Existing text will now be in yellow") -fmt.Printf("This one %s\n", "too") - -color.Unset() // Don't forget to unset - -// You can mix up parameters -color.Set(color.FgMagenta, color.Bold) -defer color.Unset() // Use it in your function - -fmt.Println("All text will now be bold magenta.") -``` - -### Disable/Enable color - -There might be a case where you want to explicitly disable/enable color output. the -`go-isatty` package will automatically disable color output for non-tty output streams -(for example if the output were piped directly to `less`). - -The `color` package also disables color output if the [`NO_COLOR`](https://no-color.org) environment -variable is set to a non-empty string. - -`Color` has support to disable/enable colors programmatically both globally and -for single color definitions. For example suppose you have a CLI app and a -`-no-color` bool flag. You can easily disable the color output with: - -```go -var flagNoColor = flag.Bool("no-color", false, "Disable color output") - -if *flagNoColor { - color.NoColor = true // disables colorized output -} -``` - -It also has support for single color definitions (local). You can -disable/enable color output on the fly: - -```go -c := color.New(color.FgCyan) -c.Println("Prints cyan text") - -c.DisableColor() -c.Println("This is printed without any color") - -c.EnableColor() -c.Println("This prints again cyan...") -``` - -## GitHub Actions - -To output color in GitHub Actions (or other CI systems that support ANSI colors), make sure to set `color.NoColor = false` so that it bypasses the check for non-tty output streams. - -## Todo - -* Save/Return previous values -* Evaluate fmt.Formatter interface - -## Credits - -* [Fatih Arslan](https://github.com/fatih) -* Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) - -## License - -The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go deleted file mode 100644 index 81094e87c..000000000 --- a/vendor/github.com/fatih/color/color.go +++ /dev/null @@ -1,655 +0,0 @@ -package color - -import ( - "fmt" - "io" - "os" - "strconv" - "strings" - "sync" - - "github.com/mattn/go-colorable" - "github.com/mattn/go-isatty" -) - -var ( - // NoColor defines if the output is colorized or not. It's dynamically set to - // false or true based on the stdout's file descriptor referring to a terminal - // or not. It's also set to true if the NO_COLOR environment variable is - // set (regardless of its value). This is a global option and affects all - // colors. For more control over each color block use the methods - // DisableColor() individually. - NoColor = noColorIsSet() || os.Getenv("TERM") == "dumb" || - (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) - - // Output defines the standard output of the print functions. By default, - // os.Stdout is used. - Output = colorable.NewColorableStdout() - - // Error defines a color supporting writer for os.Stderr. - Error = colorable.NewColorableStderr() - - // colorsCache is used to reduce the count of created Color objects and - // allows to reuse already created objects with required Attribute. - colorsCache = make(map[Attribute]*Color) - colorsCacheMu sync.Mutex // protects colorsCache -) - -// noColorIsSet returns true if the environment variable NO_COLOR is set to a non-empty string. -func noColorIsSet() bool { - return os.Getenv("NO_COLOR") != "" -} - -// Color defines a custom color object which is defined by SGR parameters. -type Color struct { - params []Attribute - noColor *bool -} - -// Attribute defines a single SGR Code -type Attribute int - -const escape = "\x1b" - -// Base attributes -const ( - Reset Attribute = iota - Bold - Faint - Italic - Underline - BlinkSlow - BlinkRapid - ReverseVideo - Concealed - CrossedOut -) - -const ( - ResetBold Attribute = iota + 22 - ResetItalic - ResetUnderline - ResetBlinking - _ - ResetReversed - ResetConcealed - ResetCrossedOut -) - -var mapResetAttributes map[Attribute]Attribute = map[Attribute]Attribute{ - Bold: ResetBold, - Faint: ResetBold, - Italic: ResetItalic, - Underline: ResetUnderline, - BlinkSlow: ResetBlinking, - BlinkRapid: ResetBlinking, - ReverseVideo: ResetReversed, - Concealed: ResetConcealed, - CrossedOut: ResetCrossedOut, -} - -// Foreground text colors -const ( - FgBlack Attribute = iota + 30 - FgRed - FgGreen - FgYellow - FgBlue - FgMagenta - FgCyan - FgWhite -) - -// Foreground Hi-Intensity text colors -const ( - FgHiBlack Attribute = iota + 90 - FgHiRed - FgHiGreen - FgHiYellow - FgHiBlue - FgHiMagenta - FgHiCyan - FgHiWhite -) - -// Background text colors -const ( - BgBlack Attribute = iota + 40 - BgRed - BgGreen - BgYellow - BgBlue - BgMagenta - BgCyan - BgWhite -) - -// Background Hi-Intensity text colors -const ( - BgHiBlack Attribute = iota + 100 - BgHiRed - BgHiGreen - BgHiYellow - BgHiBlue - BgHiMagenta - BgHiCyan - BgHiWhite -) - -// New returns a newly created color object. -func New(value ...Attribute) *Color { - c := &Color{ - params: make([]Attribute, 0), - } - - if noColorIsSet() { - c.noColor = boolPtr(true) - } - - c.Add(value...) - return c -} - -// Set sets the given parameters immediately. It will change the color of -// output with the given SGR parameters until color.Unset() is called. -func Set(p ...Attribute) *Color { - c := New(p...) - c.Set() - return c -} - -// Unset resets all escape attributes and clears the output. Usually should -// be called after Set(). -func Unset() { - if NoColor { - return - } - - fmt.Fprintf(Output, "%s[%dm", escape, Reset) -} - -// Set sets the SGR sequence. -func (c *Color) Set() *Color { - if c.isNoColorSet() { - return c - } - - fmt.Fprint(Output, c.format()) - return c -} - -func (c *Color) unset() { - if c.isNoColorSet() { - return - } - - Unset() -} - -// SetWriter is used to set the SGR sequence with the given io.Writer. This is -// a low-level function, and users should use the higher-level functions, such -// as color.Fprint, color.Print, etc. -func (c *Color) SetWriter(w io.Writer) *Color { - if c.isNoColorSet() { - return c - } - - fmt.Fprint(w, c.format()) - return c -} - -// UnsetWriter resets all escape attributes and clears the output with the give -// io.Writer. Usually should be called after SetWriter(). -func (c *Color) UnsetWriter(w io.Writer) { - if c.isNoColorSet() { - return - } - - if NoColor { - return - } - - fmt.Fprintf(w, "%s[%dm", escape, Reset) -} - -// Add is used to chain SGR parameters. Use as many as parameters to combine -// and create custom color objects. Example: Add(color.FgRed, color.Underline). -func (c *Color) Add(value ...Attribute) *Color { - c.params = append(c.params, value...) - return c -} - -// Fprint formats using the default formats for its operands and writes to w. -// Spaces are added between operands when neither is a string. -// It returns the number of bytes written and any write error encountered. -// On Windows, users should wrap w with colorable.NewColorable() if w is of -// type *os.File. -func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - c.SetWriter(w) - defer c.UnsetWriter(w) - - return fmt.Fprint(w, a...) -} - -// Print formats using the default formats for its operands and writes to -// standard output. Spaces are added between operands when neither is a -// string. It returns the number of bytes written and any write error -// encountered. This is the standard fmt.Print() method wrapped with the given -// color. -func (c *Color) Print(a ...interface{}) (n int, err error) { - c.Set() - defer c.unset() - - return fmt.Fprint(Output, a...) -} - -// Fprintf formats according to a format specifier and writes to w. -// It returns the number of bytes written and any write error encountered. -// On Windows, users should wrap w with colorable.NewColorable() if w is of -// type *os.File. -func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - c.SetWriter(w) - defer c.UnsetWriter(w) - - return fmt.Fprintf(w, format, a...) -} - -// Printf formats according to a format specifier and writes to standard output. -// It returns the number of bytes written and any write error encountered. -// This is the standard fmt.Printf() method wrapped with the given color. -func (c *Color) Printf(format string, a ...interface{}) (n int, err error) { - c.Set() - defer c.unset() - - return fmt.Fprintf(Output, format, a...) -} - -// Fprintln formats using the default formats for its operands and writes to w. -// Spaces are always added between operands and a newline is appended. -// On Windows, users should wrap w with colorable.NewColorable() if w is of -// type *os.File. -func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprintln(w, c.wrap(sprintln(a...))) -} - -// Println formats using the default formats for its operands and writes to -// standard output. Spaces are always added between operands and a newline is -// appended. It returns the number of bytes written and any write error -// encountered. This is the standard fmt.Print() method wrapped with the given -// color. -func (c *Color) Println(a ...interface{}) (n int, err error) { - return fmt.Fprintln(Output, c.wrap(sprintln(a...))) -} - -// Sprint is just like Print, but returns a string instead of printing it. -func (c *Color) Sprint(a ...interface{}) string { - return c.wrap(fmt.Sprint(a...)) -} - -// Sprintln is just like Println, but returns a string instead of printing it. -func (c *Color) Sprintln(a ...interface{}) string { - return c.wrap(sprintln(a...)) + "\n" -} - -// Sprintf is just like Printf, but returns a string instead of printing it. -func (c *Color) Sprintf(format string, a ...interface{}) string { - return c.wrap(fmt.Sprintf(format, a...)) -} - -// FprintFunc returns a new function that prints the passed arguments as -// colorized with color.Fprint(). -func (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) { - return func(w io.Writer, a ...interface{}) { - c.Fprint(w, a...) - } -} - -// PrintFunc returns a new function that prints the passed arguments as -// colorized with color.Print(). -func (c *Color) PrintFunc() func(a ...interface{}) { - return func(a ...interface{}) { - c.Print(a...) - } -} - -// FprintfFunc returns a new function that prints the passed arguments as -// colorized with color.Fprintf(). -func (c *Color) FprintfFunc() func(w io.Writer, format string, a ...interface{}) { - return func(w io.Writer, format string, a ...interface{}) { - c.Fprintf(w, format, a...) - } -} - -// PrintfFunc returns a new function that prints the passed arguments as -// colorized with color.Printf(). -func (c *Color) PrintfFunc() func(format string, a ...interface{}) { - return func(format string, a ...interface{}) { - c.Printf(format, a...) - } -} - -// FprintlnFunc returns a new function that prints the passed arguments as -// colorized with color.Fprintln(). -func (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) { - return func(w io.Writer, a ...interface{}) { - c.Fprintln(w, a...) - } -} - -// PrintlnFunc returns a new function that prints the passed arguments as -// colorized with color.Println(). -func (c *Color) PrintlnFunc() func(a ...interface{}) { - return func(a ...interface{}) { - c.Println(a...) - } -} - -// SprintFunc returns a new function that returns colorized strings for the -// given arguments with fmt.Sprint(). Useful to put into or mix into other -// string. Windows users should use this in conjunction with color.Output, example: -// -// put := New(FgYellow).SprintFunc() -// fmt.Fprintf(color.Output, "This is a %s", put("warning")) -func (c *Color) SprintFunc() func(a ...interface{}) string { - return func(a ...interface{}) string { - return c.wrap(fmt.Sprint(a...)) - } -} - -// SprintfFunc returns a new function that returns colorized strings for the -// given arguments with fmt.Sprintf(). Useful to put into or mix into other -// string. Windows users should use this in conjunction with color.Output. -func (c *Color) SprintfFunc() func(format string, a ...interface{}) string { - return func(format string, a ...interface{}) string { - return c.wrap(fmt.Sprintf(format, a...)) - } -} - -// SprintlnFunc returns a new function that returns colorized strings for the -// given arguments with fmt.Sprintln(). Useful to put into or mix into other -// string. Windows users should use this in conjunction with color.Output. -func (c *Color) SprintlnFunc() func(a ...interface{}) string { - return func(a ...interface{}) string { - return c.wrap(sprintln(a...)) + "\n" - } -} - -// sequence returns a formatted SGR sequence to be plugged into a "\x1b[...m" -// an example output might be: "1;36" -> bold cyan -func (c *Color) sequence() string { - format := make([]string, len(c.params)) - for i, v := range c.params { - format[i] = strconv.Itoa(int(v)) - } - - return strings.Join(format, ";") -} - -// wrap wraps the s string with the colors attributes. The string is ready to -// be printed. -func (c *Color) wrap(s string) string { - if c.isNoColorSet() { - return s - } - - return c.format() + s + c.unformat() -} - -func (c *Color) format() string { - return fmt.Sprintf("%s[%sm", escape, c.sequence()) -} - -func (c *Color) unformat() string { - //return fmt.Sprintf("%s[%dm", escape, Reset) - //for each element in sequence let's use the speficic reset escape, ou the generic one if not found - format := make([]string, len(c.params)) - for i, v := range c.params { - format[i] = strconv.Itoa(int(Reset)) - ra, ok := mapResetAttributes[v] - if ok { - format[i] = strconv.Itoa(int(ra)) - } - } - - return fmt.Sprintf("%s[%sm", escape, strings.Join(format, ";")) -} - -// DisableColor disables the color output. Useful to not change any existing -// code and still being able to output. Can be used for flags like -// "--no-color". To enable back use EnableColor() method. -func (c *Color) DisableColor() { - c.noColor = boolPtr(true) -} - -// EnableColor enables the color output. Use it in conjunction with -// DisableColor(). Otherwise, this method has no side effects. -func (c *Color) EnableColor() { - c.noColor = boolPtr(false) -} - -func (c *Color) isNoColorSet() bool { - // check first if we have user set action - if c.noColor != nil { - return *c.noColor - } - - // if not return the global option, which is disabled by default - return NoColor -} - -// Equals returns a boolean value indicating whether two colors are equal. -func (c *Color) Equals(c2 *Color) bool { - if c == nil && c2 == nil { - return true - } - if c == nil || c2 == nil { - return false - } - if len(c.params) != len(c2.params) { - return false - } - - for _, attr := range c.params { - if !c2.attrExists(attr) { - return false - } - } - - return true -} - -func (c *Color) attrExists(a Attribute) bool { - for _, attr := range c.params { - if attr == a { - return true - } - } - - return false -} - -func boolPtr(v bool) *bool { - return &v -} - -func getCachedColor(p Attribute) *Color { - colorsCacheMu.Lock() - defer colorsCacheMu.Unlock() - - c, ok := colorsCache[p] - if !ok { - c = New(p) - colorsCache[p] = c - } - - return c -} - -func colorPrint(format string, p Attribute, a ...interface{}) { - c := getCachedColor(p) - - if !strings.HasSuffix(format, "\n") { - format += "\n" - } - - if len(a) == 0 { - c.Print(format) - } else { - c.Printf(format, a...) - } -} - -func colorString(format string, p Attribute, a ...interface{}) string { - c := getCachedColor(p) - - if len(a) == 0 { - return c.SprintFunc()(format) - } - - return c.SprintfFunc()(format, a...) -} - -// Black is a convenient helper function to print with black foreground. A -// newline is appended to format by default. -func Black(format string, a ...interface{}) { colorPrint(format, FgBlack, a...) } - -// Red is a convenient helper function to print with red foreground. A -// newline is appended to format by default. -func Red(format string, a ...interface{}) { colorPrint(format, FgRed, a...) } - -// Green is a convenient helper function to print with green foreground. A -// newline is appended to format by default. -func Green(format string, a ...interface{}) { colorPrint(format, FgGreen, a...) } - -// Yellow is a convenient helper function to print with yellow foreground. -// A newline is appended to format by default. -func Yellow(format string, a ...interface{}) { colorPrint(format, FgYellow, a...) } - -// Blue is a convenient helper function to print with blue foreground. A -// newline is appended to format by default. -func Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, a...) } - -// Magenta is a convenient helper function to print with magenta foreground. -// A newline is appended to format by default. -func Magenta(format string, a ...interface{}) { colorPrint(format, FgMagenta, a...) } - -// Cyan is a convenient helper function to print with cyan foreground. A -// newline is appended to format by default. -func Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, a...) } - -// White is a convenient helper function to print with white foreground. A -// newline is appended to format by default. -func White(format string, a ...interface{}) { colorPrint(format, FgWhite, a...) } - -// BlackString is a convenient helper function to return a string with black -// foreground. -func BlackString(format string, a ...interface{}) string { return colorString(format, FgBlack, a...) } - -// RedString is a convenient helper function to return a string with red -// foreground. -func RedString(format string, a ...interface{}) string { return colorString(format, FgRed, a...) } - -// GreenString is a convenient helper function to return a string with green -// foreground. -func GreenString(format string, a ...interface{}) string { return colorString(format, FgGreen, a...) } - -// YellowString is a convenient helper function to return a string with yellow -// foreground. -func YellowString(format string, a ...interface{}) string { return colorString(format, FgYellow, a...) } - -// BlueString is a convenient helper function to return a string with blue -// foreground. -func BlueString(format string, a ...interface{}) string { return colorString(format, FgBlue, a...) } - -// MagentaString is a convenient helper function to return a string with magenta -// foreground. -func MagentaString(format string, a ...interface{}) string { - return colorString(format, FgMagenta, a...) -} - -// CyanString is a convenient helper function to return a string with cyan -// foreground. -func CyanString(format string, a ...interface{}) string { return colorString(format, FgCyan, a...) } - -// WhiteString is a convenient helper function to return a string with white -// foreground. -func WhiteString(format string, a ...interface{}) string { return colorString(format, FgWhite, a...) } - -// HiBlack is a convenient helper function to print with hi-intensity black foreground. A -// newline is appended to format by default. -func HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiBlack, a...) } - -// HiRed is a convenient helper function to print with hi-intensity red foreground. A -// newline is appended to format by default. -func HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed, a...) } - -// HiGreen is a convenient helper function to print with hi-intensity green foreground. A -// newline is appended to format by default. -func HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiGreen, a...) } - -// HiYellow is a convenient helper function to print with hi-intensity yellow foreground. -// A newline is appended to format by default. -func HiYellow(format string, a ...interface{}) { colorPrint(format, FgHiYellow, a...) } - -// HiBlue is a convenient helper function to print with hi-intensity blue foreground. A -// newline is appended to format by default. -func HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBlue, a...) } - -// HiMagenta is a convenient helper function to print with hi-intensity magenta foreground. -// A newline is appended to format by default. -func HiMagenta(format string, a ...interface{}) { colorPrint(format, FgHiMagenta, a...) } - -// HiCyan is a convenient helper function to print with hi-intensity cyan foreground. A -// newline is appended to format by default. -func HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCyan, a...) } - -// HiWhite is a convenient helper function to print with hi-intensity white foreground. A -// newline is appended to format by default. -func HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiWhite, a...) } - -// HiBlackString is a convenient helper function to return a string with hi-intensity black -// foreground. -func HiBlackString(format string, a ...interface{}) string { - return colorString(format, FgHiBlack, a...) -} - -// HiRedString is a convenient helper function to return a string with hi-intensity red -// foreground. -func HiRedString(format string, a ...interface{}) string { return colorString(format, FgHiRed, a...) } - -// HiGreenString is a convenient helper function to return a string with hi-intensity green -// foreground. -func HiGreenString(format string, a ...interface{}) string { - return colorString(format, FgHiGreen, a...) -} - -// HiYellowString is a convenient helper function to return a string with hi-intensity yellow -// foreground. -func HiYellowString(format string, a ...interface{}) string { - return colorString(format, FgHiYellow, a...) -} - -// HiBlueString is a convenient helper function to return a string with hi-intensity blue -// foreground. -func HiBlueString(format string, a ...interface{}) string { return colorString(format, FgHiBlue, a...) } - -// HiMagentaString is a convenient helper function to return a string with hi-intensity magenta -// foreground. -func HiMagentaString(format string, a ...interface{}) string { - return colorString(format, FgHiMagenta, a...) -} - -// HiCyanString is a convenient helper function to return a string with hi-intensity cyan -// foreground. -func HiCyanString(format string, a ...interface{}) string { return colorString(format, FgHiCyan, a...) } - -// HiWhiteString is a convenient helper function to return a string with hi-intensity white -// foreground. -func HiWhiteString(format string, a ...interface{}) string { - return colorString(format, FgHiWhite, a...) -} - -// sprintln is a helper function to format a string with fmt.Sprintln and trim the trailing newline. -func sprintln(a ...interface{}) string { - return strings.TrimSuffix(fmt.Sprintln(a...), "\n") -} diff --git a/vendor/github.com/fatih/color/color_windows.go b/vendor/github.com/fatih/color/color_windows.go deleted file mode 100644 index be01c558e..000000000 --- a/vendor/github.com/fatih/color/color_windows.go +++ /dev/null @@ -1,19 +0,0 @@ -package color - -import ( - "os" - - "golang.org/x/sys/windows" -) - -func init() { - // Opt-in for ansi color support for current process. - // https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#output-sequences - var outMode uint32 - out := windows.Handle(os.Stdout.Fd()) - if err := windows.GetConsoleMode(out, &outMode); err != nil { - return - } - outMode |= windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING - _ = windows.SetConsoleMode(out, outMode) -} diff --git a/vendor/github.com/fatih/color/doc.go b/vendor/github.com/fatih/color/doc.go deleted file mode 100644 index 9491ad541..000000000 --- a/vendor/github.com/fatih/color/doc.go +++ /dev/null @@ -1,134 +0,0 @@ -/* -Package color is an ANSI color package to output colorized or SGR defined -output to the standard output. The API can be used in several way, pick one -that suits you. - -Use simple and default helper functions with predefined foreground colors: - - color.Cyan("Prints text in cyan.") - - // a newline will be appended automatically - color.Blue("Prints %s in blue.", "text") - - // More default foreground colors.. - color.Red("We have red") - color.Yellow("Yellow color too!") - color.Magenta("And many others ..") - - // Hi-intensity colors - color.HiGreen("Bright green color.") - color.HiBlack("Bright black means gray..") - color.HiWhite("Shiny white color!") - -However, there are times when custom color mixes are required. Below are some -examples to create custom color objects and use the print functions of each -separate color object. - - // Create a new color object - c := color.New(color.FgCyan).Add(color.Underline) - c.Println("Prints cyan text with an underline.") - - // Or just add them to New() - d := color.New(color.FgCyan, color.Bold) - d.Printf("This prints bold cyan %s\n", "too!.") - - - // Mix up foreground and background colors, create new mixes! - red := color.New(color.FgRed) - - boldRed := red.Add(color.Bold) - boldRed.Println("This will print text in bold red.") - - whiteBackground := red.Add(color.BgWhite) - whiteBackground.Println("Red text with White background.") - - // Use your own io.Writer output - color.New(color.FgBlue).Fprintln(myWriter, "blue color!") - - blue := color.New(color.FgBlue) - blue.Fprint(myWriter, "This will print text in blue.") - -You can create PrintXxx functions to simplify even more: - - // Create a custom print function for convenient - red := color.New(color.FgRed).PrintfFunc() - red("warning") - red("error: %s", err) - - // Mix up multiple attributes - notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() - notice("don't forget this...") - -You can also FprintXxx functions to pass your own io.Writer: - - blue := color.New(FgBlue).FprintfFunc() - blue(myWriter, "important notice: %s", stars) - - // Mix up with multiple attributes - success := color.New(color.Bold, color.FgGreen).FprintlnFunc() - success(myWriter, don't forget this...") - -Or create SprintXxx functions to mix strings with other non-colorized strings: - - yellow := New(FgYellow).SprintFunc() - red := New(FgRed).SprintFunc() - - fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) - - info := New(FgWhite, BgGreen).SprintFunc() - fmt.Printf("this %s rocks!\n", info("package")) - -Windows support is enabled by default. All Print functions work as intended. -However, only for color.SprintXXX functions, user should use fmt.FprintXXX and -set the output to color.Output: - - fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) - - info := New(FgWhite, BgGreen).SprintFunc() - fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) - -Using with existing code is possible. Just use the Set() method to set the -standard output to the given parameters. That way a rewrite of an existing -code is not required. - - // Use handy standard colors. - color.Set(color.FgYellow) - - fmt.Println("Existing text will be now in Yellow") - fmt.Printf("This one %s\n", "too") - - color.Unset() // don't forget to unset - - // You can mix up parameters - color.Set(color.FgMagenta, color.Bold) - defer color.Unset() // use it in your function - - fmt.Println("All text will be now bold magenta.") - -There might be a case where you want to disable color output (for example to -pipe the standard output of your app to somewhere else). `Color` has support to -disable colors both globally and for single color definition. For example -suppose you have a CLI app and a `--no-color` bool flag. You can easily disable -the color output with: - - var flagNoColor = flag.Bool("no-color", false, "Disable color output") - - if *flagNoColor { - color.NoColor = true // disables colorized output - } - -You can also disable the color by setting the NO_COLOR environment variable to any value. - -It also has support for single color definitions (local). You can -disable/enable color output on the fly: - - c := color.New(color.FgCyan) - c.Println("Prints cyan text") - - c.DisableColor() - c.Println("This is printed without any color") - - c.EnableColor() - c.Println("This prints again cyan...") -*/ -package color diff --git a/vendor/github.com/fatih/structtag/LICENSE b/vendor/github.com/fatih/structtag/LICENSE deleted file mode 100644 index 4fd15f9f8..000000000 --- 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 c4e8b1e86..000000000 --- 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 c168fb21c..000000000 --- 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 f288702d2..000000000 --- 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 ecd4915a8..000000000 --- a/vendor/github.com/firefart/nonamedreturns/analyzer/analyzer.go +++ /dev/null @@ -1,139 +0,0 @@ -package analyzer - -import ( - "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 := pass.ResultOf[inspect.Analyzer].(*inspector.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 -} - -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 fad895851..000000000 --- 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 32f1001be..000000000 --- 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 4cd0cbaf4..000000000 --- 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 a04f2907f..000000000 --- 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 6cbabe5ef..000000000 --- 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 cc01c08f5..000000000 --- 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 8a642563d..000000000 --- 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 e180c8fb0..000000000 --- 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 0731c5ef8..000000000 --- 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 b3ac3d8f5..000000000 --- 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 0f4ee52e8..000000000 --- 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 596885598..000000000 --- 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 a6d0e0ec8..000000000 --- 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 b572a37c3..000000000 --- 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 6fb8d8532..000000000 --- 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 36cc3845b..000000000 --- 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 98cd8476f..000000000 --- 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 02ce7deb0..000000000 --- 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 c9bedfb3b..000000000 --- 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 1c09f1a06..000000000 --- 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 45f88d6cb..000000000 --- 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 d357b8ef7..000000000 --- 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 2d8bcff25..000000000 --- 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 65f5077e8..000000000 --- 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 b4ee3c448..000000000 --- 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 a5c82fef5..000000000 --- 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 2fe2d0cdb..000000000 --- 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 0a377e4b6..000000000 --- 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/getkin/kin-openapi/LICENSE b/vendor/github.com/getkin/kin-openapi/LICENSE deleted file mode 100644 index 40fce95d2..000000000 --- a/vendor/github.com/getkin/kin-openapi/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017-2018 the 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/getkin/kin-openapi/jsoninfo/doc.go b/vendor/github.com/getkin/kin-openapi/jsoninfo/doc.go deleted file mode 100644 index e59ec2c34..000000000 --- a/vendor/github.com/getkin/kin-openapi/jsoninfo/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package jsoninfo provides information and functions for marshalling/unmarshalling JSON. -package jsoninfo diff --git a/vendor/github.com/getkin/kin-openapi/jsoninfo/field_info.go b/vendor/github.com/getkin/kin-openapi/jsoninfo/field_info.go deleted file mode 100644 index d949a79d3..000000000 --- a/vendor/github.com/getkin/kin-openapi/jsoninfo/field_info.go +++ /dev/null @@ -1,122 +0,0 @@ -package jsoninfo - -import ( - "reflect" - "strings" - "unicode" - "unicode/utf8" -) - -// FieldInfo contains information about JSON serialization of a field. -type FieldInfo struct { - MultipleFields bool // Whether multiple Go fields share this JSON name - HasJSONTag bool - TypeIsMarshaller bool - TypeIsUnmarshaller bool - JSONOmitEmpty bool - JSONString bool - Index []int - Type reflect.Type - JSONName string -} - -func AppendFields(fields []FieldInfo, parentIndex []int, t reflect.Type) []FieldInfo { - // For each field - numField := t.NumField() -iteration: - for i := 0; i < numField; i++ { - f := t.Field(i) - index := make([]int, 0, len(parentIndex)+1) - index = append(index, parentIndex...) - index = append(index, i) - - // See whether this is an embedded field - if f.Anonymous { - if f.Tag.Get("json") == "-" { - continue - } - fields = AppendFields(fields, index, f.Type) - continue iteration - } - - // Ignore certain types - switch f.Type.Kind() { - case reflect.Func, reflect.Chan: - continue iteration - } - - // Is it a private (lowercase) field? - firstRune, _ := utf8.DecodeRuneInString(f.Name) - if unicode.IsLower(firstRune) { - continue iteration - } - - // Declare a field - field := FieldInfo{ - Index: index, - Type: f.Type, - JSONName: f.Name, - } - - // Read "json" tag - jsonTag := f.Tag.Get("json") - - // Read our custom "multijson" tag that - // allows multiple fields with the same name. - if v := f.Tag.Get("multijson"); len(v) > 0 { - field.MultipleFields = true - jsonTag = v - } - - // Handle "-" - if jsonTag == "-" { - continue - } - - // Parse the tag - if len(jsonTag) > 0 { - field.HasJSONTag = true - for i, part := range strings.Split(jsonTag, ",") { - if i == 0 { - if len(part) > 0 { - field.JSONName = part - } - } else { - switch part { - case "omitempty": - field.JSONOmitEmpty = true - case "string": - field.JSONString = true - } - } - } - } - - if _, ok := field.Type.MethodByName("MarshalJSON"); ok { - field.TypeIsMarshaller = true - } - if _, ok := field.Type.MethodByName("UnmarshalJSON"); ok { - field.TypeIsUnmarshaller = true - } - - // Field is done - fields = append(fields, field) - } - - return fields -} - -type sortableFieldInfos []FieldInfo - -func (list sortableFieldInfos) Len() int { - return len(list) -} - -func (list sortableFieldInfos) Less(i, j int) bool { - return list[i].JSONName < list[j].JSONName -} - -func (list sortableFieldInfos) Swap(i, j int) { - a, b := list[i], list[j] - list[i], list[j] = b, a -} diff --git a/vendor/github.com/getkin/kin-openapi/jsoninfo/marshal.go b/vendor/github.com/getkin/kin-openapi/jsoninfo/marshal.go deleted file mode 100644 index 93de99a56..000000000 --- a/vendor/github.com/getkin/kin-openapi/jsoninfo/marshal.go +++ /dev/null @@ -1,162 +0,0 @@ -package jsoninfo - -import ( - "encoding/json" - "fmt" - "reflect" -) - -// MarshalStrictStruct function: -// * Marshals struct fields, ignoring MarshalJSON() and fields without 'json' tag. -// * Correctly handles StrictStruct semantics. -func MarshalStrictStruct(value StrictStruct) ([]byte, error) { - encoder := NewObjectEncoder() - if err := value.EncodeWith(encoder, value); err != nil { - return nil, err - } - return encoder.Bytes() -} - -type ObjectEncoder struct { - result map[string]json.RawMessage -} - -func NewObjectEncoder() *ObjectEncoder { - return &ObjectEncoder{ - result: make(map[string]json.RawMessage, 8), - } -} - -// Bytes returns the result of encoding. -func (encoder *ObjectEncoder) Bytes() ([]byte, error) { - return json.Marshal(encoder.result) -} - -// EncodeExtension adds a key/value to the current JSON object. -func (encoder *ObjectEncoder) EncodeExtension(key string, value interface{}) error { - data, err := json.Marshal(value) - if err != nil { - return err - } - encoder.result[key] = data - return nil -} - -// EncodeExtensionMap adds all properties to the result. -func (encoder *ObjectEncoder) EncodeExtensionMap(value map[string]json.RawMessage) error { - if value != nil { - result := encoder.result - for k, v := range value { - result[k] = v - } - } - return nil -} - -func (encoder *ObjectEncoder) EncodeStructFieldsAndExtensions(value interface{}) error { - reflection := reflect.ValueOf(value) - - // Follow "encoding/json" semantics - if reflection.Kind() != reflect.Ptr { - // Panic because this is a clear programming error - panic(fmt.Errorf("Value %s is not a pointer", reflection.Type().String())) - } - if reflection.IsNil() { - // Panic because this is a clear programming error - panic(fmt.Errorf("Value %s is nil", reflection.Type().String())) - } - - // Take the element - reflection = reflection.Elem() - - // Obtain typeInfo - typeInfo := GetTypeInfo(reflection.Type()) - - // Declare result - result := encoder.result - - // Supported fields -iteration: - for _, field := range typeInfo.Fields { - // Fields without JSON tag are ignored - if !field.HasJSONTag { - continue - } - - // Marshal - fieldValue := reflection.FieldByIndex(field.Index) - if v, ok := fieldValue.Interface().(json.Marshaler); ok { - if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() { - if field.JSONOmitEmpty { - continue iteration - } - result[field.JSONName] = []byte("null") - continue - } - fieldData, err := v.MarshalJSON() - if err != nil { - return err - } - result[field.JSONName] = fieldData - continue - } - switch fieldValue.Kind() { - case reflect.Ptr, reflect.Interface: - if fieldValue.IsNil() { - if field.JSONOmitEmpty { - continue iteration - } - result[field.JSONName] = []byte("null") - continue - } - case reflect.Struct: - case reflect.Map: - if field.JSONOmitEmpty && (fieldValue.IsNil() || fieldValue.Len() == 0) { - continue iteration - } - case reflect.Slice: - if field.JSONOmitEmpty && fieldValue.Len() == 0 { - continue iteration - } - case reflect.Bool: - x := fieldValue.Bool() - if field.JSONOmitEmpty && !x { - continue iteration - } - s := "false" - if x { - s = "true" - } - result[field.JSONName] = []byte(s) - continue iteration - case reflect.Int64, reflect.Int, reflect.Int32: - if field.JSONOmitEmpty && fieldValue.Int() == 0 { - continue iteration - } - case reflect.Uint64, reflect.Uint, reflect.Uint32: - if field.JSONOmitEmpty && fieldValue.Uint() == 0 { - continue iteration - } - case reflect.Float64: - if field.JSONOmitEmpty && fieldValue.Float() == 0.0 { - continue iteration - } - case reflect.String: - if field.JSONOmitEmpty && len(fieldValue.String()) == 0 { - continue iteration - } - default: - panic(fmt.Errorf("Field '%s' has unsupported type %s", field.JSONName, field.Type.String())) - } - - // No special treament is needed - // Use plain old "encoding/json".Marshal - fieldData, err := json.Marshal(fieldValue.Addr().Interface()) - if err != nil { - return err - } - result[field.JSONName] = fieldData - } - - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/jsoninfo/marshal_ref.go b/vendor/github.com/getkin/kin-openapi/jsoninfo/marshal_ref.go deleted file mode 100644 index 9738bf08f..000000000 --- a/vendor/github.com/getkin/kin-openapi/jsoninfo/marshal_ref.go +++ /dev/null @@ -1,30 +0,0 @@ -package jsoninfo - -import ( - "encoding/json" -) - -func MarshalRef(value string, otherwise interface{}) ([]byte, error) { - if len(value) > 0 { - return json.Marshal(&refProps{ - Ref: value, - }) - } - return json.Marshal(otherwise) -} - -func UnmarshalRef(data []byte, destRef *string, destOtherwise interface{}) error { - refProps := &refProps{} - if err := json.Unmarshal(data, refProps); err == nil { - ref := refProps.Ref - if len(ref) > 0 { - *destRef = ref - return nil - } - } - return json.Unmarshal(data, destOtherwise) -} - -type refProps struct { - Ref string `json:"$ref,omitempty"` -} diff --git a/vendor/github.com/getkin/kin-openapi/jsoninfo/strict_struct.go b/vendor/github.com/getkin/kin-openapi/jsoninfo/strict_struct.go deleted file mode 100644 index 6b4d83977..000000000 --- a/vendor/github.com/getkin/kin-openapi/jsoninfo/strict_struct.go +++ /dev/null @@ -1,6 +0,0 @@ -package jsoninfo - -type StrictStruct interface { - EncodeWith(encoder *ObjectEncoder, value interface{}) error - DecodeWith(decoder *ObjectDecoder, value interface{}) error -} diff --git a/vendor/github.com/getkin/kin-openapi/jsoninfo/type_info.go b/vendor/github.com/getkin/kin-openapi/jsoninfo/type_info.go deleted file mode 100644 index 5d7a4eda4..000000000 --- a/vendor/github.com/getkin/kin-openapi/jsoninfo/type_info.go +++ /dev/null @@ -1,68 +0,0 @@ -package jsoninfo - -import ( - "reflect" - "sort" - "sync" -) - -var ( - typeInfos = map[reflect.Type]*TypeInfo{} - typeInfosMutex sync.RWMutex -) - -// TypeInfo contains information about JSON serialization of a type -type TypeInfo struct { - Type reflect.Type - Fields []FieldInfo -} - -func GetTypeInfoForValue(value interface{}) *TypeInfo { - return GetTypeInfo(reflect.TypeOf(value)) -} - -// GetTypeInfo returns TypeInfo for the given type. -func GetTypeInfo(t reflect.Type) *TypeInfo { - for t.Kind() == reflect.Ptr { - t = t.Elem() - } - typeInfosMutex.RLock() - typeInfo, exists := typeInfos[t] - typeInfosMutex.RUnlock() - if exists { - return typeInfo - } - if t.Kind() != reflect.Struct { - typeInfo = &TypeInfo{ - Type: t, - } - } else { - // Allocate - typeInfo = &TypeInfo{ - Type: t, - Fields: make([]FieldInfo, 0, 16), - } - - // Add fields - typeInfo.Fields = AppendFields(nil, nil, t) - - // Sort fields - sort.Sort(sortableFieldInfos(typeInfo.Fields)) - } - - // Publish - typeInfosMutex.Lock() - typeInfos[t] = typeInfo - typeInfosMutex.Unlock() - return typeInfo -} - -// FieldNames returns all field names -func (typeInfo *TypeInfo) FieldNames() []string { - fields := typeInfo.Fields - names := make([]string, len(fields)) - for i, field := range fields { - names[i] = field.JSONName - } - return names -} diff --git a/vendor/github.com/getkin/kin-openapi/jsoninfo/unmarshal.go b/vendor/github.com/getkin/kin-openapi/jsoninfo/unmarshal.go deleted file mode 100644 index 329718758..000000000 --- a/vendor/github.com/getkin/kin-openapi/jsoninfo/unmarshal.go +++ /dev/null @@ -1,121 +0,0 @@ -package jsoninfo - -import ( - "encoding/json" - "fmt" - "reflect" -) - -// UnmarshalStrictStruct function: -// * Unmarshals struct fields, ignoring UnmarshalJSON(...) and fields without 'json' tag. -// * Correctly handles StrictStruct -func UnmarshalStrictStruct(data []byte, value StrictStruct) error { - decoder, err := NewObjectDecoder(data) - if err != nil { - return err - } - return value.DecodeWith(decoder, value) -} - -type ObjectDecoder struct { - Data []byte - remainingFields map[string]json.RawMessage -} - -func NewObjectDecoder(data []byte) (*ObjectDecoder, error) { - var remainingFields map[string]json.RawMessage - if err := json.Unmarshal(data, &remainingFields); err != nil { - return nil, fmt.Errorf("Failed to unmarshal extension properties: %v\nInput: %s", err, data) - } - return &ObjectDecoder{ - Data: data, - remainingFields: remainingFields, - }, nil -} - -// DecodeExtensionMap returns all properties that were not decoded previously. -func (decoder *ObjectDecoder) DecodeExtensionMap() map[string]json.RawMessage { - return decoder.remainingFields -} - -func (decoder *ObjectDecoder) DecodeStructFieldsAndExtensions(value interface{}) error { - reflection := reflect.ValueOf(value) - if reflection.Kind() != reflect.Ptr { - panic(fmt.Errorf("Value %T is not a pointer", value)) - } - if reflection.IsNil() { - panic(fmt.Errorf("Value %T is nil", value)) - } - reflection = reflection.Elem() - for (reflection.Kind() == reflect.Interface || reflection.Kind() == reflect.Ptr) && !reflection.IsNil() { - reflection = reflection.Elem() - } - reflectionType := reflection.Type() - if reflectionType.Kind() != reflect.Struct { - panic(fmt.Errorf("Value %T is not a struct", value)) - } - typeInfo := GetTypeInfo(reflectionType) - - // Supported fields - fields := typeInfo.Fields - remainingFields := decoder.remainingFields - for fieldIndex, field := range fields { - // Fields without JSON tag are ignored - if !field.HasJSONTag { - continue - } - - // Get data - fieldData, exists := remainingFields[field.JSONName] - if !exists { - continue - } - - // Unmarshal - if field.TypeIsUnmarshaller { - fieldType := field.Type - isPtr := false - if fieldType.Kind() == reflect.Ptr { - fieldType = fieldType.Elem() - isPtr = true - } - fieldValue := reflect.New(fieldType) - if err := fieldValue.Interface().(json.Unmarshaler).UnmarshalJSON(fieldData); err != nil { - if field.MultipleFields { - i := fieldIndex + 1 - if i < len(fields) && fields[i].JSONName == field.JSONName { - continue - } - } - return fmt.Errorf("Error while unmarshalling property '%s' (%s): %v", - field.JSONName, fieldValue.Type().String(), err) - } - if !isPtr { - fieldValue = fieldValue.Elem() - } - reflection.FieldByIndex(field.Index).Set(fieldValue) - - // Remove the field from remaining fields - delete(remainingFields, field.JSONName) - } else { - fieldPtr := reflection.FieldByIndex(field.Index) - if fieldPtr.Kind() != reflect.Ptr || fieldPtr.IsNil() { - fieldPtr = fieldPtr.Addr() - } - if err := json.Unmarshal(fieldData, fieldPtr.Interface()); err != nil { - if field.MultipleFields { - i := fieldIndex + 1 - if i < len(fields) && fields[i].JSONName == field.JSONName { - continue - } - } - return fmt.Errorf("Error while unmarshalling property '%s' (%s): %v", - field.JSONName, fieldPtr.Type().String(), err) - } - - // Remove the field from remaining fields - delete(remainingFields, field.JSONName) - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/jsoninfo/unsupported_properties_error.go b/vendor/github.com/getkin/kin-openapi/jsoninfo/unsupported_properties_error.go deleted file mode 100644 index 0df3f8a2d..000000000 --- a/vendor/github.com/getkin/kin-openapi/jsoninfo/unsupported_properties_error.go +++ /dev/null @@ -1,45 +0,0 @@ -package jsoninfo - -import ( - "encoding/json" - "fmt" - "sort" - "strings" -) - -// UnsupportedPropertiesError is a helper for extensions that want to refuse -// unsupported JSON object properties. -// -// It produces a helpful error message. -type UnsupportedPropertiesError struct { - Value interface{} - UnsupportedProperties map[string]json.RawMessage -} - -func NewUnsupportedPropertiesError(v interface{}, m map[string]json.RawMessage) error { - return &UnsupportedPropertiesError{ - Value: v, - UnsupportedProperties: m, - } -} - -func (err *UnsupportedPropertiesError) Error() string { - m := err.UnsupportedProperties - typeInfo := GetTypeInfoForValue(err.Value) - if m == nil || typeInfo == nil { - return "Invalid UnsupportedPropertiesError" - } - keys := make([]string, 0, len(m)) - for k := range m { - keys = append(keys, k) - } - sort.Strings(keys) - supported := typeInfo.FieldNames() - if len(supported) == 0 { - return fmt.Sprintf("Type '%T' doesn't take any properties. Unsupported properties: '%s'\n", - err.Value, strings.Join(keys, "', '")) - } - return fmt.Sprintf("Unsupported properties: '%s'\nSupported properties are: '%s'", - strings.Join(keys, "', '"), - strings.Join(supported, "', '")) -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/callback.go b/vendor/github.com/getkin/kin-openapi/openapi3/callback.go deleted file mode 100644 index 60196ba16..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/callback.go +++ /dev/null @@ -1,15 +0,0 @@ -package openapi3 - -import "context" - -// Callback is specified by OpenAPI/Swagger standard version 3.0. -type Callback map[string]*PathItem - -func (value Callback) Validate(c context.Context) error { - for _, v := range value { - if err := v.Validate(c); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/components.go b/vendor/github.com/getkin/kin-openapi/openapi3/components.go deleted file mode 100644 index 93a26cfae..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/components.go +++ /dev/null @@ -1,105 +0,0 @@ -package openapi3 - -import ( - "context" - "fmt" - "regexp" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -// Components is specified by OpenAPI/Swagger standard version 3.0. -type Components struct { - ExtensionProps - Schemas map[string]*SchemaRef `json:"schemas,omitempty"` - Parameters map[string]*ParameterRef `json:"parameters,omitempty"` - Headers map[string]*HeaderRef `json:"headers,omitempty"` - RequestBodies map[string]*RequestBodyRef `json:"requestBodies,omitempty"` - Responses map[string]*ResponseRef `json:"responses,omitempty"` - SecuritySchemes map[string]*SecuritySchemeRef `json:"securitySchemes,omitempty"` - Examples map[string]*ExampleRef `json:"examples,omitempty"` - Tags Tags `json:"tags,omitempty"` - Links map[string]*LinkRef `json:"links,omitempty"` - Callbacks map[string]*CallbackRef `json:"callbacks,omitempty"` -} - -func NewComponents() Components { - return Components{} -} - -func (components *Components) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(components) -} - -func (components *Components) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, components) -} - -func (components *Components) Validate(c context.Context) (err error) { - for k, v := range components.Schemas { - if err = ValidateIdentifier(k); err != nil { - return - } - if err = v.Validate(c); err != nil { - return - } - } - - for k, v := range components.Parameters { - if err = ValidateIdentifier(k); err != nil { - return - } - if err = v.Validate(c); err != nil { - return - } - } - - for k, v := range components.RequestBodies { - if err = ValidateIdentifier(k); err != nil { - return - } - if err = v.Validate(c); err != nil { - return - } - } - - for k, v := range components.Responses { - if err = ValidateIdentifier(k); err != nil { - return - } - if err = v.Validate(c); err != nil { - return - } - } - - for k, v := range components.Headers { - if err = ValidateIdentifier(k); err != nil { - return - } - if err = v.Validate(c); err != nil { - return - } - } - - for k, v := range components.SecuritySchemes { - if err = ValidateIdentifier(k); err != nil { - return - } - if err = v.Validate(c); err != nil { - return - } - } - - return -} - -const identifierPattern = `^[a-zA-Z0-9.\-_]+$` - -var identifierRegExp = regexp.MustCompile(identifierPattern) - -func ValidateIdentifier(value string) error { - if identifierRegExp.MatchString(value) { - return nil - } - return fmt.Errorf("Identifier '%s' is not supported by OpenAPI version 3 standard (regexp: '%s')", value, identifierPattern) -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/content.go b/vendor/github.com/getkin/kin-openapi/openapi3/content.go deleted file mode 100644 index 57eb89abe..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/content.go +++ /dev/null @@ -1,45 +0,0 @@ -package openapi3 - -import ( - "context" - "strings" -) - -// Content is specified by OpenAPI/Swagger 3.0 standard. -type Content map[string]*MediaType - -func NewContent() Content { - return make(map[string]*MediaType, 4) -} - -func NewContentWithJSONSchema(schema *Schema) Content { - return Content{ - "application/json": NewMediaType().WithSchema(schema), - } -} -func NewContentWithJSONSchemaRef(schema *SchemaRef) Content { - return Content{ - "application/json": NewMediaType().WithSchemaRef(schema), - } -} - -func (content Content) Get(mime string) *MediaType { - if v := content[mime]; v != nil { - return v - } - i := strings.IndexByte(mime, ';') - if i < 0 { - return nil - } - return content[mime[:i]] -} - -func (content Content) Validate(c context.Context) error { - for _, v := range content { - // Validate MediaType - if err := v.Validate(c); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/doc.go b/vendor/github.com/getkin/kin-openapi/openapi3/doc.go deleted file mode 100644 index 9f9554962..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package openapi3 parses and writes OpenAPI 3 specifications. -// -// The OpenAPI 3.0 specification can be found at: -// https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.md -package openapi3 diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/encoding.go b/vendor/github.com/getkin/kin-openapi/openapi3/encoding.go deleted file mode 100644 index 8ac3ca33e..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/encoding.go +++ /dev/null @@ -1,61 +0,0 @@ -package openapi3 - -import ( - "context" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -// Encoding is specified by OpenAPI/Swagger 3.0 standard. -type Encoding struct { - ExtensionProps - - ContentType string `json:"contentType,omitempty"` - Headers map[string]*HeaderRef `json:"headers,omitempty"` - Style string `json:"style,omitempty"` - Explode bool `json:"explode,omitempty"` - AllowReserved bool `json:"allowReserved,omitempty"` -} - -func NewEncoding() *Encoding { - return &Encoding{} -} - -func (encoding *Encoding) WithHeader(name string, header *Header) *Encoding { - return encoding.WithHeaderRef(name, &HeaderRef{ - Value: header, - }) -} - -func (encoding *Encoding) WithHeaderRef(name string, ref *HeaderRef) *Encoding { - headers := encoding.Headers - if headers == nil { - headers = make(map[string]*HeaderRef) - encoding.Headers = headers - } - headers[name] = ref - return encoding -} - -func (encoding *Encoding) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(encoding) -} - -func (encoding *Encoding) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, encoding) -} - -func (encoding *Encoding) Validate(c context.Context) error { - if encoding == nil { - return nil - } - for k, v := range encoding.Headers { - if err := ValidateIdentifier(k); err != nil { - return nil - } - if err := v.Validate(c); err != nil { - return nil - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/examples.go b/vendor/github.com/getkin/kin-openapi/openapi3/examples.go deleted file mode 100644 index 50d6dda93..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/examples.go +++ /dev/null @@ -1,29 +0,0 @@ -package openapi3 - -import ( - "github.com/getkin/kin-openapi/jsoninfo" -) - -// Example is specified by OpenAPI/Swagger 3.0 standard. -type Example struct { - ExtensionProps - - Summary string `json:"summary,omitempty"` - Description string `json:"description,omitempty"` - Value interface{} `json:"value,omitempty"` - ExternalValue string `json:"externalValue,omitempty"` -} - -func NewExample(value interface{}) *Example { - return &Example{ - Value: value, - } -} - -func (example *Example) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(example) -} - -func (example *Example) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, example) -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/extension.go b/vendor/github.com/getkin/kin-openapi/openapi3/extension.go deleted file mode 100644 index d6bee2cb0..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/extension.go +++ /dev/null @@ -1,37 +0,0 @@ -package openapi3 - -import ( - "github.com/getkin/kin-openapi/jsoninfo" -) - -// ExtensionProps provides support for OpenAPI extensions. -// It reads/writes all properties that begin with "x-". -type ExtensionProps struct { - Extensions map[string]interface{} `json:"-"` -} - -// Assert that the type implements the interface -var _ jsoninfo.StrictStruct = &ExtensionProps{} - -// EncodeWith will be invoked by package "jsoninfo" -func (props *ExtensionProps) EncodeWith(encoder *jsoninfo.ObjectEncoder, value interface{}) error { - for k, v := range props.Extensions { - if err := encoder.EncodeExtension(k, v); err != nil { - return err - } - } - return encoder.EncodeStructFieldsAndExtensions(value) -} - -// DecodeWith will be invoked by package "jsoninfo" -func (props *ExtensionProps) DecodeWith(decoder *jsoninfo.ObjectDecoder, value interface{}) error { - source := decoder.DecodeExtensionMap() - if len(source) > 0 { - result := make(map[string]interface{}, len(source)) - for k, v := range source { - result[k] = v - } - props.Extensions = result - } - return decoder.DecodeStructFieldsAndExtensions(value) -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/external_docs.go b/vendor/github.com/getkin/kin-openapi/openapi3/external_docs.go deleted file mode 100644 index 7f606a43f..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/external_docs.go +++ /dev/null @@ -1,7 +0,0 @@ -package openapi3 - -// ExternalDocs is specified by OpenAPI/Swagger standard version 3.0. -type ExternalDocs struct { - Description string `json:"description,omitempty"` - URL string `json:"url,omitempty"` -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/header.go b/vendor/github.com/getkin/kin-openapi/openapi3/header.go deleted file mode 100644 index 31571de90..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/header.go +++ /dev/null @@ -1,24 +0,0 @@ -package openapi3 - -import ( - "context" -) - -type Header struct { - ExtensionProps - - // Optional description. Should use CommonMark syntax. - Description string `json:"description,omitempty"` - - // Optional schema - Schema *SchemaRef `json:"schema,omitempty"` -} - -func (value *Header) Validate(c context.Context) error { - if v := value.Schema; v != nil { - if err := v.Validate(c); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/info.go b/vendor/github.com/getkin/kin-openapi/openapi3/info.go deleted file mode 100644 index 3cff33072..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/info.go +++ /dev/null @@ -1,55 +0,0 @@ -package openapi3 - -import ( - "github.com/getkin/kin-openapi/jsoninfo" -) - -// Info is specified by OpenAPI/Swagger standard version 3.0. -type Info struct { - ExtensionProps - Title string `json:"title,omitempty"` - Description string `json:"description,omitempty"` - TermsOfService string `json:"termsOfService,omitempty"` - Contact *Contact `json:"contact,omitempty"` - License *License `json:"license,omitempty"` - Version string `json:"version,omitempty"` -} - -func (value *Info) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(value) -} - -func (value *Info) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, value) -} - -// Contact is specified by OpenAPI/Swagger standard version 3.0. -type Contact struct { - ExtensionProps - Name string `json:"name,omitempty"` - URL string `json:"url,omitempty"` - Email string `json:"email,omitempty"` -} - -func (value *Contact) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(value) -} - -func (value *Contact) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, value) -} - -// License is specified by OpenAPI/Swagger standard version 3.0. -type License struct { - ExtensionProps - Name string `json:"name,omitempty"` - URL string `json:"url,omitempty"` -} - -func (value *License) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(value) -} - -func (value *License) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, value) -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/link.go b/vendor/github.com/getkin/kin-openapi/openapi3/link.go deleted file mode 100644 index 59ba87d7b..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/link.go +++ /dev/null @@ -1,29 +0,0 @@ -package openapi3 - -import ( - "context" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -// Link is specified by OpenAPI/Swagger standard version 3.0. -type Link struct { - ExtensionProps - Description string `json:"description,omitempty"` - Href string `json:"href,omitempty"` - OperationID string `json:"operationId,omitempty"` - Parameters map[string]interface{} `json:"parameters,omitempty"` - Headers map[string]*Schema `json:"headers,omitempty"` -} - -func (value *Link) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(value) -} - -func (value *Link) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, value) -} - -func (value *Link) Validate(c context.Context) error { - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/media_type.go b/vendor/github.com/getkin/kin-openapi/openapi3/media_type.go deleted file mode 100644 index 09713c11b..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/media_type.go +++ /dev/null @@ -1,79 +0,0 @@ -package openapi3 - -import ( - "context" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -// MediaType is specified by OpenAPI/Swagger 3.0 standard. -type MediaType struct { - ExtensionProps - - Schema *SchemaRef `json:"schema,omitempty"` - Example interface{} `json:"example,omitempty"` - Examples map[string]*ExampleRef `json:"examples,omitempty"` - Encoding map[string]*Encoding `json:"encoding,omitempty"` -} - -func NewMediaType() *MediaType { - return &MediaType{} -} - -func (mediaType *MediaType) WithSchema(schema *Schema) *MediaType { - if schema == nil { - mediaType.Schema = nil - } else { - mediaType.Schema = &SchemaRef{ - Value: schema, - } - } - return mediaType -} - -func (mediaType *MediaType) WithSchemaRef(schema *SchemaRef) *MediaType { - mediaType.Schema = schema - return mediaType -} - -func (mediaType *MediaType) WithExample(name string, value interface{}) *MediaType { - example := mediaType.Examples - if example == nil { - example = make(map[string]*ExampleRef) - mediaType.Examples = example - } - example[name] = &ExampleRef{ - Value: NewExample(value), - } - return mediaType -} - -func (mediaType *MediaType) WithEncoding(name string, enc *Encoding) *MediaType { - encoding := mediaType.Encoding - if encoding == nil { - encoding = make(map[string]*Encoding) - mediaType.Encoding = encoding - } - encoding[name] = enc - return mediaType -} - -func (mediaType *MediaType) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(mediaType) -} - -func (mediaType *MediaType) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, mediaType) -} - -func (mediaType *MediaType) Validate(c context.Context) error { - if mediaType == nil { - return nil - } - if schema := mediaType.Schema; schema != nil { - if err := schema.Validate(c); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/operation.go b/vendor/github.com/getkin/kin-openapi/openapi3/operation.go deleted file mode 100644 index 743625efc..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/operation.go +++ /dev/null @@ -1,98 +0,0 @@ -package openapi3 - -import ( - "context" - "strconv" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -// Operation represents "operation" specified by" OpenAPI/Swagger 3.0 standard. -type Operation struct { - ExtensionProps - - // Optional tags for documentation. - Tags []string `json:"tags,omitempty"` - - // Optional short summary. - Summary string `json:"summary,omitempty"` - - // Optional description. Should use CommonMark syntax. - Description string `json:"description,omitempty"` - - // Optional operation ID. - OperationID string `json:"operationId,omitempty"` - - // Optional parameters. - Parameters Parameters `json:"parameters,omitempty"` - - // Optional body parameter. - RequestBody *RequestBodyRef `json:"requestBody,omitempty"` - - // Optional responses. - Responses Responses `json:"responses,omitempty"` - - // Optional callbacks - Callbacks map[string]*CallbackRef `json:"callbacks,omitempty"` - - Deprecated bool `json:"deprecated,omitempty"` - - // Optional security requirements that overrides top-level security. - Security *SecurityRequirements `json:"security,omitempty"` - - // Optional servers that overrides top-level servers. - Servers *Servers `json:"servers,omitempty"` -} - -func NewOperation() *Operation { - return &Operation{} -} - -func (operation *Operation) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(operation) -} - -func (operation *Operation) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, operation) -} - -func (operation *Operation) AddParameter(p *Parameter) { - operation.Parameters = append(operation.Parameters, &ParameterRef{ - Value: p, - }) -} - -func (operation *Operation) AddResponse(status int, response *Response) { - responses := operation.Responses - if responses == nil { - operation.Responses = NewResponses() - } - if status == 0 { - responses["default"] = &ResponseRef{ - Value: response, - } - } else { - responses[strconv.FormatInt(int64(status), 10)] = &ResponseRef{ - Value: response, - } - } -} - -func (operation *Operation) Validate(c context.Context) error { - if v := operation.Parameters; v != nil { - if err := v.Validate(c); err != nil { - return err - } - } - if v := operation.RequestBody; v != nil { - if err := v.Validate(c); err != nil { - return err - } - } - if v := operation.Responses; v != nil { - if err := v.Validate(c); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/parameter.go b/vendor/github.com/getkin/kin-openapi/openapi3/parameter.go deleted file mode 100644 index 63d30f983..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/parameter.go +++ /dev/null @@ -1,158 +0,0 @@ -package openapi3 - -import ( - "context" - "errors" - "fmt" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -// Parameters is specified by OpenAPI/Swagger 3.0 standard. -type Parameters []*ParameterRef - -func NewParameters() Parameters { - return make(Parameters, 0, 4) -} - -func (parameters Parameters) GetByInAndName(in string, name string) *Parameter { - for _, item := range parameters { - if v := item.Value; v != nil { - if v.Name == name && v.In == in { - return v - } - } - } - return nil -} - -func (parameters Parameters) Validate(c context.Context) error { - m := make(map[string]struct{}) - for _, item := range parameters { - if err := item.Validate(c); err != nil { - return err - } - if v := item.Value; v != nil { - in := v.In - name := v.Name - key := in + ":" + name - if _, exists := m[key]; exists { - return fmt.Errorf("More than one '%s' parameter has name '%s'", in, name) - } - m[key] = struct{}{} - if err := item.Validate(c); err != nil { - return err - } - } - } - return nil -} - -// Parameter is specified by OpenAPI/Swagger 3.0 standard. -type Parameter struct { - ExtensionProps - Name string `json:"name,omitempty"` - In string `json:"in,omitempty"` - Description string `json:"description,omitempty"` - Style string `json:"style,omitempty"` - AllowEmptyValue bool `json:"allowEmptyValue,omitempty"` - AllowReserved bool `json:"allowReserved,omitempty"` - Deprecated bool `json:"deprecated,omitempty"` - Required bool `json:"required,omitempty"` - Schema *SchemaRef `json:"schema,omitempty"` - Example interface{} `json:"example,omitempty"` - Examples map[string]*ExampleRef `json:"examples,omitempty"` - Content Content `json:"content,omitempty"` -} - -const ( - ParameterInPath = "path" - ParameterInQuery = "query" - ParameterInHeader = "header" - ParameterInCookie = "cookie" -) - -func NewPathParameter(name string) *Parameter { - return &Parameter{ - Name: name, - In: ParameterInPath, - Required: true, - } -} - -func NewQueryParameter(name string) *Parameter { - return &Parameter{ - Name: name, - In: ParameterInQuery, - } -} - -func NewHeaderParameter(name string) *Parameter { - return &Parameter{ - Name: name, - In: ParameterInHeader, - } -} - -func NewCookieParameter(name string) *Parameter { - return &Parameter{ - Name: name, - In: ParameterInCookie, - } -} - -func (parameter *Parameter) WithDescription(value string) *Parameter { - parameter.Description = value - return parameter -} - -func (parameter *Parameter) WithRequired(value bool) *Parameter { - parameter.Required = value - return parameter -} - -func (parameter *Parameter) WithSchema(value *Schema) *Parameter { - if value == nil { - parameter.Schema = nil - } else { - parameter.Schema = &SchemaRef{ - Value: value, - } - } - return parameter -} - -func (parameter *Parameter) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(parameter) -} - -func (parameter *Parameter) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, parameter) -} - -func (parameter *Parameter) Validate(c context.Context) error { - if parameter.Name == "" { - return errors.New("Parameter name can't be blank") - } - in := parameter.In - switch in { - case - ParameterInPath, - ParameterInQuery, - ParameterInHeader, - ParameterInCookie: - default: - return fmt.Errorf("Parameter can't have 'in' value '%s'", parameter.In) - } - if schema := parameter.Schema; schema != nil { - if err := schema.Validate(c); err != nil { - return fmt.Errorf("Parameter '%v' schema is invalid: %v", parameter.Name, err) - } - } - if content := parameter.Content; content != nil { - if err := content.Validate(c); err != nil { - return fmt.Errorf("Parameter content is invalid: %v", err) - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/path_item.go b/vendor/github.com/getkin/kin-openapi/openapi3/path_item.go deleted file mode 100644 index fe4ac47e3..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/path_item.go +++ /dev/null @@ -1,124 +0,0 @@ -package openapi3 - -import ( - "context" - "fmt" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -type PathItem struct { - ExtensionProps - Summary string `json:"summary,omitempty"` - Description string `json:"description,omitempty"` - Connect *Operation `json:"connect,omitempty"` - Delete *Operation `json:"delete,omitempty"` - Get *Operation `json:"get,omitempty"` - Head *Operation `json:"head,omitempty"` - Options *Operation `json:"options,omitempty"` - Patch *Operation `json:"patch,omitempty"` - Post *Operation `json:"post,omitempty"` - Put *Operation `json:"put,omitempty"` - Trace *Operation `json:"trace,omitempty"` - Servers Servers `json:"servers,omitempty"` - Parameters Parameters `json:"parameters,omitempty"` -} - -func (pathItem *PathItem) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(pathItem) -} - -func (pathItem *PathItem) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, pathItem) -} - -func (pathItem *PathItem) Operations() map[string]*Operation { - operations := make(map[string]*Operation, 4) - if v := pathItem.Connect; v != nil { - operations["CONNECT"] = v - } - if v := pathItem.Delete; v != nil { - operations["DELETE"] = v - } - if v := pathItem.Get; v != nil { - operations["GET"] = v - } - if v := pathItem.Head; v != nil { - operations["HEAD"] = v - } - if v := pathItem.Options; v != nil { - operations["OPTIONS"] = v - } - if v := pathItem.Patch; v != nil { - operations["PATCH"] = v - } - if v := pathItem.Post; v != nil { - operations["POST"] = v - } - if v := pathItem.Put; v != nil { - operations["PUT"] = v - } - if v := pathItem.Trace; v != nil { - operations["TRACE"] = v - } - return operations -} - -func (pathItem *PathItem) GetOperation(method string) *Operation { - switch method { - case "CONNECT": - return pathItem.Connect - case "DELETE": - return pathItem.Delete - case "GET": - return pathItem.Get - case "HEAD": - return pathItem.Head - case "OPTIONS": - return pathItem.Options - case "PATCH": - return pathItem.Patch - case "POST": - return pathItem.Post - case "PUT": - return pathItem.Put - case "TRACE": - return pathItem.Trace - default: - panic(fmt.Errorf("Unsupported HTTP method '%s'", method)) - } -} - -func (pathItem *PathItem) SetOperation(method string, operation *Operation) { - switch method { - case "CONNECT": - pathItem.Connect = operation - case "DELETE": - pathItem.Delete = operation - case "GET": - pathItem.Get = operation - case "HEAD": - pathItem.Head = operation - case "OPTIONS": - pathItem.Options = operation - case "PATCH": - pathItem.Patch = operation - case "POST": - pathItem.Post = operation - case "PUT": - pathItem.Put = operation - case "TRACE": - pathItem.Trace = operation - default: - panic(fmt.Errorf("Unsupported HTTP method '%s'", method)) - } -} - -func (pathItem *PathItem) Validate(c context.Context) error { - for _, operation := range pathItem.Operations() { - if err := operation.Validate(c); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/paths.go b/vendor/github.com/getkin/kin-openapi/openapi3/paths.go deleted file mode 100644 index 3b46b39a2..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/paths.go +++ /dev/null @@ -1,99 +0,0 @@ -package openapi3 - -import ( - "context" - "fmt" - "strings" -) - -// Paths is specified by OpenAPI/Swagger standard version 3.0. -type Paths map[string]*PathItem - -func (paths Paths) Validate(c context.Context) error { - normalizedPaths := make(map[string]string) - for path, pathItem := range paths { - normalizedPath := normalizePathKey(path) - if oldPath, exists := normalizedPaths[normalizedPath]; exists { - return fmt.Errorf("Conflicting paths '%v' and '%v'", path, oldPath) - } - if path == "" || path[0] != '/' { - return fmt.Errorf("Path '%v' does not start with '/'", path) - } - if strings.Contains(path, "//") { - return fmt.Errorf("Path '%v' contains '//'", path) - } - normalizedPaths[path] = path - if err := pathItem.Validate(c); err != nil { - return err - } - } - return nil -} - -// Find returns a path that matches the key. -// -// The method ignores differences in template variable names (except possible "*" suffix). -// -// For example: -// -// paths := openapi3.Paths { -// "/person/{personName}": &openapi3.PathItem{}, -// } -// pathItem := path.Find("/person/{name}") -// -// would return the correct path item. -func (paths Paths) Find(key string) *PathItem { - // Try directly access the map - pathItem := paths[key] - if pathItem != nil { - return pathItem - } - - // Use normalized keys - normalizedSearchedPath := normalizePathKey(key) - for path, pathItem := range paths { - normalizedPath := normalizePathKey(path) - if normalizedPath == normalizedSearchedPath { - return pathItem - } - } - return nil -} - -func normalizePathKey(key string) string { - // If the argument has no path variables, return the argument - if strings.IndexByte(key, '{') < 0 { - return key - } - - // Allocate buffer - buf := make([]byte, 0, len(key)) - - // Visit each byte - isVariable := false - for i := 0; i < len(key); i++ { - c := key[i] - if isVariable { - if c == '}' { - // End path variables - // First append possible '*' before this character - // The character '}' will be appended - if i > 0 && key[i-1] == '*' { - buf = append(buf, '*') - } - isVariable = false - } else { - // Skip this character - continue - } - } else if c == '{' { - // Begin path variable - // The character '{' will be appended - isVariable = true - } - - // Append the character - buf = append(buf, c) - } - return string(buf) -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/refs.go b/vendor/github.com/getkin/kin-openapi/openapi3/refs.go deleted file mode 100644 index 9790b4705..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/refs.go +++ /dev/null @@ -1,199 +0,0 @@ -package openapi3 - -import ( - "context" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -type CallbackRef struct { - Ref string - Value *Callback -} - -func (value *CallbackRef) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalRef(value.Ref, value.Value) -} - -func (value *CallbackRef) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) -} - -func (value *CallbackRef) Validate(c context.Context) error { - v := value.Value - if v == nil { - return foundUnresolvedRef(value.Ref) - } - return v.Validate(c) -} - -type ExampleRef struct { - Ref string - Value *Example -} - -func (value *ExampleRef) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalRef(value.Ref, value.Value) -} - -func (value *ExampleRef) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) -} - -func (value *ExampleRef) Validate(c context.Context) error { - return nil -} - -type HeaderRef struct { - Ref string - Value *Header -} - -func (value *HeaderRef) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalRef(value.Ref, value.Value) -} - -func (value *HeaderRef) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) -} - -func (value *HeaderRef) Validate(c context.Context) error { - v := value.Value - if v == nil { - return foundUnresolvedRef(value.Ref) - } - return v.Validate(c) -} - -type LinkRef struct { - Ref string - Value *Link -} - -func (value *LinkRef) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalRef(value.Ref, value.Value) -} - -func (value *LinkRef) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) -} - -func (value *LinkRef) Validate(c context.Context) error { - v := value.Value - if v == nil { - return foundUnresolvedRef(value.Ref) - } - return v.Validate(c) -} - -type ParameterRef struct { - Ref string - Value *Parameter -} - -func (value *ParameterRef) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalRef(value.Ref, value.Value) -} - -func (value *ParameterRef) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) -} - -func (value *ParameterRef) Validate(c context.Context) error { - v := value.Value - if v == nil { - return foundUnresolvedRef(value.Ref) - } - return v.Validate(c) -} - -type ResponseRef struct { - Ref string - Value *Response -} - -func (value *ResponseRef) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalRef(value.Ref, value.Value) -} - -func (value *ResponseRef) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) -} - -func (value *ResponseRef) Validate(c context.Context) error { - v := value.Value - if v == nil { - return foundUnresolvedRef(value.Ref) - } - return v.Validate(c) -} - -type RequestBodyRef struct { - Ref string - Value *RequestBody -} - -func (value *RequestBodyRef) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalRef(value.Ref, value.Value) -} - -func (value *RequestBodyRef) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) -} - -func (value *RequestBodyRef) Validate(c context.Context) error { - v := value.Value - if v == nil { - return foundUnresolvedRef(value.Ref) - } - return v.Validate(c) -} - -type SchemaRef struct { - Ref string - Value *Schema -} - -func NewSchemaRef(ref string, value *Schema) *SchemaRef { - return &SchemaRef{ - Ref: ref, - Value: value, - } -} - -func (value *SchemaRef) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalRef(value.Ref, value.Value) -} - -func (value *SchemaRef) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) -} - -func (value *SchemaRef) Validate(c context.Context) error { - v := value.Value - if v == nil { - return foundUnresolvedRef(value.Ref) - } - return v.Validate(c) -} - -type SecuritySchemeRef struct { - Ref string - Value *SecurityScheme -} - -func (value *SecuritySchemeRef) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalRef(value.Ref, value.Value) -} - -func (value *SecuritySchemeRef) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) -} - -func (value *SecuritySchemeRef) Validate(c context.Context) error { - v := value.Value - if v == nil { - return foundUnresolvedRef(value.Ref) - } - return v.Validate(c) -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/request_body.go b/vendor/github.com/getkin/kin-openapi/openapi3/request_body.go deleted file mode 100644 index 1175d6e4d..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/request_body.go +++ /dev/null @@ -1,69 +0,0 @@ -package openapi3 - -import ( - "context" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -// RequestBody is specified by OpenAPI/Swagger 3.0 standard. -type RequestBody struct { - ExtensionProps - Description string `json:"description,omitempty"` - Required bool `json:"required,omitempty"` - Content Content `json:"content,omitempty"` -} - -func NewRequestBody() *RequestBody { - return &RequestBody{} -} - -func (requestBody *RequestBody) WithDescription(value string) *RequestBody { - requestBody.Description = value - return requestBody -} - -func (requestBody *RequestBody) WithRequired(value bool) *RequestBody { - requestBody.Required = value - return requestBody -} - -func (requestBody *RequestBody) WithContent(content Content) *RequestBody { - requestBody.Content = content - return requestBody -} - -func (requestBody *RequestBody) WithJSONSchemaRef(value *SchemaRef) *RequestBody { - requestBody.Content = NewContentWithJSONSchemaRef(value) - return requestBody -} - -func (requestBody *RequestBody) WithJSONSchema(value *Schema) *RequestBody { - requestBody.Content = NewContentWithJSONSchema(value) - return requestBody -} - -func (requestBody *RequestBody) GetMediaType(mediaType string) *MediaType { - m := requestBody.Content - if m == nil { - return nil - } - return m[mediaType] -} - -func (requestBody *RequestBody) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(requestBody) -} - -func (requestBody *RequestBody) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, requestBody) -} - -func (requestBody *RequestBody) Validate(c context.Context) error { - if v := requestBody.Content; v != nil { - if err := v.Validate(c); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/response.go b/vendor/github.com/getkin/kin-openapi/openapi3/response.go deleted file mode 100644 index 8604e499e..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/response.go +++ /dev/null @@ -1,82 +0,0 @@ -package openapi3 - -import ( - "context" - "strconv" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -// Responses is specified by OpenAPI/Swagger 3.0 standard. -type Responses map[string]*ResponseRef - -func NewResponses() Responses { - return make(Responses, 8) -} - -func (responses Responses) Default() *ResponseRef { - return responses["default"] -} - -func (responses Responses) Get(status int) *ResponseRef { - return responses[strconv.FormatInt(int64(status), 10)] -} - -func (responses Responses) Validate(c context.Context) error { - for _, v := range responses { - if err := v.Validate(c); err != nil { - return err - } - } - return nil -} - -// Response is specified by OpenAPI/Swagger 3.0 standard. -type Response struct { - ExtensionProps - Description string `json:"description,omitempty"` - Headers map[string]*Schema `json:"headers,omitempty"` - Content Content `json:"content,omitempty"` - Links map[string]*LinkRef `json:"links,omitempty"` -} - -func NewResponse() *Response { - return &Response{} -} - -func (response *Response) WithDescription(value string) *Response { - response.Description = value - return response -} - -func (response *Response) WithContent(content Content) *Response { - response.Content = content - return response -} - -func (response *Response) WithJSONSchema(schema *Schema) *Response { - response.Content = NewContentWithJSONSchema(schema) - return response -} - -func (response *Response) WithJSONSchemaRef(schema *SchemaRef) *Response { - response.Content = NewContentWithJSONSchemaRef(schema) - return response -} - -func (response *Response) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(response) -} - -func (response *Response) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, response) -} - -func (response *Response) Validate(c context.Context) error { - if content := response.Content; content != nil { - if err := content.Validate(c); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/schema.go b/vendor/github.com/getkin/kin-openapi/openapi3/schema.go deleted file mode 100644 index 316119ca6..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/schema.go +++ /dev/null @@ -1,1200 +0,0 @@ -package openapi3 - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "math" - "math/big" - "regexp" - "strconv" - "unicode/utf16" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -var ( - // SchemaErrorDetailsDisabled disables printing of details about schema errors. - SchemaErrorDetailsDisabled = false - - errSchema = errors.New("Input does not match the schema") - - ErrSchemaInputNaN = errors.New("NaN is not allowed") - ErrSchemaInputInf = errors.New("Inf is not allowed") -) - -// Float64Ptr is a helper for defining OpenAPI schemas. -func Float64Ptr(value float64) *float64 { - return &value -} - -// BoolPtr is a helper for defining OpenAPI schemas. -func BoolPtr(value bool) *bool { - return &value -} - -// Int64Ptr is a helper for defining OpenAPI schemas. -func Int64Ptr(value int64) *int64 { - return &value -} - -// Uint64Ptr is a helper for defining OpenAPI schemas. -func Uint64Ptr(value uint64) *uint64 { - return &value -} - -// Schema is specified by OpenAPI/Swagger 3.0 standard. -type Schema struct { - ExtensionProps - - OneOf []*SchemaRef `json:"oneOf,omitempty"` - AnyOf []*SchemaRef `json:"anyOf,omitempty"` - AllOf []*SchemaRef `json:"allOf,omitempty"` - Not *SchemaRef `json:"not,omitempty"` - Type string `json:"type,omitempty"` - Format string `json:"format,omitempty"` - Description string `json:"description,omitempty"` - Enum []interface{} `json:"enum,omitempty"` - Default interface{} `json:"default,omitempty"` - Example interface{} `json:"example,omitempty"` - ExternalDocs interface{} `json:"externalDocs,omitempty"` - - // Object-related, here for struct compactness - AdditionalPropertiesAllowed *bool `json:"-" multijson:"additionalProperties,omitempty"` - // Array-related, here for struct compactness - UniqueItems bool `json:"uniqueItems,omitempty"` - // Number-related, here for struct compactness - ExclusiveMin bool `json:"exclusiveMinimum,omitempty"` - ExclusiveMax bool `json:"exclusiveMaximum,omitempty"` - // Properties - Nullable bool `json:"nullable,omitempty"` - ReadOnly bool `json:"readOnly,omitempty"` - WriteOnly bool `json:"writeOnly,omitempty"` - XML interface{} `json:"xml,omitempty"` - - // Number - Min *float64 `json:"minimum,omitempty"` - Max *float64 `json:"maximum,omitempty"` - MultipleOf *float64 `json:"multipleOf,omitempty"` - - // String - MinLength uint64 `json:"minLength,omitempty"` - MaxLength *uint64 `json:"maxLength,omitempty"` - Pattern string `json:"pattern,omitempty"` - compiledPattern *compiledPattern - - // Array - MinItems uint64 `json:"minItems,omitempty"` - MaxItems *uint64 `json:"maxItems,omitempty"` - Items *SchemaRef `json:"items,omitempty"` - - // Object - Required []string `json:"required,omitempty"` - Properties map[string]*SchemaRef `json:"properties,omitempty"` - MinProps uint64 `json:"minProperties,omitempty"` - MaxProps *uint64 `json:"maxProperties,omitempty"` - AdditionalProperties *SchemaRef `json:"-" multijson:"additionalProperties,omitempty"` - Discriminator string `json:"discriminator,omitempty"` - - PatternProperties string `json:"patternProperties,omitempty"` - compiledPatternProperties *compiledPattern -} - -func NewSchema() *Schema { - return &Schema{} -} - -func (schema *Schema) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(schema) -} - -func (schema *Schema) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, schema) -} - -func (schema *Schema) NewRef() *SchemaRef { - return &SchemaRef{ - Value: schema, - } -} - -func NewOneOfSchema(schemas ...*Schema) *Schema { - refs := make([]*SchemaRef, len(schemas)) - for i, schema := range schemas { - refs[i] = &SchemaRef{Value: schema} - } - return &Schema{ - OneOf: refs, - } -} - -func NewAnyOfSchema(schemas ...*Schema) *Schema { - refs := make([]*SchemaRef, len(schemas)) - for i, schema := range schemas { - refs[i] = &SchemaRef{Value: schema} - } - return &Schema{ - AnyOf: refs, - } -} - -func NewAllOfSchema(schemas ...*Schema) *Schema { - refs := make([]*SchemaRef, len(schemas)) - for i, schema := range schemas { - refs[i] = &SchemaRef{Value: schema} - } - return &Schema{ - AllOf: refs, - } -} - -func NewBoolSchema() *Schema { - return &Schema{ - Type: "boolean", - } -} - -func NewFloat64Schema() *Schema { - return &Schema{ - Type: "number", - } -} - -func NewIntegerSchema() *Schema { - return &Schema{ - Type: "integer", - } -} - -func NewInt32Schema() *Schema { - return &Schema{ - Type: "integer", - Format: "int32", - } -} - -func NewInt64Schema() *Schema { - return &Schema{ - Type: "integer", - Format: "int64", - } -} - -func NewStringSchema() *Schema { - return &Schema{ - Type: "string", - } -} - -func NewDateTimeSchema() *Schema { - return &Schema{ - Type: "string", - Format: "date-time", - } -} - -func NewBytesSchema() *Schema { - return &Schema{ - Type: "string", - Format: "byte", - } -} - -func NewArraySchema() *Schema { - return &Schema{ - Type: "array", - } -} - -func NewObjectSchema() *Schema { - return &Schema{ - Type: "object", - Properties: make(map[string]*SchemaRef), - } -} - -type compiledPattern struct { - Regexp *regexp.Regexp - ErrReason string -} - -func (schema *Schema) WithNullable() *Schema { - schema.Nullable = true - return schema -} - -func (schema *Schema) WithMin(value float64) *Schema { - schema.Min = &value - return schema -} - -func (schema *Schema) WithMax(value float64) *Schema { - schema.Max = &value - return schema -} -func (schema *Schema) WithExclusiveMin(value bool) *Schema { - schema.ExclusiveMin = value - return schema -} - -func (schema *Schema) WithExclusiveMax(value bool) *Schema { - schema.ExclusiveMax = value - return schema -} - -func (schema *Schema) WithEnum(values ...interface{}) *Schema { - schema.Enum = values - return schema -} - -func (schema *Schema) WithFormat(value string) *Schema { - schema.Format = value - return schema -} - -func (schema *Schema) WithLength(i int64) *Schema { - n := uint64(i) - schema.MinLength = n - schema.MaxLength = &n - return schema -} - -func (schema *Schema) WithMinLength(i int64) *Schema { - n := uint64(i) - schema.MinLength = n - return schema -} - -func (schema *Schema) WithMaxLength(i int64) *Schema { - n := uint64(i) - schema.MaxLength = &n - return schema -} - -func (schema *Schema) WithLengthDecodedBase64(i int64) *Schema { - n := uint64(i) - v := (n*8 + 5) / 6 - schema.MinLength = v - schema.MaxLength = &v - return schema -} - -func (schema *Schema) WithMinLengthDecodedBase64(i int64) *Schema { - n := uint64(i) - schema.MinLength = (n*8 + 5) / 6 - return schema -} - -func (schema *Schema) WithMaxLengthDecodedBase64(i int64) *Schema { - n := uint64(i) - schema.MinLength = (n*8 + 5) / 6 - return schema -} - -func (schema *Schema) WithPattern(pattern string) *Schema { - schema.Pattern = pattern - return schema -} - -func (schema *Schema) WithItems(value *Schema) *Schema { - schema.Items = &SchemaRef{ - Value: value, - } - return schema -} - -func (schema *Schema) WithMinItems(i int64) *Schema { - n := uint64(i) - schema.MinItems = n - return schema -} - -func (schema *Schema) WithMaxItems(i int64) *Schema { - n := uint64(i) - schema.MaxItems = &n - return schema -} - -func (schema *Schema) WithUniqueItems(unique bool) *Schema { - schema.UniqueItems = unique - return schema -} - -func (schema *Schema) WithProperty(name string, propertySchema *Schema) *Schema { - return schema.WithPropertyRef(name, &SchemaRef{ - Value: propertySchema, - }) -} - -func (schema *Schema) WithPropertyRef(name string, ref *SchemaRef) *Schema { - properties := schema.Properties - if properties == nil { - properties = make(map[string]*SchemaRef) - schema.Properties = properties - } - properties[name] = ref - return schema -} - -func (schema *Schema) WithProperties(properties map[string]*Schema) *Schema { - result := make(map[string]*SchemaRef, len(properties)) - for k, v := range properties { - result[k] = &SchemaRef{ - Value: v, - } - } - schema.Properties = result - return schema -} - -func (schema *Schema) WithMinProperties(i int64) *Schema { - n := uint64(i) - schema.MinProps = n - return schema -} - -func (schema *Schema) WithMaxProperties(i int64) *Schema { - n := uint64(i) - schema.MaxProps = &n - return schema -} - -func (schema *Schema) WithAnyAdditionalProperties() *Schema { - schema.AdditionalProperties = nil - t := true - schema.AdditionalPropertiesAllowed = &t - return schema -} - -func (schema *Schema) WithAdditionalProperties(v *Schema) *Schema { - if v == nil { - schema.AdditionalProperties = nil - } else { - schema.AdditionalProperties = &SchemaRef{ - Value: v, - } - } - return schema -} - -func (schema *Schema) IsEmpty() bool { - if schema.Type != "" || schema.Format != "" || len(schema.Enum) != 0 || - schema.UniqueItems || schema.ExclusiveMin || schema.ExclusiveMax || - !schema.Nullable || - schema.Min != nil || schema.Max != nil || schema.MultipleOf != nil || - schema.MinLength != 0 || schema.MaxLength != nil || schema.Pattern != "" || - schema.MinItems != 0 || schema.MaxItems != nil || - len(schema.Required) != 0 || - schema.MinProps != 0 || schema.MaxProps != nil { - return false - } - if n := schema.Not; n != nil && !n.Value.IsEmpty() { - return false - } - if ap := schema.AdditionalProperties; ap != nil && !ap.Value.IsEmpty() { - return false - } - if apa := schema.AdditionalPropertiesAllowed; apa != nil && !*apa { - return false - } - if items := schema.Items; items != nil && !items.Value.IsEmpty() { - return false - } - for _, s := range schema.Properties { - if !s.Value.IsEmpty() { - return false - } - } - for _, s := range schema.OneOf { - if !s.Value.IsEmpty() { - return false - } - } - for _, s := range schema.AnyOf { - if !s.Value.IsEmpty() { - return false - } - } - for _, s := range schema.AllOf { - if !s.Value.IsEmpty() { - return false - } - } - return true -} - -func (schema *Schema) Validate(c context.Context) error { - return schema.validate(c, make([]*Schema, 2)) -} - -func (schema *Schema) validate(c context.Context, stack []*Schema) (err error) { - for _, existing := range stack { - if existing == schema { - return - } - } - stack = append(stack, schema) - for _, item := range schema.OneOf { - v := item.Value - if v == nil { - return foundUnresolvedRef(item.Ref) - } - if err = v.validate(c, stack); err == nil { - return - } - } - for _, item := range schema.AnyOf { - v := item.Value - if v == nil { - return foundUnresolvedRef(item.Ref) - } - if err = v.validate(c, stack); err != nil { - return - } - } - for _, item := range schema.AllOf { - v := item.Value - if v == nil { - return foundUnresolvedRef(item.Ref) - } - if err = v.validate(c, stack); err != nil { - return - } - } - if ref := schema.Not; ref != nil { - v := ref.Value - if v == nil { - return foundUnresolvedRef(ref.Ref) - } - if err = v.validate(c, stack); err != nil { - return - } - } - schemaType := schema.Type - switch schemaType { - case "": - case "boolean": - case "number": - if format := schema.Format; len(format) > 0 { - switch format { - case "float", "double": - default: - return unsupportedFormat(format) - } - } - case "integer": - if format := schema.Format; len(format) > 0 { - switch format { - case "int32", "int64": - default: - return unsupportedFormat(format) - } - } - case "string": - if format := schema.Format; len(format) > 0 { - switch format { - case "byte", "binary", "date", "date-time", "password": - default: - return unsupportedFormat(format) - } - } - case "array": - if schema.Items == nil { - return errors.New("When schema type is 'array', schema 'items' must be non-null") - } - case "object": - default: - return fmt.Errorf("Unsupported 'type' value '%s'", schemaType) - } - if ref := schema.Items; ref != nil { - v := ref.Value - if v == nil { - return foundUnresolvedRef(ref.Ref) - } - if err = v.validate(c, stack); err != nil { - return - } - } - for _, ref := range schema.Properties { - v := ref.Value - if v == nil { - return foundUnresolvedRef(ref.Ref) - } - if err = v.validate(c, stack); err != nil { - return - } - } - if ref := schema.AdditionalProperties; ref != nil { - v := ref.Value - if v == nil { - return foundUnresolvedRef(ref.Ref) - } - if err = v.validate(c, stack); err != nil { - return - } - } - return -} - -func (schema *Schema) IsMatching(value interface{}) bool { - return schema.visitJSON(value, true) == nil -} - -func (schema *Schema) IsMatchingJSONBoolean(value bool) bool { - return schema.visitJSON(value, true) == nil -} - -func (schema *Schema) IsMatchingJSONNumber(value float64) bool { - return schema.visitJSON(value, true) == nil -} - -func (schema *Schema) IsMatchingJSONString(value string) bool { - return schema.visitJSON(value, true) == nil -} - -func (schema *Schema) IsMatchingJSONArray(value []interface{}) bool { - return schema.visitJSON(value, true) == nil -} - -func (schema *Schema) IsMatchingJSONObject(value map[string]interface{}) bool { - return schema.visitJSON(value, true) == nil -} - -func (schema *Schema) VisitJSON(value interface{}) error { - return schema.visitJSON(value, false) -} - -func (schema *Schema) visitJSON(value interface{}, fast bool) (err error) { - switch value := value.(type) { - case float64: - if math.IsNaN(value) { - return ErrSchemaInputNaN - } - if math.IsInf(value, 0) { - return ErrSchemaInputInf - } - } - - if schema.IsEmpty() { - return - } - if err = schema.visitSetOperations(value, fast); err != nil { - return - } - - switch value := value.(type) { - case nil: - return schema.visitJSONNull(fast) - case bool: - return schema.visitJSONBoolean(value, fast) - case float64: - return schema.visitJSONNumber(value, fast) - case string: - return schema.visitJSONString(value, fast) - case []interface{}: - return schema.visitJSONArray(value, fast) - case map[string]interface{}: - return schema.visitJSONObject(value, fast) - default: - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "type", - Reason: fmt.Sprintf("Not a JSON value: %T", value), - } - } -} - -func (schema *Schema) visitSetOperations(value interface{}, fast bool) (err error) { - if enum := schema.Enum; len(enum) != 0 { - for _, v := range enum { - if value == v { - return - } - } - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "enum", - Reason: "JSON value is not one of the allowed values", - } - } - - if ref := schema.Not; ref != nil { - v := ref.Value - if v == nil { - return foundUnresolvedRef(ref.Ref) - } - if err := v.visitJSON(value, true); err == nil { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "not", - } - } - } - - if v := schema.OneOf; len(v) > 0 { - ok := 0 - for _, item := range v { - v := item.Value - if v == nil { - return foundUnresolvedRef(item.Ref) - } - if err := v.visitJSON(value, true); err == nil { - ok++ - } - } - if ok != 1 { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "oneOf", - } - } - } - - if v := schema.AnyOf; len(v) > 0 { - ok := false - for _, item := range v { - v := item.Value - if v == nil { - return foundUnresolvedRef(item.Ref) - } - if err := v.visitJSON(value, true); err == nil { - ok = true - break - } - } - if !ok { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "anyOf", - } - } - } - - for _, item := range schema.AllOf { - v := item.Value - if v == nil { - return foundUnresolvedRef(item.Ref) - } - if err := v.visitJSON(value, true); err != nil { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "allOf", - } - } - } - return -} - -func (schema *Schema) visitJSONNull(fast bool) (err error) { - if schema.Nullable { - return - } - if fast { - return errSchema - } - return &SchemaError{ - Value: nil, - Schema: schema, - SchemaField: "nullable", - Reason: "Value is not nullable", - } -} - -func (schema *Schema) VisitJSONBoolean(value bool) error { - return schema.visitJSONBoolean(value, false) -} - -func (schema *Schema) visitJSONBoolean(value bool, fast bool) (err error) { - if schemaType := schema.Type; schemaType != "" && schemaType != "boolean" { - return schema.expectedType("boolean", fast) - } - return -} - -func (schema *Schema) VisitJSONNumber(value float64) error { - return schema.visitJSONNumber(value, false) -} - -func (schema *Schema) visitJSONNumber(value float64, fast bool) (err error) { - schemaType := schema.Type - if schemaType == "integer" { - if bigFloat := big.NewFloat(value); !bigFloat.IsInt() { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "type", - Reason: "Value must be an integer", - } - } - } else if schemaType != "" && schemaType != "number" { - return schema.expectedType("number, integer", fast) - } - - // "exclusiveMinimum" - if v := schema.ExclusiveMin; v && !(*schema.Min < value) { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "exclusiveMinimum", - Reason: fmt.Sprintf("Number must be more than %g", *schema.Min), - } - } - - // "exclusiveMaximum" - if v := schema.ExclusiveMax; v && !(*schema.Max > value) { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "exclusiveMaximum", - Reason: fmt.Sprintf("Number must be less than %g", *schema.Max), - } - } - - // "minimum" - if v := schema.Min; v != nil && !(*v <= value) { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "minimum", - Reason: fmt.Sprintf("Number must be at least %g", *v), - } - } - - // "maximum" - if v := schema.Max; v != nil && !(*v >= value) { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "maximum", - Reason: fmt.Sprintf("Number must be most %g", *v), - } - } - - // "multipleOf" - if v := schema.MultipleOf; v != nil { - // "A numeric instance is valid only if division by this keyword's - // value results in an integer." - if bigFloat := big.NewFloat(value / *v); !bigFloat.IsInt() { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "multipleOf", - } - } - } - return -} - -func (schema *Schema) VisitJSONString(value string) error { - return schema.visitJSONString(value, false) -} - -func (schema *Schema) visitJSONString(value string, fast bool) (err error) { - if schemaType := schema.Type; schemaType != "" && schemaType != "string" { - return schema.expectedType("string", fast) - } - - // "minLength" and "maxLength" - minLength := schema.MinLength - maxLength := schema.MaxLength - if minLength != 0 || maxLength != nil { - // JSON schema string lengths are UTF-16, not UTF-8! - length := int64(0) - for _, r := range value { - if utf16.IsSurrogate(r) { - length += 2 - } else { - length++ - } - } - if minLength != 0 && length < int64(minLength) { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "minLength", - Reason: fmt.Sprintf("Minimum string length is %d", minLength), - } - } - if maxLength != nil && length > int64(*maxLength) { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "maxLength", - Reason: fmt.Sprintf("Maximum string length is %d", *maxLength), - } - } - } - - // "format" and "pattern" - cp := schema.compiledPattern - if cp == nil { - pattern := schema.Pattern - if v := schema.Pattern; len(v) > 0 { - // Pattern - re, err := regexp.Compile(v) - if err != nil { - return fmt.Errorf("Error while compiling regular expression '%s': %v", pattern, err) - } - cp = &compiledPattern{ - Regexp: re, - ErrReason: "JSON string doesn't match the regular expression '" + v + "'", - } - schema.compiledPattern = cp - } else if v := schema.Format; len(v) > 0 { - // No pattern, but does have a format - re := SchemaStringFormats[v] - if re != nil { - cp = &compiledPattern{ - Regexp: re, - ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + re.String() + "`)'", - } - schema.compiledPattern = cp - } - } - } - if cp != nil { - if !cp.Regexp.MatchString(value) { - field := "format" - if schema.Pattern != "" { - field = "pattern" - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: field, - Reason: cp.ErrReason, - } - } - } - return -} - -func (schema *Schema) VisitJSONArray(value []interface{}) error { - return schema.visitJSONArray(value, false) -} - -func (schema *Schema) visitJSONArray(value []interface{}, fast bool) (err error) { - if schemaType := schema.Type; schemaType != "" && schemaType != "array" { - return schema.expectedType("array", fast) - } - - lenValue := int64(len(value)) - - // "minItems" - if v := schema.MinItems; v != 0 && lenValue < int64(v) { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "minItems", - Reason: fmt.Sprintf("Minimum number of items is %d", v), - } - } - - // "maxItems" - if v := schema.MaxItems; v != nil && lenValue > int64(*v) { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "maxItems", - Reason: fmt.Sprintf("Maximum number of items is %d", *v), - } - } - - // "uniqueItems" - if v := schema.UniqueItems; v && !isSliceOfUniqueItems(value) { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "uniqueItems", - Reason: fmt.Sprintf("Duplicate items found"), - } - } - - // "items" - if itemSchemaRef := schema.Items; itemSchemaRef != nil { - itemSchema := itemSchemaRef.Value - if itemSchema == nil { - return foundUnresolvedRef(itemSchemaRef.Ref) - } - for i, item := range value { - if err := itemSchema.VisitJSON(item); err != nil { - return markSchemaErrorIndex(err, i) - } - } - } - return -} - -func (schema *Schema) VisitJSONObject(value map[string]interface{}) error { - return schema.visitJSONObject(value, false) -} - -func (schema *Schema) visitJSONObject(value map[string]interface{}, fast bool) (err error) { - if schemaType := schema.Type; schemaType != "" && schemaType != "object" { - return schema.expectedType("object", fast) - } - - // "properties" - properties := schema.Properties - lenValue := int64(len(value)) - - // "minProperties" - if v := schema.MinProps; v != 0 && lenValue < int64(v) { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "minProperties", - Reason: fmt.Sprintf("There must be at least %d properties", v), - } - } - - // "maxProperties" - if v := schema.MaxProps; v != nil && lenValue > int64(*v) { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "maxProperties", - Reason: fmt.Sprintf("There must be at most %d properties", *v), - } - } - - // "patternProperties" - var cp *compiledPattern - patternProperties := schema.PatternProperties - if len(patternProperties) > 0 { - cp = schema.compiledPatternProperties - if cp == nil { - re, err := regexp.Compile(patternProperties) - if err != nil { - return fmt.Errorf("Error while compiling regular expression '%s': %v", patternProperties, err) - } - cp = &compiledPattern{ - Regexp: re, - ErrReason: "JSON property doesn't match the regular expression '" + patternProperties + "'", - } - schema.compiledPatternProperties = cp - } - } - - // "additionalProperties" - var additionalProperties *Schema - if ref := schema.AdditionalProperties; ref != nil { - additionalProperties = ref.Value - } - for k, v := range value { - if properties != nil { - propertyRef := properties[k] - if propertyRef != nil { - p := propertyRef.Value - if p == nil { - return foundUnresolvedRef(propertyRef.Ref) - } - if err := p.VisitJSON(v); err != nil { - if fast { - return errSchema - } - return markSchemaErrorKey(err, k) - } - continue - } - } - allowed := schema.AdditionalPropertiesAllowed - if additionalProperties != nil || allowed == nil || (allowed != nil && *allowed) { - if cp != nil { - if !cp.Regexp.MatchString(k) { - return &SchemaError{ - Schema: schema, - SchemaField: "patternProperties", - Reason: cp.ErrReason, - } - } - } - if additionalProperties != nil { - if err := additionalProperties.VisitJSON(v); err != nil { - if fast { - return errSchema - } - return markSchemaErrorKey(err, k) - } - } - continue - } - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "properties", - Reason: fmt.Sprintf("Property '%s' is unsupported", k), - } - } - for _, k := range schema.Required { - if _, ok := value[k]; !ok { - if fast { - return errSchema - } - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "required", - Reason: fmt.Sprintf("Property '%s' is missing", k), - } - } - } - return -} - -func (schema *Schema) expectedType(typ string, fast bool) error { - if fast { - return errSchema - } - return &SchemaError{ - Value: schema.Type, - Schema: schema, - SchemaField: "type", - Reason: "Field must be set to " + typ + " or not be present", - } -} - -type SchemaError struct { - Value interface{} - reversePath []string - Schema *Schema - SchemaField string - Reason string -} - -func markSchemaErrorKey(err error, key string) error { - if v, ok := err.(*SchemaError); ok { - v.reversePath = append(v.reversePath, key) - return v - } - return err -} - -func markSchemaErrorIndex(err error, index int) error { - if v, ok := err.(*SchemaError); ok { - v.reversePath = append(v.reversePath, strconv.FormatInt(int64(index), 10)) - return v - } - return err -} - -func (err *SchemaError) JSONPointer() []string { - reversePath := err.reversePath - path := make([]string, len(reversePath)) - for i := range path { - path[i] = reversePath[len(path)-1-i] - } - return path -} - -func (err *SchemaError) Error() string { - buf := bytes.NewBuffer(make([]byte, 0, 256)) - if len(err.reversePath) > 0 { - buf.WriteString(`Error at "`) - reversePath := err.reversePath - for i := len(reversePath) - 1; i >= 0; i-- { - buf.WriteByte('/') - buf.WriteString(reversePath[i]) - } - buf.WriteString(`":`) - } - reason := err.Reason - if reason == "" { - buf.WriteString(`Doesn't match schema "`) - buf.WriteString(err.SchemaField) - buf.WriteString(`"`) - } else { - buf.WriteString(reason) - } - if !SchemaErrorDetailsDisabled { - buf.WriteString("\nSchema:\n ") - encoder := json.NewEncoder(buf) - encoder.SetIndent(" ", " ") - if err := encoder.Encode(err.Schema); err != nil { - panic(err) - } - buf.WriteString("\nValue:\n ") - if err := encoder.Encode(err.Value); err != nil { - panic(err) - } - } - return buf.String() -} - -func isSliceOfUniqueItems(xs []interface{}) bool { - s := len(xs) - m := make(map[interface{}]struct{}, s) - for _, x := range xs { - m[x] = struct{}{} - } - return s == len(m) -} - -func unsupportedFormat(format string) error { - return fmt.Errorf("Unsupported 'format' value '%s'", format) -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/schema_formats.go b/vendor/github.com/getkin/kin-openapi/openapi3/schema_formats.go deleted file mode 100644 index 9f523c734..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/schema_formats.go +++ /dev/null @@ -1,33 +0,0 @@ -package openapi3 - -import ( - "fmt" - "regexp" -) - -var SchemaStringFormats = make(map[string]*regexp.Regexp, 8) - -func DefineStringFormat(name string, pattern string) { - re, err := regexp.Compile(pattern) - if err != nil { - err := fmt.Errorf("Format '%v' has invalid pattern '%v': %v", name, pattern, err) - panic(err) - } - SchemaStringFormats[name] = re -} - -func init() { - // This pattern catches only some suspiciously wrong-looking email addresses. - // Use DefineStringFormat(...) if you need something stricter. - DefineStringFormat("email", `^[^@]+@[^@<>",\w]+$`) - - // Base64 - // The pattern supports base64 and b./ase64url. Padding ('=') is supported. - DefineStringFormat("byte", `(^$|^[a-zA-Z0-9+/\-_]*=*$)`) - - // date - DefineStringFormat("date", `^[0-9]{4}-(0[0-9]|11|12)-([0-2][0-9]|30|31)$`) - - // date-time - DefineStringFormat("date-time", `^[0-9]{4}-(0[0-9]|11|12)-([0-2][0-9]|30|31)T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|(\+|-)[0-9]{2}:[0-9]{2})?$`) -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/security_requirements.go b/vendor/github.com/getkin/kin-openapi/openapi3/security_requirements.go deleted file mode 100644 index c2ea70378..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/security_requirements.go +++ /dev/null @@ -1,40 +0,0 @@ -package openapi3 - -import ( - "context" -) - -type SecurityRequirements []SecurityRequirement - -func NewSecurityRequirements() *SecurityRequirements { - return &SecurityRequirements{} -} - -func (srs *SecurityRequirements) With(securityRequirement SecurityRequirement) *SecurityRequirements { - *srs = append(*srs, securityRequirement) - return srs -} - -func (srs SecurityRequirements) Validate(c context.Context) error { - for _, item := range srs { - if err := item.Validate(c); err != nil { - return err - } - } - return nil -} - -type SecurityRequirement map[string][]string - -func NewSecurityRequirement() SecurityRequirement { - return make(SecurityRequirement) -} - -func (security SecurityRequirement) Authenticate(provider string, scopes ...string) SecurityRequirement { - security[provider] = scopes - return security -} - -func (security SecurityRequirement) Validate(c context.Context) error { - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/security_scheme.go b/vendor/github.com/getkin/kin-openapi/openapi3/security_scheme.go deleted file mode 100644 index 8900ff8ac..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/security_scheme.go +++ /dev/null @@ -1,220 +0,0 @@ -package openapi3 - -import ( - "context" - "errors" - "fmt" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -type SecurityScheme struct { - ExtensionProps - - Type string `json:"type,omitempty"` - Description string `json:"description,omitempty"` - Name string `json:"name,omitempty"` - In string `json:"in,omitempty"` - Scheme string `json:"scheme,omitempty"` - BearerFormat string `json:"bearerFormat,omitempty"` - Flows *OAuthFlows `json:"flows,omitempty"` -} - -func NewSecurityScheme() *SecurityScheme { - return &SecurityScheme{} -} - -func NewCSRFSecurityScheme() *SecurityScheme { - return &SecurityScheme{ - Type: "apiKey", - In: "header", - Name: "X-XSRF-TOKEN", - } -} - -func NewJWTSecurityScheme() *SecurityScheme { - return &SecurityScheme{ - Type: "http", - Scheme: "bearer", - BearerFormat: "JWT", - } -} - -func (ss *SecurityScheme) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(ss) -} - -func (ss *SecurityScheme) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, ss) -} - -func (ss *SecurityScheme) WithType(value string) *SecurityScheme { - ss.Type = value - return ss -} - -func (ss *SecurityScheme) WithDescription(value string) *SecurityScheme { - ss.Description = value - return ss -} - -func (ss *SecurityScheme) WithName(value string) *SecurityScheme { - ss.Name = value - return ss -} - -func (ss *SecurityScheme) WithIn(value string) *SecurityScheme { - ss.In = value - return ss -} - -func (ss *SecurityScheme) WithScheme(value string) *SecurityScheme { - ss.Scheme = value - return ss -} - -func (ss *SecurityScheme) WithBearerFormat(value string) *SecurityScheme { - ss.BearerFormat = value - return ss -} - -func (ss *SecurityScheme) Validate(c context.Context) error { - hasIn := false - hasBearerFormat := false - hasFlow := false - switch ss.Type { - case "apiKey": - hasIn = true - hasBearerFormat = true - case "http": - scheme := ss.Scheme - switch scheme { - case "bearer": - hasBearerFormat = true - case "basic": - default: - return fmt.Errorf("Security scheme of type 'http' has invalid 'scheme' value '%s'", scheme) - } - case "oauth2": - hasFlow = true - case "openIdConnect": - return fmt.Errorf("Support for security schemes with type '%v' has not been implemented", ss.Type) - default: - return fmt.Errorf("Security scheme 'type' can't be '%v'", ss.Type) - } - - // Validate "in" and "name" - if hasIn { - switch ss.In { - case "query", "header": - default: - return fmt.Errorf("Security scheme of type 'apiKey' should have 'in'. It can be 'query' or 'header', not '%s'", ss.In) - } - if ss.Name == "" { - return errors.New("Security scheme of type 'apiKey' should have 'name'") - } - } else if len(ss.In) > 0 { - return fmt.Errorf("Security scheme of type '%s' can't have 'in'", ss.Type) - } else if len(ss.Name) > 0 { - return errors.New("Security scheme of type 'apiKey' can't have 'name'") - } - - // Validate "format" - if hasBearerFormat { - switch ss.BearerFormat { - case "", "JWT": - default: - return fmt.Errorf("Security scheme has unsupported 'bearerFormat' value '%s'", ss.BearerFormat) - } - } else if len(ss.BearerFormat) > 0 { - return errors.New("Security scheme of type 'apiKey' can't have 'bearerFormat'") - } - - // Validate "flow" - if hasFlow { - flow := ss.Flows - if flow == nil { - return fmt.Errorf("Security scheme of type '%v' should have 'flows'", ss.Type) - } - if err := flow.Validate(c); err != nil { - return fmt.Errorf("Security scheme 'flow' is invalid: %v", err) - } - } else if ss.Flows != nil { - return fmt.Errorf("Security scheme of type '%s' can't have 'flows'", ss.Type) - } - return nil -} - -type OAuthFlows struct { - ExtensionProps - Implicit *OAuthFlow `json:"implicit,omitempty"` - Password *OAuthFlow `json:"password,omitempty"` - ClientCredentials *OAuthFlow `json:"clientCredentials,omitempty"` - AuthorizationCode *OAuthFlow `json:"authorizationCode,omitempty"` -} - -type oAuthFlowType int - -const ( - oAuthFlowTypeImplicit oAuthFlowType = iota - oAuthFlowTypePassword - oAuthFlowTypeClientCredentials - oAuthFlowAuthorizationCode -) - -func (flows *OAuthFlows) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(flows) -} - -func (flows *OAuthFlows) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, flows) -} - -func (flows *OAuthFlows) Validate(c context.Context) error { - if v := flows.Implicit; v != nil { - return v.Validate(c, oAuthFlowTypeImplicit) - } - if v := flows.Password; v != nil { - return v.Validate(c, oAuthFlowTypePassword) - } - if v := flows.ClientCredentials; v != nil { - return v.Validate(c, oAuthFlowTypeClientCredentials) - } - if v := flows.AuthorizationCode; v != nil { - return v.Validate(c, oAuthFlowAuthorizationCode) - } - return errors.New("No OAuth flow is defined") -} - -type OAuthFlow struct { - ExtensionProps - AuthorizationURL string `json:"authorizationUrl,omitempty"` - TokenURL string `json:"tokenUrl,omitempty"` - RefreshURL string `json:"refreshUrl,omitempty"` - Scopes map[string]string `json:"scopes"` -} - -func (flow *OAuthFlow) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(flow) -} - -func (flow *OAuthFlow) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, flow) -} - -func (flow *OAuthFlow) Validate(c context.Context, typ oAuthFlowType) error { - if typ == oAuthFlowAuthorizationCode || typ == oAuthFlowTypeImplicit { - if v := flow.AuthorizationURL; v == "" { - return errors.New("An OAuth flow is missing 'authorizationUrl in authorizationCode or implicit '") - } - } - if typ != oAuthFlowTypeImplicit { - if v := flow.TokenURL; v == "" { - return errors.New("An OAuth flow is missing 'tokenUrl in not implicit'") - } - } - if v := flow.Scopes; len(v) == 0 { - return errors.New("An OAuth flow is missing 'scopes'") - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/server.go b/vendor/github.com/getkin/kin-openapi/openapi3/server.go deleted file mode 100644 index 7d2ace5c8..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/server.go +++ /dev/null @@ -1,132 +0,0 @@ -package openapi3 - -import ( - "context" - "errors" - "net/url" - "strings" -) - -// Servers is specified by OpenAPI/Swagger standard version 3.0. -type Servers []*Server - -func (servers Servers) Validate(c context.Context) error { - for _, v := range servers { - if err := v.Validate(c); err != nil { - return err - } - } - return nil -} - -func (servers Servers) MatchURL(parsedURL *url.URL) (*Server, []string, string) { - rawURL := parsedURL.String() - if i := strings.IndexByte(rawURL, '?'); i >= 0 { - rawURL = rawURL[:i] - } - for _, server := range servers { - pathParams, remaining, ok := server.MatchRawURL(rawURL) - if ok { - return server, pathParams, remaining - } - } - return nil, nil, "" -} - -// Server is specified by OpenAPI/Swagger standard version 3.0. -type Server struct { - URL string `json:"url,omitempty"` - Description string `json:"description,omitempty"` - Variables map[string]*ServerVariable `json:"variables,omitempty"` -} - -func (server Server) ParameterNames() ([]string, error) { - pattern := server.URL - var params []string - for len(pattern) > 0 { - i := strings.IndexByte(pattern, '{') - if i < 0 { - break - } - pattern = pattern[i+1:] - i = strings.IndexByte(pattern, '}') - if i < 0 { - return nil, errors.New("Missing '}'") - } - params = append(params, strings.TrimSpace(pattern[:i])) - pattern = pattern[i+1:] - } - return params, nil -} - -func (server Server) MatchRawURL(input string) ([]string, string, bool) { - pattern := server.URL - var params []string - for len(pattern) > 0 { - c := pattern[0] - if len(pattern) == 1 && c == '/' { - break - } - if c == '{' { - // Find end of pattern - i := strings.IndexByte(pattern, '}') - if i < 0 { - return nil, "", false - } - pattern = pattern[i+1:] - - // Find next '.' or '/' - i = strings.IndexAny(input, "./") - if i < 0 { - i = len(input) - } - params = append(params, input[:i]) - input = input[i:] - continue - } - if len(input) == 0 || input[0] != c { - return nil, "", false - } - pattern = pattern[1:] - input = input[1:] - } - if input == "" { - input = "/" - } - if input[0] != '/' { - return nil, "", false - } - return params, input, true -} - -func (server *Server) Validate(c context.Context) (err error) { - for _, v := range server.Variables { - if err = v.Validate(c); err != nil { - return - } - } - return -} - -// ServerVariable is specified by OpenAPI/Swagger standard version 3.0. -type ServerVariable struct { - Enum []interface{} `json:"enum,omitempty"` - Default interface{} `json:"default,omitempty"` - Description string `json:"description,omitempty"` -} - -func (serverVariable *ServerVariable) Validate(c context.Context) error { - switch serverVariable.Default.(type) { - case float64, string: - default: - return errors.New("Variable 'default' must be either JSON number or JSON string") - } - for _, item := range serverVariable.Enum { - switch item.(type) { - case float64, string: - default: - return errors.New("Every variable 'enum' item must be number of string") - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/swagger.go b/vendor/github.com/getkin/kin-openapi/openapi3/swagger.go deleted file mode 100644 index 3f02de317..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/swagger.go +++ /dev/null @@ -1,71 +0,0 @@ -package openapi3 - -import ( - "context" - - "github.com/getkin/kin-openapi/jsoninfo" -) - -type Swagger struct { - ExtensionProps - OpenAPI string `json:"openapi"` // Required - Info Info `json:"info"` // Required - Servers Servers `json:"servers,omitempty"` - Paths Paths `json:"paths,omitempty"` - Components Components `json:"components,omitempty"` - Security SecurityRequirements `json:"security,omitempty"` - ExternalDocs *ExternalDocs `json:"externalDocs,omitempty"` -} - -func (swagger *Swagger) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(swagger) -} - -func (swagger *Swagger) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, swagger) -} - -func (swagger *Swagger) AddOperation(path string, method string, operation *Operation) { - paths := swagger.Paths - if paths == nil { - paths = make(Paths) - swagger.Paths = paths - } - pathItem := paths[path] - if pathItem == nil { - pathItem = &PathItem{} - paths[path] = pathItem - } - pathItem.SetOperation(method, operation) -} - -func (swagger *Swagger) AddServer(server *Server) { - swagger.Servers = append(swagger.Servers, server) -} - -func (swagger *Swagger) Validate(c context.Context) error { - if err := swagger.Components.Validate(c); err != nil { - return err - } - if v := swagger.Security; v != nil { - if err := v.Validate(c); err != nil { - return err - } - } - if paths := swagger.Paths; paths != nil { - if err := paths.Validate(c); err != nil { - return err - } - } - if v := swagger.Servers; v != nil { - if err := v.Validate(c); err != nil { - return err - } - } - if v := swagger.Paths; v != nil { - if err := v.Validate(c); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/swagger_loader.go b/vendor/github.com/getkin/kin-openapi/openapi3/swagger_loader.go deleted file mode 100644 index a6d81a260..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/swagger_loader.go +++ /dev/null @@ -1,480 +0,0 @@ -package openapi3 - -import ( - "context" - "encoding/json" - "fmt" - "io/ioutil" - "net/url" - "strings" - - "github.com/ghodss/yaml" -) - -func foundUnresolvedRef(ref string) error { - return fmt.Errorf("Found unresolved ref: '%s'", ref) -} - -func failedToResolveRefFragment(value string) error { - return fmt.Errorf("Failed to resolve fragment in URI: '%s'", value) -} - -func failedToResolveRefFragmentPart(value string, what string) error { - return fmt.Errorf("Failed to resolve '%s' in fragment in URI: '%s'", what, value) -} - -type SwaggerLoader struct { - IsExternalRefsAllowed bool - Context context.Context - LoadSwaggerFromURIFunc func(loader *SwaggerLoader, url *url.URL) (*Swagger, error) - visited map[interface{}]struct{} -} - -func NewSwaggerLoader() *SwaggerLoader { - return &SwaggerLoader{} -} - -func (swaggerLoader *SwaggerLoader) LoadSwaggerFromURI(location *url.URL) (*Swagger, error) { - f := swaggerLoader.LoadSwaggerFromURIFunc - if f != nil { - return f(swaggerLoader, location) - } - if location.Scheme != "" || location.Host != "" || location.RawQuery != "" { - return nil, fmt.Errorf("Unsupported URI: '%s'", location.String()) - } - data, err := ioutil.ReadFile(location.Path) - if err != nil { - return nil, err - } - return swaggerLoader.LoadSwaggerFromData(data) -} - -func (swaggerLoader *SwaggerLoader) LoadSwaggerFromFile(path string) (*Swagger, error) { - f := swaggerLoader.LoadSwaggerFromURIFunc - if f != nil { - return f(swaggerLoader, &url.URL{ - Path: path, - }) - } - data, err := ioutil.ReadFile(path) - if err != nil { - return nil, err - } - return swaggerLoader.LoadSwaggerFromData(data) -} - -func (swaggerLoader *SwaggerLoader) LoadSwaggerFromData(data []byte) (*Swagger, error) { - swagger := &Swagger{} - if err := json.Unmarshal(data, swagger); err != nil { - return nil, err - } - return swagger, swaggerLoader.ResolveRefsIn(swagger) -} - -func (swaggerLoader *SwaggerLoader) LoadSwaggerFromYAMLData(data []byte) (*Swagger, error) { - swagger := &Swagger{} - if err := yaml.Unmarshal(data, swagger); err != nil { - return nil, err - } - return swagger, swaggerLoader.ResolveRefsIn(swagger) -} - -func (swaggerLoader *SwaggerLoader) ResolveRefsIn(swagger *Swagger) (err error) { - swaggerLoader.visited = make(map[interface{}]struct{}) - - // Visit all components - components := swagger.Components - for _, component := range components.Headers { - if err = swaggerLoader.resolveHeaderRef(swagger, component); err != nil { - return - } - } - for _, component := range components.Parameters { - if err = swaggerLoader.resolveParameterRef(swagger, component); err != nil { - return - } - } - for _, component := range components.RequestBodies { - if err = swaggerLoader.resolveRequestBodyRef(swagger, component); err != nil { - return - } - } - for _, component := range components.Responses { - if err = swaggerLoader.resolveResponseRef(swagger, component); err != nil { - return - } - } - for _, component := range components.Schemas { - if err = swaggerLoader.resolveSchemaRef(swagger, component); err != nil { - return - } - } - for _, component := range components.SecuritySchemes { - if err = swaggerLoader.resolveSecuritySchemeRef(swagger, component); err != nil { - return - } - } - for _, component := range components.Examples { - if err = swaggerLoader.resolveExampleRef(swagger, component); err != nil { - return - } - } - - // Visit all operations - for _, pathItem := range swagger.Paths { - if pathItem == nil { - continue - } - for _, operation := range pathItem.Operations() { - for _, parameter := range operation.Parameters { - if err = swaggerLoader.resolveParameterRef(swagger, parameter); err != nil { - return - } - } - if requestBody := operation.RequestBody; requestBody != nil { - if err = swaggerLoader.resolveRequestBodyRef(swagger, requestBody); err != nil { - return - } - } - for _, response := range operation.Responses { - if err = swaggerLoader.resolveResponseRef(swagger, response); err != nil { - return - } - } - } - } - - return -} - -func (swaggerLoader *SwaggerLoader) resolveComponent(swagger *Swagger, ref string, prefix string) ( - components *Components, - id string, - err error, -) { - if !strings.HasPrefix(ref, "#") { - if !swaggerLoader.IsExternalRefsAllowed { - return nil, "", fmt.Errorf("Encountered non-allowed external reference: '%s'", ref) - } - parsedURL, err := url.Parse(ref) - if err != nil { - return nil, "", fmt.Errorf("Can't parse reference: '%s': %v", ref, parsedURL) - } - fragment := parsedURL.Fragment - parsedURL.Fragment = "" - if swagger, err = swaggerLoader.LoadSwaggerFromURI(parsedURL); err != nil { - return nil, "", fmt.Errorf("Error while resolving reference '%s': %v", ref, err) - } - ref = fmt.Sprintf("#%s", fragment) - } - if !strings.HasPrefix(ref, prefix) { - err := fmt.Errorf("expected prefix '%s' in URI '%s'", prefix, ref) - return nil, "", err - } - id = ref[len(prefix):] - if strings.IndexByte(id, '/') >= 0 { - return nil, "", failedToResolveRefFragmentPart(ref, id) - } - return &swagger.Components, id, nil -} - -func (swaggerLoader *SwaggerLoader) resolveHeaderRef(swagger *Swagger, component *HeaderRef) error { - // Prevent infinite recursion - visited := swaggerLoader.visited - if _, isVisited := visited[component]; isVisited { - return nil - } - visited[component] = struct{}{} - - // Resolve ref - const prefix = "#/components/headers/" - if ref := component.Ref; len(ref) > 0 { - components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix) - if err != nil { - return err - } - definitions := components.Headers - if definitions == nil { - return failedToResolveRefFragment(ref) - } - resolved := definitions[id] - if resolved == nil { - return failedToResolveRefFragment(ref) - } - if err := swaggerLoader.resolveHeaderRef(swagger, resolved); err != nil { - return err - } - component.Value = resolved.Value - } - value := component.Value - if value == nil { - return nil - } - if schema := value.Schema; schema != nil { - if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil { - return err - } - } - return nil -} - -func (swaggerLoader *SwaggerLoader) resolveParameterRef(swagger *Swagger, component *ParameterRef) error { - // Prevent infinite recursion - visited := swaggerLoader.visited - if _, isVisited := visited[component]; isVisited { - return nil - } - visited[component] = struct{}{} - - // Resolve ref - const prefix = "#/components/parameters/" - if ref := component.Ref; len(ref) > 0 { - components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix) - if err != nil { - return err - } - definitions := components.Parameters - if definitions == nil { - return failedToResolveRefFragmentPart(ref, "parameters") - } - resolved := definitions[id] - if resolved == nil { - return failedToResolveRefFragmentPart(ref, id) - } - if err := swaggerLoader.resolveParameterRef(swagger, resolved); err != nil { - return err - } - component.Value = resolved.Value - } - value := component.Value - if value == nil { - return nil - } - if schema := value.Schema; schema != nil { - if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil { - return err - } - } - return nil -} - -func (swaggerLoader *SwaggerLoader) resolveRequestBodyRef(swagger *Swagger, component *RequestBodyRef) error { - // Prevent infinite recursion - visited := swaggerLoader.visited - if _, isVisited := visited[component]; isVisited { - return nil - } - visited[component] = struct{}{} - - // Resolve ref - const prefix = "#/components/requestBodies/" - if ref := component.Ref; len(ref) > 0 { - components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix) - if err != nil { - return err - } - definitions := components.RequestBodies - if definitions == nil { - return failedToResolveRefFragmentPart(ref, "requestBodies") - } - resolved := definitions[id] - if resolved == nil { - return failedToResolveRefFragmentPart(ref, id) - } - if err = swaggerLoader.resolveRequestBodyRef(swagger, resolved); err != nil { - return err - } - component.Value = resolved.Value - } - value := component.Value - if value == nil { - return nil - } - for _, contentType := range value.Content { - if schema := contentType.Schema; schema != nil { - if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil { - return err - } - } - } - return nil -} - -func (swaggerLoader *SwaggerLoader) resolveResponseRef(swagger *Swagger, component *ResponseRef) error { - // Prevent infinite recursion - visited := swaggerLoader.visited - if _, isVisited := visited[component]; isVisited { - return nil - } - visited[component] = struct{}{} - - // Resolve ref - const prefix = "#/components/responses/" - if ref := component.Ref; len(ref) > 0 { - components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix) - if err != nil { - return err - } - definitions := components.Responses - if definitions == nil { - return failedToResolveRefFragmentPart(ref, "responses") - } - resolved := definitions[id] - if resolved == nil { - return failedToResolveRefFragmentPart(ref, id) - } - if err := swaggerLoader.resolveResponseRef(swagger, resolved); err != nil { - return err - } - component.Value = resolved.Value - } - value := component.Value - if value == nil { - return nil - } - for _, contentType := range value.Content { - if contentType == nil { - continue - } - for name, example := range contentType.Examples { - if err := swaggerLoader.resolveExampleRef(swagger, example); err != nil { - return err - } - contentType.Examples[name] = example - } - if schema := contentType.Schema; schema != nil { - if err := swaggerLoader.resolveSchemaRef(swagger, schema); err != nil { - return err - } - contentType.Schema = schema - } - } - return nil -} - -func (swaggerLoader *SwaggerLoader) resolveSchemaRef(swagger *Swagger, component *SchemaRef) error { - // Prevent infinite recursion - visited := swaggerLoader.visited - if _, isVisited := visited[component]; isVisited { - return nil - } - visited[component] = struct{}{} - - // Resolve ref - const prefix = "#/components/schemas/" - if ref := component.Ref; len(ref) > 0 { - components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix) - if err != nil { - return err - } - definitions := components.Schemas - if definitions == nil { - return failedToResolveRefFragmentPart(ref, "schemas") - } - resolved := definitions[id] - if resolved == nil { - return failedToResolveRefFragmentPart(ref, id) - } - if err := swaggerLoader.resolveSchemaRef(swagger, resolved); err != nil { - return err - } - component.Value = resolved.Value - } - value := component.Value - if value == nil { - return nil - } - - // ResolveRefs referred schemas - if v := value.Items; v != nil { - if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil { - return err - } - } - for _, v := range value.Properties { - if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil { - return err - } - } - if v := value.AdditionalProperties; v != nil { - if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil { - return err - } - } - if v := value.Not; v != nil { - if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil { - return err - } - } - for _, v := range value.AllOf { - if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil { - return err - } - } - for _, v := range value.AnyOf { - if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil { - return err - } - } - for _, v := range value.OneOf { - if err := swaggerLoader.resolveSchemaRef(swagger, v); err != nil { - return err - } - } - - return nil -} - -func (swaggerLoader *SwaggerLoader) resolveSecuritySchemeRef(swagger *Swagger, component *SecuritySchemeRef) error { - // Prevent infinite recursion - visited := swaggerLoader.visited - if _, isVisited := visited[component]; isVisited { - return nil - } - visited[component] = struct{}{} - - // Resolve ref - const prefix = "#/components/securitySchemes/" - if ref := component.Ref; len(ref) > 0 { - components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix) - if err != nil { - return err - } - definitions := components.SecuritySchemes - if definitions == nil { - return failedToResolveRefFragmentPart(ref, "securitySchemes") - } - resolved := definitions[id] - if resolved == nil { - return failedToResolveRefFragmentPart(ref, id) - } - if err := swaggerLoader.resolveSecuritySchemeRef(swagger, resolved); err != nil { - return err - } - component.Value = resolved.Value - } - return nil -} - -func (swaggerLoader *SwaggerLoader) resolveExampleRef(swagger *Swagger, component *ExampleRef) error { - const prefix = "#/components/examples/" - if ref := component.Ref; len(ref) > 0 { - components, id, err := swaggerLoader.resolveComponent(swagger, ref, prefix) - if err != nil { - return err - } - definitions := components.Examples - if definitions == nil { - return failedToResolveRefFragmentPart(ref, "examples") - } - resolved := definitions[id] - if resolved == nil { - return failedToResolveRefFragmentPart(ref, id) - } - if err := swaggerLoader.resolveExampleRef(swagger, resolved); err != nil { - return err - } - component.Value = resolved.Value - } - return nil -} diff --git a/vendor/github.com/getkin/kin-openapi/openapi3/tag.go b/vendor/github.com/getkin/kin-openapi/openapi3/tag.go deleted file mode 100644 index 311a9fd59..000000000 --- a/vendor/github.com/getkin/kin-openapi/openapi3/tag.go +++ /dev/null @@ -1,20 +0,0 @@ -package openapi3 - -// Tags is specified by OpenAPI/Swagger 3.0 standard. -type Tags []*Tag - -func (tags Tags) Get(name string) *Tag { - for _, tag := range tags { - if tag.Name == name { - return tag - } - } - return nil -} - -// Tag is specified by OpenAPI/Swagger 3.0 standard. -type Tag struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - ExternalDocs *ExternalDocs `json:"externalDocs,omitempty"` -} diff --git a/vendor/github.com/getsentry/sentry-go/.codecov.yml b/vendor/github.com/getsentry/sentry-go/.codecov.yml deleted file mode 100644 index df0b26811..000000000 --- a/vendor/github.com/getsentry/sentry-go/.codecov.yml +++ /dev/null @@ -1,13 +0,0 @@ -codecov: - # across - notify: - # Do not notify until at least this number of reports have been uploaded - # from the CI pipeline. We normally have more than that number, but 6 - # should be enough to get a first notification. - after_n_builds: 6 -coverage: - status: - project: - default: - # Do not fail the commit status if the coverage was reduced up to this value - threshold: 0.5% diff --git a/vendor/github.com/getsentry/sentry-go/.craft.yml b/vendor/github.com/getsentry/sentry-go/.craft.yml deleted file mode 100644 index 238288e45..000000000 --- a/vendor/github.com/getsentry/sentry-go/.craft.yml +++ /dev/null @@ -1,13 +0,0 @@ -minVersion: 0.35.0 -changelogPolicy: simple -artifactProvider: - name: none -targets: - - name: github - tagPrefix: v - - name: github - tagPrefix: otel/v - tagOnly: true - - name: registry - sdks: - github:getsentry/sentry-go: diff --git a/vendor/github.com/getsentry/sentry-go/.gitattributes b/vendor/github.com/getsentry/sentry-go/.gitattributes deleted file mode 100644 index bccfeeab0..000000000 --- a/vendor/github.com/getsentry/sentry-go/.gitattributes +++ /dev/null @@ -1,5 +0,0 @@ -# Tell Git to use LF for line endings on all platforms. -# Required to have correct test data on Windows. -# https://github.com/mvdan/github-actions-golang#caveats -# https://github.com/actions/checkout/issues/135#issuecomment-613361104 -* text eol=lf diff --git a/vendor/github.com/getsentry/sentry-go/.gitignore b/vendor/github.com/getsentry/sentry-go/.gitignore deleted file mode 100644 index b1249ba55..000000000 --- a/vendor/github.com/getsentry/sentry-go/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# Code coverage artifacts -coverage.txt -coverage.out -coverage.html -.coverage/ - -# Just my personal way of tracking stuff — Kamil -FIXME.md -TODO.md -!NOTES.md - -# IDE system files -.idea -.vscode diff --git a/vendor/github.com/getsentry/sentry-go/.golangci.yml b/vendor/github.com/getsentry/sentry-go/.golangci.yml deleted file mode 100644 index 285e5870e..000000000 --- a/vendor/github.com/getsentry/sentry-go/.golangci.yml +++ /dev/null @@ -1,46 +0,0 @@ -linters: - disable-all: true - enable: - - bodyclose - - dogsled - - dupl - - errcheck - - exportloopref - - gochecknoinits - - goconst - - gocritic - - gocyclo - - godot - - gofmt - - goimports - - gosec - - gosimple - - govet - - ineffassign - - misspell - - nakedret - - prealloc - - revive - - staticcheck - - typecheck - - unconvert - - unparam - - unused - - whitespace -issues: - exclude-rules: - - path: _test\.go - linters: - - goconst - - prealloc - - path: _test\.go - text: "G306:" - linters: - - gosec - - path: errors_test\.go - linters: - - unused - - path: http/example_test\.go - linters: - - errcheck - - bodyclose diff --git a/vendor/github.com/getsentry/sentry-go/CHANGELOG.md b/vendor/github.com/getsentry/sentry-go/CHANGELOG.md deleted file mode 100644 index dce9a3ff9..000000000 --- a/vendor/github.com/getsentry/sentry-go/CHANGELOG.md +++ /dev/null @@ -1,864 +0,0 @@ -# Changelog - -## 0.29.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.29.0. - -### Breaking Changes - -- Remove the `sentrymartini` integration ([#861](https://github.com/getsentry/sentry-go/pull/861)) -- The `WrapResponseWriter` has been moved from the `sentryhttp` package to the `internal/httputils` package. If you've imported it previosuly, you'll need to copy the implementation in your project. ([#871](https://github.com/getsentry/sentry-go/pull/871)) - -### Features - -- Add new convenience methods to continue a trace and propagate tracing headers for error-only use cases. ([#862](https://github.com/getsentry/sentry-go/pull/862)) - - If you are not using one of our integrations, you can manually continue an incoming trace by using `sentry.ContinueTrace()` by providing the `sentry-trace` and `baggage` header received from a downstream SDK. - - ```go - hub := sentry.CurrentHub() - sentry.ContinueTrace(hub, r.Header.Get(sentry.SentryTraceHeader), r.Header.Get(sentry.SentryBaggageHeader)), - ``` - - You can use `hub.GetTraceparent()` and `hub.GetBaggage()` to fetch the necessary header values for outgoing HTTP requests. - - ```go - hub := sentry.GetHubFromContext(ctx) - req, _ := http.NewRequest("GET", "http://localhost:3000", nil) - req.Header.Add(sentry.SentryTraceHeader, hub.GetTraceparent()) - req.Header.Add(sentry.SentryBaggageHeader, hub.GetBaggage()) - ``` - -### Bug Fixes - -- Initialize `HTTPTransport.limit` if `nil` ([#844](https://github.com/getsentry/sentry-go/pull/844)) -- Fix `sentry.StartTransaction()` returning a transaction with an outdated context on existing transactions ([#854](https://github.com/getsentry/sentry-go/pull/854)) -- Treat `Proxy-Authorization` as a sensitive header ([#859](https://github.com/getsentry/sentry-go/pull/859)) -- Add support for the `http.Hijacker` interface to the `sentrynegroni` package ([#871](https://github.com/getsentry/sentry-go/pull/871)) -- Go version >= 1.23: Use value from `http.Request.Pattern` for HTTP transaction names when using `sentryhttp` & `sentrynegroni` ([#875](https://github.com/getsentry/sentry-go/pull/875)) -- Go version >= 1.21: Fix closure functions name grouping ([#877](https://github.com/getsentry/sentry-go/pull/877)) - -### Misc - -- Collect `span` origins ([#849](https://github.com/getsentry/sentry-go/pull/849)) - -## 0.28.1 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.28.1. - -### Bug Fixes - -- Implement `http.ResponseWriter` to hook into various parts of the response process ([#837](https://github.com/getsentry/sentry-go/pull/837)) - -## 0.28.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.28.0. - -### Features - -- Add a `Fiber` performance tracing & error reporting integration ([#795](https://github.com/getsentry/sentry-go/pull/795)) -- Add performance tracing to the `Echo` integration ([#722](https://github.com/getsentry/sentry-go/pull/722)) -- Add performance tracing to the `FastHTTP` integration ([#732](https://github.com/getsentry/sentry-go/pull/723)) -- Add performance tracing to the `Iris` integration ([#809](https://github.com/getsentry/sentry-go/pull/809)) -- Add performance tracing to the `Negroni` integration ([#808](https://github.com/getsentry/sentry-go/pull/808)) -- Add `FailureIssueThreshold` & `RecoveryThreshold` to `MonitorConfig` ([#775](https://github.com/getsentry/sentry-go/pull/775)) -- Use `errors.Unwrap()` to create exception groups ([#792](https://github.com/getsentry/sentry-go/pull/792)) -- Add support for matching on strings for `ClientOptions.IgnoreErrors` & `ClientOptions.IgnoreTransactions` ([#819](https://github.com/getsentry/sentry-go/pull/819)) -- Add `http.request.method` attribute for performance span data ([#786](https://github.com/getsentry/sentry-go/pull/786)) -- Accept `interface{}` for span data values ([#784](https://github.com/getsentry/sentry-go/pull/784)) - -### Bug Fixes - -- Fix missing stack trace for parsing error in `logrusentry` ([#689](https://github.com/getsentry/sentry-go/pull/689)) - -## 0.27.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.27.0. - -### Breaking Changes - -- `Exception.ThreadId` is now typed as `uint64`. It was wrongly typed as `string` before. ([#770](https://github.com/getsentry/sentry-go/pull/770)) - -### Misc - -- Export `Event.Attachments` ([#771](https://github.com/getsentry/sentry-go/pull/771)) - -## 0.26.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.26.0. - -### Breaking Changes - -As previously announced, this release removes some methods from the SDK. - -- `sentry.TransactionName()` use `sentry.WithTransactionName()` instead. -- `sentry.OpName()` use `sentry.WithOpName()` instead. -- `sentry.TransctionSource()` use `sentry.WithTransactionSource()` instead. -- `sentry.SpanSampled()` use `sentry.WithSpanSampled()` instead. - -### Features - -- Add `WithDescription` span option ([#751](https://github.com/getsentry/sentry-go/pull/751)) - - ```go - span := sentry.StartSpan(ctx, "http.client", WithDescription("GET /api/users")) - ``` -- Add support for package name parsing in Go 1.20 and higher ([#730](https://github.com/getsentry/sentry-go/pull/730)) - -### Bug Fixes - -- Apply `ClientOptions.SampleRate` only to errors & messages ([#754](https://github.com/getsentry/sentry-go/pull/754)) -- Check if git is available before executing any git commands ([#737](https://github.com/getsentry/sentry-go/pull/737)) - -## 0.25.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.25.0. - -### Breaking Changes - -As previously announced, this release removes two global constants from the SDK. - -- `sentry.Version` was removed. Use `sentry.SDKVersion` instead ([#727](https://github.com/getsentry/sentry-go/pull/727)) -- `sentry.SDKIdentifier` was removed. Use `Client.GetSDKIdentifier()` instead ([#727](https://github.com/getsentry/sentry-go/pull/727)) - -### Features - -- Add `ClientOptions.IgnoreTransactions`, which allows you to ignore specific transactions based on their name ([#717](https://github.com/getsentry/sentry-go/pull/717)) -- Add `ClientOptions.Tags`, which allows you to set global tags that are applied to all events. You can also define tags by setting `SENTRY_TAGS_` environment variables ([#718](https://github.com/getsentry/sentry-go/pull/718)) - -### Bug fixes - -- Fix an issue in the profiler that would cause an infinite loop if the duration of a transaction is longer than 30 seconds ([#724](https://github.com/getsentry/sentry-go/issues/724)) - -### Misc - -- `dsn.RequestHeaders()` is not to be removed, though it is still considered deprecated and should only be used when using a custom transport that sends events to the `/store` endpoint ([#720](https://github.com/getsentry/sentry-go/pull/720)) - -## 0.24.1 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.24.1. - -### Bug fixes - -- Prevent a panic in `sentryotel.flushSpanProcessor()` ([(#711)](https://github.com/getsentry/sentry-go/pull/711)) -- Prevent a panic when setting the SDK identifier ([#715](https://github.com/getsentry/sentry-go/pull/715)) - -## 0.24.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.24.0. - -### Deprecations - -- `sentry.Version` to be removed in 0.25.0. Use `sentry.SDKVersion` instead. -- `sentry.SDKIdentifier` to be removed in 0.25.0. Use `Client.GetSDKIdentifier()` instead. -- `dsn.RequestHeaders()` to be removed after 0.25.0, but no earlier than December 1, 2023. Requests to the `/envelope` endpoint are authenticated using the DSN in the envelope header. - -### Features - -- Run a single instance of the profiler instead of multiple ones for each Go routine ([#655](https://github.com/getsentry/sentry-go/pull/655)) -- Use the route path as the transaction names when using the Gin integration ([#675](https://github.com/getsentry/sentry-go/pull/675)) -- Set the SDK name accordingly when a framework integration is used ([#694](https://github.com/getsentry/sentry-go/pull/694)) -- Read release information (VCS revision) from `debug.ReadBuildInfo` ([#704](https://github.com/getsentry/sentry-go/pull/704)) - -### Bug fixes - -- [otel] Fix incorrect usage of `attributes.Value.AsString` ([#684](https://github.com/getsentry/sentry-go/pull/684)) -- Fix trace function name parsing in profiler on go1.21+ ([#695](https://github.com/getsentry/sentry-go/pull/695)) - -### Misc - -- Test against Go 1.21 ([#695](https://github.com/getsentry/sentry-go/pull/695)) -- Make tests more robust ([#698](https://github.com/getsentry/sentry-go/pull/698), [#699](https://github.com/getsentry/sentry-go/pull/699), [#700](https://github.com/getsentry/sentry-go/pull/700), [#702](https://github.com/getsentry/sentry-go/pull/702)) - -## 0.23.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.23.0. - -### Features - -- Initial support for [Cron Monitoring](https://docs.sentry.io/product/crons/) ([#661](https://github.com/getsentry/sentry-go/pull/661)) - - This is how the basic usage of the feature looks like: - - ```go - // 🟡 Notify Sentry your job is running: - checkinId := sentry.CaptureCheckIn( - &sentry.CheckIn{ - MonitorSlug: "", - Status: sentry.CheckInStatusInProgress, - }, - nil, - ) - - // Execute your scheduled task here... - - // 🟢 Notify Sentry your job has completed successfully: - sentry.CaptureCheckIn( - &sentry.CheckIn{ - ID: *checkinId, - MonitorSlug: "", - Status: sentry.CheckInStatusOK, - }, - nil, - ) - ``` - - A full example of using Crons Monitoring is available [here](https://github.com/getsentry/sentry-go/blob/dde4d360660838f3c2e0ced8205bc8f7a8d312d9/_examples/crons/main.go). - - More documentation on configuring and using Crons [can be found here](https://docs.sentry.io/platforms/go/crons/). - -- Add support for [Event Attachments](https://docs.sentry.io/platforms/go/enriching-events/attachments/) ([#670](https://github.com/getsentry/sentry-go/pull/670)) - - It's now possible to add file/binary payloads to Sentry events: - - ```go - sentry.ConfigureScope(func(scope *sentry.Scope) { - scope.AddAttachment(&Attachment{ - Filename: "report.html", - ContentType: "text/html", - Payload: []byte("

Look, HTML

"), - }) - }) - ``` - - The attachment will then be accessible on the Issue Details page. - -- Add sampling decision to trace envelope header ([#666](https://github.com/getsentry/sentry-go/pull/666)) -- Expose SpanFromContext function ([#672](https://github.com/getsentry/sentry-go/pull/672)) - -### Bug fixes - -- Make `Span.Finish` a no-op when the span is already finished ([#660](https://github.com/getsentry/sentry-go/pull/660)) - -## 0.22.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.22.0. - -This release contains initial [profiling](https://docs.sentry.io/product/profiling/) support, as well as a few bug fixes and improvements. - -### Features - -- Initial (alpha) support for [profiling](https://docs.sentry.io/product/profiling/) ([#626](https://github.com/getsentry/sentry-go/pull/626)) - - Profiling is disabled by default. To enable it, configure both `TracesSampleRate` and `ProfilesSampleRate` when initializing the SDK: - - ```go - err := sentry.Init(sentry.ClientOptions{ - Dsn: "__DSN__", - EnableTracing: true, - TracesSampleRate: 1.0, - // The sampling rate for profiling is relative to TracesSampleRate. In this case, we'll capture profiles for 100% of transactions. - ProfilesSampleRate: 1.0, - }) - ``` - - More documentation on profiling and current limitations [can be found here](https://docs.sentry.io/platforms/go/profiling/). - -- Add transactions/tracing support go the Gin integration ([#644](https://github.com/getsentry/sentry-go/pull/644)) - -### Bug fixes - -- Always set a valid source on transactions ([#637](https://github.com/getsentry/sentry-go/pull/637)) -- Clone scope.Context in more places to avoid panics on concurrent reads and writes ([#638](https://github.com/getsentry/sentry-go/pull/638)) - - Fixes [#570](https://github.com/getsentry/sentry-go/issues/570) -- Fix frames recognized as not being in-app still showing as in-app ([#647](https://github.com/getsentry/sentry-go/pull/647)) - -## 0.21.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.21.0. - -Note: this release includes one **breaking change** and some **deprecations**, which are listed below. - -### Breaking Changes - -**This change does not apply if you use [https://sentry.io](https://sentry.io)** - -- Remove support for the `/store` endpoint ([#631](https://github.com/getsentry/sentry-go/pull/631)) - - This change requires a self-hosted version of Sentry 20.6.0 or higher. If you are using a version of [self-hosted Sentry](https://develop.sentry.dev/self-hosted/) (aka *on-premise*) older than 20.6.0, then you will need to [upgrade](https://develop.sentry.dev/self-hosted/releases/) your instance. - -### Features - -- Rename four span option functions ([#611](https://github.com/getsentry/sentry-go/pull/611), [#624](https://github.com/getsentry/sentry-go/pull/624)) - - `TransctionSource` -> `WithTransactionSource` - - `SpanSampled` -> `WithSpanSampled` - - `OpName` -> `WithOpName` - - `TransactionName` -> `WithTransactionName` - - Old functions `TransctionSource`, `SpanSampled`, `OpName`, and `TransactionName` are still available but are now **deprecated** and will be removed in a future release. -- Make `client.EventFromMessage` and `client.EventFromException` methods public ([#607](https://github.com/getsentry/sentry-go/pull/607)) -- Add `client.SetException` method ([#607](https://github.com/getsentry/sentry-go/pull/607)) - - This allows to set or add errors to an existing `Event`. - -### Bug Fixes - -- Protect from panics while doing concurrent reads/writes to Span data fields ([#609](https://github.com/getsentry/sentry-go/pull/609)) -- [otel] Improve detection of Sentry-related spans ([#632](https://github.com/getsentry/sentry-go/pull/632), [#636](https://github.com/getsentry/sentry-go/pull/636)) - - Fixes cases when HTTP spans containing requests to Sentry were captured by Sentry ([#627](https://github.com/getsentry/sentry-go/issues/627)) - -### Misc - -- Drop testing in (legacy) GOPATH mode ([#618](https://github.com/getsentry/sentry-go/pull/618)) -- Remove outdated documentation from https://pkg.go.dev/github.com/getsentry/sentry-go ([#623](https://github.com/getsentry/sentry-go/pull/623)) - -## 0.20.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.20.0. - -Note: this release has some **breaking changes**, which are listed below. - -### Breaking Changes - -- Remove the following methods: `Scope.SetTransaction()`, `Scope.Transaction()` ([#605](https://github.com/getsentry/sentry-go/pull/605)) - - Span.Name should be used instead to access the transaction's name. - - For example, the following [`TracesSampler`](https://docs.sentry.io/platforms/go/configuration/sampling/#setting-a-sampling-function) function should be now written as follows: - - **Before:** - ```go - TracesSampler: func(ctx sentry.SamplingContext) float64 { - hub := sentry.GetHubFromContext(ctx.Span.Context()) - if hub.Scope().Transaction() == "GET /health" { - return 0 - } - return 1 - }, - ``` - - **After:** - ```go - TracesSampler: func(ctx sentry.SamplingContext) float64 { - if ctx.Span.Name == "GET /health" { - return 0 - } - return 1 - }, - ``` - -### Features - -- Add `Span.SetContext()` method ([#599](https://github.com/getsentry/sentry-go/pull/599/)) - - It is recommended to use it instead of `hub.Scope().SetContext` when setting or updating context on transactions. -- Add `DebugMeta` interface to `Event` and extend `Frame` structure with more fields ([#606](https://github.com/getsentry/sentry-go/pull/606)) - - More about DebugMeta interface [here](https://develop.sentry.dev/sdk/event-payloads/debugmeta/). - -### Bug Fixes - -- [otel] Fix missing OpenTelemetry context on some events ([#599](https://github.com/getsentry/sentry-go/pull/599), [#605](https://github.com/getsentry/sentry-go/pull/605)) - - Fixes ([#596](https://github.com/getsentry/sentry-go/issues/596)). -- [otel] Better handling for HTTP span attributes ([#610](https://github.com/getsentry/sentry-go/pull/610)) - -### Misc - -- Bump minimum versions: `github.com/kataras/iris/v12` to 12.2.0, `github.com/labstack/echo/v4` to v4.10.0 ([#595](https://github.com/getsentry/sentry-go/pull/595)) - - Resolves [GO-2022-1144 / CVE-2022-41717](https://deps.dev/advisory/osv/GO-2022-1144), [GO-2023-1495 / CVE-2022-41721](https://deps.dev/advisory/osv/GO-2023-1495), [GO-2022-1059 / CVE-2022-32149](https://deps.dev/advisory/osv/GO-2022-1059). -- Bump `google.golang.org/protobuf` minimum required version to 1.29.1 ([#604](https://github.com/getsentry/sentry-go/pull/604)) - - This fixes a potential denial of service issue ([CVE-2023-24535](https://github.com/advisories/GHSA-hw7c-3rfg-p46j)). -- Exclude the `otel` module when building in GOPATH mode ([#615](https://github.com/getsentry/sentry-go/pull/615)) - -## 0.19.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.19.0. - -### Features - -- Add support for exception mechanism metadata ([#564](https://github.com/getsentry/sentry-go/pull/564/)) - - More about exception mechanisms [here](https://develop.sentry.dev/sdk/event-payloads/exception/#exception-mechanism). - -### Bug Fixes -- [otel] Use the correct "trace" context when sending a Sentry error ([#580](https://github.com/getsentry/sentry-go/pull/580/)) - - -### Misc -- Drop support for Go 1.17, add support for Go 1.20 ([#563](https://github.com/getsentry/sentry-go/pull/563/)) - - According to our policy, we're officially supporting the last three minor releases of Go. -- Switch repository license to MIT ([#583](https://github.com/getsentry/sentry-go/pull/583/)) - - More about Sentry licensing [here](https://open.sentry.io/licensing/). -- Bump `golang.org/x/text` minimum required version to 0.3.8 ([#586](https://github.com/getsentry/sentry-go/pull/586)) - - This fixes [CVE-2022-32149](https://github.com/advisories/GHSA-69ch-w2m2-3vjp) vulnerability. - -## 0.18.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.18.0. -This release contains initial support for [OpenTelemetry](https://opentelemetry.io/) and various other bug fixes and improvements. - -**Note**: This is the last release supporting Go 1.17. - -### Features - -- Initial support for [OpenTelemetry](https://opentelemetry.io/). - You can now send all your OpenTelemetry spans to Sentry. - - Install the `otel` module - - ```bash - go get github.com/getsentry/sentry-go \ - github.com/getsentry/sentry-go/otel - ``` - - Configure the Sentry and OpenTelemetry SDKs - - ```go - import ( - "go.opentelemetry.io/otel" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - "github.com/getsentry/sentry-go" - "github.com/getsentry/sentry-go/otel" - // ... - ) - - // Initlaize the Sentry SDK - sentry.Init(sentry.ClientOptions{ - Dsn: "__DSN__", - EnableTracing: true, - TracesSampleRate: 1.0, - }) - - // Set up the Sentry span processor - tp := sdktrace.NewTracerProvider( - sdktrace.WithSpanProcessor(sentryotel.NewSentrySpanProcessor()), - // ... - ) - otel.SetTracerProvider(tp) - - // Set up the Sentry propagator - otel.SetTextMapPropagator(sentryotel.NewSentryPropagator()) - ``` - - You can read more about using OpenTelemetry with Sentry in our [docs](https://docs.sentry.io/platforms/go/performance/instrumentation/opentelemetry/). - -### Bug Fixes - -- Do not freeze the Dynamic Sampling Context when no Sentry values are present in the baggage header ([#532](https://github.com/getsentry/sentry-go/pull/532)) -- Create a frozen Dynamic Sampling Context when calling `span.ToBaggage()` ([#566](https://github.com/getsentry/sentry-go/pull/566)) -- Fix baggage parsing and encoding in vendored otel package ([#568](https://github.com/getsentry/sentry-go/pull/568)) - -### Misc - -- Add `Span.SetDynamicSamplingContext()` ([#539](https://github.com/getsentry/sentry-go/pull/539/)) -- Add various getters for `Dsn` ([#540](https://github.com/getsentry/sentry-go/pull/540)) -- Add `SpanOption::SpanSampled` ([#546](https://github.com/getsentry/sentry-go/pull/546)) -- Add `Span.SetData()` ([#542](https://github.com/getsentry/sentry-go/pull/542)) -- Add `Span.IsTransaction()` ([#543](https://github.com/getsentry/sentry-go/pull/543)) -- Add `Span.GetTransaction()` method ([#558](https://github.com/getsentry/sentry-go/pull/558)) - -## 0.17.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.17.0. -This release contains a new `BeforeSendTransaction` hook option and corrects two regressions introduced in `0.16.0`. - -### Features - -- Add `BeforeSendTransaction` hook to `ClientOptions` ([#517](https://github.com/getsentry/sentry-go/pull/517)) - - Here's [an example](https://github.com/getsentry/sentry-go/blob/master/_examples/http/main.go#L56-L66) of how BeforeSendTransaction can be used to modify or drop transaction events. - -### Bug Fixes - -- Do not crash in Span.Finish() when the Client is empty [#520](https://github.com/getsentry/sentry-go/pull/520) - - Fixes [#518](https://github.com/getsentry/sentry-go/issues/518) -- Attach non-PII/non-sensitive request headers to events when `ClientOptions.SendDefaultPii` is set to `false` ([#524](https://github.com/getsentry/sentry-go/pull/524)) - - Fixes [#523](https://github.com/getsentry/sentry-go/issues/523) - -### Misc - -- Clarify how to handle logrus.Fatalf events ([#501](https://github.com/getsentry/sentry-go/pull/501/)) -- Rename the `examples` directory to `_examples` ([#521](https://github.com/getsentry/sentry-go/pull/521)) - - This removes an indirect dependency to `github.com/golang-jwt/jwt` - -## 0.16.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.16.0. -Due to ongoing work towards a stable API for `v1.0.0`, we sadly had to include **two breaking changes** in this release. - -### Breaking Changes - -- Add `EnableTracing`, a boolean option flag to enable performance monitoring (`false` by default). - - If you're using `TracesSampleRate` or `TracesSampler`, this option is **required** to enable performance monitoring. - - ```go - sentry.Init(sentry.ClientOptions{ - EnableTracing: true, - TracesSampleRate: 1.0, - }) - ``` -- Unify TracesSampler [#498](https://github.com/getsentry/sentry-go/pull/498) - - `TracesSampler` was changed to a callback that must return a `float64` between `0.0` and `1.0`. - - For example, you can apply a sample rate of `1.0` (100%) to all `/api` transactions, and a sample rate of `0.5` (50%) to all other transactions. - You can read more about this in our [SDK docs](https://docs.sentry.io/platforms/go/configuration/filtering/#using-sampling-to-filter-transaction-events). - - ```go - sentry.Init(sentry.ClientOptions{ - TracesSampler: sentry.TracesSampler(func(ctx sentry.SamplingContext) float64 { - hub := sentry.GetHubFromContext(ctx.Span.Context()) - name := hub.Scope().Transaction() - - if strings.HasPrefix(name, "GET /api") { - return 1.0 - } - - return 0.5 - }), - } - ``` - -### Features - -- Send errors logged with [Logrus](https://github.com/sirupsen/logrus) to Sentry. - - Have a look at our [logrus examples](https://github.com/getsentry/sentry-go/blob/master/_examples/logrus/main.go) on how to use the integration. -- Add support for Dynamic Sampling [#491](https://github.com/getsentry/sentry-go/pull/491) - - You can read more about Dynamic Sampling in our [product docs](https://docs.sentry.io/product/data-management-settings/dynamic-sampling/). -- Add detailed logging about the reason transactions are being dropped. - - You can enable SDK logging via `sentry.ClientOptions.Debug: true`. - -### Bug Fixes - -- Do not clone the hub when calling `StartTransaction` [#505](https://github.com/getsentry/sentry-go/pull/505) - - Fixes [#502](https://github.com/getsentry/sentry-go/issues/502) - -## 0.15.0 - -- fix: Scope values should not override Event values (#446) -- feat: Make maximum amount of spans configurable (#460) -- feat: Add a method to start a transaction (#482) -- feat: Extend User interface by adding Data, Name and Segment (#483) -- feat: Add ClientOptions.SendDefaultPII (#485) - -## 0.14.0 - -- feat: Add function to continue from trace string (#434) -- feat: Add `max-depth` options (#428) -- *[breaking]* ref: Use a `Context` type mapping to a `map[string]interface{}` for all event contexts (#444) -- *[breaking]* ref: Replace deprecated `ioutil` pkg with `os` & `io` (#454) -- ref: Optimize `stacktrace.go` from size and speed (#467) -- ci: Test against `go1.19` and `go1.18`, drop `go1.16` and `go1.15` support (#432, #477) -- deps: Dependency update to fix CVEs (#462, #464, #477) - -_NOTE:_ This version drops support for Go 1.16 and Go 1.15. The currently supported Go versions are the last 3 stable releases: 1.19, 1.18 and 1.17. - -## v0.13.0 - -- ref: Change DSN ProjectID to be a string (#420) -- fix: When extracting PCs from stack frames, try the `PC` field (#393) -- build: Bump gin-gonic/gin from v1.4.0 to v1.7.7 (#412) -- build: Bump Go version in go.mod (#410) -- ci: Bump golangci-lint version in GH workflow (#419) -- ci: Update GraphQL config with appropriate permissions (#417) -- ci: ci: Add craft release automation (#422) - -## v0.12.0 - -- feat: Automatic Release detection (#363, #369, #386, #400) -- fix: Do not change Hub.lastEventID for transactions (#379) -- fix: Do not clear LastEventID when events are dropped (#382) -- Updates to documentation (#366, #385) - -_NOTE:_ -This version drops support for Go 1.14, however no changes have been made that would make the SDK not work with Go 1.14. The currently supported Go versions are the last 3 stable releases: 1.15, 1.16 and 1.17. -There are two behavior changes related to `LastEventID`, both of which were intended to align the behavior of the Sentry Go SDK with other Sentry SDKs. -The new [automatic release detection feature](https://github.com/getsentry/sentry-go/issues/335) makes it easier to use Sentry and separate events per release without requiring extra work from users. We intend to improve this functionality in a future release by utilizing information that will be available in runtime starting with Go 1.18. The tracking issue is [#401](https://github.com/getsentry/sentry-go/issues/401). - -## v0.11.0 - -- feat(transports): Category-based Rate Limiting ([#354](https://github.com/getsentry/sentry-go/pull/354)) -- feat(transports): Report User-Agent identifying SDK ([#357](https://github.com/getsentry/sentry-go/pull/357)) -- fix(scope): Include event processors in clone ([#349](https://github.com/getsentry/sentry-go/pull/349)) -- Improvements to `go doc` documentation ([#344](https://github.com/getsentry/sentry-go/pull/344), [#350](https://github.com/getsentry/sentry-go/pull/350), [#351](https://github.com/getsentry/sentry-go/pull/351)) -- Miscellaneous changes to our testing infrastructure with GitHub Actions - ([57123a40](https://github.com/getsentry/sentry-go/commit/57123a409be55f61b1d5a6da93c176c55a399ad0), [#128](https://github.com/getsentry/sentry-go/pull/128), [#338](https://github.com/getsentry/sentry-go/pull/338), [#345](https://github.com/getsentry/sentry-go/pull/345), [#346](https://github.com/getsentry/sentry-go/pull/346), [#352](https://github.com/getsentry/sentry-go/pull/352), [#353](https://github.com/getsentry/sentry-go/pull/353), [#355](https://github.com/getsentry/sentry-go/pull/355)) - -_NOTE:_ -This version drops support for Go 1.13. The currently supported Go versions are the last 3 stable releases: 1.14, 1.15 and 1.16. -Users of the tracing functionality (`StartSpan`, etc) should upgrade to this version to benefit from separate rate limits for errors and transactions. -There are no breaking changes and upgrading should be a smooth experience for all users. - -## v0.10.0 - -- feat: Debug connection reuse (#323) -- fix: Send root span data as `Event.Extra` (#329) -- fix: Do not double sample transactions (#328) -- fix: Do not override trace context of transactions (#327) -- fix: Drain and close API response bodies (#322) -- ci: Run tests against Go tip (#319) -- ci: Move away from Travis in favor of GitHub Actions (#314) (#321) - -## v0.9.0 - -- feat: Initial tracing and performance monitoring support (#285) -- doc: Revamp sentryhttp documentation (#304) -- fix: Hub.PopScope never empties the scope stack (#300) -- ref: Report Event.Timestamp in local time (#299) -- ref: Report Breadcrumb.Timestamp in local time (#299) - -_NOTE:_ -This version introduces support for [Sentry's Performance Monitoring](https://docs.sentry.io/platforms/go/performance/). -The new tracing capabilities are beta, and we plan to expand them on future versions. Feedback is welcome, please open new issues on GitHub. -The `sentryhttp` package got better API docs, an [updated usage example](https://github.com/getsentry/sentry-go/tree/master/_examples/http) and support for creating automatic transactions as part of Performance Monitoring. - -## v0.8.0 - -- build: Bump required version of Iris (#296) -- fix: avoid unnecessary allocation in Client.processEvent (#293) -- doc: Remove deprecation of sentryhttp.HandleFunc (#284) -- ref: Update sentryhttp example (#283) -- doc: Improve documentation of sentryhttp package (#282) -- doc: Clarify SampleRate documentation (#279) -- fix: Remove RawStacktrace (#278) -- docs: Add example of custom HTTP transport -- ci: Test against go1.15, drop go1.12 support (#271) - -_NOTE:_ -This version comes with a few updates. Some examples and documentation have been -improved. We've bumped the supported version of the Iris framework to avoid -LGPL-licensed modules in the module dependency graph. -The `Exception.RawStacktrace` and `Thread.RawStacktrace` fields have been -removed to conform to Sentry's ingestion protocol, only `Exception.Stacktrace` -and `Thread.Stacktrace` should appear in user code. - -## v0.7.0 - -- feat: Include original error when event cannot be encoded as JSON (#258) -- feat: Use Hub from request context when available (#217, #259) -- feat: Extract stack frames from golang.org/x/xerrors (#262) -- feat: Make Environment Integration preserve existing context data (#261) -- feat: Recover and RecoverWithContext with arbitrary types (#268) -- feat: Report bad usage of CaptureMessage and CaptureEvent (#269) -- feat: Send debug logging to stderr by default (#266) -- feat: Several improvements to documentation (#223, #245, #250, #265) -- feat: Example of Recover followed by panic (#241, #247) -- feat: Add Transactions and Spans (to support OpenTelemetry Sentry Exporter) (#235, #243, #254) -- fix: Set either Frame.Filename or Frame.AbsPath (#233) -- fix: Clone requestBody to new Scope (#244) -- fix: Synchronize access and mutation of Hub.lastEventID (#264) -- fix: Avoid repeated syscalls in prepareEvent (#256) -- fix: Do not allocate new RNG for every event (#256) -- fix: Remove stale replace directive in go.mod (#255) -- fix(http): Deprecate HandleFunc, remove duplication (#260) - -_NOTE:_ -This version comes packed with several fixes and improvements and no breaking -changes. -Notably, there is a change in how the SDK reports file names in stack traces -that should resolve any ambiguity when looking at stack traces and using the -Suspect Commits feature. -We recommend all users to upgrade. - -## v0.6.1 - -- fix: Use NewEvent to init Event struct (#220) - -_NOTE:_ -A change introduced in v0.6.0 with the intent of avoiding allocations made a -pattern used in official examples break in certain circumstances (attempting -to write to a nil map). -This release reverts the change such that maps in the Event struct are always -allocated. - -## v0.6.0 - -- feat: Read module dependencies from runtime/debug (#199) -- feat: Support chained errors using Unwrap (#206) -- feat: Report chain of errors when available (#185) -- **[breaking]** fix: Accept http.RoundTripper to customize transport (#205) - Before the SDK accepted a concrete value of type `*http.Transport` in - `ClientOptions`, now it accepts any value implementing the `http.RoundTripper` - interface. Note that `*http.Transport` implements `http.RoundTripper`, so most - code bases will continue to work unchanged. - Users of custom transport gain the ability to pass in other implementations of - `http.RoundTripper` and may be able to simplify their code bases. -- fix: Do not panic when scope event processor drops event (#192) -- **[breaking]** fix: Use time.Time for timestamps (#191) - Users of sentry-go typically do not need to manipulate timestamps manually. - For those who do, the field type changed from `int64` to `time.Time`, which - should be more convenient to use. The recommended way to get the current time - is `time.Now().UTC()`. -- fix: Report usage error including stack trace (#189) -- feat: Add Exception.ThreadID field (#183) -- ci: Test against Go 1.14, drop 1.11 (#170) -- feat: Limit reading bytes from request bodies (#168) -- **[breaking]** fix: Rename fasthttp integration package sentryhttp => sentryfasthttp - The current recommendation is to use a named import, in which case existing - code should not require any change: - ```go - package main - - import ( - "fmt" - - "github.com/getsentry/sentry-go" - sentryfasthttp "github.com/getsentry/sentry-go/fasthttp" - "github.com/valyala/fasthttp" - ) - ``` - -_NOTE:_ -This version includes some new features and a few breaking changes, none of -which should pose troubles with upgrading. Most code bases should be able to -upgrade without any changes. - -## v0.5.1 - -- fix: Ignore err.Cause() when it is nil (#160) - -## v0.5.0 - -- fix: Synchronize access to HTTPTransport.disabledUntil (#158) -- docs: Update Flush documentation (#153) -- fix: HTTPTransport.Flush panic and data race (#140) - -_NOTE:_ -This version changes the implementation of the default transport, modifying the -behavior of `sentry.Flush`. The previous behavior was to wait until there were -no buffered events; new concurrent events kept `Flush` from returning. The new -behavior is to wait until the last event prior to the call to `Flush` has been -sent or the timeout; new concurrent events have no effect. The new behavior is -inline with the [Unified API -Guidelines](https://docs.sentry.io/development/sdk-dev/unified-api/). - -We have updated the documentation and examples to clarify that `Flush` is meant -to be called typically only once before program termination, to wait for -in-flight events to be sent to Sentry. Calling `Flush` after every event is not -recommended, as it introduces unnecessary latency to the surrounding function. -Please verify the usage of `sentry.Flush` in your code base. - -## v0.4.0 - -- fix(stacktrace): Correctly report package names (#127) -- fix(stacktrace): Do not rely on AbsPath of files (#123) -- build: Require github.com/ugorji/go@v1.1.7 (#110) -- fix: Correctly store last event id (#99) -- fix: Include request body in event payload (#94) -- build: Reset go.mod version to 1.11 (#109) -- fix: Eliminate data race in modules integration (#105) -- feat: Add support for path prefixes in the DSN (#102) -- feat: Add HTTPClient option (#86) -- feat: Extract correct type and value from top-most error (#85) -- feat: Check for broken pipe errors in Gin integration (#82) -- fix: Client.CaptureMessage accept nil EventModifier (#72) - -## v0.3.1 - -- feat: Send extra information exposed by the Go runtime (#76) -- fix: Handle new lines in module integration (#65) -- fix: Make sure that cache is locked when updating for contextifyFramesIntegration -- ref: Update Iris integration and example to version 12 -- misc: Remove indirect dependencies in order to move them to separate go.mod files - -## v0.3.0 - -- feat: Retry event marshaling without contextual data if the first pass fails -- fix: Include `url.Parse` error in `DsnParseError` -- fix: Make more `Scope` methods safe for concurrency -- fix: Synchronize concurrent access to `Hub.client` -- ref: Remove mutex from `Scope` exported API -- ref: Remove mutex from `Hub` exported API -- ref: Compile regexps for `filterFrames` only once -- ref: Change `SampleRate` type to `float64` -- doc: `Scope.Clear` not safe for concurrent use -- ci: Test sentry-go with `go1.13`, drop `go1.10` - -_NOTE:_ -This version removes some of the internal APIs that landed publicly (namely `Hub/Scope` mutex structs) and may require (but shouldn't) some changes to your code. -It's not done through major version update, as we are still in `0.x` stage. - -## v0.2.1 - -- fix: Run `Contextify` integration on `Threads` as well - -## v0.2.0 - -- feat: Add `SetTransaction()` method on the `Scope` -- feat: `fasthttp` framework support with `sentryfasthttp` package -- fix: Add `RWMutex` locks to internal `Hub` and `Scope` changes - -## v0.1.3 - -- feat: Move frames context reading into `contextifyFramesIntegration` (#28) - -_NOTE:_ -In case of any performance issues due to source contexts IO, you can let us know and turn off the integration in the meantime with: - -```go -sentry.Init(sentry.ClientOptions{ - Integrations: func(integrations []sentry.Integration) []sentry.Integration { - var filteredIntegrations []sentry.Integration - for _, integration := range integrations { - if integration.Name() == "ContextifyFrames" { - continue - } - filteredIntegrations = append(filteredIntegrations, integration) - } - return filteredIntegrations - }, -}) -``` - -## v0.1.2 - -- feat: Better source code location resolution and more useful inapp frames (#26) -- feat: Use `noopTransport` when no `Dsn` provided (#27) -- ref: Allow empty `Dsn` instead of returning an error (#22) -- fix: Use `NewScope` instead of literal struct inside a `scope.Clear` call (#24) -- fix: Add to `WaitGroup` before the request is put inside a buffer (#25) - -## v0.1.1 - -- fix: Check for initialized `Client` in `AddBreadcrumbs` (#20) -- build: Bump version when releasing with Craft (#19) - -## v0.1.0 - -- First stable release! \o/ - -## v0.0.1-beta.5 - -- feat: **[breaking]** Add `NewHTTPTransport` and `NewHTTPSyncTransport` which accepts all transport options -- feat: New `HTTPSyncTransport` that blocks after each call -- feat: New `Echo` integration -- ref: **[breaking]** Remove `BufferSize` option from `ClientOptions` and move it to `HTTPTransport` instead -- ref: Export default `HTTPTransport` -- ref: Export `net/http` integration handler -- ref: Set `Request` instantly in the package handlers, not in `recoverWithSentry` so it can be accessed later on -- ci: Add craft config - -## v0.0.1-beta.4 - -- feat: `IgnoreErrors` client option and corresponding integration -- ref: Reworked `net/http` integration, wrote better example and complete readme -- ref: Reworked `Gin` integration, wrote better example and complete readme -- ref: Reworked `Iris` integration, wrote better example and complete readme -- ref: Reworked `Negroni` integration, wrote better example and complete readme -- ref: Reworked `Martini` integration, wrote better example and complete readme -- ref: Remove `Handle()` from frameworks handlers and return it directly from New - -## v0.0.1-beta.3 - -- feat: `Iris` framework support with `sentryiris` package -- feat: `Gin` framework support with `sentrygin` package -- feat: `Martini` framework support with `sentrymartini` package -- feat: `Negroni` framework support with `sentrynegroni` package -- feat: Add `Hub.Clone()` for easier frameworks integration -- feat: Return `EventID` from `Recovery` methods -- feat: Add `NewScope` and `NewEvent` functions and use them in the whole codebase -- feat: Add `AddEventProcessor` to the `Client` -- fix: Operate on requests body copy instead of the original -- ref: Try to read source files from the root directory, based on the filename as well, to make it work on AWS Lambda -- ref: Remove `gocertifi` dependence and document how to provide your own certificates -- ref: **[breaking]** Remove `Decorate` and `DecorateFunc` methods in favor of `sentryhttp` package -- ref: **[breaking]** Allow for integrations to live on the client, by passing client instance in `SetupOnce` method -- ref: **[breaking]** Remove `GetIntegration` from the `Hub` -- ref: **[breaking]** Remove `GlobalEventProcessors` getter from the public API - -## v0.0.1-beta.2 - -- feat: Add `AttachStacktrace` client option to include stacktrace for messages -- feat: Add `BufferSize` client option to configure transport buffer size -- feat: Add `SetRequest` method on a `Scope` to control `Request` context data -- feat: Add `FromHTTPRequest` for `Request` type for easier extraction -- ref: Extract `Request` information more accurately -- fix: Attach `ServerName`, `Release`, `Dist`, `Environment` options to the event -- fix: Don't log events dropped due to full transport buffer as sent -- fix: Don't panic and create an appropriate event when called `CaptureException` or `Recover` with `nil` value - -## v0.0.1-beta - -- Initial release diff --git a/vendor/github.com/getsentry/sentry-go/CONTRIBUTING.md b/vendor/github.com/getsentry/sentry-go/CONTRIBUTING.md deleted file mode 100644 index 9808f1862..000000000 --- a/vendor/github.com/getsentry/sentry-go/CONTRIBUTING.md +++ /dev/null @@ -1,98 +0,0 @@ -# Contributing to sentry-go - -Hey, thank you if you're reading this, we welcome your contribution! - -## Sending a Pull Request - -Please help us save time when reviewing your PR by following this simple -process: - -1. Is your PR a simple typo fix? Read no further, **click that green "Create - pull request" button**! - -2. For more complex PRs that involve behavior changes or new APIs, please - consider [opening an **issue**][new-issue] describing the problem you're - trying to solve if there's not one already. - - A PR is often one specific solution to a problem and sometimes talking about - the problem unfolds new possible solutions. Remember we will be responsible - for maintaining the changes later. - -3. Fixing a bug and changing a behavior? Please add automated tests to prevent - future regression. - -4. Practice writing good commit messages. We have [commit - guidelines][commit-guide]. - -5. We have [guidelines for PR submitters][pr-guide]. A short summary: - - - Good PR descriptions are very helpful and most of the time they include - **why** something is done and why done in this particular way. Also list - other possible solutions that were considered and discarded. - - Be your own first reviewer. Make sure your code compiles and passes the - existing tests. - -[new-issue]: https://github.com/getsentry/sentry-go/issues/new/choose -[commit-guide]: https://develop.sentry.dev/code-review/#commit-guidelines -[pr-guide]: https://develop.sentry.dev/code-review/#guidelines-for-submitters - -Please also read through our [SDK Development docs](https://develop.sentry.dev/sdk/). -It contains information about SDK features, expected payloads and best practices for -contributing to Sentry SDKs. - -## Community - -The public-facing channels for support and development of Sentry SDKs can be found on [Discord](https://discord.gg/Ww9hbqr). - -## Testing - -```console -$ go test -``` - -### Watch mode - -Use: https://github.com/cespare/reflex - -```console -$ reflex -g '*.go' -d "none" -- sh -c 'printf "\n"; go test' -``` - -### With data race detection - -```console -$ go test -race -``` - -### Coverage - -```console -$ go test -race -coverprofile=coverage.txt -covermode=atomic && go tool cover -html coverage.txt -``` - -## Linting - -Lint with [`golangci-lint`](https://github.com/golangci/golangci-lint): - -```console -$ golangci-lint run -``` - -## Release - -1. Update `CHANGELOG.md` with new version in `vX.X.X` format title and list of changes. - - The command below can be used to get a list of changes since the last tag, with the format used in `CHANGELOG.md`: - - ```console - $ git log --no-merges --format=%s $(git describe --abbrev=0).. | sed 's/^/- /' - ``` - -2. Commit with `misc: vX.X.X changelog` commit message and push to `master`. - -3. Let [`craft`](https://github.com/getsentry/craft) do the rest: - - ```console - $ craft prepare X.X.X - $ craft publish X.X.X - ``` diff --git a/vendor/github.com/getsentry/sentry-go/LICENSE b/vendor/github.com/getsentry/sentry-go/LICENSE deleted file mode 100644 index b1b358e41..000000000 --- a/vendor/github.com/getsentry/sentry-go/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Functional Software, Inc. dba Sentry - -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/getsentry/sentry-go/MIGRATION.md b/vendor/github.com/getsentry/sentry-go/MIGRATION.md deleted file mode 100644 index 2c30d6288..000000000 --- a/vendor/github.com/getsentry/sentry-go/MIGRATION.md +++ /dev/null @@ -1,3 +0,0 @@ -# `raven-go` to `sentry-go` Migration Guide - -A [`raven-go` to `sentry-go` migration guide](https://docs.sentry.io/platforms/go/migration/) is available at the official Sentry documentation site. diff --git a/vendor/github.com/getsentry/sentry-go/Makefile b/vendor/github.com/getsentry/sentry-go/Makefile deleted file mode 100644 index 89523ac0c..000000000 --- a/vendor/github.com/getsentry/sentry-go/Makefile +++ /dev/null @@ -1,83 +0,0 @@ -.DEFAULT_GOAL := help - -MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -MKFILE_DIR := $(dir $(MKFILE_PATH)) -ALL_GO_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | sort) -GO = go -TIMEOUT = 300 - -# Parse Makefile and display the help -help: ## Show help - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' -.PHONY: help - -build: ## Build everything - for dir in $(ALL_GO_MOD_DIRS); do \ - cd "$${dir}"; \ - echo ">>> Running 'go build' for module: $${dir}"; \ - go build ./...; \ - done; -.PHONY: build - -### Tests (inspired by https://github.com/open-telemetry/opentelemetry-go/blob/main/Makefile) -TEST_TARGETS := test-short test-verbose test-race -test-race: ARGS=-race -test-short: ARGS=-short -test-verbose: ARGS=-v -race -$(TEST_TARGETS): test -test: $(ALL_GO_MOD_DIRS:%=test/%) ## Run tests -test/%: DIR=$* -test/%: - @echo ">>> Running tests for module: $(DIR)" - @# We use '-count=1' to disable test caching. - (cd $(DIR) && $(GO) test -count=1 -timeout $(TIMEOUT)s $(ARGS) ./...) -.PHONY: $(TEST_TARGETS) test - -# Coverage -COVERAGE_MODE = atomic -COVERAGE_PROFILE = coverage.out -COVERAGE_REPORT_DIR = .coverage -COVERAGE_REPORT_DIR_ABS = "$(MKFILE_DIR)/$(COVERAGE_REPORT_DIR)" -$(COVERAGE_REPORT_DIR): - mkdir -p $(COVERAGE_REPORT_DIR) -clean-report-dir: $(COVERAGE_REPORT_DIR) - test $(COVERAGE_REPORT_DIR) && rm -f $(COVERAGE_REPORT_DIR)/* -test-coverage: $(COVERAGE_REPORT_DIR) clean-report-dir ## Test with coverage enabled - set -e ; \ - for dir in $(ALL_GO_MOD_DIRS); do \ - echo ">>> Running tests with coverage for module: $${dir}"; \ - DIR_ABS=$$(python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' $${dir}) ; \ - REPORT_NAME=$$(basename $${DIR_ABS}); \ - (cd "$${dir}" && \ - $(GO) test -count=1 -timeout $(TIMEOUT)s -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" ./... && \ - cp $(COVERAGE_PROFILE) "$(COVERAGE_REPORT_DIR_ABS)/$${REPORT_NAME}_$(COVERAGE_PROFILE)" && \ - $(GO) tool cover -html=$(COVERAGE_PROFILE) -o coverage.html); \ - done; -.PHONY: test-coverage clean-report-dir - -mod-tidy: ## Check go.mod tidiness - set -e ; \ - for dir in $(ALL_GO_MOD_DIRS); do \ - cd "$${dir}"; \ - echo ">>> Running 'go mod tidy' for module: $${dir}"; \ - go mod tidy -go=1.18 -compat=1.18; \ - done; \ - git diff --exit-code; -.PHONY: mod-tidy - -vet: ## Run "go vet" - set -e ; \ - for dir in $(ALL_GO_MOD_DIRS); do \ - cd "$${dir}"; \ - echo ">>> Running 'go vet' for module: $${dir}"; \ - go vet ./...; \ - done; -.PHONY: vet - -lint: ## Lint (using "golangci-lint") - golangci-lint run -.PHONY: lint - -fmt: ## Format all Go files - gofmt -l -w -s . -.PHONY: fmt diff --git a/vendor/github.com/getsentry/sentry-go/README.md b/vendor/github.com/getsentry/sentry-go/README.md deleted file mode 100644 index 3b67fb45a..000000000 --- a/vendor/github.com/getsentry/sentry-go/README.md +++ /dev/null @@ -1,102 +0,0 @@ -

- - - - - Sentry - - -

- -# Official Sentry SDK for Go - -[![Build Status](https://github.com/getsentry/sentry-go/workflows/go-workflow/badge.svg)](https://github.com/getsentry/sentry-go/actions?query=workflow%3Ago-workflow) -[![Go Report Card](https://goreportcard.com/badge/github.com/getsentry/sentry-go)](https://goreportcard.com/report/github.com/getsentry/sentry-go) -[![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr) -[![go.dev](https://img.shields.io/badge/go.dev-pkg-007d9c.svg?style=flat)](https://pkg.go.dev/github.com/getsentry/sentry-go) - -`sentry-go` provides a Sentry client implementation for the Go programming -language. This is the next generation of the Go SDK for [Sentry](https://sentry.io/), -intended to replace the `raven-go` package. - -> Looking for the old `raven-go` SDK documentation? See the Legacy client section [here](https://docs.sentry.io/clients/go/). -> If you want to start using `sentry-go` instead, check out the [migration guide](https://docs.sentry.io/platforms/go/migration/). - -## Requirements - -The only requirement is a Go compiler. - -We verify this package against the 3 most recent releases of Go. Those are the -supported versions. The exact versions are defined in -[`GitHub workflow`](.github/workflows/test.yml). - -In addition, we run tests against the current master branch of the Go toolchain, -though support for this configuration is best-effort. - -## Installation - -`sentry-go` can be installed like any other Go library through `go get`: - -```console -$ go get github.com/getsentry/sentry-go@latest -``` - -Check out the [list of released versions](https://github.com/getsentry/sentry-go/releases). - -## Configuration - -To use `sentry-go`, you’ll need to import the `sentry-go` package and initialize -it with your DSN and other [options](https://pkg.go.dev/github.com/getsentry/sentry-go#ClientOptions). - -If not specified in the SDK initialization, the -[DSN](https://docs.sentry.io/product/sentry-basics/dsn-explainer/), -[Release](https://docs.sentry.io/product/releases/) and -[Environment](https://docs.sentry.io/product/sentry-basics/environments/) -are read from the environment variables `SENTRY_DSN`, `SENTRY_RELEASE` and -`SENTRY_ENVIRONMENT`, respectively. - -More on this in the [Configuration section of the official Sentry Go SDK documentation](https://docs.sentry.io/platforms/go/configuration/). - -## Usage - -The SDK supports reporting errors and tracking application performance. - -To get started, have a look at one of our [examples](_examples/): -- [Basic error instrumentation](_examples/basic/main.go) -- [Error and tracing for HTTP servers](_examples/http/main.go) - -We also provide a [complete API reference](https://pkg.go.dev/github.com/getsentry/sentry-go). - -For more detailed information about how to get the most out of `sentry-go`, -checkout the official documentation: - -- [Sentry Go SDK documentation](https://docs.sentry.io/platforms/go/) -- Guides: - - [net/http](https://docs.sentry.io/platforms/go/guides/http/) - - [echo](https://docs.sentry.io/platforms/go/guides/echo/) - - [fasthttp](https://docs.sentry.io/platforms/go/guides/fasthttp/) - - [gin](https://docs.sentry.io/platforms/go/guides/gin/) - - [iris](https://docs.sentry.io/platforms/go/guides/iris/) - - [negroni](https://docs.sentry.io/platforms/go/guides/negroni/) - -## Resources - -- [Bug Tracker](https://github.com/getsentry/sentry-go/issues) -- [GitHub Project](https://github.com/getsentry/sentry-go) -- [![go.dev](https://img.shields.io/badge/go.dev-pkg-007d9c.svg?style=flat)](https://pkg.go.dev/github.com/getsentry/sentry-go) -- [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/go/) -- [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-go.svg)](https://github.com/getsentry/sentry-go/discussions) -- [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr) -- [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](http://stackoverflow.com/questions/tagged/sentry) -- [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) - -## License - -Licensed under -[The MIT License](https://opensource.org/licenses/mit/), see -[`LICENSE`](LICENSE). - -## Community - -Join Sentry's [`#go` channel on Discord](https://discord.gg/Ww9hbqr) to get -involved and help us improve the SDK! diff --git a/vendor/github.com/getsentry/sentry-go/check_in.go b/vendor/github.com/getsentry/sentry-go/check_in.go deleted file mode 100644 index de6d0adb6..000000000 --- a/vendor/github.com/getsentry/sentry-go/check_in.go +++ /dev/null @@ -1,121 +0,0 @@ -package sentry - -import "time" - -type CheckInStatus string - -const ( - CheckInStatusInProgress CheckInStatus = "in_progress" - CheckInStatusOK CheckInStatus = "ok" - CheckInStatusError CheckInStatus = "error" -) - -type checkInScheduleType string - -const ( - checkInScheduleTypeCrontab checkInScheduleType = "crontab" - checkInScheduleTypeInterval checkInScheduleType = "interval" -) - -type MonitorSchedule interface { - // scheduleType is a private method that must be implemented for monitor schedule - // implementation. It should never be called. This method is made for having - // specific private implementation of MonitorSchedule interface. - scheduleType() checkInScheduleType -} - -type crontabSchedule struct { - Type string `json:"type"` - Value string `json:"value"` -} - -func (c crontabSchedule) scheduleType() checkInScheduleType { - return checkInScheduleTypeCrontab -} - -// CrontabSchedule defines the MonitorSchedule with a cron format. -// Example: "8 * * * *". -func CrontabSchedule(scheduleString string) MonitorSchedule { - return crontabSchedule{ - Type: string(checkInScheduleTypeCrontab), - Value: scheduleString, - } -} - -type intervalSchedule struct { - Type string `json:"type"` - Value int64 `json:"value"` - Unit string `json:"unit"` -} - -func (i intervalSchedule) scheduleType() checkInScheduleType { - return checkInScheduleTypeInterval -} - -type MonitorScheduleUnit string - -const ( - MonitorScheduleUnitMinute MonitorScheduleUnit = "minute" - MonitorScheduleUnitHour MonitorScheduleUnit = "hour" - MonitorScheduleUnitDay MonitorScheduleUnit = "day" - MonitorScheduleUnitWeek MonitorScheduleUnit = "week" - MonitorScheduleUnitMonth MonitorScheduleUnit = "month" - MonitorScheduleUnitYear MonitorScheduleUnit = "year" -) - -// IntervalSchedule defines the MonitorSchedule with an interval format. -// -// Example: -// -// IntervalSchedule(1, sentry.MonitorScheduleUnitDay) -func IntervalSchedule(value int64, unit MonitorScheduleUnit) MonitorSchedule { - return intervalSchedule{ - Type: string(checkInScheduleTypeInterval), - Value: value, - Unit: string(unit), - } -} - -type MonitorConfig struct { //nolint: maligned // prefer readability over optimal memory layout - Schedule MonitorSchedule `json:"schedule,omitempty"` - // The allowed margin of minutes after the expected check-in time that - // the monitor will not be considered missed for. - CheckInMargin int64 `json:"checkin_margin,omitempty"` - // The allowed duration in minutes that the monitor may be `in_progress` - // for before being considered failed due to timeout. - MaxRuntime int64 `json:"max_runtime,omitempty"` - // A tz database string representing the timezone which the monitor's execution schedule is in. - // See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones - Timezone string `json:"timezone,omitempty"` - // The number of consecutive failed check-ins it takes before an issue is created. - FailureIssueThreshold int64 `json:"failure_issue_threshold,omitempty"` - // The number of consecutive OK check-ins it takes before an issue is resolved. - RecoveryThreshold int64 `json:"recovery_threshold,omitempty"` -} - -type CheckIn struct { //nolint: maligned // prefer readability over optimal memory layout - // Check-In ID (unique and client generated) - ID EventID `json:"check_in_id"` - // The distinct slug of the monitor. - MonitorSlug string `json:"monitor_slug"` - // The status of the check-in. - Status CheckInStatus `json:"status"` - // The duration of the check-in. Will only take effect if the status is ok or error. - Duration time.Duration `json:"duration,omitempty"` -} - -// serializedCheckIn is used by checkInMarshalJSON method on Event struct. -// See https://develop.sentry.dev/sdk/check-ins/ -type serializedCheckIn struct { //nolint: maligned - // Check-In ID (unique and client generated). - CheckInID string `json:"check_in_id"` - // The distinct slug of the monitor. - MonitorSlug string `json:"monitor_slug"` - // The status of the check-in. - Status CheckInStatus `json:"status"` - // The duration of the check-in in seconds. Will only take effect if the status is ok or error. - Duration float64 `json:"duration,omitempty"` - Release string `json:"release,omitempty"` - Environment string `json:"environment,omitempty"` - MonitorConfig *MonitorConfig `json:"monitor_config,omitempty"` -} diff --git a/vendor/github.com/getsentry/sentry-go/client.go b/vendor/github.com/getsentry/sentry-go/client.go deleted file mode 100644 index b5b11b31d..000000000 --- a/vendor/github.com/getsentry/sentry-go/client.go +++ /dev/null @@ -1,740 +0,0 @@ -package sentry - -import ( - "context" - "crypto/x509" - "fmt" - "io" - "log" - "math/rand" - "net/http" - "os" - "sort" - "strings" - "sync" - "time" - - "github.com/getsentry/sentry-go/internal/debug" -) - -// The identifier of the SDK. -const sdkIdentifier = "sentry.go" - -// maxErrorDepth is the maximum number of errors reported in a chain of errors. -// This protects the SDK from an arbitrarily long chain of wrapped errors. -// -// An additional consideration is that arguably reporting a long chain of errors -// is of little use when debugging production errors with Sentry. The Sentry UI -// is not optimized for long chains either. The top-level error together with a -// stack trace is often the most useful information. -const maxErrorDepth = 10 - -// defaultMaxSpans limits the default number of recorded spans per transaction. The limit is -// meant to bound memory usage and prevent too large transaction events that -// would be rejected by Sentry. -const defaultMaxSpans = 1000 - -// hostname is the host name reported by the kernel. It is precomputed once to -// avoid syscalls when capturing events. -// -// The error is ignored because retrieving the host name is best-effort. If the -// error is non-nil, there is nothing to do other than retrying. We choose not -// to retry for now. -var hostname, _ = os.Hostname() - -// lockedRand is a random number generator safe for concurrent use. Its API is -// intentionally limited and it is not meant as a full replacement for a -// rand.Rand. -type lockedRand struct { - mu sync.Mutex - r *rand.Rand -} - -// Float64 returns a pseudo-random number in [0.0,1.0). -func (r *lockedRand) Float64() float64 { - r.mu.Lock() - defer r.mu.Unlock() - return r.r.Float64() -} - -// rng is the internal random number generator. -// -// We do not use the global functions from math/rand because, while they are -// safe for concurrent use, any package in a build could change the seed and -// affect the generated numbers, for instance making them deterministic. On the -// other hand, the source returned from rand.NewSource is not safe for -// concurrent use, so we need to couple its use with a sync.Mutex. -var rng = &lockedRand{ - // #nosec G404 -- We are fine using transparent, non-secure value here. - r: rand.New(rand.NewSource(time.Now().UnixNano())), -} - -// usageError is used to report to Sentry an SDK usage error. -// -// It is not exported because it is never returned by any function or method in -// the exported API. -type usageError struct { - error -} - -// Logger is an instance of log.Logger that is use to provide debug information about running Sentry Client -// can be enabled by either using Logger.SetOutput directly or with Debug client option. -var Logger = log.New(io.Discard, "[Sentry] ", log.LstdFlags) - -// EventProcessor is a function that processes an event. -// Event processors are used to change an event before it is sent to Sentry. -type EventProcessor func(event *Event, hint *EventHint) *Event - -// EventModifier is the interface that wraps the ApplyToEvent method. -// -// ApplyToEvent changes an event based on external data and/or -// an event hint. -type EventModifier interface { - ApplyToEvent(event *Event, hint *EventHint, client *Client) *Event -} - -var globalEventProcessors []EventProcessor - -// AddGlobalEventProcessor adds processor to the global list of event -// processors. Global event processors apply to all events. -// -// AddGlobalEventProcessor is deprecated. Most users will prefer to initialize -// the SDK with Init and provide a ClientOptions.BeforeSend function or use -// Scope.AddEventProcessor instead. -func AddGlobalEventProcessor(processor EventProcessor) { - globalEventProcessors = append(globalEventProcessors, processor) -} - -// Integration allows for registering a functions that modify or discard captured events. -type Integration interface { - Name() string - SetupOnce(client *Client) -} - -// ClientOptions that configures a SDK Client. -type ClientOptions struct { - // The DSN to use. If the DSN is not set, the client is effectively - // disabled. - Dsn string - // In debug mode, the debug information is printed to stdout to help you - // understand what sentry is doing. - Debug bool - // Configures whether SDK should generate and attach stacktraces to pure - // capture message calls. - AttachStacktrace bool - // The sample rate for event submission in the range [0.0, 1.0]. By default, - // all events are sent. Thus, as a historical special case, the sample rate - // 0.0 is treated as if it was 1.0. To drop all events, set the DSN to the - // empty string. - SampleRate float64 - // Enable performance tracing. - EnableTracing bool - // The sample rate for sampling traces in the range [0.0, 1.0]. - TracesSampleRate float64 - // Used to customize the sampling of traces, overrides TracesSampleRate. - TracesSampler TracesSampler - // The sample rate for profiling traces in the range [0.0, 1.0]. - // This is relative to TracesSampleRate - it is a ratio of profiled traces out of all sampled traces. - ProfilesSampleRate float64 - // List of regexp strings that will be used to match against event's message - // and if applicable, caught errors type and value. - // If the match is found, then a whole event will be dropped. - IgnoreErrors []string - // List of regexp strings that will be used to match against a transaction's - // name. If a match is found, then the transaction will be dropped. - IgnoreTransactions []string - // If this flag is enabled, certain personally identifiable information (PII) is added by active integrations. - // By default, no such data is sent. - SendDefaultPII bool - // BeforeSend is called before error events are sent to Sentry. - // Use it to mutate the event or return nil to discard the event. - BeforeSend func(event *Event, hint *EventHint) *Event - // BeforeSendTransaction is called before transaction events are sent to Sentry. - // Use it to mutate the transaction or return nil to discard the transaction. - BeforeSendTransaction func(event *Event, hint *EventHint) *Event - // Before breadcrumb add callback. - BeforeBreadcrumb func(breadcrumb *Breadcrumb, hint *BreadcrumbHint) *Breadcrumb - // Integrations to be installed on the current Client, receives default - // integrations. - Integrations func([]Integration) []Integration - // io.Writer implementation that should be used with the Debug mode. - DebugWriter io.Writer - // The transport to use. Defaults to HTTPTransport. - Transport Transport - // The server name to be reported. - ServerName string - // The release to be sent with events. - // - // Some Sentry features are built around releases, and, thus, reporting - // events with a non-empty release improves the product experience. See - // https://docs.sentry.io/product/releases/. - // - // If Release is not set, the SDK will try to derive a default value - // from environment variables or the Git repository in the working - // directory. - // - // If you distribute a compiled binary, it is recommended to set the - // Release value explicitly at build time. As an example, you can use: - // - // go build -ldflags='-X main.release=VALUE' - // - // That will set the value of a predeclared variable 'release' in the - // 'main' package to 'VALUE'. Then, use that variable when initializing - // the SDK: - // - // sentry.Init(ClientOptions{Release: release}) - // - // See https://golang.org/cmd/go/ and https://golang.org/cmd/link/ for - // the official documentation of -ldflags and -X, respectively. - Release string - // The dist to be sent with events. - Dist string - // The environment to be sent with events. - Environment string - // Maximum number of breadcrumbs - // when MaxBreadcrumbs is negative then ignore breadcrumbs. - MaxBreadcrumbs int - // Maximum number of spans. - // - // See https://develop.sentry.dev/sdk/envelopes/#size-limits for size limits - // applied during event ingestion. Events that exceed these limits might get dropped. - MaxSpans int - // An optional pointer to http.Client that will be used with a default - // HTTPTransport. Using your own client will make HTTPTransport, HTTPProxy, - // HTTPSProxy and CaCerts options ignored. - HTTPClient *http.Client - // An optional pointer to http.Transport that will be used with a default - // HTTPTransport. Using your own transport will make HTTPProxy, HTTPSProxy - // and CaCerts options ignored. - HTTPTransport http.RoundTripper - // An optional HTTP proxy to use. - // This will default to the HTTP_PROXY environment variable. - HTTPProxy string - // An optional HTTPS proxy to use. - // This will default to the HTTPS_PROXY environment variable. - // HTTPS_PROXY takes precedence over HTTP_PROXY for https requests. - HTTPSProxy string - // An optional set of SSL certificates to use. - CaCerts *x509.CertPool - // MaxErrorDepth is the maximum number of errors reported in a chain of errors. - // This protects the SDK from an arbitrarily long chain of wrapped errors. - // - // An additional consideration is that arguably reporting a long chain of errors - // is of little use when debugging production errors with Sentry. The Sentry UI - // is not optimized for long chains either. The top-level error together with a - // stack trace is often the most useful information. - MaxErrorDepth int - // Default event tags. These are overridden by tags set on a scope. - Tags map[string]string -} - -// Client is the underlying processor that is used by the main API and Hub -// instances. It must be created with NewClient. -type Client struct { - mu sync.RWMutex - options ClientOptions - dsn *Dsn - eventProcessors []EventProcessor - integrations []Integration - sdkIdentifier string - sdkVersion string - // Transport is read-only. Replacing the transport of an existing client is - // not supported, create a new client instead. - Transport Transport -} - -// NewClient creates and returns an instance of Client configured using -// ClientOptions. -// -// Most users will not create clients directly. Instead, initialize the SDK with -// Init and use the package-level functions (for simple programs that run on a -// single goroutine) or hub methods (for concurrent programs, for example web -// servers). -func NewClient(options ClientOptions) (*Client, error) { - // The default error event sample rate for all SDKs is 1.0 (send all). - // - // In Go, the zero value (default) for float64 is 0.0, which means that - // constructing a client with NewClient(ClientOptions{}), or, equivalently, - // initializing the SDK with Init(ClientOptions{}) without an explicit - // SampleRate would drop all events. - // - // To retain the desired default behavior, we exceptionally flip SampleRate - // from 0.0 to 1.0 here. Setting the sample rate to 0.0 is not very useful - // anyway, and the same end result can be achieved in many other ways like - // not initializing the SDK, setting the DSN to the empty string or using an - // event processor that always returns nil. - // - // An alternative API could be such that default options don't need to be - // the same as Go's zero values, for example using the Functional Options - // pattern. That would either require a breaking change if we want to reuse - // the obvious NewClient name, or a new function as an alternative - // constructor. - if options.SampleRate == 0.0 { - options.SampleRate = 1.0 - } - - if options.Debug { - debugWriter := options.DebugWriter - if debugWriter == nil { - debugWriter = os.Stderr - } - Logger.SetOutput(debugWriter) - } - - if options.Dsn == "" { - options.Dsn = os.Getenv("SENTRY_DSN") - } - - if options.Release == "" { - options.Release = defaultRelease() - } - - if options.Environment == "" { - options.Environment = os.Getenv("SENTRY_ENVIRONMENT") - } - - if options.MaxErrorDepth == 0 { - options.MaxErrorDepth = maxErrorDepth - } - - if options.MaxSpans == 0 { - options.MaxSpans = defaultMaxSpans - } - - // SENTRYGODEBUG is a comma-separated list of key=value pairs (similar - // to GODEBUG). It is not a supported feature: recognized debug options - // may change any time. - // - // The intended public is SDK developers. It is orthogonal to - // options.Debug, which is also available for SDK users. - dbg := strings.Split(os.Getenv("SENTRYGODEBUG"), ",") - sort.Strings(dbg) - // dbgOpt returns true when the given debug option is enabled, for - // example SENTRYGODEBUG=someopt=1. - dbgOpt := func(opt string) bool { - s := opt + "=1" - return dbg[sort.SearchStrings(dbg, s)%len(dbg)] == s - } - if dbgOpt("httpdump") || dbgOpt("httptrace") { - options.HTTPTransport = &debug.Transport{ - RoundTripper: http.DefaultTransport, - Output: os.Stderr, - Dump: dbgOpt("httpdump"), - Trace: dbgOpt("httptrace"), - } - } - - var dsn *Dsn - if options.Dsn != "" { - var err error - dsn, err = NewDsn(options.Dsn) - if err != nil { - return nil, err - } - } - - client := Client{ - options: options, - dsn: dsn, - sdkIdentifier: sdkIdentifier, - sdkVersion: SDKVersion, - } - - client.setupTransport() - client.setupIntegrations() - - return &client, nil -} - -func (client *Client) setupTransport() { - opts := client.options - transport := opts.Transport - - if transport == nil { - if opts.Dsn == "" { - transport = new(noopTransport) - } else { - httpTransport := NewHTTPTransport() - // When tracing is enabled, use larger buffer to - // accommodate more concurrent events. - // TODO(tracing): consider using separate buffers per - // event type. - if opts.EnableTracing { - httpTransport.BufferSize = 1000 - } - transport = httpTransport - } - } - - transport.Configure(opts) - client.Transport = transport -} - -func (client *Client) setupIntegrations() { - integrations := []Integration{ - new(contextifyFramesIntegration), - new(environmentIntegration), - new(modulesIntegration), - new(ignoreErrorsIntegration), - new(ignoreTransactionsIntegration), - new(globalTagsIntegration), - } - - if client.options.Integrations != nil { - integrations = client.options.Integrations(integrations) - } - - for _, integration := range integrations { - if client.integrationAlreadyInstalled(integration.Name()) { - Logger.Printf("Integration %s is already installed\n", integration.Name()) - continue - } - client.integrations = append(client.integrations, integration) - integration.SetupOnce(client) - Logger.Printf("Integration installed: %s\n", integration.Name()) - } - - sort.Slice(client.integrations, func(i, j int) bool { - return client.integrations[i].Name() < client.integrations[j].Name() - }) -} - -// AddEventProcessor adds an event processor to the client. It must not be -// called from concurrent goroutines. Most users will prefer to use -// ClientOptions.BeforeSend or Scope.AddEventProcessor instead. -// -// Note that typical programs have only a single client created by Init and the -// client is shared among multiple hubs, one per goroutine, such that adding an -// event processor to the client affects all hubs that share the client. -func (client *Client) AddEventProcessor(processor EventProcessor) { - client.eventProcessors = append(client.eventProcessors, processor) -} - -// Options return ClientOptions for the current Client. -func (client *Client) Options() ClientOptions { - // Note: internally, consider using `client.options` instead of `client.Options()` to avoid copying the object each time. - return client.options -} - -// CaptureMessage captures an arbitrary message. -func (client *Client) CaptureMessage(message string, hint *EventHint, scope EventModifier) *EventID { - event := client.EventFromMessage(message, LevelInfo) - return client.CaptureEvent(event, hint, scope) -} - -// CaptureException captures an error. -func (client *Client) CaptureException(exception error, hint *EventHint, scope EventModifier) *EventID { - event := client.EventFromException(exception, LevelError) - return client.CaptureEvent(event, hint, scope) -} - -// CaptureCheckIn captures a check in. -func (client *Client) CaptureCheckIn(checkIn *CheckIn, monitorConfig *MonitorConfig, scope EventModifier) *EventID { - event := client.EventFromCheckIn(checkIn, monitorConfig) - if event != nil && event.CheckIn != nil { - client.CaptureEvent(event, nil, scope) - return &event.CheckIn.ID - } - return nil -} - -// CaptureEvent captures an event on the currently active client if any. -// -// The event must already be assembled. Typically code would instead use -// the utility methods like CaptureException. The return value is the -// event ID. In case Sentry is disabled or event was dropped, the return value will be nil. -func (client *Client) CaptureEvent(event *Event, hint *EventHint, scope EventModifier) *EventID { - return client.processEvent(event, hint, scope) -} - -// Recover captures a panic. -// Returns EventID if successfully, or nil if there's no error to recover from. -func (client *Client) Recover(err interface{}, hint *EventHint, scope EventModifier) *EventID { - if err == nil { - err = recover() - } - - // Normally we would not pass a nil Context, but RecoverWithContext doesn't - // use the Context for communicating deadline nor cancelation. All it does - // is store the Context in the EventHint and there nil means the Context is - // not available. - // nolint: staticcheck - return client.RecoverWithContext(nil, err, hint, scope) -} - -// RecoverWithContext captures a panic and passes relevant context object. -// Returns EventID if successfully, or nil if there's no error to recover from. -func (client *Client) RecoverWithContext( - ctx context.Context, - err interface{}, - hint *EventHint, - scope EventModifier, -) *EventID { - if err == nil { - err = recover() - } - if err == nil { - return nil - } - - if ctx != nil { - if hint == nil { - hint = &EventHint{} - } - if hint.Context == nil { - hint.Context = ctx - } - } - - var event *Event - switch err := err.(type) { - case error: - event = client.EventFromException(err, LevelFatal) - case string: - event = client.EventFromMessage(err, LevelFatal) - default: - event = client.EventFromMessage(fmt.Sprintf("%#v", err), LevelFatal) - } - return client.CaptureEvent(event, hint, scope) -} - -// Flush waits until the underlying Transport sends any buffered events to the -// Sentry server, blocking for at most the given timeout. It returns false if -// the timeout was reached. In that case, some events may not have been sent. -// -// Flush should be called before terminating the program to avoid -// unintentionally dropping events. -// -// Do not call Flush indiscriminately after every call to CaptureEvent, -// CaptureException or CaptureMessage. Instead, to have the SDK send events over -// the network synchronously, configure it to use the HTTPSyncTransport in the -// call to Init. -func (client *Client) Flush(timeout time.Duration) bool { - return client.Transport.Flush(timeout) -} - -// EventFromMessage creates an event from the given message string. -func (client *Client) EventFromMessage(message string, level Level) *Event { - if message == "" { - err := usageError{fmt.Errorf("%s called with empty message", callerFunctionName())} - return client.EventFromException(err, level) - } - event := NewEvent() - event.Level = level - event.Message = message - - if client.options.AttachStacktrace { - event.Threads = []Thread{{ - Stacktrace: NewStacktrace(), - Crashed: false, - Current: true, - }} - } - - return event -} - -// EventFromException creates a new Sentry event from the given `error` instance. -func (client *Client) EventFromException(exception error, level Level) *Event { - event := NewEvent() - event.Level = level - - err := exception - if err == nil { - err = usageError{fmt.Errorf("%s called with nil error", callerFunctionName())} - } - - event.SetException(err, client.options.MaxErrorDepth) - - return event -} - -// EventFromCheckIn creates a new Sentry event from the given `check_in` instance. -func (client *Client) EventFromCheckIn(checkIn *CheckIn, monitorConfig *MonitorConfig) *Event { - if checkIn == nil { - return nil - } - - event := NewEvent() - event.Type = checkInType - - var checkInID EventID - if checkIn.ID == "" { - checkInID = EventID(uuid()) - } else { - checkInID = checkIn.ID - } - - event.CheckIn = &CheckIn{ - ID: checkInID, - MonitorSlug: checkIn.MonitorSlug, - Status: checkIn.Status, - Duration: checkIn.Duration, - } - event.MonitorConfig = monitorConfig - - return event -} - -func (client *Client) SetSDKIdentifier(identifier string) { - client.mu.Lock() - defer client.mu.Unlock() - - client.sdkIdentifier = identifier -} - -func (client *Client) GetSDKIdentifier() string { - client.mu.RLock() - defer client.mu.RUnlock() - - return client.sdkIdentifier -} - -// reverse reverses the slice a in place. -func reverse(a []Exception) { - for i := len(a)/2 - 1; i >= 0; i-- { - opp := len(a) - 1 - i - a[i], a[opp] = a[opp], a[i] - } -} - -func (client *Client) processEvent(event *Event, hint *EventHint, scope EventModifier) *EventID { - if event == nil { - err := usageError{fmt.Errorf("%s called with nil event", callerFunctionName())} - return client.CaptureException(err, hint, scope) - } - - // Transactions are sampled by options.TracesSampleRate or - // options.TracesSampler when they are started. Other events - // (errors, messages) are sampled here. Does not apply to check-ins. - if event.Type != transactionType && event.Type != checkInType && !sample(client.options.SampleRate) { - Logger.Println("Event dropped due to SampleRate hit.") - return nil - } - - if event = client.prepareEvent(event, hint, scope); event == nil { - return nil - } - - // Apply beforeSend* processors - if hint == nil { - hint = &EventHint{} - } - if event.Type == transactionType && client.options.BeforeSendTransaction != nil { - // Transaction events - if event = client.options.BeforeSendTransaction(event, hint); event == nil { - Logger.Println("Transaction dropped due to BeforeSendTransaction callback.") - return nil - } - } else if event.Type != transactionType && event.Type != checkInType && client.options.BeforeSend != nil { - // All other events - if event = client.options.BeforeSend(event, hint); event == nil { - Logger.Println("Event dropped due to BeforeSend callback.") - return nil - } - } - - client.Transport.SendEvent(event) - - return &event.EventID -} - -func (client *Client) prepareEvent(event *Event, hint *EventHint, scope EventModifier) *Event { - if event.EventID == "" { - // TODO set EventID when the event is created, same as in other SDKs. It's necessary for profileTransaction.ID. - event.EventID = EventID(uuid()) - } - - if event.Timestamp.IsZero() { - event.Timestamp = time.Now() - } - - if event.Level == "" { - event.Level = LevelInfo - } - - if event.ServerName == "" { - event.ServerName = client.options.ServerName - - if event.ServerName == "" { - event.ServerName = hostname - } - } - - if event.Release == "" { - event.Release = client.options.Release - } - - if event.Dist == "" { - event.Dist = client.options.Dist - } - - if event.Environment == "" { - event.Environment = client.options.Environment - } - - event.Platform = "go" - event.Sdk = SdkInfo{ - Name: client.GetSDKIdentifier(), - Version: SDKVersion, - Integrations: client.listIntegrations(), - Packages: []SdkPackage{{ - Name: "sentry-go", - Version: SDKVersion, - }}, - } - - if scope != nil { - event = scope.ApplyToEvent(event, hint, client) - if event == nil { - return nil - } - } - - for _, processor := range client.eventProcessors { - id := event.EventID - event = processor(event, hint) - if event == nil { - Logger.Printf("Event dropped by one of the Client EventProcessors: %s\n", id) - return nil - } - } - - for _, processor := range globalEventProcessors { - id := event.EventID - event = processor(event, hint) - if event == nil { - Logger.Printf("Event dropped by one of the Global EventProcessors: %s\n", id) - return nil - } - } - - if event.sdkMetaData.transactionProfile != nil { - event.sdkMetaData.transactionProfile.UpdateFromEvent(event) - } - - return event -} - -func (client *Client) listIntegrations() []string { - integrations := make([]string, len(client.integrations)) - for i, integration := range client.integrations { - integrations[i] = integration.Name() - } - return integrations -} - -func (client *Client) integrationAlreadyInstalled(name string) bool { - for _, integration := range client.integrations { - if integration.Name() == name { - return true - } - } - return false -} - -// sample returns true with the given probability, which must be in the range -// [0.0, 1.0]. -func sample(probability float64) bool { - return rng.Float64() < probability -} diff --git a/vendor/github.com/getsentry/sentry-go/doc.go b/vendor/github.com/getsentry/sentry-go/doc.go deleted file mode 100644 index 973020ae8..000000000 --- a/vendor/github.com/getsentry/sentry-go/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -/* -Package repository: https://github.com/getsentry/sentry-go/ - -For more information about Sentry and SDK features, please have a look at the official documentation site: https://docs.sentry.io/platforms/go/ -*/ -package sentry diff --git a/vendor/github.com/getsentry/sentry-go/dsn.go b/vendor/github.com/getsentry/sentry-go/dsn.go deleted file mode 100644 index ac6991a4f..000000000 --- a/vendor/github.com/getsentry/sentry-go/dsn.go +++ /dev/null @@ -1,233 +0,0 @@ -package sentry - -import ( - "encoding/json" - "fmt" - "net/url" - "strconv" - "strings" - "time" -) - -type scheme string - -const ( - schemeHTTP scheme = "http" - schemeHTTPS scheme = "https" -) - -func (scheme scheme) defaultPort() int { - switch scheme { - case schemeHTTPS: - return 443 - case schemeHTTP: - return 80 - default: - return 80 - } -} - -// DsnParseError represents an error that occurs if a Sentry -// DSN cannot be parsed. -type DsnParseError struct { - Message string -} - -func (e DsnParseError) Error() string { - return "[Sentry] DsnParseError: " + e.Message -} - -// Dsn is used as the remote address source to client transport. -type Dsn struct { - scheme scheme - publicKey string - secretKey string - host string - port int - path string - projectID string -} - -// NewDsn creates a Dsn by parsing rawURL. Most users will never call this -// function directly. It is provided for use in custom Transport -// implementations. -func NewDsn(rawURL string) (*Dsn, error) { - // Parse - parsedURL, err := url.Parse(rawURL) - if err != nil { - return nil, &DsnParseError{fmt.Sprintf("invalid url: %v", err)} - } - - // Scheme - var scheme scheme - switch parsedURL.Scheme { - case "http": - scheme = schemeHTTP - case "https": - scheme = schemeHTTPS - default: - return nil, &DsnParseError{"invalid scheme"} - } - - // PublicKey - publicKey := parsedURL.User.Username() - if publicKey == "" { - return nil, &DsnParseError{"empty username"} - } - - // SecretKey - var secretKey string - if parsedSecretKey, ok := parsedURL.User.Password(); ok { - secretKey = parsedSecretKey - } - - // Host - host := parsedURL.Hostname() - if host == "" { - return nil, &DsnParseError{"empty host"} - } - - // Port - var port int - if parsedURL.Port() != "" { - port, err = strconv.Atoi(parsedURL.Port()) - if err != nil { - return nil, &DsnParseError{"invalid port"} - } - } else { - port = scheme.defaultPort() - } - - // ProjectID - if parsedURL.Path == "" || parsedURL.Path == "/" { - return nil, &DsnParseError{"empty project id"} - } - pathSegments := strings.Split(parsedURL.Path[1:], "/") - projectID := pathSegments[len(pathSegments)-1] - - if projectID == "" { - return nil, &DsnParseError{"empty project id"} - } - - // Path - var path string - if len(pathSegments) > 1 { - path = "/" + strings.Join(pathSegments[0:len(pathSegments)-1], "/") - } - - return &Dsn{ - scheme: scheme, - publicKey: publicKey, - secretKey: secretKey, - host: host, - port: port, - path: path, - projectID: projectID, - }, nil -} - -// String formats Dsn struct into a valid string url. -func (dsn Dsn) String() string { - var url string - url += fmt.Sprintf("%s://%s", dsn.scheme, dsn.publicKey) - if dsn.secretKey != "" { - url += fmt.Sprintf(":%s", dsn.secretKey) - } - url += fmt.Sprintf("@%s", dsn.host) - if dsn.port != dsn.scheme.defaultPort() { - url += fmt.Sprintf(":%d", dsn.port) - } - if dsn.path != "" { - url += dsn.path - } - url += fmt.Sprintf("/%s", dsn.projectID) - return url -} - -// Get the scheme of the DSN. -func (dsn Dsn) GetScheme() string { - return string(dsn.scheme) -} - -// Get the public key of the DSN. -func (dsn Dsn) GetPublicKey() string { - return dsn.publicKey -} - -// Get the secret key of the DSN. -func (dsn Dsn) GetSecretKey() string { - return dsn.secretKey -} - -// Get the host of the DSN. -func (dsn Dsn) GetHost() string { - return dsn.host -} - -// Get the port of the DSN. -func (dsn Dsn) GetPort() int { - return dsn.port -} - -// Get the path of the DSN. -func (dsn Dsn) GetPath() string { - return dsn.path -} - -// Get the project ID of the DSN. -func (dsn Dsn) GetProjectID() string { - return dsn.projectID -} - -// GetAPIURL returns the URL of the envelope endpoint of the project -// associated with the DSN. -func (dsn Dsn) GetAPIURL() *url.URL { - var rawURL string - rawURL += fmt.Sprintf("%s://%s", dsn.scheme, dsn.host) - if dsn.port != dsn.scheme.defaultPort() { - rawURL += fmt.Sprintf(":%d", dsn.port) - } - if dsn.path != "" { - rawURL += dsn.path - } - rawURL += fmt.Sprintf("/api/%s/%s/", dsn.projectID, "envelope") - parsedURL, _ := url.Parse(rawURL) - return parsedURL -} - -// RequestHeaders returns all the necessary headers that have to be used in the transport when seinding events -// to the /store endpoint. -// -// Deprecated: This method shall only be used if you want to implement your own transport that sends events to -// the /store endpoint. If you're using the transport provided by the SDK, all necessary headers to authenticate -// against the /envelope endpoint are added automatically. -func (dsn Dsn) RequestHeaders() map[string]string { - auth := fmt.Sprintf("Sentry sentry_version=%s, sentry_timestamp=%d, "+ - "sentry_client=sentry.go/%s, sentry_key=%s", apiVersion, time.Now().Unix(), SDKVersion, dsn.publicKey) - - if dsn.secretKey != "" { - auth = fmt.Sprintf("%s, sentry_secret=%s", auth, dsn.secretKey) - } - - return map[string]string{ - "Content-Type": "application/json", - "X-Sentry-Auth": auth, - } -} - -// MarshalJSON converts the Dsn struct to JSON. -func (dsn Dsn) MarshalJSON() ([]byte, error) { - return json.Marshal(dsn.String()) -} - -// UnmarshalJSON converts JSON data to the Dsn struct. -func (dsn *Dsn) UnmarshalJSON(data []byte) error { - var str string - _ = json.Unmarshal(data, &str) - newDsn, err := NewDsn(str) - if err != nil { - return err - } - *dsn = *newDsn - return nil -} diff --git a/vendor/github.com/getsentry/sentry-go/dynamic_sampling_context.go b/vendor/github.com/getsentry/sentry-go/dynamic_sampling_context.go deleted file mode 100644 index 6eec95ba1..000000000 --- a/vendor/github.com/getsentry/sentry-go/dynamic_sampling_context.go +++ /dev/null @@ -1,152 +0,0 @@ -package sentry - -import ( - "strconv" - "strings" - - "github.com/getsentry/sentry-go/internal/otel/baggage" -) - -const ( - sentryPrefix = "sentry-" -) - -// DynamicSamplingContext holds information about the current event that can be used to make dynamic sampling decisions. -type DynamicSamplingContext struct { - Entries map[string]string - Frozen bool -} - -func DynamicSamplingContextFromHeader(header []byte) (DynamicSamplingContext, error) { - bag, err := baggage.Parse(string(header)) - if err != nil { - return DynamicSamplingContext{}, err - } - - entries := map[string]string{} - for _, member := range bag.Members() { - // We only store baggage members if their key starts with "sentry-". - if k, v := member.Key(), member.Value(); strings.HasPrefix(k, sentryPrefix) { - entries[strings.TrimPrefix(k, sentryPrefix)] = v - } - } - - return DynamicSamplingContext{ - Entries: entries, - // If there's at least one Sentry value, we consider the DSC frozen - Frozen: len(entries) > 0, - }, nil -} - -func DynamicSamplingContextFromTransaction(span *Span) DynamicSamplingContext { - hub := hubFromContext(span.Context()) - scope := hub.Scope() - client := hub.Client() - - if client == nil || scope == nil { - return DynamicSamplingContext{ - Entries: map[string]string{}, - Frozen: false, - } - } - - entries := make(map[string]string) - - if traceID := span.TraceID.String(); traceID != "" { - entries["trace_id"] = traceID - } - if sampleRate := span.sampleRate; sampleRate != 0 { - entries["sample_rate"] = strconv.FormatFloat(sampleRate, 'f', -1, 64) - } - - if dsn := client.dsn; dsn != nil { - if publicKey := dsn.publicKey; publicKey != "" { - entries["public_key"] = publicKey - } - } - if release := client.options.Release; release != "" { - entries["release"] = release - } - if environment := client.options.Environment; environment != "" { - entries["environment"] = environment - } - - // Only include the transaction name if it's of good quality (not empty and not SourceURL) - if span.Source != "" && span.Source != SourceURL { - if span.IsTransaction() { - entries["transaction"] = span.Name - } - } - - entries["sampled"] = strconv.FormatBool(span.Sampled.Bool()) - - return DynamicSamplingContext{Entries: entries, Frozen: true} -} - -func (d DynamicSamplingContext) HasEntries() bool { - return len(d.Entries) > 0 -} - -func (d DynamicSamplingContext) IsFrozen() bool { - return d.Frozen -} - -func (d DynamicSamplingContext) String() string { - members := []baggage.Member{} - for k, entry := range d.Entries { - member, err := baggage.NewMember(sentryPrefix+k, entry) - if err != nil { - continue - } - members = append(members, member) - } - if len(members) > 0 { - baggage, err := baggage.New(members...) - if err != nil { - return "" - } - return baggage.String() - } - - return "" -} - -// Constructs a new DynamicSamplingContext using a scope and client. Accessing -// fields on the scope are not thread safe, and this function should only be -// called within scope methods. -func DynamicSamplingContextFromScope(scope *Scope, client *Client) DynamicSamplingContext { - entries := map[string]string{} - - if client == nil || scope == nil { - return DynamicSamplingContext{ - Entries: entries, - Frozen: false, - } - } - - propagationContext := scope.propagationContext - - if traceID := propagationContext.TraceID.String(); traceID != "" { - entries["trace_id"] = traceID - } - if sampleRate := client.options.TracesSampleRate; sampleRate != 0 { - entries["sample_rate"] = strconv.FormatFloat(sampleRate, 'f', -1, 64) - } - - if dsn := client.dsn; dsn != nil { - if publicKey := dsn.publicKey; publicKey != "" { - entries["public_key"] = publicKey - } - } - if release := client.options.Release; release != "" { - entries["release"] = release - } - if environment := client.options.Environment; environment != "" { - entries["environment"] = environment - } - - return DynamicSamplingContext{ - Entries: entries, - Frozen: true, - } -} diff --git a/vendor/github.com/getsentry/sentry-go/hub.go b/vendor/github.com/getsentry/sentry-go/hub.go deleted file mode 100644 index c99b6d70d..000000000 --- a/vendor/github.com/getsentry/sentry-go/hub.go +++ /dev/null @@ -1,424 +0,0 @@ -package sentry - -import ( - "context" - "fmt" - "sync" - "time" -) - -type contextKey int - -// Keys used to store values in a Context. Use with Context.Value to access -// values stored by the SDK. -const ( - // HubContextKey is the key used to store the current Hub. - HubContextKey = contextKey(1) - // RequestContextKey is the key used to store the current http.Request. - RequestContextKey = contextKey(2) -) - -// defaultMaxBreadcrumbs is the default maximum number of breadcrumbs added to -// an event. Can be overwritten with the maxBreadcrumbs option. -const defaultMaxBreadcrumbs = 30 - -// maxBreadcrumbs is the absolute maximum number of breadcrumbs added to an -// event. The maxBreadcrumbs option cannot be set higher than this value. -const maxBreadcrumbs = 100 - -// currentHub is the initial Hub with no Client bound and an empty Scope. -var currentHub = NewHub(nil, NewScope()) - -// Hub is the central object that manages scopes and clients. -// -// This can be used to capture events and manage the scope. -// The default hub that is available automatically. -// -// In most situations developers do not need to interface the hub. Instead -// toplevel convenience functions are exposed that will automatically dispatch -// to global (CurrentHub) hub. In some situations this might not be -// possible in which case it might become necessary to manually work with the -// hub. This is for instance the case when working with async code. -type Hub struct { - mu sync.RWMutex - stack *stack - lastEventID EventID -} - -type layer struct { - // mu protects concurrent reads and writes to client. - mu sync.RWMutex - client *Client - // scope is read-only, not protected by mu. - scope *Scope -} - -// Client returns the layer's client. Safe for concurrent use. -func (l *layer) Client() *Client { - l.mu.RLock() - defer l.mu.RUnlock() - return l.client -} - -// SetClient sets the layer's client. Safe for concurrent use. -func (l *layer) SetClient(c *Client) { - l.mu.Lock() - defer l.mu.Unlock() - l.client = c -} - -type stack []*layer - -// NewHub returns an instance of a Hub with provided Client and Scope bound. -func NewHub(client *Client, scope *Scope) *Hub { - hub := Hub{ - stack: &stack{{ - client: client, - scope: scope, - }}, - } - return &hub -} - -// CurrentHub returns an instance of previously initialized Hub stored in the global namespace. -func CurrentHub() *Hub { - return currentHub -} - -// LastEventID returns the ID of the last event (error or message) captured -// through the hub and sent to the underlying transport. -// -// Transactions and events dropped by sampling or event processors do not change -// the last event ID. -// -// LastEventID is a convenience method to cover use cases in which errors are -// captured indirectly and the ID is needed. For example, it can be used as part -// of an HTTP middleware to log the ID of the last error, if any. -// -// For more flexibility, consider instead using the ClientOptions.BeforeSend -// function or event processors. -func (hub *Hub) LastEventID() EventID { - hub.mu.RLock() - defer hub.mu.RUnlock() - - return hub.lastEventID -} - -// stackTop returns the top layer of the hub stack. Valid hubs always have at -// least one layer, therefore stackTop always return a non-nil pointer. -func (hub *Hub) stackTop() *layer { - hub.mu.RLock() - defer hub.mu.RUnlock() - - stack := hub.stack - stackLen := len(*stack) - top := (*stack)[stackLen-1] - return top -} - -// Clone returns a copy of the current Hub with top-most scope and client copied over. -func (hub *Hub) Clone() *Hub { - top := hub.stackTop() - scope := top.scope - if scope != nil { - scope = scope.Clone() - } - return NewHub(top.Client(), scope) -} - -// Scope returns top-level Scope of the current Hub or nil if no Scope is bound. -func (hub *Hub) Scope() *Scope { - top := hub.stackTop() - return top.scope -} - -// Client returns top-level Client of the current Hub or nil if no Client is bound. -func (hub *Hub) Client() *Client { - top := hub.stackTop() - return top.Client() -} - -// PushScope pushes a new scope for the current Hub and reuses previously bound Client. -func (hub *Hub) PushScope() *Scope { - top := hub.stackTop() - - var scope *Scope - if top.scope != nil { - scope = top.scope.Clone() - } else { - scope = NewScope() - } - - hub.mu.Lock() - defer hub.mu.Unlock() - - *hub.stack = append(*hub.stack, &layer{ - client: top.Client(), - scope: scope, - }) - - return scope -} - -// PopScope drops the most recent scope. -// -// Calls to PopScope must be coordinated with PushScope. For most cases, using -// WithScope should be more convenient. -// -// Calls to PopScope that do not match previous calls to PushScope are silently -// ignored. -func (hub *Hub) PopScope() { - hub.mu.Lock() - defer hub.mu.Unlock() - - stack := *hub.stack - stackLen := len(stack) - if stackLen > 1 { - // Never pop the last item off the stack, the stack should always have - // at least one item. - *hub.stack = stack[0 : stackLen-1] - } -} - -// BindClient binds a new Client for the current Hub. -func (hub *Hub) BindClient(client *Client) { - top := hub.stackTop() - top.SetClient(client) -} - -// WithScope runs f in an isolated temporary scope. -// -// It is useful when extra data should be sent with a single capture call, for -// instance a different level or tags. -// -// The scope passed to f starts as a clone of the current scope and can be -// freely modified without affecting the current scope. -// -// It is a shorthand for PushScope followed by PopScope. -func (hub *Hub) WithScope(f func(scope *Scope)) { - scope := hub.PushScope() - defer hub.PopScope() - f(scope) -} - -// ConfigureScope runs f in the current scope. -// -// It is useful to set data that applies to all events that share the current -// scope. -// -// Modifying the scope affects all references to the current scope. -// -// See also WithScope for making isolated temporary changes. -func (hub *Hub) ConfigureScope(f func(scope *Scope)) { - scope := hub.Scope() - f(scope) -} - -// CaptureEvent calls the method of a same name on currently bound Client instance -// passing it a top-level Scope. -// Returns EventID if successfully, or nil if there's no Scope or Client available. -func (hub *Hub) CaptureEvent(event *Event) *EventID { - client, scope := hub.Client(), hub.Scope() - if client == nil || scope == nil { - return nil - } - eventID := client.CaptureEvent(event, nil, scope) - - if event.Type != transactionType && eventID != nil { - hub.mu.Lock() - hub.lastEventID = *eventID - hub.mu.Unlock() - } - return eventID -} - -// CaptureMessage calls the method of a same name on currently bound Client instance -// passing it a top-level Scope. -// Returns EventID if successfully, or nil if there's no Scope or Client available. -func (hub *Hub) CaptureMessage(message string) *EventID { - client, scope := hub.Client(), hub.Scope() - if client == nil || scope == nil { - return nil - } - eventID := client.CaptureMessage(message, nil, scope) - - if eventID != nil { - hub.mu.Lock() - hub.lastEventID = *eventID - hub.mu.Unlock() - } - return eventID -} - -// CaptureException calls the method of a same name on currently bound Client instance -// passing it a top-level Scope. -// Returns EventID if successfully, or nil if there's no Scope or Client available. -func (hub *Hub) CaptureException(exception error) *EventID { - client, scope := hub.Client(), hub.Scope() - if client == nil || scope == nil { - return nil - } - eventID := client.CaptureException(exception, &EventHint{OriginalException: exception}, scope) - - if eventID != nil { - hub.mu.Lock() - hub.lastEventID = *eventID - hub.mu.Unlock() - } - return eventID -} - -// CaptureCheckIn calls the method of the same name on currently bound Client instance -// passing it a top-level Scope. -// Returns CheckInID if the check-in was captured successfully, or nil otherwise. -func (hub *Hub) CaptureCheckIn(checkIn *CheckIn, monitorConfig *MonitorConfig) *EventID { - client, scope := hub.Client(), hub.Scope() - if client == nil { - return nil - } - - return client.CaptureCheckIn(checkIn, monitorConfig, scope) -} - -// AddBreadcrumb records a new breadcrumb. -// -// The total number of breadcrumbs that can be recorded are limited by the -// configuration on the client. -func (hub *Hub) AddBreadcrumb(breadcrumb *Breadcrumb, hint *BreadcrumbHint) { - client := hub.Client() - - // If there's no client, just store it on the scope straight away - if client == nil { - hub.Scope().AddBreadcrumb(breadcrumb, maxBreadcrumbs) - return - } - - max := client.options.MaxBreadcrumbs - if max < 0 { - return - } - - if client.options.BeforeBreadcrumb != nil { - if hint == nil { - hint = &BreadcrumbHint{} - } - if breadcrumb = client.options.BeforeBreadcrumb(breadcrumb, hint); breadcrumb == nil { - Logger.Println("breadcrumb dropped due to BeforeBreadcrumb callback.") - return - } - } - - if max == 0 { - max = defaultMaxBreadcrumbs - } else if max > maxBreadcrumbs { - max = maxBreadcrumbs - } - - hub.Scope().AddBreadcrumb(breadcrumb, max) -} - -// Recover calls the method of a same name on currently bound Client instance -// passing it a top-level Scope. -// Returns EventID if successfully, or nil if there's no Scope or Client available. -func (hub *Hub) Recover(err interface{}) *EventID { - if err == nil { - err = recover() - } - client, scope := hub.Client(), hub.Scope() - if client == nil || scope == nil { - return nil - } - return client.Recover(err, &EventHint{RecoveredException: err}, scope) -} - -// RecoverWithContext calls the method of a same name on currently bound Client instance -// passing it a top-level Scope. -// Returns EventID if successfully, or nil if there's no Scope or Client available. -func (hub *Hub) RecoverWithContext(ctx context.Context, err interface{}) *EventID { - if err == nil { - err = recover() - } - client, scope := hub.Client(), hub.Scope() - if client == nil || scope == nil { - return nil - } - return client.RecoverWithContext(ctx, err, &EventHint{RecoveredException: err}, scope) -} - -// Flush waits until the underlying Transport sends any buffered events to the -// Sentry server, blocking for at most the given timeout. It returns false if -// the timeout was reached. In that case, some events may not have been sent. -// -// Flush should be called before terminating the program to avoid -// unintentionally dropping events. -// -// Do not call Flush indiscriminately after every call to CaptureEvent, -// CaptureException or CaptureMessage. Instead, to have the SDK send events over -// the network synchronously, configure it to use the HTTPSyncTransport in the -// call to Init. -func (hub *Hub) Flush(timeout time.Duration) bool { - client := hub.Client() - - if client == nil { - return false - } - - return client.Flush(timeout) -} - -// GetTraceparent returns the current Sentry traceparent string, to be used as a HTTP header value -// or HTML meta tag value. -// This function is context aware, as in it either returns the traceparent based -// on the current span, or the scope's propagation context. -func (hub *Hub) GetTraceparent() string { - scope := hub.Scope() - - if scope.span != nil { - return scope.span.ToSentryTrace() - } - - return fmt.Sprintf("%s-%s", scope.propagationContext.TraceID, scope.propagationContext.SpanID) -} - -// GetBaggage returns the current Sentry baggage string, to be used as a HTTP header value -// or HTML meta tag value. -// This function is context aware, as in it either returns the baggage based -// on the current span or the scope's propagation context. -func (hub *Hub) GetBaggage() string { - scope := hub.Scope() - - if scope.span != nil { - return scope.span.ToBaggage() - } - - return scope.propagationContext.DynamicSamplingContext.String() -} - -// HasHubOnContext checks whether Hub instance is bound to a given Context struct. -func HasHubOnContext(ctx context.Context) bool { - _, ok := ctx.Value(HubContextKey).(*Hub) - return ok -} - -// GetHubFromContext tries to retrieve Hub instance from the given Context struct -// or return nil if one is not found. -func GetHubFromContext(ctx context.Context) *Hub { - if hub, ok := ctx.Value(HubContextKey).(*Hub); ok { - return hub - } - return nil -} - -// hubFromContext returns either a hub stored in the context or the current hub. -// The return value is guaranteed to be non-nil, unlike GetHubFromContext. -func hubFromContext(ctx context.Context) *Hub { - if hub, ok := ctx.Value(HubContextKey).(*Hub); ok { - return hub - } - return currentHub -} - -// SetHubOnContext stores given Hub instance on the Context struct and returns a new Context. -func SetHubOnContext(ctx context.Context, hub *Hub) context.Context { - return context.WithValue(ctx, HubContextKey, hub) -} diff --git a/vendor/github.com/getsentry/sentry-go/integrations.go b/vendor/github.com/getsentry/sentry-go/integrations.go deleted file mode 100644 index a8b2082a8..000000000 --- a/vendor/github.com/getsentry/sentry-go/integrations.go +++ /dev/null @@ -1,391 +0,0 @@ -package sentry - -import ( - "fmt" - "os" - "regexp" - "runtime" - "runtime/debug" - "strings" - "sync" -) - -// ================================ -// Modules Integration -// ================================ - -type modulesIntegration struct { - once sync.Once - modules map[string]string -} - -func (mi *modulesIntegration) Name() string { - return "Modules" -} - -func (mi *modulesIntegration) SetupOnce(client *Client) { - client.AddEventProcessor(mi.processor) -} - -func (mi *modulesIntegration) processor(event *Event, _ *EventHint) *Event { - if len(event.Modules) == 0 { - mi.once.Do(func() { - info, ok := debug.ReadBuildInfo() - if !ok { - Logger.Print("The Modules integration is not available in binaries built without module support.") - return - } - mi.modules = extractModules(info) - }) - } - event.Modules = mi.modules - return event -} - -func extractModules(info *debug.BuildInfo) map[string]string { - modules := map[string]string{ - info.Main.Path: info.Main.Version, - } - for _, dep := range info.Deps { - ver := dep.Version - if dep.Replace != nil { - ver += fmt.Sprintf(" => %s %s", dep.Replace.Path, dep.Replace.Version) - } - modules[dep.Path] = strings.TrimSuffix(ver, " ") - } - return modules -} - -// ================================ -// Environment Integration -// ================================ - -type environmentIntegration struct{} - -func (ei *environmentIntegration) Name() string { - return "Environment" -} - -func (ei *environmentIntegration) SetupOnce(client *Client) { - client.AddEventProcessor(ei.processor) -} - -func (ei *environmentIntegration) processor(event *Event, _ *EventHint) *Event { - // Initialize maps as necessary. - contextNames := []string{"device", "os", "runtime"} - if event.Contexts == nil { - event.Contexts = make(map[string]Context, len(contextNames)) - } - for _, name := range contextNames { - if event.Contexts[name] == nil { - event.Contexts[name] = make(Context) - } - } - - // Set contextual information preserving existing data. For each context, if - // the existing value is not of type map[string]interface{}, then no - // additional information is added. - if deviceContext, ok := event.Contexts["device"]; ok { - if _, ok := deviceContext["arch"]; !ok { - deviceContext["arch"] = runtime.GOARCH - } - if _, ok := deviceContext["num_cpu"]; !ok { - deviceContext["num_cpu"] = runtime.NumCPU() - } - } - if osContext, ok := event.Contexts["os"]; ok { - if _, ok := osContext["name"]; !ok { - osContext["name"] = runtime.GOOS - } - } - if runtimeContext, ok := event.Contexts["runtime"]; ok { - if _, ok := runtimeContext["name"]; !ok { - runtimeContext["name"] = "go" - } - if _, ok := runtimeContext["version"]; !ok { - runtimeContext["version"] = runtime.Version() - } - if _, ok := runtimeContext["go_numroutines"]; !ok { - runtimeContext["go_numroutines"] = runtime.NumGoroutine() - } - if _, ok := runtimeContext["go_maxprocs"]; !ok { - runtimeContext["go_maxprocs"] = runtime.GOMAXPROCS(0) - } - if _, ok := runtimeContext["go_numcgocalls"]; !ok { - runtimeContext["go_numcgocalls"] = runtime.NumCgoCall() - } - } - return event -} - -// ================================ -// Ignore Errors Integration -// ================================ - -type ignoreErrorsIntegration struct { - ignoreErrors []*regexp.Regexp -} - -func (iei *ignoreErrorsIntegration) Name() string { - return "IgnoreErrors" -} - -func (iei *ignoreErrorsIntegration) SetupOnce(client *Client) { - iei.ignoreErrors = transformStringsIntoRegexps(client.options.IgnoreErrors) - client.AddEventProcessor(iei.processor) -} - -func (iei *ignoreErrorsIntegration) processor(event *Event, _ *EventHint) *Event { - suspects := getIgnoreErrorsSuspects(event) - - for _, suspect := range suspects { - for _, pattern := range iei.ignoreErrors { - if pattern.Match([]byte(suspect)) || strings.Contains(suspect, pattern.String()) { - Logger.Printf("Event dropped due to being matched by `IgnoreErrors` option."+ - "| Value matched: %s | Filter used: %s", suspect, pattern) - return nil - } - } - } - - return event -} - -func transformStringsIntoRegexps(strings []string) []*regexp.Regexp { - var exprs []*regexp.Regexp - - for _, s := range strings { - r, err := regexp.Compile(s) - if err == nil { - exprs = append(exprs, r) - } - } - - return exprs -} - -func getIgnoreErrorsSuspects(event *Event) []string { - suspects := []string{} - - if event.Message != "" { - suspects = append(suspects, event.Message) - } - - for _, ex := range event.Exception { - suspects = append(suspects, ex.Type, ex.Value) - } - - return suspects -} - -// ================================ -// Ignore Transactions Integration -// ================================ - -type ignoreTransactionsIntegration struct { - ignoreTransactions []*regexp.Regexp -} - -func (iei *ignoreTransactionsIntegration) Name() string { - return "IgnoreTransactions" -} - -func (iei *ignoreTransactionsIntegration) SetupOnce(client *Client) { - iei.ignoreTransactions = transformStringsIntoRegexps(client.options.IgnoreTransactions) - client.AddEventProcessor(iei.processor) -} - -func (iei *ignoreTransactionsIntegration) processor(event *Event, _ *EventHint) *Event { - suspect := event.Transaction - if suspect == "" { - return event - } - - for _, pattern := range iei.ignoreTransactions { - if pattern.Match([]byte(suspect)) || strings.Contains(suspect, pattern.String()) { - Logger.Printf("Transaction dropped due to being matched by `IgnoreTransactions` option."+ - "| Value matched: %s | Filter used: %s", suspect, pattern) - return nil - } - } - - return event -} - -// ================================ -// Contextify Frames Integration -// ================================ - -type contextifyFramesIntegration struct { - sr sourceReader - contextLines int - cachedLocations sync.Map -} - -func (cfi *contextifyFramesIntegration) Name() string { - return "ContextifyFrames" -} - -func (cfi *contextifyFramesIntegration) SetupOnce(client *Client) { - cfi.sr = newSourceReader() - cfi.contextLines = 5 - - client.AddEventProcessor(cfi.processor) -} - -func (cfi *contextifyFramesIntegration) processor(event *Event, _ *EventHint) *Event { - // Range over all exceptions - for _, ex := range event.Exception { - // If it has no stacktrace, just bail out - if ex.Stacktrace == nil { - continue - } - - // If it does, it should have frames, so try to contextify them - ex.Stacktrace.Frames = cfi.contextify(ex.Stacktrace.Frames) - } - - // Range over all threads - for _, th := range event.Threads { - // If it has no stacktrace, just bail out - if th.Stacktrace == nil { - continue - } - - // If it does, it should have frames, so try to contextify them - th.Stacktrace.Frames = cfi.contextify(th.Stacktrace.Frames) - } - - return event -} - -func (cfi *contextifyFramesIntegration) contextify(frames []Frame) []Frame { - contextifiedFrames := make([]Frame, 0, len(frames)) - - for _, frame := range frames { - if !frame.InApp { - contextifiedFrames = append(contextifiedFrames, frame) - continue - } - - var path string - - if cachedPath, ok := cfi.cachedLocations.Load(frame.AbsPath); ok { - if p, ok := cachedPath.(string); ok { - path = p - } - } else { - // Optimize for happy path here - if fileExists(frame.AbsPath) { - path = frame.AbsPath - } else { - path = cfi.findNearbySourceCodeLocation(frame.AbsPath) - } - } - - if path == "" { - contextifiedFrames = append(contextifiedFrames, frame) - continue - } - - lines, contextLine := cfi.sr.readContextLines(path, frame.Lineno, cfi.contextLines) - contextifiedFrames = append(contextifiedFrames, cfi.addContextLinesToFrame(frame, lines, contextLine)) - } - - return contextifiedFrames -} - -func (cfi *contextifyFramesIntegration) findNearbySourceCodeLocation(originalPath string) string { - trimmedPath := strings.TrimPrefix(originalPath, "/") - components := strings.Split(trimmedPath, "/") - - for len(components) > 0 { - components = components[1:] - possibleLocation := strings.Join(components, "/") - - if fileExists(possibleLocation) { - cfi.cachedLocations.Store(originalPath, possibleLocation) - return possibleLocation - } - } - - cfi.cachedLocations.Store(originalPath, "") - return "" -} - -func (cfi *contextifyFramesIntegration) addContextLinesToFrame(frame Frame, lines [][]byte, contextLine int) Frame { - for i, line := range lines { - switch { - case i < contextLine: - frame.PreContext = append(frame.PreContext, string(line)) - case i == contextLine: - frame.ContextLine = string(line) - default: - frame.PostContext = append(frame.PostContext, string(line)) - } - } - return frame -} - -// ================================ -// Global Tags Integration -// ================================ - -const envTagsPrefix = "SENTRY_TAGS_" - -type globalTagsIntegration struct { - tags map[string]string - envTags map[string]string -} - -func (ti *globalTagsIntegration) Name() string { - return "GlobalTags" -} - -func (ti *globalTagsIntegration) SetupOnce(client *Client) { - ti.tags = make(map[string]string, len(client.options.Tags)) - for k, v := range client.options.Tags { - ti.tags[k] = v - } - - ti.envTags = loadEnvTags() - - client.AddEventProcessor(ti.processor) -} - -func (ti *globalTagsIntegration) processor(event *Event, _ *EventHint) *Event { - if len(ti.tags) == 0 && len(ti.envTags) == 0 { - return event - } - - if event.Tags == nil { - event.Tags = make(map[string]string, len(ti.tags)+len(ti.envTags)) - } - - for k, v := range ti.tags { - if _, ok := event.Tags[k]; !ok { - event.Tags[k] = v - } - } - - for k, v := range ti.envTags { - if _, ok := event.Tags[k]; !ok { - event.Tags[k] = v - } - } - - return event -} - -func loadEnvTags() map[string]string { - tags := map[string]string{} - for _, pair := range os.Environ() { - parts := strings.Split(pair, "=") - if !strings.HasPrefix(parts[0], envTagsPrefix) { - continue - } - tag := strings.TrimPrefix(parts[0], envTagsPrefix) - tags[tag] = parts[1] - } - return tags -} diff --git a/vendor/github.com/getsentry/sentry-go/interfaces.go b/vendor/github.com/getsentry/sentry-go/interfaces.go deleted file mode 100644 index cacb25436..000000000 --- a/vendor/github.com/getsentry/sentry-go/interfaces.go +++ /dev/null @@ -1,559 +0,0 @@ -package sentry - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net" - "net/http" - "reflect" - "strings" - "time" -) - -// eventType is the type of an error event. -const eventType = "event" - -// transactionType is the type of a transaction event. -const transactionType = "transaction" - -// profileType is the type of a profile event. -// currently, profiles are always sent as part of a transaction event. -const profileType = "profile" - -// checkInType is the type of a check in event. -const checkInType = "check_in" - -// metricType is the type of a metric event. -const metricType = "statsd" - -// Level marks the severity of the event. -type Level string - -// Describes the severity of the event. -const ( - LevelDebug Level = "debug" - LevelInfo Level = "info" - LevelWarning Level = "warning" - LevelError Level = "error" - LevelFatal Level = "fatal" -) - -// SdkInfo contains all metadata about about the SDK being used. -type SdkInfo struct { - Name string `json:"name,omitempty"` - Version string `json:"version,omitempty"` - Integrations []string `json:"integrations,omitempty"` - Packages []SdkPackage `json:"packages,omitempty"` -} - -// SdkPackage describes a package that was installed. -type SdkPackage struct { - Name string `json:"name,omitempty"` - Version string `json:"version,omitempty"` -} - -// TODO: This type could be more useful, as map of interface{} is too generic -// and requires a lot of type assertions in beforeBreadcrumb calls -// plus it could just be map[string]interface{} then. - -// BreadcrumbHint contains information that can be associated with a Breadcrumb. -type BreadcrumbHint map[string]interface{} - -// Breadcrumb specifies an application event that occurred before a Sentry event. -// An event may contain one or more breadcrumbs. -type Breadcrumb struct { - Type string `json:"type,omitempty"` - Category string `json:"category,omitempty"` - Message string `json:"message,omitempty"` - Data map[string]interface{} `json:"data,omitempty"` - Level Level `json:"level,omitempty"` - Timestamp time.Time `json:"timestamp"` -} - -// TODO: provide constants for known breadcrumb types. -// See https://develop.sentry.dev/sdk/event-payloads/breadcrumbs/#breadcrumb-types. - -// MarshalJSON converts the Breadcrumb struct to JSON. -func (b *Breadcrumb) MarshalJSON() ([]byte, error) { - // We want to omit time.Time zero values, otherwise the server will try to - // interpret dates too far in the past. However, encoding/json doesn't - // support the "omitempty" option for struct types. See - // https://golang.org/issues/11939. - // - // We overcome the limitation and achieve what we want by shadowing fields - // and a few type tricks. - - // breadcrumb aliases Breadcrumb to allow calling json.Marshal without an - // infinite loop. It preserves all fields while none of the attached - // methods. - type breadcrumb Breadcrumb - - if b.Timestamp.IsZero() { - return json.Marshal(struct { - // Embed all of the fields of Breadcrumb. - *breadcrumb - // Timestamp shadows the original Timestamp field and is meant to - // remain nil, triggering the omitempty behavior. - Timestamp json.RawMessage `json:"timestamp,omitempty"` - }{breadcrumb: (*breadcrumb)(b)}) - } - return json.Marshal((*breadcrumb)(b)) -} - -// Attachment allows associating files with your events to aid in investigation. -// An event may contain one or more attachments. -type Attachment struct { - Filename string - ContentType string - Payload []byte -} - -// User describes the user associated with an Event. If this is used, at least -// an ID or an IP address should be provided. -type User struct { - ID string `json:"id,omitempty"` - Email string `json:"email,omitempty"` - IPAddress string `json:"ip_address,omitempty"` - Username string `json:"username,omitempty"` - Name string `json:"name,omitempty"` - Segment string `json:"segment,omitempty"` - Data map[string]string `json:"data,omitempty"` -} - -func (u User) IsEmpty() bool { - if len(u.ID) > 0 { - return false - } - - if len(u.Email) > 0 { - return false - } - - if len(u.IPAddress) > 0 { - return false - } - - if len(u.Username) > 0 { - return false - } - - if len(u.Name) > 0 { - return false - } - - if len(u.Segment) > 0 { - return false - } - - if len(u.Data) > 0 { - return false - } - - return true -} - -// Request contains information on a HTTP request related to the event. -type Request struct { - URL string `json:"url,omitempty"` - Method string `json:"method,omitempty"` - Data string `json:"data,omitempty"` - QueryString string `json:"query_string,omitempty"` - Cookies string `json:"cookies,omitempty"` - Headers map[string]string `json:"headers,omitempty"` - Env map[string]string `json:"env,omitempty"` -} - -var sensitiveHeaders = map[string]struct{}{ - "Authorization": {}, - "Proxy-Authorization": {}, - "Cookie": {}, - "X-Forwarded-For": {}, - "X-Real-Ip": {}, -} - -// NewRequest returns a new Sentry Request from the given http.Request. -// -// NewRequest avoids operations that depend on network access. In particular, it -// does not read r.Body. -func NewRequest(r *http.Request) *Request { - protocol := schemeHTTP - if r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https" { - protocol = schemeHTTPS - } - url := fmt.Sprintf("%s://%s%s", protocol, r.Host, r.URL.Path) - - var cookies string - var env map[string]string - headers := map[string]string{} - - if client := CurrentHub().Client(); client != nil && client.options.SendDefaultPII { - // We read only the first Cookie header because of the specification: - // https://tools.ietf.org/html/rfc6265#section-5.4 - // When the user agent generates an HTTP request, the user agent MUST NOT - // attach more than one Cookie header field. - cookies = r.Header.Get("Cookie") - - for k, v := range r.Header { - headers[k] = strings.Join(v, ",") - } - - if addr, port, err := net.SplitHostPort(r.RemoteAddr); err == nil { - env = map[string]string{"REMOTE_ADDR": addr, "REMOTE_PORT": port} - } - } else { - for k, v := range r.Header { - if _, ok := sensitiveHeaders[k]; !ok { - headers[k] = strings.Join(v, ",") - } - } - } - - headers["Host"] = r.Host - - return &Request{ - URL: url, - Method: r.Method, - QueryString: r.URL.RawQuery, - Cookies: cookies, - Headers: headers, - Env: env, - } -} - -// Mechanism is the mechanism by which an exception was generated and handled. -type Mechanism struct { - Type string `json:"type,omitempty"` - Description string `json:"description,omitempty"` - HelpLink string `json:"help_link,omitempty"` - Source string `json:"source,omitempty"` - Handled *bool `json:"handled,omitempty"` - ParentID *int `json:"parent_id,omitempty"` - ExceptionID int `json:"exception_id"` - IsExceptionGroup bool `json:"is_exception_group,omitempty"` - Data map[string]any `json:"data,omitempty"` -} - -// SetUnhandled indicates that the exception is an unhandled exception, i.e. -// from a panic. -func (m *Mechanism) SetUnhandled() { - h := false - m.Handled = &h -} - -// Exception specifies an error that occurred. -type Exception struct { - Type string `json:"type,omitempty"` // used as the main issue title - Value string `json:"value,omitempty"` // used as the main issue subtitle - Module string `json:"module,omitempty"` - ThreadID uint64 `json:"thread_id,omitempty"` - Stacktrace *Stacktrace `json:"stacktrace,omitempty"` - Mechanism *Mechanism `json:"mechanism,omitempty"` -} - -// SDKMetaData is a struct to stash data which is needed at some point in the SDK's event processing pipeline -// but which shouldn't get send to Sentry. -type SDKMetaData struct { - dsc DynamicSamplingContext - transactionProfile *profileInfo -} - -// Contains information about how the name of the transaction was determined. -type TransactionInfo struct { - Source TransactionSource `json:"source,omitempty"` -} - -// The DebugMeta interface is not used in Golang apps, but may be populated -// when proxying Events from other platforms, like iOS, Android, and the -// Web. (See: https://develop.sentry.dev/sdk/event-payloads/debugmeta/ ). -type DebugMeta struct { - SdkInfo *DebugMetaSdkInfo `json:"sdk_info,omitempty"` - Images []DebugMetaImage `json:"images,omitempty"` -} - -type DebugMetaSdkInfo struct { - SdkName string `json:"sdk_name,omitempty"` - VersionMajor int `json:"version_major,omitempty"` - VersionMinor int `json:"version_minor,omitempty"` - VersionPatchlevel int `json:"version_patchlevel,omitempty"` -} - -type DebugMetaImage struct { - Type string `json:"type,omitempty"` // all - ImageAddr string `json:"image_addr,omitempty"` // macho,elf,pe - ImageSize int `json:"image_size,omitempty"` // macho,elf,pe - DebugID string `json:"debug_id,omitempty"` // macho,elf,pe,wasm,sourcemap - DebugFile string `json:"debug_file,omitempty"` // macho,elf,pe,wasm - CodeID string `json:"code_id,omitempty"` // macho,elf,pe,wasm - CodeFile string `json:"code_file,omitempty"` // macho,elf,pe,wasm,sourcemap - ImageVmaddr string `json:"image_vmaddr,omitempty"` // macho,elf,pe - Arch string `json:"arch,omitempty"` // macho,elf,pe - UUID string `json:"uuid,omitempty"` // proguard -} - -// EventID is a hexadecimal string representing a unique uuid4 for an Event. -// An EventID must be 32 characters long, lowercase and not have any dashes. -type EventID string - -type Context = map[string]interface{} - -// Event is the fundamental data structure that is sent to Sentry. -type Event struct { - Breadcrumbs []*Breadcrumb `json:"breadcrumbs,omitempty"` - Contexts map[string]Context `json:"contexts,omitempty"` - Dist string `json:"dist,omitempty"` - Environment string `json:"environment,omitempty"` - EventID EventID `json:"event_id,omitempty"` - Extra map[string]interface{} `json:"extra,omitempty"` - Fingerprint []string `json:"fingerprint,omitempty"` - Level Level `json:"level,omitempty"` - Message string `json:"message,omitempty"` - Platform string `json:"platform,omitempty"` - Release string `json:"release,omitempty"` - Sdk SdkInfo `json:"sdk,omitempty"` - ServerName string `json:"server_name,omitempty"` - Threads []Thread `json:"threads,omitempty"` - Tags map[string]string `json:"tags,omitempty"` - Timestamp time.Time `json:"timestamp"` - Transaction string `json:"transaction,omitempty"` - User User `json:"user,omitempty"` - Logger string `json:"logger,omitempty"` - Modules map[string]string `json:"modules,omitempty"` - Request *Request `json:"request,omitempty"` - Exception []Exception `json:"exception,omitempty"` - DebugMeta *DebugMeta `json:"debug_meta,omitempty"` - Attachments []*Attachment `json:"-"` - Metrics []Metric `json:"-"` - - // The fields below are only relevant for transactions. - - Type string `json:"type,omitempty"` - StartTime time.Time `json:"start_timestamp"` - Spans []*Span `json:"spans,omitempty"` - TransactionInfo *TransactionInfo `json:"transaction_info,omitempty"` - - // The fields below are only relevant for crons/check ins - - CheckIn *CheckIn `json:"check_in,omitempty"` - MonitorConfig *MonitorConfig `json:"monitor_config,omitempty"` - - // The fields below are not part of the final JSON payload. - - sdkMetaData SDKMetaData -} - -// SetException appends the unwrapped errors to the event's exception list. -// -// maxErrorDepth is the maximum depth of the error chain we will look -// into while unwrapping the errors. If maxErrorDepth is -1, we will -// unwrap all errors in the chain. -func (e *Event) SetException(exception error, maxErrorDepth int) { - if exception == nil { - return - } - - err := exception - - for i := 0; err != nil && (i < maxErrorDepth || maxErrorDepth == -1); i++ { - // Add the current error to the exception slice with its details - e.Exception = append(e.Exception, Exception{ - Value: err.Error(), - Type: reflect.TypeOf(err).String(), - Stacktrace: ExtractStacktrace(err), - }) - - // Attempt to unwrap the error using the standard library's Unwrap method. - // If errors.Unwrap returns nil, it means either there is no error to unwrap, - // or the error does not implement the Unwrap method. - unwrappedErr := errors.Unwrap(err) - - if unwrappedErr != nil { - // The error was successfully unwrapped using the standard library's Unwrap method. - err = unwrappedErr - continue - } - - cause, ok := err.(interface{ Cause() error }) - if !ok { - // We cannot unwrap the error further. - break - } - - // The error implements the Cause method, indicating it may have been wrapped - // using the github.com/pkg/errors package. - err = cause.Cause() - } - - // Add a trace of the current stack to the most recent error in a chain if - // it doesn't have a stack trace yet. - // We only add to the most recent error to avoid duplication and because the - // current stack is most likely unrelated to errors deeper in the chain. - if e.Exception[0].Stacktrace == nil { - e.Exception[0].Stacktrace = NewStacktrace() - } - - if len(e.Exception) <= 1 { - return - } - - // event.Exception should be sorted such that the most recent error is last. - reverse(e.Exception) - - for i := range e.Exception { - e.Exception[i].Mechanism = &Mechanism{ - IsExceptionGroup: true, - ExceptionID: i, - } - if i == 0 { - continue - } - e.Exception[i].Mechanism.ParentID = Pointer(i - 1) - } -} - -// TODO: Event.Contexts map[string]interface{} => map[string]EventContext, -// to prevent accidentally storing T when we mean *T. -// For example, the TraceContext must be stored as *TraceContext to pick up the -// MarshalJSON method (and avoid copying). -// type EventContext interface{ EventContext() } - -// MarshalJSON converts the Event struct to JSON. -func (e *Event) MarshalJSON() ([]byte, error) { - // We want to omit time.Time zero values, otherwise the server will try to - // interpret dates too far in the past. However, encoding/json doesn't - // support the "omitempty" option for struct types. See - // https://golang.org/issues/11939. - // - // We overcome the limitation and achieve what we want by shadowing fields - // and a few type tricks. - if e.Type == transactionType { - return e.transactionMarshalJSON() - } else if e.Type == checkInType { - return e.checkInMarshalJSON() - } - return e.defaultMarshalJSON() -} - -func (e *Event) defaultMarshalJSON() ([]byte, error) { - // event aliases Event to allow calling json.Marshal without an infinite - // loop. It preserves all fields while none of the attached methods. - type event Event - - // errorEvent is like Event with shadowed fields for customizing JSON - // marshaling. - type errorEvent struct { - *event - - // Timestamp shadows the original Timestamp field. It allows us to - // include the timestamp when non-zero and omit it otherwise. - Timestamp json.RawMessage `json:"timestamp,omitempty"` - - // The fields below are not part of error events and only make sense to - // be sent for transactions. They shadow the respective fields in Event - // and are meant to remain nil, triggering the omitempty behavior. - - Type json.RawMessage `json:"type,omitempty"` - StartTime json.RawMessage `json:"start_timestamp,omitempty"` - Spans json.RawMessage `json:"spans,omitempty"` - TransactionInfo json.RawMessage `json:"transaction_info,omitempty"` - } - - x := errorEvent{event: (*event)(e)} - if !e.Timestamp.IsZero() { - b, err := e.Timestamp.MarshalJSON() - if err != nil { - return nil, err - } - x.Timestamp = b - } - return json.Marshal(x) -} - -func (e *Event) transactionMarshalJSON() ([]byte, error) { - // event aliases Event to allow calling json.Marshal without an infinite - // loop. It preserves all fields while none of the attached methods. - type event Event - - // transactionEvent is like Event with shadowed fields for customizing JSON - // marshaling. - type transactionEvent struct { - *event - - // The fields below shadow the respective fields in Event. They allow us - // to include timestamps when non-zero and omit them otherwise. - - StartTime json.RawMessage `json:"start_timestamp,omitempty"` - Timestamp json.RawMessage `json:"timestamp,omitempty"` - } - - x := transactionEvent{event: (*event)(e)} - if !e.Timestamp.IsZero() { - b, err := e.Timestamp.MarshalJSON() - if err != nil { - return nil, err - } - x.Timestamp = b - } - if !e.StartTime.IsZero() { - b, err := e.StartTime.MarshalJSON() - if err != nil { - return nil, err - } - x.StartTime = b - } - return json.Marshal(x) -} - -func (e *Event) checkInMarshalJSON() ([]byte, error) { - checkIn := serializedCheckIn{ - CheckInID: string(e.CheckIn.ID), - MonitorSlug: e.CheckIn.MonitorSlug, - Status: e.CheckIn.Status, - Duration: e.CheckIn.Duration.Seconds(), - Release: e.Release, - Environment: e.Environment, - MonitorConfig: nil, - } - - if e.MonitorConfig != nil { - checkIn.MonitorConfig = &MonitorConfig{ - Schedule: e.MonitorConfig.Schedule, - CheckInMargin: e.MonitorConfig.CheckInMargin, - MaxRuntime: e.MonitorConfig.MaxRuntime, - Timezone: e.MonitorConfig.Timezone, - } - } - - return json.Marshal(checkIn) -} - -// NewEvent creates a new Event. -func NewEvent() *Event { - return &Event{ - Contexts: make(map[string]Context), - Extra: make(map[string]interface{}), - Tags: make(map[string]string), - Modules: make(map[string]string), - } -} - -// Thread specifies threads that were running at the time of an event. -type Thread struct { - ID string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Stacktrace *Stacktrace `json:"stacktrace,omitempty"` - Crashed bool `json:"crashed,omitempty"` - Current bool `json:"current,omitempty"` -} - -// EventHint contains information that can be associated with an Event. -type EventHint struct { - Data interface{} - EventID string - OriginalException error - RecoveredException interface{} - Context context.Context - Request *http.Request - Response *http.Response -} diff --git a/vendor/github.com/getsentry/sentry-go/internal/debug/transport.go b/vendor/github.com/getsentry/sentry-go/internal/debug/transport.go deleted file mode 100644 index 199c3a303..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/debug/transport.go +++ /dev/null @@ -1,79 +0,0 @@ -package debug - -import ( - "bytes" - "fmt" - "io" - "net/http" - "net/http/httptrace" - "net/http/httputil" -) - -// Transport implements http.RoundTripper and can be used to wrap other HTTP -// transports for debugging, normally http.DefaultTransport. -type Transport struct { - http.RoundTripper - Output io.Writer - // Dump controls whether to dump HTTP request and responses. - Dump bool - // Trace enables usage of net/http/httptrace. - Trace bool -} - -func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { - var buf bytes.Buffer - if t.Dump { - b, err := httputil.DumpRequestOut(req, true) - if err != nil { - panic(err) - } - _, err = buf.Write(ensureTrailingNewline(b)) - if err != nil { - panic(err) - } - } - if t.Trace { - trace := &httptrace.ClientTrace{ - DNSDone: func(di httptrace.DNSDoneInfo) { - fmt.Fprintf(&buf, "* DNS %v → %v\n", req.Host, di.Addrs) - }, - GotConn: func(ci httptrace.GotConnInfo) { - fmt.Fprintf(&buf, "* Connection local=%v remote=%v", ci.Conn.LocalAddr(), ci.Conn.RemoteAddr()) - if ci.Reused { - fmt.Fprint(&buf, " (reused)") - } - if ci.WasIdle { - fmt.Fprintf(&buf, " (idle %v)", ci.IdleTime) - } - fmt.Fprintln(&buf) - }, - } - req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) - } - resp, err := t.RoundTripper.RoundTrip(req) - if err != nil { - return nil, err - } - if t.Dump { - b, err := httputil.DumpResponse(resp, true) - if err != nil { - panic(err) - } - _, err = buf.Write(ensureTrailingNewline(b)) - if err != nil { - panic(err) - } - } - _, err = io.Copy(t.Output, &buf) - if err != nil { - panic(err) - } - return resp, nil -} - -func ensureTrailingNewline(b []byte) []byte { - if len(b) > 0 && b[len(b)-1] != '\n' { - b = append(b, '\n') - } - return b -} diff --git a/vendor/github.com/getsentry/sentry-go/internal/otel/baggage/README.md b/vendor/github.com/getsentry/sentry-go/internal/otel/baggage/README.md deleted file mode 100644 index 2718f314b..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/otel/baggage/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## Why do we have this "otel/baggage" folder? - -The root sentry-go SDK (namely, the Dynamic Sampling functionality) needs an implementation of the [baggage spec](https://www.w3.org/TR/baggage/). -For that reason, we've taken the existing baggage implementation from the [opentelemetry-go](https://github.com/open-telemetry/opentelemetry-go/) repository, and fixed a few things that in our opinion were violating the specification. - -These issues are: -1. Baggage string value `one%20two` should be properly parsed as "one two" -1. Baggage string value `one+two` should be parsed as "one+two" -1. Go string value "one two" should be encoded as `one%20two` (percent encoding), and NOT as `one+two` (URL query encoding). -1. Go string value "1=1" might be encoded as `1=1`, because the spec says: "Note, value MAY contain any number of the equal sign (=) characters. Parsers MUST NOT assume that the equal sign is only used to separate key and value.". `1%3D1` is also valid, but to simplify the implementation we're not doing it. - -Changes were made in this PR: https://github.com/getsentry/sentry-go/pull/568 diff --git a/vendor/github.com/getsentry/sentry-go/internal/otel/baggage/baggage.go b/vendor/github.com/getsentry/sentry-go/internal/otel/baggage/baggage.go deleted file mode 100644 index 180655506..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/otel/baggage/baggage.go +++ /dev/null @@ -1,604 +0,0 @@ -// Adapted from https://github.com/open-telemetry/opentelemetry-go/blob/c21b6b6bb31a2f74edd06e262f1690f3f6ea3d5c/baggage/baggage.go -// -// Copyright The OpenTelemetry 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. - -package baggage - -import ( - "errors" - "fmt" - "net/url" - "regexp" - "strings" - "unicode/utf8" - - "github.com/getsentry/sentry-go/internal/otel/baggage/internal/baggage" -) - -const ( - maxMembers = 180 - maxBytesPerMembers = 4096 - maxBytesPerBaggageString = 8192 - - listDelimiter = "," - keyValueDelimiter = "=" - propertyDelimiter = ";" - - keyDef = `([\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5a\x5e-\x7a\x7c\x7e]+)` - valueDef = `([\x21\x23-\x2b\x2d-\x3a\x3c-\x5B\x5D-\x7e]*)` - keyValueDef = `\s*` + keyDef + `\s*` + keyValueDelimiter + `\s*` + valueDef + `\s*` -) - -var ( - keyRe = regexp.MustCompile(`^` + keyDef + `$`) - valueRe = regexp.MustCompile(`^` + valueDef + `$`) - propertyRe = regexp.MustCompile(`^(?:\s*` + keyDef + `\s*|` + keyValueDef + `)$`) -) - -var ( - errInvalidKey = errors.New("invalid key") - errInvalidValue = errors.New("invalid value") - errInvalidProperty = errors.New("invalid baggage list-member property") - errInvalidMember = errors.New("invalid baggage list-member") - errMemberNumber = errors.New("too many list-members in baggage-string") - errMemberBytes = errors.New("list-member too large") - errBaggageBytes = errors.New("baggage-string too large") -) - -// Property is an additional metadata entry for a baggage list-member. -type Property struct { - key, value string - - // hasValue indicates if a zero-value value means the property does not - // have a value or if it was the zero-value. - hasValue bool - - // hasData indicates whether the created property contains data or not. - // Properties that do not contain data are invalid with no other check - // required. - hasData bool -} - -// NewKeyProperty returns a new Property for key. -// -// If key is invalid, an error will be returned. -func NewKeyProperty(key string) (Property, error) { - if !keyRe.MatchString(key) { - return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidKey, key) - } - - p := Property{key: key, hasData: true} - return p, nil -} - -// NewKeyValueProperty returns a new Property for key with value. -// -// If key or value are invalid, an error will be returned. -func NewKeyValueProperty(key, value string) (Property, error) { - if !keyRe.MatchString(key) { - return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidKey, key) - } - if !valueRe.MatchString(value) { - return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidValue, value) - } - - p := Property{ - key: key, - value: value, - hasValue: true, - hasData: true, - } - return p, nil -} - -func newInvalidProperty() Property { - return Property{} -} - -// parseProperty attempts to decode a Property from the passed string. It -// returns an error if the input is invalid according to the W3C Baggage -// specification. -func parseProperty(property string) (Property, error) { - if property == "" { - return newInvalidProperty(), nil - } - - match := propertyRe.FindStringSubmatch(property) - if len(match) != 4 { - return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidProperty, property) - } - - p := Property{hasData: true} - if match[1] != "" { - p.key = match[1] - } else { - p.key = match[2] - p.value = match[3] - p.hasValue = true - } - - return p, nil -} - -// validate ensures p conforms to the W3C Baggage specification, returning an -// error otherwise. -func (p Property) validate() error { - errFunc := func(err error) error { - return fmt.Errorf("invalid property: %w", err) - } - - if !p.hasData { - return errFunc(fmt.Errorf("%w: %q", errInvalidProperty, p)) - } - - if !keyRe.MatchString(p.key) { - return errFunc(fmt.Errorf("%w: %q", errInvalidKey, p.key)) - } - if p.hasValue && !valueRe.MatchString(p.value) { - return errFunc(fmt.Errorf("%w: %q", errInvalidValue, p.value)) - } - if !p.hasValue && p.value != "" { - return errFunc(errors.New("inconsistent value")) - } - return nil -} - -// Key returns the Property key. -func (p Property) Key() string { - return p.key -} - -// Value returns the Property value. Additionally, a boolean value is returned -// indicating if the returned value is the empty if the Property has a value -// that is empty or if the value is not set. -func (p Property) Value() (string, bool) { - return p.value, p.hasValue -} - -// String encodes Property into a string compliant with the W3C Baggage -// specification. -func (p Property) String() string { - if p.hasValue { - return fmt.Sprintf("%s%s%v", p.key, keyValueDelimiter, p.value) - } - return p.key -} - -type properties []Property - -func fromInternalProperties(iProps []baggage.Property) properties { - if len(iProps) == 0 { - return nil - } - - props := make(properties, len(iProps)) - for i, p := range iProps { - props[i] = Property{ - key: p.Key, - value: p.Value, - hasValue: p.HasValue, - } - } - return props -} - -func (p properties) asInternal() []baggage.Property { - if len(p) == 0 { - return nil - } - - iProps := make([]baggage.Property, len(p)) - for i, prop := range p { - iProps[i] = baggage.Property{ - Key: prop.key, - Value: prop.value, - HasValue: prop.hasValue, - } - } - return iProps -} - -func (p properties) Copy() properties { - if len(p) == 0 { - return nil - } - - props := make(properties, len(p)) - copy(props, p) - return props -} - -// validate ensures each Property in p conforms to the W3C Baggage -// specification, returning an error otherwise. -func (p properties) validate() error { - for _, prop := range p { - if err := prop.validate(); err != nil { - return err - } - } - return nil -} - -// String encodes properties into a string compliant with the W3C Baggage -// specification. -func (p properties) String() string { - props := make([]string, len(p)) - for i, prop := range p { - props[i] = prop.String() - } - return strings.Join(props, propertyDelimiter) -} - -// Member is a list-member of a baggage-string as defined by the W3C Baggage -// specification. -type Member struct { - key, value string - properties properties - - // hasData indicates whether the created property contains data or not. - // Properties that do not contain data are invalid with no other check - // required. - hasData bool -} - -// NewMember returns a new Member from the passed arguments. The key will be -// used directly while the value will be url decoded after validation. An error -// is returned if the created Member would be invalid according to the W3C -// Baggage specification. -func NewMember(key, value string, props ...Property) (Member, error) { - m := Member{ - key: key, - value: value, - properties: properties(props).Copy(), - hasData: true, - } - if err := m.validate(); err != nil { - return newInvalidMember(), err - } - //// NOTE(anton): I don't think we need to unescape here - // decodedValue, err := url.PathUnescape(value) - // if err != nil { - // return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value) - // } - // m.value = decodedValue - return m, nil -} - -func newInvalidMember() Member { - return Member{} -} - -// parseMember attempts to decode a Member from the passed string. It returns -// an error if the input is invalid according to the W3C Baggage -// specification. -func parseMember(member string) (Member, error) { - if n := len(member); n > maxBytesPerMembers { - return newInvalidMember(), fmt.Errorf("%w: %d", errMemberBytes, n) - } - - var ( - key, value string - props properties - ) - - parts := strings.SplitN(member, propertyDelimiter, 2) - switch len(parts) { - case 2: - // Parse the member properties. - for _, pStr := range strings.Split(parts[1], propertyDelimiter) { - p, err := parseProperty(pStr) - if err != nil { - return newInvalidMember(), err - } - props = append(props, p) - } - fallthrough - case 1: - // Parse the member key/value pair. - - // Take into account a value can contain equal signs (=). - kv := strings.SplitN(parts[0], keyValueDelimiter, 2) - if len(kv) != 2 { - return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidMember, member) - } - // "Leading and trailing whitespaces are allowed but MUST be trimmed - // when converting the header into a data structure." - key = strings.TrimSpace(kv[0]) - value = strings.TrimSpace(kv[1]) - var err error - if !keyRe.MatchString(key) { - return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidKey, key) - } - if !valueRe.MatchString(value) { - return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value) - } - decodedValue, err := url.PathUnescape(value) - if err != nil { - return newInvalidMember(), fmt.Errorf("%w: %q", err, value) - } - value = decodedValue - default: - // This should never happen unless a developer has changed the string - // splitting somehow. Panic instead of failing silently and allowing - // the bug to slip past the CI checks. - panic("failed to parse baggage member") - } - - return Member{key: key, value: value, properties: props, hasData: true}, nil -} - -// validate ensures m conforms to the W3C Baggage specification. -// A key is just an ASCII string, but a value must be URL encoded UTF-8, -// returning an error otherwise. -func (m Member) validate() error { - if !m.hasData { - return fmt.Errorf("%w: %q", errInvalidMember, m) - } - - if !keyRe.MatchString(m.key) { - return fmt.Errorf("%w: %q", errInvalidKey, m.key) - } - //// NOTE(anton): IMO it's too early to validate the value here. - // if !valueRe.MatchString(m.value) { - // return fmt.Errorf("%w: %q", errInvalidValue, m.value) - // } - return m.properties.validate() -} - -// Key returns the Member key. -func (m Member) Key() string { return m.key } - -// Value returns the Member value. -func (m Member) Value() string { return m.value } - -// Properties returns a copy of the Member properties. -func (m Member) Properties() []Property { return m.properties.Copy() } - -// String encodes Member into a string compliant with the W3C Baggage -// specification. -func (m Member) String() string { - // A key is just an ASCII string, but a value is URL encoded UTF-8. - s := fmt.Sprintf("%s%s%s", m.key, keyValueDelimiter, percentEncodeValue(m.value)) - if len(m.properties) > 0 { - s = fmt.Sprintf("%s%s%s", s, propertyDelimiter, m.properties.String()) - } - return s -} - -// percentEncodeValue encodes the baggage value, using percent-encoding for -// disallowed octets. -func percentEncodeValue(s string) string { - const upperhex = "0123456789ABCDEF" - var sb strings.Builder - - for byteIndex, width := 0, 0; byteIndex < len(s); byteIndex += width { - runeValue, w := utf8.DecodeRuneInString(s[byteIndex:]) - width = w - char := string(runeValue) - if valueRe.MatchString(char) && char != "%" { - // The character is returned as is, no need to percent-encode - sb.WriteString(char) - } else { - // We need to percent-encode each byte of the multi-octet character - for j := 0; j < width; j++ { - b := s[byteIndex+j] - sb.WriteByte('%') - // Bitwise operations are inspired by "net/url" - sb.WriteByte(upperhex[b>>4]) - sb.WriteByte(upperhex[b&15]) - } - } - } - return sb.String() -} - -// Baggage is a list of baggage members representing the baggage-string as -// defined by the W3C Baggage specification. -type Baggage struct { //nolint:golint - list baggage.List -} - -// New returns a new valid Baggage. It returns an error if it results in a -// Baggage exceeding limits set in that specification. -// -// It expects all the provided members to have already been validated. -func New(members ...Member) (Baggage, error) { - if len(members) == 0 { - return Baggage{}, nil - } - - b := make(baggage.List) - for _, m := range members { - if !m.hasData { - return Baggage{}, errInvalidMember - } - - // OpenTelemetry resolves duplicates by last-one-wins. - b[m.key] = baggage.Item{ - Value: m.value, - Properties: m.properties.asInternal(), - } - } - - // Check member numbers after deduplication. - if len(b) > maxMembers { - return Baggage{}, errMemberNumber - } - - bag := Baggage{b} - if n := len(bag.String()); n > maxBytesPerBaggageString { - return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n) - } - - return bag, nil -} - -// Parse attempts to decode a baggage-string from the passed string. It -// returns an error if the input is invalid according to the W3C Baggage -// specification. -// -// If there are duplicate list-members contained in baggage, the last one -// defined (reading left-to-right) will be the only one kept. This diverges -// from the W3C Baggage specification which allows duplicate list-members, but -// conforms to the OpenTelemetry Baggage specification. -func Parse(bStr string) (Baggage, error) { - if bStr == "" { - return Baggage{}, nil - } - - if n := len(bStr); n > maxBytesPerBaggageString { - return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n) - } - - b := make(baggage.List) - for _, memberStr := range strings.Split(bStr, listDelimiter) { - m, err := parseMember(memberStr) - if err != nil { - return Baggage{}, err - } - // OpenTelemetry resolves duplicates by last-one-wins. - b[m.key] = baggage.Item{ - Value: m.value, - Properties: m.properties.asInternal(), - } - } - - // OpenTelemetry does not allow for duplicate list-members, but the W3C - // specification does. Now that we have deduplicated, ensure the baggage - // does not exceed list-member limits. - if len(b) > maxMembers { - return Baggage{}, errMemberNumber - } - - return Baggage{b}, nil -} - -// Member returns the baggage list-member identified by key. -// -// If there is no list-member matching the passed key the returned Member will -// be a zero-value Member. -// The returned member is not validated, as we assume the validation happened -// when it was added to the Baggage. -func (b Baggage) Member(key string) Member { - v, ok := b.list[key] - if !ok { - // We do not need to worry about distinguishing between the situation - // where a zero-valued Member is included in the Baggage because a - // zero-valued Member is invalid according to the W3C Baggage - // specification (it has an empty key). - return newInvalidMember() - } - - return Member{ - key: key, - value: v.Value, - properties: fromInternalProperties(v.Properties), - hasData: true, - } -} - -// Members returns all the baggage list-members. -// The order of the returned list-members does not have significance. -// -// The returned members are not validated, as we assume the validation happened -// when they were added to the Baggage. -func (b Baggage) Members() []Member { - if len(b.list) == 0 { - return nil - } - - members := make([]Member, 0, len(b.list)) - for k, v := range b.list { - members = append(members, Member{ - key: k, - value: v.Value, - properties: fromInternalProperties(v.Properties), - hasData: true, - }) - } - return members -} - -// SetMember returns a copy the Baggage with the member included. If the -// baggage contains a Member with the same key the existing Member is -// replaced. -// -// If member is invalid according to the W3C Baggage specification, an error -// is returned with the original Baggage. -func (b Baggage) SetMember(member Member) (Baggage, error) { - if !member.hasData { - return b, errInvalidMember - } - - n := len(b.list) - if _, ok := b.list[member.key]; !ok { - n++ - } - list := make(baggage.List, n) - - for k, v := range b.list { - // Do not copy if we are just going to overwrite. - if k == member.key { - continue - } - list[k] = v - } - - list[member.key] = baggage.Item{ - Value: member.value, - Properties: member.properties.asInternal(), - } - - return Baggage{list: list}, nil -} - -// DeleteMember returns a copy of the Baggage with the list-member identified -// by key removed. -func (b Baggage) DeleteMember(key string) Baggage { - n := len(b.list) - if _, ok := b.list[key]; ok { - n-- - } - list := make(baggage.List, n) - - for k, v := range b.list { - if k == key { - continue - } - list[k] = v - } - - return Baggage{list: list} -} - -// Len returns the number of list-members in the Baggage. -func (b Baggage) Len() int { - return len(b.list) -} - -// String encodes Baggage into a string compliant with the W3C Baggage -// specification. The returned string will be invalid if the Baggage contains -// any invalid list-members. -func (b Baggage) String() string { - members := make([]string, 0, len(b.list)) - for k, v := range b.list { - members = append(members, Member{ - key: k, - value: v.Value, - properties: fromInternalProperties(v.Properties), - }.String()) - } - return strings.Join(members, listDelimiter) -} diff --git a/vendor/github.com/getsentry/sentry-go/internal/otel/baggage/internal/baggage/baggage.go b/vendor/github.com/getsentry/sentry-go/internal/otel/baggage/internal/baggage/baggage.go deleted file mode 100644 index ea99ccbff..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/otel/baggage/internal/baggage/baggage.go +++ /dev/null @@ -1,45 +0,0 @@ -// Adapted from https://github.com/open-telemetry/opentelemetry-go/blob/c21b6b6bb31a2f74edd06e262f1690f3f6ea3d5c/internal/baggage/baggage.go -// -// Copyright The OpenTelemetry 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. - -/* -Package baggage provides base types and functionality to store and retrieve -baggage in Go context. This package exists because the OpenTracing bridge to -OpenTelemetry needs to synchronize state whenever baggage for a context is -modified and that context contains an OpenTracing span. If it were not for -this need this package would not need to exist and the -`go.opentelemetry.io/otel/baggage` package would be the singular place where -W3C baggage is handled. -*/ -package baggage - -// List is the collection of baggage members. The W3C allows for duplicates, -// but OpenTelemetry does not, therefore, this is represented as a map. -type List map[string]Item - -// Item is the value and metadata properties part of a list-member. -type Item struct { - Value string - Properties []Property -} - -// Property is a metadata entry for a list-member. -type Property struct { - Key, Value string - - // HasValue indicates if a zero-value value means the property does not - // have a value or if it was the zero-value. - HasValue bool -} diff --git a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/category.go b/vendor/github.com/getsentry/sentry-go/internal/ratelimit/category.go deleted file mode 100644 index 2db76d2bf..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/category.go +++ /dev/null @@ -1,45 +0,0 @@ -package ratelimit - -import ( - "strings" - - "golang.org/x/text/cases" - "golang.org/x/text/language" -) - -// Reference: -// https://github.com/getsentry/relay/blob/0424a2e017d193a93918053c90cdae9472d164bf/relay-common/src/constants.rs#L116-L127 - -// Category classifies supported payload types that can be ingested by Sentry -// and, therefore, rate limited. -type Category string - -// Known rate limit categories. As a special case, the CategoryAll applies to -// all known payload types. -const ( - CategoryAll Category = "" - CategoryError Category = "error" - CategoryTransaction Category = "transaction" -) - -// knownCategories is the set of currently known categories. Other categories -// are ignored for the purpose of rate-limiting. -var knownCategories = map[Category]struct{}{ - CategoryAll: {}, - CategoryError: {}, - CategoryTransaction: {}, -} - -// String returns the category formatted for debugging. -func (c Category) String() string { - if c == "" { - return "CategoryAll" - } - - caser := cases.Title(language.English) - rv := "Category" - for _, w := range strings.Fields(string(c)) { - rv += caser.String(w) - } - return rv -} diff --git a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/deadline.go b/vendor/github.com/getsentry/sentry-go/internal/ratelimit/deadline.go deleted file mode 100644 index c00258335..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/deadline.go +++ /dev/null @@ -1,22 +0,0 @@ -package ratelimit - -import "time" - -// A Deadline is a time instant when a rate limit expires. -type Deadline time.Time - -// After reports whether the deadline d is after other. -func (d Deadline) After(other Deadline) bool { - return time.Time(d).After(time.Time(other)) -} - -// Equal reports whether d and e represent the same deadline. -func (d Deadline) Equal(e Deadline) bool { - return time.Time(d).Equal(time.Time(e)) -} - -// String returns the deadline formatted for debugging. -func (d Deadline) String() string { - // Like time.Time.String, but without the monotonic clock reading. - return time.Time(d).Round(0).String() -} diff --git a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/doc.go b/vendor/github.com/getsentry/sentry-go/internal/ratelimit/doc.go deleted file mode 100644 index 80b9fdda2..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package ratelimit provides tools to work with rate limits imposed by Sentry's -// data ingestion pipeline. -package ratelimit diff --git a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/map.go b/vendor/github.com/getsentry/sentry-go/internal/ratelimit/map.go deleted file mode 100644 index e590430ec..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/map.go +++ /dev/null @@ -1,64 +0,0 @@ -package ratelimit - -import ( - "net/http" - "time" -) - -// Map maps categories to rate limit deadlines. -// -// A rate limit is in effect for a given category if either the category's -// deadline or the deadline for the special CategoryAll has not yet expired. -// -// Use IsRateLimited to check whether a category is rate-limited. -type Map map[Category]Deadline - -// IsRateLimited returns true if the category is currently rate limited. -func (m Map) IsRateLimited(c Category) bool { - return m.isRateLimited(c, time.Now()) -} - -func (m Map) isRateLimited(c Category, now time.Time) bool { - return m.Deadline(c).After(Deadline(now)) -} - -// Deadline returns the deadline when the rate limit for the given category or -// the special CategoryAll expire, whichever is furthest into the future. -func (m Map) Deadline(c Category) Deadline { - categoryDeadline := m[c] - allDeadline := m[CategoryAll] - if categoryDeadline.After(allDeadline) { - return categoryDeadline - } - return allDeadline -} - -// Merge merges the other map into m. -// -// If a category appears in both maps, the deadline that is furthest into the -// future is preserved. -func (m Map) Merge(other Map) { - for c, d := range other { - if d.After(m[c]) { - m[c] = d - } - } -} - -// FromResponse returns a rate limit map from an HTTP response. -func FromResponse(r *http.Response) Map { - return fromResponse(r, time.Now()) -} - -func fromResponse(r *http.Response, now time.Time) Map { - s := r.Header.Get("X-Sentry-Rate-Limits") - if s != "" { - return parseXSentryRateLimits(s, now) - } - if r.StatusCode == http.StatusTooManyRequests { - s := r.Header.Get("Retry-After") - deadline, _ := parseRetryAfter(s, now) - return Map{CategoryAll: deadline} - } - return Map{} -} diff --git a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/rate_limits.go b/vendor/github.com/getsentry/sentry-go/internal/ratelimit/rate_limits.go deleted file mode 100644 index 579297e42..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/rate_limits.go +++ /dev/null @@ -1,76 +0,0 @@ -package ratelimit - -import ( - "errors" - "math" - "strconv" - "strings" - "time" -) - -var errInvalidXSRLRetryAfter = errors.New("invalid retry-after value") - -// parseXSentryRateLimits returns a RateLimits map by parsing an input string in -// the format of the X-Sentry-Rate-Limits header. -// -// Example -// -// X-Sentry-Rate-Limits: 60:transaction, 2700:default;error;security -// -// This will rate limit transactions for the next 60 seconds and errors for the -// next 2700 seconds. -// -// Limits for unknown categories are ignored. -func parseXSentryRateLimits(s string, now time.Time) Map { - // https://github.com/getsentry/relay/blob/0424a2e017d193a93918053c90cdae9472d164bf/relay-server/src/utils/rate_limits.rs#L44-L82 - m := make(Map, len(knownCategories)) - for _, limit := range strings.Split(s, ",") { - limit = strings.TrimSpace(limit) - if limit == "" { - continue - } - components := strings.Split(limit, ":") - if len(components) == 0 { - continue - } - retryAfter, err := parseXSRLRetryAfter(strings.TrimSpace(components[0]), now) - if err != nil { - continue - } - categories := "" - if len(components) > 1 { - categories = components[1] - } - for _, category := range strings.Split(categories, ";") { - c := Category(strings.ToLower(strings.TrimSpace(category))) - if _, ok := knownCategories[c]; !ok { - // skip unknown categories, keep m small - continue - } - // always keep the deadline furthest into the future - if retryAfter.After(m[c]) { - m[c] = retryAfter - } - } - } - return m -} - -// parseXSRLRetryAfter parses a string into a retry-after rate limit deadline. -// -// Valid input is a number, possibly signed and possibly floating-point, -// indicating the number of seconds to wait before sending another request. -// Negative values are treated as zero. Fractional values are rounded to the -// next integer. -func parseXSRLRetryAfter(s string, now time.Time) (Deadline, error) { - // https://github.com/getsentry/relay/blob/0424a2e017d193a93918053c90cdae9472d164bf/relay-quotas/src/rate_limit.rs#L88-L96 - f, err := strconv.ParseFloat(s, 64) - if err != nil { - return Deadline{}, errInvalidXSRLRetryAfter - } - d := time.Duration(math.Ceil(math.Max(f, 0.0))) * time.Second - if d < 0 { - d = 0 - } - return Deadline(now.Add(d)), nil -} diff --git a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/retry_after.go b/vendor/github.com/getsentry/sentry-go/internal/ratelimit/retry_after.go deleted file mode 100644 index 576e29dcd..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/ratelimit/retry_after.go +++ /dev/null @@ -1,40 +0,0 @@ -package ratelimit - -import ( - "errors" - "strconv" - "time" -) - -const defaultRetryAfter = 1 * time.Minute - -var errInvalidRetryAfter = errors.New("invalid input") - -// parseRetryAfter parses a string s as in the standard Retry-After HTTP header -// and returns a deadline until when requests are rate limited and therefore new -// requests should not be sent. The input may be either a date or a non-negative -// integer number of seconds. -// -// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After -// -// parseRetryAfter always returns a usable deadline, even in case of an error. -// -// This is the original rate limiting mechanism used by Sentry, superseeded by -// the X-Sentry-Rate-Limits response header. -func parseRetryAfter(s string, now time.Time) (Deadline, error) { - if s == "" { - goto invalid - } - if n, err := strconv.Atoi(s); err == nil { - if n < 0 { - goto invalid - } - d := time.Duration(n) * time.Second - return Deadline(now.Add(d)), nil - } - if date, err := time.Parse(time.RFC1123, s); err == nil { - return Deadline(date), nil - } -invalid: - return Deadline(now.Add(defaultRetryAfter)), errInvalidRetryAfter -} diff --git a/vendor/github.com/getsentry/sentry-go/internal/traceparser/README.md b/vendor/github.com/getsentry/sentry-go/internal/traceparser/README.md deleted file mode 100644 index 78964587b..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/traceparser/README.md +++ /dev/null @@ -1,15 +0,0 @@ -## Benchmark results - -``` -goos: windows -goarch: amd64 -pkg: github.com/getsentry/sentry-go/internal/trace -cpu: 12th Gen Intel(R) Core(TM) i7-12700K -BenchmarkEqualBytes-20 44323621 26.08 ns/op -BenchmarkStringEqual-20 60980257 18.27 ns/op -BenchmarkEqualPrefix-20 41369181 31.12 ns/op -BenchmarkFullParse-20 702012 1507 ns/op 1353.42 MB/s 1024 B/op 6 allocs/op -BenchmarkFramesIterator-20 1229971 969.3 ns/op 896 B/op 5 allocs/op -BenchmarkFramesReversedIterator-20 1271061 944.5 ns/op 896 B/op 5 allocs/op -BenchmarkSplitOnly-20 2250800 534.0 ns/op 3818.23 MB/s 128 B/op 1 allocs/op -``` diff --git a/vendor/github.com/getsentry/sentry-go/internal/traceparser/parser.go b/vendor/github.com/getsentry/sentry-go/internal/traceparser/parser.go deleted file mode 100644 index 8a7aab327..000000000 --- a/vendor/github.com/getsentry/sentry-go/internal/traceparser/parser.go +++ /dev/null @@ -1,217 +0,0 @@ -package traceparser - -import ( - "bytes" - "strconv" -) - -var blockSeparator = []byte("\n\n") -var lineSeparator = []byte("\n") - -// Parses multi-stacktrace text dump produced by runtime.Stack([]byte, all=true). -// The parser prioritizes performance but requires the input to be well-formed in order to return correct data. -// See https://github.com/golang/go/blob/go1.20.4/src/runtime/mprof.go#L1191 -func Parse(data []byte) TraceCollection { - var it = TraceCollection{} - if len(data) > 0 { - it.blocks = bytes.Split(data, blockSeparator) - } - return it -} - -type TraceCollection struct { - blocks [][]byte -} - -func (it TraceCollection) Length() int { - return len(it.blocks) -} - -// Returns the stacktrace item at the given index. -func (it *TraceCollection) Item(i int) Trace { - // The first item may have a leading data separator and the last one may have a trailing one. - // Note: Trim() doesn't make a copy for single-character cutset under 0x80. It will just slice the original. - var data []byte - switch { - case i == 0: - data = bytes.TrimLeft(it.blocks[i], "\n") - case i == len(it.blocks)-1: - data = bytes.TrimRight(it.blocks[i], "\n") - default: - data = it.blocks[i] - } - - var splitAt = bytes.IndexByte(data, '\n') - if splitAt < 0 { - return Trace{header: data} - } - - return Trace{ - header: data[:splitAt], - data: data[splitAt+1:], - } -} - -// Trace represents a single stacktrace block, identified by a Goroutine ID and a sequence of Frames. -type Trace struct { - header []byte - data []byte -} - -var goroutinePrefix = []byte("goroutine ") - -// GoID parses the Goroutine ID from the header. -func (t *Trace) GoID() (id uint64) { - if bytes.HasPrefix(t.header, goroutinePrefix) { - var line = t.header[len(goroutinePrefix):] - var splitAt = bytes.IndexByte(line, ' ') - if splitAt >= 0 { - id, _ = strconv.ParseUint(string(line[:splitAt]), 10, 64) - } - } - return id -} - -// UniqueIdentifier can be used as a map key to identify the trace. -func (t *Trace) UniqueIdentifier() []byte { - return t.data -} - -func (t *Trace) Frames() FrameIterator { - var lines = bytes.Split(t.data, lineSeparator) - return FrameIterator{lines: lines, i: 0, len: len(lines)} -} - -func (t *Trace) FramesReversed() ReverseFrameIterator { - var lines = bytes.Split(t.data, lineSeparator) - return ReverseFrameIterator{lines: lines, i: len(lines)} -} - -const framesElided = "...additional frames elided..." - -// FrameIterator iterates over stack frames. -type FrameIterator struct { - lines [][]byte - i int - len int -} - -// Next returns the next frame, or nil if there are none. -func (it *FrameIterator) Next() Frame { - return Frame{it.popLine(), it.popLine()} -} - -func (it *FrameIterator) popLine() []byte { - switch { - case it.i >= it.len: - return nil - case string(it.lines[it.i]) == framesElided: - it.i++ - return it.popLine() - default: - it.i++ - return it.lines[it.i-1] - } -} - -// HasNext return true if there are values to be read. -func (it *FrameIterator) HasNext() bool { - return it.i < it.len -} - -// LengthUpperBound returns the maximum number of elements this stacks may contain. -// The actual number may be lower because of elided frames. As such, the returned value -// cannot be used to iterate over the frames but may be used to reserve capacity. -func (it *FrameIterator) LengthUpperBound() int { - return it.len / 2 -} - -// ReverseFrameIterator iterates over stack frames in reverse order. -type ReverseFrameIterator struct { - lines [][]byte - i int -} - -// Next returns the next frame, or nil if there are none. -func (it *ReverseFrameIterator) Next() Frame { - var line2 = it.popLine() - return Frame{it.popLine(), line2} -} - -func (it *ReverseFrameIterator) popLine() []byte { - it.i-- - switch { - case it.i < 0: - return nil - case string(it.lines[it.i]) == framesElided: - return it.popLine() - default: - return it.lines[it.i] - } -} - -// HasNext return true if there are values to be read. -func (it *ReverseFrameIterator) HasNext() bool { - return it.i > 1 -} - -// LengthUpperBound returns the maximum number of elements this stacks may contain. -// The actual number may be lower because of elided frames. As such, the returned value -// cannot be used to iterate over the frames but may be used to reserve capacity. -func (it *ReverseFrameIterator) LengthUpperBound() int { - return len(it.lines) / 2 -} - -type Frame struct { - line1 []byte - line2 []byte -} - -// UniqueIdentifier can be used as a map key to identify the frame. -func (f *Frame) UniqueIdentifier() []byte { - // line2 contains file path, line number and program-counter offset from the beginning of a function - // e.g. C:/Users/name/scoop/apps/go/current/src/testing/testing.go:1906 +0x63a - return f.line2 -} - -var createdByPrefix = []byte("created by ") - -func (f *Frame) Func() []byte { - if bytes.HasPrefix(f.line1, createdByPrefix) { - // Since go1.21, the line ends with " in goroutine X", saying which goroutine created this one. - // We currently don't have use for that so just remove it. - var line = f.line1[len(createdByPrefix):] - var spaceAt = bytes.IndexByte(line, ' ') - if spaceAt < 0 { - return line - } - return line[:spaceAt] - } - - var end = bytes.LastIndexByte(f.line1, '(') - if end >= 0 { - return f.line1[:end] - } - - return f.line1 -} - -func (f *Frame) File() (path []byte, lineNumber int) { - var line = f.line2 - if len(line) > 0 && line[0] == '\t' { - line = line[1:] - } - - var splitAt = bytes.IndexByte(line, ' ') - if splitAt >= 0 { - line = line[:splitAt] - } - - splitAt = bytes.LastIndexByte(line, ':') - if splitAt < 0 { - return line, 0 - } - - lineNumber, _ = strconv.Atoi(string(line[splitAt+1:])) - return line[:splitAt], lineNumber -} diff --git a/vendor/github.com/getsentry/sentry-go/metrics.go b/vendor/github.com/getsentry/sentry-go/metrics.go deleted file mode 100644 index bcc94e88d..000000000 --- a/vendor/github.com/getsentry/sentry-go/metrics.go +++ /dev/null @@ -1,427 +0,0 @@ -package sentry - -import ( - "fmt" - "hash/crc32" - "math" - "regexp" - "sort" - "strings" -) - -type ( - NumberOrString interface { - int | string - } - - void struct{} -) - -var ( - member void - keyRegex = regexp.MustCompile(`[^a-zA-Z0-9_/.-]+`) - valueRegex = regexp.MustCompile(`[^\w\d\s_:/@\.{}\[\]$-]+`) - unitRegex = regexp.MustCompile(`[^a-z]+`) -) - -type MetricUnit struct { - unit string -} - -func (m MetricUnit) toString() string { - return m.unit -} - -func NanoSecond() MetricUnit { - return MetricUnit{ - "nanosecond", - } -} - -func MicroSecond() MetricUnit { - return MetricUnit{ - "microsecond", - } -} - -func MilliSecond() MetricUnit { - return MetricUnit{ - "millisecond", - } -} - -func Second() MetricUnit { - return MetricUnit{ - "second", - } -} - -func Minute() MetricUnit { - return MetricUnit{ - "minute", - } -} - -func Hour() MetricUnit { - return MetricUnit{ - "hour", - } -} - -func Day() MetricUnit { - return MetricUnit{ - "day", - } -} - -func Week() MetricUnit { - return MetricUnit{ - "week", - } -} - -func Bit() MetricUnit { - return MetricUnit{ - "bit", - } -} - -func Byte() MetricUnit { - return MetricUnit{ - "byte", - } -} - -func KiloByte() MetricUnit { - return MetricUnit{ - "kilobyte", - } -} - -func KibiByte() MetricUnit { - return MetricUnit{ - "kibibyte", - } -} - -func MegaByte() MetricUnit { - return MetricUnit{ - "megabyte", - } -} - -func MebiByte() MetricUnit { - return MetricUnit{ - "mebibyte", - } -} - -func GigaByte() MetricUnit { - return MetricUnit{ - "gigabyte", - } -} - -func GibiByte() MetricUnit { - return MetricUnit{ - "gibibyte", - } -} - -func TeraByte() MetricUnit { - return MetricUnit{ - "terabyte", - } -} - -func TebiByte() MetricUnit { - return MetricUnit{ - "tebibyte", - } -} - -func PetaByte() MetricUnit { - return MetricUnit{ - "petabyte", - } -} - -func PebiByte() MetricUnit { - return MetricUnit{ - "pebibyte", - } -} - -func ExaByte() MetricUnit { - return MetricUnit{ - "exabyte", - } -} - -func ExbiByte() MetricUnit { - return MetricUnit{ - "exbibyte", - } -} - -func Ratio() MetricUnit { - return MetricUnit{ - "ratio", - } -} - -func Percent() MetricUnit { - return MetricUnit{ - "percent", - } -} - -func CustomUnit(unit string) MetricUnit { - return MetricUnit{ - unitRegex.ReplaceAllString(unit, ""), - } -} - -type Metric interface { - GetType() string - GetTags() map[string]string - GetKey() string - GetUnit() string - GetTimestamp() int64 - SerializeValue() string - SerializeTags() string -} - -type abstractMetric struct { - key string - unit MetricUnit - tags map[string]string - // A unix timestamp (full seconds elapsed since 1970-01-01 00:00 UTC). - timestamp int64 -} - -func (am abstractMetric) GetTags() map[string]string { - return am.tags -} - -func (am abstractMetric) GetKey() string { - return am.key -} - -func (am abstractMetric) GetUnit() string { - return am.unit.toString() -} - -func (am abstractMetric) GetTimestamp() int64 { - return am.timestamp -} - -func (am abstractMetric) SerializeTags() string { - var sb strings.Builder - - values := make([]string, 0, len(am.tags)) - for k := range am.tags { - values = append(values, k) - } - sortSlice(values) - - for _, key := range values { - val := sanitizeValue(am.tags[key]) - key = sanitizeKey(key) - sb.WriteString(fmt.Sprintf("%s:%s,", key, val)) - } - s := sb.String() - if len(s) > 0 { - s = s[:len(s)-1] - } - return s -} - -// Counter Metric. -type CounterMetric struct { - value float64 - abstractMetric -} - -func (c *CounterMetric) Add(value float64) { - c.value += value -} - -func (c CounterMetric) GetType() string { - return "c" -} - -func (c CounterMetric) SerializeValue() string { - return fmt.Sprintf(":%v", c.value) -} - -// timestamp: A unix timestamp (full seconds elapsed since 1970-01-01 00:00 UTC). -func NewCounterMetric(key string, unit MetricUnit, tags map[string]string, timestamp int64, value float64) CounterMetric { - am := abstractMetric{ - key, - unit, - tags, - timestamp, - } - - return CounterMetric{ - value, - am, - } -} - -// Distribution Metric. -type DistributionMetric struct { - values []float64 - abstractMetric -} - -func (d *DistributionMetric) Add(value float64) { - d.values = append(d.values, value) -} - -func (d DistributionMetric) GetType() string { - return "d" -} - -func (d DistributionMetric) SerializeValue() string { - var sb strings.Builder - for _, el := range d.values { - sb.WriteString(fmt.Sprintf(":%v", el)) - } - return sb.String() -} - -// timestamp: A unix timestamp (full seconds elapsed since 1970-01-01 00:00 UTC). -func NewDistributionMetric(key string, unit MetricUnit, tags map[string]string, timestamp int64, value float64) DistributionMetric { - am := abstractMetric{ - key, - unit, - tags, - timestamp, - } - - return DistributionMetric{ - []float64{value}, - am, - } -} - -// Gauge Metric. -type GaugeMetric struct { - last float64 - min float64 - max float64 - sum float64 - count float64 - abstractMetric -} - -func (g *GaugeMetric) Add(value float64) { - g.last = value - g.min = math.Min(g.min, value) - g.max = math.Max(g.max, value) - g.sum += value - g.count++ -} - -func (g GaugeMetric) GetType() string { - return "g" -} - -func (g GaugeMetric) SerializeValue() string { - return fmt.Sprintf(":%v:%v:%v:%v:%v", g.last, g.min, g.max, g.sum, g.count) -} - -// timestamp: A unix timestamp (full seconds elapsed since 1970-01-01 00:00 UTC). -func NewGaugeMetric(key string, unit MetricUnit, tags map[string]string, timestamp int64, value float64) GaugeMetric { - am := abstractMetric{ - key, - unit, - tags, - timestamp, - } - - return GaugeMetric{ - value, // last - value, // min - value, // max - value, // sum - value, // count - am, - } -} - -// Set Metric. -type SetMetric[T NumberOrString] struct { - values map[T]void - abstractMetric -} - -func (s *SetMetric[T]) Add(value T) { - s.values[value] = member -} - -func (s SetMetric[T]) GetType() string { - return "s" -} - -func (s SetMetric[T]) SerializeValue() string { - _hash := func(s string) uint32 { - return crc32.ChecksumIEEE([]byte(s)) - } - - values := make([]T, 0, len(s.values)) - for k := range s.values { - values = append(values, k) - } - sortSlice(values) - - var sb strings.Builder - for _, el := range values { - switch any(el).(type) { - case int: - sb.WriteString(fmt.Sprintf(":%v", el)) - case string: - s := fmt.Sprintf("%v", el) - sb.WriteString(fmt.Sprintf(":%d", _hash(s))) - } - } - - return sb.String() -} - -// timestamp: A unix timestamp (full seconds elapsed since 1970-01-01 00:00 UTC). -func NewSetMetric[T NumberOrString](key string, unit MetricUnit, tags map[string]string, timestamp int64, value T) SetMetric[T] { - am := abstractMetric{ - key, - unit, - tags, - timestamp, - } - - return SetMetric[T]{ - map[T]void{ - value: member, - }, - am, - } -} - -func sanitizeKey(s string) string { - return keyRegex.ReplaceAllString(s, "_") -} - -func sanitizeValue(s string) string { - return valueRegex.ReplaceAllString(s, "") -} - -type Ordered interface { - ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string -} - -func sortSlice[T Ordered](s []T) { - sort.Slice(s, func(i, j int) bool { - return s[i] < s[j] - }) -} diff --git a/vendor/github.com/getsentry/sentry-go/profile_sample.go b/vendor/github.com/getsentry/sentry-go/profile_sample.go deleted file mode 100644 index 650598721..000000000 --- a/vendor/github.com/getsentry/sentry-go/profile_sample.go +++ /dev/null @@ -1,73 +0,0 @@ -package sentry - -// Based on https://github.com/getsentry/vroom/blob/d11c26063e802d66b9a592c4010261746ca3dfa4/internal/sample/sample.go - -import ( - "time" -) - -type ( - profileDevice struct { - Architecture string `json:"architecture"` - Classification string `json:"classification"` - Locale string `json:"locale"` - Manufacturer string `json:"manufacturer"` - Model string `json:"model"` - } - - profileOS struct { - BuildNumber string `json:"build_number"` - Name string `json:"name"` - Version string `json:"version"` - } - - profileRuntime struct { - Name string `json:"name"` - Version string `json:"version"` - } - - profileSample struct { - ElapsedSinceStartNS uint64 `json:"elapsed_since_start_ns"` - StackID int `json:"stack_id"` - ThreadID uint64 `json:"thread_id"` - } - - profileThreadMetadata struct { - Name string `json:"name,omitempty"` - Priority int `json:"priority,omitempty"` - } - - profileStack []int - - profileTrace struct { - Frames []*Frame `json:"frames"` - Samples []profileSample `json:"samples"` - Stacks []profileStack `json:"stacks"` - ThreadMetadata map[uint64]*profileThreadMetadata `json:"thread_metadata"` - } - - profileInfo struct { - DebugMeta *DebugMeta `json:"debug_meta,omitempty"` - Device profileDevice `json:"device"` - Environment string `json:"environment,omitempty"` - EventID string `json:"event_id"` - OS profileOS `json:"os"` - Platform string `json:"platform"` - Release string `json:"release"` - Dist string `json:"dist"` - Runtime profileRuntime `json:"runtime"` - Timestamp time.Time `json:"timestamp"` - Trace *profileTrace `json:"profile"` - Transaction profileTransaction `json:"transaction"` - Version string `json:"version"` - } - - // see https://github.com/getsentry/vroom/blob/a91e39416723ec44fc54010257020eeaf9a77cbd/internal/transaction/transaction.go - profileTransaction struct { - ActiveThreadID uint64 `json:"active_thread_id"` - DurationNS uint64 `json:"duration_ns,omitempty"` - ID EventID `json:"id"` - Name string `json:"name"` - TraceID string `json:"trace_id"` - } -) diff --git a/vendor/github.com/getsentry/sentry-go/profiler.go b/vendor/github.com/getsentry/sentry-go/profiler.go deleted file mode 100644 index c0b858cc1..000000000 --- a/vendor/github.com/getsentry/sentry-go/profiler.go +++ /dev/null @@ -1,451 +0,0 @@ -package sentry - -import ( - "container/ring" - "strconv" - - "runtime" - "sync" - "sync/atomic" - "time" - - "github.com/getsentry/sentry-go/internal/traceparser" -) - -// Start a profiler that collects samples continuously, with a buffer of up to 30 seconds. -// Later, you can collect a slice from this buffer, producing a Trace. -func startProfiling(startTime time.Time) profiler { - onProfilerStart() - - p := newProfiler(startTime) - - // Wait for the profiler to finish setting up before returning to the caller. - started := make(chan struct{}) - go p.run(started) - - if _, ok := <-started; ok { - return p - } - return nil -} - -type profiler interface { - // GetSlice returns a slice of the profiled data between the given times. - GetSlice(startTime, endTime time.Time) *profilerResult - Stop(wait bool) -} - -type profilerResult struct { - callerGoID uint64 - trace *profileTrace -} - -func getCurrentGoID() uint64 { - // We shouldn't panic but let's be super safe. - defer func() { - if err := recover(); err != nil { - Logger.Printf("Profiler panic in getCurrentGoID(): %v\n", err) - } - }() - - // Buffer to read the stack trace into. We should be good with a small buffer because we only need the first line. - var stacksBuffer = make([]byte, 100) - var n = runtime.Stack(stacksBuffer, false) - if n > 0 { - var traces = traceparser.Parse(stacksBuffer[0:n]) - if traces.Length() > 0 { - var trace = traces.Item(0) - return trace.GoID() - } - } - return 0 -} - -const profilerSamplingRateHz = 101 // 101 Hz; not 100 Hz because of the lockstep sampling (https://stackoverflow.com/a/45471031/1181370) -const profilerSamplingRate = time.Second / profilerSamplingRateHz -const stackBufferMaxGrowth = 512 * 1024 -const stackBufferLimit = 10 * 1024 * 1024 -const profilerRuntimeLimit = 30 // seconds - -type profileRecorder struct { - startTime time.Time - stopSignal chan struct{} - stopped int64 - mutex sync.RWMutex - testProfilerPanic int64 - - // Map from runtime.StackRecord.Stack0 to an index in stacks. - stackIndexes map[string]int - stacks []profileStack - newStacks []profileStack // New stacks created in the current interation. - stackKeyBuffer []byte - - // Map from runtime.Frame.PC to an index in frames. - frameIndexes map[string]int - frames []*Frame - newFrames []*Frame // New frames created in the current interation. - - // We keep a ring buffer of 30 seconds worth of samples, so that we can later slice it. - // Each bucket is a slice of samples all taken at the same time. - samplesBucketsHead *ring.Ring - - // Buffer to read current stacks - will grow automatically up to stackBufferLimit. - stacksBuffer []byte -} - -func newProfiler(startTime time.Time) *profileRecorder { - // Pre-allocate the profile trace for the currently active number of routines & 100 ms worth of samples. - // Other coefficients are just guesses of what might be a good starting point to avoid allocs on short runs. - return &profileRecorder{ - startTime: startTime, - stopSignal: make(chan struct{}, 1), - - stackIndexes: make(map[string]int, 32), - stacks: make([]profileStack, 0, 32), - newStacks: make([]profileStack, 0, 32), - - frameIndexes: make(map[string]int, 128), - frames: make([]*Frame, 0, 128), - newFrames: make([]*Frame, 0, 128), - - samplesBucketsHead: ring.New(profilerRuntimeLimit * profilerSamplingRateHz), - - // A buffer of 2 KiB per goroutine stack looks like a good starting point (empirically determined). - stacksBuffer: make([]byte, runtime.NumGoroutine()*2048), - } -} - -// This allows us to test whether panic during profiling are handled correctly and don't block execution. -// If the number is lower than 0, profilerGoroutine() will panic immedately. -// If the number is higher than 0, profiler.onTick() will panic when the given samples-set index is being collected. -var testProfilerPanic int64 -var profilerRunning int64 - -func (p *profileRecorder) run(started chan struct{}) { - // Code backup for manual test debugging: - // if !atomic.CompareAndSwapInt64(&profilerRunning, 0, 1) { - // panic("Only one profiler can be running at a time") - // } - - // We shouldn't panic but let's be super safe. - defer func() { - if err := recover(); err != nil { - Logger.Printf("Profiler panic in run(): %v\n", err) - } - atomic.StoreInt64(&testProfilerPanic, 0) - close(started) - p.stopSignal <- struct{}{} - atomic.StoreInt64(&p.stopped, 1) - atomic.StoreInt64(&profilerRunning, 0) - }() - - p.testProfilerPanic = atomic.LoadInt64(&testProfilerPanic) - if p.testProfilerPanic < 0 { - Logger.Printf("Profiler panicking during startup because testProfilerPanic == %v\n", p.testProfilerPanic) - panic("This is an expected panic in profilerGoroutine() during tests") - } - - // Collect the first sample immediately. - p.onTick() - - // Periodically collect stacks, starting after profilerSamplingRate has passed. - collectTicker := profilerTickerFactory(profilerSamplingRate) - defer collectTicker.Stop() - var tickerChannel = collectTicker.TickSource() - - started <- struct{}{} - - for { - select { - case <-tickerChannel: - p.onTick() - collectTicker.Ticked() - case <-p.stopSignal: - return - } - } -} - -func (p *profileRecorder) Stop(wait bool) { - if atomic.LoadInt64(&p.stopped) == 1 { - return - } - p.stopSignal <- struct{}{} - if wait { - <-p.stopSignal - } -} - -func (p *profileRecorder) GetSlice(startTime, endTime time.Time) *profilerResult { - // Unlikely edge cases - profiler wasn't running at all or the given times are invalid in relation to each other. - if p.startTime.After(endTime) || startTime.After(endTime) { - return nil - } - - var relativeStartNS = uint64(0) - if p.startTime.Before(startTime) { - relativeStartNS = uint64(startTime.Sub(p.startTime).Nanoseconds()) - } - var relativeEndNS = uint64(endTime.Sub(p.startTime).Nanoseconds()) - - samplesCount, bucketsReversed, trace := p.getBuckets(relativeStartNS, relativeEndNS) - if samplesCount == 0 { - return nil - } - - var result = &profilerResult{ - callerGoID: getCurrentGoID(), - trace: trace, - } - - trace.Samples = make([]profileSample, samplesCount) - trace.ThreadMetadata = make(map[uint64]*profileThreadMetadata, len(bucketsReversed[0].goIDs)) - var s = samplesCount - 1 - for _, bucket := range bucketsReversed { - var elapsedSinceStartNS = bucket.relativeTimeNS - relativeStartNS - for i, goID := range bucket.goIDs { - trace.Samples[s].ElapsedSinceStartNS = elapsedSinceStartNS - trace.Samples[s].ThreadID = goID - trace.Samples[s].StackID = bucket.stackIDs[i] - s-- - - if _, goroutineExists := trace.ThreadMetadata[goID]; !goroutineExists { - trace.ThreadMetadata[goID] = &profileThreadMetadata{ - Name: "Goroutine " + strconv.FormatUint(goID, 10), - } - } - } - } - - return result -} - -// Collect all buckets of samples in the given time range while holding a read lock. -func (p *profileRecorder) getBuckets(relativeStartNS, relativeEndNS uint64) (samplesCount int, buckets []*profileSamplesBucket, trace *profileTrace) { - p.mutex.RLock() - defer p.mutex.RUnlock() - - // sampleBucketsHead points at the last stored bucket so it's a good starting point to search backwards for the end. - var end = p.samplesBucketsHead - for end.Value != nil && end.Value.(*profileSamplesBucket).relativeTimeNS > relativeEndNS { - end = end.Prev() - } - - // Edge case - no items stored before the given endTime. - if end.Value == nil { - return 0, nil, nil - } - - { // Find the first item after the given startTime. - var start = end - var prevBucket *profileSamplesBucket - samplesCount = 0 - buckets = make([]*profileSamplesBucket, 0, int64((relativeEndNS-relativeStartNS)/uint64(profilerSamplingRate.Nanoseconds()))+1) - for start.Value != nil { - var bucket = start.Value.(*profileSamplesBucket) - - // If this bucket's time is before the requests start time, don't collect it (and stop iterating further). - if bucket.relativeTimeNS < relativeStartNS { - break - } - - // If this bucket time is greater than previous the bucket's time, we have exhausted the whole ring buffer - // before we were able to find the start time. That means the start time is not present and we must break. - // This happens if the slice duration exceeds the ring buffer capacity. - if prevBucket != nil && bucket.relativeTimeNS > prevBucket.relativeTimeNS { - break - } - - samplesCount += len(bucket.goIDs) - buckets = append(buckets, bucket) - - start = start.Prev() - prevBucket = bucket - } - } - - // Edge case - if the period requested was too short and we haven't collected enough samples. - if len(buckets) < 2 { - return 0, nil, nil - } - - trace = &profileTrace{ - Frames: p.frames, - Stacks: p.stacks, - } - return samplesCount, buckets, trace -} - -func (p *profileRecorder) onTick() { - elapsedNs := time.Since(p.startTime).Nanoseconds() - - if p.testProfilerPanic > 0 { - Logger.Printf("Profiler testProfilerPanic == %v\n", p.testProfilerPanic) - if p.testProfilerPanic == 1 { - Logger.Println("Profiler panicking onTick()") - panic("This is an expected panic in Profiler.OnTick() during tests") - } - p.testProfilerPanic-- - } - - records := p.collectRecords() - p.processRecords(uint64(elapsedNs), records) - - // Free up some memory if we don't need such a large buffer anymore. - if len(p.stacksBuffer) > len(records)*3 { - p.stacksBuffer = make([]byte, len(records)*3) - } -} - -func (p *profileRecorder) collectRecords() []byte { - for { - // Capture stacks for all existing goroutines. - // Note: runtime.GoroutineProfile() would be better but we can't use it at the moment because - // it doesn't give us `gid` for each routine, see https://github.com/golang/go/issues/59663 - n := runtime.Stack(p.stacksBuffer, true) - - // If we couldn't read everything, increase the buffer and try again. - if n >= len(p.stacksBuffer) && n < stackBufferLimit { - var newSize = n * 2 - if newSize > n+stackBufferMaxGrowth { - newSize = n + stackBufferMaxGrowth - } - if newSize > stackBufferLimit { - newSize = stackBufferLimit - } - p.stacksBuffer = make([]byte, newSize) - } else { - return p.stacksBuffer[0:n] - } - } -} - -func (p *profileRecorder) processRecords(elapsedNs uint64, stacksBuffer []byte) { - var traces = traceparser.Parse(stacksBuffer) - var length = traces.Length() - - // Shouldn't happen but let's be safe and don't store empty buckets. - if length == 0 { - return - } - - var bucket = &profileSamplesBucket{ - relativeTimeNS: elapsedNs, - stackIDs: make([]int, length), - goIDs: make([]uint64, length), - } - - // reset buffers - p.newFrames = p.newFrames[:0] - p.newStacks = p.newStacks[:0] - - for i := 0; i < length; i++ { - var stack = traces.Item(i) - bucket.stackIDs[i] = p.addStackTrace(stack) - bucket.goIDs[i] = stack.GoID() - } - - p.mutex.Lock() - defer p.mutex.Unlock() - - p.stacks = append(p.stacks, p.newStacks...) - p.frames = append(p.frames, p.newFrames...) - - p.samplesBucketsHead = p.samplesBucketsHead.Next() - p.samplesBucketsHead.Value = bucket -} - -func (p *profileRecorder) addStackTrace(capturedStack traceparser.Trace) int { - iter := capturedStack.Frames() - stack := make(profileStack, 0, iter.LengthUpperBound()) - - // Originally, we've used `capturedStack.UniqueIdentifier()` as a key but that was incorrect because it also - // contains function arguments and we want to group stacks by function name and file/line only. - // Instead, we need to parse frames and we use a list of their indexes as a key. - // We reuse the same buffer for each stack to avoid allocations; this is a hot spot. - var expectedBufferLen = cap(stack) * 5 // 4 bytes per frame + 1 byte for space - if cap(p.stackKeyBuffer) < expectedBufferLen { - p.stackKeyBuffer = make([]byte, 0, expectedBufferLen) - } else { - p.stackKeyBuffer = p.stackKeyBuffer[:0] - } - - for iter.HasNext() { - var frame = iter.Next() - if frameIndex := p.addFrame(frame); frameIndex >= 0 { - stack = append(stack, frameIndex) - - p.stackKeyBuffer = append(p.stackKeyBuffer, 0) // space - - // The following code is just like binary.AppendUvarint() which isn't yet available in Go 1.18. - x := uint64(frameIndex) + 1 - for x >= 0x80 { - p.stackKeyBuffer = append(p.stackKeyBuffer, byte(x)|0x80) - x >>= 7 - } - p.stackKeyBuffer = append(p.stackKeyBuffer, byte(x)) - } - } - - stackIndex, exists := p.stackIndexes[string(p.stackKeyBuffer)] - if !exists { - stackIndex = len(p.stacks) + len(p.newStacks) - p.newStacks = append(p.newStacks, stack) - p.stackIndexes[string(p.stackKeyBuffer)] = stackIndex - } - - return stackIndex -} - -func (p *profileRecorder) addFrame(capturedFrame traceparser.Frame) int { - // NOTE: Don't convert to string yet, it's expensive and compiler can avoid it when - // indexing into a map (only needs a copy when adding a new key to the map). - var key = capturedFrame.UniqueIdentifier() - - frameIndex, exists := p.frameIndexes[string(key)] - if !exists { - module, function := splitQualifiedFunctionName(string(capturedFrame.Func())) - file, line := capturedFrame.File() - frame := newFrame(module, function, string(file), line) - frameIndex = len(p.frames) + len(p.newFrames) - p.newFrames = append(p.newFrames, &frame) - p.frameIndexes[string(key)] = frameIndex - } - return frameIndex -} - -type profileSamplesBucket struct { - relativeTimeNS uint64 - stackIDs []int - goIDs []uint64 -} - -// A Ticker holds a channel that delivers “ticks” of a clock at intervals. -type profilerTicker interface { - // Stop turns off a ticker. After Stop, no more ticks will be sent. - Stop() - - // TickSource returns a read-only channel of ticks. - TickSource() <-chan time.Time - - // Ticked is called by the Profiler after a tick is processed to notify the ticker. Used for testing. - Ticked() -} - -type timeTicker struct { - *time.Ticker -} - -func (t *timeTicker) TickSource() <-chan time.Time { - return t.C -} - -func (t *timeTicker) Ticked() {} - -func profilerTickerFactoryDefault(d time.Duration) profilerTicker { - return &timeTicker{time.NewTicker(d)} -} - -// We allow overriding the ticker for tests. CI is terribly flaky -// because the time.Ticker doesn't guarantee regular ticks - they may come (a lot) later than the given interval. -var profilerTickerFactory = profilerTickerFactoryDefault diff --git a/vendor/github.com/getsentry/sentry-go/profiler_other.go b/vendor/github.com/getsentry/sentry-go/profiler_other.go deleted file mode 100644 index fbb79b0c6..000000000 --- a/vendor/github.com/getsentry/sentry-go/profiler_other.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !windows - -package sentry - -func onProfilerStart() {} diff --git a/vendor/github.com/getsentry/sentry-go/profiler_windows.go b/vendor/github.com/getsentry/sentry-go/profiler_windows.go deleted file mode 100644 index 332798247..000000000 --- a/vendor/github.com/getsentry/sentry-go/profiler_windows.go +++ /dev/null @@ -1,24 +0,0 @@ -package sentry - -import ( - "sync" - "syscall" -) - -// This works around the ticker resolution on Windows being ~15ms by default. -// See https://github.com/golang/go/issues/44343 -func setTimeTickerResolution() { - var winmmDLL = syscall.NewLazyDLL("winmm.dll") - if winmmDLL != nil { - var timeBeginPeriod = winmmDLL.NewProc("timeBeginPeriod") - if timeBeginPeriod != nil { - timeBeginPeriod.Call(uintptr(1)) - } - } -} - -var setupTickerResolutionOnce sync.Once - -func onProfilerStart() { - setupTickerResolutionOnce.Do(setTimeTickerResolution) -} diff --git a/vendor/github.com/getsentry/sentry-go/propagation_context.go b/vendor/github.com/getsentry/sentry-go/propagation_context.go deleted file mode 100644 index 7a0766a8a..000000000 --- a/vendor/github.com/getsentry/sentry-go/propagation_context.go +++ /dev/null @@ -1,90 +0,0 @@ -package sentry - -import ( - "crypto/rand" - "encoding/json" -) - -type PropagationContext struct { - TraceID TraceID `json:"trace_id"` - SpanID SpanID `json:"span_id"` - ParentSpanID SpanID `json:"parent_span_id"` - DynamicSamplingContext DynamicSamplingContext `json:"-"` -} - -func (p PropagationContext) MarshalJSON() ([]byte, error) { - type propagationContext PropagationContext - var parentSpanID string - if p.ParentSpanID != zeroSpanID { - parentSpanID = p.ParentSpanID.String() - } - return json.Marshal(struct { - *propagationContext - ParentSpanID string `json:"parent_span_id,omitempty"` - }{ - propagationContext: (*propagationContext)(&p), - ParentSpanID: parentSpanID, - }) -} - -func (p PropagationContext) Map() map[string]interface{} { - m := map[string]interface{}{ - "trace_id": p.TraceID, - "span_id": p.SpanID, - } - - if p.ParentSpanID != zeroSpanID { - m["parent_span_id"] = p.ParentSpanID - } - - return m -} - -func NewPropagationContext() PropagationContext { - p := PropagationContext{} - - if _, err := rand.Read(p.TraceID[:]); err != nil { - panic(err) - } - - if _, err := rand.Read(p.SpanID[:]); err != nil { - panic(err) - } - - return p -} - -func PropagationContextFromHeaders(trace, baggage string) (PropagationContext, error) { - p := NewPropagationContext() - - if _, err := rand.Read(p.SpanID[:]); err != nil { - panic(err) - } - - hasTrace := false - if trace != "" { - if tpc, valid := ParseTraceParentContext([]byte(trace)); valid { - hasTrace = true - p.TraceID = tpc.TraceID - p.ParentSpanID = tpc.ParentSpanID - } - } - - if baggage != "" { - dsc, err := DynamicSamplingContextFromHeader([]byte(baggage)) - if err != nil { - return PropagationContext{}, err - } - p.DynamicSamplingContext = dsc - } - - // In case a sentry-trace header is present but there are no sentry-related - // values in the baggage, create an empty, frozen DynamicSamplingContext. - if hasTrace && !p.DynamicSamplingContext.HasEntries() { - p.DynamicSamplingContext = DynamicSamplingContext{ - Frozen: true, - } - } - - return p, nil -} diff --git a/vendor/github.com/getsentry/sentry-go/scope.go b/vendor/github.com/getsentry/sentry-go/scope.go deleted file mode 100644 index 48621c94f..000000000 --- a/vendor/github.com/getsentry/sentry-go/scope.go +++ /dev/null @@ -1,475 +0,0 @@ -package sentry - -import ( - "bytes" - "io" - "net/http" - "sync" - "time" -) - -// Scope holds contextual data for the current scope. -// -// The scope is an object that can cloned efficiently and stores data that is -// locally relevant to an event. For instance the scope will hold recorded -// breadcrumbs and similar information. -// -// The scope can be interacted with in two ways. First, the scope is routinely -// updated with information by functions such as AddBreadcrumb which will modify -// the current scope. Second, the current scope can be configured through the -// ConfigureScope function or Hub method of the same name. -// -// The scope is meant to be modified but not inspected directly. When preparing -// an event for reporting, the current client adds information from the current -// scope into the event. -type Scope struct { - mu sync.RWMutex - breadcrumbs []*Breadcrumb - attachments []*Attachment - user User - tags map[string]string - contexts map[string]Context - extra map[string]interface{} - fingerprint []string - level Level - request *http.Request - // requestBody holds a reference to the original request.Body. - requestBody interface { - // Bytes returns bytes from the original body, lazily buffered as the - // original body is read. - Bytes() []byte - // Overflow returns true if the body is larger than the maximum buffer - // size. - Overflow() bool - } - eventProcessors []EventProcessor - - propagationContext PropagationContext - span *Span -} - -// NewScope creates a new Scope. -func NewScope() *Scope { - return &Scope{ - breadcrumbs: make([]*Breadcrumb, 0), - attachments: make([]*Attachment, 0), - tags: make(map[string]string), - contexts: make(map[string]Context), - extra: make(map[string]interface{}), - fingerprint: make([]string, 0), - propagationContext: NewPropagationContext(), - } -} - -// AddBreadcrumb adds new breadcrumb to the current scope -// and optionally throws the old one if limit is reached. -func (scope *Scope) AddBreadcrumb(breadcrumb *Breadcrumb, limit int) { - if breadcrumb.Timestamp.IsZero() { - breadcrumb.Timestamp = time.Now() - } - - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.breadcrumbs = append(scope.breadcrumbs, breadcrumb) - if len(scope.breadcrumbs) > limit { - scope.breadcrumbs = scope.breadcrumbs[1 : limit+1] - } -} - -// ClearBreadcrumbs clears all breadcrumbs from the current scope. -func (scope *Scope) ClearBreadcrumbs() { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.breadcrumbs = []*Breadcrumb{} -} - -// AddAttachment adds new attachment to the current scope. -func (scope *Scope) AddAttachment(attachment *Attachment) { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.attachments = append(scope.attachments, attachment) -} - -// ClearAttachments clears all attachments from the current scope. -func (scope *Scope) ClearAttachments() { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.attachments = []*Attachment{} -} - -// SetUser sets the user for the current scope. -func (scope *Scope) SetUser(user User) { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.user = user -} - -// SetRequest sets the request for the current scope. -func (scope *Scope) SetRequest(r *http.Request) { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.request = r - - if r == nil { - return - } - - // Don't buffer request body if we know it is oversized. - if r.ContentLength > maxRequestBodyBytes { - return - } - // Don't buffer if there is no body. - if r.Body == nil || r.Body == http.NoBody { - return - } - buf := &limitedBuffer{Capacity: maxRequestBodyBytes} - r.Body = readCloser{ - Reader: io.TeeReader(r.Body, buf), - Closer: r.Body, - } - scope.requestBody = buf -} - -// SetRequestBody sets the request body for the current scope. -// -// This method should only be called when the body bytes are already available -// in memory. Typically, the request body is buffered lazily from the -// Request.Body from SetRequest. -func (scope *Scope) SetRequestBody(b []byte) { - scope.mu.Lock() - defer scope.mu.Unlock() - - capacity := maxRequestBodyBytes - overflow := false - if len(b) > capacity { - overflow = true - b = b[:capacity] - } - scope.requestBody = &limitedBuffer{ - Capacity: capacity, - Buffer: *bytes.NewBuffer(b), - overflow: overflow, - } -} - -// maxRequestBodyBytes is the default maximum request body size to send to -// Sentry. -const maxRequestBodyBytes = 10 * 1024 - -// A limitedBuffer is like a bytes.Buffer, but limited to store at most Capacity -// bytes. Any writes past the capacity are silently discarded, similar to -// io.Discard. -type limitedBuffer struct { - Capacity int - - bytes.Buffer - overflow bool -} - -// Write implements io.Writer. -func (b *limitedBuffer) Write(p []byte) (n int, err error) { - // Silently ignore writes after overflow. - if b.overflow { - return len(p), nil - } - left := b.Capacity - b.Len() - if left < 0 { - left = 0 - } - if len(p) > left { - b.overflow = true - p = p[:left] - } - return b.Buffer.Write(p) -} - -// Overflow returns true if the limitedBuffer discarded bytes written to it. -func (b *limitedBuffer) Overflow() bool { - return b.overflow -} - -// readCloser combines an io.Reader and an io.Closer to implement io.ReadCloser. -type readCloser struct { - io.Reader - io.Closer -} - -// SetTag adds a tag to the current scope. -func (scope *Scope) SetTag(key, value string) { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.tags[key] = value -} - -// SetTags assigns multiple tags to the current scope. -func (scope *Scope) SetTags(tags map[string]string) { - scope.mu.Lock() - defer scope.mu.Unlock() - - for k, v := range tags { - scope.tags[k] = v - } -} - -// RemoveTag removes a tag from the current scope. -func (scope *Scope) RemoveTag(key string) { - scope.mu.Lock() - defer scope.mu.Unlock() - - delete(scope.tags, key) -} - -// SetContext adds a context to the current scope. -func (scope *Scope) SetContext(key string, value Context) { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.contexts[key] = value -} - -// SetContexts assigns multiple contexts to the current scope. -func (scope *Scope) SetContexts(contexts map[string]Context) { - scope.mu.Lock() - defer scope.mu.Unlock() - - for k, v := range contexts { - scope.contexts[k] = v - } -} - -// RemoveContext removes a context from the current scope. -func (scope *Scope) RemoveContext(key string) { - scope.mu.Lock() - defer scope.mu.Unlock() - - delete(scope.contexts, key) -} - -// SetExtra adds an extra to the current scope. -func (scope *Scope) SetExtra(key string, value interface{}) { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.extra[key] = value -} - -// SetExtras assigns multiple extras to the current scope. -func (scope *Scope) SetExtras(extra map[string]interface{}) { - scope.mu.Lock() - defer scope.mu.Unlock() - - for k, v := range extra { - scope.extra[k] = v - } -} - -// RemoveExtra removes a extra from the current scope. -func (scope *Scope) RemoveExtra(key string) { - scope.mu.Lock() - defer scope.mu.Unlock() - - delete(scope.extra, key) -} - -// SetFingerprint sets new fingerprint for the current scope. -func (scope *Scope) SetFingerprint(fingerprint []string) { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.fingerprint = fingerprint -} - -// SetLevel sets new level for the current scope. -func (scope *Scope) SetLevel(level Level) { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.level = level -} - -// SetPropagationContext sets the propagation context for the current scope. -func (scope *Scope) SetPropagationContext(propagationContext PropagationContext) { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.propagationContext = propagationContext -} - -// SetSpan sets a span for the current scope. -func (scope *Scope) SetSpan(span *Span) { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.span = span -} - -// Clone returns a copy of the current scope with all data copied over. -func (scope *Scope) Clone() *Scope { - scope.mu.RLock() - defer scope.mu.RUnlock() - - clone := NewScope() - clone.user = scope.user - clone.breadcrumbs = make([]*Breadcrumb, len(scope.breadcrumbs)) - copy(clone.breadcrumbs, scope.breadcrumbs) - clone.attachments = make([]*Attachment, len(scope.attachments)) - copy(clone.attachments, scope.attachments) - for key, value := range scope.tags { - clone.tags[key] = value - } - for key, value := range scope.contexts { - clone.contexts[key] = cloneContext(value) - } - for key, value := range scope.extra { - clone.extra[key] = value - } - clone.fingerprint = make([]string, len(scope.fingerprint)) - copy(clone.fingerprint, scope.fingerprint) - clone.level = scope.level - clone.request = scope.request - clone.requestBody = scope.requestBody - clone.eventProcessors = scope.eventProcessors - clone.propagationContext = scope.propagationContext - clone.span = scope.span - return clone -} - -// Clear removes the data from the current scope. Not safe for concurrent use. -func (scope *Scope) Clear() { - *scope = *NewScope() -} - -// AddEventProcessor adds an event processor to the current scope. -func (scope *Scope) AddEventProcessor(processor EventProcessor) { - scope.mu.Lock() - defer scope.mu.Unlock() - - scope.eventProcessors = append(scope.eventProcessors, processor) -} - -// ApplyToEvent takes the data from the current scope and attaches it to the event. -func (scope *Scope) ApplyToEvent(event *Event, hint *EventHint, client *Client) *Event { - scope.mu.RLock() - defer scope.mu.RUnlock() - - if len(scope.breadcrumbs) > 0 { - event.Breadcrumbs = append(event.Breadcrumbs, scope.breadcrumbs...) - } - - if len(scope.attachments) > 0 { - event.Attachments = append(event.Attachments, scope.attachments...) - } - - if len(scope.tags) > 0 { - if event.Tags == nil { - event.Tags = make(map[string]string, len(scope.tags)) - } - - for key, value := range scope.tags { - event.Tags[key] = value - } - } - - if len(scope.contexts) > 0 { - if event.Contexts == nil { - event.Contexts = make(map[string]Context) - } - - for key, value := range scope.contexts { - // Ensure we are not overwriting event fields - if _, ok := event.Contexts[key]; !ok { - event.Contexts[key] = cloneContext(value) - } - } - } - - if event.Contexts == nil { - event.Contexts = make(map[string]Context) - } - - if scope.span != nil { - event.Contexts["trace"] = scope.span.traceContext().Map() - - transaction := scope.span.GetTransaction() - if transaction != nil { - event.sdkMetaData.dsc = DynamicSamplingContextFromTransaction(transaction) - } - } else { - event.Contexts["trace"] = scope.propagationContext.Map() - - dsc := scope.propagationContext.DynamicSamplingContext - if !dsc.HasEntries() && client != nil { - dsc = DynamicSamplingContextFromScope(scope, client) - } - event.sdkMetaData.dsc = dsc - } - - if len(scope.extra) > 0 { - if event.Extra == nil { - event.Extra = make(map[string]interface{}, len(scope.extra)) - } - - for key, value := range scope.extra { - event.Extra[key] = value - } - } - - if event.User.IsEmpty() { - event.User = scope.user - } - - if len(event.Fingerprint) == 0 { - event.Fingerprint = append(event.Fingerprint, scope.fingerprint...) - } - - if scope.level != "" { - event.Level = scope.level - } - - if event.Request == nil && scope.request != nil { - event.Request = NewRequest(scope.request) - // NOTE: The SDK does not attempt to send partial request body data. - // - // The reason being that Sentry's ingest pipeline and UI are optimized - // to show structured data. Additionally, tooling around PII scrubbing - // relies on structured data; truncated request bodies would create - // invalid payloads that are more prone to leaking PII data. - // - // Users can still send more data along their events if they want to, - // for example using Event.Extra. - if scope.requestBody != nil && !scope.requestBody.Overflow() { - event.Request.Data = string(scope.requestBody.Bytes()) - } - } - - for _, processor := range scope.eventProcessors { - id := event.EventID - event = processor(event, hint) - if event == nil { - Logger.Printf("Event dropped by one of the Scope EventProcessors: %s\n", id) - return nil - } - } - - return event -} - -// cloneContext returns a new context with keys and values copied from the passed one. -// -// Note: a new Context (map) is returned, but the function does NOT do -// a proper deep copy: if some context values are pointer types (e.g. maps), -// they won't be properly copied. -func cloneContext(c Context) Context { - res := Context{} - for k, v := range c { - res[k] = v - } - return res -} diff --git a/vendor/github.com/getsentry/sentry-go/sentry.go b/vendor/github.com/getsentry/sentry-go/sentry.go deleted file mode 100644 index 0fca64e26..000000000 --- a/vendor/github.com/getsentry/sentry-go/sentry.go +++ /dev/null @@ -1,132 +0,0 @@ -package sentry - -import ( - "context" - "time" -) - -// The version of the SDK. -const SDKVersion = "0.29.0" - -// apiVersion is the minimum version of the Sentry API compatible with the -// sentry-go SDK. -const apiVersion = "7" - -// Init initializes the SDK with options. The returned error is non-nil if -// options is invalid, for instance if a malformed DSN is provided. -func Init(options ClientOptions) error { - hub := CurrentHub() - client, err := NewClient(options) - if err != nil { - return err - } - hub.BindClient(client) - return nil -} - -// AddBreadcrumb records a new breadcrumb. -// -// The total number of breadcrumbs that can be recorded are limited by the -// configuration on the client. -func AddBreadcrumb(breadcrumb *Breadcrumb) { - hub := CurrentHub() - hub.AddBreadcrumb(breadcrumb, nil) -} - -// CaptureMessage captures an arbitrary message. -func CaptureMessage(message string) *EventID { - hub := CurrentHub() - return hub.CaptureMessage(message) -} - -// CaptureException captures an error. -func CaptureException(exception error) *EventID { - hub := CurrentHub() - return hub.CaptureException(exception) -} - -// CaptureCheckIn captures a (cron) monitor check-in. -func CaptureCheckIn(checkIn *CheckIn, monitorConfig *MonitorConfig) *EventID { - hub := CurrentHub() - return hub.CaptureCheckIn(checkIn, monitorConfig) -} - -// CaptureEvent captures an event on the currently active client if any. -// -// The event must already be assembled. Typically code would instead use -// the utility methods like CaptureException. The return value is the -// event ID. In case Sentry is disabled or event was dropped, the return value will be nil. -func CaptureEvent(event *Event) *EventID { - hub := CurrentHub() - return hub.CaptureEvent(event) -} - -// Recover captures a panic. -func Recover() *EventID { - if err := recover(); err != nil { - hub := CurrentHub() - return hub.Recover(err) - } - return nil -} - -// RecoverWithContext captures a panic and passes relevant context object. -func RecoverWithContext(ctx context.Context) *EventID { - err := recover() - if err == nil { - return nil - } - - hub := GetHubFromContext(ctx) - if hub == nil { - hub = CurrentHub() - } - - return hub.RecoverWithContext(ctx, err) -} - -// WithScope is a shorthand for CurrentHub().WithScope. -func WithScope(f func(scope *Scope)) { - hub := CurrentHub() - hub.WithScope(f) -} - -// ConfigureScope is a shorthand for CurrentHub().ConfigureScope. -func ConfigureScope(f func(scope *Scope)) { - hub := CurrentHub() - hub.ConfigureScope(f) -} - -// PushScope is a shorthand for CurrentHub().PushScope. -func PushScope() { - hub := CurrentHub() - hub.PushScope() -} - -// PopScope is a shorthand for CurrentHub().PopScope. -func PopScope() { - hub := CurrentHub() - hub.PopScope() -} - -// Flush waits until the underlying Transport sends any buffered events to the -// Sentry server, blocking for at most the given timeout. It returns false if -// the timeout was reached. In that case, some events may not have been sent. -// -// Flush should be called before terminating the program to avoid -// unintentionally dropping events. -// -// Do not call Flush indiscriminately after every call to CaptureEvent, -// CaptureException or CaptureMessage. Instead, to have the SDK send events over -// the network synchronously, configure it to use the HTTPSyncTransport in the -// call to Init. -func Flush(timeout time.Duration) bool { - hub := CurrentHub() - return hub.Flush(timeout) -} - -// LastEventID returns an ID of last captured event. -func LastEventID() EventID { - hub := CurrentHub() - return hub.LastEventID() -} diff --git a/vendor/github.com/getsentry/sentry-go/sourcereader.go b/vendor/github.com/getsentry/sentry-go/sourcereader.go deleted file mode 100644 index 74a083848..000000000 --- a/vendor/github.com/getsentry/sentry-go/sourcereader.go +++ /dev/null @@ -1,70 +0,0 @@ -package sentry - -import ( - "bytes" - "os" - "sync" -) - -type sourceReader struct { - mu sync.Mutex - cache map[string][][]byte -} - -func newSourceReader() sourceReader { - return sourceReader{ - cache: make(map[string][][]byte), - } -} - -func (sr *sourceReader) readContextLines(filename string, line, context int) ([][]byte, int) { - sr.mu.Lock() - defer sr.mu.Unlock() - - lines, ok := sr.cache[filename] - - if !ok { - data, err := os.ReadFile(filename) - if err != nil { - sr.cache[filename] = nil - return nil, 0 - } - lines = bytes.Split(data, []byte{'\n'}) - sr.cache[filename] = lines - } - - return sr.calculateContextLines(lines, line, context) -} - -func (sr *sourceReader) calculateContextLines(lines [][]byte, line, context int) ([][]byte, int) { - // Stacktrace lines are 1-indexed, slices are 0-indexed - line-- - - // contextLine points to a line that caused an issue itself, in relation to - // returned slice. - contextLine := context - - if lines == nil || line >= len(lines) || line < 0 { - return nil, 0 - } - - if context < 0 { - context = 0 - contextLine = 0 - } - - start := line - context - - if start < 0 { - contextLine += start - start = 0 - } - - end := line + context + 1 - - if end > len(lines) { - end = len(lines) - } - - return lines[start:end], contextLine -} diff --git a/vendor/github.com/getsentry/sentry-go/span_recorder.go b/vendor/github.com/getsentry/sentry-go/span_recorder.go deleted file mode 100644 index 9a58574e8..000000000 --- a/vendor/github.com/getsentry/sentry-go/span_recorder.go +++ /dev/null @@ -1,56 +0,0 @@ -package sentry - -import ( - "sync" -) - -// A spanRecorder stores a span tree that makes up a transaction. Safe for -// concurrent use. It is okay to add child spans from multiple goroutines. -type spanRecorder struct { - mu sync.Mutex - spans []*Span - overflowOnce sync.Once -} - -// record stores a span. The first stored span is assumed to be the root of a -// span tree. -func (r *spanRecorder) record(s *Span) { - maxSpans := defaultMaxSpans - if client := CurrentHub().Client(); client != nil { - maxSpans = client.options.MaxSpans - } - r.mu.Lock() - defer r.mu.Unlock() - if len(r.spans) >= maxSpans { - r.overflowOnce.Do(func() { - root := r.spans[0] - Logger.Printf("Too many spans: dropping spans from transaction with TraceID=%s SpanID=%s limit=%d", - root.TraceID, root.SpanID, maxSpans) - }) - // TODO(tracing): mark the transaction event in some way to - // communicate that spans were dropped. - return - } - r.spans = append(r.spans, s) -} - -// root returns the first recorded span. Returns nil if none have been recorded. -func (r *spanRecorder) root() *Span { - r.mu.Lock() - defer r.mu.Unlock() - if len(r.spans) == 0 { - return nil - } - return r.spans[0] -} - -// children returns a list of all recorded spans, except the root. Returns nil -// if there are no children. -func (r *spanRecorder) children() []*Span { - r.mu.Lock() - defer r.mu.Unlock() - if len(r.spans) < 2 { - return nil - } - return r.spans[1:] -} diff --git a/vendor/github.com/getsentry/sentry-go/stacktrace.go b/vendor/github.com/getsentry/sentry-go/stacktrace.go deleted file mode 100644 index 3b372bcff..000000000 --- a/vendor/github.com/getsentry/sentry-go/stacktrace.go +++ /dev/null @@ -1,384 +0,0 @@ -package sentry - -import ( - "go/build" - "reflect" - "runtime" - "strings" -) - -const unknown string = "unknown" - -// The module download is split into two parts: downloading the go.mod and downloading the actual code. -// If you have dependencies only needed for tests, then they will show up in your go.mod, -// and go get will download their go.mods, but it will not download their code. -// The test-only dependencies get downloaded only when you need it, such as the first time you run go test. -// -// https://github.com/golang/go/issues/26913#issuecomment-411976222 - -// Stacktrace holds information about the frames of the stack. -type Stacktrace struct { - Frames []Frame `json:"frames,omitempty"` - FramesOmitted []uint `json:"frames_omitted,omitempty"` -} - -// NewStacktrace creates a stacktrace using runtime.Callers. -func NewStacktrace() *Stacktrace { - pcs := make([]uintptr, 100) - n := runtime.Callers(1, pcs) - - if n == 0 { - return nil - } - - runtimeFrames := extractFrames(pcs[:n]) - frames := createFrames(runtimeFrames) - - stacktrace := Stacktrace{ - Frames: frames, - } - - return &stacktrace -} - -// TODO: Make it configurable so that anyone can provide their own implementation? -// Use of reflection allows us to not have a hard dependency on any given -// package, so we don't have to import it. - -// ExtractStacktrace creates a new Stacktrace based on the given error. -func ExtractStacktrace(err error) *Stacktrace { - method := extractReflectedStacktraceMethod(err) - - var pcs []uintptr - - if method.IsValid() { - pcs = extractPcs(method) - } else { - pcs = extractXErrorsPC(err) - } - - if len(pcs) == 0 { - return nil - } - - runtimeFrames := extractFrames(pcs) - frames := createFrames(runtimeFrames) - - stacktrace := Stacktrace{ - Frames: frames, - } - - return &stacktrace -} - -func extractReflectedStacktraceMethod(err error) reflect.Value { - errValue := reflect.ValueOf(err) - - // https://github.com/go-errors/errors - methodStackFrames := errValue.MethodByName("StackFrames") - if methodStackFrames.IsValid() { - return methodStackFrames - } - - // https://github.com/pkg/errors - methodStackTrace := errValue.MethodByName("StackTrace") - if methodStackTrace.IsValid() { - return methodStackTrace - } - - // https://github.com/pingcap/errors - methodGetStackTracer := errValue.MethodByName("GetStackTracer") - if methodGetStackTracer.IsValid() { - stacktracer := methodGetStackTracer.Call(nil)[0] - stacktracerStackTrace := reflect.ValueOf(stacktracer).MethodByName("StackTrace") - - if stacktracerStackTrace.IsValid() { - return stacktracerStackTrace - } - } - - return reflect.Value{} -} - -func extractPcs(method reflect.Value) []uintptr { - var pcs []uintptr - - stacktrace := method.Call(nil)[0] - - if stacktrace.Kind() != reflect.Slice { - return nil - } - - for i := 0; i < stacktrace.Len(); i++ { - pc := stacktrace.Index(i) - - switch pc.Kind() { - case reflect.Uintptr: - pcs = append(pcs, uintptr(pc.Uint())) - case reflect.Struct: - for _, fieldName := range []string{"ProgramCounter", "PC"} { - field := pc.FieldByName(fieldName) - if !field.IsValid() { - continue - } - if field.Kind() == reflect.Uintptr { - pcs = append(pcs, uintptr(field.Uint())) - break - } - } - } - } - - return pcs -} - -// extractXErrorsPC extracts program counters from error values compatible with -// the error types from golang.org/x/xerrors. -// -// It returns nil if err is not compatible with errors from that package or if -// no program counters are stored in err. -func extractXErrorsPC(err error) []uintptr { - // This implementation uses the reflect package to avoid a hard dependency - // on third-party packages. - - // We don't know if err matches the expected type. For simplicity, instead - // of trying to account for all possible ways things can go wrong, some - // assumptions are made and if they are violated the code will panic. We - // recover from any panic and ignore it, returning nil. - //nolint: errcheck - defer func() { recover() }() - - field := reflect.ValueOf(err).Elem().FieldByName("frame") // type Frame struct{ frames [3]uintptr } - field = field.FieldByName("frames") - field = field.Slice(1, field.Len()) // drop first pc pointing to xerrors.New - pc := make([]uintptr, field.Len()) - for i := 0; i < field.Len(); i++ { - pc[i] = uintptr(field.Index(i).Uint()) - } - return pc -} - -// Frame represents a function call and it's metadata. Frames are associated -// with a Stacktrace. -type Frame struct { - Function string `json:"function,omitempty"` - Symbol string `json:"symbol,omitempty"` - // Module is, despite the name, the Sentry protocol equivalent of a Go - // package's import path. - Module string `json:"module,omitempty"` - Filename string `json:"filename,omitempty"` - AbsPath string `json:"abs_path,omitempty"` - Lineno int `json:"lineno,omitempty"` - Colno int `json:"colno,omitempty"` - PreContext []string `json:"pre_context,omitempty"` - ContextLine string `json:"context_line,omitempty"` - PostContext []string `json:"post_context,omitempty"` - InApp bool `json:"in_app"` - Vars map[string]interface{} `json:"vars,omitempty"` - // Package and the below are not used for Go stack trace frames. In - // other platforms it refers to a container where the Module can be - // found. For example, a Java JAR, a .NET Assembly, or a native - // dynamic library. They exists for completeness, allowing the - // construction and reporting of custom event payloads. - Package string `json:"package,omitempty"` - InstructionAddr string `json:"instruction_addr,omitempty"` - AddrMode string `json:"addr_mode,omitempty"` - SymbolAddr string `json:"symbol_addr,omitempty"` - ImageAddr string `json:"image_addr,omitempty"` - Platform string `json:"platform,omitempty"` - StackStart bool `json:"stack_start,omitempty"` -} - -// NewFrame assembles a stacktrace frame out of runtime.Frame. -func NewFrame(f runtime.Frame) Frame { - function := f.Function - var pkg string - - if function != "" { - pkg, function = splitQualifiedFunctionName(function) - } - - return newFrame(pkg, function, f.File, f.Line) -} - -// Like filepath.IsAbs() but doesn't care what platform you run this on. -// I.e. it also recognizies `/path/to/file` when run on Windows. -func isAbsPath(path string) bool { - if len(path) == 0 { - return false - } - - // If the volume name starts with a double slash, this is an absolute path. - if len(path) >= 1 && (path[0] == '/' || path[0] == '\\') { - return true - } - - // Windows absolute path, see https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats - if len(path) >= 3 && path[1] == ':' && (path[2] == '/' || path[2] == '\\') { - return true - } - - return false -} - -func newFrame(module string, function string, file string, line int) Frame { - frame := Frame{ - Lineno: line, - Module: module, - Function: function, - } - - switch { - case len(file) == 0: - frame.Filename = unknown - // Leave abspath as the empty string to be omitted when serializing event as JSON. - case isAbsPath(file): - frame.AbsPath = file - // TODO: in the general case, it is not trivial to come up with a - // "project relative" path with the data we have in run time. - // We shall not use filepath.Base because it creates ambiguous paths and - // affects the "Suspect Commits" feature. - // For now, leave relpath empty to be omitted when serializing the event - // as JSON. Improve this later. - default: - // f.File is a relative path. This may happen when the binary is built - // with the -trimpath flag. - frame.Filename = file - // Omit abspath when serializing the event as JSON. - } - - setInAppFrame(&frame) - - return frame -} - -// splitQualifiedFunctionName splits a package path-qualified function name into -// package name and function name. Such qualified names are found in -// runtime.Frame.Function values. -func splitQualifiedFunctionName(name string) (pkg string, fun string) { - pkg = packageName(name) - if len(pkg) > 0 { - fun = name[len(pkg)+1:] - } - return -} - -func extractFrames(pcs []uintptr) []runtime.Frame { - var frames = make([]runtime.Frame, 0, len(pcs)) - callersFrames := runtime.CallersFrames(pcs) - - for { - callerFrame, more := callersFrames.Next() - - frames = append(frames, callerFrame) - - if !more { - break - } - } - - // TODO don't append and reverse, put in the right place from the start. - // reverse - for i, j := 0, len(frames)-1; i < j; i, j = i+1, j-1 { - frames[i], frames[j] = frames[j], frames[i] - } - - return frames -} - -// createFrames creates Frame objects while filtering out frames that are not -// meant to be reported to Sentry, those are frames internal to the SDK or Go. -func createFrames(frames []runtime.Frame) []Frame { - if len(frames) == 0 { - return nil - } - - result := make([]Frame, 0, len(frames)) - - for _, frame := range frames { - function := frame.Function - var pkg string - if function != "" { - pkg, function = splitQualifiedFunctionName(function) - } - - if !shouldSkipFrame(pkg) { - result = append(result, newFrame(pkg, function, frame.File, frame.Line)) - } - } - - // Fix issues grouping errors with the new fully qualified function names - // introduced from Go 1.21 - result = cleanupFunctionNamePrefix(result) - return result -} - -// TODO ID: why do we want to do this? -// I'm not aware of other SDKs skipping all Sentry frames, regardless of their position in the stactrace. -// For example, in the .NET SDK, only the first frames are skipped until the call to the SDK. -// As is, this will also hide any intermediate frames in the stack and make debugging issues harder. -func shouldSkipFrame(module string) bool { - // Skip Go internal frames. - if module == "runtime" || module == "testing" { - return true - } - - // Skip Sentry internal frames, except for frames in _test packages (for testing). - if strings.HasPrefix(module, "github.com/getsentry/sentry-go") && - !strings.HasSuffix(module, "_test") { - return true - } - - return false -} - -// On Windows, GOROOT has backslashes, but we want forward slashes. -var goRoot = strings.ReplaceAll(build.Default.GOROOT, "\\", "/") - -func setInAppFrame(frame *Frame) { - if strings.HasPrefix(frame.AbsPath, goRoot) || - strings.Contains(frame.Module, "vendor") || - strings.Contains(frame.Module, "third_party") { - frame.InApp = false - } else { - frame.InApp = true - } -} - -func callerFunctionName() string { - pcs := make([]uintptr, 1) - runtime.Callers(3, pcs) - callersFrames := runtime.CallersFrames(pcs) - callerFrame, _ := callersFrames.Next() - return baseName(callerFrame.Function) -} - -// packageName returns the package part of the symbol name, or the empty string -// if there is none. -// It replicates https://golang.org/pkg/debug/gosym/#Sym.PackageName, avoiding a -// dependency on debug/gosym. -func packageName(name string) string { - if isCompilerGeneratedSymbol(name) { - return "" - } - - pathend := strings.LastIndex(name, "/") - if pathend < 0 { - pathend = 0 - } - - if i := strings.Index(name[pathend:], "."); i != -1 { - return name[:pathend+i] - } - return "" -} - -// baseName returns the symbol name without the package or receiver name. -// It replicates https://golang.org/pkg/debug/gosym/#Sym.BaseName, avoiding a -// dependency on debug/gosym. -func baseName(name string) string { - if i := strings.LastIndex(name, "."); i != -1 { - return name[i+1:] - } - return name -} diff --git a/vendor/github.com/getsentry/sentry-go/stacktrace_below_go1.20.go b/vendor/github.com/getsentry/sentry-go/stacktrace_below_go1.20.go deleted file mode 100644 index f6fb8e1e4..000000000 --- a/vendor/github.com/getsentry/sentry-go/stacktrace_below_go1.20.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !go1.20 - -package sentry - -import "strings" - -func isCompilerGeneratedSymbol(name string) bool { - // In versions of Go below 1.20 a prefix of "type." and "go." is a - // compiler-generated symbol that doesn't belong to any package. - // See variable reservedimports in cmd/compile/internal/gc/subr.go - if strings.HasPrefix(name, "go.") || strings.HasPrefix(name, "type.") { - return true - } - return false -} diff --git a/vendor/github.com/getsentry/sentry-go/stacktrace_below_go1.21.go b/vendor/github.com/getsentry/sentry-go/stacktrace_below_go1.21.go deleted file mode 100644 index 35a42e4dd..000000000 --- a/vendor/github.com/getsentry/sentry-go/stacktrace_below_go1.21.go +++ /dev/null @@ -1,7 +0,0 @@ -//go:build !go1.21 - -package sentry - -func cleanupFunctionNamePrefix(f []Frame) []Frame { - return f -} diff --git a/vendor/github.com/getsentry/sentry-go/stacktrace_go1.20.go b/vendor/github.com/getsentry/sentry-go/stacktrace_go1.20.go deleted file mode 100644 index ff1cbf600..000000000 --- a/vendor/github.com/getsentry/sentry-go/stacktrace_go1.20.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build go1.20 - -package sentry - -import "strings" - -func isCompilerGeneratedSymbol(name string) bool { - // In versions of Go 1.20 and above a prefix of "type:" and "go:" is a - // compiler-generated symbol that doesn't belong to any package. - // See variable reservedimports in cmd/compile/internal/gc/subr.go - if strings.HasPrefix(name, "go:") || strings.HasPrefix(name, "type:") { - return true - } - return false -} diff --git a/vendor/github.com/getsentry/sentry-go/stacktrace_go1.21.go b/vendor/github.com/getsentry/sentry-go/stacktrace_go1.21.go deleted file mode 100644 index 45147c850..000000000 --- a/vendor/github.com/getsentry/sentry-go/stacktrace_go1.21.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build go1.21 - -package sentry - -import "strings" - -// Walk backwards through the results and for the current function name -// remove it's parent function's prefix, leaving only it's actual name. This -// fixes issues grouping errors with the new fully qualified function names -// introduced from Go 1.21. - -func cleanupFunctionNamePrefix(f []Frame) []Frame { - for i := len(f) - 1; i > 0; i-- { - name := f[i].Function - parentName := f[i-1].Function + "." - - if !strings.HasPrefix(name, parentName) { - continue - } - - f[i].Function = name[len(parentName):] - } - - return f -} diff --git a/vendor/github.com/getsentry/sentry-go/traces_profiler.go b/vendor/github.com/getsentry/sentry-go/traces_profiler.go deleted file mode 100644 index 235734218..000000000 --- a/vendor/github.com/getsentry/sentry-go/traces_profiler.go +++ /dev/null @@ -1,95 +0,0 @@ -package sentry - -import ( - "sync" - "time" -) - -// Checks whether the transaction should be profiled (according to ProfilesSampleRate) -// and starts a profiler if so. -func (s *Span) sampleTransactionProfile() { - var sampleRate = s.clientOptions().ProfilesSampleRate - switch { - case sampleRate < 0.0 || sampleRate > 1.0: - Logger.Printf("Skipping transaction profiling: ProfilesSampleRate out of range [0.0, 1.0]: %f\n", sampleRate) - case sampleRate == 0.0 || rng.Float64() >= sampleRate: - Logger.Printf("Skipping transaction profiling: ProfilesSampleRate is: %f\n", sampleRate) - default: - startProfilerOnce.Do(startGlobalProfiler) - if globalProfiler == nil { - Logger.Println("Skipping transaction profiling: the profiler couldn't be started") - } else { - s.collectProfile = collectTransactionProfile - } - } -} - -// transactionProfiler collects a profile for a given span. -type transactionProfiler func(span *Span) *profileInfo - -var startProfilerOnce sync.Once -var globalProfiler profiler - -func startGlobalProfiler() { - globalProfiler = startProfiling(time.Now()) -} - -func collectTransactionProfile(span *Span) *profileInfo { - result := globalProfiler.GetSlice(span.StartTime, span.EndTime) - if result == nil || result.trace == nil { - return nil - } - - info := &profileInfo{ - Version: "1", - EventID: uuid(), - // See https://github.com/getsentry/sentry-go/pull/626#discussion_r1204870340 for explanation why we use the Transaction time. - Timestamp: span.StartTime, - Trace: result.trace, - Transaction: profileTransaction{ - DurationNS: uint64(span.EndTime.Sub(span.StartTime).Nanoseconds()), - Name: span.Name, - TraceID: span.TraceID.String(), - }, - } - if len(info.Transaction.Name) == 0 { - // Name is required by Relay so use the operation name if the span name is empty. - info.Transaction.Name = span.Op - } - if result.callerGoID > 0 { - info.Transaction.ActiveThreadID = result.callerGoID - } - return info -} - -func (info *profileInfo) UpdateFromEvent(event *Event) { - info.Environment = event.Environment - info.Platform = event.Platform - info.Release = event.Release - info.Dist = event.Dist - info.Transaction.ID = event.EventID - - getStringFromContext := func(context map[string]interface{}, originalValue, key string) string { - v, ok := context[key] - if !ok { - return originalValue - } - - if s, ok := v.(string); ok { - return s - } - - return originalValue - } - - if runtimeContext, ok := event.Contexts["runtime"]; ok { - info.Runtime.Name = getStringFromContext(runtimeContext, info.Runtime.Name, "name") - info.Runtime.Version = getStringFromContext(runtimeContext, info.Runtime.Version, "version") - } - if osContext, ok := event.Contexts["os"]; ok { - info.OS.Name = getStringFromContext(osContext, info.OS.Name, "name") - } - if deviceContext, ok := event.Contexts["device"]; ok { - info.Device.Architecture = getStringFromContext(deviceContext, info.Device.Architecture, "arch") - } -} diff --git a/vendor/github.com/getsentry/sentry-go/traces_sampler.go b/vendor/github.com/getsentry/sentry-go/traces_sampler.go deleted file mode 100644 index 69e7cb7fa..000000000 --- a/vendor/github.com/getsentry/sentry-go/traces_sampler.go +++ /dev/null @@ -1,19 +0,0 @@ -package sentry - -// A SamplingContext is passed to a TracesSampler to determine a sampling -// decision. -// -// TODO(tracing): possibly expand SamplingContext to include custom / -// user-provided data. -type SamplingContext struct { - Span *Span // The current span, always non-nil. - Parent *Span // The parent span, may be nil. -} - -// The TracesSample type is an adapter to allow the use of ordinary -// functions as a TracesSampler. -type TracesSampler func(ctx SamplingContext) float64 - -func (f TracesSampler) Sample(ctx SamplingContext) float64 { - return f(ctx) -} diff --git a/vendor/github.com/getsentry/sentry-go/tracing.go b/vendor/github.com/getsentry/sentry-go/tracing.go deleted file mode 100644 index 0f5ade2e8..000000000 --- a/vendor/github.com/getsentry/sentry-go/tracing.go +++ /dev/null @@ -1,1028 +0,0 @@ -package sentry - -import ( - "context" - "crypto/rand" - "encoding/hex" - "encoding/json" - "fmt" - "net/http" - "regexp" - "strings" - "sync" - "time" -) - -const ( - SentryTraceHeader = "sentry-trace" - SentryBaggageHeader = "baggage" -) - -// SpanOrigin indicates what created a trace or a span. See: https://develop.sentry.dev/sdk/performance/trace-origin/ -type SpanOrigin string - -const ( - SpanOriginManual = "manual" - SpanOriginEcho = "auto.http.echo" - SpanOriginFastHTTP = "auto.http.fasthttp" - SpanOriginFiber = "auto.http.fiber" - SpanOriginGin = "auto.http.gin" - SpanOriginStdLib = "auto.http.stdlib" - SpanOriginIris = "auto.http.iris" - SpanOriginNegroni = "auto.http.negroni" -) - -// A Span is the building block of a Sentry transaction. Spans build up a tree -// structure of timed operations. The span tree makes up a transaction event -// that is sent to Sentry when the root span is finished. -// -// Spans must be started with either StartSpan or Span.StartChild. -type Span struct { //nolint: maligned // prefer readability over optimal memory layout (see note below *) - TraceID TraceID `json:"trace_id"` - SpanID SpanID `json:"span_id"` - ParentSpanID SpanID `json:"parent_span_id"` - Name string `json:"name,omitempty"` - Op string `json:"op,omitempty"` - Description string `json:"description,omitempty"` - Status SpanStatus `json:"status,omitempty"` - Tags map[string]string `json:"tags,omitempty"` - StartTime time.Time `json:"start_timestamp"` - EndTime time.Time `json:"timestamp"` - Data map[string]interface{} `json:"data,omitempty"` - Sampled Sampled `json:"-"` - Source TransactionSource `json:"-"` - Origin SpanOrigin `json:"origin,omitempty"` - - // mu protects concurrent writes to map fields - mu sync.RWMutex - // sample rate the span was sampled with. - sampleRate float64 - // ctx is the context where the span was started. Always non-nil. - ctx context.Context - // Dynamic Sampling context - dynamicSamplingContext DynamicSamplingContext - // parent refers to the immediate local parent span. A remote parent span is - // only referenced by setting ParentSpanID. - parent *Span - // recorder stores all spans in a transaction. Guaranteed to be non-nil. - recorder *spanRecorder - // span context, can only be set on transactions - contexts map[string]Context - // collectProfile is a function that collects a profile of the current transaction. May be nil. - collectProfile transactionProfiler - // a Once instance to make sure that Finish() is only called once. - finishOnce sync.Once -} - -// TraceParentContext describes the context of a (remote) parent span. -// -// The context is normally extracted from a received "sentry-trace" header and -// used to initialize a new transaction. -// -// Note: the name might be not the best one. It was taken mostly to stay aligned -// with other SDKs, and it alludes to W3C "traceparent" header (https://www.w3.org/TR/trace-context/), -// which serves a similar purpose to "sentry-trace". We should eventually consider -// making this type internal-only and give it a better name. -type TraceParentContext struct { - TraceID TraceID - ParentSpanID SpanID - Sampled Sampled -} - -// (*) Note on maligned: -// -// We prefer readability over optimal memory layout. If we ever decide to -// reorder fields, we can use a tool: -// -// go run honnef.co/go/tools/cmd/structlayout -json . Span | go run honnef.co/go/tools/cmd/structlayout-optimize -// -// Other structs would deserve reordering as well, for example Event. - -// TODO: make Span.Tags and Span.Data opaque types (struct{unexported []slice}). -// An opaque type allows us to add methods and make it more convenient to use -// than maps, because maps require careful nil checks to use properly or rely on -// explicit initialization for every span, even when there might be no -// tags/data. For Span.Data, must gracefully handle values that cannot be -// marshaled into JSON (see transport.go:getRequestBodyFromEvent). - -// StartSpan starts a new span to describe an operation. The new span will be a -// child of the last span stored in ctx, if any. -// -// One or more options can be used to modify the span properties. Typically one -// option as a function literal is enough. Combining multiple options can be -// useful to define and reuse specific properties with named functions. -// -// Caller should call the Finish method on the span to mark its end. Finishing a -// root span sends the span and all of its children, recursively, as a -// transaction to Sentry. -func StartSpan(ctx context.Context, operation string, options ...SpanOption) *Span { - parent, hasParent := ctx.Value(spanContextKey{}).(*Span) - var span Span - span = Span{ - // defaults - Op: operation, - StartTime: time.Now(), - Sampled: SampledUndefined, - - ctx: context.WithValue(ctx, spanContextKey{}, &span), - parent: parent, - } - - _, err := rand.Read(span.SpanID[:]) - if err != nil { - panic(err) - } - - if hasParent { - span.TraceID = parent.TraceID - span.ParentSpanID = parent.SpanID - span.Origin = parent.Origin - } else { - // Only set the Source if this is a transaction - span.Source = SourceCustom - span.Origin = SpanOriginManual - - // Implementation note: - // - // While math/rand is ~2x faster than crypto/rand (exact - // difference depends on hardware / OS), crypto/rand is probably - // fast enough and a safer choice. - // - // For reference, OpenTelemetry [1] uses crypto/rand to seed - // math/rand. AFAICT this approach does not preserve the - // properties from crypto/rand that make it suitable for - // cryptography. While it might be debatable whether those - // properties are important for us here, again, we're taking the - // safer path. - // - // See [2a] & [2b] for a discussion of some of the properties we - // obtain by using crypto/rand and [3a] & [3b] for why we avoid - // math/rand. - // - // Because the math/rand seed has only 64 bits (int64), if the - // first thing we do after seeding an RNG is to read in a random - // TraceID, there are only 2^64 possible values. Compared to - // UUID v4 that have 122 random bits, there is a much greater - // chance of collision [4a] & [4b]. - // - // [1]: https://github.com/open-telemetry/opentelemetry-go/blob/958041ddf619a128/sdk/trace/trace.go#L25-L31 - // [2a]: https://security.stackexchange.com/q/120352/246345 - // [2b]: https://security.stackexchange.com/a/120365/246345 - // [3a]: https://github.com/golang/go/issues/11871#issuecomment-126333686 - // [3b]: https://github.com/golang/go/issues/11871#issuecomment-126357889 - // [4a]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions - // [4b]: https://www.wolframalpha.com/input/?i=sqrt%282*2%5E64*ln%281%2F%281-0.5%29%29%29 - _, err := rand.Read(span.TraceID[:]) - if err != nil { - panic(err) - } - } - - // Apply options to override defaults. - for _, option := range options { - option(&span) - } - - span.Sampled = span.sample() - - span.recorder = &spanRecorder{} - if hasParent { - span.recorder = parent.spanRecorder() - } - - span.recorder.record(&span) - - clientOptions := span.clientOptions() - if clientOptions.EnableTracing { - hub := hubFromContext(ctx) - hub.Scope().SetSpan(&span) - } - - // Start profiling only if it's a sampled root transaction. - if span.IsTransaction() && span.Sampled.Bool() { - span.sampleTransactionProfile() - } - - return &span -} - -// Finish sets the span's end time, unless already set. If the span is the root -// of a span tree, Finish sends the span tree to Sentry as a transaction. -// -// The logic is executed at most once per span, so that (incorrectly) calling it twice -// never double sends to Sentry. -func (s *Span) Finish() { - s.finishOnce.Do(s.doFinish) -} - -// Context returns the context containing the span. -func (s *Span) Context() context.Context { return s.ctx } - -// StartChild starts a new child span. -// -// The call span.StartChild(operation, options...) is a shortcut for -// StartSpan(span.Context(), operation, options...). -func (s *Span) StartChild(operation string, options ...SpanOption) *Span { - return StartSpan(s.Context(), operation, options...) -} - -// SetTag sets a tag on the span. It is recommended to use SetTag instead of -// accessing the tags map directly as SetTag takes care of initializing the map -// when necessary. -func (s *Span) SetTag(name, value string) { - s.mu.Lock() - defer s.mu.Unlock() - - if s.Tags == nil { - s.Tags = make(map[string]string) - } - s.Tags[name] = value -} - -// SetData sets a data on the span. It is recommended to use SetData instead of -// accessing the data map directly as SetData takes care of initializing the map -// when necessary. -func (s *Span) SetData(name string, value interface{}) { - if value == nil { - return - } - - s.mu.Lock() - defer s.mu.Unlock() - - if s.Data == nil { - s.Data = make(map[string]interface{}) - } - s.Data[name] = value -} - -// SetContext sets a context on the span. It is recommended to use SetContext instead of -// accessing the contexts map directly as SetContext takes care of initializing the map -// when necessary. -func (s *Span) SetContext(key string, value Context) { - s.mu.Lock() - defer s.mu.Unlock() - - if s.contexts == nil { - s.contexts = make(map[string]Context) - } - s.contexts[key] = value -} - -// IsTransaction checks if the given span is a transaction. -func (s *Span) IsTransaction() bool { - return s.parent == nil -} - -// GetTransaction returns the transaction that contains this span. -// -// For transaction spans it returns itself. For spans that were created manually -// the method returns "nil". -func (s *Span) GetTransaction() *Span { - spanRecorder := s.spanRecorder() - if spanRecorder == nil { - // This probably means that the Span was created manually (not via - // StartTransaction/StartSpan or StartChild). - // Return "nil" to indicate that it's not a normal situation. - return nil - } - recorderRoot := spanRecorder.root() - if recorderRoot == nil { - // Same as above: manually created Span. - return nil - } - return recorderRoot -} - -// TODO(tracing): maybe add shortcuts to get/set transaction name. Right now the -// transaction name is in the Scope, as it has existed there historically, prior -// to tracing. -// -// See Scope.Transaction() and Scope.SetTransaction(). -// -// func (s *Span) TransactionName() string -// func (s *Span) SetTransactionName(name string) - -// ToSentryTrace returns the seralized TraceParentContext from a transaction/span. -// Use this function to propagate the TraceParentContext to a downstream SDK, -// either as the value of the "sentry-trace" HTTP header, or as an html "sentry-trace" meta tag. -func (s *Span) ToSentryTrace() string { - // TODO(tracing): add instrumentation for outgoing HTTP requests using - // ToSentryTrace. - var b strings.Builder - fmt.Fprintf(&b, "%s-%s", s.TraceID.Hex(), s.SpanID.Hex()) - switch s.Sampled { - case SampledTrue: - b.WriteString("-1") - case SampledFalse: - b.WriteString("-0") - } - return b.String() -} - -// ToBaggage returns the serialized DynamicSamplingContext from a transaction. -// Use this function to propagate the DynamicSamplingContext to a downstream SDK, -// either as the value of the "baggage" HTTP header, or as an html "baggage" meta tag. -func (s *Span) ToBaggage() string { - t := s.GetTransaction() - if t == nil { - return "" - } - - // In case there is currently no frozen DynamicSamplingContext attached to the transaction, - // create one from the properties of the transaction. - if !s.dynamicSamplingContext.IsFrozen() { - // This will return a frozen DynamicSamplingContext. - if dsc := DynamicSamplingContextFromTransaction(t); dsc.HasEntries() { - t.dynamicSamplingContext = dsc - } - } - - return t.dynamicSamplingContext.String() -} - -// SetDynamicSamplingContext sets the given dynamic sampling context on the -// current transaction. -func (s *Span) SetDynamicSamplingContext(dsc DynamicSamplingContext) { - if s.IsTransaction() { - s.dynamicSamplingContext = dsc - } -} - -// doFinish runs the actual Span.Finish() logic. -func (s *Span) doFinish() { - if s.EndTime.IsZero() { - s.EndTime = monotonicTimeSince(s.StartTime) - } - - if !s.Sampled.Bool() { - return - } - event := s.toEvent() - if event == nil { - return - } - - if s.collectProfile != nil { - event.sdkMetaData.transactionProfile = s.collectProfile(s) - } - - // TODO(tracing): add breadcrumbs - // (see https://github.com/getsentry/sentry-python/blob/f6f3525f8812f609/sentry_sdk/tracing.py#L372) - - hub := hubFromContext(s.ctx) - hub.CaptureEvent(event) -} - -// sentryTracePattern matches either -// -// TRACE_ID - SPAN_ID -// [[:xdigit:]]{32}-[[:xdigit:]]{16} -// -// or -// -// TRACE_ID - SPAN_ID - SAMPLED -// [[:xdigit:]]{32}-[[:xdigit:]]{16}-[01] -var sentryTracePattern = regexp.MustCompile(`^([[:xdigit:]]{32})-([[:xdigit:]]{16})(?:-([01]))?$`) - -// updateFromSentryTrace parses a sentry-trace HTTP header (as returned by -// ToSentryTrace) and updates fields of the span. If the header cannot be -// recognized as valid, the span is left unchanged. The returned value indicates -// whether the span was updated. -func (s *Span) updateFromSentryTrace(header []byte) (updated bool) { - m := sentryTracePattern.FindSubmatch(header) - if m == nil { - // no match - return false - } - _, _ = hex.Decode(s.TraceID[:], m[1]) - _, _ = hex.Decode(s.ParentSpanID[:], m[2]) - if len(m[3]) != 0 { - switch m[3][0] { - case '0': - s.Sampled = SampledFalse - case '1': - s.Sampled = SampledTrue - } - } - return true -} - -func (s *Span) updateFromBaggage(header []byte) { - if s.IsTransaction() { - dsc, err := DynamicSamplingContextFromHeader(header) - if err != nil { - return - } - - s.dynamicSamplingContext = dsc - } -} - -func (s *Span) MarshalJSON() ([]byte, error) { - // span aliases Span to allow calling json.Marshal without an infinite loop. - // It preserves all fields while none of the attached methods. - type span Span - var parentSpanID string - if s.ParentSpanID != zeroSpanID { - parentSpanID = s.ParentSpanID.String() - } - return json.Marshal(struct { - *span - ParentSpanID string `json:"parent_span_id,omitempty"` - }{ - span: (*span)(s), - ParentSpanID: parentSpanID, - }) -} - -func (s *Span) clientOptions() *ClientOptions { - client := hubFromContext(s.ctx).Client() - if client != nil { - return &client.options - } - return &ClientOptions{} -} - -func (s *Span) sample() Sampled { - clientOptions := s.clientOptions() - // https://develop.sentry.dev/sdk/performance/#sampling - // #1 tracing is not enabled. - if !clientOptions.EnableTracing { - Logger.Printf("Dropping transaction: EnableTracing is set to %t", clientOptions.EnableTracing) - s.sampleRate = 0.0 - return SampledFalse - } - - // #2 explicit sampling decision via StartSpan/StartTransaction options. - if s.Sampled != SampledUndefined { - Logger.Printf("Using explicit sampling decision from StartSpan/StartTransaction: %v", s.Sampled) - switch s.Sampled { - case SampledTrue: - s.sampleRate = 1.0 - case SampledFalse: - s.sampleRate = 0.0 - } - return s.Sampled - } - - // Variant for non-transaction spans: they inherit the parent decision. - // Note: non-transaction should always have a parent, but we check both - // conditions anyway -- the first for semantic meaning, the second to - // avoid a nil pointer dereference. - if !s.IsTransaction() && s.parent != nil { - return s.parent.Sampled - } - - // #3 use TracesSampler from ClientOptions. - sampler := clientOptions.TracesSampler - samplingContext := SamplingContext{ - Span: s, - Parent: s.parent, - } - - if sampler != nil { - tracesSamplerSampleRate := sampler.Sample(samplingContext) - s.sampleRate = tracesSamplerSampleRate - if tracesSamplerSampleRate < 0.0 || tracesSamplerSampleRate > 1.0 { - Logger.Printf("Dropping transaction: Returned TracesSampler rate is out of range [0.0, 1.0]: %f", tracesSamplerSampleRate) - return SampledFalse - } - if tracesSamplerSampleRate == 0 { - Logger.Printf("Dropping transaction: Returned TracesSampler rate is: %f", tracesSamplerSampleRate) - return SampledFalse - } - - if rng.Float64() < tracesSamplerSampleRate { - return SampledTrue - } - Logger.Printf("Dropping transaction: TracesSampler returned rate: %f", tracesSamplerSampleRate) - return SampledFalse - } - // #4 inherit parent decision. - if s.parent != nil { - Logger.Printf("Using sampling decision from parent: %v", s.parent.Sampled) - switch s.parent.Sampled { - case SampledTrue: - s.sampleRate = 1.0 - case SampledFalse: - s.sampleRate = 0.0 - } - return s.parent.Sampled - } - - // #5 use TracesSampleRate from ClientOptions. - sampleRate := clientOptions.TracesSampleRate - s.sampleRate = sampleRate - if sampleRate < 0.0 || sampleRate > 1.0 { - Logger.Printf("Dropping transaction: TracesSamplerRate out of range [0.0, 1.0]: %f", sampleRate) - return SampledFalse - } - if sampleRate == 0.0 { - Logger.Printf("Dropping transaction: TracesSampleRate rate is: %f", sampleRate) - return SampledFalse - } - - if rng.Float64() < sampleRate { - return SampledTrue - } - - return SampledFalse -} - -func (s *Span) toEvent() *Event { - s.mu.Lock() - defer s.mu.Unlock() - - if !s.IsTransaction() { - return nil // only transactions can be transformed into events - } - - children := s.recorder.children() - finished := make([]*Span, 0, len(children)) - for _, child := range children { - if child.EndTime.IsZero() { - Logger.Printf("Dropped unfinished span: Op=%q TraceID=%s SpanID=%s", child.Op, child.TraceID, child.SpanID) - continue - } - finished = append(finished, child) - } - - // Create and attach a DynamicSamplingContext to the transaction. - // If the DynamicSamplingContext is not frozen at this point, we can assume being head of trace. - if !s.dynamicSamplingContext.IsFrozen() { - s.dynamicSamplingContext = DynamicSamplingContextFromTransaction(s) - } - - contexts := make(map[string]Context, len(s.contexts)) - for k, v := range s.contexts { - contexts[k] = cloneContext(v) - } - - // Make sure that the transaction source is valid - transactionSource := s.Source - if !transactionSource.isValid() { - transactionSource = SourceCustom - } - - return &Event{ - Type: transactionType, - Transaction: s.Name, - Contexts: contexts, - Tags: s.Tags, - Extra: s.Data, - Timestamp: s.EndTime, - StartTime: s.StartTime, - Spans: finished, - TransactionInfo: &TransactionInfo{ - Source: transactionSource, - }, - sdkMetaData: SDKMetaData{ - dsc: s.dynamicSamplingContext, - }, - } -} - -func (s *Span) traceContext() *TraceContext { - return &TraceContext{ - TraceID: s.TraceID, - SpanID: s.SpanID, - ParentSpanID: s.ParentSpanID, - Op: s.Op, - Description: s.Description, - Status: s.Status, - } -} - -// spanRecorder stores the span tree. Guaranteed to be non-nil. -func (s *Span) spanRecorder() *spanRecorder { return s.recorder } - -// ParseTraceParentContext parses a sentry-trace header and builds a TraceParentContext from the -// parsed values. If the header was parsed correctly, the second returned argument -// ("valid") will be set to true, otherwise (e.g., empty or malformed header) it will -// be false. -func ParseTraceParentContext(header []byte) (traceParentContext TraceParentContext, valid bool) { - s := Span{} - updated := s.updateFromSentryTrace(header) - if !updated { - return TraceParentContext{}, false - } - return TraceParentContext{ - TraceID: s.TraceID, - ParentSpanID: s.ParentSpanID, - Sampled: s.Sampled, - }, true -} - -// TraceID identifies a trace. -type TraceID [16]byte - -func (id TraceID) Hex() []byte { - b := make([]byte, hex.EncodedLen(len(id))) - hex.Encode(b, id[:]) - return b -} - -func (id TraceID) String() string { - return string(id.Hex()) -} - -func (id TraceID) MarshalText() ([]byte, error) { - return id.Hex(), nil -} - -// SpanID identifies a span. -type SpanID [8]byte - -func (id SpanID) Hex() []byte { - b := make([]byte, hex.EncodedLen(len(id))) - hex.Encode(b, id[:]) - return b -} - -func (id SpanID) String() string { - return string(id.Hex()) -} - -func (id SpanID) MarshalText() ([]byte, error) { - return id.Hex(), nil -} - -// Zero values of TraceID and SpanID used for comparisons. -var ( - zeroTraceID TraceID - zeroSpanID SpanID -) - -// Contains information about how the name of the transaction was determined. -type TransactionSource string - -const ( - SourceCustom TransactionSource = "custom" - SourceURL TransactionSource = "url" - SourceRoute TransactionSource = "route" - SourceView TransactionSource = "view" - SourceComponent TransactionSource = "component" - SourceTask TransactionSource = "task" -) - -// A set of all valid transaction sources. -var allTransactionSources = map[TransactionSource]struct{}{ - SourceCustom: {}, - SourceURL: {}, - SourceRoute: {}, - SourceView: {}, - SourceComponent: {}, - SourceTask: {}, -} - -// isValid returns 'true' if the given transaction source is a valid -// source as recognized by the envelope protocol: -// https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations -func (ts TransactionSource) isValid() bool { - _, found := allTransactionSources[ts] - return found -} - -// SpanStatus is the status of a span. -type SpanStatus uint8 - -// Implementation note: -// -// In Relay (ingestion), the SpanStatus type is an enum used as -// Annotated when embedded in structs, making it effectively -// Option. It means the status is either null or one of the known -// string values. -// -// In Snuba (search), the SpanStatus is stored as an uint8 and defaulted to 2 -// ("unknown") when not set. It means that Discover searches for -// `transaction.status:unknown` return both transactions/spans with status -// `null` or `"unknown"`. Searches for `transaction.status:""` return nothing. -// -// With that in mind, the Go SDK default is SpanStatusUndefined, which is -// null/omitted when serializing to JSON, but integrations may update the status -// automatically based on contextual information. - -const ( - SpanStatusUndefined SpanStatus = iota - SpanStatusOK - SpanStatusCanceled - SpanStatusUnknown - SpanStatusInvalidArgument - SpanStatusDeadlineExceeded - SpanStatusNotFound - SpanStatusAlreadyExists - SpanStatusPermissionDenied - SpanStatusResourceExhausted - SpanStatusFailedPrecondition - SpanStatusAborted - SpanStatusOutOfRange - SpanStatusUnimplemented - SpanStatusInternalError - SpanStatusUnavailable - SpanStatusDataLoss - SpanStatusUnauthenticated - maxSpanStatus -) - -func (ss SpanStatus) String() string { - if ss >= maxSpanStatus { - return "" - } - m := [maxSpanStatus]string{ - "", - "ok", - "cancelled", // [sic] - "unknown", - "invalid_argument", - "deadline_exceeded", - "not_found", - "already_exists", - "permission_denied", - "resource_exhausted", - "failed_precondition", - "aborted", - "out_of_range", - "unimplemented", - "internal_error", - "unavailable", - "data_loss", - "unauthenticated", - } - return m[ss] -} - -func (ss SpanStatus) MarshalJSON() ([]byte, error) { - s := ss.String() - if s == "" { - return []byte("null"), nil - } - return json.Marshal(s) -} - -// A TraceContext carries information about an ongoing trace and is meant to be -// stored in Event.Contexts (as *TraceContext). -type TraceContext struct { - TraceID TraceID `json:"trace_id"` - SpanID SpanID `json:"span_id"` - ParentSpanID SpanID `json:"parent_span_id"` - Op string `json:"op,omitempty"` - Description string `json:"description,omitempty"` - Status SpanStatus `json:"status,omitempty"` -} - -func (tc *TraceContext) MarshalJSON() ([]byte, error) { - // traceContext aliases TraceContext to allow calling json.Marshal without - // an infinite loop. It preserves all fields while none of the attached - // methods. - type traceContext TraceContext - var parentSpanID string - if tc.ParentSpanID != zeroSpanID { - parentSpanID = tc.ParentSpanID.String() - } - return json.Marshal(struct { - *traceContext - ParentSpanID string `json:"parent_span_id,omitempty"` - }{ - traceContext: (*traceContext)(tc), - ParentSpanID: parentSpanID, - }) -} - -func (tc TraceContext) Map() map[string]interface{} { - m := map[string]interface{}{ - "trace_id": tc.TraceID, - "span_id": tc.SpanID, - } - - if tc.ParentSpanID != [8]byte{} { - m["parent_span_id"] = tc.ParentSpanID - } - - if tc.Op != "" { - m["op"] = tc.Op - } - - if tc.Description != "" { - m["description"] = tc.Description - } - - if tc.Status > 0 && tc.Status < maxSpanStatus { - m["status"] = tc.Status - } - - return m -} - -// Sampled signifies a sampling decision. -type Sampled int8 - -// The possible trace sampling decisions are: SampledFalse, SampledUndefined -// (default) and SampledTrue. -const ( - SampledFalse Sampled = -1 - SampledUndefined Sampled = 0 - SampledTrue Sampled = 1 -) - -func (s Sampled) String() string { - switch s { - case SampledFalse: - return "SampledFalse" - case SampledUndefined: - return "SampledUndefined" - case SampledTrue: - return "SampledTrue" - default: - return fmt.Sprintf("SampledInvalid(%d)", s) - } -} - -// Bool returns true if the sample decision is SampledTrue, false otherwise. -func (s Sampled) Bool() bool { - return s == SampledTrue -} - -// A SpanOption is a function that can modify the properties of a span. -type SpanOption func(s *Span) - -// WithTransactionName option sets the name of the current transaction. -// -// A span tree has a single transaction name, therefore using this option when -// starting a span affects the span tree as a whole, potentially overwriting a -// name set previously. -func WithTransactionName(name string) SpanOption { - return func(s *Span) { - s.Name = name - } -} - -// WithDescription sets the description of a span. -func WithDescription(description string) SpanOption { - return func(s *Span) { - s.Description = description - } -} - -// WithOpName sets the operation name for a given span. -func WithOpName(name string) SpanOption { - return func(s *Span) { - s.Op = name - } -} - -// WithTransactionSource sets the source of the transaction name. -// -// Note: if the transaction source is not a valid source (as described -// by the spec https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations), -// it will be corrected to "custom" eventually, before the transaction is sent. -func WithTransactionSource(source TransactionSource) SpanOption { - return func(s *Span) { - s.Source = source - } -} - -// WithSpanSampled updates the sampling flag for a given span. -func WithSpanSampled(sampled Sampled) SpanOption { - return func(s *Span) { - s.Sampled = sampled - } -} - -// WithSpanOrigin sets the origin of the span. -func WithSpanOrigin(origin SpanOrigin) SpanOption { - return func(s *Span) { - s.Origin = origin - } -} - -// Continue a trace based on traceparent and bagge values. -// If the SDK is configured with tracing enabled, -// this function returns populated SpanOption. -// In any other cases, it populates the propagation context on the scope. -func ContinueTrace(hub *Hub, traceparent, baggage string) SpanOption { - scope := hub.Scope() - propagationContext, _ := PropagationContextFromHeaders(traceparent, baggage) - scope.SetPropagationContext(propagationContext) - - return ContinueFromHeaders(traceparent, baggage) -} - -// ContinueFromRequest returns a span option that updates the span to continue -// an existing trace. If it cannot detect an existing trace in the request, the -// span will be left unchanged. -// -// ContinueFromRequest is an alias for: -// -// ContinueFromHeaders(r.Header.Get(SentryTraceHeader), r.Header.Get(SentryBaggageHeader)). -func ContinueFromRequest(r *http.Request) SpanOption { - return ContinueFromHeaders(r.Header.Get(SentryTraceHeader), r.Header.Get(SentryBaggageHeader)) -} - -// ContinueFromHeaders returns a span option that updates the span to continue -// an existing TraceID and propagates the Dynamic Sampling context. -func ContinueFromHeaders(trace, baggage string) SpanOption { - return func(s *Span) { - if trace != "" { - s.updateFromSentryTrace([]byte(trace)) - } - if baggage != "" { - s.updateFromBaggage([]byte(baggage)) - } - - // In case a sentry-trace header is present but there are no sentry-related - // values in the baggage, create an empty, frozen DynamicSamplingContext. - if trace != "" && !s.dynamicSamplingContext.HasEntries() { - s.dynamicSamplingContext = DynamicSamplingContext{ - Frozen: true, - } - } - } -} - -// ContinueFromTrace returns a span option that updates the span to continue -// an existing TraceID. -func ContinueFromTrace(trace string) SpanOption { - return func(s *Span) { - if trace == "" { - return - } - s.updateFromSentryTrace([]byte(trace)) - } -} - -// spanContextKey is used to store span values in contexts. -type spanContextKey struct{} - -// TransactionFromContext returns the root span of the current transaction. It -// returns nil if no transaction is tracked in the context. -func TransactionFromContext(ctx context.Context) *Span { - if span, ok := ctx.Value(spanContextKey{}).(*Span); ok { - return span.recorder.root() - } - return nil -} - -// SpanFromContext returns the last span stored in the context, or nil if no span -// is set on the context. -func SpanFromContext(ctx context.Context) *Span { - if span, ok := ctx.Value(spanContextKey{}).(*Span); ok { - return span - } - return nil -} - -// StartTransaction will create a transaction (root span) if there's no existing -// transaction in the context otherwise, it will return the existing transaction. -func StartTransaction(ctx context.Context, name string, options ...SpanOption) *Span { - currentTransaction, exists := ctx.Value(spanContextKey{}).(*Span) - if exists { - currentTransaction.ctx = ctx - return currentTransaction - } - - options = append(options, WithTransactionName(name)) - return StartSpan( - ctx, - "", - options..., - ) -} - -// HTTPtoSpanStatus converts an HTTP status code to a SpanStatus. -func HTTPtoSpanStatus(code int) SpanStatus { - if code < http.StatusBadRequest { - return SpanStatusOK - } - if http.StatusBadRequest <= code && code < http.StatusInternalServerError { - switch code { - case http.StatusForbidden: - return SpanStatusPermissionDenied - case http.StatusNotFound: - return SpanStatusNotFound - case http.StatusTooManyRequests: - return SpanStatusResourceExhausted - case http.StatusRequestEntityTooLarge: - return SpanStatusFailedPrecondition - case http.StatusUnauthorized: - return SpanStatusUnauthenticated - case http.StatusConflict: - return SpanStatusAlreadyExists - default: - return SpanStatusInvalidArgument - } - } - if http.StatusInternalServerError <= code && code < 600 { - switch code { - case http.StatusGatewayTimeout: - return SpanStatusDeadlineExceeded - case http.StatusNotImplemented: - return SpanStatusUnimplemented - case http.StatusServiceUnavailable: - return SpanStatusUnavailable - default: - return SpanStatusInternalError - } - } - return SpanStatusUnknown -} diff --git a/vendor/github.com/getsentry/sentry-go/transport.go b/vendor/github.com/getsentry/sentry-go/transport.go deleted file mode 100644 index 02fc1d4f1..000000000 --- a/vendor/github.com/getsentry/sentry-go/transport.go +++ /dev/null @@ -1,745 +0,0 @@ -package sentry - -import ( - "bytes" - "context" - "crypto/tls" - "encoding/json" - "errors" - "fmt" - "io" - "net/http" - "net/url" - "sync" - "time" - - "github.com/getsentry/sentry-go/internal/ratelimit" -) - -const defaultBufferSize = 30 -const defaultTimeout = time.Second * 30 - -// maxDrainResponseBytes is the maximum number of bytes that transport -// implementations will read from response bodies when draining them. -// -// Sentry's ingestion API responses are typically short and the SDK doesn't need -// the contents of the response body. However, the net/http HTTP client requires -// response bodies to be fully drained (and closed) for TCP keep-alive to work. -// -// maxDrainResponseBytes strikes a balance between reading too much data (if the -// server is misbehaving) and reusing TCP connections. -const maxDrainResponseBytes = 16 << 10 - -// Transport is used by the Client to deliver events to remote server. -type Transport interface { - Flush(timeout time.Duration) bool - Configure(options ClientOptions) - SendEvent(event *Event) -} - -func getProxyConfig(options ClientOptions) func(*http.Request) (*url.URL, error) { - if options.HTTPSProxy != "" { - return func(*http.Request) (*url.URL, error) { - return url.Parse(options.HTTPSProxy) - } - } - - if options.HTTPProxy != "" { - return func(*http.Request) (*url.URL, error) { - return url.Parse(options.HTTPProxy) - } - } - - return http.ProxyFromEnvironment -} - -func getTLSConfig(options ClientOptions) *tls.Config { - if options.CaCerts != nil { - // #nosec G402 -- We should be using `MinVersion: tls.VersionTLS12`, - // but we don't want to break peoples code without the major bump. - return &tls.Config{ - RootCAs: options.CaCerts, - } - } - - return nil -} - -func getRequestBodyFromEvent(event *Event) []byte { - body, err := json.Marshal(event) - if err == nil { - return body - } - - msg := fmt.Sprintf("Could not encode original event as JSON. "+ - "Succeeded by removing Breadcrumbs, Contexts and Extra. "+ - "Please verify the data you attach to the scope. "+ - "Error: %s", err) - // Try to serialize the event, with all the contextual data that allows for interface{} stripped. - event.Breadcrumbs = nil - event.Contexts = nil - event.Extra = map[string]interface{}{ - "info": msg, - } - body, err = json.Marshal(event) - if err == nil { - Logger.Println(msg) - return body - } - - // This should _only_ happen when Event.Exception[0].Stacktrace.Frames[0].Vars is unserializable - // Which won't ever happen, as we don't use it now (although it's the part of public interface accepted by Sentry) - // Juuust in case something, somehow goes utterly wrong. - Logger.Println("Event couldn't be marshaled, even with stripped contextual data. Skipping delivery. " + - "Please notify the SDK owners with possibly broken payload.") - return nil -} - -func marshalMetrics(metrics []Metric) []byte { - var b bytes.Buffer - for i, metric := range metrics { - b.WriteString(metric.GetKey()) - if unit := metric.GetUnit(); unit != "" { - b.WriteString(fmt.Sprintf("@%s", unit)) - } - b.WriteString(fmt.Sprintf("%s|%s", metric.SerializeValue(), metric.GetType())) - if serializedTags := metric.SerializeTags(); serializedTags != "" { - b.WriteString(fmt.Sprintf("|#%s", serializedTags)) - } - b.WriteString(fmt.Sprintf("|T%d", metric.GetTimestamp())) - - if i < len(metrics)-1 { - b.WriteString("\n") - } - } - return b.Bytes() -} - -func encodeMetric(enc *json.Encoder, b io.Writer, metrics []Metric) error { - body := marshalMetrics(metrics) - // Item header - err := enc.Encode(struct { - Type string `json:"type"` - Length int `json:"length"` - }{ - Type: metricType, - Length: len(body), - }) - if err != nil { - return err - } - - // metric payload - if _, err = b.Write(body); err != nil { - return err - } - - // "Envelopes should be terminated with a trailing newline." - // - // [1]: https://develop.sentry.dev/sdk/envelopes/#envelopes - if _, err := b.Write([]byte("\n")); err != nil { - return err - } - - return err -} - -func encodeAttachment(enc *json.Encoder, b io.Writer, attachment *Attachment) error { - // Attachment header - err := enc.Encode(struct { - Type string `json:"type"` - Length int `json:"length"` - Filename string `json:"filename"` - ContentType string `json:"content_type,omitempty"` - }{ - Type: "attachment", - Length: len(attachment.Payload), - Filename: attachment.Filename, - ContentType: attachment.ContentType, - }) - if err != nil { - return err - } - - // Attachment payload - if _, err = b.Write(attachment.Payload); err != nil { - return err - } - - // "Envelopes should be terminated with a trailing newline." - // - // [1]: https://develop.sentry.dev/sdk/envelopes/#envelopes - if _, err := b.Write([]byte("\n")); err != nil { - return err - } - - return nil -} - -func encodeEnvelopeItem(enc *json.Encoder, itemType string, body json.RawMessage) error { - // Item header - err := enc.Encode(struct { - Type string `json:"type"` - Length int `json:"length"` - }{ - Type: itemType, - Length: len(body), - }) - if err == nil { - // payload - err = enc.Encode(body) - } - return err -} - -func envelopeFromBody(event *Event, dsn *Dsn, sentAt time.Time, body json.RawMessage) (*bytes.Buffer, error) { - var b bytes.Buffer - enc := json.NewEncoder(&b) - - // Construct the trace envelope header - var trace = map[string]string{} - if dsc := event.sdkMetaData.dsc; dsc.HasEntries() { - for k, v := range dsc.Entries { - trace[k] = v - } - } - - // Envelope header - err := enc.Encode(struct { - EventID EventID `json:"event_id"` - SentAt time.Time `json:"sent_at"` - Dsn string `json:"dsn"` - Sdk map[string]string `json:"sdk"` - Trace map[string]string `json:"trace,omitempty"` - }{ - EventID: event.EventID, - SentAt: sentAt, - Trace: trace, - Dsn: dsn.String(), - Sdk: map[string]string{ - "name": event.Sdk.Name, - "version": event.Sdk.Version, - }, - }) - if err != nil { - return nil, err - } - - switch event.Type { - case transactionType, checkInType: - err = encodeEnvelopeItem(enc, event.Type, body) - case metricType: - err = encodeMetric(enc, &b, event.Metrics) - default: - err = encodeEnvelopeItem(enc, eventType, body) - } - - if err != nil { - return nil, err - } - - // Attachments - for _, attachment := range event.Attachments { - if err := encodeAttachment(enc, &b, attachment); err != nil { - return nil, err - } - } - - // Profile data - if event.sdkMetaData.transactionProfile != nil { - body, err = json.Marshal(event.sdkMetaData.transactionProfile) - if err != nil { - return nil, err - } - err = encodeEnvelopeItem(enc, profileType, body) - if err != nil { - return nil, err - } - } - - return &b, nil -} - -func getRequestFromEvent(ctx context.Context, event *Event, dsn *Dsn) (r *http.Request, err error) { - defer func() { - if r != nil { - r.Header.Set("User-Agent", fmt.Sprintf("%s/%s", event.Sdk.Name, event.Sdk.Version)) - r.Header.Set("Content-Type", "application/x-sentry-envelope") - - auth := fmt.Sprintf("Sentry sentry_version=%s, "+ - "sentry_client=%s/%s, sentry_key=%s", apiVersion, event.Sdk.Name, event.Sdk.Version, dsn.publicKey) - - // The key sentry_secret is effectively deprecated and no longer needs to be set. - // However, since it was required in older self-hosted versions, - // it should still passed through to Sentry if set. - if dsn.secretKey != "" { - auth = fmt.Sprintf("%s, sentry_secret=%s", auth, dsn.secretKey) - } - - r.Header.Set("X-Sentry-Auth", auth) - } - }() - body := getRequestBodyFromEvent(event) - if body == nil { - return nil, errors.New("event could not be marshaled") - } - envelope, err := envelopeFromBody(event, dsn, time.Now(), body) - if err != nil { - return nil, err - } - - if ctx == nil { - ctx = context.Background() - } - - return http.NewRequestWithContext( - ctx, - http.MethodPost, - dsn.GetAPIURL().String(), - envelope, - ) -} - -func categoryFor(eventType string) ratelimit.Category { - switch eventType { - case "": - return ratelimit.CategoryError - case transactionType: - return ratelimit.CategoryTransaction - default: - return ratelimit.Category(eventType) - } -} - -// ================================ -// HTTPTransport -// ================================ - -// A batch groups items that are processed sequentially. -type batch struct { - items chan batchItem - started chan struct{} // closed to signal items started to be worked on - done chan struct{} // closed to signal completion of all items -} - -type batchItem struct { - request *http.Request - category ratelimit.Category -} - -// HTTPTransport is the default, non-blocking, implementation of Transport. -// -// Clients using this transport will enqueue requests in a buffer and return to -// the caller before any network communication has happened. Requests are sent -// to Sentry sequentially from a background goroutine. -type HTTPTransport struct { - dsn *Dsn - client *http.Client - transport http.RoundTripper - - // buffer is a channel of batches. Calling Flush terminates work on the - // current in-flight items and starts a new batch for subsequent events. - buffer chan batch - - start sync.Once - - // Size of the transport buffer. Defaults to 30. - BufferSize int - // HTTP Client request timeout. Defaults to 30 seconds. - Timeout time.Duration - - mu sync.RWMutex - limits ratelimit.Map -} - -// NewHTTPTransport returns a new pre-configured instance of HTTPTransport. -func NewHTTPTransport() *HTTPTransport { - transport := HTTPTransport{ - BufferSize: defaultBufferSize, - Timeout: defaultTimeout, - } - return &transport -} - -// Configure is called by the Client itself, providing it it's own ClientOptions. -func (t *HTTPTransport) Configure(options ClientOptions) { - dsn, err := NewDsn(options.Dsn) - if err != nil { - Logger.Printf("%v\n", err) - return - } - t.dsn = dsn - - // A buffered channel with capacity 1 works like a mutex, ensuring only one - // goroutine can access the current batch at a given time. Access is - // synchronized by reading from and writing to the channel. - t.buffer = make(chan batch, 1) - t.buffer <- batch{ - items: make(chan batchItem, t.BufferSize), - started: make(chan struct{}), - done: make(chan struct{}), - } - - if options.HTTPTransport != nil { - t.transport = options.HTTPTransport - } else { - t.transport = &http.Transport{ - Proxy: getProxyConfig(options), - TLSClientConfig: getTLSConfig(options), - } - } - - if options.HTTPClient != nil { - t.client = options.HTTPClient - } else { - t.client = &http.Client{ - Transport: t.transport, - Timeout: t.Timeout, - } - } - - t.start.Do(func() { - go t.worker() - }) -} - -// SendEvent assembles a new packet out of Event and sends it to the remote server. -func (t *HTTPTransport) SendEvent(event *Event) { - t.SendEventWithContext(context.Background(), event) -} - -// SendEventWithContext assembles a new packet out of Event and sends it to the remote server. -func (t *HTTPTransport) SendEventWithContext(ctx context.Context, event *Event) { - if t.dsn == nil { - return - } - - category := categoryFor(event.Type) - - if t.disabled(category) { - return - } - - request, err := getRequestFromEvent(ctx, event, t.dsn) - if err != nil { - return - } - - // <-t.buffer is equivalent to acquiring a lock to access the current batch. - // A few lines below, t.buffer <- b releases the lock. - // - // The lock must be held during the select block below to guarantee that - // b.items is not closed while trying to send to it. Remember that sending - // on a closed channel panics. - // - // Note that the select block takes a bounded amount of CPU time because of - // the default case that is executed if sending on b.items would block. That - // is, the event is dropped if it cannot be sent immediately to the b.items - // channel (used as a queue). - b := <-t.buffer - - select { - case b.items <- batchItem{ - request: request, - category: category, - }: - var eventType string - if event.Type == transactionType { - eventType = "transaction" - } else { - eventType = fmt.Sprintf("%s event", event.Level) - } - Logger.Printf( - "Sending %s [%s] to %s project: %s", - eventType, - event.EventID, - t.dsn.host, - t.dsn.projectID, - ) - default: - Logger.Println("Event dropped due to transport buffer being full.") - } - - t.buffer <- b -} - -// Flush waits until any buffered events are sent to the Sentry server, blocking -// for at most the given timeout. It returns false if the timeout was reached. -// In that case, some events may not have been sent. -// -// Flush should be called before terminating the program to avoid -// unintentionally dropping events. -// -// Do not call Flush indiscriminately after every call to SendEvent. Instead, to -// have the SDK send events over the network synchronously, configure it to use -// the HTTPSyncTransport in the call to Init. -func (t *HTTPTransport) Flush(timeout time.Duration) bool { - toolate := time.After(timeout) - - // Wait until processing the current batch has started or the timeout. - // - // We must wait until the worker has seen the current batch, because it is - // the only way b.done will be closed. If we do not wait, there is a - // possible execution flow in which b.done is never closed, and the only way - // out of Flush would be waiting for the timeout, which is undesired. - var b batch - for { - select { - case b = <-t.buffer: - select { - case <-b.started: - goto started - default: - t.buffer <- b - } - case <-toolate: - goto fail - } - } - -started: - // Signal that there won't be any more items in this batch, so that the - // worker inner loop can end. - close(b.items) - // Start a new batch for subsequent events. - t.buffer <- batch{ - items: make(chan batchItem, t.BufferSize), - started: make(chan struct{}), - done: make(chan struct{}), - } - - // Wait until the current batch is done or the timeout. - select { - case <-b.done: - Logger.Println("Buffer flushed successfully.") - return true - case <-toolate: - goto fail - } - -fail: - Logger.Println("Buffer flushing reached the timeout.") - return false -} - -func (t *HTTPTransport) worker() { - for b := range t.buffer { - // Signal that processing of the current batch has started. - close(b.started) - - // Return the batch to the buffer so that other goroutines can use it. - // Equivalent to releasing a lock. - t.buffer <- b - - // Process all batch items. - for item := range b.items { - if t.disabled(item.category) { - continue - } - - response, err := t.client.Do(item.request) - if err != nil { - Logger.Printf("There was an issue with sending an event: %v", err) - continue - } - if response.StatusCode >= 400 && response.StatusCode <= 599 { - b, err := io.ReadAll(response.Body) - if err != nil { - Logger.Printf("Error while reading response code: %v", err) - } - Logger.Printf("Sending %s failed with the following error: %s", eventType, string(b)) - } - - t.mu.Lock() - if t.limits == nil { - t.limits = make(ratelimit.Map) - } - t.limits.Merge(ratelimit.FromResponse(response)) - t.mu.Unlock() - - // Drain body up to a limit and close it, allowing the - // transport to reuse TCP connections. - _, _ = io.CopyN(io.Discard, response.Body, maxDrainResponseBytes) - response.Body.Close() - } - - // Signal that processing of the batch is done. - close(b.done) - } -} - -func (t *HTTPTransport) disabled(c ratelimit.Category) bool { - t.mu.RLock() - defer t.mu.RUnlock() - disabled := t.limits.IsRateLimited(c) - if disabled { - Logger.Printf("Too many requests for %q, backing off till: %v", c, t.limits.Deadline(c)) - } - return disabled -} - -// ================================ -// HTTPSyncTransport -// ================================ - -// HTTPSyncTransport is a blocking implementation of Transport. -// -// Clients using this transport will send requests to Sentry sequentially and -// block until a response is returned. -// -// The blocking behavior is useful in a limited set of use cases. For example, -// use it when deploying code to a Function as a Service ("Serverless") -// platform, where any work happening in a background goroutine is not -// guaranteed to execute. -// -// For most cases, prefer HTTPTransport. -type HTTPSyncTransport struct { - dsn *Dsn - client *http.Client - transport http.RoundTripper - - mu sync.Mutex - limits ratelimit.Map - - // HTTP Client request timeout. Defaults to 30 seconds. - Timeout time.Duration -} - -// NewHTTPSyncTransport returns a new pre-configured instance of HTTPSyncTransport. -func NewHTTPSyncTransport() *HTTPSyncTransport { - transport := HTTPSyncTransport{ - Timeout: defaultTimeout, - limits: make(ratelimit.Map), - } - - return &transport -} - -// Configure is called by the Client itself, providing it it's own ClientOptions. -func (t *HTTPSyncTransport) Configure(options ClientOptions) { - dsn, err := NewDsn(options.Dsn) - if err != nil { - Logger.Printf("%v\n", err) - return - } - t.dsn = dsn - - if options.HTTPTransport != nil { - t.transport = options.HTTPTransport - } else { - t.transport = &http.Transport{ - Proxy: getProxyConfig(options), - TLSClientConfig: getTLSConfig(options), - } - } - - if options.HTTPClient != nil { - t.client = options.HTTPClient - } else { - t.client = &http.Client{ - Transport: t.transport, - Timeout: t.Timeout, - } - } -} - -// SendEvent assembles a new packet out of Event and sends it to the remote server. -func (t *HTTPSyncTransport) SendEvent(event *Event) { - t.SendEventWithContext(context.Background(), event) -} - -// SendEventWithContext assembles a new packet out of Event and sends it to the remote server. -func (t *HTTPSyncTransport) SendEventWithContext(ctx context.Context, event *Event) { - if t.dsn == nil { - return - } - - if t.disabled(categoryFor(event.Type)) { - return - } - - request, err := getRequestFromEvent(ctx, event, t.dsn) - if err != nil { - return - } - - var eventType string - switch { - case event.Type == transactionType: - eventType = "transaction" - case event.Type == metricType: - eventType = metricType - default: - eventType = fmt.Sprintf("%s event", event.Level) - } - Logger.Printf( - "Sending %s [%s] to %s project: %s", - eventType, - event.EventID, - t.dsn.host, - t.dsn.projectID, - ) - - response, err := t.client.Do(request) - if err != nil { - Logger.Printf("There was an issue with sending an event: %v", err) - return - } - if response.StatusCode >= 400 && response.StatusCode <= 599 { - b, err := io.ReadAll(response.Body) - if err != nil { - Logger.Printf("Error while reading response code: %v", err) - } - Logger.Printf("Sending %s failed with the following error: %s", eventType, string(b)) - } - - t.mu.Lock() - if t.limits == nil { - t.limits = make(ratelimit.Map) - } - - t.limits.Merge(ratelimit.FromResponse(response)) - t.mu.Unlock() - - // Drain body up to a limit and close it, allowing the - // transport to reuse TCP connections. - _, _ = io.CopyN(io.Discard, response.Body, maxDrainResponseBytes) - response.Body.Close() -} - -// Flush is a no-op for HTTPSyncTransport. It always returns true immediately. -func (t *HTTPSyncTransport) Flush(_ time.Duration) bool { - return true -} - -func (t *HTTPSyncTransport) disabled(c ratelimit.Category) bool { - t.mu.Lock() - defer t.mu.Unlock() - disabled := t.limits.IsRateLimited(c) - if disabled { - Logger.Printf("Too many requests for %q, backing off till: %v", c, t.limits.Deadline(c)) - } - return disabled -} - -// ================================ -// noopTransport -// ================================ - -// noopTransport is an implementation of Transport interface which drops all the events. -// Only used internally when an empty DSN is provided, which effectively disables the SDK. -type noopTransport struct{} - -var _ Transport = noopTransport{} - -func (noopTransport) Configure(ClientOptions) { - Logger.Println("Sentry client initialized with an empty DSN. Using noopTransport. No events will be delivered.") -} - -func (noopTransport) SendEvent(*Event) { - Logger.Println("Event dropped due to noopTransport usage.") -} - -func (noopTransport) Flush(time.Duration) bool { - return true -} diff --git a/vendor/github.com/getsentry/sentry-go/util.go b/vendor/github.com/getsentry/sentry-go/util.go deleted file mode 100644 index 8f999ed7b..000000000 --- a/vendor/github.com/getsentry/sentry-go/util.go +++ /dev/null @@ -1,118 +0,0 @@ -package sentry - -import ( - "crypto/rand" - "encoding/hex" - "encoding/json" - "fmt" - "os" - "runtime/debug" - "strings" - "time" - - exec "golang.org/x/sys/execabs" -) - -func uuid() string { - id := make([]byte, 16) - // Prefer rand.Read over rand.Reader, see https://go-review.googlesource.com/c/go/+/272326/. - _, _ = rand.Read(id) - id[6] &= 0x0F // clear version - id[6] |= 0x40 // set version to 4 (random uuid) - id[8] &= 0x3F // clear variant - id[8] |= 0x80 // set to IETF variant - return hex.EncodeToString(id) -} - -func fileExists(fileName string) bool { - _, err := os.Stat(fileName) - return err == nil -} - -// monotonicTimeSince replaces uses of time.Now() to take into account the -// monotonic clock reading stored in start, such that duration = end - start is -// unaffected by changes in the system wall clock. -func monotonicTimeSince(start time.Time) (end time.Time) { - return start.Add(time.Since(start)) -} - -// nolint: deadcode, unused -func prettyPrint(data interface{}) { - dbg, _ := json.MarshalIndent(data, "", " ") - fmt.Println(string(dbg)) -} - -// defaultRelease attempts to guess a default release for the currently running -// program. -func defaultRelease() (release string) { - // Return first non-empty environment variable known to hold release info, if any. - envs := []string{ - "SENTRY_RELEASE", - "HEROKU_SLUG_COMMIT", - "SOURCE_VERSION", - "CODEBUILD_RESOLVED_SOURCE_VERSION", - "CIRCLE_SHA1", - "GAE_DEPLOYMENT_ID", - "GITHUB_SHA", // GitHub Actions - https://help.github.com/en/actions - "COMMIT_REF", // Netlify - https://docs.netlify.com/ - "VERCEL_GIT_COMMIT_SHA", // Vercel - https://vercel.com/ - "ZEIT_GITHUB_COMMIT_SHA", // Zeit (now known as Vercel) - "ZEIT_GITLAB_COMMIT_SHA", - "ZEIT_BITBUCKET_COMMIT_SHA", - } - for _, e := range envs { - if release = os.Getenv(e); release != "" { - Logger.Printf("Using release from environment variable %s: %s", e, release) - return release - } - } - - if info, ok := debug.ReadBuildInfo(); ok { - buildInfoVcsRevision := revisionFromBuildInfo(info) - if len(buildInfoVcsRevision) > 0 { - return buildInfoVcsRevision - } - } - - // Derive a version string from Git. Example outputs: - // v1.0.1-0-g9de4 - // v2.0-8-g77df-dirty - // 4f72d7 - if _, err := exec.LookPath("git"); err == nil { - cmd := exec.Command("git", "describe", "--long", "--always", "--dirty") - b, err := cmd.Output() - if err != nil { - // Either Git is not available or the current directory is not a - // Git repository. - var s strings.Builder - fmt.Fprintf(&s, "Release detection failed: %v", err) - if err, ok := err.(*exec.ExitError); ok && len(err.Stderr) > 0 { - fmt.Fprintf(&s, ": %s", err.Stderr) - } - Logger.Print(s.String()) - } else { - release = strings.TrimSpace(string(b)) - Logger.Printf("Using release from Git: %s", release) - return release - } - } - - Logger.Print("Some Sentry features will not be available. See https://docs.sentry.io/product/releases/.") - Logger.Print("To stop seeing this message, pass a Release to sentry.Init or set the SENTRY_RELEASE environment variable.") - return "" -} - -func revisionFromBuildInfo(info *debug.BuildInfo) string { - for _, setting := range info.Settings { - if setting.Key == "vcs.revision" && setting.Value != "" { - Logger.Printf("Using release from debug info: %s", setting.Value) - return setting.Value - } - } - - return "" -} - -func Pointer[T any](v T) *T { - return &v -} diff --git a/vendor/github.com/ghodss/yaml/.gitignore b/vendor/github.com/ghodss/yaml/.gitignore deleted file mode 100644 index e256a31e0..000000000 --- a/vendor/github.com/ghodss/yaml/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# OSX leaves these everywhere on SMB shares -._* - -# Eclipse files -.classpath -.project -.settings/** - -# Emacs save files -*~ - -# Vim-related files -[._]*.s[a-w][a-z] -[._]s[a-w][a-z] -*.un~ -Session.vim -.netrwhist - -# Go test binaries -*.test diff --git a/vendor/github.com/ghodss/yaml/.travis.yml b/vendor/github.com/ghodss/yaml/.travis.yml deleted file mode 100644 index 0e9d6edc0..000000000 --- a/vendor/github.com/ghodss/yaml/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go -go: - - 1.3 - - 1.4 -script: - - go test - - go build diff --git a/vendor/github.com/ghodss/yaml/LICENSE b/vendor/github.com/ghodss/yaml/LICENSE deleted file mode 100644 index 7805d36de..000000000 --- a/vendor/github.com/ghodss/yaml/LICENSE +++ /dev/null @@ -1,50 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Sam Ghods - -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. - - -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/ghodss/yaml/README.md b/vendor/github.com/ghodss/yaml/README.md deleted file mode 100644 index 0200f75b4..000000000 --- a/vendor/github.com/ghodss/yaml/README.md +++ /dev/null @@ -1,121 +0,0 @@ -# YAML marshaling and unmarshaling support for Go - -[![Build Status](https://travis-ci.org/ghodss/yaml.svg)](https://travis-ci.org/ghodss/yaml) - -## Introduction - -A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs. - -In short, this library first converts YAML to JSON using go-yaml and then uses `json.Marshal` and `json.Unmarshal` to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methods `MarshalJSON` and `UnmarshalJSON` unlike go-yaml. For a detailed overview of the rationale behind this method, [see this blog post](http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/). - -## Compatibility - -This package uses [go-yaml](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility). - -## Caveats - -**Caveat #1:** When using `yaml.Marshal` and `yaml.Unmarshal`, binary data should NOT be preceded with the `!!binary` YAML tag. If you do, go-yaml will convert the binary data from base64 to native binary data, which is not compatible with JSON. You can still use binary in your YAML files though - just store them without the `!!binary` tag and decode the base64 in your code (e.g. in the custom JSON methods `MarshalJSON` and `UnmarshalJSON`). This also has the benefit that your YAML and your JSON binary data will be decoded exactly the same way. As an example: - -``` -BAD: - exampleKey: !!binary gIGC - -GOOD: - exampleKey: gIGC -... and decode the base64 data in your code. -``` - -**Caveat #2:** When using `YAMLToJSON` directly, maps with keys that are maps will result in an error since this is not supported by JSON. This error will occur in `Unmarshal` as well since you can't unmarshal map keys anyways since struct fields can't be keys. - -## Installation and usage - -To install, run: - -``` -$ go get github.com/ghodss/yaml -``` - -And import using: - -``` -import "github.com/ghodss/yaml" -``` - -Usage is very similar to the JSON library: - -```go -package main - -import ( - "fmt" - - "github.com/ghodss/yaml" -) - -type Person struct { - Name string `json:"name"` // Affects YAML field names too. - Age int `json:"age"` -} - -func main() { - // Marshal a Person struct to YAML. - p := Person{"John", 30} - y, err := yaml.Marshal(p) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(y)) - /* Output: - age: 30 - name: John - */ - - // Unmarshal the YAML back into a Person struct. - var p2 Person - err = yaml.Unmarshal(y, &p2) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(p2) - /* Output: - {John 30} - */ -} -``` - -`yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available: - -```go -package main - -import ( - "fmt" - - "github.com/ghodss/yaml" -) - -func main() { - j := []byte(`{"name": "John", "age": 30}`) - y, err := yaml.JSONToYAML(j) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(y)) - /* Output: - name: John - age: 30 - */ - j2, err := yaml.YAMLToJSON(y) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(j2)) - /* Output: - {"age":30,"name":"John"} - */ -} -``` diff --git a/vendor/github.com/ghodss/yaml/fields.go b/vendor/github.com/ghodss/yaml/fields.go deleted file mode 100644 index 586007402..000000000 --- a/vendor/github.com/ghodss/yaml/fields.go +++ /dev/null @@ -1,501 +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. -package yaml - -import ( - "bytes" - "encoding" - "encoding/json" - "reflect" - "sort" - "strings" - "sync" - "unicode" - "unicode/utf8" -) - -// indirect walks down v allocating pointers as needed, -// until it gets to a non-pointer. -// if it encounters an Unmarshaler, indirect stops and returns that. -// if decodingNull is true, indirect stops at the last pointer so it can be set to nil. -func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { - // If v is a named type and is addressable, - // start with its address, so that if the type has pointer methods, - // we find them. - if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { - v = v.Addr() - } - for { - // Load value from interface, but only if the result will be - // usefully addressable. - if v.Kind() == reflect.Interface && !v.IsNil() { - e := v.Elem() - if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { - v = e - continue - } - } - - if v.Kind() != reflect.Ptr { - break - } - - if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() { - break - } - if v.IsNil() { - if v.CanSet() { - v.Set(reflect.New(v.Type().Elem())) - } else { - v = reflect.New(v.Type().Elem()) - } - } - if v.Type().NumMethod() > 0 { - if u, ok := v.Interface().(json.Unmarshaler); ok { - return u, nil, reflect.Value{} - } - if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { - return nil, u, reflect.Value{} - } - } - v = v.Elem() - } - return nil, nil, v -} - -// A field represents a single field found in a struct. -type field struct { - name string - nameBytes []byte // []byte(name) - equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent - - tag bool - index []int - typ reflect.Type - omitEmpty bool - quoted bool -} - -func fillField(f field) field { - f.nameBytes = []byte(f.name) - f.equalFold = foldFunc(f.nameBytes) - return f -} - -// byName sorts field by name, breaking ties with depth, -// then breaking ties with "name came from json 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 JSON 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. - count := map[reflect.Type]int{} - 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 != "" { // unexported - continue - } - tag := sf.Tag.Get("json") - if tag == "-" { - continue - } - name, opts := parseTag(tag) - if !isValidTag(name) { - name = "" - } - 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 name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { - tagged := name != "" - if name == "" { - name = sf.Name - } - fields = append(fields, fillField(field{ - name: name, - tag: tagged, - index: index, - typ: ft, - omitEmpty: opts.Contains("omitempty"), - quoted: opts.Contains("string"), - })) - 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 { - next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft})) - } - } - } - } - - sort.Sort(byName(fields)) - - // Delete all fields that are hidden by the Go rules for embedded fields, - // except that fields with JSON 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 -// JSON 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 -} - -func isValidTag(s string) bool { - if s == "" { - return false - } - for _, c := range s { - switch { - case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): - // Backslash and quote chars are reserved, but - // otherwise any punctuation chars are allowed - // in a tag name. - default: - if !unicode.IsLetter(c) && !unicode.IsDigit(c) { - return false - } - } - } - return true -} - -const ( - caseMask = ^byte(0x20) // Mask to ignore case in ASCII. - kelvin = '\u212a' - smallLongEss = '\u017f' -) - -// foldFunc returns one of four different case folding equivalence -// functions, from most general (and slow) to fastest: -// -// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8 -// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S') -// 3) asciiEqualFold, no special, but includes non-letters (including _) -// 4) simpleLetterEqualFold, no specials, no non-letters. -// -// The letters S and K are special because they map to 3 runes, not just 2: -// * S maps to s and to U+017F 'ſ' Latin small letter long s -// * k maps to K and to U+212A 'K' Kelvin sign -// See http://play.golang.org/p/tTxjOc0OGo -// -// The returned function is specialized for matching against s and -// should only be given s. It's not curried for performance reasons. -func foldFunc(s []byte) func(s, t []byte) bool { - nonLetter := false - special := false // special letter - for _, b := range s { - if b >= utf8.RuneSelf { - return bytes.EqualFold - } - upper := b & caseMask - if upper < 'A' || upper > 'Z' { - nonLetter = true - } else if upper == 'K' || upper == 'S' { - // See above for why these letters are special. - special = true - } - } - if special { - return equalFoldRight - } - if nonLetter { - return asciiEqualFold - } - return simpleLetterEqualFold -} - -// equalFoldRight is a specialization of bytes.EqualFold when s is -// known to be all ASCII (including punctuation), but contains an 's', -// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. -// See comments on foldFunc. -func equalFoldRight(s, t []byte) bool { - for _, sb := range s { - if len(t) == 0 { - return false - } - tb := t[0] - if tb < utf8.RuneSelf { - if sb != tb { - sbUpper := sb & caseMask - if 'A' <= sbUpper && sbUpper <= 'Z' { - if sbUpper != tb&caseMask { - return false - } - } else { - return false - } - } - t = t[1:] - continue - } - // sb is ASCII and t is not. t must be either kelvin - // sign or long s; sb must be s, S, k, or K. - tr, size := utf8.DecodeRune(t) - switch sb { - case 's', 'S': - if tr != smallLongEss { - return false - } - case 'k', 'K': - if tr != kelvin { - return false - } - default: - return false - } - t = t[size:] - - } - if len(t) > 0 { - return false - } - return true -} - -// asciiEqualFold is a specialization of bytes.EqualFold for use when -// s is all ASCII (but may contain non-letters) and contains no -// special-folding letters. -// See comments on foldFunc. -func asciiEqualFold(s, t []byte) bool { - if len(s) != len(t) { - return false - } - for i, sb := range s { - tb := t[i] - if sb == tb { - continue - } - if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { - if sb&caseMask != tb&caseMask { - return false - } - } else { - return false - } - } - return true -} - -// simpleLetterEqualFold is a specialization of bytes.EqualFold for -// use when s is all ASCII letters (no underscores, etc) and also -// doesn't contain 'k', 'K', 's', or 'S'. -// See comments on foldFunc. -func simpleLetterEqualFold(s, t []byte) bool { - if len(s) != len(t) { - return false - } - for i, b := range s { - if b&caseMask != t[i]&caseMask { - return false - } - } - return true -} - -// tagOptions is the string following a comma in a struct field's "json" -// tag, or the empty string. It does not include the leading comma. -type tagOptions string - -// parseTag splits a struct field's json tag into its name and -// comma-separated options. -func parseTag(tag string) (string, tagOptions) { - if idx := strings.Index(tag, ","); idx != -1 { - return tag[:idx], tagOptions(tag[idx+1:]) - } - return tag, tagOptions("") -} - -// Contains reports whether a comma-separated list of options -// contains a particular substr flag. substr must be surrounded by a -// string boundary or commas. -func (o tagOptions) Contains(optionName string) bool { - if len(o) == 0 { - return false - } - s := string(o) - for s != "" { - var next string - i := strings.Index(s, ",") - if i >= 0 { - s, next = s[:i], s[i+1:] - } - if s == optionName { - return true - } - s = next - } - return false -} diff --git a/vendor/github.com/ghodss/yaml/yaml.go b/vendor/github.com/ghodss/yaml/yaml.go deleted file mode 100644 index 4fb4054a8..000000000 --- a/vendor/github.com/ghodss/yaml/yaml.go +++ /dev/null @@ -1,277 +0,0 @@ -package yaml - -import ( - "bytes" - "encoding/json" - "fmt" - "reflect" - "strconv" - - "gopkg.in/yaml.v2" -) - -// Marshals the object into JSON then converts JSON to YAML and returns the -// YAML. -func Marshal(o interface{}) ([]byte, error) { - j, err := json.Marshal(o) - if err != nil { - return nil, fmt.Errorf("error marshaling into JSON: %v", err) - } - - y, err := JSONToYAML(j) - if err != nil { - return nil, fmt.Errorf("error converting JSON to YAML: %v", err) - } - - return y, nil -} - -// Converts YAML to JSON then uses JSON to unmarshal into an object. -func Unmarshal(y []byte, o interface{}) error { - vo := reflect.ValueOf(o) - j, err := yamlToJSON(y, &vo) - if err != nil { - return fmt.Errorf("error converting YAML to JSON: %v", err) - } - - err = json.Unmarshal(j, o) - if err != nil { - return fmt.Errorf("error unmarshaling JSON: %v", err) - } - - return nil -} - -// Convert JSON to YAML. -func JSONToYAML(j []byte) ([]byte, error) { - // Convert the JSON to an object. - var jsonObj interface{} - // We are using yaml.Unmarshal here (instead of json.Unmarshal) because the - // Go JSON library doesn't try to pick the right number type (int, float, - // etc.) when unmarshalling to interface{}, it just picks float64 - // universally. go-yaml does go through the effort of picking the right - // number type, so we can preserve number type throughout this process. - err := yaml.Unmarshal(j, &jsonObj) - if err != nil { - return nil, err - } - - // Marshal this object into YAML. - return yaml.Marshal(jsonObj) -} - -// Convert YAML to JSON. Since JSON is a subset of YAML, passing JSON through -// this method should be a no-op. -// -// Things YAML can do that are not supported by JSON: -// * In YAML you can have binary and null keys in your maps. These are invalid -// in JSON. (int and float keys are converted to strings.) -// * Binary data in YAML with the !!binary tag is not supported. If you want to -// use binary data with this library, encode the data as base64 as usual but do -// not use the !!binary tag in your YAML. This will ensure the original base64 -// encoded data makes it all the way through to the JSON. -func YAMLToJSON(y []byte) ([]byte, error) { - return yamlToJSON(y, nil) -} - -func yamlToJSON(y []byte, jsonTarget *reflect.Value) ([]byte, error) { - // Convert the YAML to an object. - var yamlObj interface{} - err := yaml.Unmarshal(y, &yamlObj) - if err != nil { - return nil, err - } - - // YAML objects are not completely compatible with JSON objects (e.g. you - // can have non-string keys in YAML). So, convert the YAML-compatible object - // to a JSON-compatible object, failing with an error if irrecoverable - // incompatibilties happen along the way. - jsonObj, err := convertToJSONableObject(yamlObj, jsonTarget) - if err != nil { - return nil, err - } - - // Convert this object to JSON and return the data. - return json.Marshal(jsonObj) -} - -func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (interface{}, error) { - var err error - - // Resolve jsonTarget to a concrete value (i.e. not a pointer or an - // interface). We pass decodingNull as false because we're not actually - // decoding into the value, we're just checking if the ultimate target is a - // string. - if jsonTarget != nil { - ju, tu, pv := indirect(*jsonTarget, false) - // We have a JSON or Text Umarshaler at this level, so we can't be trying - // to decode into a string. - if ju != nil || tu != nil { - jsonTarget = nil - } else { - jsonTarget = &pv - } - } - - // If yamlObj is a number or a boolean, check if jsonTarget is a string - - // if so, coerce. Else return normal. - // If yamlObj is a map or array, find the field that each key is - // unmarshaling to, and when you recurse pass the reflect.Value for that - // field back into this function. - switch typedYAMLObj := yamlObj.(type) { - case map[interface{}]interface{}: - // JSON does not support arbitrary keys in a map, so we must convert - // these keys to strings. - // - // From my reading of go-yaml v2 (specifically the resolve function), - // keys can only have the types string, int, int64, float64, binary - // (unsupported), or null (unsupported). - strMap := make(map[string]interface{}) - for k, v := range typedYAMLObj { - // Resolve the key to a string first. - var keyString string - switch typedKey := k.(type) { - case string: - keyString = typedKey - case int: - keyString = strconv.Itoa(typedKey) - case int64: - // go-yaml will only return an int64 as a key if the system - // architecture is 32-bit and the key's value is between 32-bit - // and 64-bit. Otherwise the key type will simply be int. - keyString = strconv.FormatInt(typedKey, 10) - case float64: - // Stolen from go-yaml to use the same conversion to string as - // the go-yaml library uses to convert float to string when - // Marshaling. - s := strconv.FormatFloat(typedKey, 'g', -1, 32) - switch s { - case "+Inf": - s = ".inf" - case "-Inf": - s = "-.inf" - case "NaN": - s = ".nan" - } - keyString = s - case bool: - if typedKey { - keyString = "true" - } else { - keyString = "false" - } - default: - return nil, fmt.Errorf("Unsupported map key of type: %s, key: %+#v, value: %+#v", - reflect.TypeOf(k), k, v) - } - - // jsonTarget should be a struct or a map. If it's a struct, find - // the field it's going to map to and pass its reflect.Value. If - // it's a map, find the element type of the map and pass the - // reflect.Value created from that type. If it's neither, just pass - // nil - JSON conversion will error for us if it's a real issue. - if jsonTarget != nil { - t := *jsonTarget - if t.Kind() == reflect.Struct { - keyBytes := []byte(keyString) - // Find the field that the JSON library would use. - var f *field - fields := cachedTypeFields(t.Type()) - for i := range fields { - ff := &fields[i] - if bytes.Equal(ff.nameBytes, keyBytes) { - f = ff - break - } - // Do case-insensitive comparison. - if f == nil && ff.equalFold(ff.nameBytes, keyBytes) { - f = ff - } - } - if f != nil { - // Find the reflect.Value of the most preferential - // struct field. - jtf := t.Field(f.index[0]) - strMap[keyString], err = convertToJSONableObject(v, &jtf) - if err != nil { - return nil, err - } - continue - } - } else if t.Kind() == reflect.Map { - // Create a zero value of the map's element type to use as - // the JSON target. - jtv := reflect.Zero(t.Type().Elem()) - strMap[keyString], err = convertToJSONableObject(v, &jtv) - if err != nil { - return nil, err - } - continue - } - } - strMap[keyString], err = convertToJSONableObject(v, nil) - if err != nil { - return nil, err - } - } - return strMap, nil - case []interface{}: - // We need to recurse into arrays in case there are any - // map[interface{}]interface{}'s inside and to convert any - // numbers to strings. - - // If jsonTarget is a slice (which it really should be), find the - // thing it's going to map to. If it's not a slice, just pass nil - // - JSON conversion will error for us if it's a real issue. - var jsonSliceElemValue *reflect.Value - if jsonTarget != nil { - t := *jsonTarget - if t.Kind() == reflect.Slice { - // By default slices point to nil, but we need a reflect.Value - // pointing to a value of the slice type, so we create one here. - ev := reflect.Indirect(reflect.New(t.Type().Elem())) - jsonSliceElemValue = &ev - } - } - - // Make and use a new array. - arr := make([]interface{}, len(typedYAMLObj)) - for i, v := range typedYAMLObj { - arr[i], err = convertToJSONableObject(v, jsonSliceElemValue) - if err != nil { - return nil, err - } - } - return arr, nil - default: - // If the target type is a string and the YAML type is a number, - // convert the YAML type to a string. - if jsonTarget != nil && (*jsonTarget).Kind() == reflect.String { - // Based on my reading of go-yaml, it may return int, int64, - // float64, or uint64. - var s string - switch typedVal := typedYAMLObj.(type) { - case int: - s = strconv.FormatInt(int64(typedVal), 10) - case int64: - s = strconv.FormatInt(typedVal, 10) - case float64: - s = strconv.FormatFloat(typedVal, 'g', -1, 32) - case uint64: - s = strconv.FormatUint(typedVal, 10) - case bool: - if typedVal { - s = "true" - } else { - s = "false" - } - } - if len(s) > 0 { - yamlObj = interface{}(s) - } - } - return yamlObj, nil - } - - return nil, nil -} diff --git a/vendor/github.com/ghostiam/protogetter/.goreleaser.yaml b/vendor/github.com/ghostiam/protogetter/.goreleaser.yaml deleted file mode 100644 index a70d0fb00..000000000 --- a/vendor/github.com/ghostiam/protogetter/.goreleaser.yaml +++ /dev/null @@ -1,24 +0,0 @@ -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:' \ No newline at end of file diff --git a/vendor/github.com/ghostiam/protogetter/LICENSE b/vendor/github.com/ghostiam/protogetter/LICENSE deleted file mode 100644 index b4449661b..000000000 --- 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 4c2a62af1..000000000 --- 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 c033e9597..000000000 --- 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/posfilter.go b/vendor/github.com/ghostiam/protogetter/posfilter.go deleted file mode 100644 index 82075ccb1..000000000 --- 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 eca82939d..000000000 --- a/vendor/github.com/ghostiam/protogetter/processor.go +++ /dev/null @@ -1,351 +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 _, s := range x.Lhs { - c.filter.AddPos(s.Pos()) - - if se, ok := s.(*ast.StarExpr); ok { - c.filter.AddPos(se.X.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.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 - } - } - - f, ok := x.Fun.(*ast.SelectorExpr) - if !ok { - return &Result{}, nil - } - - if !isProtoMessage(c.info, f.X) { - return &Result{}, nil - } - - c.processInner(x) - - 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(".") - - // If getter exists, use it. - if methodIsExists(c.info, x.X, "Get"+x.Sel.Name) { - 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: - // 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 -} diff --git a/vendor/github.com/ghostiam/protogetter/protogetter.go b/vendor/github.com/ghostiam/protogetter/protogetter.go deleted file mode 100644 index 31eee8572..000000000 --- a/vendor/github.com/ghostiam/protogetter/protogetter.go +++ /dev/null @@ -1,279 +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" -) - -type Mode int - -const ( - StandaloneMode Mode = iota - GolangciLintMode -) - -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 { - Mode Mode // Zero value is StandaloneMode. - SkipGeneratedBy []string - SkipFiles []string - SkipAnyGenerated bool - ReplaceFirstArgInAppend bool -} - -func Run(pass *analysis.Pass, cfg *Config) ([]Issue, 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 nil, 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), - } - - // 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) - - var issues []Issue - - filter := NewPosFilter() - ins.Preorder(nodeTypes, func(node ast.Node) { - report := analyse(pass, filter, node, cfg) - if report == nil { - return - } - - switch cfg.Mode { - case StandaloneMode: - pass.Report(report.ToDiagReport()) - case GolangciLintMode: - issues = append(issues, report.ToIssue(pass.Fset)) - } - }) - - return issues, 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, - } -} - -// Issue is used to integrate with golangci-lint's inline auto fix. -type Issue struct { - Pos token.Position - Message string - InlineFix InlineFix -} - -type InlineFix struct { - StartCol int // zero-based - Length int - NewString string -} - -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 (r *Report) ToIssue(fset *token.FileSet) Issue { - msg := fmt.Sprintf(msgFormat, r.result.From, r.result.To) - return Issue{ - Pos: fset.Position(r.node.Pos()), - Message: msg, - InlineFix: InlineFix{ - StartCol: fset.Position(r.node.Pos()).Column - 1, - Length: len(r.result.From), - NewString: 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() - - // https://golang.org/s/generatedcode - if skipAny && strings.HasPrefix(firstComment, "Code generated") { - 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 5198a4a94..000000000 --- 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 2a67dccec..000000000 --- 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 81a7aa30b..000000000 --- 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 9be45ccc7..000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/badCond_checker.go +++ /dev/null @@ -1,161 +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) -} - -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 6c6845053..000000000 --- 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.warn("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.warn("clearing unset flag %c in %s", ch, e.Value) - } - } else { - if state[ch] { - c.warn("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.warn("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.warn("`%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.warn("^ 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.warn("$ 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) warn(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 a1c69cb7a..000000000 --- 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 d8be10ce9..000000000 --- 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 0b4b7bafb..000000000 --- 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 b31a6f7fd..000000000 --- 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 306756834..000000000 --- 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(s *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 5797dafdf..000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/checkers.go +++ /dev/null @@ -1,19 +0,0 @@ -// Package checkers is a gocritic 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 6eeb0bb5d..000000000 --- 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 b834158ec..000000000 --- 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 8595b7951..000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go +++ /dev/null @@ -1,167 +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 - } - - 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 - } - - // Some attempts to avoid false positives. - if c.skipBlock(s) { - 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) - } -} - -func (c *commentedOutCodeChecker) skipBlock(s string) bool { - lines := strings.Split(s, "\n") // There is at least 1 line, that's invariant - - // Special example test block. - if isExampleTestFunc(c.fn) && strings.Contains(lines[0], "Output:") { - return true - } - - return false -} - -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 e0855da81..000000000 --- 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 cdebaef98..000000000 --- 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 37c80c864..000000000 --- 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 c61d773da..000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/deprecatedComment_checker.go +++ /dev/null @@ -1,156 +0,0 @@ -package checkers - -import ( - "go/ast" - "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 = "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. - - for _, comment := range doc.List { - if strings.HasPrefix(comment.Text, "/*") { - // TODO(quasilyte): handle multi-line doc comments. - continue - } - l := comment.Text[len("//"):] - if len(l) < len("Deprecated: ") { - continue - } - l = strings.TrimSpace(l) - - // Check whether someone messed up with a prefix casing. - upcase := strings.ToUpper(l) - if strings.HasPrefix(upcase, "DEPRECATED: ") && !strings.HasPrefix(l, "Deprecated: ") { - 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 - } - } - } -} - -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) -} 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 aa23de42c..000000000 --- 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 c4f018387..000000000 --- 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 381bad68b..000000000 --- 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 ed674eb85..000000000 --- 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/dupSubExpr_checker.go b/vendor/github.com/go-critic/go-critic/checkers/dupSubExpr_checker.go deleted file mode 100644 index 9ab75945c..000000000 --- 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 857d09fa0..000000000 --- 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 ad507425e..000000000 --- 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 a008c6187..000000000 --- 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 f8c5ae542..000000000 --- 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 9889f48e8..000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/exitAfterDefer_checker.go +++ /dev/null @@ -1,85 +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 { - // 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 17ab0ea83..000000000 --- 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 701066860..000000000 --- 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 7301bd325..000000000 --- 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 7b7a3c538..000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/hugeParam_checker.go +++ /dev/null @@ -1,83 +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 && - 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 e73c609d5..000000000 --- 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 b690487b7..000000000 --- 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 8612717b2..000000000 --- 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 6c60e3fed..000000000 --- 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 39b536508..000000000 --- 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 de66c1081..000000000 --- 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 c7e3a4371..000000000 --- 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 e042f0d5e..000000000 --- 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 0c9c14955..000000000 --- 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 f6808cbb4..000000000 --- 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 e455b3f8b..000000000 --- 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 403292f66..000000000 --- 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 912de867d..000000000 --- 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 bc9bdef47..000000000 --- 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 3486a8e62..000000000 --- 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 1f6e948d5..000000000 --- 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(f *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 f838a64c1..000000000 --- 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 a6d0ad7c4..000000000 --- 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 f64907d69..000000000 --- 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 ebe7835e5..000000000 --- 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 4370f5818..000000000 --- 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 2885dc725..000000000 --- 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 755d3b472..000000000 --- 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 dfe73018c..000000000 --- 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 1a1b05e0d..000000000 --- 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 9a1213f5c..000000000 --- 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 a25fac85c..000000000 --- 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 c777fec9e..000000000 --- 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 172a4acb5..000000000 --- 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/rangeExprCopy_checker.go b/vendor/github.com/go-critic/go-critic/checkers/rangeExprCopy_checker.go deleted file mode 100644 index 3f61ee0bd..000000000 --- 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 6d15c30cd..000000000 --- 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 45aba261b..000000000 --- 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 f500f4350..000000000 --- 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 29723a69a..000000000 --- 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(err 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 4ab31076f..000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go +++ /dev/null @@ -1,2521 +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: "math.Max($x, $x)"}, - {Line: 386, Value: "math.Min($x, $x)"}, - {Line: 387, Value: "reflect.Copy($x, $x)"}, - {Line: 388, Value: "reflect.DeepEqual($x, $x)"}, - {Line: 389, Value: "strings.Contains($x, $x)"}, - {Line: 390, Value: "strings.Compare($x, $x)"}, - {Line: 391, Value: "strings.EqualFold($x, $x)"}, - {Line: 392, Value: "strings.HasPrefix($x, $x)"}, - {Line: 393, Value: "strings.HasSuffix($x, $x)"}, - {Line: 394, Value: "strings.Index($x, $x)"}, - {Line: 395, Value: "strings.LastIndex($x, $x)"}, - {Line: 396, Value: "strings.Split($x, $x)"}, - {Line: 397, Value: "strings.SplitAfter($x, $x)"}, - {Line: 398, Value: "strings.SplitAfterN($x, $x, $_)"}, - {Line: 399, Value: "strings.SplitN($x, $x, $_)"}, - {Line: 400, Value: "strings.Replace($_, $x, $x, $_)"}, - {Line: 401, Value: "strings.ReplaceAll($_, $x, $x)"}, - {Line: 402, Value: "bytes.Contains($x, $x)"}, - {Line: 403, Value: "bytes.Compare($x, $x)"}, - {Line: 404, Value: "bytes.Equal($x, $x)"}, - {Line: 405, Value: "bytes.EqualFold($x, $x)"}, - {Line: 406, Value: "bytes.HasPrefix($x, $x)"}, - {Line: 407, Value: "bytes.HasSuffix($x, $x)"}, - {Line: 408, Value: "bytes.Index($x, $x)"}, - {Line: 409, Value: "bytes.LastIndex($x, $x)"}, - {Line: 410, Value: "bytes.Split($x, $x)"}, - {Line: 411, Value: "bytes.SplitAfter($x, $x)"}, - {Line: 412, Value: "bytes.SplitAfterN($x, $x, $_)"}, - {Line: 413, Value: "bytes.SplitN($x, $x, $_)"}, - {Line: 414, Value: "bytes.Replace($_, $x, $x, $_)"}, - {Line: 415, Value: "bytes.ReplaceAll($_, $x, $x)"}, - {Line: 416, Value: "types.Identical($x, $x)"}, - {Line: 417, Value: "types.IdenticalIgnoreTags($x, $x)"}, - {Line: 418, Value: "draw.Draw($x, $_, $x, $_, $_)"}, - }, - ReportTemplate: "suspicious duplicated args in $$", - WhereExpr: ir.FilterExpr{Line: 419, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - }, - }, - { - Line: 427, - 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: 428, - SyntaxPatterns: []ir.PatternString{{Line: 428, Value: "if $_ { $*_; http.Error($w, $err, $code) }"}}, - ReportTemplate: "Possibly return is missed after the http.Error call", - LocationVar: "w", - }}, - }, - { - Line: 437, - 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: 438, - SyntaxPatterns: []ir.PatternString{{Line: 438, 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: 439, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Type.Is(`string`) && m[\"y\"].Type.Is(`string`)", - Args: []ir.FilterExpr{ - { - Line: 439, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`string`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 439, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - { - Line: 439, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"y\"].Type.Is(`string`)", - Value: "y", - Args: []ir.FilterExpr{{Line: 439, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - }, - }, - }}, - }, - { - Line: 448, - 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: 449, - SyntaxPatterns: []ir.PatternString{{Line: 449, Value: "$w.Write([]byte($s))"}}, - ReportTemplate: "$w.WriteString($s) should be preferred to the $$", - SuggestTemplate: "$w.WriteString($s)", - WhereExpr: ir.FilterExpr{ - Line: 450, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 450, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, - }, - }, - { - Line: 454, - SyntaxPatterns: []ir.PatternString{{Line: 454, Value: "io.WriteString($w, $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: 464, - 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: 465, - SyntaxPatterns: []ir.PatternString{{Line: 465, 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: 466, - Op: ir.FilterEqOp, - Src: "m[\"zero\"].Value.Int() == 0", - Args: []ir.FilterExpr{ - { - Line: 466, - Op: ir.FilterVarValueIntOp, - Src: "m[\"zero\"].Value.Int()", - Value: "zero", - }, - { - Line: 466, - Op: ir.FilterIntOp, - Src: "0", - Value: int64(0), - }, - }, - }, - }}, - }, - { - Line: 474, - 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: 475, - SyntaxPatterns: []ir.PatternString{{Line: 475, Value: "$_, $ok := $m.Load($k); if $ok { $m.Delete($k); $*_ }"}}, - ReportTemplate: "use $m.LoadAndDelete to perform load+delete operations atomically", - WhereExpr: ir.FilterExpr{ - Line: 476, - Op: ir.FilterAndOp, - Src: "m.GoVersion().GreaterEqThan(\"1.15\") &&\n\tm[\"m\"].Type.Is(`*sync.Map`)", - Args: []ir.FilterExpr{ - { - Line: 476, - Op: ir.FilterGoVersionGreaterEqThanOp, - Src: "m.GoVersion().GreaterEqThan(\"1.15\")", - Value: "1.15", - }, - { - Line: 477, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"m\"].Type.Is(`*sync.Map`)", - Value: "m", - Args: []ir.FilterExpr{{Line: 477, Op: ir.FilterStringOp, Src: "`*sync.Map`", Value: "*sync.Map"}}, - }, - }, - }, - }}, - }, - { - Line: 485, - 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: 486, - SyntaxPatterns: []ir.PatternString{{Line: 486, Value: "fmt.Sprintf($s, $*_)"}}, - ReportTemplate: "use %q instead of \"%s\" for quoted strings", - WhereExpr: ir.FilterExpr{ - Line: 487, - Op: ir.FilterOrOp, - Src: "m[\"s\"].Text.Matches(\"^`.*\\\"%s\\\".*`$\") ||\n\tm[\"s\"].Text.Matches(`^\".*\\\\\"%s\\\\\".*\"$`)", - Args: []ir.FilterExpr{ - { - Line: 487, - Op: ir.FilterVarTextMatchesOp, - Src: "m[\"s\"].Text.Matches(\"^`.*\\\"%s\\\".*`$\")", - Value: "s", - Args: []ir.FilterExpr{{Line: 487, Op: ir.FilterStringOp, Src: "\"^`.*\\\"%s\\\".*`$\"", Value: "^`.*\"%s\".*`$"}}, - }, - { - Line: 488, - Op: ir.FilterVarTextMatchesOp, - Src: "m[\"s\"].Text.Matches(`^\".*\\\\\"%s\\\\\".*\"$`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 488, Op: ir.FilterStringOp, Src: "`^\".*\\\\\"%s\\\\\".*\"$`", Value: "^\".*\\\\\"%s\\\\\".*\"$"}}, - }, - }, - }, - }}, - }, - { - Line: 496, - 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: 497, - SyntaxPatterns: []ir.PatternString{{Line: 497, 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: 498, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"x\"].Type.Is(`[]$_`)", - Args: []ir.FilterExpr{ - {Line: 498, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - { - Line: 498, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`[]$_`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 498, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}}, - }, - }, - }, - }, - { - Line: 505, - SyntaxPatterns: []ir.PatternString{ - {Line: 506, Value: "$i := strings.Index($s, $_); $_ := $slicing[$i:]"}, - {Line: 507, Value: "$i := strings.Index($s, $_); $_ = $slicing[$i:]"}, - {Line: 508, Value: "$i := bytes.Index($s, $_); $_ := $slicing[$i:]"}, - {Line: 509, Value: "$i := bytes.Index($s, $_); $_ = $slicing[$i:]"}, - }, - ReportTemplate: "Index() can return -1; maybe you wanted to do $s[$i+1:]", - WhereExpr: ir.FilterExpr{ - Line: 510, - Op: ir.FilterEqOp, - Src: "m[\"s\"].Text == m[\"slicing\"].Text", - Args: []ir.FilterExpr{ - {Line: 510, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"}, - {Line: 510, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"}, - }, - }, - LocationVar: "slicing", - }, - { - Line: 514, - SyntaxPatterns: []ir.PatternString{ - {Line: 515, Value: "$i := strings.Index($s, $_); $_ := $slicing[:$i]"}, - {Line: 516, Value: "$i := strings.Index($s, $_); $_ = $slicing[:$i]"}, - {Line: 517, Value: "$i := bytes.Index($s, $_); $_ := $slicing[:$i]"}, - {Line: 518, Value: "$i := bytes.Index($s, $_); $_ = $slicing[:$i]"}, - }, - ReportTemplate: "Index() can return -1; maybe you wanted to do $s[:$i+1]", - WhereExpr: ir.FilterExpr{ - Line: 519, - Op: ir.FilterEqOp, - Src: "m[\"s\"].Text == m[\"slicing\"].Text", - Args: []ir.FilterExpr{ - {Line: 519, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"}, - {Line: 519, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"}, - }, - }, - LocationVar: "slicing", - }, - { - Line: 523, - SyntaxPatterns: []ir.PatternString{ - {Line: 524, Value: "$s[strings.Index($s, $_):]"}, - {Line: 525, Value: "$s[:strings.Index($s, $_)]"}, - {Line: 526, Value: "$s[bytes.Index($s, $_):]"}, - {Line: 527, Value: "$s[:bytes.Index($s, $_)]"}, - }, - ReportTemplate: "Index() can return -1; maybe you wanted to do Index()+1", - }, - }, - }, - { - Line: 535, - 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: 536, - SyntaxPatterns: []ir.PatternString{{Line: 536, Value: "$s[:]"}}, - ReportTemplate: "could simplify $$ to $s", - SuggestTemplate: "$s", - WhereExpr: ir.FilterExpr{ - Line: 537, - Op: ir.FilterOrOp, - Src: "m[\"s\"].Type.Is(`string`) || m[\"s\"].Type.Is(`[]$_`)", - Args: []ir.FilterExpr{ - { - Line: 537, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`string`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 537, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - { - Line: 537, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`[]$_`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 537, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}}, - }, - }, - }, - }}, - }, - { - Line: 546, - 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: 547, - SyntaxPatterns: []ir.PatternString{{Line: 547, Value: "$constval != $x"}}, - ReportTemplate: "consider to change order in expression to $x != $constval", - WhereExpr: ir.FilterExpr{ - Line: 547, - Op: ir.FilterAndOp, - Src: "m[\"constval\"].Node.Is(`BasicLit`) && !m[\"x\"].Node.Is(`BasicLit`)", - Args: []ir.FilterExpr{ - { - Line: 547, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"constval\"].Node.Is(`BasicLit`)", - Value: "constval", - Args: []ir.FilterExpr{{Line: 547, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, - }, - { - Line: 547, - Op: ir.FilterNotOp, - Src: "!m[\"x\"].Node.Is(`BasicLit`)", - Args: []ir.FilterExpr{{ - Line: 547, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"x\"].Node.Is(`BasicLit`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 547, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, - }}, - }, - }, - }, - }, - { - Line: 549, - SyntaxPatterns: []ir.PatternString{{Line: 549, Value: "$constval == $x"}}, - ReportTemplate: "consider to change order in expression to $x == $constval", - WhereExpr: ir.FilterExpr{ - Line: 549, - Op: ir.FilterAndOp, - Src: "m[\"constval\"].Node.Is(`BasicLit`) && !m[\"x\"].Node.Is(`BasicLit`)", - Args: []ir.FilterExpr{ - { - Line: 549, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"constval\"].Node.Is(`BasicLit`)", - Value: "constval", - Args: []ir.FilterExpr{{Line: 549, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, - }, - { - Line: 549, - Op: ir.FilterNotOp, - Src: "!m[\"x\"].Node.Is(`BasicLit`)", - Args: []ir.FilterExpr{{ - Line: 549, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"x\"].Node.Is(`BasicLit`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 549, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, - }}, - }, - }, - }, - }, - { - Line: 552, - SyntaxPatterns: []ir.PatternString{{Line: 552, Value: "nil != $x"}}, - ReportTemplate: "consider to change order in expression to $x != nil", - WhereExpr: ir.FilterExpr{ - 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: "nil == $x"}}, - ReportTemplate: "consider to change order in expression to $x == nil", - WhereExpr: ir.FilterExpr{ - 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: 562, - 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: 571, - SyntaxPatterns: []ir.PatternString{ - {Line: 572, Value: "strings.ToLower($x) == $y"}, - {Line: 573, Value: "strings.ToLower($x) == strings.ToLower($y)"}, - {Line: 574, Value: "$x == strings.ToLower($y)"}, - {Line: 575, Value: "strings.ToUpper($x) == $y"}, - {Line: 576, Value: "strings.ToUpper($x) == strings.ToUpper($y)"}, - {Line: 577, Value: "$x == strings.ToUpper($y)"}, - }, - ReportTemplate: "consider replacing with strings.EqualFold($x, $y)", - SuggestTemplate: "strings.EqualFold($x, $y)", - WhereExpr: ir.FilterExpr{ - Line: 578, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - { - Line: 578, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure", - Args: []ir.FilterExpr{ - {Line: 578, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - {Line: 578, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, - }, - }, - { - Line: 578, - Op: ir.FilterNeqOp, - Src: "m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - {Line: 578, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, - {Line: 578, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, - }, - }, - }, - }, - }, - { - Line: 583, - SyntaxPatterns: []ir.PatternString{ - {Line: 584, Value: "strings.ToLower($x) != $y"}, - {Line: 585, Value: "strings.ToLower($x) != strings.ToLower($y)"}, - {Line: 586, Value: "$x != strings.ToLower($y)"}, - {Line: 587, Value: "strings.ToUpper($x) != $y"}, - {Line: 588, Value: "strings.ToUpper($x) != strings.ToUpper($y)"}, - {Line: 589, Value: "$x != strings.ToUpper($y)"}, - }, - ReportTemplate: "consider replacing with !strings.EqualFold($x, $y)", - SuggestTemplate: "!strings.EqualFold($x, $y)", - WhereExpr: ir.FilterExpr{ - Line: 590, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - { - Line: 590, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure", - Args: []ir.FilterExpr{ - {Line: 590, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - {Line: 590, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, - }, - }, - { - Line: 590, - Op: ir.FilterNeqOp, - Src: "m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - {Line: 590, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, - {Line: 590, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, - }, - }, - }, - }, - }, - { - Line: 595, - SyntaxPatterns: []ir.PatternString{ - {Line: 596, Value: "bytes.Equal(bytes.ToLower($x), $y)"}, - {Line: 597, Value: "bytes.Equal(bytes.ToLower($x), bytes.ToLower($y))"}, - {Line: 598, Value: "bytes.Equal($x, bytes.ToLower($y))"}, - {Line: 599, Value: "bytes.Equal(bytes.ToUpper($x), $y)"}, - {Line: 600, Value: "bytes.Equal(bytes.ToUpper($x), bytes.ToUpper($y))"}, - {Line: 601, Value: "bytes.Equal($x, bytes.ToUpper($y))"}, - }, - ReportTemplate: "consider replacing with bytes.EqualFold($x, $y)", - SuggestTemplate: "bytes.EqualFold($x, $y)", - WhereExpr: ir.FilterExpr{ - Line: 602, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - { - Line: 602, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure", - Args: []ir.FilterExpr{ - {Line: 602, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - {Line: 602, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, - }, - }, - { - Line: 602, - Op: ir.FilterNeqOp, - Src: "m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - {Line: 602, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, - {Line: 602, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, - }, - }, - }, - }, - }, - }, - }, - { - Line: 611, - Name: "argOrder", - MatcherName: "m", - DocTags: []string{"diagnostic"}, - DocSummary: "Detects suspicious arguments order", - DocBefore: "strings.HasPrefix(\"#\", userpass)", - DocAfter: "strings.HasPrefix(userpass, \"#\")", - Rules: []ir.Rule{{ - Line: 612, - SyntaxPatterns: []ir.PatternString{ - {Line: 613, Value: "strings.HasPrefix($lit, $s)"}, - {Line: 614, Value: "bytes.HasPrefix($lit, $s)"}, - {Line: 615, Value: "strings.HasSuffix($lit, $s)"}, - {Line: 616, Value: "bytes.HasSuffix($lit, $s)"}, - {Line: 617, Value: "strings.Contains($lit, $s)"}, - {Line: 618, Value: "bytes.Contains($lit, $s)"}, - {Line: 619, Value: "strings.TrimPrefix($lit, $s)"}, - {Line: 620, Value: "bytes.TrimPrefix($lit, $s)"}, - {Line: 621, Value: "strings.TrimSuffix($lit, $s)"}, - {Line: 622, Value: "bytes.TrimSuffix($lit, $s)"}, - {Line: 623, Value: "strings.Split($lit, $s)"}, - {Line: 624, Value: "bytes.Split($lit, $s)"}, - }, - ReportTemplate: "$lit and $s arguments order looks reversed", - WhereExpr: ir.FilterExpr{ - Line: 625, - 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: 625, - Op: ir.FilterAndOp, - Src: "(m[\"lit\"].Const || m[\"lit\"].ConstSlice) &&\n\t!(m[\"s\"].Const || m[\"s\"].ConstSlice)", - Args: []ir.FilterExpr{ - { - Line: 625, - Op: ir.FilterOrOp, - Src: "(m[\"lit\"].Const || m[\"lit\"].ConstSlice)", - Args: []ir.FilterExpr{ - { - Line: 625, - Op: ir.FilterVarConstOp, - Src: "m[\"lit\"].Const", - Value: "lit", - }, - { - Line: 625, - Op: ir.FilterVarConstSliceOp, - Src: "m[\"lit\"].ConstSlice", - Value: "lit", - }, - }, - }, - { - Line: 626, - Op: ir.FilterNotOp, - Src: "!(m[\"s\"].Const || m[\"s\"].ConstSlice)", - Args: []ir.FilterExpr{{ - Line: 626, - Op: ir.FilterOrOp, - Src: "(m[\"s\"].Const || m[\"s\"].ConstSlice)", - Args: []ir.FilterExpr{ - { - Line: 626, - Op: ir.FilterVarConstOp, - Src: "m[\"s\"].Const", - Value: "s", - }, - { - Line: 626, - Op: ir.FilterVarConstSliceOp, - Src: "m[\"s\"].ConstSlice", - Value: "s", - }, - }, - }}, - }, - }, - }, - { - Line: 627, - Op: ir.FilterNotOp, - Src: "!m[\"lit\"].Node.Is(`Ident`)", - Args: []ir.FilterExpr{{ - Line: 627, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"lit\"].Node.Is(`Ident`)", - Value: "lit", - Args: []ir.FilterExpr{{Line: 627, Op: ir.FilterStringOp, Src: "`Ident`", Value: "Ident"}}, - }}, - }, - }, - }, - }}, - }, - { - Line: 635, - 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: 636, - SyntaxPatterns: []ir.PatternString{{Line: 636, Value: "strings.Join([]string{$x, $y}, \"\")"}}, - ReportTemplate: "suggestion: $x + $y", - SuggestTemplate: "$x + $y", - }, - { - Line: 637, - SyntaxPatterns: []ir.PatternString{{Line: 637, Value: "strings.Join([]string{$x, $y, $z}, \"\")"}}, - ReportTemplate: "suggestion: $x + $y + $z", - SuggestTemplate: "$x + $y + $z", - }, - { - Line: 638, - SyntaxPatterns: []ir.PatternString{{Line: 638, Value: "strings.Join([]string{$x, $y}, $glue)"}}, - ReportTemplate: "suggestion: $x + $glue + $y", - SuggestTemplate: "$x + $glue + $y", - }, - }, - }, - { - Line: 645, - 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: 650, - SyntaxPatterns: []ir.PatternString{{Line: 650, Value: "$t.Unix() / 1000"}}, - ReportTemplate: "use $t.UnixMilli() instead of $$", - SuggestTemplate: "$t.UnixMilli()", - WhereExpr: ir.FilterExpr{ - Line: 651, - Op: ir.FilterAndOp, - Src: "m.GoVersion().GreaterEqThan(\"1.17\") && isTime(m[\"t\"])", - Args: []ir.FilterExpr{ - { - Line: 651, - Op: ir.FilterGoVersionGreaterEqThanOp, - Src: "m.GoVersion().GreaterEqThan(\"1.17\")", - Value: "1.17", - }, - { - Line: 651, - Op: ir.FilterOrOp, - Src: "isTime(m[\"t\"])", - Args: []ir.FilterExpr{ - { - Line: 651, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"t\"].Type.Is(`time.Time`)", - Value: "t", - Args: []ir.FilterExpr{{Line: 647, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}}, - }, - { - Line: 651, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"t\"].Type.Is(`*time.Time`)", - Value: "t", - Args: []ir.FilterExpr{{Line: 647, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, - }, - }, - }, - }, - }, - }, - { - Line: 655, - SyntaxPatterns: []ir.PatternString{{Line: 655, Value: "$t.UnixNano() * 1000"}}, - ReportTemplate: "use $t.UnixMicro() instead of $$", - SuggestTemplate: "$t.UnixMicro()", - 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: 647, 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: 647, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, - }, - }, - }, - }, - }, - }, - }, - }, - { - Line: 665, - 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: 670, - SyntaxPatterns: []ir.PatternString{{Line: 670, Value: "type $x struct { $*_; sync.Mutex; $*_ }"}}, - ReportTemplate: "don't embed sync.Mutex", - WhereExpr: ir.FilterExpr{ - Line: 671, - Op: ir.FilterVarTextMatchesOp, - Src: "isExported(m[\"x\"])", - Value: "x", - Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, - }, - }, - { - Line: 674, - SyntaxPatterns: []ir.PatternString{{Line: 674, Value: "type $x struct { $*_; *sync.Mutex; $*_ }"}}, - ReportTemplate: "don't embed *sync.Mutex", - WhereExpr: ir.FilterExpr{ - Line: 675, - Op: ir.FilterVarTextMatchesOp, - Src: "isExported(m[\"x\"])", - Value: "x", - Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, - }, - }, - { - Line: 678, - SyntaxPatterns: []ir.PatternString{{Line: 678, Value: "type $x struct { $*_; sync.RWMutex; $*_ }"}}, - ReportTemplate: "don't embed sync.RWMutex", - WhereExpr: ir.FilterExpr{ - Line: 679, - Op: ir.FilterVarTextMatchesOp, - Src: "isExported(m[\"x\"])", - Value: "x", - Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, - }, - }, - { - Line: 682, - SyntaxPatterns: []ir.PatternString{{Line: 682, Value: "type $x struct { $*_; *sync.RWMutex; $*_ }"}}, - ReportTemplate: "don't embed *sync.RWMutex", - WhereExpr: ir.FilterExpr{ - Line: 683, - Op: ir.FilterVarTextMatchesOp, - Src: "isExported(m[\"x\"])", - Value: "x", - Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, - }, - }, - }, - }, - { - Line: 691, - 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: 692, - SyntaxPatterns: []ir.PatternString{{Line: 692, Value: "$x = sort.IntSlice($x)"}}, - ReportTemplate: "suspicious sort.IntSlice usage, maybe sort.Ints was intended?", - SuggestTemplate: "sort.Ints($x)", - WhereExpr: ir.FilterExpr{ - Line: 693, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`[]int`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 693, Op: ir.FilterStringOp, Src: "`[]int`", Value: "[]int"}}, - }, - }, - { - Line: 697, - SyntaxPatterns: []ir.PatternString{{Line: 697, Value: "$x = sort.Float64Slice($x)"}}, - ReportTemplate: "suspicious sort.Float64s usage, maybe sort.Float64s was intended?", - SuggestTemplate: "sort.Float64s($x)", - WhereExpr: ir.FilterExpr{ - Line: 698, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`[]float64`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 698, Op: ir.FilterStringOp, Src: "`[]float64`", Value: "[]float64"}}, - }, - }, - { - Line: 702, - SyntaxPatterns: []ir.PatternString{{Line: 702, Value: "$x = sort.StringSlice($x)"}}, - ReportTemplate: "suspicious sort.StringSlice usage, maybe sort.Strings was intended?", - SuggestTemplate: "sort.Strings($x)", - WhereExpr: ir.FilterExpr{ - Line: 703, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`[]string`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 703, Op: ir.FilterStringOp, Src: "`[]string`", Value: "[]string"}}, - }, - }, - }, - }, - { - Line: 712, - 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: 713, - SyntaxPatterns: []ir.PatternString{{Line: 713, Value: "$pkg.$err = $x"}}, - ReportTemplate: "suspicious reassignment of error from another package", - WhereExpr: ir.FilterExpr{ - Line: 714, - Op: ir.FilterAndOp, - Src: "m[\"err\"].Type.Is(`error`) && m[\"pkg\"].Object.Is(`PkgName`)", - Args: []ir.FilterExpr{ - { - Line: 714, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"err\"].Type.Is(`error`)", - Value: "err", - Args: []ir.FilterExpr{{Line: 714, Op: ir.FilterStringOp, Src: "`error`", Value: "error"}}, - }, - { - Line: 714, - Op: ir.FilterVarObjectIsOp, - Src: "m[\"pkg\"].Object.Is(`PkgName`)", - Value: "pkg", - Args: []ir.FilterExpr{{Line: 714, Op: ir.FilterStringOp, Src: "`PkgName`", Value: "PkgName"}}, - }, - }, - }, - }}, - }, - { - Line: 722, - Name: "emptyDecl", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects suspicious empty declarations blocks", - DocBefore: "var()", - DocAfter: "/* nothing */", - Rules: []ir.Rule{ - { - Line: 723, - SyntaxPatterns: []ir.PatternString{{Line: 723, Value: "var()"}}, - ReportTemplate: "empty var() block", - }, - { - Line: 724, - SyntaxPatterns: []ir.PatternString{{Line: 724, Value: "const()"}}, - ReportTemplate: "empty const() block", - }, - { - Line: 725, - SyntaxPatterns: []ir.PatternString{{Line: 725, Value: "type()"}}, - ReportTemplate: "empty type() block", - }, - }, - }, - { - Line: 732, - Name: "dynamicFmtString", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects suspicious formatting strings usage", - DocBefore: "fmt.Errorf(msg)", - DocAfter: "fmt.Errorf(\"%s\", msg)", - Rules: []ir.Rule{ - { - Line: 733, - SyntaxPatterns: []ir.PatternString{{Line: 733, Value: "fmt.Errorf($f)"}}, - ReportTemplate: "use errors.New($f) or fmt.Errorf(\"%s\", $f) instead", - SuggestTemplate: "errors.New($f)", - WhereExpr: ir.FilterExpr{ - Line: 734, - Op: ir.FilterNotOp, - Src: "!m[\"f\"].Const", - Args: []ir.FilterExpr{{ - Line: 734, - Op: ir.FilterVarConstOp, - Src: "m[\"f\"].Const", - Value: "f", - }}, - }, - }, - { - Line: 738, - SyntaxPatterns: []ir.PatternString{{Line: 738, Value: "fmt.Errorf($f($*args))"}}, - ReportTemplate: "use errors.New($f($*args)) or fmt.Errorf(\"%s\", $f($*args)) instead", - SuggestTemplate: "errors.New($f($*args))", - }, - }, - }, - { - Line: 747, - 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: 748, - SyntaxPatterns: []ir.PatternString{{Line: 748, Value: "strings.Compare($s1, $s2) == 0"}}, - ReportTemplate: "suggestion: $s1 == $s2", - SuggestTemplate: "$s1 == $s2", - }, - { - Line: 751, - SyntaxPatterns: []ir.PatternString{ - {Line: 751, Value: "strings.Compare($s1, $s2) == -1"}, - {Line: 752, Value: "strings.Compare($s1, $s2) < 0"}, - }, - ReportTemplate: "suggestion: $s1 < $s2", - SuggestTemplate: "$s1 < $s2", - }, - { - Line: 755, - SyntaxPatterns: []ir.PatternString{ - {Line: 755, Value: "strings.Compare($s1, $s2) == 1"}, - {Line: 756, Value: "strings.Compare($s1, $s2) > 0"}, - }, - ReportTemplate: "suggestion: $s1 > $s2", - SuggestTemplate: "$s1 > $s2", - }, - }, - }, - { - Line: 764, - 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: 765, - SyntaxPatterns: []ir.PatternString{ - {Line: 766, Value: "if $err := $_($*_); $err2 != nil { $*_ }"}, - {Line: 767, Value: "if $err = $_($*_); $err2 != nil { $*_ }"}, - {Line: 768, Value: "if $*_, $err := $_($*_); $err2 != nil { $*_ }"}, - {Line: 769, Value: "if $*_, $err = $_($*_); $err2 != nil { $*_ }"}, - }, - ReportTemplate: "$err error is unchecked, maybe intended to check it instead of $err2", - WhereExpr: ir.FilterExpr{ - Line: 770, - 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: 770, - Op: ir.FilterAndOp, - Src: "m[\"err\"].Type.Implements(\"error\") && m[\"err2\"].Type.Implements(\"error\")", - Args: []ir.FilterExpr{ - { - Line: 770, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"err\"].Type.Implements(\"error\")", - Value: "err", - Args: []ir.FilterExpr{{Line: 770, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}}, - }, - { - Line: 770, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"err2\"].Type.Implements(\"error\")", - Value: "err2", - Args: []ir.FilterExpr{{Line: 770, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}}, - }, - }, - }, - { - Line: 771, - Op: ir.FilterNeqOp, - Src: "m[\"err\"].Text != m[\"err2\"].Text", - Args: []ir.FilterExpr{ - {Line: 771, Op: ir.FilterVarTextOp, Src: "m[\"err\"].Text", Value: "err"}, - {Line: 771, Op: ir.FilterVarTextOp, Src: "m[\"err2\"].Text", Value: "err2"}, - }, - }, - }, - }, - LocationVar: "err", - }}, - }, - { - Line: 780, - 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: 781, - SyntaxPatterns: []ir.PatternString{{Line: 781, Value: "$*_; sync.OnceFunc($x); $*_;"}}, - ReportTemplate: "possible sync.OnceFunc misuse, sync.OnceFunc($x) result is not used", - WhereExpr: ir.FilterExpr{ - Line: 783, - Op: ir.FilterGoVersionGreaterEqThanOp, - Src: "m.GoVersion().GreaterEqThan(\"1.21\")", - Value: "1.21", - }, - }, - { - Line: 785, - SyntaxPatterns: []ir.PatternString{{Line: 785, Value: "sync.OnceFunc($x)()"}}, - ReportTemplate: "possible sync.OnceFunc misuse, consider to assign sync.OnceFunc($x) to a variable", - WhereExpr: ir.FilterExpr{ - Line: 787, - Op: ir.FilterGoVersionGreaterEqThanOp, - Src: "m.GoVersion().GreaterEqThan(\"1.21\")", - Value: "1.21", - }, - }, - }, - }, - }, -} - 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 a1a399fda..000000000 --- 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 d83d7fd5a..000000000 --- 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 454ab78b1..000000000 --- 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 22ef3b16a..000000000 --- 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 8a132b586..000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go +++ /dev/null @@ -1,168 +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.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 f8e4b9b3c..000000000 --- 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 57411ba24..000000000 --- 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 b36902526..000000000 --- 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 e0d20fd4c..000000000 --- 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 11381c401..000000000 --- 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 4b27b1792..000000000 --- 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 e2e225ebf..000000000 --- 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 0ce2c89ba..000000000 --- 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 d0e83f3c2..000000000 --- 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 0401bf5d3..000000000 --- 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 0d40addf7..000000000 --- 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 b577ff421..000000000 --- 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 4c1ed41f6..000000000 --- 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 6e12cf9b3..000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/utils.go +++ /dev/null @@ -1,311 +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. -// 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, - "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/ecdsa": true, - "crypto/elliptic": true, - "crypto/hmac": true, - "crypto/internal/randutil": true, - "crypto/internal/subtle": 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/dwarf": true, - "debug/elf": true, - "debug/gosym": true, - "debug/macho": true, - "debug/pe": true, - "debug/plan9obj": 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/constant": true, - "go/doc": true, - "go/format": true, - "go/importer": true, - "go/internal/gccgoimporter": true, - "go/internal/gcimporter": true, - "go/internal/srcimporter": true, - "go/parser": true, - "go/printer": true, - "go/scanner": true, - "go/token": true, - "go/types": true, - "hash": true, - "hash/adler32": true, - "hash/crc32": true, - "hash/crc64": true, - "hash/fnv": true, - "html": true, - "html/template": true, - "image": true, - "image/color": true, - "image/color/palette": true, - "image/draw": true, - "image/gif": true, - "image/internal/imageutil": true, - "image/jpeg": true, - "image/png": true, - "index/suffixarray": true, - "internal/bytealg": true, - "internal/cpu": true, - "internal/nettrace": true, - "internal/poll": true, - "internal/race": true, - "internal/singleflight": true, - "internal/syscall/unix": true, - "internal/syscall/windows": true, - "internal/syscall/windows/registry": true, - "internal/syscall/windows/sysdll": true, - "internal/testenv": true, - "internal/testlog": true, - "internal/trace": true, - "io": true, - "io/ioutil": true, - "log": true, - "log/syslog": true, - "math": true, - "math/big": true, - "math/bits": true, - "math/cmplx": true, - "math/rand": 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/internal": true, - "net/http/pprof": true, - "net/internal/socktest": true, - "net/mail": 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/signal/internal/pty": true, - "os/user": true, - "path": true, - "path/filepath": true, - "plugin": true, - "reflect": true, - "regexp": true, - "regexp/syntax": true, - "runtime": true, - "runtime/cgo": true, - "runtime/debug": true, - "runtime/internal/atomic": true, - "runtime/internal/sys": true, - "runtime/pprof": true, - "runtime/pprof/internal/profile": true, - "runtime/race": true, - "runtime/trace": true, - "sort": true, - "strconv": true, - "strings": true, - "sync": true, - "sync/atomic": true, - "syscall": true, - "testing": true, - "testing/internal/testdeps": true, - "testing/iotest": true, - "testing/quick": true, - "text/scanner": true, - "text/tabwriter": true, - "text/template": true, - "text/template/parse": true, - "time": true, - "unicode": true, - "unicode/utf16": true, - "unicode/utf8": true, - "unsafe": true, -} - -var goBuiltins = map[string]bool{ - // Types - "bool": true, - "byte": 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, - "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 3d7c9c122..000000000 --- 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 eaa53e5d5..000000000 --- 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 b5ef2f75f..000000000 --- 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 0a3fc0292..000000000 --- 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(info *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 d4bc17536..000000000 --- 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 gocritic does) behave -// like all features are available. To make gocritic -// 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-kivik/couchdb/v3/.gitignore b/vendor/github.com/go-kivik/couchdb/v3/.gitignore deleted file mode 100644 index a3204f676..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -Gopkg.lock -vendor/ -*~ diff --git a/vendor/github.com/go-kivik/couchdb/v3/.gitlab-ci.yml b/vendor/github.com/go-kivik/couchdb/v3/.gitlab-ci.yml deleted file mode 100644 index 204bb4b66..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/.gitlab-ci.yml +++ /dev/null @@ -1,87 +0,0 @@ -stages: - - test - -variables: - SRCDIR: /go/src/github.com/go-kivik/couchdb - GO111MODULE: "on" - -.test: &test_template - stage: test - services: - - name: couchdb:1.7.2 - alias: couch17 - - name: couchdb:2.2.0 - alias: couch22 - - name: apache/couchdb:2.3.1 - alias: couch23 - - name: apache/couchdb:3.0.0 - alias: couch30 - variables: - COUCHDB_USER: admin - COUCHDB_PASSWORD: abc123 - KIVIK_TEST_DSN_COUCH17: http://admin:abc123@couch17:5984/ - KIVIK_TEST_DSN_COUCH22: http://admin:abc123@couch22:5984/ - KIVIK_TEST_DSN_COUCH23: http://admin:abc123@couch23:5984/ - KIVIK_TEST_DSN_COUCH30: http://admin:abc123@couch30:5984/ - before_script: - - ./script/complete_couch1.sh ${KIVIK_TEST_DSN_COUCH17} - - ./script/complete_couch2.sh ${KIVIK_TEST_DSN_COUCH22} - - ./script/complete_couch2.sh ${KIVIK_TEST_DSN_COUCH23} - - ./script/complete_couch2.sh ${KIVIK_TEST_DSN_COUCH30} - script: - - go mod download - - ./script/test_version.sh - - go test -race -tags=livetest ./... - -.nomod: &nomod_template - <<: *test_template - script: - - mkdir -p /go/src - - ln -s /builds /go/src/github.com - - cd ${SRCDIR} - - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh - - dep ensure && dep status - - ./script/test_version.sh - - go test -race -tags=livetest ./... - -linter: - stage: test - image: golangci/golangci-lint:v1.28 - script: - - go mod download - - golangci-lint run ./... - -coverage: - stage: test - image: golang:1.15 - services: [] - before_script: - - '' - script: - - go mod download - - ./script/coverage.sh - -go-1.11: - <<: *test_template - image: golang:1.11 - -go-1.12: - <<: *test_template - image: golang:1.12 - -go-1.13: - <<: *test_template - image: golang:1.13 - -go-1.14: - <<: *test_template - image: golang:1.14 - -go-1.15: - <<: *test_template - image: golang:1.15 - -go-rc: - <<: *test_template - image: golang:rc - allow_failure: true diff --git a/vendor/github.com/go-kivik/couchdb/v3/.golangci.toml b/vendor/github.com/go-kivik/couchdb/v3/.golangci.toml deleted file mode 100644 index 2949d722a..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/.golangci.toml +++ /dev/null @@ -1,9 +0,0 @@ -[output] -format = "colored-line-number" - -[linters] -enable = [ - "interfacer", "gocyclo", "unconvert", "goimports", "unused", "varcheck", - "vetshadow", "misspell", "nakedret", "errcheck", "golint", "ineffassign", - "deadcode", "goconst", "vet", "unparam", "gofmt" -] diff --git a/vendor/github.com/go-kivik/couchdb/v3/LICENSE.md b/vendor/github.com/go-kivik/couchdb/v3/LICENSE.md deleted file mode 100644 index 0a2865e54..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/LICENSE.md +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (c) 2017 Jonathan Hall - -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/go-kivik/couchdb/v3/README.md b/vendor/github.com/go-kivik/couchdb/v3/README.md deleted file mode 100644 index 970c7ba5e..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/README.md +++ /dev/null @@ -1,35 +0,0 @@ -[![Build Status](https://travis-ci.org/go-kivik/couchdb.svg?branch=master)](https://travis-ci.org/go-kivik/couchdb) [![Codecov](https://img.shields.io/codecov/c/github/go-kivik/couchdb.svg?style=flat)](https://codecov.io/gh/go-kivik/couchdb) [![GoDoc](https://godoc.org/github.com/go-kivik/couchdb?status.svg)](http://godoc.org/github.com/go-kivik/couchdb) - -# Kivik CouchDB - -CouchDB driver for [Kivik](https://github.com/go-kivik/kivik). - -## Usage - -This package provides an implementation of the -[`github.com/go-kivik/kivik/v3/driver`](http://godoc.org/github.com/go-kivik/kivik/driver) -interface. You must import the driver and can then use the full -[`Kivik`](http://godoc.org/github.com/go-kivik/kivik) API. Please consult the -[Kivik wiki](https://github.com/go-kivik/kivik/wiki) for complete documentation -and coding examples. - -```go -package main - -import ( - "context" - - kivik "github.com/go-kivik/kivik/v3" - _ "github.com/go-kivik/couchdb/v3" // The CouchDB driver -) - -func main() { - client, err := kivik.New(context.TODO(), "couch", "") - // ... -} -``` - -## License - -This software is released under the terms of the Apache 2.0 license. See -LICENCE.md, or read the [full license](http://www.apache.org/licenses/LICENSE-2.0). diff --git a/vendor/github.com/go-kivik/couchdb/v3/attachments.go b/vendor/github.com/go-kivik/couchdb/v3/attachments.go deleted file mode 100644 index 145f84e96..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/attachments.go +++ /dev/null @@ -1,171 +0,0 @@ -package couchdb - -import ( - "context" - "errors" - "net/http" - - "github.com/go-kivik/couchdb/v3/chttp" - kivik "github.com/go-kivik/kivik/v3" - "github.com/go-kivik/kivik/v3/driver" -) - -func (d *db) PutAttachment(ctx context.Context, docID, rev string, att *driver.Attachment, options map[string]interface{}) (newRev string, err error) { - if docID == "" { - return "", missingArg("docID") - } - if att == nil { - return "", missingArg("att") - } - if att.Filename == "" { - return "", missingArg("att.Filename") - } - if att.Content == nil { - return "", missingArg("att.Content") - } - - fullCommit, err := fullCommit(options) - if err != nil { - return "", err - } - - query, err := optionsToParams(options) - if err != nil { - return "", err - } - if rev != "" { - query.Set("rev", rev) - } - var response struct { - Rev string `json:"rev"` - } - opts := &chttp.Options{ - Body: att.Content, - ContentType: att.ContentType, - FullCommit: fullCommit, - Query: query, - } - _, err = d.Client.DoJSON(ctx, http.MethodPut, d.path(chttp.EncodeDocID(docID)+"/"+att.Filename), opts, &response) - if err != nil { - return "", err - } - return response.Rev, nil -} - -func (d *db) GetAttachmentMeta(ctx context.Context, docID, filename string, options map[string]interface{}) (*driver.Attachment, error) { - resp, err := d.fetchAttachment(ctx, http.MethodHead, docID, filename, options) - if err != nil { - return nil, err - } - att, err := decodeAttachment(resp) - return att, err -} - -func (d *db) GetAttachment(ctx context.Context, docID, filename string, options map[string]interface{}) (*driver.Attachment, error) { - resp, err := d.fetchAttachment(ctx, http.MethodGet, docID, filename, options) - if err != nil { - return nil, err - } - return decodeAttachment(resp) -} - -func (d *db) fetchAttachment(ctx context.Context, method, docID, filename string, options map[string]interface{}) (*http.Response, error) { - if method == "" { - return nil, errors.New("method required") - } - if docID == "" { - return nil, missingArg("docID") - } - if filename == "" { - return nil, missingArg("filename") - } - - inm, err := ifNoneMatch(options) - if err != nil { - return nil, err - } - - query, err := optionsToParams(options) - if err != nil { - return nil, err - } - opts := &chttp.Options{ - IfNoneMatch: inm, - Query: query, - } - resp, err := d.Client.DoReq(ctx, method, d.path(chttp.EncodeDocID(docID)+"/"+filename), opts) - if err != nil { - return nil, err - } - return resp, chttp.ResponseError(resp) -} - -func decodeAttachment(resp *http.Response) (*driver.Attachment, error) { - cType, err := getContentType(resp) - if err != nil { - return nil, err - } - digest, err := getDigest(resp) - if err != nil { - return nil, err - } - - return &driver.Attachment{ - ContentType: cType, - Digest: digest, - Size: resp.ContentLength, - Content: resp.Body, - }, nil -} - -func getContentType(resp *http.Response) (string, error) { - ctype := resp.Header.Get("Content-Type") - if _, ok := resp.Header["Content-Type"]; !ok { - return "", &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: errors.New("no Content-Type in response")} - } - return ctype, nil -} - -func getDigest(resp *http.Response) (string, error) { - etag, ok := chttp.ETag(resp) - if !ok { - return "", &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: errors.New("ETag header not found")} - } - return etag, nil -} - -func (d *db) DeleteAttachment(ctx context.Context, docID, rev, filename string, options map[string]interface{}) (newRev string, err error) { - if docID == "" { - return "", missingArg("docID") - } - if rev == "" { - return "", missingArg("rev") - } - if filename == "" { - return "", missingArg("filename") - } - - fullCommit, err := fullCommit(options) - if err != nil { - return "", err - } - - query, err := optionsToParams(options) - if err != nil { - return "", err - } - query.Set("rev", rev) - var response struct { - Rev string `json:"rev"` - } - - opts := &chttp.Options{ - FullCommit: fullCommit, - Query: query, - } - _, err = d.Client.DoJSON(ctx, http.MethodDelete, d.path(chttp.EncodeDocID(docID)+"/"+filename), opts, &response) - if err != nil { - return "", err - } - return response.Rev, nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/auth.go b/vendor/github.com/go-kivik/couchdb/v3/auth.go deleted file mode 100644 index ada9fe631..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/auth.go +++ /dev/null @@ -1,140 +0,0 @@ -package couchdb - -import ( - "context" - "errors" - "net/http" - - "github.com/go-kivik/couchdb/v3/chttp" - kivik "github.com/go-kivik/kivik/v3" -) - -func (c *client) Authenticate(ctx context.Context, a interface{}) error { - if auth, ok := a.(chttp.Authenticator); ok { - return auth.Authenticate(c.Client) - } - if auth, ok := a.(Authenticator); ok { - return auth.auth(ctx, c) - } - return &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: errors.New("kivik: invalid authenticator")} -} - -// Authenticator is a CouchDB authenticator. Direct use of the Authenticator -// interface is for advanced usage. Typically, it is sufficient to provide -// a username and password in the connecting DSN to perform authentication. -// Only use one of these provided authenticators if you have specific, special -// needs. -type Authenticator interface { - auth(context.Context, *client) error -} - -type xportAuth struct { - http.RoundTripper -} - -var _ Authenticator = &xportAuth{} - -func (a *xportAuth) auth(_ context.Context, c *client) error { - if c.Client.Client.Transport != nil { - return &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: errors.New("kivik: HTTP client transport already set")} - } - c.Client.Client.Transport = a.RoundTripper - return nil -} - -// SetTransport returns an authenticator that can be used to set a client -// connection's HTTP Transport. This can be used to control proxies, TLS -// configuration, keep-alives, compression, etc. -// -// Example: -// -// setXport := couchdb.SetTransport(&http.Transport{ -// // .. custom config -// }) -// client, _ := kivik.New( ... ) -// client.Authenticate(setXport) -func SetTransport(t http.RoundTripper) Authenticator { - return &xportAuth{t} -} - -type authFunc func(context.Context, *client) error - -func (a authFunc) auth(ctx context.Context, c *client) error { - return a(ctx, c) -} - -// BasicAuth provides support for HTTP Basic authentication. -func BasicAuth(user, password string) Authenticator { - auth := chttp.BasicAuth{Username: user, Password: password} - return authFunc(func(ctx context.Context, c *client) error { - return auth.Authenticate(c.Client) - }) -} - -// CookieAuth provides support for CouchDB cookie-based authentication. -func CookieAuth(user, password string) Authenticator { - auth := chttp.CookieAuth{Username: user, Password: password} - return authFunc(func(ctx context.Context, c *client) error { - return auth.Authenticate(c.Client) - }) -} - -// ProxyAuth provides support for Proxy authentication. -// -// The `secret` argument represents the `couch_httpd_auth/secret` value -// configured on the CouchDB server. See https://docs.couchdb.org/en/stable/config/auth.html#couch_httpd_auth/secret -// If `secret` is the empty string, the X-Auth-CouchDB-Token header will not be -// set, to support disabling the `proxy_use_secret` server setting. See https://docs.couchdb.org/en/stable/config/auth.html#couch_httpd_auth/proxy_use_secret -// -// The optional `headers` map may be passed to use non-standard header names. -// For instance, to use `X-User` in place of the `X-Auth-CouchDB-Username` -// header, pass a value of {"X-Auth-CouchDB-UserName": "X-User"}. -// The relevant headers are X-Auth-CouchDB-UserName, X-Auth-CouchDB-Roles, and -// X-Auth-CouchDB-Token. -// -// See https://docs.couchdb.org/en/stable/api/server/authn.html?highlight=proxy%20auth#proxy-authentication -func ProxyAuth(user, secret string, roles []string, headers ...map[string]string) Authenticator { - headerOverrides := http.Header{} - for _, h := range headers { - for k, v := range h { - headerOverrides.Set(k, v) - } - } - auth := chttp.ProxyAuth{Username: user, Secret: secret, Roles: roles, Headers: headerOverrides} - return authFunc(func(ctx context.Context, c *client) error { - return auth.Authenticate(c.Client) - }) -} - -type rawCookie struct { - cookie *http.Cookie - next http.RoundTripper -} - -var ( - _ Authenticator = &rawCookie{} - _ http.RoundTripper = &rawCookie{} -) - -func (a *rawCookie) auth(_ context.Context, c *client) error { - if c.Client.Client.Transport != nil { - return &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: errors.New("kivik: HTTP client transport already set")} - } - a.next = c.Client.Client.Transport - if a.next == nil { - a.next = http.DefaultTransport - } - c.Client.Client.Transport = a - return nil -} - -func (a *rawCookie) RoundTrip(r *http.Request) (*http.Response, error) { - r.AddCookie(a.cookie) - return a.next.RoundTrip(r) -} - -// SetCookie adds cookie to all outbound requests. This is useful when using -// kivik as a proxy. -func SetCookie(cookie *http.Cookie) Authenticator { - return &rawCookie{cookie: cookie} -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/bulk.go b/vendor/github.com/go-kivik/couchdb/v3/bulk.go deleted file mode 100644 index 8081cd116..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/bulk.go +++ /dev/null @@ -1,106 +0,0 @@ -package couchdb - -import ( - "context" - "encoding/json" - "errors" - "io" - "net/http" - - "github.com/go-kivik/couchdb/v3/chttp" - kivik "github.com/go-kivik/kivik/v3" - "github.com/go-kivik/kivik/v3/driver" -) - -type bulkResults struct { - body io.ReadCloser - dec *json.Decoder -} - -var _ driver.BulkResults = &bulkResults{} - -func newBulkResults(body io.ReadCloser) (*bulkResults, error) { - dec := json.NewDecoder(body) - // Consume the opening '[' char - if err := consumeDelim(dec, json.Delim('[')); err != nil { - return nil, err - } - return &bulkResults{ - body: body, - dec: dec, - }, nil -} - -func (r *bulkResults) Next(update *driver.BulkResult) error { - if !r.dec.More() { - if err := consumeDelim(r.dec, json.Delim(']')); err != nil { - return err - } - return io.EOF - } - var updateResult struct { - ID string `json:"id"` - Rev string `json:"rev"` - Error string `json:"error"` - Reason string `json:"reason"` - } - if err := r.dec.Decode(&updateResult); err != nil { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - update.ID = updateResult.ID - update.Rev = updateResult.Rev - update.Error = nil - if updateResult.Error != "" { - var status int - switch updateResult.Error { - case "conflict": - status = http.StatusConflict - default: - status = http.StatusInternalServerError - } - update.Error = &kivik.Error{HTTPStatus: status, FromServer: true, Err: errors.New(updateResult.Reason)} - } - return nil -} - -func (r *bulkResults) Close() error { - return r.body.Close() -} - -func (d *db) BulkDocs(ctx context.Context, docs []interface{}, options map[string]interface{}) (driver.BulkResults, error) { - if options == nil { - options = make(map[string]interface{}) - } - fullCommit, err := fullCommit(options) - if err != nil { - return nil, err - } - options["docs"] = docs - opts := &chttp.Options{ - GetBody: chttp.BodyEncoder(options), - FullCommit: fullCommit, - } - resp, err := d.Client.DoReq(ctx, http.MethodPost, d.path("_bulk_docs"), opts) - if err != nil { - return nil, err - } - switch resp.StatusCode { - case http.StatusCreated: - // Nothing to do - case http.StatusExpectationFailed: - err = &chttp.HTTPError{ - Response: resp, - Reason: "one or more document was rejected", - } - default: - // All other errors can consume the response body and return immediately - if e := chttp.ResponseError(resp); e != nil { - return nil, e - } - } - results, bulkErr := newBulkResults(resp.Body) - if bulkErr != nil { - return nil, bulkErr - } - return results, err -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/bulkget.go b/vendor/github.com/go-kivik/couchdb/v3/bulkget.go deleted file mode 100644 index 5c9fb8c45..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/bulkget.go +++ /dev/null @@ -1,61 +0,0 @@ -package couchdb - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - - "github.com/go-kivik/couchdb/v3/chttp" - "github.com/go-kivik/kivik/v3/driver" -) - -func (d *db) BulkGet(ctx context.Context, docs []driver.BulkGetReference, opts map[string]interface{}) (driver.Rows, error) { - query, err := optionsToParams(opts) - if err != nil { - return nil, err - } - body := map[string]interface{}{ - "docs": docs, - } - options := &chttp.Options{ - Query: query, - GetBody: chttp.BodyEncoder(body), - Header: http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - }, - } - resp, err := d.Client.DoReq(ctx, http.MethodPost, d.path("_bulk_get"), options) - if err != nil { - return nil, err - } - if err = chttp.ResponseError(resp); err != nil { - return nil, err - } - return newBulkGetRows(ctx, resp.Body), nil -} - -// BulkGetError represents an error for a single document returned by a -// GetBulk call. -type BulkGetError struct { - ID string `json:"id"` - Rev string `json:"rev"` - Err string `json:"error"` - Reason string `json:"reason"` -} - -var _ error = &BulkGetError{} - -func (e *BulkGetError) Error() string { - return fmt.Sprintf("%s: %s", e.Err, e.Reason) -} - -type bulkResultDoc struct { - Doc json.RawMessage `json:"ok,omitempty"` - Error *BulkGetError `json:"error,omitempty"` -} - -type bulkResult struct { - ID string `json:"id"` - Docs []bulkResultDoc `json:"docs"` -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/changes.go b/vendor/github.com/go-kivik/couchdb/v3/changes.go deleted file mode 100644 index 8b6c0c99a..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/changes.go +++ /dev/null @@ -1,120 +0,0 @@ -package couchdb - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "io" - "net/http" - - "github.com/go-kivik/couchdb/v3/chttp" - kivik "github.com/go-kivik/kivik/v3" - "github.com/go-kivik/kivik/v3/driver" -) - -// Changes returns the changes stream for the database. -func (d *db) Changes(ctx context.Context, opts map[string]interface{}) (driver.Changes, error) { - key := "results" - if f, ok := opts["feed"]; ok { - if f == "eventsource" { - return nil, &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: errors.New("kivik: eventsource feed not supported, use 'continuous'")} - } - if f == "continuous" { - key = "" - } - } - query, err := optionsToParams(opts) - if err != nil { - return nil, err - } - options := &chttp.Options{ - Query: query, - } - resp, err := d.Client.DoReq(ctx, http.MethodGet, d.path("_changes"), options) - if err != nil { - return nil, err - } - if err = chttp.ResponseError(resp); err != nil { - return nil, err - } - etag, _ := chttp.ETag(resp) - return newChangesRows(ctx, key, resp.Body, etag), nil -} - -type continuousChangesParser struct{} - -func (p *continuousChangesParser) parseMeta(i interface{}, dec *json.Decoder, key string) error { - meta := i.(*changesMeta) - return meta.parseMeta(key, dec) -} - -func (p *continuousChangesParser) decodeItem(i interface{}, dec *json.Decoder) error { - row := i.(*driver.Change) - ch := &change{Change: row} - if err := dec.Decode(ch); err != nil { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - ch.Change.Seq = string(ch.Seq) - return nil -} - -type changesMeta struct { - lastSeq sequenceID - pending int64 -} - -// parseMeta parses result metadata -func (m *changesMeta) parseMeta(key string, dec *json.Decoder) error { - switch key { - case "last_seq": - return dec.Decode(&m.lastSeq) - case "pending": - return dec.Decode(&m.pending) - } - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: fmt.Errorf("Unexpected key: %s", key)} -} - -type changesRows struct { - *iter - *changesMeta - etag string -} - -func newChangesRows(ctx context.Context, key string, r io.ReadCloser, etag string) *changesRows { - var meta *changesMeta - if key != "" { - meta = &changesMeta{} - } - return &changesRows{ - iter: newIter(ctx, meta, key, r, &continuousChangesParser{}), - etag: etag, - } -} - -var _ driver.Changes = &changesRows{} - -type change struct { - *driver.Change - Seq sequenceID `json:"seq"` -} - -func (r *changesRows) Next(row *driver.Change) error { - row.Deleted = false - return r.iter.next(row) -} - -// LastSeq returns the last sequence ID. -func (r *changesRows) LastSeq() string { - return string(r.lastSeq) -} - -// Pending returns the pending count. -func (r *changesRows) Pending() int64 { - return r.pending -} - -// ETag returns the unquoted ETag header for the CouchDB response, if any. -func (r *changesRows) ETag() string { - return r.etag -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/auth.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/auth.go deleted file mode 100644 index d69c5a82f..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/auth.go +++ /dev/null @@ -1,22 +0,0 @@ -package chttp - -import ( - "net/http/cookiejar" - - "golang.org/x/net/publicsuffix" -) - -// Authenticator is an interface that provides authentication to a server. -type Authenticator interface { - Authenticate(*Client) error -} - -func (a *CookieAuth) setCookieJar() { - // If a jar is already set, just use it - if a.client.Jar != nil { - return - } - // cookiejar.New never returns an error - jar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List}) - a.client.Jar = jar -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/basicauth.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/basicauth.go deleted file mode 100644 index ab58a7d84..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/basicauth.go +++ /dev/null @@ -1,34 +0,0 @@ -package chttp - -import ( - "net/http" -) - -// BasicAuth provides HTTP Basic Auth for a client. -type BasicAuth struct { - Username string - Password string - - // transport stores the original transport that is overridden by this auth - // mechanism - transport http.RoundTripper -} - -var _ Authenticator = &BasicAuth{} - -// RoundTrip fulfills the http.RoundTripper interface. It sets HTTP Basic Auth -// on outbound requests. -func (a *BasicAuth) RoundTrip(req *http.Request) (*http.Response, error) { - req.SetBasicAuth(a.Username, a.Password) - return a.transport.RoundTrip(req) -} - -// Authenticate sets HTTP Basic Auth headers for the client. -func (a *BasicAuth) Authenticate(c *Client) error { - a.transport = c.Transport - if a.transport == nil { - a.transport = http.DefaultTransport - } - c.Transport = a - return nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/chttp.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/chttp.go deleted file mode 100644 index 67610d5cd..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/chttp.go +++ /dev/null @@ -1,535 +0,0 @@ -// Package chttp provides a minimal HTTP driver backend for communicating with -// CouchDB servers. -package chttp - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "net" - "net/http" - "net/url" - "os" - "regexp" - "runtime" - "strings" - "sync" - "syscall" - - "github.com/go-kivik/kivik/v3" -) - -const typeJSON = "application/json" - -// The default UserAgent values -const ( - UserAgent = "Kivik chttp" - Version = "3.2.5" -) - -// Client represents a client connection. It embeds an *http.Client -type Client struct { - // UserAgents is appended to set the User-Agent header. Typically it should - // contain pairs of product name and version. - UserAgents []string - - *http.Client - - rawDSN string - dsn *url.URL - auth Authenticator - authMU sync.Mutex -} - -// New returns a connection to a remote CouchDB server. If credentials are -// included in the URL, requests will be authenticated using Cookie Auth. To -// use HTTP BasicAuth or some other authentication mechanism, do not specify -// credentials in the URL, and instead call the Auth() method later. -func New(dsn string) (*Client, error) { - return NewWithClient(&http.Client{}, dsn) -} - -// NewWithClient works the same as New(), but allows providing a custom -// *http.Client for all network connections. -func NewWithClient(client *http.Client, dsn string) (*Client, error) { - dsnURL, err := parseDSN(dsn) - if err != nil { - return nil, err - } - user := dsnURL.User - dsnURL.User = nil - c := &Client{ - Client: client, - dsn: dsnURL, - rawDSN: dsn, - } - if user != nil { - password, _ := user.Password() - err := c.Auth(&CookieAuth{ - Username: user.Username(), - Password: password, - }) - if err != nil { - return nil, err - } - } - return c, nil -} - -func parseDSN(dsn string) (*url.URL, error) { - if dsn == "" { - return nil, &curlError{ - httpStatus: http.StatusBadRequest, - curlStatus: ExitFailedToInitialize, - error: errors.New("no URL specified"), - } - } - if !strings.HasPrefix(dsn, "http://") && !strings.HasPrefix(dsn, "https://") { - dsn = "http://" + dsn - } - dsnURL, err := url.Parse(dsn) - if err != nil { - return nil, fullError(http.StatusBadRequest, ExitStatusURLMalformed, err) - } - if dsnURL.Path == "" { - dsnURL.Path = "/" - } - return dsnURL, nil -} - -// DSN returns the unparsed DSN used to connect. -func (c *Client) DSN() string { - return c.rawDSN -} - -// Auth authenticates using the provided Authenticator. -func (c *Client) Auth(a Authenticator) error { - if c.auth != nil { - return errors.New("auth already set") - } - if err := a.Authenticate(c); err != nil { - return err - } - c.auth = a - return nil -} - -// Options are optional parameters which may be sent with a request. -type Options struct { - // Accept sets the request's Accept header. Defaults to "application/json". - // To specify any, use "*/*". - Accept string - - // ContentType sets the requests's Content-Type header. Defaults to "application/json". - ContentType string - - // ContentLength, if set, sets the ContentLength of the request - ContentLength int64 - - // Body sets the body of the request. - Body io.ReadCloser - - // GetBody is a function to set the body, and can be used on retries. If - // set, Body is ignored. - GetBody func() (io.ReadCloser, error) - - // JSON is an arbitrary data type which is marshaled to the request's body. - // It an error to set both Body and JSON on the same request. When this is - // set, ContentType is unconditionally set to 'application/json'. Note that - // for large JSON payloads, it can be beneficial to do your own JSON stream - // encoding, so that the request can be live on the wire during JSON - // encoding. - JSON interface{} - - // FullCommit adds the X-Couch-Full-Commit: true header to requests - FullCommit bool - - // IfNoneMatch adds the If-None-Match header. The value will be quoted if - // it is not already. - IfNoneMatch string - - // Query is appended to the exiting url, if present. If the passed url - // already contains query parameters, the values in Query are appended. - // No merging takes place. - Query url.Values - - // Header is a list of default headers to be set on the request. - Header http.Header -} - -// Response represents a response from a CouchDB server. -type Response struct { - *http.Response - - // ContentType is the base content type, parsed from the response headers. - ContentType string -} - -// DecodeJSON unmarshals the response body into i. This method consumes and -// closes the response body. -func DecodeJSON(r *http.Response, i interface{}) error { - defer r.Body.Close() // nolint: errcheck - if err := json.NewDecoder(r.Body).Decode(i); err != nil { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - return nil -} - -// DoJSON combines DoReq() and, ResponseError(), and (*Response).DecodeJSON(), and -// closes the response body. -func (c *Client) DoJSON(ctx context.Context, method, path string, opts *Options, i interface{}) (*http.Response, error) { - res, err := c.DoReq(ctx, method, path, opts) - if err != nil { - return res, err - } - if err = ResponseError(res); err != nil { - return res, err - } - err = DecodeJSON(res, i) - return res, err -} - -// NewRequest returns a new *http.Request to the CouchDB server, and the -// specified path. The host, schema, etc, of the specified path are ignored. -func (c *Client) NewRequest(ctx context.Context, method, path string, body io.Reader) (*http.Request, error) { - fullPath := path - if cPath := strings.TrimSuffix(c.dsn.Path, "/"); cPath != "" { - fullPath = cPath + "/" + strings.TrimPrefix(path, "/") - } - reqPath, err := url.Parse(fullPath) - if err != nil { - return nil, fullError(http.StatusBadRequest, ExitStatusURLMalformed, err) - } - u := *c.dsn // Make a copy - u.Path = reqPath.Path - u.RawQuery = reqPath.RawQuery - req, err := http.NewRequest(method, u.String(), body) - if err != nil { - return nil, &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: err} - } - req.Header.Add("User-Agent", c.userAgent()) - return req.WithContext(ctx), nil -} - -// DoReq does an HTTP request. An error is returned only if there was an error -// processing the request. In particular, an error status code, such as 400 -// or 500, does _not_ cause an error to be returned. -func (c *Client) DoReq(ctx context.Context, method, path string, opts *Options) (*http.Response, error) { - if method == "" { - return nil, errors.New("chttp: method required") - } - var body io.Reader - if opts != nil { - if opts.GetBody != nil { - var err error - opts.Body, err = opts.GetBody() - if err != nil { - return nil, err - } - } - if opts.Body != nil { - body = opts.Body - defer opts.Body.Close() // nolint: errcheck - } - } - req, err := c.NewRequest(ctx, method, path, body) - if err != nil { - return nil, err - } - fixPath(req, path) - setHeaders(req, opts) - setQuery(req, opts) - if opts != nil { - req.GetBody = opts.GetBody - } - - trace := ContextClientTrace(ctx) - if trace != nil { - trace.httpRequest(req) - trace.httpRequestBody(req) - } - - response, err := c.Do(req) - if trace != nil { - trace.httpResponse(response) - trace.httpResponseBody(response) - } - return response, netError(err) -} - -func netError(err error) error { - if err == nil { - return nil - } - if urlErr, ok := err.(*url.Error); ok { - // If this error was generated by EncodeBody, it may have an emedded - // status code (!= 500), which we should honor. - status := kivik.StatusCode(urlErr.Err) - if status == http.StatusInternalServerError { - status = http.StatusBadGateway - } - return fullError(status, curlStatus(err), err) - } - if status := kivik.StatusCode(err); status != http.StatusInternalServerError { - return err - } - return fullError(http.StatusBadGateway, ExitUnknownFailure, err) -} - -var tooManyRecirectsRE = regexp.MustCompile(`stopped after \d+ redirect`) - -func curlStatus(err error) int { - if urlErr, ok := err.(*url.Error); ok { - // Timeout error - if urlErr.Timeout() { - return ExitOperationTimeout - } - // Host lookup failure - if opErr, ok := urlErr.Err.(*net.OpError); ok { - if _, ok := opErr.Err.(*net.DNSError); ok { - return ExitHostNotResolved - } - if scErr, ok := opErr.Err.(*os.SyscallError); ok { - if errno, ok := scErr.Err.(syscall.Errno); ok { - if errno == syscall.ECONNREFUSED { - return ExitFailedToConnect - } - } - } - } - - if tooManyRecirectsRE.MatchString(urlErr.Err.Error()) { - return ExitTooManyRedirects - } - } - return 0 -} - -// fixPath sets the request's URL.RawPath to work with escaped characters in -// paths. -func fixPath(req *http.Request, path string) { - // Remove any query parameters - parts := strings.SplitN(path, "?", 2) - req.URL.RawPath = "/" + strings.TrimPrefix(parts[0], "/") -} - -// BodyEncoder returns a function which returns the encoded body. It is meant -// to be used as a http.Request.GetBody value. -func BodyEncoder(i interface{}) func() (io.ReadCloser, error) { - return func() (io.ReadCloser, error) { - return EncodeBody(i), nil - } -} - -// EncodeBody JSON encodes i to an io.ReadCloser. If an encoding error -// occurs, it will be returned on the next read. -func EncodeBody(i interface{}) io.ReadCloser { - done := make(chan struct{}) - r, w := io.Pipe() - go func() { - defer close(done) - var err error - switch t := i.(type) { - case []byte: - _, err = w.Write(t) - case json.RawMessage: // Only needed for Go 1.7 - _, err = w.Write(t) - case string: - _, err = w.Write([]byte(t)) - default: - err = json.NewEncoder(w).Encode(i) - switch err.(type) { - case *json.MarshalerError, *json.UnsupportedTypeError, *json.UnsupportedValueError: - err = &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: err} - } - } - _ = w.CloseWithError(err) - }() - return &ebReader{ - ReadCloser: r, - done: done, - } -} - -type ebReader struct { - io.ReadCloser - done <-chan struct{} -} - -var _ io.ReadCloser = &ebReader{} - -func (r *ebReader) Close() error { - err := r.ReadCloser.Close() - <-r.done - return err -} - -func setHeaders(req *http.Request, opts *Options) { - accept := typeJSON - contentType := typeJSON - if opts != nil { - if opts.Accept != "" { - accept = opts.Accept - } - if opts.ContentType != "" { - contentType = opts.ContentType - } - if opts.FullCommit { - req.Header.Add("X-Couch-Full-Commit", "true") - } - if opts.IfNoneMatch != "" { - inm := "\"" + strings.Trim(opts.IfNoneMatch, "\"") + "\"" - req.Header.Set("If-None-Match", inm) - } - if opts.ContentLength != 0 { - req.ContentLength = opts.ContentLength - } - for k, v := range opts.Header { - if _, ok := req.Header[k]; !ok { - req.Header[k] = v - } - } - } - req.Header.Add("Accept", accept) - req.Header.Add("Content-Type", contentType) -} - -func setQuery(req *http.Request, opts *Options) { - if opts == nil || len(opts.Query) == 0 { - return - } - if req.URL.RawQuery == "" { - req.URL.RawQuery = opts.Query.Encode() - return - } - req.URL.RawQuery = strings.Join([]string{req.URL.RawQuery, opts.Query.Encode()}, "&") -} - -// DoError is the same as DoReq(), followed by checking the response error. This -// method is meant for cases where the only information you need from the -// response is the status code. It unconditionally closes the response body. -func (c *Client) DoError(ctx context.Context, method, path string, opts *Options) (*http.Response, error) { - res, err := c.DoReq(ctx, method, path, opts) - if err != nil { - return res, err - } - if res.Body != nil { - defer res.Body.Close() // nolint: errcheck - } - err = ResponseError(res) - return res, err -} - -// ETag returns the unquoted ETag value, and a bool indicating whether it was -// found. -func ETag(resp *http.Response) (string, bool) { - if resp == nil { - return "", false - } - etag, ok := resp.Header["Etag"] - if !ok { - etag, ok = resp.Header["ETag"] // nolint: staticcheck - } - if !ok { - return "", false - } - return strings.Trim(etag[0], `"`), ok -} - -// GetRev extracts the revision from the response's Etag header -func GetRev(resp *http.Response) (rev string, err error) { - if err = ResponseError(resp); err != nil { - return "", err - } - rev, ok := ETag(resp) - if ok { - return rev, nil - } - return extractRev(resp) -} - -// When the ETag header is missing, which can happen, for example, when doing -// a request with revs_info=true. This means we need to look through the -// body of the request for the revision. Fortunately, CouchDB tends to send -// the _id and _rev fields first, so we shouldn't need to parse the entire -// body. The important thing is that resp.Body must be restored, so that the -// normal document scanning can take place as usual. -func extractRev(resp *http.Response) (string, error) { - if resp.Request.Method == http.MethodHead { - return "", errors.New("unable to determine document revision") - } - buf := &bytes.Buffer{} - r := io.TeeReader(resp.Body, buf) - defer func() { - // Restore the original resp.Body - resp.Body = struct { - io.Reader - io.Closer - }{ - Reader: io.MultiReader(buf, resp.Body), - Closer: resp.Body, - } - }() - rev, err := readRev(r) - if err != nil { - return "", fmt.Errorf("unable to determine document revision: %s", err) - } - return rev, nil -} - -// readRev searches r for a `_rev` field, and returns its value without reading -// the rest of the JSON stream. -func readRev(r io.Reader) (string, error) { - dec := json.NewDecoder(r) - tk, err := dec.Token() - if err != nil { - return "", err - } - if tk != json.Delim('{') { - return "", fmt.Errorf("Expected %q token, found %q", '{', tk) - } - for dec.More() { - tk, err = dec.Token() - if err != nil { - return "", err - } - if tk == "_rev" { - tk, err = dec.Token() - if err != nil { - return "", err - } - if value, ok := tk.(string); ok { - return value, nil - } - return "", fmt.Errorf("found %q in place of _rev value", tk) - } - } - - return "", errors.New("_rev key not found in response body") -} - -type exitStatuser interface { - ExitStatus() int -} - -// ExitStatus returns the curl exit status embedded in the error, or 1 (unknown -// error), if there was no specified exit status. If err is nil, ExitStatus -// returns 0. -func ExitStatus(err error) int { - if err == nil { - return 0 - } - if statuser, ok := err.(exitStatuser); ok { // nolint: misspell - return statuser.ExitStatus() - } - return 0 -} - -func (c *Client) userAgent() string { - ua := fmt.Sprintf("%s/%s (Language=%s; Platform=%s/%s)", - UserAgent, Version, runtime.Version(), runtime.GOARCH, runtime.GOOS) - return strings.Join(append([]string{ua}, c.UserAgents...), " ") -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/constants.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/constants.go deleted file mode 100644 index b56077d34..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/constants.go +++ /dev/null @@ -1,7 +0,0 @@ -package chttp - -// Standard headers used by CouchDB. -const ( - HeaderDestination = "Destination" - HeaderIdempotencyKey = "X-Idempotency-Key" -) diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/cookieauth.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/cookieauth.go deleted file mode 100644 index bc87cac07..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/cookieauth.go +++ /dev/null @@ -1,112 +0,0 @@ -package chttp - -import ( - "context" - "net/http" - "time" - - kivik "github.com/go-kivik/kivik/v3" -) - -// CookieAuth provides CouchDB Cookie auth services as described at -// http://docs.couchdb.org/en/2.0.0/api/server/authn.html#cookie-authentication -// -// CookieAuth stores authentication state after use, so should not be re-used. -type CookieAuth struct { - Username string `json:"name"` - Password string `json:"password"` - - client *Client - // transport stores the original transport that is overridden by this auth - // mechanism - transport http.RoundTripper -} - -var _ Authenticator = &CookieAuth{} - -// Authenticate initiates a session with the CouchDB server. -func (a *CookieAuth) Authenticate(c *Client) error { - a.client = c - a.setCookieJar() - a.transport = c.Transport - if a.transport == nil { - a.transport = http.DefaultTransport - } - c.Transport = a - return nil -} - -// shouldAuth returns true if there is no cookie set, or if it has expired. -func (a *CookieAuth) shouldAuth(req *http.Request) bool { - if _, err := req.Cookie(kivik.SessionCookieName); err == nil { - return false - } - cookie := a.Cookie() - if cookie == nil { - return true - } - if !cookie.Expires.IsZero() { - return cookie.Expires.Before(time.Now()) - } - // If we get here, it means the server did not include an expiry time in - // the session cookie. Some CouchDB configurations do this, but rather than - // re-authenticating for every request, we'll let the session expire. A - // future change might be to make a client-configurable option to set the - // re-authentication timeout. - return false -} - -// Cookie returns the current session cookie if found, or nil if not. -func (a *CookieAuth) Cookie() *http.Cookie { - if a.client == nil { - return nil - } - for _, cookie := range a.client.Jar.Cookies(a.client.dsn) { - if cookie.Name == kivik.SessionCookieName { - return cookie - } - } - return nil -} - -var authInProgress = &struct{ name string }{"in progress"} - -// RoundTrip fulfills the http.RoundTripper interface. It sets -// (re-)authenticates when the cookie has expired or is not yet set. -func (a *CookieAuth) RoundTrip(req *http.Request) (*http.Response, error) { - if err := a.authenticate(req); err != nil { - return nil, err - } - return a.transport.RoundTrip(req) -} - -func (a *CookieAuth) authenticate(req *http.Request) error { - ctx := req.Context() - if inProg, _ := ctx.Value(authInProgress).(bool); inProg { - return nil - } - if !a.shouldAuth(req) { - return nil - } - a.client.authMU.Lock() - defer a.client.authMU.Unlock() - if c := a.Cookie(); c != nil { - // In case another simultaneous process authenticated successfully first - req.AddCookie(c) - return nil - } - ctx = context.WithValue(ctx, authInProgress, true) - opts := &Options{ - GetBody: BodyEncoder(a), - Header: http.Header{ - HeaderIdempotencyKey: []string{}, - }, - } - if _, err := a.client.DoError(ctx, http.MethodPost, "/_session", opts); err != nil { - return err - } - if c := a.Cookie(); c != nil { - req.AddCookie(c) - } - return nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/encode.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/encode.go deleted file mode 100644 index 731f9c73f..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/encode.go +++ /dev/null @@ -1,25 +0,0 @@ -package chttp - -import ( - "net/url" - "strings" -) - -const ( - prefixDesign = "_design/" - prefixLocal = "_local/" -) - -// EncodeDocID encodes a document ID according to CouchDB's path encoding rules. -// -// In particular: -// - '_design/' and '_local/' prefixes are unaltered. -// - The rest of the docID is Query-URL encoded (despite being part of the path) -func EncodeDocID(docID string) string { - for _, prefix := range []string{prefixDesign, prefixLocal} { - if strings.HasPrefix(docID, prefix) { - return prefix + url.PathEscape(strings.TrimPrefix(docID, prefix)) - } - } - return url.PathEscape(docID) -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/errors.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/errors.go deleted file mode 100644 index 49e6a346f..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/errors.go +++ /dev/null @@ -1,108 +0,0 @@ -package chttp - -import ( - "encoding/json" - "fmt" - "mime" - "net/http" -) - -// HTTPError is an error that represents an HTTP transport error. -type HTTPError struct { - // Response is the HTTP response received by the client. Typically the - // response body has already been consumed, but the response and request - // headers and other metadata will typically be in tact for debugging - // purposes. - Response *http.Response `json:"-"` - - // Reason is the server-supplied error reason. - Reason string `json:"reason"` - - exitStatus int -} - -func (e *HTTPError) Error() string { - if e.Reason == "" { - return http.StatusText(e.StatusCode()) - } - if statusText := http.StatusText(e.StatusCode()); statusText != "" { - return fmt.Sprintf("%s: %s", statusText, e.Reason) - } - return e.Reason -} - -// StatusCode returns the embedded status code. -func (e *HTTPError) StatusCode() int { - return e.Response.StatusCode -} - -// ExitStatus returns the embedded exit status. -func (e *HTTPError) ExitStatus() int { - return e.exitStatus -} - -// Format implements fmt.Formatter -func (e *HTTPError) Format(f fmt.State, c rune) { - formatError(e, f, c) -} - -// FormatError satisfies the Go 1.13 errors.Formatter interface -// (golang.org/x/xerrors.Formatter for older versions of Go). -func (e *HTTPError) FormatError(p printer) error { - p.Print(e.Error()) - if p.Detail() { - p.Printf("REQUEST: %s %s (%d bytes)", e.Response.Request.Method, e.Response.Request.URL.String(), e.Response.Request.ContentLength) - p.Printf("\nRESPONSE: %d / %s (%d bytes)\n", e.Response.StatusCode, http.StatusText(e.Response.StatusCode), e.Response.ContentLength) - } - return nil -} - -// ResponseError returns an error from an *http.Response. -func ResponseError(resp *http.Response) error { - if resp.StatusCode < 400 { - return nil - } - if resp.Body != nil { - defer resp.Body.Close() // nolint: errcheck - } - httpErr := &HTTPError{ - Response: resp, - exitStatus: ExitNotRetrieved, - } - if resp.Request.Method != "HEAD" && resp.ContentLength != 0 { - if ct, _, _ := mime.ParseMediaType(resp.Header.Get("Content-Type")); ct == typeJSON { - _ = json.NewDecoder(resp.Body).Decode(httpErr) - } - } - return httpErr -} - -type curlError struct { - curlStatus int - httpStatus int - error -} - -func (e *curlError) ExitStatus() int { - return e.curlStatus -} - -func (e *curlError) StatusCode() int { - return e.httpStatus -} - -func fullError(httpStatus, curlStatus int, err error) error { - return &curlError{ - curlStatus: curlStatus, - httpStatus: httpStatus, - error: err, - } -} - -func (e *curlError) Cause() error { - return e.error -} - -func (e *curlError) Unwrap() error { - return e.error -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/exitstatus.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/exitstatus.go deleted file mode 100644 index 44aa28df8..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/exitstatus.go +++ /dev/null @@ -1,63 +0,0 @@ -package chttp - -// Exit statuses, borrowed from Curl. Not all Curl statuses are represented here. -const ( - // Exited with an unknown failure. - ExitUnknownFailure = 1 - // Failed to initialize. - ExitFailedToInitialize = 2 - // URL malformed. The syntax was not correct. - ExitStatusURLMalformed = 3 - // The given remote host was not resolved. - ExitHostNotResolved = 6 - // Failed to connect to host. - ExitFailedToConnect = 7 - // Weird server reply. The server sent data kouch couldn't parse. - ExitWeirdReply = 8 - // The requested url was not found or returned another error with the HTTP error code being 400 or above. - ExitNotRetrieved = 22 - // Write error. Kouch couldn't write data to a local filesystem or similar. - ExitWriteError = 23 - // Read error. Various reading problems. - ExitReadError = 26 - // The specified time-out period was reached according to the conditions. - ExitOperationTimeout = 28 - // Internal post request generation error. - ExitPostError = 34 - // When following redirects, curl hit the maximum amount. - ExitTooManyRedirects = 47 - -/* -5 Couldn't resolve proxy. The given proxy host could not be resolved. -18 Partial file. Only a part of the file was transferred. -27 Out of memory. A memory allocation request failed. -33 HTTP range error. The range "command" didn't work. -35 SSL connect error. The SSL handshaking failed. -37 FILE couldn't read file. Failed to open the file. Permissions? -43 Internal error. A function was called with a bad parameter. -45 Interface error. A specified outgoing interface could not be used. -51 The peer's SSL certificate or SSH MD5 fingerprint was not OK. -52 The server didn't reply anything, which here is considered an error. -53 SSL crypto engine not found. -54 Cannot set SSL crypto engine as default. -55 Failed sending network data. -56 Failure in receiving network data. -58 Problem with the local certificate. -59 Couldn't use specified SSL cipher. -60 Peer certificate cannot be authenticated with known CA certificates. -61 Unrecognized transfer encoding. -63 Maximum file size exceeded. -65 Sending the data requires a rewind that failed. -66 Failed to initialise SSL Engine. -67 The user name, password, or similar was not accepted and curl failed to log in. -75 Character conversion failed. -76 Character conversion functions required. -77 Problem with reading the SSL CA cert (path? access rights?). -78 The resource referenced in the URL does not exist. -80 Failed to shut down the SSL connection. -82 Could not load CRL file, missing or wrong format (added in 7.19.0). -83 Issuer check failed (added in 7.19.0). -89 No connection available, the session will be queued -90 SSL public key does not matched pinned public key -*/ -) diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/proxyauth.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/proxyauth.go deleted file mode 100644 index 5f5b38915..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/proxyauth.go +++ /dev/null @@ -1,63 +0,0 @@ -package chttp - -import ( - "crypto/hmac" - "crypto/sha1" - "encoding/hex" - "net/http" - "strings" -) - -type ProxyAuth struct { - Username string - Secret string - Roles []string - Headers http.Header - - transport http.RoundTripper - token string -} - -var _ Authenticator = &ProxyAuth{} - -func (a *ProxyAuth) header(header string) string { - if h := a.Headers.Get(header); h != "" { - return http.CanonicalHeaderKey(h) - } - return header -} - -func (a *ProxyAuth) genToken() string { - if a.Secret == "" { - return "" - } - if a.token != "" { - return a.token - } - // Generate auth token - // https://docs.couchdb.org/en/stable/config/auth.html#couch_httpd_auth/x_auth_token - h := hmac.New(sha1.New, []byte(a.Secret)) - _, _ = h.Write([]byte(a.Username)) - a.token = hex.EncodeToString(h.Sum(nil)) - return a.token -} - -func (a *ProxyAuth) RoundTrip(req *http.Request) (*http.Response, error) { - if token := a.genToken(); token != "" { - req.Header.Set(a.header("X-Auth-CouchDB-Token"), token) - } - - req.Header.Set(a.header("X-Auth-CouchDB-UserName"), a.Username) - req.Header.Set(a.header("X-Auth-CouchDB-Roles"), strings.Join(a.Roles, ",")) - - return a.transport.RoundTrip(req) -} - -func (a *ProxyAuth) Authenticate(c *Client) error { - a.transport = c.Transport - if a.transport == nil { - a.transport = http.DefaultTransport - } - c.Transport = a - return nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/trace.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/trace.go deleted file mode 100644 index 39a9b20ba..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/trace.go +++ /dev/null @@ -1,136 +0,0 @@ -package chttp - -import ( - "bytes" - "context" - "io" - "io/ioutil" - "net/http" -) - -var clientTraceContextKey = &struct{ name string }{"client trace"} - -// ContextClientTrace returns the ClientTrace associated with the -// provided context. If none, it returns nil. -func ContextClientTrace(ctx context.Context) *ClientTrace { - trace, _ := ctx.Value(clientTraceContextKey).(*ClientTrace) - return trace -} - -// ClientTrace is a set of hooks to run at various stages of an outgoing -// HTTP request. Any particular hook may be nil. Functions may be -// called concurrently from different goroutines and some may be called -// after the request has completed or failed. -type ClientTrace struct { - // HTTPResponse returns a cloe of the *http.Response received from the - // server, with the body set to nil. If you need the body, use the more - // expensive HTTPResponseBody. - HTTPResponse func(*http.Response) - - // HTTPResponseBody returns a clone of the *http.Response received from the - // server, with the body cloned. This can be expensive for responses - // with large bodies. - HTTPResponseBody func(*http.Response) - - // HTTPRequest returns a clone of the *http.Request sent to the server, with - // the body set to nil. If you need the body, use the more expensive - // HTTPRequestBody. - HTTPRequest func(*http.Request) - - // HTTPRequestBody returns a clone of the *http.Request sent to the server, - // with the body cloned, if it is set. This can be expensive for requests - // with large bodies. - HTTPRequestBody func(*http.Request) -} - -// WithClientTrace returns a new context based on the provided parent -// ctx. HTTP client requests made with the returned context will use -// the provided trace hooks, in addition to any previous hooks -// registered with ctx. Any hooks defined in the provided trace will -// be called first. -func WithClientTrace(ctx context.Context, trace *ClientTrace) context.Context { - if trace == nil { - panic("nil trace") - } - return context.WithValue(ctx, clientTraceContextKey, trace) -} - -func (t *ClientTrace) httpResponse(r *http.Response) { - if t.HTTPResponse == nil || r == nil { - return - } - clone := new(http.Response) - *clone = *r - clone.Body = nil - t.HTTPResponse(clone) -} - -func (t *ClientTrace) httpResponseBody(r *http.Response) { - if t.HTTPResponseBody == nil || r == nil { - return - } - clone := new(http.Response) - *clone = *r - rBody := r.Body - body, readErr := ioutil.ReadAll(rBody) - closeErr := rBody.Close() - r.Body = newReplay(body, readErr, closeErr) - clone.Body = newReplay(body, readErr, closeErr) - t.HTTPResponseBody(clone) -} - -func (t *ClientTrace) httpRequest(r *http.Request) { - if t.HTTPRequest == nil { - return - } - clone := new(http.Request) - *clone = *r - clone.Body = nil - t.HTTPRequest(clone) -} - -func (t *ClientTrace) httpRequestBody(r *http.Request) { - if t.HTTPRequestBody == nil { - return - } - clone := new(http.Request) - *clone = *r - if r.Body != nil { - rBody := r.Body - body, readErr := ioutil.ReadAll(rBody) - closeErr := rBody.Close() - r.Body = newReplay(body, readErr, closeErr) - clone.Body = newReplay(body, readErr, closeErr) - } - t.HTTPRequestBody(clone) -} - -func newReplay(body []byte, readErr, closeErr error) io.ReadCloser { - if readErr == nil && closeErr == nil { - return ioutil.NopCloser(bytes.NewReader(body)) - } - return &replayReadCloser{ - Reader: ioutil.NopCloser(bytes.NewReader(body)), - readErr: readErr, - closeErr: closeErr, - } -} - -// replayReadCloser replays read and close errors -type replayReadCloser struct { - io.Reader - readErr error - closeErr error -} - -func (r *replayReadCloser) Read(p []byte) (int, error) { - c, err := r.Reader.Read(p) - if err == io.EOF && r.readErr != nil { - err = r.readErr - } - return c, err -} - -func (r *replayReadCloser) Close() error { - return r.closeErr -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/xerrors_13.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/xerrors_13.go deleted file mode 100644 index e98f2bd8d..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/xerrors_13.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build 1.13 - -package chttp - -type printer = errors.Printer - -var formatError = errors.FormatError diff --git a/vendor/github.com/go-kivik/couchdb/v3/chttp/xerrors_pre13.go b/vendor/github.com/go-kivik/couchdb/v3/chttp/xerrors_pre13.go deleted file mode 100644 index 72e41abf2..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/chttp/xerrors_pre13.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !1.13 - -package chttp - -import ( - "golang.org/x/xerrors" -) - -type printer = xerrors.Printer - -var formatError = xerrors.FormatError diff --git a/vendor/github.com/go-kivik/couchdb/v3/client.go b/vendor/github.com/go-kivik/couchdb/v3/client.go deleted file mode 100644 index 4497e31c5..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/client.go +++ /dev/null @@ -1,104 +0,0 @@ -package couchdb - -import ( - "context" - "encoding/json" - "io" - "net/http" - "net/url" - "strings" - - "github.com/go-kivik/couchdb/v3/chttp" - kivik "github.com/go-kivik/kivik/v3" - "github.com/go-kivik/kivik/v3/driver" -) - -func (c *client) AllDBs(ctx context.Context, opts map[string]interface{}) ([]string, error) { - query, err := optionsToParams(opts) - if err != nil { - return nil, err - } - var allDBs []string - _, err = c.DoJSON(ctx, http.MethodGet, "/_all_dbs", &chttp.Options{Query: query}, &allDBs) - return allDBs, err -} - -func (c *client) DBExists(ctx context.Context, dbName string, _ map[string]interface{}) (bool, error) { - if dbName == "" { - return false, missingArg("dbName") - } - _, err := c.DoError(ctx, http.MethodHead, dbName, nil) - if kivik.StatusCode(err) == http.StatusNotFound { - return false, nil - } - return err == nil, err -} - -func (c *client) CreateDB(ctx context.Context, dbName string, opts map[string]interface{}) error { - if dbName == "" { - return missingArg("dbName") - } - query, err := optionsToParams(opts) - if err != nil { - return err - } - _, err = c.DoError(ctx, http.MethodPut, url.PathEscape(dbName), &chttp.Options{Query: query}) - return err -} - -func (c *client) DestroyDB(ctx context.Context, dbName string, _ map[string]interface{}) error { - if dbName == "" { - return missingArg("dbName") - } - _, err := c.DoError(ctx, http.MethodDelete, url.PathEscape(dbName), nil) - return err -} - -func (c *client) DBUpdates(ctx context.Context) (updates driver.DBUpdates, err error) { - resp, err := c.DoReq(ctx, http.MethodGet, "/_db_updates?feed=continuous&since=now", nil) - if err != nil { - return nil, err - } - if err := chttp.ResponseError(resp); err != nil { - return nil, err - } - return newUpdates(ctx, resp.Body), nil -} - -type couchUpdates struct { - *iter -} - -var _ driver.DBUpdates = &couchUpdates{} - -type updatesParser struct{} - -var _ parser = &updatesParser{} - -func (p *updatesParser) decodeItem(i interface{}, dec *json.Decoder) error { - return dec.Decode(i) -} - -func newUpdates(ctx context.Context, body io.ReadCloser) *couchUpdates { - return &couchUpdates{ - iter: newIter(ctx, nil, "", body, &updatesParser{}), - } -} - -func (u *couchUpdates) Next(update *driver.DBUpdate) error { - return u.iter.next(update) -} - -// Ping queries the /_up endpoint, and returns true if there are no errors, or -// if a 400 (Bad Request) is returned, and the Server: header indicates a server -// version prior to 2.x. -func (c *client) Ping(ctx context.Context) (bool, error) { - resp, err := c.DoError(ctx, http.MethodHead, "/_up", nil) - if kivik.StatusCode(err) == http.StatusBadRequest { - return strings.HasPrefix(resp.Header.Get("Server"), "CouchDB/1."), nil - } - if kivik.StatusCode(err) == http.StatusNotFound { - return false, nil - } - return err == nil, err -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/cluster.go b/vendor/github.com/go-kivik/couchdb/v3/cluster.go deleted file mode 100644 index 399de1af8..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/cluster.go +++ /dev/null @@ -1,35 +0,0 @@ -package couchdb - -import ( - "context" - "net/http" - - "github.com/go-kivik/couchdb/v3/chttp" - "github.com/go-kivik/kivik/v3/driver" -) - -func (c *client) ClusterStatus(ctx context.Context, opts map[string]interface{}) (string, error) { - var result struct { - State string `json:"state"` - } - query, err := optionsToParams(opts) - if err != nil { - return "", err - } - _, err = c.DoJSON(ctx, http.MethodGet, "/_cluster_setup", &chttp.Options{Query: query}, &result) - return result.State, err -} - -func (c *client) ClusterSetup(ctx context.Context, action interface{}) error { - options := &chttp.Options{ - Body: chttp.EncodeBody(action), - } - _, err := c.DoError(ctx, http.MethodPost, "/_cluster_setup", options) - return err -} - -func (c *client) Membership(ctx context.Context) (*driver.ClusterMembership, error) { - result := new(driver.ClusterMembership) - _, err := c.DoJSON(ctx, http.MethodGet, "/_membership", nil, &result) - return result, err -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/codecov.yml b/vendor/github.com/go-kivik/couchdb/v3/codecov.yml deleted file mode 100644 index b8a66592a..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/codecov.yml +++ /dev/null @@ -1,2 +0,0 @@ -ignore: - - "test/.*" diff --git a/vendor/github.com/go-kivik/couchdb/v3/config.go b/vendor/github.com/go-kivik/couchdb/v3/config.go deleted file mode 100644 index a014368f3..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/config.go +++ /dev/null @@ -1,67 +0,0 @@ -package couchdb - -import ( - "bytes" - "context" - "encoding/json" - "io/ioutil" - "net/http" - "strings" - - "github.com/go-kivik/couchdb/v3/chttp" - "github.com/go-kivik/kivik/v3/driver" -) - -// Couch1ConfigNode can be passed to any of the Config-related methods as the -// node name, to query the /_config endpoint in a CouchDB 1.x-compatible way. -const Couch1ConfigNode = "" - -var _ driver.Configer = &client{} - -func configURL(node string, parts ...string) string { - var components []string - if node == Couch1ConfigNode { - components = append(make([]string, 0, len(parts)+1), - "_config") - } else { - components = append(make([]string, 0, len(parts)+3), - "_node", node, "_config", - ) - } - components = append(components, parts...) - return "/" + strings.Join(components, "/") -} - -func (c *client) Config(ctx context.Context, node string) (driver.Config, error) { - cf := driver.Config{} - _, err := c.Client.DoJSON(ctx, http.MethodGet, configURL(node), nil, &cf) - return cf, err -} - -func (c *client) ConfigSection(ctx context.Context, node, section string) (driver.ConfigSection, error) { - sec := driver.ConfigSection{} - _, err := c.Client.DoJSON(ctx, http.MethodGet, configURL(node, section), nil, &sec) - return sec, err -} - -func (c *client) ConfigValue(ctx context.Context, node, section, key string) (string, error) { - var value string - _, err := c.Client.DoJSON(ctx, http.MethodGet, configURL(node, section, key), nil, &value) - return value, err -} - -func (c *client) SetConfigValue(ctx context.Context, node, section, key, value string) (string, error) { - body, _ := json.Marshal(value) // Strings never cause JSON marshaling errors - var old string - opts := &chttp.Options{ - Body: ioutil.NopCloser(bytes.NewReader(body)), - } - _, err := c.Client.DoJSON(ctx, http.MethodPut, configURL(node, section, key), opts, &old) - return old, err -} - -func (c *client) DeleteConfigKey(ctx context.Context, node, section, key string) (string, error) { - var value string - _, err := c.Client.DoJSON(ctx, http.MethodDelete, configURL(node, section, key), nil, &value) - return value, err -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/constants.go b/vendor/github.com/go-kivik/couchdb/v3/constants.go deleted file mode 100644 index 875bd9289..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/constants.go +++ /dev/null @@ -1,44 +0,0 @@ -package couchdb - -// Version is the current version of this package. -const Version = "3.2.5" - -const ( - // OptionFullCommit is the option key used to set the `X-Couch-Full-Commit` - // header in the request when set to true. - // - // Example: - // - // db.Put(ctx, "doc_id", doc, kivik.Options{couchdb.OptionFullCommit: true}) - OptionFullCommit = "X-Couch-Full-Commit" - - // OptionIfNoneMatch is an option key to set the If-None-Match header on - // the request. - // - // Example: - // - // row, err := db.Get(ctx, "doc_id", kivik.Options{couchdb.OptionIfNoneMatch: "1-xxx"}) - OptionIfNoneMatch = "If-None-Match" - - // OptionPartition instructs supporting methods to limit the query to the - // specified partition. Supported methods are: Query, AllDocs, Find, and - // Explain. Only supported by CouchDB 3.0.0 and newer. - // - // See https://docs.couchdb.org/en/stable/api/partitioned-dbs.html - OptionPartition = "kivik:partition" - - // NoMultipartPut instructs the Put() method not to use CouchDB's - // multipart/related upload capabilities. This only affects PUT requests that - // also include attachments. - NoMultipartPut = "kivik:no-multipart-put" - - // NoMultipartGet instructs the Get() method not to use CouchDB's ability to - // download attachments with the multipart/related media type. This only - // affects GET requests that request attachments. - NoMultipartGet = "kivik:no-multipart-get" -) - -const ( - typeJSON = "application/json" - typeMPRelated = "multipart/related" -) diff --git a/vendor/github.com/go-kivik/couchdb/v3/couchdb.go b/vendor/github.com/go-kivik/couchdb/v3/couchdb.go deleted file mode 100644 index 0b7f63606..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/couchdb.go +++ /dev/null @@ -1,85 +0,0 @@ -package couchdb - -import ( - "context" - "fmt" - "net/http" - "net/url" - "sync" - - "github.com/go-kivik/couchdb/v3/chttp" - kivik "github.com/go-kivik/kivik/v3" - "github.com/go-kivik/kivik/v3/driver" -) - -// Couch represents the parent driver instance. -type Couch struct { - // If provided, UserAgent is appended to the User-Agent header on all - // outbound requests. - UserAgent string - - // If provided, HTTPClient will be used for requests to the CouchDB server. - HTTPClient *http.Client -} - -var _ driver.Driver = &Couch{} - -func init() { - kivik.Register("couch", &Couch{}) -} - -// Known vendor strings -const ( - VendorCouchDB = "The Apache Software Foundation" - VendorCloudant = "IBM Cloudant" -) - -type client struct { - *chttp.Client - - // schedulerDetected will be set once the scheduler has been detected. - // It should only be accessed through the schedulerSupported() method. - schedulerDetected *bool - sdMU sync.Mutex -} - -var ( - _ driver.Client = &client{} - _ driver.DBUpdater = &client{} -) - -// NewClient establishes a new connection to a CouchDB server instance. If -// auth credentials are included in the URL, they are used to authenticate using -// CookieAuth (or BasicAuth if compiled with GopherJS). If you wish to use a -// different auth mechanism, do not specify credentials here, and instead call -// Authenticate() later. -func (d *Couch) NewClient(dsn string) (driver.Client, error) { - httpClient := d.HTTPClient - if httpClient == nil { - httpClient = &http.Client{} - } - chttpClient, err := chttp.NewWithClient(httpClient, dsn) - if err != nil { - return nil, err - } - chttpClient.UserAgents = []string{ - fmt.Sprintf("Kivik/%s", kivik.KivikVersion), - fmt.Sprintf("Kivik CouchDB driver/%s", Version), - } - if d.UserAgent != "" { - chttpClient.UserAgents = append(chttpClient.UserAgents, d.UserAgent) - } - return &client{ - Client: chttpClient, - }, nil -} - -func (c *client) DB(_ context.Context, dbName string, _ map[string]interface{}) (driver.DB, error) { - if dbName == "" { - return nil, missingArg("dbName") - } - return &db{ - client: c, - dbName: url.PathEscape(dbName), - }, nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/db.go b/vendor/github.com/go-kivik/couchdb/v3/db.go deleted file mode 100644 index d6d1efdd8..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/db.go +++ /dev/null @@ -1,914 +0,0 @@ -package couchdb - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "mime" - "mime/multipart" - "net/http" - "net/textproto" - "net/url" - "os" - "path" - "path/filepath" - "reflect" - "sort" - "strconv" - "strings" - "sync" - - "github.com/go-kivik/couchdb/v3/chttp" - kivik "github.com/go-kivik/kivik/v3" - "github.com/go-kivik/kivik/v3/driver" -) - -type db struct { - *client - dbName string -} - -var ( - _ driver.DB = &db{} - _ driver.OptsFinder = &db{} - _ driver.MetaGetter = &db{} - _ driver.AttachmentMetaGetter = &db{} - _ driver.PartitionedDB = &db{} -) - -func (d *db) path(path string) string { - url, err := url.Parse(d.dbName + "/" + strings.TrimPrefix(path, "/")) - if err != nil { - panic("THIS IS A BUG: d.path failed: " + err.Error()) - } - return url.String() -} - -func optionsToParams(opts ...map[string]interface{}) (url.Values, error) { - params := url.Values{} - for _, optsSet := range opts { - if err := encodeKeys(optsSet); err != nil { - return nil, err - } - for key, i := range optsSet { - var values []string - switch v := i.(type) { - case string: - values = []string{v} - case []string: - values = v - case bool: - values = []string{fmt.Sprintf("%t", v)} - case int, uint, uint8, uint16, uint32, uint64, int8, int16, int32, int64: - values = []string{fmt.Sprintf("%d", v)} - default: - return nil, &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: fmt.Errorf("kivik: invalid type %T for options", i)} - } - for _, value := range values { - params.Add(key, value) - } - } - } - return params, nil -} - -// rowsQuery performs a query that returns a rows iterator. -func (d *db) rowsQuery(ctx context.Context, path string, opts map[string]interface{}) (driver.Rows, error) { - payload := make(map[string]interface{}) - if keys := opts["keys"]; keys != nil { - delete(opts, "keys") - payload["keys"] = keys - } - rowsInit := newRows - if queries := opts["queries"]; queries != nil { - rowsInit = func(ctx context.Context, r io.ReadCloser) driver.Rows { - return newMultiQueriesRows(ctx, r) - } - delete(opts, "queries") - payload["queries"] = queries - // Funny that this works even in CouchDB 1.x. It seems 1.x just ignores - // extra path elements beyond the view name. So yay for accidental - // backward compatibility! - path = filepath.Join(path, "queries") - } - query, err := optionsToParams(opts) - if err != nil { - return nil, err - } - options := &chttp.Options{Query: query} - method := http.MethodGet - if len(payload) > 0 { - method = http.MethodPost - options.GetBody = chttp.BodyEncoder(payload) - options.Header = http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - } - } - resp, err := d.Client.DoReq(ctx, method, d.path(path), options) - if err != nil { - return nil, err - } - if err = chttp.ResponseError(resp); err != nil { - return nil, err - } - return rowsInit(ctx, resp.Body), nil -} - -// AllDocs returns all of the documents in the database. -func (d *db) AllDocs(ctx context.Context, opts map[string]interface{}) (driver.Rows, error) { - reqPath := "_all_docs" - if part, ok := opts[OptionPartition].(string); ok { - delete(opts, OptionPartition) - reqPath = path.Join("_partition", part, reqPath) - } - return d.rowsQuery(ctx, reqPath, opts) -} - -// DesignDocs returns all of the documents in the database. -func (d *db) DesignDocs(ctx context.Context, opts map[string]interface{}) (driver.Rows, error) { - return d.rowsQuery(ctx, "_design_docs", opts) -} - -// LocalDocs returns all of the documents in the database. -func (d *db) LocalDocs(ctx context.Context, opts map[string]interface{}) (driver.Rows, error) { - return d.rowsQuery(ctx, "_local_docs", opts) -} - -// Query queries a view. -func (d *db) Query(ctx context.Context, ddoc, view string, opts map[string]interface{}) (driver.Rows, error) { - reqPath := fmt.Sprintf("_design/%s/_view/%s", chttp.EncodeDocID(ddoc), chttp.EncodeDocID(view)) - if part, ok := opts[OptionPartition].(string); ok { - delete(opts, OptionPartition) - reqPath = path.Join("_partition", part, reqPath) - } - return d.rowsQuery(ctx, reqPath, opts) -} - -// Get fetches the requested document. -func (d *db) Get(ctx context.Context, docID string, options map[string]interface{}) (*driver.Document, error) { - resp, rev, err := d.get(ctx, http.MethodGet, docID, options) - if err != nil { - return nil, err - } - ct, params, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) - if err != nil { - return nil, &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - switch ct { - case typeJSON: - return &driver.Document{ - Rev: rev, - ContentLength: resp.ContentLength, - Body: resp.Body, - }, nil - case typeMPRelated: - boundary := strings.Trim(params["boundary"], "\"") - if boundary == "" { - return nil, &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: errors.New("kivik: boundary missing for multipart/related response")} - } - mpReader := multipart.NewReader(resp.Body, boundary) - body, err := mpReader.NextPart() - if err != nil { - return nil, &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - length := int64(-1) - if cl, e := strconv.ParseInt(body.Header.Get("Content-Length"), 10, 64); e == nil { - length = cl - } - - // TODO: Use a TeeReader here, to avoid slurping the entire body into memory at once - content, err := ioutil.ReadAll(body) - if err != nil { - return nil, &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - var metaDoc struct { - Attachments map[string]attMeta `json:"_attachments"` - } - if err := json.Unmarshal(content, &metaDoc); err != nil { - return nil, &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - - return &driver.Document{ - ContentLength: length, - Rev: rev, - Body: ioutil.NopCloser(bytes.NewBuffer(content)), - Attachments: &multipartAttachments{ - content: resp.Body, - mpReader: mpReader, - meta: metaDoc.Attachments, - }, - }, nil - default: - return nil, &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: fmt.Errorf("kivik: invalid content type in response: %s", ct)} - } -} - -type attMeta struct { - ContentType string `json:"content_type"` - Size *int64 `json:"length"` - Follows bool `json:"follows"` -} - -type multipartAttachments struct { - content io.ReadCloser - mpReader *multipart.Reader - meta map[string]attMeta -} - -var _ driver.Attachments = &multipartAttachments{} - -func (a *multipartAttachments) Next(att *driver.Attachment) error { - part, err := a.mpReader.NextPart() - switch err { - case io.EOF: - return err - case nil: - // fall through - default: - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - - disp, dispositionParams, err := mime.ParseMediaType(part.Header.Get("Content-Disposition")) - if err != nil { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: fmt.Errorf("Content-Disposition: %s", err)} - } - if disp != "attachment" { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: fmt.Errorf("Unexpected Content-Disposition: %s", disp)} - } - filename := dispositionParams["filename"] - - meta := a.meta[filename] - if !meta.Follows { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: fmt.Errorf("File '%s' not in manifest", filename)} - } - - size := int64(-1) - if meta.Size != nil { - size = *meta.Size - } else if cl, e := strconv.ParseInt(part.Header.Get("Content-Length"), 10, 64); e == nil { - size = cl - } - - var cType string - if ctHeader, ok := part.Header["Content-Type"]; ok { - cType, _, err = mime.ParseMediaType(ctHeader[0]) - if err != nil { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - } else { - cType = meta.ContentType - } - - *att = driver.Attachment{ - Filename: filename, - Size: size, - ContentType: cType, - Content: part, - ContentEncoding: part.Header.Get("Content-Encoding"), - } - return nil -} - -func (a *multipartAttachments) Close() error { - return a.content.Close() -} - -// Rev returns the most current rev of the requested document. -func (d *db) GetMeta(ctx context.Context, docID string, options map[string]interface{}) (size int64, rev string, err error) { - resp, rev, err := d.get(ctx, http.MethodHead, docID, options) - if err != nil { - return 0, "", err - } - return resp.ContentLength, rev, err -} - -func (d *db) get(ctx context.Context, method string, docID string, options map[string]interface{}) (*http.Response, string, error) { - if docID == "" { - return nil, "", missingArg("docID") - } - - inm, err := ifNoneMatch(options) - if err != nil { - return nil, "", err - } - - params, err := optionsToParams(options) - if err != nil { - return nil, "", err - } - opts := &chttp.Options{ - Accept: typeMPRelated + "," + typeJSON, - IfNoneMatch: inm, - Query: params, - } - if _, ok := options[NoMultipartGet]; ok { - opts.Accept = typeJSON - } - resp, err := d.Client.DoReq(ctx, method, d.path(chttp.EncodeDocID(docID)), opts) - if err != nil { - return nil, "", err - } - if respErr := chttp.ResponseError(resp); respErr != nil { - return nil, "", respErr - } - rev, err := chttp.GetRev(resp) - return resp, rev, err -} - -func (d *db) CreateDoc(ctx context.Context, doc interface{}, options map[string]interface{}) (docID, rev string, err error) { - result := struct { - ID string `json:"id"` - Rev string `json:"rev"` - }{} - - fullCommit, err := fullCommit(options) - if err != nil { - return "", "", err - } - - path := d.dbName - if len(options) > 0 { - params, e := optionsToParams(options) - if e != nil { - return "", "", e - } - path += "?" + params.Encode() - } - - opts := &chttp.Options{ - Body: chttp.EncodeBody(doc), - FullCommit: fullCommit, - } - _, err = d.Client.DoJSON(ctx, http.MethodPost, path, opts, &result) - return result.ID, result.Rev, err -} - -func putOpts(doc interface{}, options map[string]interface{}) (*chttp.Options, error) { - fullCommit, err := fullCommit(options) - if err != nil { - return nil, err - } - params, err := optionsToParams(options) - if err != nil { - return nil, err - } - if _, ok := options[NoMultipartPut]; !ok { - if atts, ok := extractAttachments(doc); ok { - boundary, size, multipartBody, e := newMultipartAttachments(chttp.EncodeBody(doc), atts) - if e != nil { - return nil, e - } - return &chttp.Options{ - Body: multipartBody, - FullCommit: fullCommit, - Query: params, - ContentLength: size, - ContentType: fmt.Sprintf(typeMPRelated+"; boundary=%q", boundary), - }, nil - } - } - return &chttp.Options{ - Body: chttp.EncodeBody(doc), - FullCommit: fullCommit, - Query: params, - }, nil -} - -func (d *db) Put(ctx context.Context, docID string, doc interface{}, options map[string]interface{}) (rev string, err error) { - if docID == "" { - return "", missingArg("docID") - } - opts, err := putOpts(doc, options) - if err != nil { - return "", err - } - var result struct { - ID string `json:"id"` - Rev string `json:"rev"` - } - _, err = d.Client.DoJSON(ctx, http.MethodPut, d.path(chttp.EncodeDocID(docID)), opts, &result) - if err != nil { - return "", err - } - return result.Rev, nil -} - -const attachmentsKey = "_attachments" - -func extractAttachments(doc interface{}) (*kivik.Attachments, bool) { - if doc == nil { - return nil, false - } - v := reflect.ValueOf(doc) - if v.Type().Kind() == reflect.Ptr { - return extractAttachments(v.Elem().Interface()) - } - if stdMap, ok := doc.(map[string]interface{}); ok { - return interfaceToAttachments(stdMap[attachmentsKey]) - } - if v.Kind() != reflect.Struct { - return nil, false - } - for i := 0; i < v.NumField(); i++ { - if v.Type().Field(i).Tag.Get("json") == attachmentsKey { - return interfaceToAttachments(v.Field(i).Interface()) - } - } - return nil, false -} - -func interfaceToAttachments(i interface{}) (*kivik.Attachments, bool) { - switch t := i.(type) { - case kivik.Attachments: - atts := make(kivik.Attachments, len(t)) - for k, v := range t { - atts[k] = v - delete(t, k) - } - return &atts, true - case *kivik.Attachments: - atts := new(kivik.Attachments) - *atts = *t - *t = nil - return atts, true - } - return nil, false -} - -// newMultipartAttachments reads a json stream on in, and produces a -// multipart/related output suitable for a PUT request. -func newMultipartAttachments(in io.ReadCloser, att *kivik.Attachments) (boundary string, size int64, content io.ReadCloser, err error) { - tmp, err := ioutil.TempFile("", "kivik-multipart-*") - if err != nil { - return "", 0, nil, err - } - body := multipart.NewWriter(tmp) - w := sync.WaitGroup{} - w.Add(1) - go func() { - err = createMultipart(body, in, att) - e := in.Close() - if err == nil { - err = e - } - w.Done() - }() - w.Wait() - if e := tmp.Sync(); err == nil { - err = e - } - if info, e := tmp.Stat(); e == nil { - size = info.Size() - } else { - if err == nil { - err = e - } - } - if _, e := tmp.Seek(0, 0); e != nil && err == nil { - err = e - } - return body.Boundary(), - size, - tmp, - err -} - -func createMultipart(w *multipart.Writer, r io.ReadCloser, atts *kivik.Attachments) error { - doc, err := w.CreatePart(textproto.MIMEHeader{ - "Content-Type": {typeJSON}, - }) - if err != nil { - return err - } - attJSON := replaceAttachments(r, atts) - if _, e := io.Copy(doc, attJSON); e != nil { - return e - } - - // Sort the filenames to ensure order consistent with json.Marshal's ordering - // of the stubs in the body - filenames := make([]string, 0, len(*atts)) - for filename := range *atts { - filenames = append(filenames, filename) - } - sort.Strings(filenames) - - for _, filename := range filenames { - att := (*atts)[filename] - file, err := w.CreatePart(textproto.MIMEHeader{ - // "Content-Type": {att.ContentType}, - // "Content-Disposition": {fmt.Sprintf(`attachment; filename=%q`, filename)}, - // "Content-Length": {strconv.FormatInt(att.Size, 10)}, - }) - if err != nil { - return err - } - if _, err := io.Copy(file, att.Content); err != nil { - return err - } - _ = att.Content.Close() - } - - return w.Close() -} - -type lener interface { - Len() int -} - -type stater interface { - Stat() (os.FileInfo, error) -} - -// attachmentSize determines the size of the `in` stream by reading the entire -// stream first. This method is a no-op if att.Size is already > , and sets the Size -// parameter accordingly. If Size is already set, this function does nothing. -// It attempts the following methods: -// -// 1. Calls `Len()`, if implemented by `in` (i.e. `*bytes.Buffer`) -// 2. Calls `Stat()`, if implemented by `in` (i.e. `*os.File`) then returns -// the file's size -// 3. Read the entire stream to determine the size, and replace att.Content -// to be replayed. -func attachmentSize(att *kivik.Attachment) error { - if att.Size > 0 { - return nil - } - size, r, err := readerSize(att.Content) - if err != nil { - return err - } - rc, ok := r.(io.ReadCloser) - if !ok { - rc = ioutil.NopCloser(r) - } - - att.Content = rc - att.Size = size - return nil -} - -func readerSize(in io.Reader) (int64, io.Reader, error) { - if ln, ok := in.(lener); ok { - return int64(ln.Len()), in, nil - } - if st, ok := in.(stater); ok { - info, err := st.Stat() - if err != nil { - return 0, nil, err - } - return info.Size(), in, nil - } - content, err := ioutil.ReadAll(in) - if err != nil { - return 0, nil, err - } - buf := bytes.NewBuffer(content) - return int64(buf.Len()), ioutil.NopCloser(buf), nil -} - -// NewAttachment is a convenience function, which sets the size of the attachment -// based on content. This is intended for creating attachments to be uploaded -// using multipart/related capabilities of Put(). The attachment size will be -// set to the first of the following found: -// -// 1. `size`, if present. Only the first value is considered -// 2. content.Len(), if implemented (i.e. *bytes.Buffer) -// 3. content.Stat().Size(), if implemented (i.e. *os.File) -// 4. Read the entire content into memory, to determine the size. This can -// use a lot of memory for large attachments. Please use a file, or -// specify the size directly instead. -func NewAttachment(filename, contentType string, content io.Reader, size ...int64) (*kivik.Attachment, error) { - var filesize int64 - if len(size) > 0 { - filesize = size[0] - } else { - var err error - filesize, content, err = readerSize(content) - if err != nil { - return nil, err - } - } - rc, ok := content.(io.ReadCloser) - if !ok { - rc = ioutil.NopCloser(content) - } - return &kivik.Attachment{ - Filename: filename, - ContentType: contentType, - Content: rc, - Size: filesize, - }, nil -} - -// replaceAttachments reads a json stream on in, looking for the _attachments -// key, then replaces its value with the marshaled version of att. -func replaceAttachments(in io.ReadCloser, atts *kivik.Attachments) io.ReadCloser { - r, w := io.Pipe() - go func() { - stubs, err := attachmentStubs(atts) - if err != nil { - _ = w.CloseWithError(err) - _ = in.Close() - return - } - err = copyWithAttachmentStubs(w, in, stubs) - e := in.Close() - if err == nil { - err = e - } - _ = w.CloseWithError(err) - }() - return r -} - -type stub struct { - ContentType string `json:"content_type"` - Size int64 `json:"length"` -} - -func (s *stub) MarshalJSON() ([]byte, error) { - type attJSON struct { - stub - Follows bool `json:"follows"` - } - att := attJSON{ - stub: *s, - Follows: true, - } - return json.Marshal(att) -} - -func attachmentStubs(atts *kivik.Attachments) (map[string]*stub, error) { - if atts == nil { - return nil, nil - } - result := make(map[string]*stub, len(*atts)) - for filename, att := range *atts { - if err := attachmentSize(att); err != nil { - return nil, err - } - result[filename] = &stub{ - ContentType: att.ContentType, - Size: att.Size, - } - } - return result, nil -} - -// copyWithAttachmentStubs copies r to w, replacing the _attachment value with the -// marshaled version of atts. -func copyWithAttachmentStubs(w io.Writer, r io.Reader, atts map[string]*stub) error { - dec := json.NewDecoder(r) - t, err := dec.Token() - if err == nil { - if t != json.Delim('{') { - return &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: fmt.Errorf("expected '{', found '%v'", t)} - } - } - if err != nil { - if err != io.EOF { - return err - } - } - if _, err := fmt.Fprintf(w, "%v", t); err != nil { - return err - } - first := true - for { - t, err := dec.Token() - if err == io.EOF { - break - } - if err != nil { - return &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: err} - } - switch tp := t.(type) { - case string: - if !first { - if _, e := w.Write([]byte(",")); e != nil { - return e - } - } - first = false - if _, e := fmt.Fprintf(w, `"%s":`, tp); e != nil { - return e - } - var val json.RawMessage - if e := dec.Decode(&val); e != nil { - return e - } - if tp == attachmentsKey { - if e := json.NewEncoder(w).Encode(atts); e != nil { - return e - } - // Once we're here, we can just stream the rest of the input - // unaltered. - if _, e := io.Copy(w, dec.Buffered()); e != nil { - return e - } - _, e := io.Copy(w, r) - return e - } - if _, e := w.Write(val); e != nil { - return e - } - case json.Delim: - if tp != json.Delim('}') { - return fmt.Errorf("expected '}', found '%v'", t) - } - if _, err := fmt.Fprintf(w, "%v", t); err != nil { - return err - } - } - } - return nil -} - -func (d *db) Delete(ctx context.Context, docID, rev string, options map[string]interface{}) (string, error) { - if docID == "" { - return "", missingArg("docID") - } - if rev == "" { - return "", missingArg("rev") - } - - fullCommit, err := fullCommit(options) - if err != nil { - return "", err - } - - query, err := optionsToParams(options) - if err != nil { - return "", err - } - if query.Get("rev") == "" { - query.Set("rev", rev) - } - opts := &chttp.Options{ - FullCommit: fullCommit, - Query: query, - } - resp, err := d.Client.DoReq(ctx, http.MethodDelete, d.path(chttp.EncodeDocID(docID)), opts) - if err != nil { - return "", err - } - defer resp.Body.Close() // nolint: errcheck - return chttp.GetRev(resp) -} - -func (d *db) Flush(ctx context.Context) error { - opts := &chttp.Options{ - Header: http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - }, - } - _, err := d.Client.DoError(ctx, http.MethodPost, d.path("/_ensure_full_commit"), opts) - return err -} - -func (d *db) Compact(ctx context.Context) error { - opts := &chttp.Options{ - Header: http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - }, - } - res, err := d.Client.DoReq(ctx, http.MethodPost, d.path("/_compact"), opts) - if err != nil { - return err - } - return chttp.ResponseError(res) -} - -func (d *db) CompactView(ctx context.Context, ddocID string) error { - if ddocID == "" { - return missingArg("ddocID") - } - opts := &chttp.Options{ - Header: http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - }, - } - res, err := d.Client.DoReq(ctx, http.MethodPost, d.path("/_compact/"+ddocID), opts) - if err != nil { - return err - } - return chttp.ResponseError(res) -} - -func (d *db) ViewCleanup(ctx context.Context) error { - opts := &chttp.Options{ - Header: http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - }, - } - res, err := d.Client.DoReq(ctx, http.MethodPost, d.path("/_view_cleanup"), opts) - if err != nil { - return err - } - return chttp.ResponseError(res) -} - -func (d *db) Security(ctx context.Context) (*driver.Security, error) { - var sec *driver.Security - _, err := d.Client.DoJSON(ctx, http.MethodGet, d.path("/_security"), nil, &sec) - return sec, err -} - -func (d *db) SetSecurity(ctx context.Context, security *driver.Security) error { - opts := &chttp.Options{ - GetBody: chttp.BodyEncoder(security), - Header: http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - }, - } - res, err := d.Client.DoReq(ctx, http.MethodPut, d.path("/_security"), opts) - if err != nil { - return err - } - defer res.Body.Close() // nolint: errcheck - return chttp.ResponseError(res) -} - -func (d *db) Copy(ctx context.Context, targetID, sourceID string, options map[string]interface{}) (targetRev string, err error) { - if sourceID == "" { - return "", missingArg("sourceID") - } - if targetID == "" { - return "", missingArg("targetID") - } - fullCommit, err := fullCommit(options) - if err != nil { - return "", err - } - params, err := optionsToParams(options) - if err != nil { - return "", err - } - opts := &chttp.Options{ - FullCommit: fullCommit, - Query: params, - Header: http.Header{ - chttp.HeaderDestination: []string{targetID}, - }, - } - resp, err := d.Client.DoReq(ctx, "COPY", d.path(chttp.EncodeDocID(sourceID)), opts) - if err != nil { - return "", err - } - defer resp.Body.Close() // nolint: errcheck - return chttp.GetRev(resp) -} - -func (d *db) Purge(ctx context.Context, docMap map[string][]string) (*driver.PurgeResult, error) { - result := &driver.PurgeResult{} - options := &chttp.Options{ - GetBody: chttp.BodyEncoder(docMap), - Header: http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - }, - } - _, err := d.Client.DoJSON(ctx, http.MethodPost, d.path("_purge"), options, &result) - return result, err -} - -var _ driver.RevsDiffer = &db{} - -func (d *db) RevsDiff(ctx context.Context, revMap interface{}) (driver.Rows, error) { - options := &chttp.Options{ - GetBody: chttp.BodyEncoder(revMap), - Header: http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - }, - } - resp, err := d.Client.DoReq(ctx, http.MethodPost, d.path("_revs_diff"), options) - if err != nil { - return nil, err - } - if err = chttp.ResponseError(resp); err != nil { - return nil, err - } - return newRevsDiffRows(ctx, resp.Body), nil -} - -type revsDiffParser struct{} - -func (p *revsDiffParser) decodeItem(i interface{}, dec *json.Decoder) error { - t, err := dec.Token() - if err != nil { - return err - } - row := i.(*driver.Row) - row.ID = t.(string) - return dec.Decode(&row.Value) -} - -func newRevsDiffRows(ctx context.Context, in io.ReadCloser) driver.Rows { - iter := newIter(ctx, nil, "", in, &revsDiffParser{}) - iter.objMode = true - return &rows{iter: iter} -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/dbstats.go b/vendor/github.com/go-kivik/couchdb/v3/dbstats.go deleted file mode 100644 index 31af2d638..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/dbstats.go +++ /dev/null @@ -1,129 +0,0 @@ -package couchdb - -import ( - "bytes" - "context" - "encoding/json" - "net/http" - - "github.com/go-kivik/couchdb/v3/chttp" - "github.com/go-kivik/kivik/v3/driver" -) - -type dbStats struct { - driver.DBStats - Sizes struct { - File int64 `json:"file"` - External int64 `json:"external"` - Active int64 `json:"active"` - } `json:"sizes"` - UpdateSeq json.RawMessage `json:"update_seq"` // nolint: govet - rawBody json.RawMessage -} - -func (s *dbStats) UnmarshalJSON(p []byte) error { - type dbStatsClone dbStats - c := dbStatsClone(*s) - if err := json.Unmarshal(p, &c); err != nil { - return err - } - *s = dbStats(c) - s.rawBody = p - return nil -} - -func (s *dbStats) driverStats() *driver.DBStats { - stats := &s.DBStats - if s.Sizes.File > 0 { - stats.DiskSize = s.Sizes.File - } - if s.Sizes.External > 0 { - stats.ExternalSize = s.Sizes.External - } - if s.Sizes.Active > 0 { - stats.ActiveSize = s.Sizes.Active - } - stats.UpdateSeq = string(bytes.Trim(s.UpdateSeq, `"`)) - stats.RawResponse = s.rawBody - return stats -} - -func (d *db) Stats(ctx context.Context) (*driver.DBStats, error) { - result := dbStats{} - if _, err := d.Client.DoJSON(ctx, http.MethodGet, d.dbName, nil, &result); err != nil { - return nil, err - } - return result.driverStats(), nil -} - -type dbsInfoRequest struct { - Keys []string `json:"keys"` -} - -type dbsInfoResponse struct { - Key string `json:"key"` - DBInfo dbStats `json:"info"` - Error string `json:"error"` -} - -func (c *client) DBsStats(ctx context.Context, dbnames []string) ([]*driver.DBStats, error) { - opts := &chttp.Options{ - GetBody: chttp.BodyEncoder(dbsInfoRequest{Keys: dbnames}), - Header: http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - }, - } - result := []dbsInfoResponse{} - _, err := c.DoJSON(context.Background(), http.MethodPost, "/_dbs_info", opts, &result) - if err != nil { - return nil, err - } - stats := make([]*driver.DBStats, len(result)) - for i := range result { - if result[i].Error == "" { - stats[i] = result[i].DBInfo.driverStats() - } - } - return stats, nil -} - -type partitionStats struct { - DBName string `json:"db_name"` - DocCount int64 `json:"doc_count"` - DocDelCount int64 `json:"doc_del_count"` - Partition string `json:"partition"` - Sizes struct { - Active int64 `json:"active"` - External int64 `json:"external"` - } - rawBody json.RawMessage -} - -func (s *partitionStats) UnmarshalJSON(p []byte) error { - c := struct { - partitionStats - UnmarshalJSON struct{} - }{} - if err := json.Unmarshal(p, &c); err != nil { - return err - } - *s = c.partitionStats - s.rawBody = p - return nil -} - -func (d *db) PartitionStats(ctx context.Context, name string) (*driver.PartitionStats, error) { - result := partitionStats{} - if _, err := d.Client.DoJSON(ctx, http.MethodGet, d.path("_partition/"+name), nil, &result); err != nil { - return nil, err - } - return &driver.PartitionStats{ - DBName: result.DBName, - DocCount: result.DocCount, - DeletedDocCount: result.DocDelCount, - Partition: result.Partition, - ActiveSize: result.Sizes.Active, - ExternalSize: result.Sizes.External, - RawResponse: result.rawBody, - }, nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/doc.go b/vendor/github.com/go-kivik/couchdb/v3/doc.go deleted file mode 100644 index 04d533c45..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/doc.go +++ /dev/null @@ -1,106 +0,0 @@ -/* -Package couchdb is a driver for connecting with a CouchDB server over HTTP. - -General Usage - -Use the `couch` driver name when using this driver. The DSN should be a full -URL, likely with login credentials: - - import ( - kivik "github.com/go-kivik/kivik/v3" - _ "github.com/go-kivik/couchdb/v3" // The CouchDB driver - ) - - client, err := kivik.New("couch", "http://username:password@127.0.0.1:5984/") - -Options - -The CouchDB driver generally interprets kivik.Options keys and values as URL -query parameters. Values of the following types will be converted to their -appropriate string representation when URL-encoded: - - - bool - - string - - []string - - int, uint, uint8, uint16, uint32, uint64, int8, int16, int32, int64 - -Passing any other type will return an error. - -The only exceptions to the above rule are: - - - the special option keys defined by the package constants `OptionFullCommit` - and `OptionIfNoneMatch`. These options set the appropriate HTTP request - headers rather than setting a URL parameter. - - the `keys` key, when passed to a view query, will result in a POST query - being done, rather than a GET, to accommodate an arbitrary number of keys. - - the 'NoMultipartPut' option is interpreted by the Kivik CouchDB driver to - disable multipart/related PUT uploads of attachments. - - the 'NoMultipartGet' option is interpreted by the Kivik CouchDB driver to - disable multipart/related GET downloads of attachments. - -Authentication - -The CouchDB driver supports a number of authentication methods. For most uses, -you don't need to worry about authentication at all--just include authentication -credentials in your connection DSN: - - client, _ := kivik.New("couch", "http://user:password@localhost:5984/") - -This will use Cookie authentication by default. - -To use one of the explicit authentication mechanisms, you'll need to use kivik's -Authenticate method. For example: - - client, _ := kivik.New("couch", "http://localhost:5984/") - err := client.Authenticate(ctx, couchdb.BasicAuth("bob", "abc123")) - -Multipart PUT - -Normally, to include an attachment in a CouchDB document, it must be base-64 -encoded, which leads to increased network traffic and higher CPU load. CouchDB -also supports the option to upload multiple attachments in a single request -using the 'multipart/related' content type. See -http://docs.couchdb.org/en/stable/api/document/common.html#creating-multiple-attachments - -As an experimental feature, this is now supported by the Kivik CouchDB driver as -well. To take advantage of this capability, the `doc` argument to the Put() -method must be either: - - - a map of type `map[string]interface{}`, with a key called `_attachments', - and value of type `kivik.Attachments` or `*kivik.Attachments` - - a struct, with a field having the tag `json:"_attachment"`, and the field - having the type `kivik.Attachments` or `*kivik.Attachments`. - -With this in place, the CouchDB driver will switch to `multipart/related` mode, -sending each attachment in binary format, rather than base-64 encoding it. - -To function properly, each attachment must have an accurate Size value. If the -Size value is unset, the entirely attachment may be read to determine its size, -prior to sending it over the network, leading to delays and unnecessary I/O and -CPU usage. The simplest way to ensure efficiency is to use the NewAttachment() -method, provided by this package. See the documentation on that method for -proper usage. - -Example: - - file, _ := os.Open("/path/to/photo.jpg") - atts := &kivik.Attachments{ - "photo.jpg": NewAttachment("photo.jpg", "image/jpeg", file), - } - doc := map[string]interface{}{ - "_id": "user123", - "_attachments": atts, - } - rev, err := db.Put(ctx, "user123", doc) - -To disable the `multipart/related` capabilities entirely, you may pass the -`NoMultipartPut` option, with any value. This will fallback to the default of -inline base-64 encoding the attachments. Example: - - rev, err := db.Put(ctx, "user123", doc", kivik.Options{couchdb.NoMultipartPut: "xxx"}) - -If you find yourself wanting to disable this feature, due to bugs or performance, -please consider filing a bug report against Kivik as well, so we can look for a -solution that will allow using this optimization. -*/ -package couchdb diff --git a/vendor/github.com/go-kivik/couchdb/v3/errors.go b/vendor/github.com/go-kivik/couchdb/v3/errors.go deleted file mode 100644 index 96f13ac7d..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/errors.go +++ /dev/null @@ -1,12 +0,0 @@ -package couchdb - -import ( - "fmt" - "net/http" - - kivik "github.com/go-kivik/kivik/v3" -) - -func missingArg(arg string) error { - return &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: fmt.Errorf("kivik: %s required", arg)} -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/find.go b/vendor/github.com/go-kivik/couchdb/v3/find.go deleted file mode 100644 index 3cdfc8466..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/find.go +++ /dev/null @@ -1,149 +0,0 @@ -package couchdb - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "path" - - "github.com/go-kivik/couchdb/v3/chttp" - "github.com/go-kivik/kivik/v3/driver" -) - -const ( - pathIndex = "_index" -) - -func (d *db) CreateIndex(ctx context.Context, ddoc, name string, index interface{}, opts map[string]interface{}) error { - reqPath := pathIndex - if part, ok := opts[OptionPartition].(string); ok { - delete(opts, OptionPartition) - reqPath = path.Join("_partition", part, reqPath) - } - indexObj, err := deJSONify(index) - if err != nil { - return err - } - parameters := struct { - Index interface{} `json:"index"` - Ddoc string `json:"ddoc,omitempty"` - Name string `json:"name,omitempty"` - }{ - Index: indexObj, - Ddoc: ddoc, - Name: name, - } - options := &chttp.Options{ - Body: chttp.EncodeBody(parameters), - } - _, err = d.Client.DoError(ctx, http.MethodPost, d.path(reqPath), options) - return err -} - -func (d *db) GetIndexes(ctx context.Context, opts map[string]interface{}) ([]driver.Index, error) { - reqPath := pathIndex - if part, ok := opts[OptionPartition].(string); ok { - delete(opts, OptionPartition) - reqPath = path.Join("_partition", part, reqPath) - } - var result struct { - Indexes []driver.Index `json:"indexes"` - } - _, err := d.Client.DoJSON(ctx, http.MethodGet, d.path(reqPath), nil, &result) - return result.Indexes, err -} - -func (d *db) DeleteIndex(ctx context.Context, ddoc, name string, opts map[string]interface{}) error { - if ddoc == "" { - return missingArg("ddoc") - } - if name == "" { - return missingArg("name") - } - reqPath := pathIndex - if part, ok := opts[OptionPartition].(string); ok { - delete(opts, OptionPartition) - reqPath = path.Join("_partition", part, reqPath) - } - path := fmt.Sprintf("%s/%s/json/%s", reqPath, ddoc, name) - _, err := d.Client.DoError(ctx, http.MethodDelete, d.path(path), nil) - return err -} - -func (d *db) Find(ctx context.Context, query interface{}, opts map[string]interface{}) (driver.Rows, error) { - reqPath := "_find" - if part, ok := opts[OptionPartition].(string); ok { - delete(opts, OptionPartition) - reqPath = path.Join("_partition", part, reqPath) - } - options := &chttp.Options{ - GetBody: chttp.BodyEncoder(query), - Header: http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - }, - } - resp, err := d.Client.DoReq(ctx, http.MethodPost, d.path(reqPath), options) - if err != nil { - return nil, err - } - if err = chttp.ResponseError(resp); err != nil { - return nil, err - } - return newFindRows(ctx, resp.Body), nil -} - -type queryPlan struct { - DBName string `json:"dbname"` - Index map[string]interface{} `json:"index"` - Selector map[string]interface{} `json:"selector"` - Options map[string]interface{} `json:"opts"` - Limit int64 `json:"limit"` - Skip int64 `json:"skip"` - Fields fields `json:"fields"` - Range map[string]interface{} `json:"range"` -} - -type fields []interface{} - -func (f *fields) UnmarshalJSON(data []byte) error { - if string(data) == `"all_fields"` { - return nil - } - var i []interface{} - if err := json.Unmarshal(data, &i); err != nil { - return err - } - newFields := make([]interface{}, len(i)) - copy(newFields, i) - *f = newFields - return nil -} - -func (d *db) Explain(ctx context.Context, query interface{}, opts map[string]interface{}) (*driver.QueryPlan, error) { - reqPath := "_explain" - if part, ok := opts[OptionPartition].(string); ok { - delete(opts, OptionPartition) - reqPath = path.Join("_partition", part, reqPath) - } - options := &chttp.Options{ - GetBody: chttp.BodyEncoder(query), - Header: http.Header{ - chttp.HeaderIdempotencyKey: []string{}, - }, - } - var plan queryPlan - if _, err := d.Client.DoJSON(ctx, http.MethodPost, d.path(reqPath), options, &plan); err != nil { - return nil, err - } - return &driver.QueryPlan{ - DBName: plan.DBName, - Index: plan.Index, - Selector: plan.Selector, - Options: plan.Options, - Limit: plan.Limit, - Skip: plan.Skip, - Fields: plan.Fields, - Range: plan.Range, - }, nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/iter.go b/vendor/github.com/go-kivik/couchdb/v3/iter.go deleted file mode 100644 index 07eaefa8e..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/iter.go +++ /dev/null @@ -1,300 +0,0 @@ -package couchdb - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "io" - "net/http" - "sync" - "sync/atomic" - - kivik "github.com/go-kivik/kivik/v3" -) - -type parser interface { - decodeItem(interface{}, *json.Decoder) error -} - -type metaParser interface { - parseMeta(interface{}, *json.Decoder, string) error -} - -type cancelableReadCloser struct { - ctx context.Context - rc io.ReadCloser - cancel func() - - mu sync.RWMutex - closed bool - err error -} - -var _ io.ReadCloser = &cancelableReadCloser{} - -func newCancelableReadCloser(ctx context.Context, rc io.ReadCloser) io.ReadCloser { - ctx, cancel := context.WithCancel(ctx) - return &cancelableReadCloser{ - ctx: ctx, - rc: rc, - cancel: cancel, - } -} - -func (r *cancelableReadCloser) readErr() error { - r.mu.RLock() - if !r.closed { - r.mu.RUnlock() - return nil - } - err := r.err - r.mu.RUnlock() - if err == nil { - err = errors.New("iterator closed") - } - return err -} - -func (r *cancelableReadCloser) Read(p []byte) (int, error) { - if err := r.readErr(); err != nil { - return 0, err - } - var c int - var err error - done := make(chan struct{}) - go func() { - c, err = r.rc.Read(p) - close(done) - }() - select { - case <-r.ctx.Done(): - var err error - if err = r.readErr(); err == nil { - err = r.ctx.Err() - } - return 0, r.close(err) - case <-done: - if err != nil { - e := r.close(err) - return c, e - } - return c, nil - } -} - -func (r *cancelableReadCloser) close(err error) error { - r.mu.Lock() - defer r.mu.Unlock() - if !r.closed { - r.cancel() - r.closed = true - e := r.rc.Close() - if err == nil { - err = e - } - r.err = err - } - return r.err -} - -func (r *cancelableReadCloser) Close() error { - err := r.close(nil) - if err == io.EOF { - return nil - } - return err -} - -type iter struct { - meta interface{} - expectedKey string - body io.ReadCloser - parser parser - - // objMode enables reading one object at a time, with the ID treated as the - // docid. This was added for the _revs_diff endpoint. - objMode bool - - dec *json.Decoder - closed int32 -} - -func newIter(ctx context.Context, meta interface{}, expectedKey string, body io.ReadCloser, parser parser) *iter { - return &iter{ - meta: meta, - expectedKey: expectedKey, - body: newCancelableReadCloser(ctx, body), - parser: parser, - } -} - -func (i *iter) next(row interface{}) error { - if atomic.LoadInt32(&i.closed) == 1 { - return io.EOF - } - if i.dec == nil { - // We haven't begun yet - i.dec = json.NewDecoder(i.body) - if err := i.begin(); err != nil { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - } - - err := i.nextRow(row) - if err != nil { - if err == io.EOF { - if e := i.finish(); e != nil { - err = e - } - return err - } - } - return err -} - -// begin parses the top-level of the result object; until rows -func (i *iter) begin() error { - if i.expectedKey == "" && !i.objMode { - return nil - } - // consume the first '{' - if err := consumeDelim(i.dec, json.Delim('{')); err != nil { - return err - } - if i.objMode { - return nil - } - for { - key, err := nextKey(i.dec) - if err != nil { - return err - } - if key == i.expectedKey { - // Consume the first '[' - return consumeDelim(i.dec, json.Delim('[')) - } - if err := i.parseMeta(key); err != nil { - return err - } - } -} - -func nextKey(dec *json.Decoder) (string, error) { - t, err := dec.Token() - if err != nil { - // I can't find a test case to trigger this, so it remains uncovered. - return "", err - } - key, ok := t.(string) - if !ok { - // The JSON parser should never permit this - return "", fmt.Errorf("Unexpected token: (%T) %v", t, t) - } - return key, nil -} - -func (i *iter) parseMeta(key string) error { - if i.meta == nil { - return nil - } - if mp, ok := i.parser.(metaParser); ok { - return mp.parseMeta(i.meta, i.dec, key) - } - return nil -} - -func (i *iter) finish() (err error) { - defer func() { - e2 := i.Close() - if err == nil { - err = e2 - } - }() - if i.expectedKey == "" && !i.objMode { - _, err := i.dec.Token() - if err != nil && err != io.EOF { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - return nil - } - if i.objMode { - err := consumeDelim(i.dec, json.Delim('}')) - if err != nil && err != io.EOF { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - return nil - } - if err := consumeDelim(i.dec, json.Delim(']')); err != nil { - return err - } - for i.dec.More() { - t, err := i.dec.Token() - if err != nil { - return err - } - switch v := t.(type) { - case json.Delim: - if v != json.Delim('}') { - // This should never happen, as the JSON parser should prevent it. - return fmt.Errorf("Unexpected JSON delimiter: %c", v) - } - case string: - if err := i.parseMeta(v); err != nil { - return err - } - default: - // This should never happen, as the JSON parser would never get - // this far. - return fmt.Errorf("Unexpected JSON token: (%T) '%s'", t, t) - } - } - return consumeDelim(i.dec, json.Delim('}')) - // return nil -} - -func (i *iter) nextRow(row interface{}) error { - if !i.dec.More() { - return io.EOF - } - return i.parser.decodeItem(row, i.dec) -} - -func (i *iter) Close() error { - atomic.StoreInt32(&i.closed, 1) - // body will be nil if we're iterating over a multi-query resultset. - if i.body == nil { - return nil - } - return i.body.Close() -} - -// consumeDelim consumes the expected delimiter from the stream, or returns an -// error if an unexpected token was found. -func consumeDelim(dec *json.Decoder, expectedDelim json.Delim) error { - t, err := dec.Token() - if err != nil { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - d, ok := t.(json.Delim) - if !ok { - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: fmt.Errorf("Unexpected token %T: %v", t, t)} - } - if d != expectedDelim { - return unexpectedDelim(d) - } - return nil -} - -// unexpectedDelim is used to indicate to the multiQueriesRows type that the -// end of input has been reached, while behaving as an unexpected delimter -// error to all other code. -type unexpectedDelim byte - -func (d unexpectedDelim) Error() string { - return fmt.Sprintf("Unexpected JSON delimiter: %c", d) -} - -func (d unexpectedDelim) StatusCode() int { - return http.StatusBadGateway -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/json.go b/vendor/github.com/go-kivik/couchdb/v3/json.go deleted file mode 100644 index e25377be5..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/json.go +++ /dev/null @@ -1,35 +0,0 @@ -package couchdb - -import ( - "encoding/json" - "net/http" - - kivik "github.com/go-kivik/kivik/v3" -) - -// encodeKey encodes a key to a view query, or similar, to be passed to CouchDB. -func encodeKey(i interface{}) (string, error) { - if raw, ok := i.(json.RawMessage); ok { - return string(raw), nil - } - raw, err := json.Marshal(i) - if err != nil { - err = &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: err} - } - return string(raw), err -} - -var jsonKeys = []string{"endkey", "end_key", "key", "startkey", "start_key", "keys", "doc_ids"} - -func encodeKeys(opts map[string]interface{}) error { - for _, key := range jsonKeys { - if v, ok := opts[key]; ok { - new, err := encodeKey(v) - if err != nil { - return err - } - opts[key] = new - } - } - return nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/options.go b/vendor/github.com/go-kivik/couchdb/v3/options.go deleted file mode 100644 index 4ec334023..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/options.go +++ /dev/null @@ -1,37 +0,0 @@ -package couchdb - -import ( - "fmt" - "net/http" - - kivik "github.com/go-kivik/kivik/v3" -) - -func fullCommit(opts map[string]interface{}) (bool, error) { - fc, ok := opts[OptionFullCommit] - if !ok { - return false, nil - } - fcBool, ok := fc.(bool) - if !ok { - return false, &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: fmt.Errorf("kivik: option '%s' must be bool, not %T", OptionFullCommit, fc)} - } - delete(opts, OptionFullCommit) - return fcBool, nil -} - -func ifNoneMatch(opts map[string]interface{}) (string, error) { - inm, ok := opts[OptionIfNoneMatch] - if !ok { - return "", nil - } - inmString, ok := inm.(string) - if !ok { - return "", &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: fmt.Errorf("kivik: option '%s' must be string, not %T", OptionIfNoneMatch, inm)} - } - delete(opts, OptionIfNoneMatch) - if inmString[0] != '"' { - return `"` + inmString + `"`, nil - } - return inmString, nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/replication.go b/vendor/github.com/go-kivik/couchdb/v3/replication.go deleted file mode 100644 index 8ae09f01e..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/replication.go +++ /dev/null @@ -1,319 +0,0 @@ -package couchdb - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "net/http" - "strconv" - "strings" - "sync" - "time" - - "github.com/go-kivik/couchdb/v3/chttp" - kivik "github.com/go-kivik/kivik/v3" - "github.com/go-kivik/kivik/v3/driver" -) - -type replicationError struct { - status int - reason string -} - -func (re *replicationError) Error() string { - return re.reason -} - -func (re *replicationError) StatusCode() int { - return re.status -} - -func (re *replicationError) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &re.reason); err != nil { - return err - } - switch (strings.SplitN(re.reason, ":", 2))[0] { - case "db_not_found": - re.status = http.StatusNotFound - case "timeout": - re.status = http.StatusRequestTimeout - case "unauthorized": - re.status = http.StatusUnauthorized - default: - re.status = http.StatusInternalServerError - } - return nil -} - -type replicationStateTime time.Time - -func (t *replicationStateTime) UnmarshalJSON(data []byte) error { - input := string(bytes.Trim(data, `"`)) - if ts, err := time.Parse(time.RFC3339, input); err == nil { - *t = replicationStateTime(ts) - return nil - } - // Fallback for really old versions of CouchDB - if seconds, err := strconv.ParseInt(input, 10, 64); err == nil { - epochTime := replicationStateTime(time.Unix(seconds, 0).UTC()) - *t = epochTime - return nil - } - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: fmt.Errorf("kivik: '%s' does not appear to be a valid timestamp", string(data))} -} - -type replication struct { - docID string - replicationID string - source string - target string - startTime time.Time - endTime time.Time - state string - err error - - // mu protects the above values - mu sync.RWMutex - - *db -} - -var _ driver.Replication = &replication{} - -func (c *client) fetchReplication(ctx context.Context, docID string) *replication { - rep := c.newReplication(docID) - rep.db = &db{client: c, dbName: "_replicator"} - // Do an update to get the initial state, but don't fail if there's an error - // at this stage, because we successfully created the replication doc. - _ = rep.updateMain(ctx) - return rep -} - -func (c *client) newReplication(docID string) *replication { - return &replication{ - docID: docID, - db: &db{ - client: c, - dbName: "_replicator", - }, - } -} - -func (r *replication) readLock() func() { - r.mu.RLock() - return r.mu.RUnlock -} - -func (r *replication) ReplicationID() string { defer r.readLock()(); return r.replicationID } -func (r *replication) Source() string { defer r.readLock()(); return r.source } -func (r *replication) Target() string { defer r.readLock()(); return r.target } -func (r *replication) StartTime() time.Time { defer r.readLock()(); return r.startTime } -func (r *replication) EndTime() time.Time { defer r.readLock()(); return r.endTime } -func (r *replication) State() string { defer r.readLock()(); return r.state } -func (r *replication) Err() error { defer r.readLock()(); return r.err } - -func (r *replication) Update(ctx context.Context, state *driver.ReplicationInfo) error { - if err := r.updateMain(ctx); err != nil { - return err - } - if r.State() == "complete" { - state.Progress = 100 - return nil - } - info, err := r.updateActiveTasks(ctx) - if err != nil { - if kivik.StatusCode(err) == http.StatusNotFound { - // not listed in _active_tasks (because the replication is done, or - // hasn't yet started), but this isn't an error - return nil - } - return err - } - state.DocWriteFailures = info.DocWriteFailures - state.DocsRead = info.DocsRead - state.DocsWritten = info.DocsWritten - // state.progress = info.Progress - return nil -} - -type activeTask struct { - Type string `json:"type"` - ReplicationID string `json:"replication_id"` - DocsWritten int64 `json:"docs_written"` - DocsRead int64 `json:"docs_read"` - DocWriteFailures int64 `json:"doc_write_failures"` -} - -func (r *replication) updateActiveTasks(ctx context.Context) (*activeTask, error) { - resp, err := r.client.DoReq(ctx, http.MethodGet, "/_active_tasks", nil) - if err != nil { - return nil, err - } - if err = chttp.ResponseError(resp); err != nil { - return nil, err - } - defer func() { _ = resp.Body.Close() }() - var tasks []*activeTask - if err = json.NewDecoder(resp.Body).Decode(&tasks); err != nil { - return nil, &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: err} - } - for _, task := range tasks { - if task.Type != "replication" { - continue - } - repIDparts := strings.SplitN(task.ReplicationID, "+", 2) - if repIDparts[0] != r.replicationID { - continue - } - return task, nil - } - return nil, &kivik.Error{HTTPStatus: http.StatusNotFound, Err: errors.New("task not found")} -} - -// updateMain updates the "main" fields: those stored directly in r. -func (r *replication) updateMain(ctx context.Context) error { - doc, err := r.getReplicatorDoc(ctx) - if err != nil { - return err - } - r.setFromReplicatorDoc(doc) - return nil -} - -func (r *replication) getReplicatorDoc(ctx context.Context) (*replicatorDoc, error) { - row, err := r.db.Get(ctx, r.docID, nil) - if err != nil { - return nil, err - } - var doc replicatorDoc - err = json.NewDecoder(row.Body).Decode(&doc) - return &doc, err -} - -func (r *replication) setFromReplicatorDoc(doc *replicatorDoc) { - r.mu.Lock() - defer r.mu.Unlock() - switch kivik.ReplicationState(doc.State) { - case kivik.ReplicationStarted: - r.startTime = time.Time(doc.StateTime) - case kivik.ReplicationError, kivik.ReplicationComplete: - r.endTime = time.Time(doc.StateTime) - } - r.state = doc.State - if doc.Error != nil { - r.err = doc.Error - } else { - r.err = nil - } - if r.source == "" { - r.source = doc.Source - } - if r.target == "" { - r.target = doc.Target - } - if r.replicationID == "" { - r.replicationID = doc.ReplicationID - } -} - -func (r *replication) Delete(ctx context.Context) error { - _, rev, err := r.GetMeta(ctx, r.docID, nil) - if err != nil { - return err - } - _, err = r.db.Delete(ctx, r.docID, rev, nil) - return err -} - -type replicatorDoc struct { - DocID string `json:"_id"` - ReplicationID string `json:"_replication_id"` - Source string `json:"source"` - Target string `json:"target"` - State string `json:"_replication_state"` - StateTime replicationStateTime `json:"_replication_state_time"` - Error *replicationError `json:"_replication_state_reason,omitempty"` -} - -func (c *client) GetReplications(ctx context.Context, options map[string]interface{}) ([]driver.Replication, error) { - scheduler, err := c.schedulerSupported(ctx) - if err != nil { - return nil, err - } - if scheduler { - return c.getReplicationsFromScheduler(ctx, options) - } - return c.legacyGetReplications(ctx, options) -} - -func (c *client) legacyGetReplications(ctx context.Context, options map[string]interface{}) ([]driver.Replication, error) { - if options == nil { - options = map[string]interface{}{} - } - delete(options, "conflicts") - delete(options, "update_seq") - options["include_docs"] = true - params, err := optionsToParams(options) - if err != nil { - return nil, err - } - var result struct { - Rows []struct { - Doc replicatorDoc `json:"doc"` - } `json:"rows"` - } - path := "/_replicator/_all_docs?" + params.Encode() - if _, err = c.DoJSON(ctx, http.MethodGet, path, nil, &result); err != nil { - return nil, err - } - reps := make([]driver.Replication, 0, len(result.Rows)) - for _, row := range result.Rows { - if row.Doc.DocID == "_design/_replicator" { - continue - } - rep := c.newReplication(row.Doc.DocID) - rep.setFromReplicatorDoc(&row.Doc) - reps = append(reps, rep) - } - return reps, nil -} - -func (c *client) Replicate(ctx context.Context, targetDSN, sourceDSN string, options map[string]interface{}) (driver.Replication, error) { - if options == nil { - options = make(map[string]interface{}) - } - // Allow overriding source and target with options, i.e. for auth options - if _, ok := options["source"]; !ok { - options["source"] = sourceDSN - } - if _, ok := options["target"]; !ok { - options["target"] = targetDSN - } - if t := options["target"]; t == "" { - return nil, missingArg("targetDSN") - } - if s := options["source"]; s == "" { - return nil, missingArg("sourceDSN") - } - - scheduler, err := c.schedulerSupported(ctx) - if err != nil { - return nil, err - } - opts := &chttp.Options{ - Body: chttp.EncodeBody(options), - } - - var repStub struct { - ID string `json:"id"` - } - if _, e := c.Client.DoJSON(ctx, http.MethodPost, "/_replicator", opts, &repStub); e != nil { - return nil, e - } - if scheduler { - return c.fetchSchedulerReplication(ctx, repStub.ID) - } - return c.fetchReplication(ctx, repStub.ID), nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/rows.go b/vendor/github.com/go-kivik/couchdb/v3/rows.go deleted file mode 100644 index 09f1faf65..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/rows.go +++ /dev/null @@ -1,281 +0,0 @@ -package couchdb - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net/http" - "strings" - "sync/atomic" - - kivik "github.com/go-kivik/kivik/v3" - "github.com/go-kivik/kivik/v3/driver" -) - -type rowsMeta struct { - offset int64 - totalRows int64 - updateSeq sequenceID - warning string - bookmark string -} - -type rows struct { - *iter - *rowsMeta -} - -var _ driver.Rows = &rows{} - -type rowsMetaParser struct{} - -func (p *rowsMetaParser) parseMeta(i interface{}, dec *json.Decoder, key string) error { - meta := i.(*rowsMeta) - return meta.parseMeta(key, dec) -} - -type rowParser struct { - rowsMetaParser -} - -var _ parser = &rowParser{} - -func (p *rowParser) decodeItem(i interface{}, dec *json.Decoder) error { - return dec.Decode(i) -} - -func newRows(ctx context.Context, in io.ReadCloser) driver.Rows { - meta := &rowsMeta{} - return &rows{ - iter: newIter(ctx, meta, "rows", in, &rowParser{}), - rowsMeta: meta, - } -} - -type findParser struct { - rowsMetaParser -} - -var _ parser = &findParser{} - -func (p *findParser) decodeItem(i interface{}, dec *json.Decoder) error { - row := i.(*driver.Row) - return dec.Decode(&row.Doc) -} - -func newFindRows(ctx context.Context, in io.ReadCloser) driver.Rows { - meta := &rowsMeta{} - return &rows{ - iter: newIter(ctx, meta, "docs", in, &findParser{}), - rowsMeta: meta, - } -} - -type bulkParser struct { - rowsMetaParser -} - -var _ parser = &bulkParser{} - -func (p *bulkParser) decodeItem(i interface{}, dec *json.Decoder) error { - row := i.(*driver.Row) - var result bulkResult - if err := dec.Decode(&result); err != nil { - return err - } - row.ID = result.ID - row.Doc = result.Docs[0].Doc - row.Error = nil - if err := result.Docs[0].Error; err != nil { - row.Error = err - } - return nil -} - -func newBulkGetRows(ctx context.Context, in io.ReadCloser) driver.Rows { - meta := &rowsMeta{} - return &rows{ - iter: newIter(ctx, meta, "results", in, &bulkParser{}), - rowsMeta: meta, - } -} - -func (r *rows) Offset() int64 { - return r.offset -} - -func (r *rows) TotalRows() int64 { - return r.totalRows -} - -func (r *rows) Warning() string { - return r.warning -} - -func (r *rows) Bookmark() string { - return r.bookmark -} - -func (r *rows) UpdateSeq() string { - return string(r.updateSeq) -} - -func (r *rows) Next(row *driver.Row) error { - row.Error = nil - return r.iter.next(row) -} - -// parseMeta parses result metadata -func (r *rowsMeta) parseMeta(key string, dec *json.Decoder) error { - switch key { - case "update_seq": - return dec.Decode(&r.updateSeq) - case "offset": - return dec.Decode(&r.offset) - case "total_rows": - return dec.Decode(&r.totalRows) - case "warning": - return dec.Decode(&r.warning) - case "bookmark": - return dec.Decode(&r.bookmark) - } - return &kivik.Error{HTTPStatus: http.StatusBadGateway, Err: fmt.Errorf("Unexpected key: %s", key)} -} - -func newMultiQueriesRows(ctx context.Context, in io.ReadCloser) driver.Rows { - return &multiQueriesRows{ - ctx: ctx, - r: in, - } -} - -type multiQueriesRows struct { - *rows - ctx context.Context - r io.ReadCloser - dec *json.Decoder - queryIndex int - closed int32 - - // legacy indicates this is an old-style iterator, and won't have more than - // one resultset. - legacy int32 -} - -func (r *multiQueriesRows) Next(row *driver.Row) error { - if atomic.LoadInt32(&r.closed) == 1 { - return io.EOF - } - if r.rows != nil && atomic.LoadInt32(&r.rows.closed) == 1 { - if err := r.nextQuery(); err != nil { - return err - } - } - if r.dec == nil { - if err := r.begin(); err != nil { - return err - } - } - if err := r.rows.Next(row); err != nil { - if err == io.EOF && atomic.LoadInt32(&r.legacy) == 0 { - return driver.EOQ - } - return err - } - return nil -} - -func (r *multiQueriesRows) begin() error { - r.dec = json.NewDecoder(r.r) - // consume the first '{' - if err := consumeDelim(r.dec, json.Delim('{')); err != nil { - return err - } - key, err := nextKey(r.dec) - if err != nil { - return err - } - if key != "results" { - // These indicate the server does not support multiple queries; probably - // an old version. Fall back to the standard iterator. - atomic.StoreInt32(&r.legacy, 1) - keyJSON, _ := json.Marshal(key) - var in io.ReadCloser = struct { - io.Reader - io.Closer - }{ - Reader: io.MultiReader( - strings.NewReader("{"), - bytes.NewReader(keyJSON), - r.dec.Buffered(), - r.r), - Closer: r.r, - } - r.rows = newRows(r.ctx, in).(*rows) - r.rows.body = nil - r.rows.dec = json.NewDecoder(in) - return r.rows.begin() - } - // consume the opening '[' - if err := consumeDelim(r.dec, json.Delim('[')); err != nil { - return err - } - r.rows = newRows(r.ctx, r.r).(*rows) - r.rows.body = nil - r.rows.iter.dec = r.dec - return r.rows.iter.begin() -} - -func (r *multiQueriesRows) nextQuery() error { - if atomic.LoadInt32(&r.legacy) == 1 { - if err := r.Close(); err != nil { - return err - } - return io.EOF - } - rows := newRows(r.ctx, r.r).(*rows) - rows.iter.dec = r.dec - if err := rows.iter.begin(); err != nil { - // I'd normally use errors.As, but I want to retain backward - // compatibility to at least Go 1.11. - if ud, _ := err.(unexpectedDelim); ud == unexpectedDelim(']') { - if err := r.Close(); err != nil { - return err - } - return io.EOF - } - return err - } - r.queryIndex++ - r.rows = rows - r.rows.body = nil - return nil -} - -func (r *multiQueriesRows) Close() error { - if atomic.AddInt32(&r.closed, 1) > 1 { - return nil - } - r.dec = nil - if r.rows != nil { - defer r.rows.Close() // nolint:errcheck - } - defer r.r.Close() // nolint:errcheck - if _, err := ioutil.ReadAll(r.r); err != nil { - return err - } - if err := r.r.Close(); err != nil { - return err - } - if r.rows == nil { - return nil - } - return r.rows.Close() -} - -func (r *multiQueriesRows) QueryIndex() int { - return r.queryIndex -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/scheduler.go b/vendor/github.com/go-kivik/couchdb/v3/scheduler.go deleted file mode 100644 index 9f41fbf25..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/scheduler.go +++ /dev/null @@ -1,235 +0,0 @@ -package couchdb - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "net/http" - "time" - - "github.com/go-kivik/couchdb/v3/chttp" - "github.com/go-kivik/kivik/v3/driver" -) - -type schedulerDoc struct { - Database string `json:"database"` - DocID string `json:"doc_id"` - ReplicationID string `json:"id"` - Source string `json:"source"` - Target string `json:"target"` - StartTime time.Time `json:"start_time"` - LastUpdated time.Time `json:"last_updated"` - State string `json:"state"` - Info repInfo `json:"info"` -} - -type repInfo struct { - Error error - DocsRead int64 `json:"docs_read"` - DocsWritten int64 `json:"docs_written"` - DocWriteFailures int64 `json:"doc_write_failures"` - Pending int64 `json:"changes_pending"` -} - -func (i *repInfo) UnmarshalJSON(data []byte) error { - switch { - case string(data) == "null": - return nil - case bytes.HasPrefix(data, []byte(`{"error":`)): - var e struct { - Error *replicationError `json:"error"` - } - if err := json.Unmarshal(data, &e); err != nil { - return err - } - i.Error = e.Error - case data[0] == '{': - type repInfoClone repInfo - var x repInfoClone - if err := json.Unmarshal(data, &x); err != nil { - return err - } - *i = repInfo(x) - default: - var e replicationError - if err := json.Unmarshal(data, &e); err != nil { - return err - } - i.Error = &e - } - return nil -} - -type schedulerReplication struct { - docID string - database string - replicationID string - source string - target string - startTime time.Time - lastUpdated time.Time - state string - info repInfo - - *db -} - -var _ driver.Replication = &schedulerReplication{} - -func (c *client) schedulerSupported(ctx context.Context) (bool, error) { - c.sdMU.Lock() - defer c.sdMU.Unlock() - if c.schedulerDetected != nil { - return *c.schedulerDetected, nil - } - resp, err := c.DoReq(ctx, http.MethodHead, "_scheduler/jobs", nil) - if err != nil { - return false, err - } - var supported bool - switch resp.StatusCode { - case http.StatusBadRequest: - // 1.6.x, 1.7.x - supported = false - case http.StatusNotFound: - // 2.0.x - supported = false - case http.StatusOK, http.StatusUnauthorized: - // 2.1.x + - supported = true - default: - // Assume not supported - supported = false - } - c.schedulerDetected = &supported - return supported, nil -} - -func (c *client) newSchedulerReplication(doc *schedulerDoc) *schedulerReplication { - rep := &schedulerReplication{ - db: &db{ - client: c, - dbName: doc.Database, - }, - } - rep.setFromDoc(doc) - return rep -} - -func (r *schedulerReplication) setFromDoc(doc *schedulerDoc) { - if r.source == "" { - r.docID = doc.DocID - r.database = doc.Database - r.replicationID = doc.ReplicationID - r.source = doc.Source - r.target = doc.Target - r.startTime = doc.StartTime - } - r.lastUpdated = doc.LastUpdated - r.state = doc.State - r.info = doc.Info -} - -func (c *client) fetchSchedulerReplication(ctx context.Context, docID string) (*schedulerReplication, error) { - rep := &schedulerReplication{ - docID: docID, - database: "_replicator", - db: &db{ - client: c, - dbName: "_replicator", - }, - } - for rep.source == "" { - if err := rep.update(ctx); err != nil { - return rep, err - } - time.Sleep(100 * time.Millisecond) - } - return rep, nil -} - -func (r *schedulerReplication) StartTime() time.Time { return r.startTime } -func (r *schedulerReplication) EndTime() time.Time { - if r.state == "failed" || r.state == "completed" { - return r.lastUpdated - } - return time.Time{} -} -func (r *schedulerReplication) Err() error { return r.info.Error } -func (r *schedulerReplication) ReplicationID() string { return r.replicationID } -func (r *schedulerReplication) Source() string { return r.source } -func (r *schedulerReplication) Target() string { return r.target } -func (r *schedulerReplication) State() string { return r.state } - -func (r *schedulerReplication) Update(ctx context.Context, rep *driver.ReplicationInfo) error { - if err := r.update(ctx); err != nil { - return err - } - rep.DocWriteFailures = r.info.DocWriteFailures - rep.DocsRead = r.info.DocsRead - rep.DocsWritten = r.info.DocsWritten - return nil -} - -func (r *schedulerReplication) Delete(ctx context.Context) error { - _, rev, err := r.GetMeta(ctx, r.docID, nil) - if err != nil { - return err - } - _, err = r.db.Delete(ctx, r.docID, rev, nil) - return err -} - -// isBug1000 detects a race condition bug in CouchDB 2.1.x so the attempt can -// be retried. See https://github.com/apache/couchdb/issues/1000 -func isBug1000(err error) bool { - if err == nil { - return false - } - cerr, ok := err.(*chttp.HTTPError) - if !ok { - // should never happen - return false - } - if cerr.Response.StatusCode != http.StatusInternalServerError { - return false - } - return cerr.Reason == "function_clause" -} - -func (r *schedulerReplication) update(ctx context.Context) error { - path := fmt.Sprintf("/_scheduler/docs/%s/%s", r.database, chttp.EncodeDocID(r.docID)) - var doc schedulerDoc - if _, err := r.db.Client.DoJSON(ctx, http.MethodGet, path, nil, &doc); err != nil { - if isBug1000(err) { - return r.update(ctx) - } - return err - } - r.setFromDoc(&doc) - return nil -} - -func (c *client) getReplicationsFromScheduler(ctx context.Context, options map[string]interface{}) ([]driver.Replication, error) { - params, err := optionsToParams(options) - if err != nil { - return nil, err - } - var result struct { - Docs []schedulerDoc `json:"docs"` - } - path := "/_scheduler/docs" - if params != nil { - path = path + "?" + params.Encode() - } - if _, err = c.DoJSON(ctx, http.MethodGet, path, nil, &result); err != nil { - return nil, err - } - reps := make([]driver.Replication, 0, len(result.Docs)) - for _, row := range result.Docs { - rep := c.newSchedulerReplication(&row) - reps = append(reps, rep) - } - return reps, nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/seqid.go b/vendor/github.com/go-kivik/couchdb/v3/seqid.go deleted file mode 100644 index 189285ed4..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/seqid.go +++ /dev/null @@ -1,15 +0,0 @@ -package couchdb - -import "bytes" - -// sequenceID is a CouchDB update sequence ID. This is just a string, but has -// a special JSON unmarshaler to work with both CouchDB 2.0.0 (which uses -// normal) strings for sequence IDs, and earlier versions (which use integers) -type sequenceID string - -// UnmarshalJSON satisfies the json.Unmarshaler interface. -func (id *sequenceID) UnmarshalJSON(data []byte) error { - sid := sequenceID(bytes.Trim(data, `""`)) - *id = sid - return nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/session.go b/vendor/github.com/go-kivik/couchdb/v3/session.go deleted file mode 100644 index 6ccb9d75a..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/session.go +++ /dev/null @@ -1,50 +0,0 @@ -package couchdb - -import ( - "context" - "encoding/json" - "net/http" - - "github.com/go-kivik/kivik/v3/driver" -) - -type session struct { - Data json.RawMessage - Info authInfo `json:"info"` - UserCtx userContext `json:"userCtx"` -} - -type authInfo struct { - AuthenticationMethod string `json:"authenticated"` - AuthenticationDB string `json:"authentiation_db"` - AuthenticationHandlers []string `json:"authentication_handlers"` -} - -type userContext struct { - Name string `json:"name"` - Roles []string `json:"roles"` -} - -func (s *session) UnmarshalJSON(data []byte) error { - type alias session - var a alias - if err := json.Unmarshal(data, &a); err != nil { - return err - } - *s = session(a) - s.Data = data - return nil -} - -func (c *client) Session(ctx context.Context) (*driver.Session, error) { - s := &session{} - _, err := c.DoJSON(ctx, http.MethodGet, "/_session", nil, s) - return &driver.Session{ - RawResponse: s.Data, - Name: s.UserCtx.Name, - Roles: s.UserCtx.Roles, - AuthenticationMethod: s.Info.AuthenticationMethod, - AuthenticationDB: s.Info.AuthenticationDB, - AuthenticationHandlers: s.Info.AuthenticationHandlers, - }, err -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/util.go b/vendor/github.com/go-kivik/couchdb/v3/util.go deleted file mode 100644 index e7a672bfe..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/util.go +++ /dev/null @@ -1,29 +0,0 @@ -package couchdb - -import ( - "encoding/json" - "net/http" - - kivik "github.com/go-kivik/kivik/v3" -) - -// deJSONify unmarshals a string, []byte, or json.RawMessage. All other types -// are returned as-is. -func deJSONify(i interface{}) (interface{}, error) { - var data []byte - switch t := i.(type) { - case string: - data = []byte(t) - case []byte: - data = t - case json.RawMessage: - data = []byte(t) - default: - return i, nil - } - var x interface{} - if err := json.Unmarshal(data, &x); err != nil { - return nil, &kivik.Error{HTTPStatus: http.StatusBadRequest, Err: err} - } - return x, nil -} diff --git a/vendor/github.com/go-kivik/couchdb/v3/version.go b/vendor/github.com/go-kivik/couchdb/v3/version.go deleted file mode 100644 index d29b139c4..000000000 --- a/vendor/github.com/go-kivik/couchdb/v3/version.go +++ /dev/null @@ -1,43 +0,0 @@ -package couchdb - -import ( - "context" - "encoding/json" - "net/http" - - "github.com/go-kivik/kivik/v3/driver" -) - -// Version returns the server's version info. -func (c *client) Version(ctx context.Context) (*driver.Version, error) { - i := &info{} - _, err := c.DoJSON(ctx, http.MethodGet, "/", nil, i) - return &driver.Version{ - Version: i.Version, - Vendor: i.Vendor.Name, - Features: i.Features, - RawResponse: i.Data, - }, err -} - -type info struct { - Data json.RawMessage - Version string `json:"version"` - Features []string `json:"features"` - Vendor struct { - Name string `json:"name"` - } `json:"vendor"` -} - -func (i *info) UnmarshalJSON(data []byte) error { - type alias info - var a alias - if err := json.Unmarshal(data, &a); err != nil { - return err - } - i.Data = data - i.Version = a.Version - i.Vendor = a.Vendor - i.Features = a.Features - return nil -} diff --git a/vendor/github.com/go-kivik/kivik/v3/.codecov.yml b/vendor/github.com/go-kivik/kivik/v3/.codecov.yml deleted file mode 100644 index 52cd7a417..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/.codecov.yml +++ /dev/null @@ -1,2 +0,0 @@ -ignore: - - test/**/* diff --git a/vendor/github.com/go-kivik/kivik/v3/.gitignore b/vendor/github.com/go-kivik/kivik/v3/.gitignore deleted file mode 100644 index a918b00d8..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -test/pouch__all_dbs__/ -vendor -test.* -Gopkg.lock -node_modules -coverage.txt diff --git a/vendor/github.com/go-kivik/kivik/v3/.gitlab-ci.yml b/vendor/github.com/go-kivik/kivik/v3/.gitlab-ci.yml deleted file mode 100644 index ed57f7938..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/.gitlab-ci.yml +++ /dev/null @@ -1,83 +0,0 @@ -stages: - - test - -variables: - GO111MODULE: "on" - COUCHDB_USER: admin - COUCHDB_PASSWORD: abc123 - KIVIK_TEST_DSN_COUCH23: http://admin:abc123@couch23:5984/ - KIVIK_TEST_DSN_COUCH30: http://admin:abc123@couch30:5984/ - -.test: &test_template - stage: test - services: - - name: apache/couchdb:2.3.1 - alias: couch23 - - name: apache/couchdb:3.0.0 - alias: couch30 - before_script: - - ./script/complete_couch2.sh ${KIVIK_TEST_DSN_COUCH23} - - ./script/complete_couch2.sh ${KIVIK_TEST_DSN_COUCH30} - script: - - go mod download - - ./script/test_version.sh - - go test -race -tags=livetest ./... - -linter: - stage: test - image: golangci/golangci-lint:v1.33 - script: - - go mod download - - golangci-lint run ./... - -go-1.11: - <<: *test_template - image: golang:1.11 - -go-1.12: - <<: *test_template - image: golang:1.12 - -go-1.13: - <<: *test_template - image: golang:1.13 - -go-1.14: - <<: *test_template - image: golang:1.14 - -go-1.15: - <<: *test_template - image: golang:1.15 - -gopherjs-1.12: - <<: *test_template - image: golang:1.14 - variables: - SRCDIR: /go/src/github.com/go-kivik/kivik/v3 - script: - - go get golang.org/dl/go1.12.16 - - go1.12.16 download - - mkdir -p ${SRCDIR} - - mv ${CI_PROJECT_DIR}/* ${SRCDIR} - - cd ${SRCDIR} - - go mod vendor - - curl -sL https://deb.nodesource.com/setup_12.x | bash - - - apt-get update -qq && apt-get install -y nodejs - - npm install - - GO111MODULE=off go get -u github.com/gopherjs/gopherjs - - npm install source-map-support - - | - ( - cd $GOPATH/src/github.com/gopherjs/gopherjs/node-syscall/ - npm install --global node-gyp - node-gyp rebuild - mkdir -p ~/.node_libraries/ - cp build/Release/syscall.node ~/.node_libraries/syscall.node - ) - - GOPHERJS_GOROOT="$(go1.12.16 env GOROOT)" gopherjs test ./... - -go-rc: - <<: *test_template - image: golang:rc - allow_failure: true diff --git a/vendor/github.com/go-kivik/kivik/v3/.golangci.toml b/vendor/github.com/go-kivik/kivik/v3/.golangci.toml deleted file mode 100644 index 44a20fe9d..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/.golangci.toml +++ /dev/null @@ -1,12 +0,0 @@ -[output] -format = "colored-line-number" - -[linters] -enable = [ - "interfacer", "gocyclo", "unconvert", "goimports", "unused", "varcheck", - "vetshadow", "misspell", "nakedret", "errcheck", "golint", "ineffassign", - "deadcode", "goconst", "vet", "unparam", "gofumpt" -] - -[issues] -exclude-use-default = false \ No newline at end of file diff --git a/vendor/github.com/go-kivik/kivik/v3/CONTRIBUTING.md b/vendor/github.com/go-kivik/kivik/v3/CONTRIBUTING.md deleted file mode 100644 index fa05cdd85..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/CONTRIBUTING.md +++ /dev/null @@ -1,18 +0,0 @@ -# Contributing - -Kivik is an open source project, and contributions are always welcome. - -Contributing to Kivik involves very little formal procedure. Anyone is -encouraged to file bug reports, feature requests, or submit PRs. PRs are not -guaranteed to be accepted, but they are guaranteed to be reviewed and discussed. -For any large-scale change, opening an issue to discuss the change prior to -submitting a PR is probably appropriate, to avoid possibly wasting time on an -implementation that may not be accepted. - -## Licensing - -Kivik is licensed under the Apache license, version 2.0. All code contributions -to this project are therefore also contributed under the same license. **If you -are uncomfortable with, or unable to comply with this** (perhaps due to legal -limitations imposed by your employer), **DO NOT SUBMIT CODE**! You are still -welcome to participate in bug reports and discussions. diff --git a/vendor/github.com/go-kivik/kivik/v3/ISSUE_TEMPLATE.md b/vendor/github.com/go-kivik/kivik/v3/ISSUE_TEMPLATE.md deleted file mode 100644 index a6650972d..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,11 +0,0 @@ -## Bug Report Checklist (remove this template if submitting a feature request) - -1. Which version of Kivik are you using? - -2. Which version of Go are you using? (Output of `go version`) -- Kivik 1.x aims to support all versions of Go from 1.7. The master branch aims to support Go 1.8 and later. - -3. What did you do? (Include your code if possible) - -4. What did you expect to see? - -5. What did you see instead? diff --git a/vendor/github.com/go-kivik/kivik/v3/LICENSE.md b/vendor/github.com/go-kivik/kivik/v3/LICENSE.md deleted file mode 100644 index 0a2865e54..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/LICENSE.md +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (c) 2017 Jonathan Hall - -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/go-kivik/kivik/v3/README.md b/vendor/github.com/go-kivik/kivik/v3/README.md deleted file mode 100644 index eca6028ae..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/README.md +++ /dev/null @@ -1,174 +0,0 @@ -[![Build Status](https://gitlab.com/go-kivik/kivik/badges/master/pipeline.svg)](https://gitlab.com/go-kivik/kivik/pipelines) [![Codecov](https://img.shields.io/codecov/c/github/go-kivik/kivik.svg?style=flat)](https://codecov.io/gh/go-kivik/kivik) [![Go Report Card](https://goreportcard.com/badge/github.com/go-kivik/kivik)](https://goreportcard.com/report/github.com/go-kivik/kivik) [![GoDoc](https://godoc.org/github.com/go-kivik/kivik?status.svg)](http://godoc.org/github.com/go-kivik/kivik) [![Website](https://img.shields.io/website-up-down-green-red/http/kivik.io.svg?label=website&colorB=007fff)](http://kivik.io) - -# Kivik - -Package kivik provides a common interface to CouchDB or CouchDB-like databases. - -The kivik package must be used in conjunction with a database driver. - -The kivik driver system is modeled after the standard library's [sql](https://golang.org/pkg/database/sql/) -and [sql/driver](https://golang.org/pkg/database/sql/driver/) packages, although -the client API is completely different due to the different database models -implemented by SQL and NoSQL databases such as CouchDB. - -# Versions - -You are browsing the **stable v3** branch of Kivik. For the latest changes, you -may be interested in the [development branch](https://github.com/go-kivik/kivik). - -Example configuration for common dependency managers follow. - -## Go Modules - -Kivik 3.x and later depends on Go modules, which requires Go 1.11 or later. If -your project does not use modules, and you are unable to switch, you may use -[Kivik 2.x](https://github.com/go-kivik/kivik/tree/v2). - -# Installation - -Install Kivik as you normally would for any Go package: - - go get -u github.com/go-kivik/kivik/v3 - go get -u github.com/go-kivik/couchdb/v3 - -This will install the main Kivik package and the CouchDB database driver. See -the [list of Kivik database drivers](https://github.com/go-kivik/kivik/wiki/Kivik-database-drivers) -for a complete list of available drivers. - -# Example Usage - -Please consult the the [package documentation](https://godoc.org/github.com/go-kivik/kivik) -for all available API methods, and a complete usage documentation. And for -additional usage examples, [consult the wiki](https://github.com/go-kivik/kivik/wiki/Usage-Examples). - -```go -package main - -import ( - "context" - "fmt" - - kivik "github.com/go-kivik/kivik/v3" - _ "github.com/go-kivik/couchdb/v3" // The CouchDB driver -) - -func main() { - client, err := kivik.New("couch", "http://localhost:5984/") - if err != nil { - panic(err) - } - - db := client.DB(context.TODO(), "animals") - - doc := map[string]interface{}{ - "_id": "cow", - "feet": 4, - "greeting": "moo", - } - - rev, err := db.Put(context.TODO(), "cow", doc) - if err != nil { - panic(err) - } - fmt.Printf("Cow inserted with revision %s\n", rev) -} -``` - -# Frequently Asked Questions - -Nobody has ever asked me any of these questions, so they're probably better called -"Never Asked Questions" or possibly "Imagined Questions." - -## Why another CouchDB client API? - -Read the [design goals](https://github.com/go-kivik/kivik/wiki/Design-goals) for -the general design goals. - -Specifically, I was motivated to write Kivik for a few reasons: - -1. I was unhappy with any of the existing CouchDB drivers for Go. The [best -one](https://github.com/fjl/go-couchdb) had a number of shortcomings: - - - It is no longer actively developed. - - It [doesn't have an open source license](https://github.com/fjl/go-couchdb/issues/15). - - It doesn't support iterating over result sets, forcing one to load all - results of a query into memory at once. - - It [doesn't support CouchDB 2.0](https://github.com/fjl/go-couchdb/issues/14) - sequence IDs or MongoDB-style queries. - - It doesn't natively support CookieAuth (it does allow a generic Auth method - which could be used to do this, but I think it's appropriate to put directly - in the library). - -2. I wanted a single client API that worked with both CouchDB and -[PouchDB](https://pouchdb.com/). I had previously written -[go-pouchdb](https://github.com/flimzy/go-pouchdb), a GopherJS wrapper around -the PouchDB library with a public API modeled after `fjl/go-couchdb`, but I -still wanted a unified driver infrastructure. - -3. I want an unambiguous, open source license. This software is released under -the Apache 2.0 license. See the included LICENSE.md file for details. - -4. I wanted the ability to mock CouchDB connections for testing. This is possible -with the `sql` / `sql/driver` approach by implementing a mock driver, but was -not possible with any existing CouchDB client libraries. This library makes that -possible for CouchDB apps, too. - -5. I wanted a simple, mock CouchDB server I could use for testing. It doesn't -need to be efficient, or support all CouchDB servers, but it should be enough -to test the basic functionality of a PouchDB app, for instance. Kivik aims to -do this with the `kivik serve` command, in the near future. - -6. I wanted a toolkit that would make it easy to build a proxy to sit in front -of CouchDB to handle custom authentication or other logic that CouchDB cannot -support natively. Kivik aims to accomplish this in the future. - -## What are Kivik's requirements? - -Kivik's test suite is automatically run on Linux for every pull request, but -should work on all supported Go architectures. If you find it not working for -your OS/architecture, please submit a bug report. - -Below are the compatibility targets for specific runtime and database versions. -If you discover a bug affecting any of these supported environments, please let -me know by submitting a bug report via GitHub. - -- **Go** Kivik 3.x aims for full compatibility with all stable releases of Go - from 1.9. For Go 1.7 or 1.8 you can use [Kivik 1.x](https://github.com/go-kivik/kivik/tree/v1) -- **CouchDB** The Kivik 3.x CouchDB driver aims for compatibility with all - stable releases of CouchDB from 1.6.1. -- **GopherJS** GopherJS always requires the latest stable version of Go, so - building Kivik with GopherJS has this same requirement. -- **PouchDB** The Kivik 3.x PouchDB driver aims for compatibility with all - stable releases of PouchDB from 6.0.0. - -## What is the development status? - -Kivik 3.x is considered production-ready and comes with a complete client API -client and backend drivers for CouchDB and PouchDB. - -Future goals are to flesh out the Memory driver, which will make automated -testing without a real CouchDB server easier. Then I will work on completing -the 'serve' mode. - -You can see a complete overview of the current status on the -[Compatibility chart](https://github.com/go-kivik/kivik/blob/master/doc/COMPATIBILITY.md) - -## Why the name "Kivik"? - -[Kivik](http://www.ikea.com/us/en/catalog/categories/series/18329/) is a line -of sofas (couches) from IKEA. And in the spirit of IKEA, and build-your-own -furniture, Kivik aims to allow you to "build your own" CouchDB client, server, -and proxy applications. - -## What license is Kivik released under? - -This software is released under the terms of the Apache 2.0 license. See -LICENCE.md, or read the [full license](http://www.apache.org/licenses/LICENSE-2.0). - -## What projects currently use Kivik? - -If your project uses Kivik, and you'd like to be added to this list, create an -issue or submit a pull request. - -- [Cayley](https://github.com/cayleygraph/cayley) is an open-source graph - database. It uses Kivik for the CouchDB and PouchDB storage backends. diff --git a/vendor/github.com/go-kivik/kivik/v3/attachments.go b/vendor/github.com/go-kivik/kivik/v3/attachments.go deleted file mode 100644 index 197d799e0..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/attachments.go +++ /dev/null @@ -1,175 +0,0 @@ -package kivik - -import ( - "bytes" - "encoding/json" - "io" - "io/ioutil" - - "github.com/go-kivik/kivik/v3/driver" -) - -// Attachments is a collection of one or more file attachments. -type Attachments map[string]*Attachment - -// Get fetches the requested attachment, or returns nil if it does not exist. -func (a *Attachments) Get(filename string) *Attachment { - return map[string]*Attachment(*a)[filename] -} - -// Set sets the attachment associated with filename in the collection, -// replacing it if it already existed. -func (a *Attachments) Set(filename string, att *Attachment) { - map[string]*Attachment(*a)[filename] = att -} - -// Delete removes the specified file from the collection. -func (a *Attachments) Delete(filename string) { - delete(map[string]*Attachment(*a), filename) -} - -// Attachment represents a file attachment on a CouchDB document. -type Attachment struct { - // Filename is the name of the attachment. - Filename string `json:"-"` - - // ContentType is the MIME type of the attachment contents. - ContentType string `json:"content_type"` - - // Stub will be true if the data structure only represents file metadata, - // and contains no actual content. Stub will be true when returned by the - // GetAttachmentMeta function, or when included in a document without the - // 'include_docs' option. - Stub bool `json:"stub"` - - // Follows will be true when reading attachments in multipart/related - // format. - Follows bool `json:"follows"` - - // Content represents the attachment's content. - // - // Kivik will always return a non-nil Content, even for 0-byte attachments - // or when Stub is true. It is the caller's responsibility to close - // Content. - Content io.ReadCloser `json:"-"` - - // Size records the uncompressed size of the attachment. The value -1 - // indicates that the length is unknown. Unless Stub is true, values >= 0 - // indicate that the given number of bytes may be read from Content. - Size int64 `json:"length"` - - // Used compression codec, if any. Will be the empty string if the - // attachment is uncompressed. - ContentEncoding string `json:"encoding"` - - // EncodedLength records the compressed attachment size in bytes. Only - // meaningful when ContentEncoding is defined. - EncodedLength int64 `json:"encoded_length"` - - // RevPos is the revision number when attachment was added. - RevPos int64 `json:"revpos"` - - // Digest is the content hash digest. - Digest string `json:"digest"` -} - -// bufCloser wraps a *bytes.Buffer to create an io.ReadCloser -type bufCloser struct { - *bytes.Buffer -} - -var _ io.ReadCloser = &bufCloser{} - -func (b *bufCloser) Close() error { return nil } - -// validate returns an error if the attachment is invalid. -func (a *Attachment) validate() error { - if a.Filename == "" { - return missingArg("filename") - } - return nil -} - -// MarshalJSON satisfies the json.Marshaler interface. -func (a *Attachment) MarshalJSON() ([]byte, error) { - type jsonAttachment struct { - ContentType string `json:"content_type"` - Stub *bool `json:"stub,omitempty"` - Follows *bool `json:"follows,omitempty"` - Size int64 `json:"length,omitempty"` - RevPos int64 `json:"revpos,omitempty"` - Data []byte `json:"data,omitempty"` - Digest string `json:"digest,omitempty"` - } - att := &jsonAttachment{ - ContentType: a.ContentType, - Size: a.Size, - RevPos: a.RevPos, - Digest: a.Digest, - } - switch { - case a.Stub: - att.Stub = &a.Stub - case a.Follows: - att.Follows = &a.Follows - default: - defer a.Content.Close() // nolint: errcheck - data, err := ioutil.ReadAll(a.Content) - if err != nil { - return nil, err - } - att.Data = data - } - return json.Marshal(att) -} - -// UnmarshalJSON implements the json.Unmarshaler interface for an Attachment. -func (a *Attachment) UnmarshalJSON(data []byte) error { - type clone Attachment - type jsonAtt struct { - clone - Data []byte `json:"data"` - } - var att jsonAtt - if err := json.Unmarshal(data, &att); err != nil { - return err - } - *a = Attachment(att.clone) - if att.Data != nil { - a.Content = ioutil.NopCloser(bytes.NewReader(att.Data)) - } else { - a.Content = nilContent - } - return nil -} - -// UnmarshalJSON implements the json.Unmarshaler interface for a collection of -// Attachments. -func (a *Attachments) UnmarshalJSON(data []byte) error { - atts := make(map[string]*Attachment) - if err := json.Unmarshal(data, &atts); err != nil { - return err - } - for filename, att := range atts { - att.Filename = filename - } - *a = atts - return nil -} - -// AttachmentsIterator is an experimental way to read streamed attachments from -// a multi-part Get request. -type AttachmentsIterator struct { - atti driver.Attachments -} - -// Next returns the next attachment in the stream. io.EOF will be -// returned when there are no more attachments. -func (i *AttachmentsIterator) Next() (*Attachment, error) { - att := new(driver.Attachment) - if err := i.atti.Next(att); err != nil { - return nil, err - } - katt := Attachment(*att) - return &katt, nil -} diff --git a/vendor/github.com/go-kivik/kivik/v3/bulk.go b/vendor/github.com/go-kivik/kivik/v3/bulk.go deleted file mode 100644 index b5eebc5af..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/bulk.go +++ /dev/null @@ -1,155 +0,0 @@ -package kivik - -import ( - "context" - "errors" - "io" - "net/http" - - "github.com/go-kivik/kivik/v3/driver" -) - -// BulkResults is an iterator over the results of a BulkDocs query. -type BulkResults struct { - *iter - bulki driver.BulkResults -} - -// Next returns the next BulkResult from the feed. If an error occurs, it will -// be returned and the feed closed. io.EOF will be returned when there are no -// more results. -func (r *BulkResults) Next() bool { - return r.iter.Next() -} - -// Err returns the error, if any, that was encountered during iteration. Err -// may be called after an explicit or implicit Close. -func (r *BulkResults) Err() error { - return r.iter.Err() -} - -// Close closes the feed. Any unread updates will still be accessible via -// Next(). -func (r *BulkResults) Close() error { - return r.iter.Close() -} - -type bulkIterator struct{ driver.BulkResults } - -var _ iterator = &bulkIterator{} - -func (r *bulkIterator) Next(i interface{}) error { - return r.BulkResults.Next(i.(*driver.BulkResult)) -} - -func newBulkResults(ctx context.Context, bulki driver.BulkResults) *BulkResults { - return &BulkResults{ - iter: newIterator(ctx, &bulkIterator{bulki}, &driver.BulkResult{}), - bulki: bulki, - } -} - -// ID returns the document ID name for the current result. -func (r *BulkResults) ID() string { - runlock, err := r.rlock() - if err != nil { - return "" - } - defer runlock() - return r.curVal.(*driver.BulkResult).ID -} - -// Rev returns the revision of the current curResult. -func (r *BulkResults) Rev() string { - runlock, err := r.rlock() - if err != nil { - return "" - } - defer runlock() - return r.curVal.(*driver.BulkResult).Rev -} - -// UpdateErr returns the error associated with the current result, or nil -// if none. Do not confuse this with Err, which returns an error for the -// iterator itself. -func (r *BulkResults) UpdateErr() error { - runlock, err := r.rlock() - if err != nil { - return nil - } - defer runlock() - return r.curVal.(*driver.BulkResult).Error -} - -// BulkDocs allows you to create and update multiple documents at the same time -// within a single request. This function returns an iterator over the results -// of the bulk operation. -// See http://docs.couchdb.org/en/2.0.0/api/database/bulk-api.html#db-bulk-docs -// -// As with Put, each individual document may be a JSON-marshable object, or a -// raw JSON string in a []byte, json.RawMessage, or io.Reader. -func (db *DB) BulkDocs(ctx context.Context, docs []interface{}, options ...Options) (*BulkResults, error) { - docsi, err := docsInterfaceSlice(docs) - if err != nil { - return nil, err - } - if len(docsi) == 0 { - return nil, &Error{HTTPStatus: http.StatusBadRequest, Err: errors.New("kivik: no documents provided")} - } - opts := mergeOptions(options...) - if bulkDocer, ok := db.driverDB.(driver.BulkDocer); ok { - bulki, err := bulkDocer.BulkDocs(ctx, docsi, opts) - if err != nil { - return nil, err - } - return newBulkResults(ctx, bulki), nil - } - var results []driver.BulkResult - for _, doc := range docsi { - var err error - var id, rev string - if docID, ok := extractDocID(doc); ok { - id = docID - rev, err = db.Put(ctx, id, doc, opts) - } else { - id, rev, err = db.CreateDoc(ctx, doc, opts) - } - results = append(results, driver.BulkResult{ - ID: id, - Rev: rev, - Error: err, - }) - } - return newBulkResults(ctx, &emulatedBulkResults{results}), nil -} - -type emulatedBulkResults struct { - results []driver.BulkResult -} - -var _ driver.BulkResults = &emulatedBulkResults{} - -func (r *emulatedBulkResults) Close() error { - r.results = nil - return nil -} - -func (r *emulatedBulkResults) Next(res *driver.BulkResult) error { - if len(r.results) == 0 { - return io.EOF - } - *res = r.results[0] - r.results = r.results[1:] - return nil -} - -func docsInterfaceSlice(docsi []interface{}) ([]interface{}, error) { - for i, doc := range docsi { - x, err := normalizeFromJSON(doc) - if err != nil { - return nil, &Error{HTTPStatus: http.StatusBadRequest, Err: err} - } - docsi[i] = x - } - return docsi, nil -} diff --git a/vendor/github.com/go-kivik/kivik/v3/changes.go b/vendor/github.com/go-kivik/kivik/v3/changes.go deleted file mode 100644 index 78403b2ca..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/changes.go +++ /dev/null @@ -1,124 +0,0 @@ -package kivik - -import ( - "context" - - "github.com/go-kivik/kivik/v3/driver" -) - -// Changes is an iterator over the database changes feed. -type Changes struct { - *iter - changesi driver.Changes -} - -// Next prepares the next result value for reading. It returns true on success -// or false if there are no more results, due to an error or the changes feed -// having been closed. Err should be consulted to determine any error. -func (c *Changes) Next() bool { - return c.iter.Next() -} - -// Err returns the error, if any, that was encountered during iteration. Err may -// be called after an explicit or implicit Close. -func (c *Changes) Err() error { - return c.iter.Err() -} - -// Close closes the Changes feed, preventing further enumeration, and freeing -// any resources (such as the http request body) of the underlying query. If -// Next is called and there are no further results, Changes is closed -// automatically and it will suffice to check the result of Err. Close is -// idempotent and does not affect the result of Err. -func (c *Changes) Close() error { - return c.iter.Close() -} - -type changesIterator struct{ driver.Changes } - -var _ iterator = &changesIterator{} - -func (c *changesIterator) Next(i interface{}) error { return c.Changes.Next(i.(*driver.Change)) } - -func newChanges(ctx context.Context, changesi driver.Changes) *Changes { - return &Changes{ - iter: newIterator(ctx, &changesIterator{changesi}, &driver.Change{}), - changesi: changesi, - } -} - -// Changes returns a list of changed revs. -func (c *Changes) Changes() []string { - return c.curVal.(*driver.Change).Changes -} - -// Deleted returns true if the change relates to a deleted document. -func (c *Changes) Deleted() bool { - return c.curVal.(*driver.Change).Deleted -} - -// ID returns the ID of the current result. -func (c *Changes) ID() string { - return c.curVal.(*driver.Change).ID -} - -// ScanDoc works the same as ScanValue, but on the doc field of the result. It -// is only valid for results that include documents. -func (c *Changes) ScanDoc(dest interface{}) error { - runlock, err := c.rlock() - if err != nil { - return err - } - defer runlock() - return scan(dest, c.curVal.(*driver.Change).Doc) -} - -// Changes returns an iterator over the real-time changes feed. The feed remains -// open until explicitly closed, or an error is encountered. -// See http://couchdb.readthedocs.io/en/latest/api/database/changes.html#get--db-_changes -func (db *DB) Changes(ctx context.Context, options ...Options) (*Changes, error) { - changesi, err := db.driverDB.Changes(ctx, mergeOptions(options...)) - if err != nil { - return nil, err - } - return newChanges(ctx, changesi), nil -} - -// Seq returns the Seq of the current result. -func (c *Changes) Seq() string { - return c.curVal.(*driver.Change).Seq -} - -// LastSeq returns the last update sequence id present in the change set, -// if returned by the server. This value is only guaranteed to be set after -// all changes have been enumerated through by Next, thus should only be -// read after processing all changes in a change set. Calling Close before -// enumerating will render this value unreliable. -func (c *Changes) LastSeq() string { - if c.changesi == nil { - return "" - } - return c.changesi.LastSeq() -} - -// Pending returns the count of remaining items in the change feed. This -// value is only guaranteed to be set after all changes have been -// enumerated through by Next, thus should only be read after processing all -// changes in a change set. Calling Close before enumerating will render -// this value unreliable. -func (c *Changes) Pending() int64 { - if c.changesi == nil { - return 0 - } - return c.changesi.Pending() -} - -// ETag returns the unquoted ETag header, if any. Unlike LastSeq and Pending, -// because this value is returned in the response header (for standard CouchDB -// operation) anyway, it can be read immediately, before iteration even begins. -func (c *Changes) ETag() string { - if c.changesi == nil { - return "" - } - return c.changesi.ETag() -} diff --git a/vendor/github.com/go-kivik/kivik/v3/cluster.go b/vendor/github.com/go-kivik/kivik/v3/cluster.go deleted file mode 100644 index be1ee08a2..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/cluster.go +++ /dev/null @@ -1,53 +0,0 @@ -package kivik - -import ( - "context" - "net/http" - - "github.com/go-kivik/kivik/v3/driver" -) - -var clusterNotImplemented = &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: driver does not support cluster operations"} - -// ClusterStatus returns the current cluster status. -// -// See http://docs.couchdb.org/en/stable/api/server/common.html#cluster-setup -func (c *Client) ClusterStatus(ctx context.Context, options ...Options) (string, error) { - cluster, ok := c.driverClient.(driver.Cluster) - if !ok { - return "", clusterNotImplemented - } - return cluster.ClusterStatus(ctx, mergeOptions(options...)) -} - -// ClusterSetup performs the requested cluster action. action should be -// an object understood by the driver. For the CouchDB driver, this means an -// object which is marshalable to a JSON object of the expected format. -// -// See http://docs.couchdb.org/en/stable/api/server/common.html#post--_cluster_setup -func (c *Client) ClusterSetup(ctx context.Context, action interface{}) error { - cluster, ok := c.driverClient.(driver.Cluster) - if !ok { - return clusterNotImplemented - } - return cluster.ClusterSetup(ctx, action) -} - -// ClusterMembership contains the list of known nodes, and cluster nodes, as returned -// by the /_membership endpoint. -// See https://docs.couchdb.org/en/latest/api/server/common.html#get--_membership -type ClusterMembership struct { - AllNodes []string `json:"all_nodes"` - ClusterNodes []string `json:"cluster_nodes"` -} - -// Membership returns a list of known CouchDB nodes. -// See https://docs.couchdb.org/en/latest/api/server/common.html#get--_membership -func (c *Client) Membership(ctx context.Context) (*ClusterMembership, error) { - cluster, ok := c.driverClient.(driver.Cluster2) - if !ok { - return nil, &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: driver does not support the /_membership endpoint"} - } - nodes, err := cluster.Membership(ctx) - return (*ClusterMembership)(nodes), err -} diff --git a/vendor/github.com/go-kivik/kivik/v3/codecov.yml b/vendor/github.com/go-kivik/kivik/v3/codecov.yml deleted file mode 100644 index aea8ff245..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/codecov.yml +++ /dev/null @@ -1,3 +0,0 @@ -ignore: -- "test" -- "mock" diff --git a/vendor/github.com/go-kivik/kivik/v3/config.go b/vendor/github.com/go-kivik/kivik/v3/config.go deleted file mode 100644 index 8c91fd743..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/config.go +++ /dev/null @@ -1,81 +0,0 @@ -package kivik - -import ( - "context" - "net/http" - - "github.com/go-kivik/kivik/v3/driver" -) - -// Config represents all the config sections. -// -// Note that the Config struct, and all of the config-related methods are -// considered experimental, and may change in the future. -type Config map[string]ConfigSection - -// ConfigSection represents all key/value pairs for a section of configuration. -type ConfigSection map[string]string - -var configNotImplemented = &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: driver does not support Config interface"} - -// Config returns the entire server config, for the specified node. -// -// See http://docs.couchdb.org/en/stable/api/server/configuration.html#get--_node-node-name-_config -func (c *Client) Config(ctx context.Context, node string) (Config, error) { - if configer, ok := c.driverClient.(driver.Configer); ok { - driverCf, err := configer.Config(ctx, node) - if err != nil { - return nil, err - } - cf := Config{} - for k, v := range driverCf { - cf[k] = ConfigSection(v) - } - return cf, nil - } - return nil, configNotImplemented -} - -// ConfigSection returns the requested section of the server config for the -// specified node. -// -// See http://docs.couchdb.org/en/stable/api/server/configuration.html#node-node-name-config-section -func (c *Client) ConfigSection(ctx context.Context, node, section string) (ConfigSection, error) { - if configer, ok := c.driverClient.(driver.Configer); ok { - sec, err := configer.ConfigSection(ctx, node, section) - return ConfigSection(sec), err - } - return nil, configNotImplemented -} - -// ConfigValue returns a single config value for the specified node. -// -// See http://docs.couchdb.org/en/stable/api/server/configuration.html#get--_node-node-name-_config-section-key -func (c *Client) ConfigValue(ctx context.Context, node, section, key string) (string, error) { - if configer, ok := c.driverClient.(driver.Configer); ok { - return configer.ConfigValue(ctx, node, section, key) - } - return "", configNotImplemented -} - -// SetConfigValue sets the server's config value on the specified node, creating -// the key if it doesn't exist. It returns the old value. -// -// See http://docs.couchdb.org/en/stable/api/server/configuration.html#put--_node-node-name-_config-section-key -func (c *Client) SetConfigValue(ctx context.Context, node, section, key, value string) (string, error) { - if configer, ok := c.driverClient.(driver.Configer); ok { - return configer.SetConfigValue(ctx, node, section, key, value) - } - return "", configNotImplemented -} - -// DeleteConfigKey deletes the configuration key and associated value from the -// specified node. It returns the old value. -// -// See http://docs.couchdb.org/en/stable/api/server/configuration.html#delete--_node-node-name-_config-section-key -func (c *Client) DeleteConfigKey(ctx context.Context, node, section, key string) (string, error) { - if configer, ok := c.driverClient.(driver.Configer); ok { - return configer.DeleteConfigKey(ctx, node, section, key) - } - return "", configNotImplemented -} diff --git a/vendor/github.com/go-kivik/kivik/v3/constants.go b/vendor/github.com/go-kivik/kivik/v3/constants.go deleted file mode 100644 index b85610065..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/constants.go +++ /dev/null @@ -1,27 +0,0 @@ -package kivik - -const ( - // KivikVersion is the version of the Kivik library. - KivikVersion = "3.1.0" - // KivikVendor is the vendor string reported by this library. - KivikVendor = "Kivik" -) - -// SessionCookieName is the name of the CouchDB session cookie. -const SessionCookieName = "AuthSession" - -// UserPrefix is the mandatory CouchDB user prefix. -// See http://docs.couchdb.org/en/2.0.0/intro/security.html#org-couchdb-user -const UserPrefix = "org.couchdb.user:" - -// EndKeySuffix is a high Unicode character (0xfff0) useful for appending to an -// endkey argument, when doing a ranged search, as described here: -// http://couchdb.readthedocs.io/en/latest/ddocs/views/collation.html#string-ranges -// -// Example, to return all results with keys beginning with "foo": -// -// rows, err := db.Query(context.TODO(), "ddoc", "view", map[string]interface{}{ -// "startkey": "foo", -// "endkey": "foo" + kivik.EndKeySuffix, -// }) -const EndKeySuffix = string(rune(0xfff0)) diff --git a/vendor/github.com/go-kivik/kivik/v3/db.go b/vendor/github.com/go-kivik/kivik/v3/db.go deleted file mode 100644 index 5deeb2a30..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/db.go +++ /dev/null @@ -1,733 +0,0 @@ -package kivik - -import ( - "context" - "encoding/json" - "errors" - "io" - "io/ioutil" - "net/http" - "reflect" - "strings" - - "github.com/go-kivik/kivik/v3/driver" -) - -// DB is a handle to a specific database. -type DB struct { - client *Client - name string - driverDB driver.DB - err error -} - -// Client returns the Client used to connect to the database. -func (db *DB) Client() *Client { - return db.client -} - -// Name returns the database name as passed when creating the DB connection. -func (db *DB) Name() string { - return db.name -} - -// Err returns the error, if any, that occurred while connecting to or creating -// the database. This error will be deferred until the next call, normally, so -// using this method is only ever necessary if you need to directly check the -// error status, and intend to do nothing else with the DB object. -func (db *DB) Err() error { - return db.err -} - -// AllDocs returns a list of all documents in the database. -func (db *DB) AllDocs(ctx context.Context, options ...Options) (*Rows, error) { - if db.err != nil { - return nil, db.err - } - rowsi, err := db.driverDB.AllDocs(ctx, mergeOptions(options...)) - if err != nil { - return nil, err - } - return newRows(ctx, rowsi), nil -} - -// DesignDocs returns a list of all documents in the database. -func (db *DB) DesignDocs(ctx context.Context, options ...Options) (*Rows, error) { - if db.err != nil { - return nil, db.err - } - ddocer, ok := db.driverDB.(driver.DesignDocer) - if !ok { - return nil, &Error{HTTPStatus: http.StatusNotImplemented, Err: errors.New("kivik: design doc view not supported by driver")} - } - rowsi, err := ddocer.DesignDocs(ctx, mergeOptions(options...)) - if err != nil { - return nil, err - } - return newRows(ctx, rowsi), nil -} - -// LocalDocs returns a list of all documents in the database. -func (db *DB) LocalDocs(ctx context.Context, options ...Options) (*Rows, error) { - if db.err != nil { - return nil, db.err - } - ldocer, ok := db.driverDB.(driver.LocalDocer) - if !ok { - return nil, &Error{HTTPStatus: http.StatusNotImplemented, Err: errors.New("kivik: local doc view not supported by driver")} - } - rowsi, err := ldocer.LocalDocs(ctx, mergeOptions(options...)) - if err != nil { - return nil, err - } - return newRows(ctx, rowsi), nil -} - -// Query executes the specified view function from the specified design -// document. ddoc and view may or may not be be prefixed with '_design/' -// and '_view/' respectively. No other -func (db *DB) Query(ctx context.Context, ddoc, view string, options ...Options) (*Rows, error) { - if db.err != nil { - return nil, db.err - } - ddoc = strings.TrimPrefix(ddoc, "_design/") - view = strings.TrimPrefix(view, "_view/") - rowsi, err := db.driverDB.Query(ctx, ddoc, view, mergeOptions(options...)) - if err != nil { - return nil, err - } - return newRows(ctx, rowsi), nil -} - -// Row contains the result of calling Get for a single document. For most uses, -// it is sufficient just to call the ScanDoc method. For more advanced uses, the -// fields may be accessed directly. -type Row struct { - // ContentLength records the size of the JSON representation of the document - // as requestd. The value -1 indicates that the length is unknown. Values - // >= 0 indicate that the given number of bytes may be read from Body. - ContentLength int64 - - // Rev is the revision ID of the returned document. - Rev string - - // Body represents the document's content. - // - // Kivik will always return a non-nil Body, except when Err is non-nil. The - // ScanDoc method will close Body. When not using ScanDoc, it is the - // caller's responsibility to close Body - Body io.ReadCloser - - // Err contains any error that occurred while fetching the document. It is - // typically returned by ScanDoc. - Err error - - // Attachments is experimental - Attachments *AttachmentsIterator -} - -// ScanDoc unmarshals the data from the fetched row into dest. It is an -// intelligent wrapper around json.Unmarshal which also handles -// multipart/related responses. When done, the underlying reader is closed. -func (r *Row) ScanDoc(dest interface{}) error { - if r.Err != nil { - return r.Err - } - if reflect.TypeOf(dest).Kind() != reflect.Ptr { - return errNonPtr - } - defer r.Body.Close() // nolint: errcheck - if err := json.NewDecoder(r.Body).Decode(dest); err != nil { - return err - } - return nil -} - -// Get fetches the requested document. Any errors are deferred until the -// row.ScanDoc call. -func (db *DB) Get(ctx context.Context, docID string, options ...Options) *Row { - if db.err != nil { - return &Row{Err: db.err} - } - doc, err := db.driverDB.Get(ctx, docID, mergeOptions(options...)) - if err != nil { - return &Row{Err: err} - } - row := &Row{ - ContentLength: doc.ContentLength, - Rev: doc.Rev, - Body: doc.Body, - } - if doc.Attachments != nil { - row.Attachments = &AttachmentsIterator{atti: doc.Attachments} - } - return row -} - -// GetMeta returns the size and rev of the specified document. GetMeta accepts -// the same options as the Get method. -func (db *DB) GetMeta(ctx context.Context, docID string, options ...Options) (size int64, rev string, err error) { - if db.err != nil { - return 0, "", db.err - } - opts := mergeOptions(options...) - if r, ok := db.driverDB.(driver.MetaGetter); ok { - return r.GetMeta(ctx, docID, opts) - } - row := db.Get(ctx, docID, opts) - if row.Err != nil { - return 0, "", row.Err - } - if row.Rev != "" { - _ = row.Body.Close() - return row.ContentLength, row.Rev, nil - } - var doc struct { - Rev string `json:"_rev"` - } - // These last two lines cannot be combined for GopherJS due to a bug. - // See https://github.com/gopherjs/gopherjs/issues/608 - err = row.ScanDoc(&doc) - return row.ContentLength, doc.Rev, err -} - -// CreateDoc creates a new doc with an auto-generated unique ID. The generated -// docID and new rev are returned. -func (db *DB) CreateDoc(ctx context.Context, doc interface{}, options ...Options) (docID, rev string, err error) { - if db.err != nil { - return "", "", db.err - } - return db.driverDB.CreateDoc(ctx, doc, mergeOptions(options...)) -} - -// normalizeFromJSON unmarshals a []byte, json.RawMessage or io.Reader to a -// map[string]interface{}, or passed through any other types. -func normalizeFromJSON(i interface{}) (interface{}, error) { - var body []byte - switch t := i.(type) { - case []byte: - body = t - case json.RawMessage: - body = t - default: - r, ok := i.(io.Reader) - if !ok { - return i, nil - } - var err error - body, err = ioutil.ReadAll(r) - if err != nil { - return nil, &Error{HTTPStatus: http.StatusBadRequest, Err: err} - } - } - var x map[string]interface{} - if err := json.Unmarshal(body, &x); err != nil { - return nil, &Error{HTTPStatus: http.StatusBadRequest, Err: err} - } - return x, nil -} - -func extractDocID(i interface{}) (string, bool) { - if i == nil { - return "", false - } - var id string - var ok bool - switch t := i.(type) { - case map[string]interface{}: - id, ok = t["_id"].(string) - case map[string]string: - id, ok = t["_id"] - default: - data, err := json.Marshal(i) - if err != nil { - return "", false - } - var result struct { - ID string `json:"_id"` - } - if err := json.Unmarshal(data, &result); err != nil { - return "", false - } - id = result.ID - ok = result.ID != "" - } - if !ok { - return "", false - } - return id, true -} - -// Put creates a new doc or updates an existing one, with the specified docID. -// If the document already exists, the current revision must be included in doc, -// with JSON key '_rev', otherwise a conflict will occur. The new rev is -// returned. -// -// doc may be one of: -// -// - An object to be marshaled to JSON. The resulting JSON structure must -// conform to CouchDB standards. -// - A []byte value, containing a valid JSON document -// - A json.RawMessage value containing a valid JSON document -// - An io.Reader, from which a valid JSON document may be read. -func (db *DB) Put(ctx context.Context, docID string, doc interface{}, options ...Options) (rev string, err error) { - if db.err != nil { - return "", db.err - } - if docID == "" { - return "", missingArg("docID") - } - i, err := normalizeFromJSON(doc) - if err != nil { - return "", err - } - return db.driverDB.Put(ctx, docID, i, mergeOptions(options...)) -} - -// Delete marks the specified document as deleted. The revision may be provided -// via options, which takes priority over the rev argument. -func (db *DB) Delete(ctx context.Context, docID, rev string, options ...Options) (newRev string, err error) { - if db.err != nil { - return "", db.err - } - if docID == "" { - return "", missingArg("docID") - } - opts := mergeOptions(options...) - if rv, ok := opts["rev"].(string); ok && rv != "" { - rev = rv - } - return db.driverDB.Delete(ctx, docID, rev, opts) -} - -// Flush requests a flush of disk cache to disk or other permanent storage. -// -// See http://docs.couchdb.org/en/2.0.0/api/database/compact.html#db-ensure-full-commit -func (db *DB) Flush(ctx context.Context) error { - if db.err != nil { - return db.err - } - if flusher, ok := db.driverDB.(driver.Flusher); ok { - return flusher.Flush(ctx) - } - return &Error{HTTPStatus: http.StatusNotImplemented, Err: errors.New("kivik: flush not supported by driver")} -} - -// DBStats contains database statistics.. -type DBStats struct { - // Name is the name of the database. - Name string `json:"db_name"` - // CompactRunning is true if the database is currently being compacted. - CompactRunning bool `json:"compact_running"` - // DocCount is the number of documents are currently stored in the database. - DocCount int64 `json:"doc_count"` - // DeletedCount is a count of documents which have been deleted from the - // database. - DeletedCount int64 `json:"doc_del_count"` - // UpdateSeq is the current update sequence for the database. - UpdateSeq string `json:"update_seq"` - // DiskSize is the number of bytes used on-disk to store the database. - DiskSize int64 `json:"disk_size"` - // ActiveSize is the number of bytes used on-disk to store active documents. - // If this number is lower than DiskSize, then compaction would free disk - // space. - ActiveSize int64 `json:"data_size"` - // ExternalSize is the size of the documents in the database, as represented - // as JSON, before compression. - ExternalSize int64 `json:"-"` - // Cluster reports the cluster replication configuration variables. - Cluster *ClusterConfig `json:"cluster,omitempty"` - // RawResponse is the raw response body returned by the server, useful if - // you need additional backend-specific information. - // - // For the format of this document, see - // http://docs.couchdb.org/en/2.1.1/api/database/common.html#get--db - RawResponse json.RawMessage `json:"-"` -} - -// ClusterConfig contains the cluster configuration for the database. -type ClusterConfig struct { - Replicas int `json:"n"` - Shards int `json:"q"` - ReadQuorum int `json:"r"` - WriteQuorum int `json:"w"` -} - -// Stats returns database statistics. -// -// See https://docs.couchdb.org/en/stable/api/database/common.html#get--db -func (db *DB) Stats(ctx context.Context) (*DBStats, error) { - if db.err != nil { - return nil, db.err - } - i, err := db.driverDB.Stats(ctx) - if err != nil { - return nil, err - } - return driverStats2kivikStats(i), nil -} - -func driverStats2kivikStats(i *driver.DBStats) *DBStats { - var cluster *ClusterConfig - if i.Cluster != nil { - c := ClusterConfig(*i.Cluster) - cluster = &c - } - return &DBStats{ - Name: i.Name, - CompactRunning: i.CompactRunning, - DocCount: i.DocCount, - DeletedCount: i.DeletedCount, - UpdateSeq: i.UpdateSeq, - DiskSize: i.DiskSize, - ActiveSize: i.ActiveSize, - ExternalSize: i.ExternalSize, - Cluster: cluster, - RawResponse: i.RawResponse, - } -} - -// Compact begins compaction of the database. Check the CompactRunning field -// returned by Info() to see if the compaction has completed. -// See http://docs.couchdb.org/en/2.0.0/api/database/compact.html#db-compact -// -// This method may return immediately, or may wait for the compaction to -// complete before returning, depending on the backend implementation. In -// particular, CouchDB triggers the compaction and returns immediately, whereas -// PouchDB waits until compaction has completed, before returning. -func (db *DB) Compact(ctx context.Context) error { - if db.err != nil { - return db.err - } - return db.driverDB.Compact(ctx) -} - -// CompactView compats the view indexes associated with the specified design -// document. -// See http://docs.couchdb.org/en/2.0.0/api/database/compact.html#db-compact-design-doc -// -// This method may return immediately, or may wait for the compaction to -// complete before returning, depending on the backend implementation. In -// particular, CouchDB triggers the compaction and returns immediately, whereas -// PouchDB waits until compaction has completed, before returning. -func (db *DB) CompactView(ctx context.Context, ddocID string) error { - return db.driverDB.CompactView(ctx, ddocID) -} - -// ViewCleanup removes view index files that are no longer required as a result -// of changed views within design documents. -// See http://docs.couchdb.org/en/2.0.0/api/database/compact.html#db-view-cleanup -func (db *DB) ViewCleanup(ctx context.Context) error { - if db.err != nil { - return db.err - } - return db.driverDB.ViewCleanup(ctx) -} - -// Security returns the database's security document. -// See http://couchdb.readthedocs.io/en/latest/api/database/security.html#get--db-_security -func (db *DB) Security(ctx context.Context) (*Security, error) { - if db.err != nil { - return nil, db.err - } - s, err := db.driverDB.Security(ctx) - if err != nil { - return nil, err - } - return &Security{ - Admins: Members(s.Admins), - Members: Members(s.Members), - }, err -} - -// SetSecurity sets the database's security document. -// See http://couchdb.readthedocs.io/en/latest/api/database/security.html#put--db-_security -func (db *DB) SetSecurity(ctx context.Context, security *Security) error { - if db.err != nil { - return db.err - } - if security == nil { - return missingArg("security") - } - sec := &driver.Security{ - Admins: driver.Members(security.Admins), - Members: driver.Members(security.Members), - } - return db.driverDB.SetSecurity(ctx, sec) -} - -// Copy copies the source document to a new document with an ID of targetID. If -// the database backend does not support COPY directly, the operation will be -// emulated with a Get followed by Put. The target will be an exact copy of the -// source, with only the ID and revision changed. -// -// See http://docs.couchdb.org/en/2.0.0/api/document/common.html#copy--db-docid -func (db *DB) Copy(ctx context.Context, targetID, sourceID string, options ...Options) (targetRev string, err error) { - if db.err != nil { - return "", db.err - } - if targetID == "" { - return "", missingArg("targetID") - } - if sourceID == "" { - return "", missingArg("sourceID") - } - opts := mergeOptions(options...) - if copier, ok := db.driverDB.(driver.Copier); ok { - return copier.Copy(ctx, targetID, sourceID, opts) - } - var doc map[string]interface{} - if err = db.Get(ctx, sourceID, opts).ScanDoc(&doc); err != nil { - return "", err - } - delete(doc, "_rev") - doc["_id"] = targetID - delete(opts, "rev") // rev has a completely different meaning for Copy and Put - return db.Put(ctx, targetID, doc, opts) -} - -// PutAttachment uploads the supplied content as an attachment to the specified -// document. -func (db *DB) PutAttachment(ctx context.Context, docID, rev string, att *Attachment, options ...Options) (newRev string, err error) { - if db.err != nil { - return "", db.err - } - if docID == "" { - return "", missingArg("docID") - } - if e := att.validate(); e != nil { - return "", e - } - a := driver.Attachment(*att) - opts := mergeOptions(options...) - if rv, ok := opts["rev"].(string); ok && rv != "" { - rev = rv - } - return db.driverDB.PutAttachment(ctx, docID, rev, &a, mergeOptions(options...)) -} - -// GetAttachment returns a file attachment associated with the document. -func (db *DB) GetAttachment(ctx context.Context, docID, filename string, options ...Options) (*Attachment, error) { - if db.err != nil { - return nil, db.err - } - if docID == "" { - return nil, missingArg("docID") - } - if filename == "" { - return nil, missingArg("filename") - } - att, err := db.driverDB.GetAttachment(ctx, docID, filename, mergeOptions(options...)) - if err != nil { - return nil, err - } - a := Attachment(*att) - return &a, nil -} - -type nilContentReader struct{} - -var _ io.ReadCloser = &nilContentReader{} - -func (c nilContentReader) Read(_ []byte) (int, error) { return 0, io.EOF } -func (c nilContentReader) Close() error { return nil } - -var nilContent = nilContentReader{} - -// GetAttachmentMeta returns meta data about an attachment. The attachment -// content returned will be empty. -func (db *DB) GetAttachmentMeta(ctx context.Context, docID, filename string, options ...Options) (*Attachment, error) { - if db.err != nil { - return nil, db.err - } - if docID == "" { - return nil, missingArg("docID") - } - if filename == "" { - return nil, missingArg("filename") - } - var att *Attachment - if metaer, ok := db.driverDB.(driver.AttachmentMetaGetter); ok { - a, err := metaer.GetAttachmentMeta(ctx, docID, filename, mergeOptions(options...)) - if err != nil { - return nil, err - } - att = new(Attachment) - *att = Attachment(*a) - } else { - var err error - att, err = db.GetAttachment(ctx, docID, filename, options...) - if err != nil { - return nil, err - } - } - if att.Content != nil { - _ = att.Content.Close() // Ensure this is closed - } - att.Content = nilContent - return att, nil -} - -// DeleteAttachment deletes an attachment from a document, returning the -// document's new revision. The revision may be provided via options, which -// takes priority over the rev argument. -func (db *DB) DeleteAttachment(ctx context.Context, docID, rev, filename string, options ...Options) (newRev string, err error) { - if db.err != nil { - return "", db.err - } - if docID == "" { - return "", missingArg("docID") - } - if filename == "" { - return "", missingArg("filename") - } - opts := mergeOptions(options...) - if rv, ok := opts["rev"].(string); ok && rv != "" { - rev = rv - } - return db.driverDB.DeleteAttachment(ctx, docID, rev, filename, opts) -} - -// PurgeResult is the result of a purge request. -type PurgeResult struct { - // Seq is the purge sequence number. - Seq int64 `json:"purge_seq"` - // Purged is a map of document ids to revisions, indicated the - // document/revision pairs that were successfully purged. - Purged map[string][]string `json:"purged"` -} - -// Purge permanently removes the reference to deleted documents from the -// database. Normal deletion only marks the document with the key/value pair -// `_deleted=true`, to ensure proper replication of deleted documents. By -// using Purge, the document can be completely removed. But note that this -// operation is not replication safe, so great care must be taken when using -// Purge, and this should only be used as a last resort. -// -// Purge expects as input a map with document ID as key, and slice of -// revisions as value. -func (db *DB) Purge(ctx context.Context, docRevMap map[string][]string) (*PurgeResult, error) { - if db.err != nil { - return nil, db.err - } - if purger, ok := db.driverDB.(driver.Purger); ok { - res, err := purger.Purge(ctx, docRevMap) - if err != nil { - return nil, err - } - r := PurgeResult(*res) - return &r, nil - } - return nil, &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: purge not supported by driver"} -} - -// BulkGetReference is a reference to a document given in a BulkGet query. -type BulkGetReference struct { - ID string `json:"id"` - Rev string `json:"rev,omitempty"` - AttsSince string `json:"atts_since,omitempty"` -} - -// BulkGet can be called to query several documents in bulk. It is well suited -// for fetching a specific revision of documents, as replicators do for example, -// or for getting revision history. -// -// See http://docs.couchdb.org/en/stable/api/database/bulk-api.html#db-bulk-get -func (db *DB) BulkGet(ctx context.Context, docs []BulkGetReference, options ...Options) (*Rows, error) { - if db.err != nil { - return nil, db.err - } - bulkGetter, ok := db.driverDB.(driver.BulkGetter) - if !ok { - return nil, &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: bulk get not supported by driver"} - } - refs := make([]driver.BulkGetReference, len(docs)) - for i, ref := range docs { - refs[i] = driver.BulkGetReference(ref) - } - rowsi, err := bulkGetter.BulkGet(ctx, refs, mergeOptions(options...)) - if err != nil { - return nil, err - } - return newRows(ctx, rowsi), nil -} - -// Close cleans up any resources used by the DB. The default CouchDB driver -// does not use this, the default PouchDB driver does. -func (db *DB) Close(ctx context.Context) error { - if db.err != nil { - return db.err - } - if closer, ok := db.driverDB.(driver.DBCloser); ok { - return closer.Close(ctx) - } - return nil -} - -// RevDiff represents a rev diff for a single document, as returned by the -// RevsDiff method. -type RevDiff struct { - Missing []string `json:"missing,omitempty"` - PossibleAncestors []string `json:"possible_ancestors,omitempty"` -} - -// Diffs is a collection of RevDiffs as returned by RevsDiff. The map key is -// the document ID. -type Diffs map[string]RevDiff - -// RevsDiff the subset of document/revision IDs that do not correspond to -// revisions stored in the database. This is used by the replication protocol, -// and is normally never needed otherwise. revMap must marshal to the expected -// format. -// -// Use ID() to return the current document ID, and ScanValue to access the full -// JSON value, which should be of the JSON format: -// -// { -// "missing": ["rev1",...], -// "possible_ancestors": ["revA",...] -// } -// -// See http://docs.couchdb.org/en/stable/api/database/misc.html#db-revs-diff -func (db *DB) RevsDiff(ctx context.Context, revMap interface{}) (*Rows, error) { - if db.err != nil { - return nil, db.err - } - if rd, ok := db.driverDB.(driver.RevsDiffer); ok { - rowsi, err := rd.RevsDiff(ctx, revMap) - if err != nil { - return nil, err - } - return newRows(ctx, rowsi), nil - } - return nil, &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: _revs_diff not supported by driver"} -} - -// PartitionStats contains partition statistics. -type PartitionStats struct { - DBName string - DocCount int64 - DeletedDocCount int64 - Partition string - ActiveSize int64 - ExternalSize int64 - RawResponse json.RawMessage -} - -// PartitionStats returns statistics about the named partition. -// -// See https://docs.couchdb.org/en/stable/api/partitioned-dbs.html#db-partition-partition -func (db *DB) PartitionStats(ctx context.Context, name string) (*PartitionStats, error) { - if db.err != nil { - return nil, db.err - } - if pdb, ok := db.driverDB.(driver.PartitionedDB); ok { - stats, err := pdb.PartitionStats(ctx, name) - if err != nil { - return nil, err - } - s := PartitionStats(*stats) - return &s, nil - } - return nil, &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: partitions not supported by driver"} -} diff --git a/vendor/github.com/go-kivik/kivik/v3/doc.go b/vendor/github.com/go-kivik/kivik/v3/doc.go deleted file mode 100644 index 9b39c0ca8..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/doc.go +++ /dev/null @@ -1,80 +0,0 @@ -/* -Package kivik provides a generic interface to CouchDB or CouchDB-like databases. - -The kivik package must be used in conjunction with a database driver. The -officially supported drivers are: - - - CouchDB: https://github.com/go-kivik/couchdb - - PouchDB: https://github.com/go-kivik/pouchdb (requires GopherJS) - - KivikMock: https://github.com/go-kivik/kivikmock - -The Filesystem and Memory drivers are also available, but in early stages of -development, and so many features do not yet work: - - - Filesystem: https://github.com/go-kivik/fsdb - - MemroyDB: https://github.com/go-kivik/memorydb - -The kivik driver system is modeled after the standard library's `sql` and -`sql/driver` packages, although the client API is completely different due to -the different database models implemented by SQL and NoSQL databases such as -CouchDB. - -Working with JSON - -couchDB stores JSON, so Kivik translates Go data structures to and from JSON as -necessary. The conversion between Go data types and JSON, and vice versa, is -handled automatically according to the rules and behavior described in the -documentationf or the standard library's `encoding/json` package -(https://golang.org/pkg/encoding/json). - -One would be well-advised to become familiar with using `json` struct field -tags (https://golang.org/pkg/encoding/json/#Marshal) when working with JSON -documents. - -Using contexts - -Most Kivik methods take `context.Context` as their first argument. This allows -the cancellation of blocking operations in the case that the result is no -longer needed. A typical use case for a web application would be to cancel a -Kivik request if the remote HTTP client ahs disconnected, rednering the results -of the query irrelevant. - -To learn more about Go's contexts, read the `context` package documentation -(https://golang.org/pkg/context/) and read the Go blog post "Go Concurrency -Patterns: Context" (https://blog.golang.org/context) for example code. - -If in doubt, you can pass `context.TODO()` as the context variable. Example: - - row := db.Get(context.TODO(), "some_doc_id") - -Error Handling - -Kivik returns errors that embed an HTTP status code. In most cases, this is the -HTTP status code returned by the server. The embedded HTTP status code may be -accessed easily using the StatusCode() method, or with a type assertion to -`interface { StatusCode() int }`. Example: - - if statusErr, ok := err.(interface{ StatusCode() int }); ok { - status = statusErr.StatusCode() - } - -Any error that does not conform to this interface will be assumed to represent -a http.StatusInternalServerError status code. - -Authentication - -For common usage, authentication should be as simple as including the authentication credentials in the connection DSN. For example: - - client, err := kivik.New("couch", "http://admin:abc123@localhost:5984/") - -This will connect to `localhost` on port 5984, using the username `admin` and -the password `abc123`. When connecting to CouchDB (as in the above example), -this will use cookie auth (https://docs.couchdb.org/en/stable/api/server/authn.html?highlight=cookie%20auth#cookie-authentication). - -Depending on which driver you use, there may be other ways to authenticate, as -well. At the moment, the CouchDB driver is the only official driver which offers -additional authentication methods. Please refer to the CouchDB package -documentation for details (https://pkg.go.dev/github.com/go-kivik/couchdb/v3). - -*/ -package kivik // import "github.com/go-kivik/kivik/v3" diff --git a/vendor/github.com/go-kivik/kivik/v3/driver/bulkget.go b/vendor/github.com/go-kivik/kivik/v3/driver/bulkget.go deleted file mode 100644 index ebdc37b4c..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/driver/bulkget.go +++ /dev/null @@ -1,17 +0,0 @@ -package driver - -import "context" - -// BulkGetReference is a reference to a document given in a BulkGet query. -type BulkGetReference struct { - ID string `json:"id"` - Rev string `json:"rev,omitempty"` - AttsSince string `json:"atts_since,omitempty"` -} - -// BulkGetter is an optional interface which may be implemented by a driver to -// support bulk get operations. -type BulkGetter interface { - // BulkGet uses the _bulk_get interface to fetch multiple documents in a single query. - BulkGet(ctx context.Context, docs []BulkGetReference, options map[string]interface{}) (Rows, error) -} diff --git a/vendor/github.com/go-kivik/kivik/v3/driver/changes.go b/vendor/github.com/go-kivik/kivik/v3/driver/changes.go deleted file mode 100644 index 10d923059..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/driver/changes.go +++ /dev/null @@ -1,56 +0,0 @@ -package driver - -import "encoding/json" - -// Changes is an iterator of the database changes feed. -type Changes interface { - // Next is called to populate *Change with the next value in the changes - // feed. - // - // Next should return io.EOF when the changes feed is closed by request. - Next(*Change) error - // Close closes the changes feed iterator. - Close() error - // LastSeq returns the last change update sequence. - LastSeq() string - // Pending returns the count of remaining items in the feed - Pending() int64 - // ETag returns the unquoted ETag header, if present. - ETag() string -} - -// Change represents the changes to a single document. -type Change struct { - // ID is the document ID to which the change relates. - ID string `json:"id"` - // Seq is the update sequence for the changes feed. - Seq string `json:"seq"` - // Deleted is set to true for the changes feed, if the document has been - // deleted. - Deleted bool `json:"deleted"` - // Changes represents a list of document leaf revisions for the /_changes - // endpoint. - Changes ChangedRevs `json:"changes"` - // Doc is the raw, un-decoded JSON document. This is only populated when - // include_docs=true is set. - Doc json.RawMessage `json:"doc"` -} - -// ChangedRevs represents a "changes" field of a result in the /_changes stream. -type ChangedRevs []string - -// UnmarshalJSON satisfies the json.Unmarshaler interface -func (c *ChangedRevs) UnmarshalJSON(data []byte) error { - var changes []struct { - Rev string `json:"rev"` - } - if err := json.Unmarshal(data, &changes); err != nil { - return err - } - revs := ChangedRevs(make([]string, len(changes))) - for i, change := range changes { - revs[i] = change.Rev - } - *c = revs - return nil -} diff --git a/vendor/github.com/go-kivik/kivik/v3/driver/config.go b/vendor/github.com/go-kivik/kivik/v3/driver/config.go deleted file mode 100644 index 0a33bf453..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/driver/config.go +++ /dev/null @@ -1,19 +0,0 @@ -package driver - -import "context" - -// Config represents all the config sections. -type Config map[string]ConfigSection - -// ConfigSection represents all key/value pairs for a section of configuration. -type ConfigSection map[string]string - -// Configer is an optional interface that may be implemented by a Client to -// allow access to reading and setting server configuration. -type Configer interface { - Config(ctx context.Context, node string) (Config, error) - ConfigSection(ctx context.Context, node, section string) (ConfigSection, error) - ConfigValue(ctx context.Context, node, section, key string) (string, error) - SetConfigValue(ctx context.Context, node, section, key, value string) (string, error) - DeleteConfigKey(ctx context.Context, node, section, key string) (string, error) -} diff --git a/vendor/github.com/go-kivik/kivik/v3/driver/doc.go b/vendor/github.com/go-kivik/kivik/v3/driver/doc.go deleted file mode 100644 index 19c45bca3..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/driver/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package driver defines interfaces to be implemented by database drivers as -// used by package kivik. -// -// Most code should use package kivik. -package driver // import "github.com/go-kivik/kivik/v3/driver" diff --git a/vendor/github.com/go-kivik/kivik/v3/driver/driver.go b/vendor/github.com/go-kivik/kivik/v3/driver/driver.go deleted file mode 100644 index 41523b5a5..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/driver/driver.go +++ /dev/null @@ -1,438 +0,0 @@ -package driver - -import ( - "context" - "encoding/json" - "io" - "time" -) - -// Driver is the interface that must be implemented by a database driver. -type Driver interface { - // NewClient returns a connection handle to the database. The name is in a - // driver-specific format. - NewClient(name string) (Client, error) -} - -// Version represents a server version response. -type Version struct { - // Version is the version number reported by the server or backend. - Version string - // Vendor is the vendor string reported by the server or backend. - Vendor string - // Features is a list of enabled, optional features. This was added in - // CouchDB 2.1.0, and can be expected to be empty for older versions. - Features []string - // RawResponse is the raw response body as returned by the server. - RawResponse json.RawMessage -} - -// Client is a connection to a database server. -type Client interface { - // Version returns the server implementation's details. - Version(ctx context.Context) (*Version, error) - // AllDBs returns a list of all existing database names. - AllDBs(ctx context.Context, options map[string]interface{}) ([]string, error) - // DBExists returns true if the database exists. - DBExists(ctx context.Context, dbName string, options map[string]interface{}) (bool, error) - // CreateDB creates the requested DB. The dbName is validated as a valid - // CouchDB database name prior to calling this function, so the driver can - // assume a valid name. - CreateDB(ctx context.Context, dbName string, options map[string]interface{}) error - // DestroyDB deletes the requested DB. - DestroyDB(ctx context.Context, dbName string, options map[string]interface{}) error - // DB returns a handleto the requested database - DB(ctx context.Context, dbName string, options map[string]interface{}) (DB, error) -} - -// DBsStatser is an optional interface, added to support CouchDB 2.2.0's -// /_dbs_info endpoint. If this is not supported, or if this method returns -// status 404, Kivik will fall back to calling the method of issuing a -// GET /{db} for each database requested. -type DBsStatser interface { - // DBsStats returns database statistical information for each database - // named in dbNames. The returned values should be in the same order as - // the requested database names, and any missing databases should return - // a nil *DBStats value. - DBsStats(ctx context.Context, dbNames []string) ([]*DBStats, error) -} - -// Replication represents a _replicator document. -type Replication interface { - // The following methods are called just once, when the Replication is first - // returned from Replicate() or GetReplications(). - ReplicationID() string - Source() string - Target() string - StartTime() time.Time - EndTime() time.Time - State() string - Err() error - - // These methods may be triggered by user actions. - - // Delete deletes a replication, which cancels it if it is running. - Delete(context.Context) error - // Update fetches the latest replication state from the server. - Update(context.Context, *ReplicationInfo) error -} - -// ReplicationInfo represents a snap-shot state of a replication, as provided -// by the _active_tasks endpoint. -type ReplicationInfo struct { - DocWriteFailures int64 - DocsRead int64 - DocsWritten int64 - Progress float64 -} - -// ClientReplicator is an optional interface that may be implemented by a Client -// that supports replication between two database. -type ClientReplicator interface { - // Replicate initiates a replication. - Replicate(ctx context.Context, targetDSN, sourceDSN string, options map[string]interface{}) (Replication, error) - // GetReplications returns a list of replicatoins (i.e. all docs in the - // _replicator database) - GetReplications(ctx context.Context, options map[string]interface{}) ([]Replication, error) -} - -// Authenticator is an optional interface that may be implemented by a Client -// that supports authenitcated connections. -type Authenticator interface { - // Authenticate attempts to authenticate the client using an authenticator. - // If the authenticator is not known to the client, an error should be - // returned. - Authenticate(ctx context.Context, authenticator interface{}) error -} - -// DBStats contains database statistics. -type DBStats struct { - Name string `json:"db_name"` - CompactRunning bool `json:"compact_running"` - DocCount int64 `json:"doc_count"` - DeletedCount int64 `json:"doc_del_count"` - UpdateSeq string `json:"update_seq"` - DiskSize int64 `json:"disk_size"` - ActiveSize int64 `json:"data_size"` - ExternalSize int64 `json:"-"` - Cluster *ClusterStats `json:"cluster,omitempty"` - RawResponse json.RawMessage `json:"-"` -} - -// ClusterStats contains the cluster configuration for the database. -type ClusterStats struct { - Replicas int `json:"n"` - Shards int `json:"q"` - ReadQuorum int `json:"r"` - WriteQuorum int `json:"w"` -} - -// Members represents the members of a database security document. -type Members struct { - Names []string `json:"names,omitempty"` - Roles []string `json:"roles,omitempty"` -} - -// Security represents a database security document. -type Security struct { - Admins Members `json:"admins"` - Members Members `json:"members"` -} - -// DB is a database handle. -type DB interface { - // AllDocs returns all of the documents in the database, subject to the - // options provided. - AllDocs(ctx context.Context, options map[string]interface{}) (Rows, error) - // Get fetches the requested document from the database, and returns the - // content length (or -1 if unknown), and an io.ReadCloser to access the - // raw JSON content. - Get(ctx context.Context, docID string, options map[string]interface{}) (*Document, error) - // CreateDoc creates a new doc, with a server-generated ID. - CreateDoc(ctx context.Context, doc interface{}, options map[string]interface{}) (docID, rev string, err error) - // Put writes the document in the database. - Put(ctx context.Context, docID string, doc interface{}, options map[string]interface{}) (rev string, err error) - // Delete marks the specified document as deleted. - Delete(ctx context.Context, docID, rev string, options map[string]interface{}) (newRev string, err error) - // Stats returns database statistics. - Stats(ctx context.Context) (*DBStats, error) - // Compact initiates compaction of the database. - Compact(ctx context.Context) error - // CompactView initiates compaction of the view. - CompactView(ctx context.Context, ddocID string) error - // ViewCleanup cleans up stale view files. - ViewCleanup(ctx context.Context) error - // Security returns the database's security document. - Security(ctx context.Context) (*Security, error) - // SetSecurity sets the database's security document. - SetSecurity(ctx context.Context, security *Security) error - // Changes returns a Rows iterator for the changes feed. In continuous mode, - // the iterator will continue indefinitely, until Close is called. - Changes(ctx context.Context, options map[string]interface{}) (Changes, error) - // PutAttachment uploads an attachment to the specified document, returning - // the new revision. - PutAttachment(ctx context.Context, docID, rev string, att *Attachment, options map[string]interface{}) (newRev string, err error) - // GetAttachment fetches an attachment for the associated document ID. - GetAttachment(ctx context.Context, docID, filename string, options map[string]interface{}) (*Attachment, error) - // DeleteAttachment deletes an attachment from a document, returning the - // document's new revision. - DeleteAttachment(ctx context.Context, docID, rev, filename string, options map[string]interface{}) (newRev string, err error) - // Query performs a query against a view, subject to the options provided. - // ddoc will be the design doc name without the '_design/' previx. - // view will be the view name without the '_view/' prefix. - Query(ctx context.Context, ddoc, view string, options map[string]interface{}) (Rows, error) -} - -// Document represents a single document returned by Get -type Document struct { - // ContentLength is the size of the document response in bytes. - ContentLength int64 - - // Rev is the revision number returned - Rev string - - // Body contains the respons body, either in raw JSON or multipart/related - // format. - Body io.ReadCloser - - // Attachments will be nil except when attachments=true. - Attachments Attachments -} - -// Attachments is an iterator over the attachments included in a document when -// Get is called with `include_docs=true`. -type Attachments interface { - // Next is called to pupulate att with the next attachment in the result - // set. - // - // Next should return io.EOF when there are no more attachments. - Next(att *Attachment) error - - // Close closes the Attachments iterator - Close() error -} - -// Purger is an optional interface which may be implemented by a DB to support -// document purging. -type Purger interface { - // Purge permanently removes the references to deleted documents from the - // database. - Purge(ctx context.Context, docRevMap map[string][]string) (*PurgeResult, error) -} - -// PurgeResult is the result of a purge request. -type PurgeResult struct { - Seq int64 `json:"purge_seq"` - Purged map[string][]string `json:"purged"` -} - -// BulkDocer is an optional interface which may be implemented by a DB to -// support bulk insert/update operations. For any driver that does not support -// the BulkDocer interface, the Put or CreateDoc methods will be called for each -// document to emulate the same functionality, with options passed through -// unaltered. -type BulkDocer interface { - // BulkDocs alls bulk create, update and/or delete operations. It returns an - // iterator over the results. - BulkDocs(ctx context.Context, docs []interface{}, options map[string]interface{}) (BulkResults, error) -} - -// Finder is the old Finder interface, which does not accept options. It -// remains for compatibility with older backends. -// -// Deprecated: Use OptsFinder instead. -type Finder interface { - Find(ctx context.Context, query interface{}) (Rows, error) - CreateIndex(ctx context.Context, ddoc, name string, index interface{}) error - GetIndexes(ctx context.Context) ([]Index, error) - DeleteIndex(ctx context.Context, ddoc, name string) error - Explain(ctx context.Context, query interface{}) (*QueryPlan, error) -} - -// OptsFinder is an optional interface which may be implemented by a DB. The -// Finder interface provides access to the new (in CouchDB 2.0) MongoDB-style -// query interface. -type OptsFinder interface { - // Find executes a query using the new /_find interface. If query is a - // string, []byte, or json.RawMessage, it should be treated as a raw JSON - // payload. Any other type should be marshaled to JSON. - Find(ctx context.Context, query interface{}, options map[string]interface{}) (Rows, error) - // CreateIndex creates an index if it doesn't already exist. If the index - // already exists, it should do nothing. ddoc and name may be empty, in - // which case they should be provided by the backend. If index is a string, - // []byte, or json.RawMessage, it should be treated as a raw JSON payload. - // Any other type should be marshaled to JSON. - CreateIndex(ctx context.Context, ddoc, name string, index interface{}, options map[string]interface{}) error - // GetIndexes returns a list of all indexes in the database. - GetIndexes(ctx context.Context, options map[string]interface{}) ([]Index, error) - // Delete deletes the requested index. - DeleteIndex(ctx context.Context, ddoc, name string, options map[string]interface{}) error - // Explain returns the query plan for a given query. Explain takes the same - // arguments as Find. - Explain(ctx context.Context, query interface{}, options map[string]interface{}) (*QueryPlan, error) -} - -// QueryPlan is the response of an Explain query. -type QueryPlan struct { - DBName string `json:"dbname"` - Index map[string]interface{} `json:"index"` - Selector map[string]interface{} `json:"selector"` - Options map[string]interface{} `json:"opts"` - Limit int64 `json:"limit"` - Skip int64 `json:"skip"` - - // Fields is the list of fields to be returned in the result set, or - // an empty list if all fields are to be returned. - Fields []interface{} `json:"fields"` - Range map[string]interface{} `json:"range"` -} - -// Index is a MonboDB-style index definition. -type Index struct { - DesignDoc string `json:"ddoc,omitempty"` - Name string `json:"name"` - Type string `json:"type"` - Definition interface{} `json:"def"` -} - -// Attachment represents a file attachment to a document. -type Attachment struct { - Filename string `json:"-"` - ContentType string `json:"content_type"` - Stub bool `json:"stub"` - Follows bool `json:"follows"` - Content io.ReadCloser `json:"-"` - Size int64 `json:"length"` - ContentEncoding string `json:"encoding"` - EncodedLength int64 `json:"encoded_length"` - RevPos int64 `json:"revpos"` - Digest string `json:"digest"` -} - -// AttachmentMetaGetter is an optional interface which may be satisfied by a -// DB. If satisfied, it may be used to fetch meta data about an attachment. If -// not satisfied, GetAttachment will be used instead. -type AttachmentMetaGetter interface { - // GetAttachmentMetaOpts returns meta information about an attachment. - GetAttachmentMeta(ctx context.Context, docID, filename string, options map[string]interface{}) (*Attachment, error) -} - -// BulkResult is the result of a single doc update in a BulkDocs request. -type BulkResult struct { - ID string `json:"id"` - Rev string `json:"rev"` - Error error -} - -// BulkResults is an iterator over the results for a BulkDocs call. -type BulkResults interface { - // Next is called to populate *BulkResult with the values of the next bulk - // result in the set. - // - // Next should return io.EOF when there are no more results. - Next(*BulkResult) error - // Close closes the bulk results iterator. - Close() error -} - -// MetaGetter is an optional interface that may be implemented by a DB. If not -// implemented, the Get method will be used to emulate the functionality, with -// options passed through unaltered. -type MetaGetter interface { - // GetMeta returns the document size and revision of the requested document. - // GetMeta should accept the same options as the Get method. - GetMeta(ctx context.Context, docID string, options map[string]interface{}) (size int64, rev string, err error) -} - -// Flusher is an optional interface that may be implemented by a DB that can -// force a flush of the database backend file(s) to disk or other permanent -// storage. -type Flusher interface { - // Flush requests a flush of disk cache to disk or other permanent storage. - // - // See http://docs.couchdb.org/en/2.0.0/api/database/compact.html#db-ensure-full-commit - Flush(ctx context.Context) error -} - -// Copier is an optional interface that may be implemented by a DB. -// -// If a DB does implement Copier, Copy() functions will use it. If a DB does -// not implement the Copier interface, the functionality will be emulated by -// calling Get followed by Put, with options passed through unaltered, except -// that the 'rev' option will be removed for the Put call. -type Copier interface { - Copy(ctx context.Context, targetID, sourceID string, options map[string]interface{}) (targetRev string, err error) -} - -// DesignDocer is an optional interface that may be implemented by a DB. -type DesignDocer interface { - // DesignDocs returns all of the design documents in the database, subject - // to the options provided. - DesignDocs(ctx context.Context, options map[string]interface{}) (Rows, error) -} - -// LocalDocer is an optional interface that may be implemented by a DB. -type LocalDocer interface { - // LocalDocs returns all of the local documents in the database, subject to - // the options provided. - LocalDocs(ctx context.Context, options map[string]interface{}) (Rows, error) -} - -// Pinger is an optional interface that may be implemented by a Client. When -// not implemented, Kivik will call Version instead, to determine if the -// database is usable. -type Pinger interface { - // Ping returns true if the database is online and available for requests. - Ping(ctx context.Context) (bool, error) -} - -// ClusterMembership contains the list of known nodes, and cluster nodes, as returned -// by the /_membership endpoint. -// See https://docs.couchdb.org/en/latest/api/server/common.html#get--_membership -type ClusterMembership struct { - AllNodes []string `json:"all_nodes"` - ClusterNodes []string `json:"cluster_nodes"` -} - -// Cluster is an optional interface that may be implemented by a Client to -// support CouchDB cluster configuration operations. -type Cluster interface { - // ClusterStatus returns the current cluster status. - ClusterStatus(ctx context.Context, options map[string]interface{}) (string, error) - // ClusterSetup performs the action specified by action. - ClusterSetup(ctx context.Context, action interface{}) error -} - -// Cluster2 extends Cluster (and is merged with it in kivik v4), to allow -// access to the /_membership endpoint. -type Cluster2 interface { - // Membership returns a list of all known nodes, and all nodes configured as - // part of the cluster. - Membership(ctx context.Context) (*ClusterMembership, error) -} - -// ClientCloser is an optional interface that may be implemented by a Client -// to clean up resources when a Client is no longer needed. -type ClientCloser interface { - Close(ctx context.Context) error -} - -// DBCloser is an optional interface that may be implemented by a DB to clean -// up resources when a DB is no longer needed. -type DBCloser interface { - Close(ctx context.Context) error -} - -// RevDiff represents a rev diff for a single document, as returned by the -// RevsDiff method. -type RevDiff struct { - Missing []string `json:"missing,omitempty"` - PossibleAncestors []string `json:"possible_ancestors,omitempty"` -} - -// RevsDiffer is an optional interface that may be implemented by a DB. -type RevsDiffer interface { - // RevsDiff returns a Rows iterator, which should populate the ID and Value - // fields, and nothing else. - RevsDiff(ctx context.Context, revMap interface{}) (Rows, error) -} diff --git a/vendor/github.com/go-kivik/kivik/v3/driver/errors.go b/vendor/github.com/go-kivik/kivik/v3/driver/errors.go deleted file mode 100644 index 79004fd53..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/driver/errors.go +++ /dev/null @@ -1,11 +0,0 @@ -package driver - -type err string - -func (e err) Error() string { - return string(e) -} - -// EOQ should be returned by a view iterator at the end of each query result -// set. -const EOQ = err("EOQ") diff --git a/vendor/github.com/go-kivik/kivik/v3/driver/partition.go b/vendor/github.com/go-kivik/kivik/v3/driver/partition.go deleted file mode 100644 index 35d56a132..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/driver/partition.go +++ /dev/null @@ -1,24 +0,0 @@ -package driver - -import ( - "context" - "encoding/json" -) - -// PartitionedDB is an optional interface that may be satisfied by a DB to -// support querying partitoin-specific information. -type PartitionedDB interface { - // PartitionStats returns information about the named partition. - PartitionStats(ctx context.Context, name string) (*PartitionStats, error) -} - -// PartitionStats contains partition statistics. -type PartitionStats struct { - DBName string - DocCount int64 - DeletedDocCount int64 - Partition string - ActiveSize int64 - ExternalSize int64 - RawResponse json.RawMessage -} diff --git a/vendor/github.com/go-kivik/kivik/v3/driver/rows.go b/vendor/github.com/go-kivik/kivik/v3/driver/rows.go deleted file mode 100644 index 61411ad3f..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/driver/rows.go +++ /dev/null @@ -1,65 +0,0 @@ -package driver - -import ( - "encoding/json" -) - -// Row is a generic view result row. -type Row struct { - // ID is the document ID of the result. - ID string `json:"id"` - // Key is the view key of the result. For built-in views, this is the same - // as ID. - Key json.RawMessage `json:"key"` - // Value is the raw, un-decoded JSON value. For most built-in views (such as - // /_all_docs), this is `{"rev":"X-xxx"}`. - Value json.RawMessage `json:"value"` - // Doc is the raw, un-decoded JSON document. This is only populated by views - // which return docs, such as /_all_docs?include_docs=true. - Doc json.RawMessage `json:"doc"` - // Error represents the error for any row not fetched. Usually just - // 'not_found'. - Error error `json:"-"` -} - -// Rows is an iterator over a view's results. -type Rows interface { - // Next is called to populate row with the next row in the result set. - // - // Next should return io.EOF when there are no more rows. - Next(row *Row) error - // Close closes the rows iterator. - Close() error - // UpdateSeq is the update sequence of the database, if requested in the - // result set. - UpdateSeq() string - // Offset is the offset where the result set starts. - Offset() int64 - // TotalRows is the number of documents in the database/view. - TotalRows() int64 -} - -// RowsWarner is an optional interface that may be implemented by a Rows, which -// allows a rows iterator to return a non-fatal warning. This is intended for -// use by the /_find endpoint, which generates warnings when indexes don't -// exist. -type RowsWarner interface { - // Warning returns the warning generated by the query, if any. - Warning() string -} - -// Bookmarker is an optional interface that may be implemented by a Rows for -// returning a paging bookmark. -type Bookmarker interface { - // Bookmark returns an opaque bookmark string used for paging, added to - // the /_find endpoint in CouchDB 2.1.1. See the CouchDB documentation for - // usage: http://docs.couchdb.org/en/2.1.1/api/database/find.html#pagination - Bookmark() string -} - -// QueryIndexer is an optional interface that may be implemented by a Rows, -// which allows a rows iterator to return a query index value. This is intended -// for use by multi-query queries to views. -type QueryIndexer interface { - QueryIndex() int -} diff --git a/vendor/github.com/go-kivik/kivik/v3/driver/session.go b/vendor/github.com/go-kivik/kivik/v3/driver/session.go deleted file mode 100644 index 4e73f23b7..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/driver/session.go +++ /dev/null @@ -1,33 +0,0 @@ -package driver - -import ( - "context" - "encoding/json" -) - -// Session is a copy of kivik.Session -type Session struct { - // Name is the name of the authenticated user. - Name string - // Roles is a list of roles the user belongs to. - Roles []string - // AuthenticationMethod is the authentication method that was used for this - // session. - AuthenticationMethod string - // AuthenticationDB is the user database against which authentication was - // performed. - AuthenticationDB string - // AuthenticationHandlers is a list of authentication handlers configured on - // the server. - AuthenticationHandlers []string - // RawResponse is the raw JSON response sent by the server, useful for - // custom backends which may provide additional fields. - RawResponse json.RawMessage -} - -// Sessioner is an optional interface that a Client may satisfy to provide -// access to the authenticated session information. -type Sessioner interface { - // Session returns information about the authenticated user. - Session(ctx context.Context) (*Session, error) -} diff --git a/vendor/github.com/go-kivik/kivik/v3/driver/updates.go b/vendor/github.com/go-kivik/kivik/v3/driver/updates.go deleted file mode 100644 index 44aa92c81..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/driver/updates.go +++ /dev/null @@ -1,29 +0,0 @@ -package driver - -import "context" - -// DBUpdate represents a database update event. -type DBUpdate struct { - DBName string `json:"db_name"` - Type string `json:"type"` - Seq string `json:"seq"` -} - -// DBUpdates is a DBUpdates iterator. -type DBUpdates interface { - // Next is called to populate DBUpdate with the values of the next update in - // the feed. - // - // Next should return io.EOF when the feed is closed normally. - Next(*DBUpdate) error - // Close closes the iterator. - Close() error -} - -// DBUpdater is an optional interface that may be implemented by a Client to -// provide access to the DB Updates feed. -type DBUpdater interface { - // DBUpdates must return a DBUpdate iterator. The context, or the iterator's - // Close method, may be used to close the iterator. - DBUpdates(context.Context) (DBUpdates, error) -} diff --git a/vendor/github.com/go-kivik/kivik/v3/errors.go b/vendor/github.com/go-kivik/kivik/v3/errors.go deleted file mode 100644 index 7b45c6622..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/errors.go +++ /dev/null @@ -1,154 +0,0 @@ -package kivik - -import ( - "fmt" - "net/http" - "strings" - - "golang.org/x/xerrors" -) - -// Error represents an error returned by Kivik. -// -// This type definition is not guaranteed to remain stable, or even exported. -// When examining errors programatically, you should rely instead on the -// StatusCode() function in this package, rather than on directly observing -// the fields of this type. -type Error struct { - // HTTPStatus is the HTTP status code associated with this error. Normally - // this is the actual HTTP status returned by the server, but in some cases - // it may be generated by Kivik directly. Check the FromServer value if - // the distinction matters to you. - HTTPStatus int - - // FromServer is set to true if the error was returned by the server. - // This field is deprecated and will soon be removed. - FromServer bool - - // Message is the error message. - Message string - - // Err is the originating error, if any. - Err error -} - -var ( - _ error = &Error{} - _ statusCoder = &Error{} - _ causer = &Error{} -) - -func (e *Error) Error() string { - if e.Err == nil { - return e.msg() - } - if e.Message == "" { - return e.Err.Error() - } - return e.Message + ": " + e.Err.Error() -} - -// StatusCode returns the HTTP status code associated with the error, or 500 -// (internal server error), if none. -func (e *Error) StatusCode() int { - if e.HTTPStatus == 0 { - return http.StatusInternalServerError - } - return e.HTTPStatus -} - -// Cause satisfies the github.com/pkg/errors.causer interface by returning e.Err. -func (e *Error) Cause() error { - return e.Err -} - -// Unwrap satisfies the Go 1.13 errors.Wrapper interface -// (golang.org/x/xerrors.Unwrap for older versions of Go). -func (e *Error) Unwrap() error { - return e.Err -} - -// Format implements fmt.Formatter -func (e *Error) Format(f fmt.State, c rune) { - parts := make([]string, 0, 3) - if e.Message != "" { - parts = append(parts, e.Message) - } - switch c { - case 'v': - if f.Flag('+') { - var prefix string - if e.FromServer { - prefix = "server responded with" - } else { - prefix = "kivik generated" - } - parts = append(parts, fmt.Sprintf("%s %d / %s", prefix, e.HTTPStatus, http.StatusText(e.HTTPStatus))) - } - } - if e.Err != nil { - parts = append(parts, e.Err.Error()) - } - _, _ = fmt.Fprint(f, strings.Join(parts, ": ")) -} - -func (e *Error) msg() string { - switch e.Message { - case "": - return http.StatusText(e.StatusCode()) - default: - return e.Message - } -} - -type statusCoder interface { - StatusCode() int -} - -type causer interface { - Cause() error -} - -// StatusCode returns the HTTP status code embedded in the error, or 500 -// (internal server error), if there was no specified status code. If err is -// nil, StatusCode returns 0. This provides a convenient way to determine the -// precise nature of a Kivik-returned error. -// -// For example, to panic for all but NotFound errors: -// -// err := db.Get(context.TODO(), "docID").ScanDoc(&doc) -// if kivik.StatusCode(err) == kivik.StatusNotFound { -// return -// } -// if err != nil { -// panic(err) -// } -// -// This method uses the statusCoder interface, which is not exported by this -// package, but is considered part of the stable public API. Driver -// implementations are expected to return errors which conform to this -// interface. -// -// type statusCoder interface { -// StatusCode() (httpStatusCode int) -// } -func StatusCode(err error) int { - if err == nil { - return 0 - } - var coder statusCoder - for { - if xerrors.As(err, &coder) { - return coder.StatusCode() - } - if uw := xerrors.Unwrap(err); uw != nil { - err = uw - continue - } - if c, ok := err.(causer); ok { - err = c.Cause() - continue - } - return http.StatusInternalServerError - } -} diff --git a/vendor/github.com/go-kivik/kivik/v3/find.go b/vendor/github.com/go-kivik/kivik/v3/find.go deleted file mode 100644 index e4bce58bc..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/find.go +++ /dev/null @@ -1,128 +0,0 @@ -package kivik - -import ( - "context" - "net/http" - - "github.com/go-kivik/kivik/v3/driver" -) - -var findNotImplemented = &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: driver does not support Find interface"} - -// Find executes a query using the new /_find interface. The query must be -// JSON-marshalable to a valid query. -// See http://docs.couchdb.org/en/2.0.0/api/database/find.html#db-find -func (db *DB) Find(ctx context.Context, query interface{}, options ...Options) (*Rows, error) { - if finder, ok := db.driverDB.(driver.OptsFinder); ok { - rowsi, err := finder.Find(ctx, query, mergeOptions(options...)) - if err != nil { - return nil, err - } - return newRows(ctx, rowsi), nil - } - // nolint:staticcheck - if finder, ok := db.driverDB.(driver.Finder); ok { - rowsi, err := finder.Find(ctx, query) - if err != nil { - return nil, err - } - return newRows(ctx, rowsi), nil - } - return nil, findNotImplemented -} - -// CreateIndex creates an index if it doesn't already exist. ddoc and name may -// be empty, in which case they will be auto-generated. index must be a valid -// index object, as described here: -// http://docs.couchdb.org/en/stable/api/database/find.html#db-index -func (db *DB) CreateIndex(ctx context.Context, ddoc, name string, index interface{}, options ...Options) error { - if finder, ok := db.driverDB.(driver.OptsFinder); ok { - return finder.CreateIndex(ctx, ddoc, name, index, mergeOptions(options...)) - } - // nolint:staticcheck - if finder, ok := db.driverDB.(driver.Finder); ok { - return finder.CreateIndex(ctx, ddoc, name, index) - } - return findNotImplemented -} - -// DeleteIndex deletes the requested index. -func (db *DB) DeleteIndex(ctx context.Context, ddoc, name string, options ...Options) error { - if finder, ok := db.driverDB.(driver.OptsFinder); ok { - return finder.DeleteIndex(ctx, ddoc, name, mergeOptions(options...)) - } - // nolint:staticcheck - if finder, ok := db.driverDB.(driver.Finder); ok { - return finder.DeleteIndex(ctx, ddoc, name) - } - return findNotImplemented -} - -// Index is a MonboDB-style index definition. -type Index struct { - DesignDoc string `json:"ddoc,omitempty"` - Name string `json:"name"` - Type string `json:"type"` - Definition interface{} `json:"def"` -} - -// GetIndexes returns the indexes defined on the current database. -func (db *DB) GetIndexes(ctx context.Context, options ...Options) ([]Index, error) { - if finder, ok := db.driverDB.(driver.OptsFinder); ok { - dIndexes, err := finder.GetIndexes(ctx, mergeOptions(options...)) - indexes := make([]Index, len(dIndexes)) - for i, index := range dIndexes { - indexes[i] = Index(index) - } - return indexes, err - } - // nolint:staticcheck - if finder, ok := db.driverDB.(driver.Finder); ok { - dIndexes, err := finder.GetIndexes(ctx) - indexes := make([]Index, len(dIndexes)) - for i, index := range dIndexes { - indexes[i] = Index(index) - } - return indexes, err - } - return nil, findNotImplemented -} - -// QueryPlan is the query execution plan for a query, as returned by the Explain -// function. -type QueryPlan struct { - DBName string `json:"dbname"` - Index map[string]interface{} `json:"index"` - Selector map[string]interface{} `json:"selector"` - Options map[string]interface{} `json:"opts"` - Limit int64 `json:"limit"` - Skip int64 `json:"skip"` - - // Fields is the list of fields to be returned in the result set, or - // an empty list if all fields are to be returned. - Fields []interface{} `json:"fields"` - Range map[string]interface{} `json:"range"` -} - -// Explain returns the query plan for a given query. Explain takes the same -// arguments as Find. -func (db *DB) Explain(ctx context.Context, query interface{}, options ...Options) (*QueryPlan, error) { - if explainer, ok := db.driverDB.(driver.OptsFinder); ok { - plan, err := explainer.Explain(ctx, query, mergeOptions(options...)) - if err != nil { - return nil, err - } - qp := QueryPlan(*plan) - return &qp, nil - } - // nolint:staticcheck - if explainer, ok := db.driverDB.(driver.Finder); ok { - plan, err := explainer.Explain(ctx, query) - if err != nil { - return nil, err - } - qp := QueryPlan(*plan) - return &qp, nil - } - return nil, findNotImplemented -} diff --git a/vendor/github.com/go-kivik/kivik/v3/internal/registry/registry.go b/vendor/github.com/go-kivik/kivik/v3/internal/registry/registry.go deleted file mode 100644 index ef131fbef..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/internal/registry/registry.go +++ /dev/null @@ -1,36 +0,0 @@ -// Package registry handles driver registrations. It's in a separate package -// to facilitate testing. -package registry - -import ( - "sync" - - "github.com/go-kivik/kivik/v3/driver" -) - -var ( - driversMu sync.RWMutex - drivers = make(map[string]driver.Driver) -) - -// Register makes a database driver available by the provided name. If Register -// is called twice with the same name or if driver is nil, it panics. -func Register(name string, driver driver.Driver) { - driversMu.Lock() - defer driversMu.Unlock() - if driver == nil { - panic("kivik: Register driver is nil") - } - if _, dup := drivers[name]; dup { - panic("kivik: Register called twice for driver " + name) - } - drivers[name] = driver -} - -// Driver returns the driver registered with the requested name, or nil if -// it has not been registered. -func Driver(name string) driver.Driver { - driversMu.RLock() - defer driversMu.RUnlock() - return drivers[name] -} diff --git a/vendor/github.com/go-kivik/kivik/v3/iterator.go b/vendor/github.com/go-kivik/kivik/v3/iterator.go deleted file mode 100644 index e4644dbe8..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/iterator.go +++ /dev/null @@ -1,171 +0,0 @@ -package kivik - -import ( - "context" - "encoding/json" - "io" - "net/http" - "reflect" - "sync" - - "github.com/go-kivik/kivik/v3/driver" -) - -type iterator interface { - Next(interface{}) error - Close() error -} - -type iter struct { - feed iterator - - mu sync.RWMutex - ready bool // Set to true once Next() has been called - closed bool - lasterr error // non-nil only if closed is true - eoq bool - - cancel func() // cancel function to exit context goroutine when iterator is closed - - curVal interface{} -} - -func (i *iter) rlock() (unlock func(), err error) { - i.mu.RLock() - if i.closed { - i.mu.RUnlock() - return nil, &Error{HTTPStatus: http.StatusBadRequest, Message: "kivik: Iterator is closed"} - } - if !i.ready { - i.mu.RUnlock() - return nil, &Error{HTTPStatus: http.StatusBadRequest, Message: "kivik: Iterator access before calling Next"} - } - return func() { i.mu.RUnlock() }, nil -} - -// newIterator instantiates a new iterator. -// -// ctx is a possibly-cancellable context -// zeroValue is an empty instance of the data type this iterator iterates over -// feed is the iterator interface, which typically wraps a driver.X iterator -func newIterator(ctx context.Context, feed iterator, zeroValue interface{}) *iter { - i := &iter{ - feed: feed, - curVal: zeroValue, - } - ctx, i.cancel = context.WithCancel(ctx) - go i.awaitDone(ctx) - return i -} - -// awaitDone blocks until the rows are closed or the context is cancelled, then closes the iterator if it's still open. -func (i *iter) awaitDone(ctx context.Context) { - <-ctx.Done() - _ = i.close(ctx.Err()) -} - -// Next prepares the next iterator result value for reading. It returns true on -// success, or false if there is no next result or an error occurs while -// preparing it. Err should be consulted to distinguish between the two. -func (i *iter) Next() bool { - doClose, ok := i.next() - if doClose { - _ = i.Close() - } - return ok -} - -func (i *iter) next() (doClose, ok bool) { - i.mu.RLock() - defer i.mu.RUnlock() - if i.closed { - return false, false - } - i.ready = true - i.eoq = false - err := i.feed.Next(i.curVal) - if err == driver.EOQ { - i.eoq = true - err = nil - } - i.lasterr = err - if i.lasterr != nil { - return true, false - } - return false, true -} - -// EOQ returns true if the iterator has reached the end of a query in a -// multi-query query. When EOQ is true, the row data will not have been -// updated. It is common to simply `continue` in case of EOQ, unless you care -// about the per-query metadata, such as offset, total rows, etc. -func (i *iter) EOQ() bool { - return i.eoq -} - -// Close closes the Iterator, preventing further enumeration, and freeing any -// resources (such as the http request body) of the underlying feed. If Next is -// called and there are no further results, Iterator is closed automatically and -// it will suffice to check the result of Err. Close is idempotent and does not -// affect the result of Err. -func (i *iter) Close() error { - return i.close(nil) -} - -func (i *iter) close(err error) error { - i.mu.Lock() - defer i.mu.Unlock() - if i.closed { - return nil - } - i.closed = true - - if i.lasterr == nil { - i.lasterr = err - } - - err = i.feed.Close() - - if i.cancel != nil { - i.cancel() - } - - return err -} - -// Err returns the error, if any, that was encountered during iteration. Err -// may be called after an explicit or implicit Close. -func (i *iter) Err() error { - i.mu.RLock() - defer i.mu.RUnlock() - if i.lasterr == io.EOF { - return nil - } - return i.lasterr -} - -func scan(dest interface{}, val json.RawMessage) error { - if reflect.TypeOf(dest).Kind() != reflect.Ptr { - return errNonPtr - } - switch d := dest.(type) { - case *[]byte: - if d == nil { - return errNilPtr - } - tgt := make([]byte, len(val)) - copy(tgt, val) - *d = tgt - return nil - case *json.RawMessage: - if d == nil { - return errNilPtr - } - *d = val - return nil - } - if err := json.Unmarshal(val, dest); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/go-kivik/kivik/v3/kivik.go b/vendor/github.com/go-kivik/kivik/v3/kivik.go deleted file mode 100644 index fc005343d..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/kivik.go +++ /dev/null @@ -1,206 +0,0 @@ -package kivik - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - - "github.com/go-kivik/kivik/v3/driver" - "github.com/go-kivik/kivik/v3/internal/registry" -) - -// Client is a client connection handle to a CouchDB-like server. -type Client struct { - dsn string - driverName string - driverClient driver.Client -} - -// Options is a collection of options. The keys and values are backend specific. -type Options map[string]interface{} - -func mergeOptions(otherOpts ...Options) Options { - if len(otherOpts) == 0 { - return nil - } - options := make(Options) - for _, opts := range otherOpts { - for k, v := range opts { - options[k] = v - } - } - if len(options) == 0 { - return nil - } - return options -} - -// Register makes a database driver available by the provided name. If Register -// is called twice with the same name or if driver is nil, it panics. -func Register(name string, driver driver.Driver) { - registry.Register(name, driver) -} - -// New creates a new client object specified by its database driver name -// and a driver-specific data source name. -func New(driverName, dataSourceName string) (*Client, error) { - driveri := registry.Driver(driverName) - if driveri == nil { - return nil, &Error{HTTPStatus: http.StatusBadRequest, Message: fmt.Sprintf("kivik: unknown driver %q (forgotten import?)", driverName)} - } - client, err := driveri.NewClient(dataSourceName) - if err != nil { - return nil, err - } - return &Client{ - dsn: dataSourceName, - driverName: driverName, - driverClient: client, - }, nil -} - -// Driver returns the name of the driver string used to connect this client. -func (c *Client) Driver() string { - return c.driverName -} - -// DSN returns the data source name used to connect this client. -func (c *Client) DSN() string { - return c.dsn -} - -// Version represents a server version response. -type Version struct { - // Version is the version number reported by the server or backend. - Version string - // Vendor is the vendor string reported by the server or backend. - Vendor string - // Features is a list of enabled, optional features. This was added in - // CouchDB 2.1.0, and can be expected to be empty for older versions. - Features []string - // RawResponse is the raw response body returned by the server, useful if - // you need additional backend-specific information. - // - // For the format of this document, see - // http://docs.couchdb.org/en/2.0.0/api/server/common.html#get - RawResponse json.RawMessage -} - -// Version returns version and vendor info about the backend. -func (c *Client) Version(ctx context.Context) (*Version, error) { - ver, err := c.driverClient.Version(ctx) - if err != nil { - return nil, err - } - v := &Version{} - *v = Version(*ver) - return v, nil -} - -// DB returns a handle to the requested database. Any options parameters -// passed are merged, with later values taking precidence. If any errors occur -// at this stage, they are deferred, or may be checked directly with Err() -func (c *Client) DB(ctx context.Context, dbName string, options ...Options) *DB { - db, err := c.driverClient.DB(ctx, dbName, mergeOptions(options...)) - return &DB{ - client: c, - name: dbName, - driverDB: db, - err: err, - } -} - -// AllDBs returns a list of all databases. -func (c *Client) AllDBs(ctx context.Context, options ...Options) ([]string, error) { - return c.driverClient.AllDBs(ctx, mergeOptions(options...)) -} - -// DBExists returns true if the specified database exists. -func (c *Client) DBExists(ctx context.Context, dbName string, options ...Options) (bool, error) { - return c.driverClient.DBExists(ctx, dbName, mergeOptions(options...)) -} - -// CreateDB creates a DB of the requested name. Any errors are deferred, or may -// be checked with Err(). -func (c *Client) CreateDB(ctx context.Context, dbName string, options ...Options) error { - return c.driverClient.CreateDB(ctx, dbName, mergeOptions(options...)) -} - -// DestroyDB deletes the requested DB. -func (c *Client) DestroyDB(ctx context.Context, dbName string, options ...Options) error { - return c.driverClient.DestroyDB(ctx, dbName, mergeOptions(options...)) -} - -// Authenticate authenticates the client with the passed authenticator, which -// is driver-specific. If the driver does not understand the authenticator, an -// error will be returned. -func (c *Client) Authenticate(ctx context.Context, a interface{}) error { - if auth, ok := c.driverClient.(driver.Authenticator); ok { - return auth.Authenticate(ctx, a) - } - return &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: driver does not support authentication"} -} - -func missingArg(arg string) error { - return &Error{HTTPStatus: http.StatusBadRequest, Message: fmt.Sprintf("kivik: %s required", arg)} -} - -// DBsStats returns database statistics about one or more databases. -func (c *Client) DBsStats(ctx context.Context, dbnames []string) ([]*DBStats, error) { - dbstats, err := c.nativeDBsStats(ctx, dbnames) - switch StatusCode(err) { - case http.StatusNotFound, http.StatusNotImplemented: - return c.fallbackDBsStats(ctx, dbnames) - } - return dbstats, err -} - -func (c *Client) fallbackDBsStats(ctx context.Context, dbnames []string) ([]*DBStats, error) { - dbstats := make([]*DBStats, len(dbnames)) - for i, dbname := range dbnames { - db := c.DB(ctx, dbname) - stat, err := db.Stats(ctx) - if err != nil { - return nil, err - } - dbstats[i] = stat - } - return dbstats, nil -} - -func (c *Client) nativeDBsStats(ctx context.Context, dbnames []string) ([]*DBStats, error) { - statser, ok := c.driverClient.(driver.DBsStatser) - if !ok { - return nil, &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: not supported by driver"} - } - stats, err := statser.DBsStats(ctx, dbnames) - if err != nil { - return nil, err - } - dbstats := make([]*DBStats, len(stats)) - for i, stat := range stats { - dbstats[i] = driverStats2kivikStats(stat) - } - return dbstats, nil -} - -// Ping returns true if the database is online and available for requests, -// for instance by querying the /_up endpoint. If the underlying driver -// supports the Pinger interface, it will be used. Otherwise, a fallback is -// made to calling Version. -func (c *Client) Ping(ctx context.Context) (bool, error) { - if pinger, ok := c.driverClient.(driver.Pinger); ok { - return pinger.Ping(ctx) - } - _, err := c.driverClient.Version(ctx) - return err == nil, err -} - -// Close cleans up any resources used by Client. -func (c *Client) Close(ctx context.Context) error { - if closer, ok := c.driverClient.(driver.ClientCloser); ok { - return closer.Close(ctx) - } - return nil -} diff --git a/vendor/github.com/go-kivik/kivik/v3/package.json b/vendor/github.com/go-kivik/kivik/v3/package.json deleted file mode 100644 index 727715456..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "kivik", - "version": "0.0.1", - "description": "Isomorphic Go and GopherJS client library for CouchDB & PouchDB", - "author": "Jonathan Hall ", - "repository": { - "type": "git", - "url": "https://github.com/go-kivik/kivik" - }, - "devDependencies": { - "pouchdb": "*", - "pouchdb-find": "*", - "pouchdb-all-dbs": "*", - "memdown": ">=1.1.0", - "inherits": "*", - "xhr2": "*" - } -} diff --git a/vendor/github.com/go-kivik/kivik/v3/replication.go b/vendor/github.com/go-kivik/kivik/v3/replication.go deleted file mode 100644 index 4188fef2f..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/replication.go +++ /dev/null @@ -1,199 +0,0 @@ -package kivik - -import ( - "context" - "net/http" - "sync" - "time" - - "github.com/go-kivik/kivik/v3/driver" -) - -// ReplicationState represents a replication's state -type ReplicationState string - -// The possible values for the _replication_state field in _replicator documents -// plus a blank value for unstarted replications. -const ( - ReplicationNotStarted ReplicationState = "" - ReplicationStarted ReplicationState = "triggered" - ReplicationError ReplicationState = "error" - ReplicationComplete ReplicationState = "completed" -) - -// The additional possible values for the state field in the _scheduler docs. -const ( - ReplicationInitializing ReplicationState = "initializing" - ReplicationRunning ReplicationState = "running" - ReplicationPending ReplicationState = "pending" - ReplicationCrashing ReplicationState = "crashing" - ReplicationFailed ReplicationState = "failed" -) - -// Replication represents a CouchDB replication process. -type Replication struct { - Source string - Target string - - infoMU sync.RWMutex - info *driver.ReplicationInfo - statusErr error - irep driver.Replication -} - -// DocsWritten returns the number of documents written, if known. -func (r *Replication) DocsWritten() int64 { - if r != nil && r.info != nil { - r.infoMU.RLock() - defer r.infoMU.RUnlock() - return r.info.DocsWritten - } - return 0 -} - -// DocsRead returns the number of documents read, if known. -func (r *Replication) DocsRead() int64 { - if r != nil && r.info != nil { - r.infoMU.RLock() - defer r.infoMU.RUnlock() - return r.info.DocsRead - } - return 0 -} - -// DocWriteFailures returns the number of doc write failures, if known. -func (r *Replication) DocWriteFailures() int64 { - if r != nil && r.info != nil { - r.infoMU.RLock() - defer r.infoMU.RUnlock() - return r.info.DocWriteFailures - } - return 0 -} - -// Progress returns the current replication progress, if known. -func (r *Replication) Progress() float64 { - if r != nil && r.info != nil { - r.infoMU.RLock() - defer r.infoMU.RUnlock() - return r.info.Progress - } - return 0 -} - -func newReplication(rep driver.Replication) *Replication { - return &Replication{ - Source: rep.Source(), - Target: rep.Target(), - irep: rep, - } -} - -// ReplicationID returns the _replication_id field of the replicator document. -func (r *Replication) ReplicationID() string { - return r.irep.ReplicationID() -} - -// StartTime returns the replication start time, once the replication has been -// triggered. -func (r *Replication) StartTime() time.Time { - return r.irep.StartTime() -} - -// EndTime returns the replication end time, once the replication has terminated. -func (r *Replication) EndTime() time.Time { - return r.irep.EndTime() -} - -// State returns the current replication state -func (r *Replication) State() ReplicationState { - return ReplicationState(r.irep.State()) -} - -// Err returns the error, if any, that caused the replication to abort. -func (r *Replication) Err() error { - if r == nil { - return nil - } - return r.irep.Err() -} - -// IsActive returns true if the replication has not yet completed or -// errored. -func (r *Replication) IsActive() bool { - if r == nil { - return false - } - switch r.State() { - case ReplicationError, ReplicationComplete, ReplicationCrashing, ReplicationFailed: - return false - default: - return true - } -} - -// Delete deletes a replication. If it is currently running, it will be -// cancelled. -func (r *Replication) Delete(ctx context.Context) error { - return r.irep.Delete(ctx) -} - -// Update requests a replication state update from the server. If there is an -// error retrieving the update, it is returned and the replication state is -// unaltered. -func (r *Replication) Update(ctx context.Context) error { - var info driver.ReplicationInfo - r.statusErr = r.irep.Update(ctx, &info) - if r.statusErr != nil { - return r.statusErr - } - r.infoMU.Lock() - r.info = &info - r.infoMU.Unlock() - return nil -} - -var replicationNotImplemented = &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: driver does not support replication"} - -// GetReplications returns a list of defined replications in the _replicator -// database. Options are in the same format as to AllDocs(), except that -// "conflicts" and "update_seq" are ignored. -func (c *Client) GetReplications(ctx context.Context, options ...Options) ([]*Replication, error) { - replicator, ok := c.driverClient.(driver.ClientReplicator) - if !ok { - return nil, replicationNotImplemented - } - reps, err := replicator.GetReplications(ctx, mergeOptions(options...)) - if err != nil { - return nil, err - } - replications := make([]*Replication, len(reps)) - for i, rep := range reps { - replications[i] = newReplication(rep) - } - return replications, nil -} - -// Replicate initiates a replication from source to target. -// -// To use an object for either "source" or "target", pass the desired object -// in options. This will override targetDSN and sourceDSN function parameters. -func (c *Client) Replicate(ctx context.Context, targetDSN, sourceDSN string, options ...Options) (*Replication, error) { - replicator, ok := c.driverClient.(driver.ClientReplicator) - if !ok { - return nil, replicationNotImplemented - } - rep, err := replicator.Replicate(ctx, targetDSN, sourceDSN, mergeOptions(options...)) - if err != nil { - return nil, err - } - return newReplication(rep), nil -} - -// ReplicationInfo represents a snapshot of the status of a replication. -type ReplicationInfo struct { - DocWriteFailures int64 - DocsRead int64 - DocsWritten int64 - Progress float64 -} diff --git a/vendor/github.com/go-kivik/kivik/v3/rows.go b/vendor/github.com/go-kivik/kivik/v3/rows.go deleted file mode 100644 index 73aa26348..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/rows.go +++ /dev/null @@ -1,188 +0,0 @@ -package kivik - -import ( - "context" - "net/http" - - "github.com/go-kivik/kivik/v3/driver" -) - -// Rows is an iterator over a a multi-value query. -type Rows struct { - *iter - rowsi driver.Rows -} - -// Next prepares the next result value for reading. It returns true on success -// or false if there are no more results or an error occurs while preparing it. -// Err should be consulted to distinguish between the two. -func (r *Rows) Next() bool { - return r.iter.Next() -} - -// Err returns the error, if any, that was encountered during iteration. Err may -// be called after an explicit or implicit Close. -func (r *Rows) Err() error { - return r.iter.Err() -} - -// Close closes the Rows, preventing further enumeration, and freeing any -// resources (such as the http request body) of the underlying query. If Next is -// called and there are no further results, Rows is closed automatically and it -// will suffice to check the result of Err. Close is idempotent and does not -// affect the result of Err. -func (r *Rows) Close() error { - return r.iter.Close() -} - -type rowsIterator struct{ driver.Rows } - -var _ iterator = &rowsIterator{} - -func (r *rowsIterator) Next(i interface{}) error { return r.Rows.Next(i.(*driver.Row)) } - -func newRows(ctx context.Context, rowsi driver.Rows) *Rows { - return &Rows{ - iter: newIterator(ctx, &rowsIterator{rowsi}, &driver.Row{}), - rowsi: rowsi, - } -} - -var ( - errNilPtr = &Error{HTTPStatus: http.StatusBadRequest, Message: "kivik: destination pointer is nil"} - errNonPtr = &Error{HTTPStatus: http.StatusBadRequest, Message: "kivik: destination is not a pointer"} -) - -// ScanValue copies the data from the result value into the value pointed at by -// dest. Think of this as a json.Unmarshal into dest. -// -// If the dest argument has type *[]byte, Scan stores a copy of the input data. -// The copy is owned by the caller and can be modified and held indefinitely. -// -// The copy can be avoided by using an argument of type *json.RawMessage -// instead. After a ScanValue into a json.RawMessage, the slice is only valid -// until the next call to Next or Close. -// -// For all other types, refer to the documentation for json.Unmarshal for type -// conversion rules. -func (r *Rows) ScanValue(dest interface{}) error { - runlock, err := r.rlock() - if err != nil { - return err - } - defer runlock() - if err := r.curVal.(*driver.Row).Error; err != nil { - return err - } - return scan(dest, r.curVal.(*driver.Row).Value) -} - -// ScanDoc works the same as ScanValue, but on the doc field of the result. It -// will panic if the query does not include documents. -func (r *Rows) ScanDoc(dest interface{}) error { - runlock, err := r.rlock() - if err != nil { - return err - } - defer runlock() - if err := r.curVal.(*driver.Row).Error; err != nil { - return err - } - doc := r.curVal.(*driver.Row).Doc - if doc == nil { - return &Error{HTTPStatus: http.StatusBadRequest, Message: "kivik: doc is nil; does the query include docs?"} - } - return scan(dest, doc) -} - -// ScanKey works the same as ScanValue, but on the key field of the result. For -// simple keys, which are just strings, the Key() method may be easier to use. -func (r *Rows) ScanKey(dest interface{}) error { - runlock, err := r.rlock() - if err != nil { - return err - } - if err := r.curVal.(*driver.Row).Error; err != nil { - return err - } - defer runlock() - return scan(dest, r.curVal.(*driver.Row).Key) -} - -// ID returns the ID of the current result. -func (r *Rows) ID() string { - runlock, err := r.rlock() - if err != nil { - return "" - } - defer runlock() - return r.curVal.(*driver.Row).ID -} - -// Key returns the Key of the current result as a raw JSON string. For -// compound keys, the ScanKey() method may be more convenient. -func (r *Rows) Key() string { - runlock, err := r.rlock() - if err != nil { - return "" - } - defer runlock() - return string(r.curVal.(*driver.Row).Key) -} - -// Offset returns the starting offset where the result set started. It is -// only guaranteed to be set after all result rows have been enumerated through -// by Next, and thus should only be read after processing all rows in a result -// set. Calling Close before enumerating will render this value unreliable. -func (r *Rows) Offset() int64 { - return r.rowsi.Offset() -} - -// TotalRows returns the total number of rows in the view which would have been -// returned if no limiting were used. This value is only guaranteed to be set -// after all result rows have been enumerated through by Next, and thus should -// only be read after processing all rows in a result set. Calling Close before -// enumerating will render this value unreliable. -func (r *Rows) TotalRows() int64 { - return r.rowsi.TotalRows() -} - -// UpdateSeq returns the sequence id of the underlying database the view -// reflects, if requested in the query. This value is only guaranteed to be set -// after all result rows have been enumerated through by Next, and thus should -// only be read after processing all rows in a result set. Calling Close before -// enumerating will render this value unreliable. -func (r *Rows) UpdateSeq() string { - return r.rowsi.UpdateSeq() -} - -// Warning returns a warning generated by the query, if any. This value is only -// guaranteed to be set after all result rows have been enumeratd through by -// Next. -func (r *Rows) Warning() string { - if w, ok := r.rowsi.(driver.RowsWarner); ok { - return w.Warning() - } - return "" -} - -// QueryIndex returns the 0-based index of the query. For standard queries, -// this is always 0. When multiple queries are passed to the view, this will -// represent the query currently being iterated -func (r *Rows) QueryIndex() int { - if qi, ok := r.rowsi.(driver.QueryIndexer); ok { - return qi.QueryIndex() - } - return 0 -} - -// Bookmark returns the paging bookmark, if one was provided with the result -// set. This is intended for use with the Mango /_find interface, with CouchDB -// 2.1.1 and later. Consult the official CouchDB documentation for detailed -// usage instructions. http://docs.couchdb.org/en/2.1.1/api/database/find.html#pagination -func (r *Rows) Bookmark() string { - if b, ok := r.rowsi.(driver.Bookmarker); ok { - return b.Bookmark() - } - return "" -} diff --git a/vendor/github.com/go-kivik/kivik/v3/security.go b/vendor/github.com/go-kivik/kivik/v3/security.go deleted file mode 100644 index af3da4b0b..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/security.go +++ /dev/null @@ -1,13 +0,0 @@ -package kivik - -// Members represents the members of a database security document. -type Members struct { - Names []string `json:"names,omitempty"` - Roles []string `json:"roles,omitempty"` -} - -// Security represents a database security document. -type Security struct { - Admins Members `json:"admins"` - Members Members `json:"members"` -} diff --git a/vendor/github.com/go-kivik/kivik/v3/session.go b/vendor/github.com/go-kivik/kivik/v3/session.go deleted file mode 100644 index 56a6f4647..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/session.go +++ /dev/null @@ -1,42 +0,0 @@ -package kivik - -import ( - "context" - "encoding/json" - "net/http" - - "github.com/go-kivik/kivik/v3/driver" -) - -// Session represents an authentication session. -type Session struct { - // Name is the name of the authenticated user. - Name string - // Roles is a list of roles the user belongs to. - Roles []string - // AuthenticationMethod is the authentication method that was used for this - // session. - AuthenticationMethod string - // AuthenticationDB is the user database against which authentication was - // performed. - AuthenticationDB string - // AuthenticationHandlers is a list of authentication handlers configured on - // the server. - AuthenticationHandlers []string - // RawResponse is the raw JSON response sent by the server, useful for - // custom backends which may provide additional fields. - RawResponse json.RawMessage -} - -// Session returns information about the currently authenticated user. -func (c *Client) Session(ctx context.Context) (*Session, error) { - if sessioner, ok := c.driverClient.(driver.Sessioner); ok { - session, err := sessioner.Session(ctx) - if err != nil { - return nil, err - } - ses := Session(*session) - return &ses, nil - } - return nil, &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: driver does not support sessions"} -} diff --git a/vendor/github.com/go-kivik/kivik/v3/updates.go b/vendor/github.com/go-kivik/kivik/v3/updates.go deleted file mode 100644 index e6bd15966..000000000 --- a/vendor/github.com/go-kivik/kivik/v3/updates.go +++ /dev/null @@ -1,90 +0,0 @@ -package kivik - -import ( - "context" - "net/http" - - "github.com/go-kivik/kivik/v3/driver" -) - -// DBUpdates provides access to database updates. -type DBUpdates struct { - *iter - updatesi driver.DBUpdates -} - -// Next returns the next DBUpdate from the feed. This function will block -// until an event is received. If an error occurs, it will be returned and -// the feed closed. If the feed was closed normally, io.EOF will be returned -// when there are no more events in the buffer. -func (f *DBUpdates) Next() bool { - return f.iter.Next() -} - -// Close closes the feed. Any unread updates will still be accessible via -// Next(). -func (f *DBUpdates) Close() error { - return f.iter.Close() -} - -// Err returns the error, if any, that was encountered during iteration. Err -// may be called after an explicit or implicit Close. -func (f *DBUpdates) Err() error { - return f.iter.Err() -} - -type updatesIterator struct{ driver.DBUpdates } - -var _ iterator = &updatesIterator{} - -func (r *updatesIterator) Next(i interface{}) error { return r.DBUpdates.Next(i.(*driver.DBUpdate)) } - -func newDBUpdates(ctx context.Context, updatesi driver.DBUpdates) *DBUpdates { - return &DBUpdates{ - iter: newIterator(ctx, &updatesIterator{updatesi}, &driver.DBUpdate{}), - updatesi: updatesi, - } -} - -// DBName returns the database name for the current update. -func (f *DBUpdates) DBName() string { - runlock, err := f.rlock() - if err != nil { - return "" - } - defer runlock() - return f.curVal.(*driver.DBUpdate).DBName -} - -// Type returns the type of the current update. -func (f *DBUpdates) Type() string { - runlock, err := f.rlock() - if err != nil { - return "" - } - defer runlock() - return f.curVal.(*driver.DBUpdate).Type -} - -// Seq returns the update sequence of the current update. -func (f *DBUpdates) Seq() string { - runlock, err := f.rlock() - if err != nil { - return "" - } - defer runlock() - return f.curVal.(*driver.DBUpdate).Seq -} - -// DBUpdates begins polling for database updates. -func (c *Client) DBUpdates(ctx context.Context) (*DBUpdates, error) { - updater, ok := c.driverClient.(driver.DBUpdater) - if !ok { - return nil, &Error{HTTPStatus: http.StatusNotImplemented, Message: "kivik: driver does not implement DBUpdater"} - } - updatesi, err := updater.DBUpdates(ctx) - if err != nil { - return nil, err - } - return newDBUpdates(context.Background(), updatesi), nil -} diff --git a/vendor/github.com/go-pg/pg/.travis.yml b/vendor/github.com/go-pg/pg/.travis.yml deleted file mode 100644 index 5ae69b823..000000000 --- a/vendor/github.com/go-pg/pg/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -dist: trusty -language: go - -addons: - postgresql: "9.6" - -go: - - 1.9.x - - 1.10.x - - tip - -matrix: - allow_failures: - - go: tip - -before_install: - - psql -U postgres -c "CREATE EXTENSION hstore" - -install: - - go get github.com/jinzhu/inflection - - go get gopkg.in/check.v1 - - go get github.com/onsi/ginkgo - - go get github.com/onsi/gomega diff --git a/vendor/github.com/go-pg/pg/CHANGELOG.md b/vendor/github.com/go-pg/pg/CHANGELOG.md deleted file mode 100644 index e99e449e2..000000000 --- a/vendor/github.com/go-pg/pg/CHANGELOG.md +++ /dev/null @@ -1,70 +0,0 @@ -# Changelog - -## Unreleased - -- Added Options.MinIdleConns. -- Options.MaxAge renamed to Options.MaxConnAge. -- PoolStats.FreeConns is renamed to PoolStats.IdleConns. -- New hook BeforeSelectQuery. -- `,override` is renamed to `,inherit`. - -## v6.15 - -- Dialer.KeepAlive is set to 5 minutes by default. - -## v6.14 - -- Fields ignored with `sql:"-"` tag are no longer considered by ORM relation detector. - -## v6.12 - -- `Insert`, `Update`, and `Delete` can return `pg.ErrNoRows` and `pg.ErrMultiRows` when `Returning` is used and model expects single row. - -## v6.11 - -- `db.Model(&strct).Update()` and `db.Model(&strct).Delete()` no longer adds WHERE condition based on primary key when there are no conditions. Instead you should use `db.Update(&strct)` or `db.Model(&strct).WherePK().Update()`. - -## v6.10 - -- `?Columns` is renamed to `?TableColumns`. `?Columns` is changed to produce column names without table alias. - -## v6.9 - -- `pg:"fk"` tag now accepts SQL names instead of Go names, e.g. `pg:"fk:ParentId"` becomes `pg:"fk:parent_id"`. Old code should continue working in most cases, but it is strongly advised to start using new convention. -- uint and uint64 SQL type is changed from decimal to bigint according to the the lesser of two evils principle. Use `sql:"type:decimal"` to get old behavior. - -## v6.8 - -- `CreateTable` no longer adds ON DELETE hook by default. To get old behavior users should add `sql:"on_delete:CASCADE"` tag on foreign key field. - -## v6 - - - `types.Result` is renamed to `orm.Result`. - - Added `OnQueryProcessed` event that can be used to log / report queries timing. Query logger is removed. - - `orm.URLValues` is renamed to `orm.URLFilters`. It no longer adds ORDER clause. - - `orm.Pager` is renamed to `orm.Pagination`. - - Support for net.IP and net.IPNet. - - Support for context.Context. - - Bulk/multi updates. - - Query.WhereGroup for enclosing conditions in paretheses. - -## v5 - - - All fields are nullable by default. `,null` tag is replaced with `,notnull`. - - `Result.Affected` renamed to `Result.RowsAffected`. - - Added `Result.RowsReturned`. - - `Create` renamed to `Insert`, `BeforeCreate` to `BeforeInsert`, `AfterCreate` to `AfterInsert`. - - Indexed placeholders support, e.g. `db.Exec("SELECT ?0 + ?0", 1)`. - - Named placeholders are evaluated when query is executed. - - Added Update and Delete hooks. - - Order reworked to quote column names. OrderExpr added to bypass Order quoting restrictions. - - Group reworked to quote column names. GroupExpr added to bypass Group quoting restrictions. - -## v4 - - - `Options.Host` and `Options.Port` merged into `Options.Addr`. - - Added `Options.MaxRetries`. Now queries are not retried by default. - - `LoadInto` renamed to `Scan`, `ColumnLoader` renamed to `ColumnScanner`, LoadColumn renamed to ScanColumn, `NewRecord() interface{}` changed to `NewModel() ColumnScanner`, `AppendQuery(dst []byte) []byte` changed to `AppendValue(dst []byte, quote bool) ([]byte, error)`. - - Structs, maps and slices are marshalled to JSON by default. - - Added support for scanning slices, .e.g. scanning `[]int`. - - Added object relational mapping. diff --git a/vendor/github.com/go-pg/pg/LICENSE b/vendor/github.com/go-pg/pg/LICENSE deleted file mode 100644 index 7751509b8..000000000 --- a/vendor/github.com/go-pg/pg/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2013 github.com/go-pg/pg 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. - -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/go-pg/pg/Makefile b/vendor/github.com/go-pg/pg/Makefile deleted file mode 100644 index 5c67b332a..000000000 --- a/vendor/github.com/go-pg/pg/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -all: - go test ./... - go test ./... -short -race - env GOOS=linux GOARCH=386 go test ./... - go vet ./... diff --git a/vendor/github.com/go-pg/pg/README.md b/vendor/github.com/go-pg/pg/README.md deleted file mode 100644 index 8e652ff52..000000000 --- a/vendor/github.com/go-pg/pg/README.md +++ /dev/null @@ -1,167 +0,0 @@ -# PostgreSQL client and ORM for Golang - -[![Build Status](https://travis-ci.org/go-pg/pg.svg?branch=master)](https://travis-ci.org/go-pg/pg) -[![GoDoc](https://godoc.org/github.com/go-pg/pg?status.svg)](https://godoc.org/github.com/go-pg/pg) - -## Features: - -- Basic types: integers, floats, string, bool, time.Time, net.IP, net.IPNet. -- sql.NullBool, sql.NullString, sql.NullInt64, sql.NullFloat64 and [pg.NullTime](http://godoc.org/github.com/go-pg/pg#NullTime). -- [sql.Scanner](http://golang.org/pkg/database/sql/#Scanner) and [sql/driver.Valuer](http://golang.org/pkg/database/sql/driver/#Valuer) interfaces. -- Structs, maps and arrays are marshalled as JSON by default. -- PostgreSQL multidimensional Arrays using [array tag](https://godoc.org/github.com/go-pg/pg#example-DB-Model-PostgresArrayStructTag) and [Array wrapper](https://godoc.org/github.com/go-pg/pg#example-Array). -- Hstore using [hstore tag](https://godoc.org/github.com/go-pg/pg#example-DB-Model-HstoreStructTag) and [Hstore wrapper](https://godoc.org/github.com/go-pg/pg#example-Hstore). -- [Composite types](https://godoc.org/github.com/go-pg/pg#example-DB-Model-CompositeType). -- All struct fields are nullable by default and zero values (empty string, 0, zero time, empty map or slice) are marshalled as SQL `NULL`. `sql:",notnull"` tag is used to reverse this behaviour. -- [Transactions](http://godoc.org/github.com/go-pg/pg#example-DB-Begin). -- [Prepared statements](http://godoc.org/github.com/go-pg/pg#example-DB-Prepare). -- [Notifications](http://godoc.org/github.com/go-pg/pg#example-Listener) using `LISTEN` and `NOTIFY`. -- [Copying data](http://godoc.org/github.com/go-pg/pg#example-DB-CopyFrom) using `COPY FROM` and `COPY TO`. -- [Timeouts](http://godoc.org/github.com/go-pg/pg#Options). -- Automatic connection pooling with [circuit breaker](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern) support. -- Queries retries on network errors. -- Working with models using [ORM](https://godoc.org/github.com/go-pg/pg#example-DB-Model) and [SQL](https://godoc.org/github.com/go-pg/pg#example-DB-Query). -- Scanning variables using [ORM](https://godoc.org/github.com/go-pg/pg#example-DB-Select-SomeColumnsIntoVars) and [SQL](https://godoc.org/github.com/go-pg/pg#example-Scan). -- [SelectOrInsert](https://godoc.org/github.com/go-pg/pg#example-DB-Insert-SelectOrInsert) using on-conflict. -- [INSERT ... ON CONFLICT DO UPDATE](https://godoc.org/github.com/go-pg/pg#example-DB-Insert-OnConflictDoUpdate) using ORM. -- Bulk/batch [inserts](https://godoc.org/github.com/go-pg/pg#example-DB-Insert-BulkInsert), [updates](https://godoc.org/github.com/go-pg/pg#example-DB-Update-BulkUpdate), and [deletes](https://godoc.org/github.com/go-pg/pg#example-DB-Delete-BulkDelete). -- Common table expressions using [WITH](https://godoc.org/github.com/go-pg/pg#example-DB-Select-With) and [WrapWith](https://godoc.org/github.com/go-pg/pg#example-DB-Select-WrapWith). -- [CountEstimate](https://godoc.org/github.com/go-pg/pg#example-DB-Model-CountEstimate) using `EXPLAIN` to get [estimated number of matching rows](https://wiki.postgresql.org/wiki/Count_estimate). -- ORM supports [has one](https://godoc.org/github.com/go-pg/pg#example-DB-Model-HasOne), [belongs to](https://godoc.org/github.com/go-pg/pg#example-DB-Model-BelongsTo), [has many](https://godoc.org/github.com/go-pg/pg#example-DB-Model-HasMany), and [many to many](https://godoc.org/github.com/go-pg/pg#example-DB-Model-ManyToMany) with composite/multi-column primary keys. -- [Soft deletes](https://godoc.org/github.com/go-pg/pg#example-DB-Model-SoftDelete). -- [Creating tables from structs](https://godoc.org/github.com/go-pg/pg#example-DB-CreateTable). -- [Pagination](https://godoc.org/github.com/go-pg/pg/orm#Pagination) and [URL filters](https://godoc.org/github.com/go-pg/pg/orm#URLFilters) helpers. -- [ForEach](https://godoc.org/github.com/go-pg/pg#example-DB-Model-ForEach) that calls a function for each row returned by the query without loading all rows into the memory. -- Works with PgBouncer in transaction pooling mode. -- [Migrations](https://github.com/go-pg/migrations). -- [Sharding](https://github.com/go-pg/sharding). - -## Get Started - -```shell -go get -u github.com/go-pg/pg -``` - -- [Wiki](https://github.com/go-pg/pg/wiki) -- [API docs](http://godoc.org/github.com/go-pg/pg) -- [Examples](http://godoc.org/github.com/go-pg/pg#pkg-examples) - -## Look & Feel - -```go -package pg_test - -import ( - "fmt" - - "github.com/go-pg/pg" - "github.com/go-pg/pg/orm" -) - -type User struct { - Id int64 - Name string - Emails []string -} - -func (u User) String() string { - return fmt.Sprintf("User<%d %s %v>", u.Id, u.Name, u.Emails) -} - -type Story struct { - Id int64 - Title string - AuthorId int64 - Author *User -} - -func (s Story) String() string { - return fmt.Sprintf("Story<%d %s %s>", s.Id, s.Title, s.Author) -} - -func ExampleDB_Model() { - db := pg.Connect(&pg.Options{ - User: "postgres", - }) - defer db.Close() - - err := createSchema(db) - if err != nil { - panic(err) - } - - user1 := &User{ - Name: "admin", - Emails: []string{"admin1@admin", "admin2@admin"}, - } - err = db.Insert(user1) - if err != nil { - panic(err) - } - - err = db.Insert(&User{ - Name: "root", - Emails: []string{"root1@root", "root2@root"}, - }) - if err != nil { - panic(err) - } - - story1 := &Story{ - Title: "Cool story", - AuthorId: user1.Id, - } - err = db.Insert(story1) - if err != nil { - panic(err) - } - - // Select user by primary key. - user := &User{Id: user1.Id} - err = db.Select(user) - if err != nil { - panic(err) - } - - // Select all users. - var users []User - err = db.Model(&users).Select() - if err != nil { - panic(err) - } - - // Select story and associated author in one query. - story := new(Story) - err = db.Model(story). - Relation("Author"). - Where("story.id = ?", story1.Id). - Select() - if err != nil { - panic(err) - } - - fmt.Println(user) - fmt.Println(users) - fmt.Println(story) - // Output: User<1 admin [admin1@admin admin2@admin]> - // [User<1 admin [admin1@admin admin2@admin]> User<2 root [root1@root root2@root]>] - // Story<1 Cool story User<1 admin [admin1@admin admin2@admin]>> -} - -func createSchema(db *pg.DB) error { - for _, model := range []interface{}{(*User)(nil), (*Story)(nil)} { - err := db.CreateTable(model, &orm.CreateTableOptions{ - Temp: true, - }) - if err != nil { - return err - } - } - return nil -} -``` - -## See also - -- [Golang msgpack](https://github.com/vmihailenco/msgpack) -- [Golang message task queue](https://github.com/go-msgqueue/msgqueue) diff --git a/vendor/github.com/go-pg/pg/db.go b/vendor/github.com/go-pg/pg/db.go deleted file mode 100644 index c8bbac06c..000000000 --- a/vendor/github.com/go-pg/pg/db.go +++ /dev/null @@ -1,517 +0,0 @@ -package pg - -import ( - "context" - "fmt" - "io" - "time" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/internal/pool" - "github.com/go-pg/pg/orm" -) - -// Connect connects to a database using provided options. -// -// The returned DB is safe for concurrent use by multiple goroutines -// and maintains its own connection pool. -func Connect(opt *Options) *DB { - opt.init() - return &DB{ - opt: opt, - pool: newConnPool(opt), - } -} - -// DB is a database handle representing a pool of zero or more -// underlying connections. It's safe for concurrent use by multiple -// goroutines. -type DB struct { - opt *Options - pool pool.Pooler - fmter orm.Formatter - - queryProcessedHooks []queryProcessedHook - - ctx context.Context -} - -var _ orm.DB = (*DB)(nil) - -func (db *DB) String() string { - return fmt.Sprintf("DB", db.opt.Addr, db.fmter) -} - -// Options returns read-only Options that were used to connect to the DB. -func (db *DB) Options() *Options { - return db.opt -} - -// Context returns DB context. -func (db *DB) Context() context.Context { - if db.ctx != nil { - return db.ctx - } - return context.Background() -} - -// WithContext returns a copy of the DB that uses the ctx. -func (db *DB) WithContext(ctx context.Context) *DB { - return &DB{ - opt: db.opt, - pool: db.pool, - fmter: db.fmter, - - queryProcessedHooks: copyQueryProcessedHooks(db.queryProcessedHooks), - - ctx: ctx, - } -} - -// WithTimeout returns a copy of the DB that uses d as the read/write timeout. -func (db *DB) WithTimeout(d time.Duration) *DB { - newopt := *db.opt - newopt.ReadTimeout = d - newopt.WriteTimeout = d - - return &DB{ - opt: &newopt, - pool: db.pool, - fmter: db.fmter, - - queryProcessedHooks: copyQueryProcessedHooks(db.queryProcessedHooks), - - ctx: db.ctx, - } -} - -// WithParam returns a copy of the DB that replaces the param with the value -// in queries. -func (db *DB) WithParam(param string, value interface{}) *DB { - return &DB{ - opt: db.opt, - pool: db.pool, - fmter: db.fmter.WithParam(param, value), - - queryProcessedHooks: copyQueryProcessedHooks(db.queryProcessedHooks), - - ctx: db.ctx, - } -} - -// Param returns value for the param. -func (db *DB) Param(param string) interface{} { - return db.fmter.Param(param) -} - -type PoolStats pool.Stats - -// PoolStats returns connection pool stats. -func (db *DB) PoolStats() *PoolStats { - stats := db.pool.Stats() - return (*PoolStats)(stats) -} - -func (db *DB) retryBackoff(retry int) time.Duration { - return internal.RetryBackoff(retry, db.opt.MinRetryBackoff, db.opt.MaxRetryBackoff) -} - -func (db *DB) conn() (*pool.Conn, error) { - cn, err := db.pool.Get() - if err != nil { - return nil, err - } - - if cn.InitedAt.IsZero() { - cn.InitedAt = time.Now() - err = db.initConn(cn) - if err != nil { - db.pool.Remove(cn) - return nil, err - } - } - - return cn, nil -} - -func (db *DB) initConn(cn *pool.Conn) error { - if db.opt.TLSConfig != nil { - err := db.enableSSL(cn, db.opt.TLSConfig) - if err != nil { - return err - } - } - - err := db.startup(cn, db.opt.User, db.opt.Password, db.opt.Database, db.opt.ApplicationName) - if err != nil { - return err - } - - if db.opt.OnConnect != nil { - dbConn := &DB{ - opt: db.opt, - pool: pool.NewSingleConnPool(cn), - fmter: db.fmter, - } - return db.opt.OnConnect(dbConn) - } - - return nil -} - -func (db *DB) freeConn(cn *pool.Conn, err error) { - if !isBadConn(err, false) { - db.pool.Put(cn) - } else { - db.pool.Remove(cn) - } -} - -func (db *DB) shouldRetry(err error) bool { - if err == nil { - return false - } - if pgerr, ok := err.(Error); ok { - switch pgerr.Field('C') { - case "40001": // serialization_failure - return true - case "55000": // attempted to delete invisible tuple - return true - case "57014": // statement_timeout - return db.opt.RetryStatementTimeout - default: - return false - } - } - return isNetworkError(err) -} - -// Close closes the database client, releasing any open resources. -// -// It is rare to Close a DB, as the DB handle is meant to be -// long-lived and shared between many goroutines. -func (db *DB) Close() error { - return db.pool.Close() -} - -// Exec executes a query ignoring returned rows. The params are for any -// placeholders in the query. -func (db *DB) Exec(query interface{}, params ...interface{}) (res orm.Result, err error) { - for attempt := 0; attempt <= db.opt.MaxRetries; attempt++ { - var cn *pool.Conn - - if attempt >= 1 { - time.Sleep(db.retryBackoff(attempt - 1)) - } - - cn, err = db.conn() - if err != nil { - continue - } - - start := time.Now() - res, err = db.simpleQuery(cn, query, params...) - db.freeConn(cn, err) - db.queryProcessed(db, start, query, params, attempt, res, err) - - if !db.shouldRetry(err) { - break - } - } - return res, err -} - -// ExecOne acts like Exec, but query must affect only one row. It -// returns ErrNoRows error when query returns zero rows or -// ErrMultiRows when query returns multiple rows. -func (db *DB) ExecOne(query interface{}, params ...interface{}) (orm.Result, error) { - res, err := db.Exec(query, params...) - if err != nil { - return nil, err - } - - if err := internal.AssertOneRow(res.RowsAffected()); err != nil { - return nil, err - } - return res, nil -} - -// Query executes a query that returns rows, typically a SELECT. -// The params are for any placeholders in the query. -func (db *DB) Query(model, query interface{}, params ...interface{}) (res orm.Result, err error) { - for attempt := 0; attempt <= db.opt.MaxRetries; attempt++ { - var cn *pool.Conn - - if attempt >= 1 { - time.Sleep(db.retryBackoff(attempt - 1)) - } - - cn, err = db.conn() - if err != nil { - continue - } - - start := time.Now() - res, err = db.simpleQueryData(cn, model, query, params...) - db.freeConn(cn, err) - db.queryProcessed(db, start, query, params, attempt, res, err) - - if !db.shouldRetry(err) { - break - } - } - if err != nil { - return nil, err - } - - if mod := res.Model(); mod != nil && res.RowsReturned() > 0 { - if err = mod.AfterQuery(db); err != nil { - return res, err - } - } - - return res, nil -} - -// QueryOne acts like Query, but query must return only one row. It -// returns ErrNoRows error when query returns zero rows or -// ErrMultiRows when query returns multiple rows. -func (db *DB) QueryOne(model, query interface{}, params ...interface{}) (orm.Result, error) { - res, err := db.Query(model, query, params...) - if err != nil { - return nil, err - } - - if err := internal.AssertOneRow(res.RowsAffected()); err != nil { - return nil, err - } - return res, nil -} - -// Listen listens for notifications sent with NOTIFY command. -func (db *DB) Listen(channels ...string) *Listener { - ln := &Listener{ - db: db, - } - ln.init() - _ = ln.Listen(channels...) - return ln -} - -// CopyFrom copies data from reader to a table. -func (db *DB) CopyFrom(r io.Reader, query interface{}, params ...interface{}) (orm.Result, error) { - cn, err := db.conn() - if err != nil { - return nil, err - } - - res, err := db.copyFrom(cn, r, query, params...) - db.freeConn(cn, err) - return res, err -} - -func (db *DB) copyFrom(cn *pool.Conn, r io.Reader, query interface{}, params ...interface{}) (orm.Result, error) { - err := cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - return writeQueryMsg(wb, db, query, params...) - }) - if err != nil { - return nil, err - } - - err = cn.WithReader(db.opt.ReadTimeout, func(rd *pool.Reader) error { - return readCopyInResponse(rd) - }) - if err != nil { - return nil, err - } - - for { - err = cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - return writeCopyData(wb, r) - }) - if err != nil { - if err == io.EOF { - break - } - return nil, err - } - } - - err = cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - writeCopyDone(wb) - return nil - }) - if err != nil { - return nil, err - } - - var res orm.Result - err = cn.WithReader(db.opt.ReadTimeout, func(rd *pool.Reader) error { - res, err = readReadyForQuery(rd) - return err - }) - if err != nil { - return nil, err - } - - return res, nil -} - -// CopyTo copies data from a table to writer. -func (db *DB) CopyTo(w io.Writer, query interface{}, params ...interface{}) (orm.Result, error) { - cn, err := db.conn() - if err != nil { - return nil, err - } - - res, err := db.copyTo(cn, w, query, params...) - if err != nil { - db.freeConn(cn, err) - return nil, err - } - - db.pool.Put(cn) - return res, nil -} - -func (db *DB) copyTo(cn *pool.Conn, w io.Writer, query interface{}, params ...interface{}) (orm.Result, error) { - err := cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - return writeQueryMsg(wb, db, query, params...) - }) - if err != nil { - return nil, err - } - - var res orm.Result - err = cn.WithReader(db.opt.ReadTimeout, func(rd *pool.Reader) error { - err := readCopyOutResponse(rd) - if err != nil { - return err - } - - res, err = readCopyData(rd, w) - return err - }) - if err != nil { - return nil, err - } - - return res, nil -} - -// Model returns new query for the model. -func (db *DB) Model(model ...interface{}) *orm.Query { - return orm.NewQuery(db, model...) -} - -// Select selects the model by primary key. -func (db *DB) Select(model interface{}) error { - return orm.Select(db, model) -} - -// Insert inserts the model updating primary keys if they are empty. -func (db *DB) Insert(model ...interface{}) error { - return orm.Insert(db, model...) -} - -// Update updates the model by primary key. -func (db *DB) Update(model interface{}) error { - return orm.Update(db, model) -} - -// Delete deletes the model by primary key. -func (db *DB) Delete(model interface{}) error { - return orm.Delete(db, model) -} - -// Delete forces delete of the model with deleted_at column. -func (db *DB) ForceDelete(model interface{}) error { - return orm.ForceDelete(db, model) -} - -// CreateTable creates table for the model. It recognizes following field tags: -// - notnull - sets NOT NULL constraint. -// - unique - sets UNIQUE constraint. -// - default:value - sets default value. -func (db *DB) CreateTable(model interface{}, opt *orm.CreateTableOptions) error { - return orm.CreateTable(db, model, opt) -} - -// DropTable drops table for the model. -func (db *DB) DropTable(model interface{}, opt *orm.DropTableOptions) error { - return orm.DropTable(db, model, opt) -} - -func (db *DB) CreateComposite(model interface{}, opt *orm.CreateCompositeOptions) error { - return orm.CreateComposite(db, model, opt) -} - -func (db *DB) DropComposite(model interface{}, opt *orm.DropCompositeOptions) error { - return orm.DropComposite(db, model, opt) -} - -func (db *DB) FormatQuery(dst []byte, query string, params ...interface{}) []byte { - return db.fmter.Append(dst, query, params...) -} - -func (db *DB) cancelRequest(processId, secretKey int32) error { - cn, err := db.pool.NewConn() - if err != nil { - return err - } - - err = cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - writeCancelRequestMsg(wb, processId, secretKey) - return nil - }) - if err != nil { - return err - } - - cn.Close() - return nil -} - -func (db *DB) simpleQuery( - cn *pool.Conn, query interface{}, params ...interface{}, -) (orm.Result, error) { - err := cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - return writeQueryMsg(wb, db, query, params...) - }) - if err != nil { - return nil, err - } - - var res orm.Result - err = cn.WithReader(db.opt.ReadTimeout, func(rd *pool.Reader) error { - res, err = readSimpleQuery(rd) - return err - }) - if err != nil { - return nil, err - } - - return res, nil -} - -func (db *DB) simpleQueryData( - cn *pool.Conn, model, query interface{}, params ...interface{}, -) (orm.Result, error) { - err := cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - return writeQueryMsg(wb, db, query, params...) - }) - if err != nil { - return nil, err - } - - var res orm.Result - err = cn.WithReader(db.opt.ReadTimeout, func(rd *pool.Reader) error { - res, err = readSimpleQueryData(rd, model) - return err - }) - if err != nil { - return nil, err - } - - return res, nil -} diff --git a/vendor/github.com/go-pg/pg/doc.go b/vendor/github.com/go-pg/pg/doc.go deleted file mode 100644 index f1d8eb192..000000000 --- a/vendor/github.com/go-pg/pg/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -/* -Package github.com/go-pg/pg implements a PostgreSQL client. -*/ -package pg diff --git a/vendor/github.com/go-pg/pg/error.go b/vendor/github.com/go-pg/pg/error.go deleted file mode 100644 index 995207608..000000000 --- a/vendor/github.com/go-pg/pg/error.go +++ /dev/null @@ -1,61 +0,0 @@ -package pg - -import ( - "io" - "net" - - "github.com/go-pg/pg/internal" -) - -// ErrNoRows is returned by QueryOne and ExecOne when query returned zero rows -// but at least one row is expected. -var ErrNoRows = internal.ErrNoRows - -// ErrMultiRows is returned by QueryOne and ExecOne when query returned -// multiple rows but exactly one row is expected. -var ErrMultiRows = internal.ErrMultiRows - -// Error represents an error returned by PostgreSQL server -// using PostgreSQL ErrorResponse protocol. -// -// https://www.postgresql.org/docs/10/static/protocol-message-formats.html -type Error interface { - // Field returns a string value associated with an error code. - // - // https://www.postgresql.org/docs/10/static/protocol-error-fields.html - Field(byte) string - - // IntegrityViolation reports whether an error is a part of - // Integrity Constraint Violation class of errors. - // - // https://www.postgresql.org/docs/10/static/errcodes-appendix.html - IntegrityViolation() bool -} - -var _ Error = (*internal.PGError)(nil) - -func isBadConn(err error, allowTimeout bool) bool { - if err == nil { - return false - } - if _, ok := err.(internal.Error); ok { - return false - } - if pgErr, ok := err.(Error); ok && pgErr.Field('S') != "FATAL" { - return false - } - if allowTimeout { - if netErr, ok := err.(net.Error); ok && netErr.Timeout() { - return false - } - } - return true -} - -func isNetworkError(err error) bool { - if err == io.EOF { - return true - } - _, ok := err.(net.Error) - return ok -} diff --git a/vendor/github.com/go-pg/pg/hook.go b/vendor/github.com/go-pg/pg/hook.go deleted file mode 100644 index ff6723b3f..000000000 --- a/vendor/github.com/go-pg/pg/hook.go +++ /dev/null @@ -1,145 +0,0 @@ -package pg - -import ( - "fmt" - "runtime" - "strings" - "time" - - "github.com/go-pg/pg/orm" -) - -type dummyDB struct { - orm.DB -} - -var _ orm.DB = dummyDB{} - -func (dummyDB) FormatQuery(dst []byte, query string, params ...interface{}) []byte { - return append(dst, query...) -} - -type QueryProcessedEvent struct { - StartTime time.Time - Func string - File string - Line int - - DB orm.DB - Query interface{} - Params []interface{} - Attempt int - Result orm.Result - Error error -} - -func (ev *QueryProcessedEvent) UnformattedQuery() (string, error) { - b, err := queryString(ev.Query) - if err != nil { - return "", err - } - return string(b), nil -} - -func (ev *QueryProcessedEvent) FormattedQuery() (string, error) { - b, err := appendQuery(nil, ev.DB, ev.Query, ev.Params...) - if err != nil { - return "", err - } - return string(b), nil -} - -func queryString(query interface{}) ([]byte, error) { - switch query := query.(type) { - case orm.QueryAppender: - query = query.Copy() - query.Query().DB(dummyDB{}) - return query.AppendQuery(nil) - case string: - return dummyDB{}.FormatQuery(nil, query), nil - default: - return nil, fmt.Errorf("pg: can't append %T", query) - } -} - -type queryProcessedHook func(*QueryProcessedEvent) - -// OnQueryProcessed calls the fn with QueryProcessedEvent -// when query is processed. -func (db *DB) OnQueryProcessed(fn func(*QueryProcessedEvent)) { - db.queryProcessedHooks = append(db.queryProcessedHooks, fn) -} - -func (db *DB) queryProcessed( - ormDB orm.DB, - start time.Time, - query interface{}, - params []interface{}, - attempt int, - res orm.Result, - err error, -) { - if len(db.queryProcessedHooks) == 0 { - return - } - - funcName, file, line := fileLine(2) - event := &QueryProcessedEvent{ - StartTime: start, - Func: funcName, - File: file, - Line: line, - - DB: ormDB, - Query: query, - Params: params, - Attempt: attempt, - Result: res, - Error: err, - } - for _, hook := range db.queryProcessedHooks { - hook(event) - } -} - -const packageName = "github.com/go-pg/pg" - -func fileLine(depth int) (string, string, int) { - for i := depth; ; i++ { - pc, file, line, ok := runtime.Caller(i) - if !ok { - break - } - if strings.Contains(file, packageName) { - continue - } - _, funcName := packageFuncName(pc) - return funcName, file, line - } - return "", "", 0 -} - -func packageFuncName(pc uintptr) (string, string) { - f := runtime.FuncForPC(pc) - if f == nil { - return "", "" - } - - packageName := "" - funcName := f.Name() - - if ind := strings.LastIndex(funcName, "/"); ind > 0 { - packageName += funcName[:ind+1] - funcName = funcName[ind+1:] - } - if ind := strings.Index(funcName, "."); ind > 0 { - packageName += funcName[:ind] - funcName = funcName[ind+1:] - } - - return packageName, funcName -} - -func copyQueryProcessedHooks(s []queryProcessedHook) []queryProcessedHook { - return s[:len(s):len(s)] -} diff --git a/vendor/github.com/go-pg/pg/internal/error.go b/vendor/github.com/go-pg/pg/internal/error.go deleted file mode 100644 index c6ff3d181..000000000 --- a/vendor/github.com/go-pg/pg/internal/error.go +++ /dev/null @@ -1,59 +0,0 @@ -package internal - -import ( - "fmt" -) - -var ErrNoRows = Errorf("pg: no rows in result set") -var ErrMultiRows = Errorf("pg: multiple rows in result set") - -type Error struct { - s string -} - -func Errorf(s string, args ...interface{}) Error { - return Error{s: fmt.Sprintf(s, args...)} -} - -func (err Error) Error() string { - return err.s -} - -type PGError struct { - m map[byte]string -} - -func NewPGError(m map[byte]string) PGError { - return PGError{ - m: m, - } -} - -func (err PGError) Field(k byte) string { - return err.m[k] -} - -func (err PGError) IntegrityViolation() bool { - switch err.Field('C') { - case "23000", "23001", "23502", "23503", "23505", "23514", "23P01": - return true - default: - return false - } -} - -func (err PGError) Error() string { - return fmt.Sprintf("%s #%s %s", - err.Field('S'), err.Field('C'), err.Field('M')) -} - -func AssertOneRow(l int) error { - switch { - case l == 0: - return ErrNoRows - case l > 1: - return ErrMultiRows - default: - return nil - } -} diff --git a/vendor/github.com/go-pg/pg/internal/internal.go b/vendor/github.com/go-pg/pg/internal/internal.go deleted file mode 100644 index ad3fc3c9f..000000000 --- a/vendor/github.com/go-pg/pg/internal/internal.go +++ /dev/null @@ -1,24 +0,0 @@ -package internal - -import ( - "math/rand" - "time" -) - -// Retry backoff with jitter sleep to prevent overloaded conditions during intervals -// https://www.awsarchitectureblog.com/2015/03/backoff.html -func RetryBackoff(retry int, minBackoff, maxBackoff time.Duration) time.Duration { - if retry < 0 { - retry = 0 - } - - backoff := minBackoff << uint(retry) - if backoff > maxBackoff || backoff < minBackoff { - backoff = maxBackoff - } - - if backoff == 0 { - return 0 - } - return time.Duration(rand.Int63n(int64(backoff))) -} diff --git a/vendor/github.com/go-pg/pg/internal/log.go b/vendor/github.com/go-pg/pg/internal/log.go deleted file mode 100644 index fd14222ee..000000000 --- a/vendor/github.com/go-pg/pg/internal/log.go +++ /dev/null @@ -1,15 +0,0 @@ -package internal - -import ( - "fmt" - "log" -) - -var Logger *log.Logger - -func Logf(s string, args ...interface{}) { - if Logger == nil { - return - } - Logger.Output(2, fmt.Sprintf(s, args...)) -} diff --git a/vendor/github.com/go-pg/pg/internal/parser/array_parser.go b/vendor/github.com/go-pg/pg/internal/parser/array_parser.go deleted file mode 100644 index 524d1244d..000000000 --- a/vendor/github.com/go-pg/pg/internal/parser/array_parser.go +++ /dev/null @@ -1,92 +0,0 @@ -package parser - -import ( - "bytes" - "fmt" -) - -type ArrayParser struct { - *Parser - - stickyErr error -} - -func NewArrayParser(b []byte) *ArrayParser { - var err error - if len(b) < 2 || b[0] != '{' || b[len(b)-1] != '}' { - err = fmt.Errorf("pg: can't parse array: %s", string(b)) - } else { - b = b[1 : len(b)-1] - } - return &ArrayParser{ - Parser: New(b), - - stickyErr: err, - } -} - -func (p *ArrayParser) NextElem() ([]byte, error) { - if p.stickyErr != nil { - return nil, p.stickyErr - } - - switch c := p.Peek(); c { - case '"': - p.Advance() - b := p.readSubstring() - - if p.Valid() { - if err := p.MustSkip(','); err != nil { - return nil, err - } - } - - return b, nil - case '{': - b := p.readSubArray() - if b != nil { - b = append(b, '}') - } - - if p.Valid() { - if err := p.MustSkip(','); err != nil { - return nil, err - } - } - - return b, nil - default: - b, _ := p.ReadSep(',') - if bytes.Equal(b, pgNull) { - b = nil - } - return b, nil - } -} - -func (p *ArrayParser) readSubArray() []byte { - var b []byte - for p.Valid() { - c := p.Read() - switch c { - case '"': - b = append(b, '"') - for { - bb, ok := p.ReadSep('"') - b = append(b, bb...) - stop := len(b) > 0 && b[len(b)-1] != '\\' - if ok { - b = append(b, '"') - } - if stop { - break - } - } - case '}': - return b - default: - b = append(b, c) - } - } - return b -} diff --git a/vendor/github.com/go-pg/pg/internal/parser/composite_parser.go b/vendor/github.com/go-pg/pg/internal/parser/composite_parser.go deleted file mode 100644 index 2b918eaa9..000000000 --- a/vendor/github.com/go-pg/pg/internal/parser/composite_parser.go +++ /dev/null @@ -1,53 +0,0 @@ -package parser - -import ( - "fmt" -) - -type CompositeParser struct { - *Parser - - stickyErr error -} - -func NewCompositeParser(b []byte) *CompositeParser { - var err error - if len(b) < 2 || b[0] != '(' || b[len(b)-1] != ')' { - err = fmt.Errorf("pg: can't parse composite value: %s", string(b)) - } else { - b = b[1 : len(b)-1] - } - return &CompositeParser{ - Parser: New(b), - - stickyErr: err, - } -} - -func (p *CompositeParser) NextElem() ([]byte, error) { - if p.stickyErr != nil { - return nil, p.stickyErr - } - - switch c := p.Peek(); c { - case '"': - b, err := p.ReadString() - if err != nil { - return nil, err - } - - if p.Valid() { - if err := p.MustSkip(','); err != nil { - return nil, err - } - } - - return b, nil - default: - b, _ := p.ReadSep(',') - if len(b) == 0 { // NULL - b = nil - } - return b, nil - } -} diff --git a/vendor/github.com/go-pg/pg/internal/parser/hstore_parser.go b/vendor/github.com/go-pg/pg/internal/parser/hstore_parser.go deleted file mode 100644 index f51561bd5..000000000 --- a/vendor/github.com/go-pg/pg/internal/parser/hstore_parser.go +++ /dev/null @@ -1,40 +0,0 @@ -package parser - -import "fmt" - -type HstoreParser struct { - *Parser -} - -func NewHstoreParser(b []byte) *HstoreParser { - return &HstoreParser{ - Parser: New(b), - } -} - -func (p *HstoreParser) NextKey() ([]byte, error) { - if p.Skip(',') { - p.Skip(' ') - } - - if !p.Skip('"') { - return nil, fmt.Errorf("pg: can't parse hstore key: %q", p.Bytes()) - } - - key := p.readSubstring() - if !(p.Skip('=') && p.Skip('>')) { - return nil, fmt.Errorf("pg: can't parse hstore key: %q", p.Bytes()) - } - - return key, nil -} - -func (p *HstoreParser) NextValue() ([]byte, error) { - if !p.Skip('"') { - return nil, fmt.Errorf("pg: can't parse hstore value: %q", p.Bytes()) - } - - value := p.readSubstring() - p.SkipBytes([]byte(", ")) - return value, nil -} diff --git a/vendor/github.com/go-pg/pg/internal/parser/parser.go b/vendor/github.com/go-pg/pg/internal/parser/parser.go deleted file mode 100644 index d94b7be26..000000000 --- a/vendor/github.com/go-pg/pg/internal/parser/parser.go +++ /dev/null @@ -1,170 +0,0 @@ -package parser - -import ( - "bytes" - "fmt" - "strconv" - - "github.com/go-pg/pg/internal" -) - -type Parser struct { - b []byte -} - -func New(b []byte) *Parser { - return &Parser{ - b: b, - } -} - -func NewString(s string) *Parser { - return New(internal.StringToBytes(s)) -} - -func (p *Parser) Bytes() []byte { - return p.b -} - -func (p *Parser) Valid() bool { - return len(p.b) > 0 -} - -func (p *Parser) Read() byte { - if p.Valid() { - c := p.b[0] - p.Advance() - return c - } - return 0 -} - -func (p *Parser) Peek() byte { - if p.Valid() { - return p.b[0] - } - return 0 -} - -func (p *Parser) Advance() { - p.b = p.b[1:] -} - -func (p *Parser) Skip(c byte) bool { - if p.Peek() == c { - p.Advance() - return true - } - return false -} - -func (p *Parser) MustSkip(c byte) error { - if p.Skip(c) { - return nil - } - return fmt.Errorf("expecting '%c', got %q", c, p.Bytes()) -} - -func (p *Parser) SkipBytes(b []byte) bool { - if len(b) > len(p.b) { - return false - } - if !bytes.Equal(p.b[:len(b)], b) { - return false - } - p.b = p.b[len(b):] - return true -} - -func (p *Parser) ReadSep(c byte) ([]byte, bool) { - ind := bytes.IndexByte(p.b, c) - if ind == -1 { - b := p.b - p.b = p.b[len(p.b):] - return b, false - } - - b := p.b[:ind] - p.b = p.b[ind+1:] - return b, true -} - -func (p *Parser) ReadIdentifier() (s string, numeric bool) { - end := len(p.b) - numeric = true - for i, ch := range p.b { - if isNum(ch) { - continue - } - if isAlpha(ch) || (i > 0 && ch == '_') { - numeric = false - continue - } - end = i - break - } - if end == 0 { - return "", false - } - b := p.b[:end] - p.b = p.b[end:] - return internal.BytesToString(b), numeric -} - -func (p *Parser) ReadNumber() int { - end := len(p.b) - for i, ch := range p.b { - if !isNum(ch) { - end = i - break - } - } - if end <= 0 { - return 0 - } - n, _ := strconv.Atoi(string(p.b[:end])) - p.b = p.b[end:] - return n -} - -func (p *Parser) ReadString() ([]byte, error) { - quote := p.Read() - b, ok := p.ReadSep(quote) - if !ok { - return nil, fmt.Errorf("can't find closing quote") - } - return b, nil -} - -func (p *Parser) readSubstring() []byte { - var b []byte - for p.Valid() { - c := p.Read() - switch c { - case '\\': - switch p.Peek() { - case '\\': - b = append(b, '\\') - p.Advance() - case '"': - b = append(b, '"') - p.Advance() - default: - b = append(b, c) - } - case '\'': - switch p.Peek() { - case '\'': - b = append(b, '\'') - p.Advance() - default: - b = append(b, c) - } - case '"': - return b - default: - b = append(b, c) - } - } - return b -} diff --git a/vendor/github.com/go-pg/pg/internal/parser/util.go b/vendor/github.com/go-pg/pg/internal/parser/util.go deleted file mode 100644 index 23844e31a..000000000 --- a/vendor/github.com/go-pg/pg/internal/parser/util.go +++ /dev/null @@ -1,15 +0,0 @@ -package parser - -var pgNull = []byte("NULL") - -func isNum(c byte) bool { - return c >= '0' && c <= '9' -} - -func isAlpha(c byte) bool { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') -} - -func isAlnum(c byte) bool { - return isAlpha(c) || isNum(c) -} diff --git a/vendor/github.com/go-pg/pg/internal/pool/conn.go b/vendor/github.com/go-pg/pg/internal/pool/conn.go deleted file mode 100644 index b1900eeca..000000000 --- a/vendor/github.com/go-pg/pg/internal/pool/conn.go +++ /dev/null @@ -1,129 +0,0 @@ -package pool - -import ( - "net" - "strconv" - "sync/atomic" - "time" -) - -var noDeadline = time.Time{} - -type Conn struct { - netConn net.Conn - - buf []byte - rd *Reader - rdLocked bool - wb *WriteBuffer - - InitedAt time.Time - pooled bool - usedAt atomic.Value - - ProcessId int32 - SecretKey int32 - - _lastId int64 -} - -func NewConn(netConn net.Conn) *Conn { - cn := &Conn{ - buf: makeBuffer(), - rd: NewReader(NewElasticBufReader(netConn)), - wb: NewWriteBuffer(), - } - cn.SetNetConn(netConn) - cn.SetUsedAt(time.Now()) - return cn -} - -func (cn *Conn) UsedAt() time.Time { - return cn.usedAt.Load().(time.Time) -} - -func (cn *Conn) SetUsedAt(tm time.Time) { - cn.usedAt.Store(tm) -} - -func (cn *Conn) RemoteAddr() net.Addr { - return cn.netConn.RemoteAddr() -} - -func (cn *Conn) SetNetConn(netConn net.Conn) { - cn.netConn = netConn - cn.rd.Reset(netConn) -} - -func (cn *Conn) NetConn() net.Conn { - return cn.netConn -} - -func (cn *Conn) NextId() string { - cn._lastId++ - return strconv.FormatInt(cn._lastId, 10) -} - -func (cn *Conn) setReadTimeout(timeout time.Duration) error { - now := time.Now() - cn.SetUsedAt(now) - if timeout > 0 { - return cn.netConn.SetReadDeadline(now.Add(timeout)) - } - return cn.netConn.SetReadDeadline(noDeadline) -} - -func (cn *Conn) setWriteTimeout(timeout time.Duration) error { - now := time.Now() - cn.SetUsedAt(now) - if timeout > 0 { - return cn.netConn.SetWriteDeadline(now.Add(timeout)) - } - return cn.netConn.SetWriteDeadline(noDeadline) -} - -func (cn *Conn) LockReaderBuffer() { - cn.rdLocked = true - cn.rd.ResetBuffer(makeBuffer()) -} - -func (cn *Conn) WithReader(timeout time.Duration, fn func(rd *Reader) error) error { - _ = cn.setReadTimeout(timeout) - - if !cn.rdLocked { - cn.rd.ResetBuffer(cn.buf) - } - - err := fn(cn.rd) - - if !cn.rdLocked { - cn.buf = cn.rd.Buffer() - } - - return err -} - -func (cn *Conn) WithWriter(timeout time.Duration, fn func(wb *WriteBuffer) error) error { - _ = cn.setWriteTimeout(timeout) - - cn.wb.ResetBuffer(cn.buf) - - firstErr := fn(cn.wb) - - _, err := cn.netConn.Write(cn.wb.Bytes) - cn.buf = cn.wb.Buffer() - if err != nil && firstErr == nil { - firstErr = err - } - - return firstErr -} - -func (cn *Conn) Close() error { - return cn.netConn.Close() -} - -func makeBuffer() []byte { - const defaulBufSize = 4096 - return make([]byte, defaulBufSize) -} diff --git a/vendor/github.com/go-pg/pg/internal/pool/elastic_reader.go b/vendor/github.com/go-pg/pg/internal/pool/elastic_reader.go deleted file mode 100644 index b4f8a6eef..000000000 --- a/vendor/github.com/go-pg/pg/internal/pool/elastic_reader.go +++ /dev/null @@ -1,185 +0,0 @@ -package pool - -import ( - "bytes" - "errors" - "io" -) - -const defaultBufSize = 4096 - -// ElasticBufReader is like bufio.Reader but instead of returning ErrBufferFull -// it automatically grows the buffer. -type ElasticBufReader struct { - buf []byte - rd io.Reader // reader provided by the client - r, w int // buf read and write positions - err error -} - -func NewElasticBufReader(rd io.Reader) *ElasticBufReader { - return &ElasticBufReader{ - rd: rd, - } -} - -func (b *ElasticBufReader) Reset(rd io.Reader) { - b.rd = rd - b.r, b.w = 0, 0 - b.err = nil -} - -func (b *ElasticBufReader) Buffer() []byte { - return b.buf -} - -func (b *ElasticBufReader) ResetBuffer(buf []byte) { - b.buf = buf - b.r, b.w = 0, 0 - b.err = nil -} - -// Buffered returns the number of bytes that can be read from the current buffer. -func (b *ElasticBufReader) Buffered() int { - return b.w - b.r -} - -func (b *ElasticBufReader) Bytes() []byte { - return b.buf[b.r:b.w] -} - -var errNegativeRead = errors.New("bufio: reader returned negative count from Read") - -// fill reads a new chunk into the buffer. -func (b *ElasticBufReader) fill() { - // Slide existing data to beginning. - if b.r > 0 { - copy(b.buf, b.buf[b.r:b.w]) - b.w -= b.r - b.r = 0 - } - - if b.w >= len(b.buf) { - panic("bufio: tried to fill full buffer") - } - - // Read new data: try a limited number of times. - const maxConsecutiveEmptyReads = 100 - for i := maxConsecutiveEmptyReads; i > 0; i-- { - n, err := b.rd.Read(b.buf[b.w:]) - if n < 0 { - panic(errNegativeRead) - } - b.w += n - if err != nil { - b.err = err - return - } - if n > 0 { - return - } - } - b.err = io.ErrNoProgress -} - -func (b *ElasticBufReader) readErr() error { - err := b.err - b.err = nil - return err -} - -func (b *ElasticBufReader) ReadSlice(delim byte) (line []byte, err error) { - for { - // Search buffer. - if i := bytes.IndexByte(b.buf[b.r:b.w], delim); i >= 0 { - line = b.buf[b.r : b.r+i+1] - b.r += i + 1 - break - } - - // Pending error? - if b.err != nil { - line = b.buf[b.r:b.w] - b.r = b.w - err = b.readErr() - break - } - - // Buffer full? - if b.Buffered() >= len(b.buf) { - b.grow(len(b.buf) + defaultBufSize) - } - - b.fill() // buffer is not full - } - - return -} - -func (b *ElasticBufReader) ReadLine() (line []byte, err error) { - line, err = b.ReadSlice('\n') - if len(line) == 0 { - if err != nil { - line = nil - } - return - } - err = nil - - if line[len(line)-1] == '\n' { - drop := 1 - if len(line) > 1 && line[len(line)-2] == '\r' { - drop = 2 - } - line = line[:len(line)-drop] - } - return -} - -func (b *ElasticBufReader) ReadByte() (byte, error) { - for b.r == b.w { - if b.err != nil { - return 0, b.readErr() - } - b.fill() // buffer is empty - } - c := b.buf[b.r] - b.r++ - return c, nil -} - -func (b *ElasticBufReader) ReadN(n int) ([]byte, error) { - b.grow(n) - for b.Buffered() < n { - // Pending error? - if b.err != nil { - buf := b.buf[b.r:b.w] - b.r = b.w - return buf, b.readErr() - } - - b.fill() - } - - buf := b.buf[b.r : b.r+n] - b.r += n - return buf, nil -} - -func (b *ElasticBufReader) grow(n int) { - if b.w-b.r >= n { - return - } - - // Slide existing data to beginning. - if b.r > 0 { - copy(b.buf, b.buf[b.r:b.w]) - b.w -= b.r - b.r = 0 - } - - // Extend buffer if needed. - if d := n - len(b.buf); d > 0 { - b.buf = append(b.buf, make([]byte, d)...) - } -} diff --git a/vendor/github.com/go-pg/pg/internal/pool/pool.go b/vendor/github.com/go-pg/pg/internal/pool/pool.go deleted file mode 100644 index 4bdd1e069..000000000 --- a/vendor/github.com/go-pg/pg/internal/pool/pool.go +++ /dev/null @@ -1,476 +0,0 @@ -package pool - -import ( - "errors" - "net" - "sync" - "sync/atomic" - "time" - - "github.com/go-pg/pg/internal" -) - -var ErrClosed = errors.New("pg: database is closed") -var ErrPoolTimeout = errors.New("pg: connection pool timeout") - -var timers = sync.Pool{ - New: func() interface{} { - t := time.NewTimer(time.Hour) - t.Stop() - return t - }, -} - -// Stats contains pool state information and accumulated stats. -type Stats struct { - Hits uint32 // number of times free connection was found in the pool - Misses uint32 // number of times free connection was NOT found in the pool - Timeouts uint32 // number of times a wait timeout occurred - - TotalConns uint32 // number of total connections in the pool - IdleConns uint32 // number of idle connections in the pool - StaleConns uint32 // number of stale connections removed from the pool -} - -type Pooler interface { - NewConn() (*Conn, error) - CloseConn(*Conn) error - - Get() (*Conn, error) - Put(*Conn) - Remove(*Conn) - - Len() int - IdleLen() int - Stats() *Stats - - Close() error -} - -type Options struct { - Dialer func() (net.Conn, error) - OnClose func(*Conn) error - - PoolSize int - MinIdleConns int - MaxConnAge time.Duration - PoolTimeout time.Duration - IdleTimeout time.Duration - IdleCheckFrequency time.Duration -} - -type ConnPool struct { - opt *Options - - dialErrorsNum uint32 // atomic - - lastDialErrorMu sync.RWMutex - lastDialError error - - queue chan struct{} - - connsMu sync.Mutex - conns []*Conn - idleConns []*Conn - poolSize int - idleConnsLen int - - stats Stats - - _closed uint32 // atomic -} - -var _ Pooler = (*ConnPool)(nil) - -func NewConnPool(opt *Options) *ConnPool { - p := &ConnPool{ - opt: opt, - - queue: make(chan struct{}, opt.PoolSize), - conns: make([]*Conn, 0, opt.PoolSize), - idleConns: make([]*Conn, 0, opt.PoolSize), - } - - for i := 0; i < opt.MinIdleConns; i++ { - p.checkMinIdleConns() - } - - if opt.IdleTimeout > 0 && opt.IdleCheckFrequency > 0 { - go p.reaper(opt.IdleCheckFrequency) - } - - return p -} - -func (p *ConnPool) checkMinIdleConns() { - if p.opt.MinIdleConns == 0 { - return - } - if p.poolSize < p.opt.PoolSize && p.idleConnsLen < p.opt.MinIdleConns { - p.poolSize++ - p.idleConnsLen++ - go p.addIdleConn() - } -} - -func (p *ConnPool) addIdleConn() { - cn, err := p.newConn(true) - if err != nil { - return - } - - p.connsMu.Lock() - p.conns = append(p.conns, cn) - p.idleConns = append(p.idleConns, cn) - p.connsMu.Unlock() -} - -func (p *ConnPool) NewConn() (*Conn, error) { - return p._NewConn(false) -} - -func (p *ConnPool) _NewConn(pooled bool) (*Conn, error) { - cn, err := p.newConn(pooled) - if err != nil { - return nil, err - } - - p.connsMu.Lock() - p.conns = append(p.conns, cn) - if pooled { - if p.poolSize < p.opt.PoolSize { - p.poolSize++ - } else { - cn.pooled = false - } - } - p.connsMu.Unlock() - return cn, nil -} - -func (p *ConnPool) newConn(pooled bool) (*Conn, error) { - if p.closed() { - return nil, ErrClosed - } - - if atomic.LoadUint32(&p.dialErrorsNum) >= uint32(p.opt.PoolSize) { - return nil, p.getLastDialError() - } - - netConn, err := p.opt.Dialer() - if err != nil { - p.setLastDialError(err) - if atomic.AddUint32(&p.dialErrorsNum, 1) == uint32(p.opt.PoolSize) { - go p.tryDial() - } - return nil, err - } - - cn := NewConn(netConn) - cn.pooled = pooled - return cn, nil -} - -func (p *ConnPool) tryDial() { - for { - if p.closed() { - return - } - - conn, err := p.opt.Dialer() - if err != nil { - p.setLastDialError(err) - time.Sleep(time.Second) - continue - } - - atomic.StoreUint32(&p.dialErrorsNum, 0) - _ = conn.Close() - return - } -} - -func (p *ConnPool) setLastDialError(err error) { - p.lastDialErrorMu.Lock() - p.lastDialError = err - p.lastDialErrorMu.Unlock() -} - -func (p *ConnPool) getLastDialError() error { - p.lastDialErrorMu.RLock() - err := p.lastDialError - p.lastDialErrorMu.RUnlock() - return err -} - -// Get returns existed connection from the pool or creates a new one. -func (p *ConnPool) Get() (*Conn, error) { - if p.closed() { - return nil, ErrClosed - } - - err := p.waitTurn() - if err != nil { - return nil, err - } - - for { - p.connsMu.Lock() - cn := p.popIdle() - p.connsMu.Unlock() - - if cn == nil { - break - } - - if p.isStaleConn(cn) { - _ = p.CloseConn(cn) - continue - } - - atomic.AddUint32(&p.stats.Hits, 1) - return cn, nil - } - - atomic.AddUint32(&p.stats.Misses, 1) - - newcn, err := p._NewConn(true) - if err != nil { - p.freeTurn() - return nil, err - } - - return newcn, nil -} - -func (p *ConnPool) getTurn() { - p.queue <- struct{}{} -} - -func (p *ConnPool) waitTurn() error { - select { - case p.queue <- struct{}{}: - return nil - default: - timer := timers.Get().(*time.Timer) - timer.Reset(p.opt.PoolTimeout) - - select { - case p.queue <- struct{}{}: - if !timer.Stop() { - <-timer.C - } - timers.Put(timer) - return nil - case <-timer.C: - timers.Put(timer) - atomic.AddUint32(&p.stats.Timeouts, 1) - return ErrPoolTimeout - } - } -} - -func (p *ConnPool) freeTurn() { - <-p.queue -} - -func (p *ConnPool) popIdle() *Conn { - if len(p.idleConns) == 0 { - return nil - } - - idx := len(p.idleConns) - 1 - cn := p.idleConns[idx] - p.idleConns = p.idleConns[:idx] - p.idleConnsLen-- - p.checkMinIdleConns() - return cn -} - -func (p *ConnPool) Put(cn *Conn) { - if !cn.pooled { - p.Remove(cn) - return - } - - p.connsMu.Lock() - p.idleConns = append(p.idleConns, cn) - p.idleConnsLen++ - p.connsMu.Unlock() - p.freeTurn() -} - -func (p *ConnPool) Remove(cn *Conn) { - p.removeConn(cn) - p.freeTurn() - _ = p.closeConn(cn) -} - -func (p *ConnPool) CloseConn(cn *Conn) error { - p.removeConn(cn) - return p.closeConn(cn) -} - -func (p *ConnPool) removeConn(cn *Conn) { - p.connsMu.Lock() - for i, c := range p.conns { - if c == cn { - p.conns = append(p.conns[:i], p.conns[i+1:]...) - if cn.pooled { - p.poolSize-- - p.checkMinIdleConns() - } - break - } - } - p.connsMu.Unlock() -} - -func (p *ConnPool) closeConn(cn *Conn) error { - if p.opt.OnClose != nil { - _ = p.opt.OnClose(cn) - } - return cn.Close() -} - -// Len returns total number of connections. -func (p *ConnPool) Len() int { - p.connsMu.Lock() - n := len(p.conns) - p.connsMu.Unlock() - return n -} - -// IdleLen returns number of idle connections. -func (p *ConnPool) IdleLen() int { - p.connsMu.Lock() - n := p.idleConnsLen - p.connsMu.Unlock() - return n -} - -func (p *ConnPool) Stats() *Stats { - idleLen := p.IdleLen() - return &Stats{ - Hits: atomic.LoadUint32(&p.stats.Hits), - Misses: atomic.LoadUint32(&p.stats.Misses), - Timeouts: atomic.LoadUint32(&p.stats.Timeouts), - - TotalConns: uint32(p.Len()), - IdleConns: uint32(idleLen), - StaleConns: atomic.LoadUint32(&p.stats.StaleConns), - } -} - -func (p *ConnPool) closed() bool { - return atomic.LoadUint32(&p._closed) == 1 -} - -func (p *ConnPool) Filter(fn func(*Conn) bool) error { - var firstErr error - p.connsMu.Lock() - for _, cn := range p.conns { - if fn(cn) { - if err := p.closeConn(cn); err != nil && firstErr == nil { - firstErr = err - } - } - } - p.connsMu.Unlock() - return firstErr -} - -func (p *ConnPool) Close() error { - if !atomic.CompareAndSwapUint32(&p._closed, 0, 1) { - return ErrClosed - } - - var firstErr error - p.connsMu.Lock() - for _, cn := range p.conns { - if err := p.closeConn(cn); err != nil && firstErr == nil { - firstErr = err - } - } - p.conns = nil - p.poolSize = 0 - p.idleConns = nil - p.idleConnsLen = 0 - p.connsMu.Unlock() - - return firstErr -} - -func (p *ConnPool) reapStaleConn() *Conn { - if len(p.idleConns) == 0 { - return nil - } - - cn := p.idleConns[0] - if !p.isStaleConn(cn) { - return nil - } - - p.idleConns = append(p.idleConns[:0], p.idleConns[1:]...) - p.idleConnsLen-- - - return cn -} - -func (p *ConnPool) ReapStaleConns() (int, error) { - var n int - for { - p.getTurn() - - p.connsMu.Lock() - cn := p.reapStaleConn() - p.connsMu.Unlock() - - if cn != nil { - p.removeConn(cn) - } - - p.freeTurn() - - if cn != nil { - p.closeConn(cn) - n++ - } else { - break - } - } - return n, nil -} - -func (p *ConnPool) reaper(frequency time.Duration) { - ticker := time.NewTicker(frequency) - defer ticker.Stop() - - for range ticker.C { - if p.closed() { - break - } - n, err := p.ReapStaleConns() - if err != nil { - internal.Logf("ReapStaleConns failed: %s", err) - continue - } - atomic.AddUint32(&p.stats.StaleConns, uint32(n)) - } -} - -func (p *ConnPool) isStaleConn(cn *Conn) bool { - if p.opt.IdleTimeout == 0 && p.opt.MaxConnAge == 0 { - return false - } - - now := time.Now() - if p.opt.IdleTimeout > 0 && now.Sub(cn.UsedAt()) >= p.opt.IdleTimeout { - return true - } - if p.opt.MaxConnAge > 0 && now.Sub(cn.InitedAt) >= p.opt.MaxConnAge { - return true - } - - return false -} diff --git a/vendor/github.com/go-pg/pg/internal/pool/pool_single.go b/vendor/github.com/go-pg/pg/internal/pool/pool_single.go deleted file mode 100644 index b35b78afb..000000000 --- a/vendor/github.com/go-pg/pg/internal/pool/pool_single.go +++ /dev/null @@ -1,53 +0,0 @@ -package pool - -type SingleConnPool struct { - cn *Conn -} - -var _ Pooler = (*SingleConnPool)(nil) - -func NewSingleConnPool(cn *Conn) *SingleConnPool { - return &SingleConnPool{ - cn: cn, - } -} - -func (p *SingleConnPool) NewConn() (*Conn, error) { - panic("not implemented") -} - -func (p *SingleConnPool) CloseConn(*Conn) error { - panic("not implemented") -} - -func (p *SingleConnPool) Get() (*Conn, error) { - return p.cn, nil -} - -func (p *SingleConnPool) Put(cn *Conn) { - if p.cn != cn { - panic("p.cn != cn") - } -} - -func (p *SingleConnPool) Remove(cn *Conn) { - if p.cn != cn { - panic("p.cn != cn") - } -} - -func (p *SingleConnPool) Len() int { - return 1 -} - -func (p *SingleConnPool) IdleLen() int { - return 0 -} - -func (p *SingleConnPool) Stats() *Stats { - return nil -} - -func (p *SingleConnPool) Close() error { - return nil -} diff --git a/vendor/github.com/go-pg/pg/internal/pool/reader.go b/vendor/github.com/go-pg/pg/internal/pool/reader.go deleted file mode 100644 index 9eedd4762..000000000 --- a/vendor/github.com/go-pg/pg/internal/pool/reader.go +++ /dev/null @@ -1,71 +0,0 @@ -package pool - -import ( - "encoding/binary" - - "github.com/go-pg/pg/internal" -) - -type Reader struct { - *ElasticBufReader - Columns [][]byte -} - -func NewReader(buf *ElasticBufReader) *Reader { - return &Reader{ElasticBufReader: buf} -} - -func (rd *Reader) ReadInt16() (int16, error) { - b, err := rd.ReadN(2) - if err != nil { - return 0, err - } - return int16(binary.BigEndian.Uint16(b)), nil -} - -func (rd *Reader) ReadInt32() (int32, error) { - b, err := rd.ReadN(4) - if err != nil { - return 0, err - } - return int32(binary.BigEndian.Uint32(b)), nil -} - -func (rd *Reader) ReadString() (string, error) { - b, err := rd.ReadSlice(0) - if err != nil { - return "", err - } - return string(b[:len(b)-1]), nil -} - -func (rd *Reader) ReadError() (error, error) { - m := make(map[byte]string) - for { - c, err := rd.ReadByte() - if err != nil { - return nil, err - } - if c == 0 { - break - } - s, err := rd.ReadString() - if err != nil { - return nil, err - } - m[c] = s - } - return internal.NewPGError(m), nil -} - -func (rd *Reader) ReadMessageType() (byte, int, error) { - c, err := rd.ReadByte() - if err != nil { - return 0, 0, err - } - l, err := rd.ReadInt32() - if err != nil { - return 0, 0, err - } - return c, int(l) - 4, nil -} diff --git a/vendor/github.com/go-pg/pg/internal/pool/write_buffer.go b/vendor/github.com/go-pg/pg/internal/pool/write_buffer.go deleted file mode 100644 index 71eb753c1..000000000 --- a/vendor/github.com/go-pg/pg/internal/pool/write_buffer.go +++ /dev/null @@ -1,96 +0,0 @@ -package pool - -import ( - "encoding/binary" - "io" -) - -type WriteBuffer struct { - Bytes []byte - - msgStart, paramStart int -} - -func NewWriteBuffer() *WriteBuffer { - return new(WriteBuffer) -} - -func (buf *WriteBuffer) Buffer() []byte { - return buf.Bytes[:cap(buf.Bytes)] -} - -func (buf *WriteBuffer) Reset() { - buf.Bytes = buf.Bytes[:0] -} - -func (buf *WriteBuffer) ResetBuffer(b []byte) { - buf.Bytes = b[:0] -} - -func (buf *WriteBuffer) StartMessage(c byte) { - if c == 0 { - buf.msgStart = len(buf.Bytes) - buf.Bytes = append(buf.Bytes, 0, 0, 0, 0) - } else { - buf.msgStart = len(buf.Bytes) + 1 - buf.Bytes = append(buf.Bytes, c, 0, 0, 0, 0) - } -} - -func (buf *WriteBuffer) FinishMessage() { - binary.BigEndian.PutUint32( - buf.Bytes[buf.msgStart:], uint32(len(buf.Bytes)-buf.msgStart)) -} - -func (buf *WriteBuffer) StartParam() { - buf.paramStart = len(buf.Bytes) - buf.Bytes = append(buf.Bytes, 0, 0, 0, 0) -} - -func (buf *WriteBuffer) FinishParam() { - binary.BigEndian.PutUint32( - buf.Bytes[buf.paramStart:], uint32(len(buf.Bytes)-buf.paramStart-4)) -} - -var nullParamLength = int32(-1) - -func (buf *WriteBuffer) FinishNullParam() { - binary.BigEndian.PutUint32( - buf.Bytes[buf.paramStart:], uint32(nullParamLength)) -} - -func (buf *WriteBuffer) Write(b []byte) (int, error) { - buf.Bytes = append(buf.Bytes, b...) - return len(b), nil -} - -func (buf *WriteBuffer) WriteInt16(num int16) { - buf.Bytes = append(buf.Bytes, 0, 0) - binary.BigEndian.PutUint16(buf.Bytes[len(buf.Bytes)-2:], uint16(num)) -} - -func (buf *WriteBuffer) WriteInt32(num int32) { - buf.Bytes = append(buf.Bytes, 0, 0, 0, 0) - binary.BigEndian.PutUint32(buf.Bytes[len(buf.Bytes)-4:], uint32(num)) -} - -func (buf *WriteBuffer) WriteString(s string) { - buf.Bytes = append(buf.Bytes, s...) - buf.Bytes = append(buf.Bytes, 0) -} - -func (buf *WriteBuffer) WriteBytes(b []byte) { - buf.Bytes = append(buf.Bytes, b...) - buf.Bytes = append(buf.Bytes, 0) -} - -func (buf *WriteBuffer) WriteByte(c byte) error { - buf.Bytes = append(buf.Bytes, c) - return nil -} - -func (buf *WriteBuffer) ReadFrom(r io.Reader) (int64, error) { - n, err := r.Read(buf.Bytes[len(buf.Bytes):cap(buf.Bytes)]) - buf.Bytes = buf.Bytes[:len(buf.Bytes)+int(n)] - return int64(n), err -} diff --git a/vendor/github.com/go-pg/pg/internal/safe.go b/vendor/github.com/go-pg/pg/internal/safe.go deleted file mode 100644 index 870fe541f..000000000 --- a/vendor/github.com/go-pg/pg/internal/safe.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build appengine - -package internal - -func BytesToString(b []byte) string { - return string(b) -} - -func StringToBytes(s string) []byte { - return []byte(s) -} diff --git a/vendor/github.com/go-pg/pg/internal/strconv.go b/vendor/github.com/go-pg/pg/internal/strconv.go deleted file mode 100644 index 9e42ffb03..000000000 --- a/vendor/github.com/go-pg/pg/internal/strconv.go +++ /dev/null @@ -1,19 +0,0 @@ -package internal - -import "strconv" - -func Atoi(b []byte) (int, error) { - return strconv.Atoi(BytesToString(b)) -} - -func ParseInt(b []byte, base int, bitSize int) (int64, error) { - return strconv.ParseInt(BytesToString(b), base, bitSize) -} - -func ParseUint(b []byte, base int, bitSize int) (uint64, error) { - return strconv.ParseUint(BytesToString(b), base, bitSize) -} - -func ParseFloat(b []byte, bitSize int) (float64, error) { - return strconv.ParseFloat(BytesToString(b), bitSize) -} diff --git a/vendor/github.com/go-pg/pg/internal/underscore.go b/vendor/github.com/go-pg/pg/internal/underscore.go deleted file mode 100644 index e71c11705..000000000 --- a/vendor/github.com/go-pg/pg/internal/underscore.go +++ /dev/null @@ -1,93 +0,0 @@ -package internal - -func IsUpper(c byte) bool { - return c >= 'A' && c <= 'Z' -} - -func IsLower(c byte) bool { - return c >= 'a' && c <= 'z' -} - -func ToUpper(c byte) byte { - return c - 32 -} - -func ToLower(c byte) byte { - return c + 32 -} - -// Underscore converts "CamelCasedString" to "camel_cased_string". -func Underscore(s string) string { - r := make([]byte, 0, len(s)+5) - for i := 0; i < len(s); i++ { - c := s[i] - if IsUpper(c) { - if i > 0 && i+1 < len(s) && (IsLower(s[i-1]) || IsLower(s[i+1])) { - r = append(r, '_', ToLower(c)) - } else { - r = append(r, ToLower(c)) - } - } else { - r = append(r, c) - } - } - return string(r) -} - -func CamelCased(s string) string { - r := make([]byte, 0, len(s)) - upperNext := true - for i := 0; i < len(s); i++ { - c := s[i] - if c == '_' { - upperNext = true - continue - } - if upperNext { - if IsLower(c) { - c = ToUpper(c) - } - upperNext = false - } - r = append(r, c) - } - return string(r) -} - -func ToExported(s string) string { - if len(s) == 0 { - return s - } - if c := s[0]; IsLower(c) { - b := []byte(s) - b[0] = ToUpper(c) - return string(b) - } - return s -} - -func UpperString(s string) string { - if isUpperString(s) { - return s - } - - b := make([]byte, len(s)) - for i := range b { - c := s[i] - if IsLower(c) { - c = ToUpper(c) - } - b[i] = c - } - return string(b) -} - -func isUpperString(s string) bool { - for i := 0; i < len(s); i++ { - c := s[i] - if IsLower(c) { - return false - } - } - return true -} diff --git a/vendor/github.com/go-pg/pg/internal/unsafe.go b/vendor/github.com/go-pg/pg/internal/unsafe.go deleted file mode 100644 index f8bc18d91..000000000 --- a/vendor/github.com/go-pg/pg/internal/unsafe.go +++ /dev/null @@ -1,22 +0,0 @@ -// +build !appengine - -package internal - -import ( - "unsafe" -) - -// BytesToString converts byte slice to string. -func BytesToString(b []byte) string { - return *(*string)(unsafe.Pointer(&b)) -} - -// StringToBytes converts string to byte slice. -func StringToBytes(s string) []byte { - return *(*[]byte)(unsafe.Pointer( - &struct { - string - Cap int - }{s, len(s)}, - )) -} diff --git a/vendor/github.com/go-pg/pg/internal/util.go b/vendor/github.com/go-pg/pg/internal/util.go deleted file mode 100644 index 12ec11923..000000000 --- a/vendor/github.com/go-pg/pg/internal/util.go +++ /dev/null @@ -1,36 +0,0 @@ -package internal - -import "reflect" - -func MakeSliceNextElemFunc(v reflect.Value) func() reflect.Value { - elemType := v.Type().Elem() - - if elemType.Kind() == reflect.Ptr { - elemType = elemType.Elem() - return func() reflect.Value { - if v.Len() < v.Cap() { - v.Set(v.Slice(0, v.Len()+1)) - elem := v.Index(v.Len() - 1) - if elem.IsNil() { - elem.Set(reflect.New(elemType)) - } - return elem.Elem() - } - - elem := reflect.New(elemType) - v.Set(reflect.Append(v, elem)) - return elem.Elem() - } - } - - zero := reflect.Zero(elemType) - return func() reflect.Value { - if v.Len() < v.Cap() { - v.Set(v.Slice(0, v.Len()+1)) - return v.Index(v.Len() - 1) - } - - v.Set(reflect.Append(v, zero)) - return v.Index(v.Len() - 1) - } -} diff --git a/vendor/github.com/go-pg/pg/listener.go b/vendor/github.com/go-pg/pg/listener.go deleted file mode 100644 index 2eade2b45..000000000 --- a/vendor/github.com/go-pg/pg/listener.go +++ /dev/null @@ -1,316 +0,0 @@ -package pg - -import ( - "errors" - "sync" - "time" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/internal/pool" - "github.com/go-pg/pg/types" -) - -const gopgChannel = "gopg:ping" - -var errListenerClosed = errors.New("pg: listener is closed") - -// A notification received with LISTEN command. -type Notification struct { - Channel string - Payload string -} - -// Listener listens for notifications sent with NOTIFY command. -// It's NOT safe for concurrent use by multiple goroutines -// except the Channel API. -type Listener struct { - db *DB - - channels []string - - mu sync.Mutex - cn *pool.Conn - closed bool - exit chan struct{} - - chOnce sync.Once - ch chan *Notification - pingCh chan struct{} -} - -func (ln *Listener) init() { - ln.exit = make(chan struct{}) -} - -func (ln *Listener) conn() (*pool.Conn, error) { - ln.mu.Lock() - cn, err := ln._conn() - ln.mu.Unlock() - - switch err { - case nil: - return cn, nil - case errListenerClosed: - return nil, err - case pool.ErrClosed: - _ = ln.Close() - return nil, errListenerClosed - default: - internal.Logf("pg: Listen failed: %s", err) - return nil, err - } -} - -func (ln *Listener) _conn() (*pool.Conn, error) { - if ln.closed { - return nil, errListenerClosed - } - - if ln.cn != nil { - return ln.cn, nil - } - - cn, err := ln.db.pool.NewConn() - if err != nil { - return nil, err - } - cn.LockReaderBuffer() - - if cn.InitedAt.IsZero() { - err := ln.db.initConn(cn) - if err != nil { - _ = ln.db.pool.CloseConn(cn) - return nil, err - } - cn.InitedAt = time.Now() - } - - if len(ln.channels) > 0 { - err := ln.listen(cn, ln.channels...) - if err != nil { - _ = ln.db.pool.CloseConn(cn) - return nil, err - } - } - - ln.cn = cn - return cn, nil -} - -func (ln *Listener) releaseConn(cn *pool.Conn, err error, allowTimeout bool) { - ln.mu.Lock() - if ln.cn == cn { - if isBadConn(err, allowTimeout) { - ln._reconnect(err) - } - } - ln.mu.Unlock() -} - -func (ln *Listener) _closeTheCn(reason error) error { - if ln.cn == nil { - return nil - } - if !ln.closed { - internal.Logf("pg: discarding bad listener connection: %s", reason) - } - - err := ln.db.pool.CloseConn(ln.cn) - ln.cn = nil - return err -} - -func (ln *Listener) _reconnect(reason error) { - _ = ln._closeTheCn(reason) - _, _ = ln._conn() -} - -// Close closes the listener, releasing any open resources. -func (ln *Listener) Close() error { - ln.mu.Lock() - defer ln.mu.Unlock() - - if ln.closed { - return errListenerClosed - } - ln.closed = true - close(ln.exit) - - return ln._closeTheCn(errListenerClosed) -} - -// Listen starts listening for notifications on channels. -func (ln *Listener) Listen(channels ...string) error { - cn, err := ln.conn() - if err != nil { - return err - } - - err = ln.listen(cn, channels...) - if err != nil { - ln.releaseConn(cn, err, false) - return err - } - - ln.channels = appendIfNotExists(ln.channels, channels...) - return nil -} - -func (ln *Listener) listen(cn *pool.Conn, channels ...string) error { - err := cn.WithWriter(ln.db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - for _, channel := range channels { - err := writeQueryMsg(wb, ln.db, "LISTEN ?", pgChan(channel)) - if err != nil { - return err - } - } - return nil - }) - return err -} - -// Receive indefinitely waits for a notification. This is low-level API -// and in most cases Channel should be used instead. -func (ln *Listener) Receive() (channel string, payload string, err error) { - return ln.ReceiveTimeout(0) -} - -// ReceiveTimeout waits for a notification until timeout is reached. -// This is low-level API and in most cases Channel should be used instead. -func (ln *Listener) ReceiveTimeout(timeout time.Duration) (channel, payload string, err error) { - cn, err := ln.conn() - if err != nil { - return "", "", err - } - - err = cn.WithReader(timeout, func(rd *pool.Reader) error { - channel, payload, err = readNotification(rd) - return err - }) - if err != nil { - ln.releaseConn(cn, err, timeout > 0) - return "", "", err - } - - return channel, payload, nil -} - -// Channel returns a channel for concurrently receiving notifications. -// It periodically sends Ping messages to test connection health. -// -// The channel is closed with Listener. Receive* APIs can not be used -// after channel is created. -func (ln *Listener) Channel() <-chan *Notification { - ln.chOnce.Do(ln.initChannel) - return ln.ch -} - -func (ln *Listener) initChannel() { - _ = ln.Listen(gopgChannel) - - ln.ch = make(chan *Notification, 100) - ln.pingCh = make(chan struct{}, 10) - - go func() { - var errCount int - for { - channel, payload, err := ln.Receive() - if err != nil { - if err == errListenerClosed { - close(ln.ch) - return - } - if errCount > 0 { - time.Sleep(ln.db.retryBackoff(errCount)) - } - errCount++ - continue - } - errCount = 0 - - // Any message is as good as a ping. - select { - case ln.pingCh <- struct{}{}: - default: - } - - switch channel { - case gopgChannel: - // ignore - default: - ln.ch <- &Notification{channel, payload} - } - } - }() - - go func() { - const timeout = 5 * time.Second - - timer := time.NewTimer(timeout) - timer.Stop() - - healthy := true - var pingErr error - for { - timer.Reset(timeout) - select { - case <-ln.pingCh: - healthy = true - if !timer.Stop() { - <-timer.C - } - case <-timer.C: - pingErr = ln.ping() - if healthy { - healthy = false - } else { - ln.mu.Lock() - ln._reconnect(pingErr) - ln.mu.Unlock() - } - case <-ln.exit: - return - } - } - }() -} - -func (ln *Listener) ping() error { - _, err := ln.db.Exec("NOTIFY ?", pgChan(gopgChannel)) - return err -} - -func appendIfNotExists(ss []string, es ...string) []string { -loop: - for _, e := range es { - for _, s := range ss { - if s == e { - continue loop - } - } - ss = append(ss, e) - } - return ss -} - -type pgChan string - -var _ types.ValueAppender = pgChan("") - -func (ch pgChan) AppendValue(b []byte, quote int) []byte { - if quote == 0 { - return append(b, ch...) - } - - b = append(b, '"') - for _, c := range []byte(ch) { - if c == '"' { - b = append(b, '"', '"') - } else { - b = append(b, c) - } - } - b = append(b, '"') - - return b -} diff --git a/vendor/github.com/go-pg/pg/messages.go b/vendor/github.com/go-pg/pg/messages.go deleted file mode 100644 index 9d71e97f6..000000000 --- a/vendor/github.com/go-pg/pg/messages.go +++ /dev/null @@ -1,1093 +0,0 @@ -package pg - -import ( - "crypto/md5" - "crypto/tls" - "encoding/hex" - "errors" - "fmt" - "io" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/internal/pool" - "github.com/go-pg/pg/orm" - "github.com/go-pg/pg/types" -) - -const ( - commandCompleteMsg = 'C' - errorResponseMsg = 'E' - noticeResponseMsg = 'N' - parameterStatusMsg = 'S' - authenticationOKMsg = 'R' - backendKeyDataMsg = 'K' - noDataMsg = 'n' - passwordMessageMsg = 'p' - terminateMsg = 'X' - - authenticationOK = 0 - authenticationCleartextPassword = 3 - authenticationMD5Password = 5 - authenticationSASL = 10 - - notificationResponseMsg = 'A' - - describeMsg = 'D' - parameterDescriptionMsg = 't' - - queryMsg = 'Q' - readyForQueryMsg = 'Z' - emptyQueryResponseMsg = 'I' - rowDescriptionMsg = 'T' - dataRowMsg = 'D' - - parseMsg = 'P' - parseCompleteMsg = '1' - - bindMsg = 'B' - bindCompleteMsg = '2' - - executeMsg = 'E' - - syncMsg = 'S' - flushMsg = 'H' - - closeMsg = 'C' - closeCompleteMsg = '3' - - copyInResponseMsg = 'G' - copyOutResponseMsg = 'H' - copyDataMsg = 'd' - copyDoneMsg = 'c' -) - -var errEmptyQuery = internal.Errorf("pg: query is empty") - -func (db *DB) startup(cn *pool.Conn, user, password, database, appName string) error { - err := cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - writeStartupMsg(wb, user, database, appName) - return nil - }) - if err != nil { - return err - } - - return cn.WithReader(db.opt.ReadTimeout, func(rd *pool.Reader) error { - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return err - } - - switch c { - case backendKeyDataMsg: - processId, err := rd.ReadInt32() - if err != nil { - return err - } - secretKey, err := rd.ReadInt32() - if err != nil { - return err - } - cn.ProcessId = processId - cn.SecretKey = secretKey - case parameterStatusMsg: - if err := logParameterStatus(rd, msgLen); err != nil { - return err - } - case authenticationOKMsg: - err := db.auth(cn, rd, user, password) - if err != nil { - return err - } - case readyForQueryMsg: - _, err := rd.ReadN(msgLen) - return err - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return err - } - return e - default: - return fmt.Errorf("pg: unknown startup message response: %q", c) - } - } - }) -} - -var errSSLNotSupported = errors.New("pg: SSL is not enabled on the server") - -func (db *DB) enableSSL(cn *pool.Conn, tlsConf *tls.Config) error { - err := cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - writeSSLMsg(wb) - return nil - }) - if err != nil { - return err - } - - err = cn.WithReader(db.opt.ReadTimeout, func(rd *pool.Reader) error { - c, err := rd.ReadByte() - if err != nil { - return err - } - if c != 'S' { - return errSSLNotSupported - } - return nil - }) - if err != nil { - return err - } - - cn.SetNetConn(tls.Client(cn.NetConn(), tlsConf)) - return nil -} - -func (db *DB) auth(cn *pool.Conn, rd *pool.Reader, user, password string) error { - num, err := rd.ReadInt32() - if err != nil { - return err - } - - switch num { - case authenticationOK: - return nil - case authenticationCleartextPassword: - return db.authCleartext(cn, rd, password) - case authenticationMD5Password: - return db.authMD5(cn, rd, user, password) - case authenticationSASL: - return db.authSASL(cn, rd, user, password) - default: - return fmt.Errorf("pg: unknown authentication message response: %d", num) - } -} - -func (db *DB) authCleartext(cn *pool.Conn, rd *pool.Reader, password string) error { - err := cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - writePasswordMsg(wb, password) - return nil - }) - if err != nil { - return err - } - - c, _, err := rd.ReadMessageType() - if err != nil { - return err - } - - switch c { - case authenticationOKMsg: - code, err := rd.ReadInt32() - if err != nil { - return err - } - if code != 0 { - return fmt.Errorf("pg: unexpected authentication code: %d", code) - } - return nil - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return err - } - return e - default: - return fmt.Errorf("pg: unknown password message response: %q", c) - } -} - -func (db *DB) authMD5(cn *pool.Conn, rd *pool.Reader, user, password string) error { - b, err := rd.ReadN(4) - if err != nil { - return err - } - - secret := "md5" + md5s(md5s(password+user)+string(b)) - err = cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - writePasswordMsg(wb, secret) - return nil - }) - if err != nil { - return err - } - - c, _, err := rd.ReadMessageType() - if err != nil { - return err - } - switch c { - case authenticationOKMsg: - code, err := rd.ReadInt32() - if err != nil { - return err - } - if code != 0 { - return fmt.Errorf("pg: unexpected authentication code: %d", code) - } - return nil - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return err - } - return e - default: - return fmt.Errorf("pg: unknown password message response: %q", c) - } -} - -func (db *DB) authSASL(cn *pool.Conn, rd *pool.Reader, user, password string) error { - return fmt.Errorf("pg: SASL authentication is not supported") -} - -func md5s(s string) string { - h := md5.New() - h.Write([]byte(s)) - return hex.EncodeToString(h.Sum(nil)) -} - -func writeStartupMsg(buf *pool.WriteBuffer, user, database, appName string) { - buf.StartMessage(0) - buf.WriteInt32(196608) - buf.WriteString("user") - buf.WriteString(user) - buf.WriteString("database") - buf.WriteString(database) - if appName != "" { - buf.WriteString("application_name") - buf.WriteString(appName) - } - buf.WriteString("") - buf.FinishMessage() -} - -func writeSSLMsg(buf *pool.WriteBuffer) { - buf.StartMessage(0) - buf.WriteInt32(80877103) - buf.FinishMessage() -} - -func writePasswordMsg(buf *pool.WriteBuffer, password string) { - buf.StartMessage(passwordMessageMsg) - buf.WriteString(password) - buf.FinishMessage() -} - -func writeFlushMsg(buf *pool.WriteBuffer) { - buf.StartMessage(flushMsg) - buf.FinishMessage() -} - -func writeCancelRequestMsg(buf *pool.WriteBuffer, processId, secretKey int32) { - buf.StartMessage(0) - buf.WriteInt32(80877102) - buf.WriteInt32(processId) - buf.WriteInt32(secretKey) - buf.FinishMessage() -} - -func writeQueryMsg(buf *pool.WriteBuffer, fmter orm.QueryFormatter, query interface{}, params ...interface{}) error { - buf.StartMessage(queryMsg) - bytes, err := appendQuery(buf.Bytes, fmter, query, params...) - if err != nil { - buf.Reset() - return err - } - buf.Bytes = bytes - buf.WriteByte(0x0) - buf.FinishMessage() - return nil -} - -func appendQuery(dst []byte, fmter orm.QueryFormatter, query interface{}, params ...interface{}) ([]byte, error) { - switch query := query.(type) { - case orm.QueryAppender: - return query.AppendQuery(dst) - case string: - return fmter.FormatQuery(dst, query, params...), nil - default: - return nil, fmt.Errorf("pg: can't append %T", query) - } -} - -func writeSyncMsg(buf *pool.WriteBuffer) { - buf.StartMessage(syncMsg) - buf.FinishMessage() -} - -func writeParseDescribeSyncMsg(buf *pool.WriteBuffer, name, q string) { - buf.StartMessage(parseMsg) - buf.WriteString(name) - buf.WriteString(q) - buf.WriteInt16(0) - buf.FinishMessage() - - buf.StartMessage(describeMsg) - buf.WriteByte('S') - buf.WriteString(name) - buf.FinishMessage() - - writeSyncMsg(buf) -} - -func readParseDescribeSync(rd *pool.Reader) ([][]byte, error) { - var columns [][]byte - var firstErr error - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return nil, err - } - switch c { - case parseCompleteMsg: - _, err = rd.ReadN(msgLen) - if err != nil { - return nil, err - } - case rowDescriptionMsg: // Response to the DESCRIBE message. - columns, err = readRowDescription(rd, nil) - if err != nil { - return nil, err - } - case parameterDescriptionMsg: // Response to the DESCRIBE message. - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - case noDataMsg: // Response to the DESCRIBE message. - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - case readyForQueryMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if firstErr != nil { - return nil, firstErr - } - return columns, err - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return nil, err - } - if firstErr == nil { - firstErr = e - } - case noticeResponseMsg: - if err := logNotice(rd, msgLen); err != nil { - return nil, err - } - case parameterStatusMsg: - if err := logParameterStatus(rd, msgLen); err != nil { - return nil, err - } - default: - return nil, fmt.Errorf("pg: readParseDescribeSync: unexpected message %#x", c) - } - } -} - -// Writes BIND, EXECUTE and SYNC messages. -func writeBindExecuteMsg(buf *pool.WriteBuffer, name string, params ...interface{}) error { - buf.StartMessage(bindMsg) - buf.WriteString("") - buf.WriteString(name) - buf.WriteInt16(0) - buf.WriteInt16(int16(len(params))) - for _, param := range params { - buf.StartParam() - bytes := types.Append(buf.Bytes, param, 0) - if bytes != nil { - buf.Bytes = bytes - buf.FinishParam() - } else { - buf.FinishNullParam() - } - } - buf.WriteInt16(0) - buf.FinishMessage() - - buf.StartMessage(executeMsg) - buf.WriteString("") - buf.WriteInt32(0) - buf.FinishMessage() - - writeSyncMsg(buf) - - return nil -} - -func writeCloseMsg(buf *pool.WriteBuffer, name string) { - buf.StartMessage(closeMsg) - buf.WriteByte('S') - buf.WriteString(name) - buf.FinishMessage() -} - -func readCloseCompleteMsg(rd *pool.Reader) error { - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return err - } - switch c { - case closeCompleteMsg: - _, err := rd.ReadN(msgLen) - return err - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return err - } - return e - case noticeResponseMsg: - if err := logNotice(rd, msgLen); err != nil { - return err - } - case parameterStatusMsg: - if err := logParameterStatus(rd, msgLen); err != nil { - return err - } - default: - return fmt.Errorf("pg: readCloseCompleteMsg: unexpected message %#x", c) - } - } -} - -func readSimpleQuery(rd *pool.Reader) (*result, error) { - var res result - var firstErr error - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return nil, err - } - - switch c { - case commandCompleteMsg: - b, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if err := res.parse(b); err != nil && firstErr == nil { - firstErr = err - } - case readyForQueryMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if firstErr != nil { - return nil, firstErr - } - return &res, nil - case rowDescriptionMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - case dataRowMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - res.returned++ - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return nil, err - } - if firstErr == nil { - firstErr = e - } - case emptyQueryResponseMsg: - if firstErr == nil { - firstErr = errEmptyQuery - } - case noticeResponseMsg: - if err := logNotice(rd, msgLen); err != nil { - return nil, err - } - case parameterStatusMsg: - if err := logParameterStatus(rd, msgLen); err != nil { - return nil, err - } - default: - return nil, fmt.Errorf("pg: readSimpleQuery: unexpected message %#x", c) - } - } -} - -func readExtQuery(rd *pool.Reader) (*result, error) { - var res result - var firstErr error - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return nil, err - } - - switch c { - case bindCompleteMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - case dataRowMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - res.returned++ - case commandCompleteMsg: // Response to the EXECUTE message. - b, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if err := res.parse(b); err != nil && firstErr == nil { - firstErr = err - } - case readyForQueryMsg: // Response to the SYNC message. - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if firstErr != nil { - return nil, firstErr - } - return &res, nil - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return nil, err - } - if firstErr == nil { - firstErr = e - } - case emptyQueryResponseMsg: - if firstErr == nil { - firstErr = errEmptyQuery - } - case noticeResponseMsg: - if err := logNotice(rd, msgLen); err != nil { - return nil, err - } - case parameterStatusMsg: - if err := logParameterStatus(rd, msgLen); err != nil { - return nil, err - } - default: - return nil, fmt.Errorf("pg: readExtQuery: unexpected message %#x", c) - } - } -} - -func readRowDescription(rd *pool.Reader, columns [][]byte) ([][]byte, error) { - colNum, err := rd.ReadInt16() - if err != nil { - return nil, err - } - - columns = setByteSliceLen(columns, int(colNum)) - for i := 0; i < int(colNum); i++ { - b, err := rd.ReadSlice(0) - if err != nil { - return nil, err - } - columns[i] = append(columns[i][:0], b[:len(b)-1]...) - - _, err = rd.ReadN(18) - if err != nil { - return nil, err - } - } - - return columns, nil -} - -func setByteSliceLen(b [][]byte, n int) [][]byte { - if n <= cap(b) { - return b[:n] - } - b = b[:cap(b)] - b = append(b, make([][]byte, n-cap(b))...) - return b -} - -func readDataRow(rd *pool.Reader, scanner orm.ColumnScanner, columns [][]byte) error { - colNum, err := rd.ReadInt16() - if err != nil { - return err - } - - var firstErr error - for colIdx := int16(0); colIdx < colNum; colIdx++ { - l, err := rd.ReadInt32() - if err != nil { - return err - } - - var b []byte - if l != -1 { // NULL - b, err = rd.ReadN(int(l)) - if err != nil { - return err - } - } - - column := internal.BytesToString(columns[colIdx]) - err = scanner.ScanColumn(int(colIdx), column, b) - if err != nil && firstErr == nil { - firstErr = internal.Errorf(err.Error()) - } - - } - - return firstErr -} - -func newModel(mod interface{}) (orm.Model, error) { - m, err := orm.NewModel(mod) - if err != nil { - return nil, err - } - return m, m.Init() -} - -func readSimpleQueryData(rd *pool.Reader, mod interface{}) (*result, error) { - var res result - var firstErr error - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return nil, err - } - - switch c { - case rowDescriptionMsg: - rd.Columns, err = readRowDescription(rd, rd.Columns[:0]) - if err != nil { - return nil, err - } - - if res.model == nil { - var err error - res.model, err = newModel(mod) - if err != nil { - if firstErr == nil { - firstErr = err - } - res.model = Discard - } - } - case dataRowMsg: - m := res.model.NewModel() - if err := readDataRow(rd, m, rd.Columns); err != nil { - if firstErr == nil { - firstErr = err - } - } else if err := res.model.AddModel(m); err != nil { - if firstErr == nil { - firstErr = err - } - } - - res.returned++ - case commandCompleteMsg: - b, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if err := res.parse(b); err != nil && firstErr == nil { - firstErr = err - } - case readyForQueryMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if firstErr != nil { - return nil, firstErr - } - return &res, nil - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return nil, err - } - if firstErr == nil { - firstErr = e - } - case emptyQueryResponseMsg: - if firstErr == nil { - firstErr = errEmptyQuery - } - case noticeResponseMsg: - if err := logNotice(rd, msgLen); err != nil { - return nil, err - } - case parameterStatusMsg: - if err := logParameterStatus(rd, msgLen); err != nil { - return nil, err - } - default: - return nil, fmt.Errorf("pg: readSimpleQueryData: unexpected message %#x", c) - } - } -} - -func readExtQueryData(rd *pool.Reader, mod interface{}, columns [][]byte) (*result, error) { - var res result - var firstErr error - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return nil, err - } - - switch c { - case bindCompleteMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - case dataRowMsg: - if res.model == nil { - var err error - res.model, err = newModel(mod) - if err != nil { - if firstErr == nil { - firstErr = err - } - res.model = Discard - } - } - - m := res.model.NewModel() - if err := readDataRow(rd, m, columns); err != nil { - if firstErr == nil { - firstErr = err - } - } else if err := res.model.AddModel(m); err != nil { - if firstErr == nil { - firstErr = err - } - } - - res.returned++ - case commandCompleteMsg: // Response to the EXECUTE message. - b, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if err := res.parse(b); err != nil && firstErr == nil { - firstErr = err - } - case readyForQueryMsg: // Response to the SYNC message. - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if firstErr != nil { - return nil, firstErr - } - return &res, nil - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return nil, err - } - if firstErr == nil { - firstErr = e - } - case noticeResponseMsg: - if err := logNotice(rd, msgLen); err != nil { - return nil, err - } - case parameterStatusMsg: - if err := logParameterStatus(rd, msgLen); err != nil { - return nil, err - } - default: - return nil, fmt.Errorf("pg: readExtQueryData: unexpected message %#x", c) - } - } -} - -func readCopyInResponse(rd *pool.Reader) error { - var firstErr error - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return err - } - - switch c { - case copyInResponseMsg: - _, err := rd.ReadN(msgLen) - return err - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return err - } - if firstErr == nil { - firstErr = e - } - case readyForQueryMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return err - } - return firstErr - case noticeResponseMsg: - if err := logNotice(rd, msgLen); err != nil { - return err - } - case parameterStatusMsg: - if err := logParameterStatus(rd, msgLen); err != nil { - return err - } - default: - return fmt.Errorf("pg: readCopyInResponse: unexpected message %#x", c) - } - } -} - -func readCopyOutResponse(rd *pool.Reader) error { - var firstErr error - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return err - } - - switch c { - case copyOutResponseMsg: - _, err := rd.ReadN(msgLen) - return err - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return err - } - if firstErr == nil { - firstErr = e - } - case readyForQueryMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return err - } - return firstErr - case noticeResponseMsg: - if err := logNotice(rd, msgLen); err != nil { - return err - } - case parameterStatusMsg: - if err := logParameterStatus(rd, msgLen); err != nil { - return err - } - default: - return fmt.Errorf("pg: readCopyOutResponse: unexpected message %#x", c) - } - } -} - -func readCopyData(rd *pool.Reader, w io.Writer) (*result, error) { - var res result - var firstErr error - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return nil, err - } - - switch c { - case copyDataMsg: - b, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - - _, err = w.Write(b) - if err != nil { - return nil, err - } - case copyDoneMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - case commandCompleteMsg: - b, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if err := res.parse(b); err != nil && firstErr == nil { - firstErr = err - } - case readyForQueryMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if firstErr != nil { - return nil, firstErr - } - return &res, nil - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return nil, err - } - return nil, e - case noticeResponseMsg: - if err := logNotice(rd, msgLen); err != nil { - return nil, err - } - case parameterStatusMsg: - if err := logParameterStatus(rd, msgLen); err != nil { - return nil, err - } - default: - return nil, fmt.Errorf("pg: readCopyData: unexpected message %#x", c) - } - } -} - -func writeCopyData(buf *pool.WriteBuffer, r io.Reader) error { - buf.StartMessage(copyDataMsg) - _, err := buf.ReadFrom(r) - buf.FinishMessage() - return err -} - -func writeCopyDone(buf *pool.WriteBuffer) { - buf.StartMessage(copyDoneMsg) - buf.FinishMessage() -} - -func readReadyForQuery(rd *pool.Reader) (*result, error) { - var res result - var firstErr error - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return nil, err - } - - switch c { - case commandCompleteMsg: - b, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if err := res.parse(b); err != nil && firstErr == nil { - firstErr = err - } - case readyForQueryMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return nil, err - } - if firstErr != nil { - return nil, firstErr - } - return &res, nil - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return nil, err - } - if firstErr == nil { - firstErr = e - } - case noticeResponseMsg: - if err := logNotice(rd, msgLen); err != nil { - return nil, err - } - case parameterStatusMsg: - if err := logParameterStatus(rd, msgLen); err != nil { - return nil, err - } - default: - return nil, fmt.Errorf("pg: readReadyForQueryOrError: unexpected message %#x", c) - } - } -} - -func readNotification(rd *pool.Reader) (channel, payload string, err error) { - for { - c, msgLen, err := rd.ReadMessageType() - if err != nil { - return "", "", err - } - - switch c { - case commandCompleteMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return "", "", err - } - case readyForQueryMsg: - _, err := rd.ReadN(msgLen) - if err != nil { - return "", "", err - } - case errorResponseMsg: - e, err := rd.ReadError() - if err != nil { - return "", "", err - } - return "", "", e - case noticeResponseMsg: - if err := logNotice(rd, msgLen); err != nil { - return "", "", err - } - case notificationResponseMsg: - _, err := rd.ReadInt32() - if err != nil { - return "", "", err - } - channel, err = rd.ReadString() - if err != nil { - return "", "", err - } - payload, err = rd.ReadString() - if err != nil { - return "", "", err - } - return channel, payload, nil - default: - return "", "", fmt.Errorf("pg: unexpected message %q", c) - } - } -} - -var terminateMessage = []byte{terminateMsg, 0, 0, 0, 4} - -func terminateConn(cn *pool.Conn) error { - // Don't use cn.Buf because it is racy with user code. - _, err := cn.NetConn().Write(terminateMessage) - return err -} - -//------------------------------------------------------------------------------ - -func logNotice(rd *pool.Reader, msgLen int) error { - _, err := rd.ReadN(msgLen) - return err -} - -func logParameterStatus(rd *pool.Reader, msgLen int) error { - _, err := rd.ReadN(msgLen) - return err -} diff --git a/vendor/github.com/go-pg/pg/options.go b/vendor/github.com/go-pg/pg/options.go deleted file mode 100644 index 11e249737..000000000 --- a/vendor/github.com/go-pg/pg/options.go +++ /dev/null @@ -1,242 +0,0 @@ -package pg - -import ( - "crypto/tls" - "errors" - "fmt" - "net" - "net/url" - "runtime" - "strings" - "time" - - "github.com/go-pg/pg/internal/pool" -) - -// Database connection options. -type Options struct { - // Network type, either tcp or unix. - // Default is tcp. - Network string - // TCP host:port or Unix socket depending on Network. - Addr string - - // Dialer creates new network connection and has priority over - // Network and Addr options. - Dialer func(network, addr string) (net.Conn, error) - - // Hook that is called when new connection is established. - OnConnect func(*DB) error - - User string - Password string - Database string - - // ApplicationName is the application name. Used in logs on Pg side. - // Only availaible from pg-9.0. - ApplicationName string - - // TLS config for secure connections. - TLSConfig *tls.Config - - // Maximum number of retries before giving up. - // Default is to not retry failed queries. - MaxRetries int - // Whether to retry queries cancelled because of statement_timeout. - RetryStatementTimeout bool - // Minimum backoff between each retry. - // Default is 250 milliseconds; -1 disables backoff. - MinRetryBackoff time.Duration - // Maximum backoff between each retry. - // Default is 4 seconds; -1 disables backoff. - MaxRetryBackoff time.Duration - - // Dial timeout for establishing new connections. - // Default is 5 seconds. - DialTimeout time.Duration - - // Timeout for socket reads. If reached, commands will fail - // with a timeout instead of blocking. - ReadTimeout time.Duration - // Timeout for socket writes. If reached, commands will fail - // with a timeout instead of blocking. - WriteTimeout time.Duration - - // Maximum number of socket connections. - // Default is 10 connections per every CPU as reported by runtime.NumCPU. - PoolSize int - // Minimum number of idle connections which is useful when establishing - // new connection is slow. - MinIdleConns int - // Connection age at which client retires (closes) the connection. - // It is useful with proxies like PgBouncer and HAProxy. - // Default is to not close aged connections. - MaxConnAge time.Duration - // Time for which client waits for free connection if all - // connections are busy before returning an error. - // Default is 30 seconds if ReadTimeOut is not defined, otherwise, - // ReadTimeout + 1 second. - PoolTimeout time.Duration - // Amount of time after which client closes idle connections. - // Should be less than server's timeout. - // Default is 5 minutes. -1 disables idle timeout check. - IdleTimeout time.Duration - // Frequency of idle checks made by idle connections reaper. - // Default is 1 minute. -1 disables idle connections reaper, - // but idle connections are still discarded by the client - // if IdleTimeout is set. - IdleCheckFrequency time.Duration -} - -func (opt *Options) init() { - if opt.Network == "" { - opt.Network = "tcp" - } - - if opt.Addr == "" { - switch opt.Network { - case "tcp": - opt.Addr = "localhost:5432" - case "unix": - opt.Addr = "/var/run/postgresql/.s.PGSQL.5432" - } - } - - if opt.PoolSize == 0 { - opt.PoolSize = 10 * runtime.NumCPU() - } - - if opt.PoolTimeout == 0 { - if opt.ReadTimeout != 0 { - opt.PoolTimeout = opt.ReadTimeout + time.Second - } else { - opt.PoolTimeout = 30 * time.Second - } - } - - if opt.DialTimeout == 0 { - opt.DialTimeout = 5 * time.Second - } - - if opt.IdleTimeout == 0 { - opt.IdleTimeout = 5 * time.Minute - } - if opt.IdleCheckFrequency == 0 { - opt.IdleCheckFrequency = time.Minute - } - - switch opt.MinRetryBackoff { - case -1: - opt.MinRetryBackoff = 0 - case 0: - opt.MinRetryBackoff = 250 * time.Millisecond - } - switch opt.MaxRetryBackoff { - case -1: - opt.MaxRetryBackoff = 0 - case 0: - opt.MaxRetryBackoff = 4 * time.Second - } -} - -// ParseURL parses an URL into options that can be used to connect to PostgreSQL. -func ParseURL(sURL string) (*Options, error) { - parsedUrl, err := url.Parse(sURL) - if err != nil { - return nil, err - } - - // scheme - if parsedUrl.Scheme != "postgres" && parsedUrl.Scheme != "postgresql" { - return nil, errors.New("pg: invalid scheme: " + parsedUrl.Scheme) - } - - // host and port - options := &Options{ - Addr: parsedUrl.Host, - } - if !strings.Contains(options.Addr, ":") { - options.Addr = options.Addr + ":5432" - } - - // username and password - if parsedUrl.User != nil { - options.User = parsedUrl.User.Username() - - if password, ok := parsedUrl.User.Password(); ok { - options.Password = password - } - } - - if options.User == "" { - options.User = "postgres" - } - - // database - if len(strings.Trim(parsedUrl.Path, "/")) > 0 { - options.Database = parsedUrl.Path[1:] - } else { - return nil, errors.New("pg: database name not provided") - } - - // ssl mode - query, err := url.ParseQuery(parsedUrl.RawQuery) - if err != nil { - return nil, err - } - - if sslMode, ok := query["sslmode"]; ok && len(sslMode) > 0 { - switch sslMode[0] { - case "allow", "prefer", "require": - options.TLSConfig = &tls.Config{InsecureSkipVerify: true} - case "disable": - options.TLSConfig = nil - default: - return nil, errors.New(fmt.Sprintf("pg: sslmode '%v' is not supported", sslMode[0])) - } - } else { - options.TLSConfig = &tls.Config{InsecureSkipVerify: true} - } - - delete(query, "sslmode") - - if appName, ok := query["application_name"]; ok && len(appName) > 0 { - options.ApplicationName = appName[0] - } - - delete(query, "application_name") - - if len(query) > 0 { - return nil, errors.New("pg: options other than 'sslmode' and 'application_name' are not supported") - } - - return options, nil -} - -func (opt *Options) getDialer() func() (net.Conn, error) { - if opt.Dialer != nil { - return func() (net.Conn, error) { - return opt.Dialer(opt.Network, opt.Addr) - } - } - return func() (net.Conn, error) { - netDialer := &net.Dialer{ - Timeout: opt.DialTimeout, - KeepAlive: 5 * time.Minute, - } - return netDialer.Dial(opt.Network, opt.Addr) - } -} - -func newConnPool(opt *Options) *pool.ConnPool { - return pool.NewConnPool(&pool.Options{ - Dialer: opt.getDialer(), - PoolSize: opt.PoolSize, - PoolTimeout: opt.PoolTimeout, - IdleTimeout: opt.IdleTimeout, - IdleCheckFrequency: opt.IdleCheckFrequency, - OnClose: func(cn *pool.Conn) error { - return terminateConn(cn) - }, - }) -} diff --git a/vendor/github.com/go-pg/pg/orm/composite.go b/vendor/github.com/go-pg/pg/orm/composite.go deleted file mode 100644 index 45a11ff17..000000000 --- a/vendor/github.com/go-pg/pg/orm/composite.go +++ /dev/null @@ -1,56 +0,0 @@ -package orm - -import ( - "fmt" - "reflect" - - "github.com/go-pg/pg/internal/parser" - "github.com/go-pg/pg/types" -) - -func compositeScanner(typ reflect.Type) types.ScannerFunc { - return func(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - - if b == nil { - if !v.IsNil() { - v.Set(reflect.Zero(v.Type())) - } - return nil - } - - table := GetTable(typ) - p := parser.NewCompositeParser(b) - for i := 0; p.Valid(); i++ { - elem, err := p.NextElem() - if err != nil { - return err - } - - field := table.Fields[i] - err = field.ScanValue(v, elem) - if err != nil { - return err - } - } - - return nil - } -} - -func compositeAppender(typ reflect.Type) types.AppenderFunc { - return func(b []byte, v reflect.Value, quote int) []byte { - table := GetTable(typ) - b = append(b, '(') - for i, f := range table.Fields { - if i > 0 { - b = append(b, ',') - } - b = f.AppendValue(b, v, quote) - } - b = append(b, ')') - return b - } -} diff --git a/vendor/github.com/go-pg/pg/orm/composite_create.go b/vendor/github.com/go-pg/pg/orm/composite_create.go deleted file mode 100644 index 2714efa0f..000000000 --- a/vendor/github.com/go-pg/pg/orm/composite_create.go +++ /dev/null @@ -1,68 +0,0 @@ -package orm - -import ( - "errors" - "strconv" -) - -type CreateCompositeOptions struct { - Varchar int // replaces PostgreSQL data type `text` with `varchar(n)` -} - -func CreateComposite(db DB, model interface{}, opt *CreateCompositeOptions) error { - q := NewQuery(db, model) - _, err := q.db.Exec(createCompositeQuery{ - q: q, - opt: opt, - }) - return err -} - -type createCompositeQuery struct { - q *Query - opt *CreateCompositeOptions -} - -func (q createCompositeQuery) Copy() QueryAppender { - return q -} - -func (q createCompositeQuery) Query() *Query { - return q.q -} - -func (q createCompositeQuery) AppendQuery(b []byte) ([]byte, error) { - if q.q.stickyErr != nil { - return nil, q.q.stickyErr - } - if q.q.model == nil { - return nil, errors.New("pg: Model(nil)") - } - - table := q.q.model.Table() - - b = append(b, "CREATE TYPE "...) - b = append(b, q.q.model.Table().Alias...) - b = append(b, " AS ("...) - - for i, field := range table.Fields { - if i > 0 { - b = append(b, ", "...) - } - - b = append(b, field.Column...) - b = append(b, " "...) - if q.opt != nil && q.opt.Varchar > 0 && - field.SQLType == "text" && !field.HasFlag(customTypeFlag) { - b = append(b, "varchar("...) - b = strconv.AppendInt(b, int64(q.opt.Varchar), 10) - b = append(b, ")"...) - } else { - b = append(b, field.SQLType...) - } - } - - b = append(b, ")"...) - - return b, nil -} diff --git a/vendor/github.com/go-pg/pg/orm/composite_drop.go b/vendor/github.com/go-pg/pg/orm/composite_drop.go deleted file mode 100644 index f2198030a..000000000 --- a/vendor/github.com/go-pg/pg/orm/composite_drop.go +++ /dev/null @@ -1,50 +0,0 @@ -package orm - -import "errors" - -type DropCompositeOptions struct { - IfExists bool - Cascade bool -} - -func DropComposite(db DB, model interface{}, opt *DropCompositeOptions) error { - q := NewQuery(db, model) - _, err := q.db.Exec(dropCompositeQuery{ - q: q, - opt: opt, - }) - return err -} - -type dropCompositeQuery struct { - q *Query - opt *DropCompositeOptions -} - -func (q dropCompositeQuery) Copy() QueryAppender { - return q -} - -func (q dropCompositeQuery) Query() *Query { - return q.q -} - -func (q dropCompositeQuery) AppendQuery(b []byte) ([]byte, error) { - if q.q.stickyErr != nil { - return nil, q.q.stickyErr - } - if q.q.model == nil { - return nil, errors.New("pg: Model(nil)") - } - - b = append(b, "DROP TYPE "...) - if q.opt != nil && q.opt.IfExists { - b = append(b, "IF EXISTS "...) - } - b = append(b, q.q.model.Table().Alias...) - if q.opt != nil && q.opt.Cascade { - b = append(b, " CASCADE"...) - } - - return b, nil -} diff --git a/vendor/github.com/go-pg/pg/orm/count_estimate.go b/vendor/github.com/go-pg/pg/orm/count_estimate.go deleted file mode 100644 index c8fde32e2..000000000 --- a/vendor/github.com/go-pg/pg/orm/count_estimate.go +++ /dev/null @@ -1,85 +0,0 @@ -package orm - -import ( - "fmt" - - "github.com/go-pg/pg/internal" -) - -// Placeholder that is replaced with count(*). -const placeholder = `'_go_pg_placeholder'` - -// https://wiki.postgresql.org/wiki/Count_estimate -var pgCountEstimateFunc = fmt.Sprintf(` -CREATE OR REPLACE FUNCTION _go_pg_count_estimate_v2(query text, threshold int) -RETURNS int AS $$ -DECLARE - rec record; - nrows int; -BEGIN - FOR rec IN EXECUTE 'EXPLAIN ' || query LOOP - nrows := substring(rec."QUERY PLAN" FROM ' rows=(\d+)'); - EXIT WHEN nrows IS NOT NULL; - END LOOP; - - -- Return the estimation if there are too many rows. - IF nrows > threshold THEN - RETURN nrows; - END IF; - - -- Otherwise execute real count query. - query := replace(query, 'SELECT '%s'', 'SELECT count(*)'); - EXECUTE query INTO nrows; - - IF nrows IS NULL THEN - nrows := 0; - END IF; - - RETURN nrows; -END; -$$ LANGUAGE plpgsql; -`, placeholder) - -// CountEstimate uses EXPLAIN to get estimated number of rows returned the query. -// If that number is bigger than the threshold it returns the estimation. -// Otherwise it executes another query using count aggregate function and -// returns the result. -// -// Based on https://wiki.postgresql.org/wiki/Count_estimate -func (q *Query) CountEstimate(threshold int) (int, error) { - if q.stickyErr != nil { - return 0, q.stickyErr - } - - query, err := q.countSelectQuery(placeholder).AppendQuery(nil) - if err != nil { - return 0, err - } - - for i := 0; i < 3; i++ { - var count int - _, err = q.db.QueryOne( - Scan(&count), - "SELECT _go_pg_count_estimate_v2(?, ?)", - string(query), threshold, - ) - if err != nil { - if pgerr, ok := err.(internal.PGError); ok && pgerr.Field('C') == "42883" { - // undefined_function - err = q.createCountEstimateFunc() - if err != nil { - return 0, err - } - continue - } - } - return count, err - } - - return 0, err -} - -func (q *Query) createCountEstimateFunc() error { - _, err := q.db.Exec(pgCountEstimateFunc) - return err -} diff --git a/vendor/github.com/go-pg/pg/orm/delete.go b/vendor/github.com/go-pg/pg/orm/delete.go deleted file mode 100644 index 5bd188899..000000000 --- a/vendor/github.com/go-pg/pg/orm/delete.go +++ /dev/null @@ -1,83 +0,0 @@ -package orm - -import ( - "github.com/go-pg/pg/internal" -) - -func Delete(db DB, model interface{}) error { - res, err := NewQuery(db, model).WherePK().Delete() - if err != nil { - return err - } - return internal.AssertOneRow(res.RowsAffected()) -} - -func ForceDelete(db DB, model interface{}) error { - res, err := NewQuery(db, model).WherePK().ForceDelete() - if err != nil { - return err - } - return internal.AssertOneRow(res.RowsAffected()) -} - -type deleteQuery struct { - q *Query -} - -var _ QueryAppender = (*deleteQuery)(nil) - -func (q deleteQuery) Copy() QueryAppender { - return deleteQuery{ - q: q.q.Copy(), - } -} - -func (q deleteQuery) Query() *Query { - return q.q -} - -func (q deleteQuery) AppendQuery(b []byte) ([]byte, error) { - if q.q.stickyErr != nil { - return nil, q.q.stickyErr - } - - var err error - - if len(q.q.with) > 0 { - b, err = q.q.appendWith(b) - if err != nil { - return nil, err - } - } - - b = append(b, "DELETE FROM "...) - b = q.q.appendFirstTableWithAlias(b) - - if q.q.hasMultiTables() { - b = append(b, " USING "...) - b = q.q.appendOtherTables(b) - } - - b = append(b, " WHERE "...) - value := q.q.model.Value() - if q.q.isSliceModel() { - table := q.q.model.Table() - b = appendColumnAndSliceValue(b, value, table.Alias, table.PKs) - - if q.q.hasWhere() { - b = append(b, " AND "...) - b = q.q.appendWhere(b) - } - } else { - b, err = q.q.mustAppendWhere(b) - if err != nil { - return nil, err - } - } - - if len(q.q.returning) > 0 { - b = q.q.appendReturning(b) - } - - return b, nil -} diff --git a/vendor/github.com/go-pg/pg/orm/field.go b/vendor/github.com/go-pg/pg/orm/field.go deleted file mode 100644 index fc954bbf6..000000000 --- a/vendor/github.com/go-pg/pg/orm/field.go +++ /dev/null @@ -1,108 +0,0 @@ -package orm - -import ( - "reflect" - - "github.com/go-pg/pg/types" -) - -const ( - PrimaryKeyFlag = uint8(1) << iota - ForeignKeyFlag - NotNullFlag - UniqueFlag - ArrayFlag - customTypeFlag -) - -type Field struct { - Field reflect.StructField - Type reflect.Type - - GoName string // struct field name, e.g. Id - SQLName string // SQL name, .e.g. id - Column types.Q // escaped SQL name, e.g. "id" - SQLType string - Index []int - Default types.Q - OnDelete string - - flags uint8 - - append types.AppenderFunc - scan types.ScannerFunc - - isZero func(reflect.Value) bool -} - -func indexEqual(ind1, ind2 []int) bool { - if len(ind1) != len(ind2) { - return false - } - for i, ind := range ind1 { - if ind != ind2[i] { - return false - } - } - return true -} - -func (f *Field) Copy() *Field { - cp := *f - cp.Index = cp.Index[:len(f.Index):len(f.Index)] - return &cp -} - -func (f *Field) SetFlag(flag uint8) { - f.flags |= flag -} - -func (f *Field) HasFlag(flag uint8) bool { - return f.flags&flag != 0 -} - -func (f *Field) Value(strct reflect.Value) reflect.Value { - return strct.FieldByIndex(f.Index) -} - -func (f *Field) IsZero(strct reflect.Value) bool { - return f.isZero(f.Value(strct)) -} - -func (f *Field) OmitZero() bool { - return !f.HasFlag(NotNullFlag) -} - -func (f *Field) AppendValue(b []byte, strct reflect.Value, quote int) []byte { - fv := f.Value(strct) - if !f.HasFlag(NotNullFlag) && f.isZero(fv) { - return types.AppendNull(b, quote) - } - return f.append(b, fv, quote) -} - -func (f *Field) ScanValue(strct reflect.Value, b []byte) error { - fv := fieldByIndex(strct, f.Index) - return f.scan(fv, b) -} - -type Method struct { - Index int - - flags int8 - - appender func([]byte, reflect.Value, int) []byte -} - -func (m *Method) Has(flag int8) bool { - return m.flags&flag != 0 -} - -func (m *Method) Value(strct reflect.Value) reflect.Value { - return strct.Method(m.Index).Call(nil)[0] -} - -func (m *Method) AppendValue(dst []byte, strct reflect.Value, quote int) []byte { - mv := m.Value(strct) - return m.appender(dst, mv, quote) -} diff --git a/vendor/github.com/go-pg/pg/orm/format.go b/vendor/github.com/go-pg/pg/orm/format.go deleted file mode 100644 index 9c5f9788e..000000000 --- a/vendor/github.com/go-pg/pg/orm/format.go +++ /dev/null @@ -1,286 +0,0 @@ -package orm - -import ( - "bytes" - "fmt" - "sort" - "strconv" - "strings" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/internal/parser" - "github.com/go-pg/pg/types" -) - -var formatter Formatter - -type FormatAppender interface { - AppendFormat([]byte, QueryFormatter) []byte -} - -type sepFormatAppender interface { - FormatAppender - AppendSep([]byte) []byte -} - -//------------------------------------------------------------------------------ - -type queryParamsAppender struct { - query string - params []interface{} -} - -var _ FormatAppender = (*queryParamsAppender)(nil) -var _ types.ValueAppender = (*queryParamsAppender)(nil) - -func Q(query string, params ...interface{}) *queryParamsAppender { - return &queryParamsAppender{query, params} -} - -func (q *queryParamsAppender) AppendFormat(b []byte, f QueryFormatter) []byte { - return f.FormatQuery(b, q.query, q.params...) -} - -func (q *queryParamsAppender) AppendValue(b []byte, quote int) []byte { - return q.AppendFormat(b, formatter) -} - -func (q *queryParamsAppender) Value() types.Q { - b := q.AppendValue(nil, 1) - return types.Q(internal.BytesToString(b)) -} - -//------------------------------------------------------------------------------ - -type condGroupAppender struct { - sep string - cond []sepFormatAppender -} - -var _ FormatAppender = (*condAppender)(nil) -var _ sepFormatAppender = (*condAppender)(nil) - -func (q *condGroupAppender) AppendSep(b []byte) []byte { - return append(b, q.sep...) -} - -func (q *condGroupAppender) AppendFormat(b []byte, f QueryFormatter) []byte { - b = append(b, '(') - for i, app := range q.cond { - if i > 0 { - b = app.AppendSep(b) - } - b = app.AppendFormat(b, f) - } - b = append(b, ')') - return b -} - -//------------------------------------------------------------------------------ - -type condAppender struct { - sep string - cond string - params []interface{} -} - -var _ FormatAppender = (*condAppender)(nil) -var _ sepFormatAppender = (*condAppender)(nil) - -func (q *condAppender) AppendSep(b []byte) []byte { - return append(b, q.sep...) -} - -func (q *condAppender) AppendFormat(b []byte, f QueryFormatter) []byte { - b = append(b, '(') - b = f.FormatQuery(b, q.cond, q.params...) - b = append(b, ')') - return b -} - -//------------------------------------------------------------------------------ - -type fieldAppender struct { - field string -} - -var _ FormatAppender = (*fieldAppender)(nil) - -func (a fieldAppender) AppendFormat(b []byte, f QueryFormatter) []byte { - return types.AppendField(b, a.field, 1) -} - -//------------------------------------------------------------------------------ - -type Formatter struct { - namedParams map[string]interface{} -} - -func (f Formatter) String() string { - if len(f.namedParams) == 0 { - return "" - } - - var keys []string - for k, _ := range f.namedParams { - keys = append(keys, k) - } - sort.Strings(keys) - - var ss []string - for _, k := range keys { - ss = append(ss, fmt.Sprintf("%s=%v", k, f.namedParams[k])) - } - return " " + strings.Join(ss, " ") -} - -func (f Formatter) copy() Formatter { - var cp Formatter - for param, value := range f.namedParams { - cp.SetParam(param, value) - } - return cp -} - -func (f *Formatter) SetParam(param string, value interface{}) { - if f.namedParams == nil { - f.namedParams = make(map[string]interface{}) - } - f.namedParams[param] = value -} - -func (f *Formatter) WithParam(param string, value interface{}) Formatter { - cp := f.copy() - cp.SetParam(param, value) - return cp -} - -func (f Formatter) Param(param string) interface{} { - return f.namedParams[param] -} - -func (f Formatter) Append(dst []byte, src string, params ...interface{}) []byte { - if (params == nil && f.namedParams == nil) || strings.IndexByte(src, '?') == -1 { - return append(dst, src...) - } - return f.append(dst, parser.NewString(src), params) -} - -func (f Formatter) AppendBytes(dst, src []byte, params ...interface{}) []byte { - if (params == nil && f.namedParams == nil) || bytes.IndexByte(src, '?') == -1 { - return append(dst, src...) - } - return f.append(dst, parser.New(src), params) -} - -func (f Formatter) FormatQuery(dst []byte, query string, params ...interface{}) []byte { - return f.Append(dst, query, params...) -} - -func (f Formatter) append(dst []byte, p *parser.Parser, params []interface{}) []byte { - var paramsIndex int - var namedParamsOnce bool - var tableParams *tableParams - var model tableModel - - if len(params) > 0 { - var ok bool - model, ok = params[len(params)-1].(tableModel) - if ok { - params = params[:len(params)-1] - } - } - - for p.Valid() { - b, ok := p.ReadSep('?') - if !ok { - dst = append(dst, b...) - continue - } - if len(b) > 0 && b[len(b)-1] == '\\' { - dst = append(dst, b[:len(b)-1]...) - dst = append(dst, '?') - continue - } - dst = append(dst, b...) - - if id, numeric := p.ReadIdentifier(); id != "" { - if numeric { - idx, err := strconv.Atoi(id) - if err != nil { - goto restore_param - } - - if idx >= len(params) { - goto restore_param - } - - dst = f.appendParam(dst, params[idx]) - continue - } - - if f.namedParams != nil { - param, paramOK := f.namedParams[id] - if paramOK { - dst = f.appendParam(dst, param) - continue - } - } - - if !namedParamsOnce && len(params) > 0 { - namedParamsOnce = true - tableParams, _ = newTableParams(params[len(params)-1]) - } - - if tableParams != nil { - dst, ok = tableParams.AppendParam(dst, f, id) - if ok { - continue - } - } - - if model != nil { - dst, ok = model.AppendParam(dst, f, id) - if ok { - continue - } - } - - restore_param: - dst = append(dst, '?') - dst = append(dst, id...) - continue - } - - if paramsIndex >= len(params) { - dst = append(dst, '?') - continue - } - - param := params[paramsIndex] - paramsIndex++ - - dst = f.appendParam(dst, param) - } - - return dst -} - -type queryAppender interface { - AppendQuery(dst []byte) ([]byte, error) -} - -func (f Formatter) appendParam(b []byte, param interface{}) []byte { - switch param := param.(type) { - case queryAppender: - bb, err := param.AppendQuery(b) - if err != nil { - return types.AppendError(b, err) - } - return bb - case FormatAppender: - return param.AppendFormat(b, f) - default: - return types.Append(b, param, 1) - } -} diff --git a/vendor/github.com/go-pg/pg/orm/hook.go b/vendor/github.com/go-pg/pg/orm/hook.go deleted file mode 100644 index 45e589cea..000000000 --- a/vendor/github.com/go-pg/pg/orm/hook.go +++ /dev/null @@ -1,199 +0,0 @@ -package orm - -import ( - "reflect" -) - -type hookStubs struct{} - -func (hookStubs) AfterQuery(_ DB) error { - return nil -} - -func (hookStubs) BeforeSelectQuery(db DB, q *Query) (*Query, error) { - return q, nil -} - -func (hookStubs) AfterSelect(_ DB) error { - return nil -} - -func (hookStubs) BeforeInsert(_ DB) error { - return nil -} - -func (hookStubs) AfterInsert(_ DB) error { - return nil -} - -func (hookStubs) BeforeUpdate(_ DB) error { - return nil -} - -func (hookStubs) AfterUpdate(_ DB) error { - return nil -} - -func (hookStubs) BeforeDelete(_ DB) error { - return nil -} - -func (hookStubs) AfterDelete(_ DB) error { - return nil -} - -func callHookSlice(slice reflect.Value, ptr bool, db DB, hook func(reflect.Value, DB) error) error { - var firstErr error - for i := 0; i < slice.Len(); i++ { - var err error - if ptr { - err = hook(slice.Index(i), db) - } else { - err = hook(slice.Index(i).Addr(), db) - } - if err != nil && firstErr == nil { - firstErr = err - } - } - return firstErr -} - -//------------------------------------------------------------------------------ - -type afterQueryHook interface { - AfterQuery(db DB) error -} - -var afterQueryHookType = reflect.TypeOf((*afterQueryHook)(nil)).Elem() - -func callAfterQueryHook(v reflect.Value, db DB) error { - return v.Interface().(afterQueryHook).AfterQuery(db) -} - -func callAfterQueryHookSlice(slice reflect.Value, ptr bool, db DB) error { - return callHookSlice(slice, ptr, db, callAfterQueryHook) -} - -//------------------------------------------------------------------------------ - -type beforeSelectQueryHook interface { - BeforeSelectQuery(db DB, q *Query) (*Query, error) -} - -var beforeSelectQueryHookType = reflect.TypeOf((*beforeSelectQueryHook)(nil)).Elem() - -func callBeforeSelectQueryHook(v reflect.Value, db DB, q *Query) (*Query, error) { - return v.Interface().(beforeSelectQueryHook).BeforeSelectQuery(db, q) -} - -//------------------------------------------------------------------------------ - -type afterSelectHook interface { - AfterSelect(db DB) error -} - -var afterSelectHookType = reflect.TypeOf((*afterSelectHook)(nil)).Elem() - -func callAfterSelectHook(v reflect.Value, db DB) error { - return v.Interface().(afterSelectHook).AfterSelect(db) -} - -func callAfterSelectHookSlice(slice reflect.Value, ptr bool, db DB) error { - return callHookSlice(slice, ptr, db, callAfterSelectHook) -} - -//------------------------------------------------------------------------------ - -type beforeInsertHook interface { - BeforeInsert(db DB) error -} - -var beforeInsertHookType = reflect.TypeOf((*beforeInsertHook)(nil)).Elem() - -func callBeforeInsertHook(v reflect.Value, db DB) error { - return v.Interface().(beforeInsertHook).BeforeInsert(db) -} - -func callBeforeInsertHookSlice(slice reflect.Value, ptr bool, db DB) error { - return callHookSlice(slice, ptr, db, callBeforeInsertHook) -} - -//------------------------------------------------------------------------------ - -type afterInsertHook interface { - AfterInsert(db DB) error -} - -var afterInsertHookType = reflect.TypeOf((*afterInsertHook)(nil)).Elem() - -func callAfterInsertHook(v reflect.Value, db DB) error { - return v.Interface().(afterInsertHook).AfterInsert(db) -} - -func callAfterInsertHookSlice(slice reflect.Value, ptr bool, db DB) error { - return callHookSlice(slice, ptr, db, callAfterInsertHook) -} - -//------------------------------------------------------------------------------ - -type beforeUpdateHook interface { - BeforeUpdate(db DB) error -} - -var beforeUpdateHookType = reflect.TypeOf((*beforeUpdateHook)(nil)).Elem() - -func callBeforeUpdateHook(v reflect.Value, db DB) error { - return v.Interface().(beforeUpdateHook).BeforeUpdate(db) -} - -func callBeforeUpdateHookSlice(slice reflect.Value, ptr bool, db DB) error { - return callHookSlice(slice, ptr, db, callBeforeUpdateHook) -} - -//------------------------------------------------------------------------------ - -type afterUpdateHook interface { - AfterUpdate(db DB) error -} - -var afterUpdateHookType = reflect.TypeOf((*afterUpdateHook)(nil)).Elem() - -func callAfterUpdateHook(v reflect.Value, db DB) error { - return v.Interface().(afterUpdateHook).AfterUpdate(db) -} - -func callAfterUpdateHookSlice(slice reflect.Value, ptr bool, db DB) error { - return callHookSlice(slice, ptr, db, callAfterUpdateHook) -} - -//------------------------------------------------------------------------------ - -type beforeDeleteHook interface { - BeforeDelete(db DB) error -} - -var beforeDeleteHookType = reflect.TypeOf((*beforeDeleteHook)(nil)).Elem() - -func callBeforeDeleteHook(v reflect.Value, db DB) error { - return v.Interface().(beforeDeleteHook).BeforeDelete(db) -} - -func callBeforeDeleteHookSlice(slice reflect.Value, ptr bool, db DB) error { - return callHookSlice(slice, ptr, db, callBeforeDeleteHook) -} - -//------------------------------------------------------------------------------ - -type afterDeleteHook interface { - AfterDelete(db DB) error -} - -var afterDeleteHookType = reflect.TypeOf((*afterDeleteHook)(nil)).Elem() - -func callAfterDeleteHook(v reflect.Value, db DB) error { - return v.Interface().(afterDeleteHook).AfterDelete(db) -} - -func callAfterDeleteHookSlice(slice reflect.Value, ptr bool, db DB) error { - return callHookSlice(slice, ptr, db, callAfterDeleteHook) -} diff --git a/vendor/github.com/go-pg/pg/orm/inflection.go b/vendor/github.com/go-pg/pg/orm/inflection.go deleted file mode 100644 index 9ff8bd624..000000000 --- a/vendor/github.com/go-pg/pg/orm/inflection.go +++ /dev/null @@ -1,17 +0,0 @@ -package orm - -import ( - "github.com/jinzhu/inflection" -) - -var tableNameInflector func(string) string - -func init() { - SetTableNameInflector(inflection.Plural) -} - -// SetTableNameInflector overrides the default func that pluralizes -// model name to get table name, e.g. my_article becomes my_articles. -func SetTableNameInflector(fn func(string) string) { - tableNameInflector = fn -} diff --git a/vendor/github.com/go-pg/pg/orm/insert.go b/vendor/github.com/go-pg/pg/orm/insert.go deleted file mode 100644 index 559072f97..000000000 --- a/vendor/github.com/go-pg/pg/orm/insert.go +++ /dev/null @@ -1,157 +0,0 @@ -package orm - -import ( - "errors" - "fmt" - "reflect" -) - -func Insert(db DB, model ...interface{}) error { - _, err := NewQuery(db, model...).Insert() - return err -} - -type insertQuery struct { - q *Query - returningFields []*Field -} - -var _ QueryAppender = (*insertQuery)(nil) - -func (q *insertQuery) Copy() QueryAppender { - return &insertQuery{ - q: q.q.Copy(), - } -} - -func (q *insertQuery) Query() *Query { - return q.q -} - -func (q *insertQuery) AppendQuery(b []byte) ([]byte, error) { - if q.q.stickyErr != nil { - return nil, q.q.stickyErr - } - if q.q.model == nil { - return nil, errors.New("pg: Model(nil)") - } - - table := q.q.model.Table() - value := q.q.model.Value() - var err error - - if len(q.q.with) > 0 { - b, err = q.q.appendWith(b) - if err != nil { - return nil, err - } - } - - b = append(b, "INSERT INTO "...) - if q.q.onConflict != nil { - b = q.q.appendFirstTableWithAlias(b) - } else { - b = q.q.appendFirstTable(b) - } - - if q.q.hasMultiTables() { - if q.q.columns != nil { - b = append(b, " ("...) - b = q.q.appendColumns(b) - b = append(b, ")"...) - } - b = append(b, " SELECT * FROM "...) - b = q.q.appendOtherTables(b) - } else { - fields, err := q.q.getFields() - if err != nil { - return nil, err - } - - if len(fields) == 0 { - fields = table.Fields - } - - b = append(b, " ("...) - b = appendColumns(b, "", fields) - b = append(b, ") VALUES ("...) - if value.Kind() == reflect.Struct { - b = q.appendValues(b, fields, value) - } else { - if value.Len() == 0 { - err = fmt.Errorf("pg: can't bulk-insert empty slice %s", value.Type()) - return nil, err - } - - for i := 0; i < value.Len(); i++ { - el := indirect(value.Index(i)) - b = q.appendValues(b, fields, el) - if i != value.Len()-1 { - b = append(b, "), ("...) - } - } - } - b = append(b, ")"...) - } - - if q.q.onConflict != nil { - b = append(b, " ON CONFLICT "...) - b = q.q.onConflict.AppendFormat(b, q.q) - - if q.q.onConflictDoUpdate() { - if len(q.q.set) > 0 { - b = q.q.appendSet(b) - } - - if len(q.q.updWhere) > 0 { - b = append(b, " WHERE "...) - b = q.q.appendUpdWhere(b) - } - } - } - - if len(q.q.returning) > 0 { - b = q.q.appendReturning(b) - } else if len(q.returningFields) > 0 { - b = appendReturningFields(b, q.returningFields) - } - - return b, nil -} - -func (q *insertQuery) appendValues(b []byte, fields []*Field, v reflect.Value) []byte { - for i, f := range fields { - if i > 0 { - b = append(b, ", "...) - } - - app, ok := q.q.modelValues[f.SQLName] - if ok { - b = app.AppendFormat(b, q.q) - continue - } - - if (f.Default != "" || f.OmitZero()) && f.IsZero(v) { - b = append(b, "DEFAULT"...) - q.addReturningField(f) - } else { - b = f.AppendValue(b, v, 1) - } - } - return b -} - -func (ins *insertQuery) addReturningField(field *Field) { - for _, f := range ins.returningFields { - if f == field { - return - } - } - ins.returningFields = append(ins.returningFields, field) -} - -func appendReturningFields(b []byte, fields []*Field) []byte { - b = append(b, " RETURNING "...) - b = appendColumns(b, "", fields) - return b -} diff --git a/vendor/github.com/go-pg/pg/orm/join.go b/vendor/github.com/go-pg/pg/orm/join.go deleted file mode 100644 index f7c3a99e4..000000000 --- a/vendor/github.com/go-pg/pg/orm/join.go +++ /dev/null @@ -1,345 +0,0 @@ -package orm - -import ( - "reflect" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/types" -) - -type join struct { - Parent *join - BaseModel tableModel - JoinModel tableModel - Rel *Relation - - ApplyQuery func(*Query) (*Query, error) - Columns []string - on []*condAppender -} - -func (j *join) AppendOn(app *condAppender) { - j.on = append(j.on, app) -} - -func (j *join) Select(q *Query) error { - switch j.Rel.Type { - case HasManyRelation: - return j.selectMany(q) - case Many2ManyRelation: - return j.selectM2M(q) - } - panic("not reached") -} - -func (j *join) selectMany(q *Query) error { - q, err := j.manyQuery(q) - if err != nil { - return err - } - if q == nil { - return nil - } - return q.Select() -} - -func (j *join) manyQuery(q *Query) (*Query, error) { - manyModel := newManyModel(j) - if manyModel == nil { - return nil, nil - } - - q = q.Model(manyModel) - if j.ApplyQuery != nil { - var err error - q, err = j.ApplyQuery(q) - if err != nil { - return nil, err - } - } - - if len(q.columns) == 0 { - q.columns = append(q.columns, hasManyColumnsAppender{j}) - } - - baseTable := j.BaseModel.Table() - var where []byte - if len(j.Rel.FKs) > 1 { - where = append(where, '(') - } - where = appendColumns(where, j.JoinModel.Table().Alias, j.Rel.FKs) - if len(j.Rel.FKs) > 1 { - where = append(where, '(') - } - where = append(where, " IN ("...) - where = appendChildValues( - where, j.JoinModel.Root(), j.JoinModel.ParentIndex(), j.Rel.FKValues) - where = append(where, ")"...) - q = q.Where(internal.BytesToString(where)) - - if j.Rel.Polymorphic != nil { - q = q.Where(`? IN (?, ?)`, - j.Rel.Polymorphic.Column, - baseTable.ModelName, baseTable.TypeName) - } - - return q, nil -} - -func (j *join) selectM2M(q *Query) error { - q, err := j.m2mQuery(q) - if err != nil { - return err - } - if q == nil { - return nil - } - return q.Select() -} - -func (j *join) m2mQuery(q *Query) (*Query, error) { - m2mModel := newM2MModel(j) - if m2mModel == nil { - return nil, nil - } - - q = q.Model(m2mModel) - if j.ApplyQuery != nil { - var err error - q, err = j.ApplyQuery(q) - if err != nil { - return nil, err - } - } - - if len(q.columns) == 0 { - q.columns = append(q.columns, hasManyColumnsAppender{j}) - } - - index := j.JoinModel.ParentIndex() - baseTable := j.BaseModel.Table() - var join []byte - join = append(join, "JOIN "...) - join = q.FormatQuery(join, string(j.Rel.M2MTableName)) - join = append(join, " AS "...) - join = append(join, j.Rel.M2MTableAlias...) - join = append(join, " ON ("...) - for i, col := range j.Rel.BaseFKs { - if i > 0 { - join = append(join, ", "...) - } - join = append(join, j.Rel.M2MTableAlias...) - join = append(join, '.') - join = types.AppendField(join, col, 1) - } - join = append(join, ") IN ("...) - join = appendChildValues(join, j.BaseModel.Root(), index, baseTable.PKs) - join = append(join, ")"...) - q = q.Join(internal.BytesToString(join)) - - joinTable := j.JoinModel.Table() - for i, col := range j.Rel.JoinFKs { - if i >= len(joinTable.PKs) { - break - } - pk := joinTable.PKs[i] - q = q.Where("?.? = ?.?", - joinTable.Alias, pk.Column, - j.Rel.M2MTableAlias, types.F(col)) - } - - return q, nil -} - -func (j *join) hasParent() bool { - if j.Parent != nil { - switch j.Parent.Rel.Type { - case HasOneRelation, BelongsToRelation: - return true - } - } - return false -} - -func (j *join) appendAlias(b []byte) []byte { - b = append(b, '"') - b = appendAlias(b, j, true) - b = append(b, '"') - return b -} - -func (j *join) appendAliasColumn(b []byte, column string) []byte { - b = append(b, '"') - b = appendAlias(b, j, true) - b = append(b, "__"...) - b = types.AppendField(b, column, 2) - b = append(b, '"') - return b -} - -func (j *join) appendBaseAlias(b []byte) []byte { - if j.hasParent() { - b = append(b, '"') - b = appendAlias(b, j.Parent, true) - b = append(b, '"') - return b - } - return append(b, j.BaseModel.Table().Alias...) -} - -func appendAlias(b []byte, j *join, topLevel bool) []byte { - if j.hasParent() { - b = appendAlias(b, j.Parent, topLevel) - topLevel = false - } - if !topLevel { - b = append(b, "__"...) - } - b = append(b, j.Rel.Field.SQLName...) - return b -} - -func (j *join) appendHasOneColumns(b []byte) []byte { - if j.Columns == nil { - for i, f := range j.JoinModel.Table().Fields { - if i > 0 { - b = append(b, ", "...) - } - b = j.appendAlias(b) - b = append(b, '.') - b = append(b, f.Column...) - b = append(b, " AS "...) - b = j.appendAliasColumn(b, f.SQLName) - } - return b - } - - for i, column := range j.Columns { - if i > 0 { - b = append(b, ", "...) - } - b = j.appendAlias(b) - b = append(b, '.') - b = types.AppendField(b, column, 1) - b = append(b, " AS "...) - b = j.appendAliasColumn(b, column) - } - - return b -} - -func (j *join) appendHasOneJoin(q *Query, b []byte) []byte { - b = append(b, "LEFT JOIN "...) - b = q.FormatQuery(b, string(j.JoinModel.Table().NameForSelects)) - b = append(b, " AS "...) - b = j.appendAlias(b) - - b = append(b, " ON "...) - - if len(j.Rel.FKs) > 1 { - b = append(b, '(') - } - if j.Rel.Type == HasOneRelation { - joinTable := j.Rel.JoinTable - for i, fk := range j.Rel.FKs { - if i > 0 { - b = append(b, " AND "...) - } - b = j.appendAlias(b) - b = append(b, '.') - b = append(b, joinTable.PKs[i].Column...) - b = append(b, " = "...) - b = j.appendBaseAlias(b) - b = append(b, '.') - b = append(b, fk.Column...) - } - } else { - baseTable := j.BaseModel.Table() - for i, fk := range j.Rel.FKs { - if i > 0 { - b = append(b, " AND "...) - } - b = j.appendAlias(b) - b = append(b, '.') - b = append(b, fk.Column...) - b = append(b, " = "...) - b = j.appendBaseAlias(b) - b = append(b, '.') - b = append(b, baseTable.PKs[i].Column...) - } - } - if len(j.Rel.FKs) > 1 { - b = append(b, ')') - } - - for _, on := range j.on { - b = on.AppendSep(b) - b = on.AppendFormat(b, q) - } - - if q.softDelete() { - b = append(b, " AND "...) - b = j.appendBaseAlias(b) - b = q.appendSoftDelete(b) - } - - return b -} - -type hasManyColumnsAppender struct { - *join -} - -func (q hasManyColumnsAppender) AppendFormat(b []byte, f QueryFormatter) []byte { - if q.Rel.M2MTableAlias != "" { - b = append(b, q.Rel.M2MTableAlias...) - b = append(b, ".*, "...) - } - - joinTable := q.JoinModel.Table() - - if q.Columns != nil { - for i, column := range q.Columns { - if i > 0 { - b = append(b, ", "...) - } - b = append(b, joinTable.Alias...) - b = append(b, '.') - b = types.AppendField(b, column, 1) - } - return b - } - - return appendColumns(b, joinTable.Alias, joinTable.Fields) -} - -func appendChildValues(b []byte, v reflect.Value, index []int, fields []*Field) []byte { - seen := make(map[string]struct{}) - walk(v, index, func(v reflect.Value) { - start := len(b) - - if len(fields) > 1 { - b = append(b, '(') - } - for i, f := range fields { - if i > 0 { - b = append(b, ", "...) - } - b = f.AppendValue(b, v, 1) - } - if len(fields) > 1 { - b = append(b, ')') - } - b = append(b, ", "...) - - if _, ok := seen[string(b[start:])]; ok { - b = b[:start] - } else { - seen[string(b[start:])] = struct{}{} - } - }) - if len(seen) > 0 { - b = b[:len(b)-2] // trim ", " - } - return b -} diff --git a/vendor/github.com/go-pg/pg/orm/model.go b/vendor/github.com/go-pg/pg/orm/model.go deleted file mode 100644 index 1ecb3c9fc..000000000 --- a/vendor/github.com/go-pg/pg/orm/model.go +++ /dev/null @@ -1,110 +0,0 @@ -package orm - -import ( - "database/sql" - "errors" - "fmt" - "reflect" - - "github.com/go-pg/pg/types" -) - -type useQueryOne interface { - useQueryOne() bool -} - -type HooklessModel interface { - // Init is responsible to initialize/reset model state. - // It is called only once no matter how many rows - // were returned by database. - Init() error - - // NewModel returns ColumnScanner that is used to scan columns - // from the current row. It is called once for every row. - NewModel() ColumnScanner - - // AddModel adds ColumnScanner created by NewModel to the Collection. - AddModel(ColumnScanner) error - - ColumnScanner -} - -type Model interface { - HooklessModel - - AfterQuery(DB) error - - BeforeSelectQuery(DB, *Query) (*Query, error) - AfterSelect(DB) error - - BeforeInsert(DB) error - AfterInsert(DB) error - - BeforeUpdate(DB) error - AfterUpdate(DB) error - - BeforeDelete(DB) error - AfterDelete(DB) error -} - -func NewModel(values ...interface{}) (Model, error) { - if len(values) > 1 { - return Scan(values...), nil - } - - v0 := values[0] - switch v0 := v0.(type) { - case Model: - return v0, nil - case HooklessModel: - return newModelWithHookStubs(v0), nil - case sql.Scanner: - return Scan(v0), nil - } - - v := reflect.ValueOf(v0) - if !v.IsValid() { - return nil, errors.New("pg: Model(nil)") - } - if v.Kind() != reflect.Ptr { - return nil, fmt.Errorf("pg: Model(non-pointer %T)", v0) - } - v = v.Elem() - - switch v.Kind() { - case reflect.Struct: - return newStructTableModelValue(v), nil - case reflect.Slice: - typ := v.Type() - structType := indirectType(typ.Elem()) - if structType.Kind() == reflect.Struct && structType != timeType { - m := sliceTableModel{ - structTableModel: structTableModel{ - table: GetTable(structType), - root: v, - }, - slice: v, - } - m.init(typ) - return &m, nil - } else { - return &sliceModel{ - slice: v, - scan: types.Scanner(structType), - }, nil - } - } - - return Scan(v0), nil -} - -type modelWithHookStubs struct { - hookStubs - HooklessModel -} - -func newModelWithHookStubs(m HooklessModel) Model { - return modelWithHookStubs{ - HooklessModel: m, - } -} diff --git a/vendor/github.com/go-pg/pg/orm/model_discard.go b/vendor/github.com/go-pg/pg/orm/model_discard.go deleted file mode 100644 index 3b7b4389f..000000000 --- a/vendor/github.com/go-pg/pg/orm/model_discard.go +++ /dev/null @@ -1,23 +0,0 @@ -package orm - -type Discard struct { - hookStubs -} - -var _ Model = (*Discard)(nil) - -func (Discard) Init() error { - return nil -} - -func (m Discard) NewModel() ColumnScanner { - return m -} - -func (m Discard) AddModel(ColumnScanner) error { - return nil -} - -func (m Discard) ScanColumn(colIdx int, colName string, b []byte) error { - return nil -} diff --git a/vendor/github.com/go-pg/pg/orm/model_func.go b/vendor/github.com/go-pg/pg/orm/model_func.go deleted file mode 100644 index 64b300b7c..000000000 --- a/vendor/github.com/go-pg/pg/orm/model_func.go +++ /dev/null @@ -1,89 +0,0 @@ -package orm - -import ( - "fmt" - "reflect" -) - -var errorType = reflect.TypeOf((*error)(nil)).Elem() - -type funcModel struct { - Model - fnv reflect.Value - fnIn []reflect.Value -} - -var _ Model = (*funcModel)(nil) - -func newFuncModel(fn interface{}) *funcModel { - m := &funcModel{ - fnv: reflect.ValueOf(fn), - } - - fnt := m.fnv.Type() - if fnt.Kind() != reflect.Func { - panic(fmt.Errorf("ForEach expects a %s, got a %s", - reflect.Func, fnt.Kind())) - } - - if fnt.NumIn() < 1 { - panic(fmt.Errorf("ForEach expects at least 1 arg, got %d", fnt.NumIn())) - } - - if fnt.NumOut() != 1 { - panic(fmt.Errorf("ForEach must return 1 value, got %d", fnt.NumOut())) - } - if fnt.Out(0) != errorType { - panic(fmt.Errorf("ForEach must return an error, got %T", fnt.Out(0))) - } - - if fnt.NumIn() > 1 { - initFuncModelScan(m, fnt) - return m - } - - t0 := fnt.In(0) - var v0 reflect.Value - if t0.Kind() == reflect.Ptr { - t0 = t0.Elem() - v0 = reflect.New(t0) - } else { - v0 = reflect.New(t0).Elem() - } - - m.fnIn = []reflect.Value{v0} - - model, ok := v0.Interface().(Model) - if ok { - m.Model = model - return m - } - - if v0.Kind() == reflect.Ptr { - v0 = v0.Elem() - } - if v0.Kind() != reflect.Struct { - panic(fmt.Errorf("ForEach accepts a %s, got %s", - reflect.Struct, v0.Kind())) - } - m.Model = newStructTableModelValue(v0) - - return m -} - -func initFuncModelScan(m *funcModel, fnt reflect.Type) { - m.fnIn = make([]reflect.Value, fnt.NumIn()) - for i := 0; i < fnt.NumIn(); i++ { - m.fnIn[i] = reflect.New(fnt.In(i)).Elem() - } - m.Model = scanReflectValues(m.fnIn) -} - -func (m *funcModel) AddModel(_ ColumnScanner) error { - out := m.fnv.Call(m.fnIn) - errv := out[0] - if !errv.IsNil() { - return errv.Interface().(error) - } - return nil -} diff --git a/vendor/github.com/go-pg/pg/orm/model_scan.go b/vendor/github.com/go-pg/pg/orm/model_scan.go deleted file mode 100644 index 6874b736b..000000000 --- a/vendor/github.com/go-pg/pg/orm/model_scan.go +++ /dev/null @@ -1,68 +0,0 @@ -package orm - -import ( - "fmt" - "reflect" - - "github.com/go-pg/pg/types" -) - -type scanValuesModel struct { - Discard - values []interface{} -} - -var _ Model = scanValuesModel{} - -func Scan(values ...interface{}) scanValuesModel { - return scanValuesModel{ - values: values, - } -} - -func (scanValuesModel) useQueryOne() bool { - return true -} - -func (m scanValuesModel) NewModel() ColumnScanner { - return m -} - -func (m scanValuesModel) ScanColumn(colIdx int, colName string, b []byte) error { - if colIdx >= len(m.values) { - return fmt.Errorf("pg: no Scan var for column index=%d name=%q", - colIdx, colName) - } - return types.Scan(m.values[colIdx], b) -} - -//------------------------------------------------------------------------------ - -type scanReflectValuesModel struct { - Discard - values []reflect.Value -} - -var _ Model = scanReflectValuesModel{} - -func scanReflectValues(values []reflect.Value) scanReflectValuesModel { - return scanReflectValuesModel{ - values: values, - } -} - -func (scanReflectValuesModel) useQueryOne() bool { - return true -} - -func (m scanReflectValuesModel) NewModel() ColumnScanner { - return m -} - -func (m scanReflectValuesModel) ScanColumn(colIdx int, colName string, b []byte) error { - if colIdx >= len(m.values) { - return fmt.Errorf("pg: no Scan var for column index=%d name=%q", - colIdx, colName) - } - return types.ScanValue(m.values[colIdx], b) -} diff --git a/vendor/github.com/go-pg/pg/orm/model_slice.go b/vendor/github.com/go-pg/pg/orm/model_slice.go deleted file mode 100644 index 3e79be2fc..000000000 --- a/vendor/github.com/go-pg/pg/orm/model_slice.go +++ /dev/null @@ -1,35 +0,0 @@ -package orm - -import ( - "reflect" - - "github.com/go-pg/pg/internal" -) - -type sliceModel struct { - Discard - slice reflect.Value - nextElem func() reflect.Value - scan func(reflect.Value, []byte) error -} - -var _ Model = (*sliceModel)(nil) - -func (m *sliceModel) Init() error { - if m.slice.IsValid() && m.slice.Len() > 0 { - m.slice.Set(m.slice.Slice(0, 0)) - } - return nil -} - -func (m *sliceModel) NewModel() ColumnScanner { - return m -} - -func (m *sliceModel) ScanColumn(colIdx int, _ string, b []byte) error { - if m.nextElem == nil { - m.nextElem = internal.MakeSliceNextElemFunc(m.slice) - } - v := m.nextElem() - return m.scan(v, b) -} diff --git a/vendor/github.com/go-pg/pg/orm/model_table.go b/vendor/github.com/go-pg/pg/orm/model_table.go deleted file mode 100644 index f67b9fb75..000000000 --- a/vendor/github.com/go-pg/pg/orm/model_table.go +++ /dev/null @@ -1,109 +0,0 @@ -package orm - -import ( - "errors" - "fmt" - "reflect" -) - -type tableModel interface { - Model - - Table() *Table - Relation() *Relation - AppendParam([]byte, QueryFormatter, string) ([]byte, bool) - - Join(string, func(*Query) (*Query, error)) *join - GetJoin(string) *join - GetJoins() []join - AddJoin(join) *join - - Root() reflect.Value - Index() []int - ParentIndex() []int - Mount(reflect.Value) - Kind() reflect.Kind - Value() reflect.Value - - setDeletedAt() - scanColumn(int, string, []byte) (bool, error) -} - -func newTableModel(value interface{}) (tableModel, error) { - if value, ok := value.(tableModel); ok { - return value, nil - } - - v := reflect.ValueOf(value) - if !v.IsValid() { - return nil, errors.New("pg: Model(nil)") - } - if v.Kind() != reflect.Ptr { - return nil, fmt.Errorf("pg: Model(non-pointer %T)", value) - } - - if v.IsNil() { - typ := v.Type().Elem() - if typ.Kind() == reflect.Struct { - return newStructTableModelType(typ), nil - } - return nil, errors.New("pg: Model(nil)") - } - - return newTableModelValue(v.Elem()) -} - -func newTableModelValue(v reflect.Value) (tableModel, error) { - switch v.Kind() { - case reflect.Struct: - return newStructTableModelValue(v), nil - case reflect.Slice: - structType := sliceElemType(v) - if structType.Kind() == reflect.Struct { - m := sliceTableModel{ - structTableModel: structTableModel{ - table: GetTable(structType), - root: v, - }, - slice: v, - } - m.init(v.Type()) - return &m, nil - } - } - - return nil, fmt.Errorf("pg: Model(unsupported %s)", v.Type()) -} - -func newTableModelIndex(root reflect.Value, index []int, rel *Relation) (tableModel, error) { - typ := typeByIndex(root.Type(), index) - - if typ.Kind() == reflect.Struct { - return &structTableModel{ - table: GetTable(typ), - rel: rel, - - root: root, - index: index, - }, nil - } - - if typ.Kind() == reflect.Slice { - structType := indirectType(typ.Elem()) - if structType.Kind() == reflect.Struct { - m := sliceTableModel{ - structTableModel: structTableModel{ - table: GetTable(structType), - rel: rel, - - root: root, - index: index, - }, - } - m.init(typ) - return &m, nil - } - } - - return nil, fmt.Errorf("pg: NewModel(%s)", typ) -} diff --git a/vendor/github.com/go-pg/pg/orm/model_table_m2m.go b/vendor/github.com/go-pg/pg/orm/model_table_m2m.go deleted file mode 100644 index 98bb68612..000000000 --- a/vendor/github.com/go-pg/pg/orm/model_table_m2m.go +++ /dev/null @@ -1,135 +0,0 @@ -package orm - -import ( - "fmt" - "reflect" -) - -type m2mModel struct { - *sliceTableModel - baseTable *Table - rel *Relation - - buf []byte - dstValues map[string][]reflect.Value - columns map[string]string -} - -var _ tableModel = (*m2mModel)(nil) - -func newM2MModel(j *join) *m2mModel { - baseTable := j.BaseModel.Table() - joinModel := j.JoinModel.(*sliceTableModel) - dstValues := dstValues(joinModel, baseTable.PKs) - if len(dstValues) == 0 { - return nil - } - m := &m2mModel{ - sliceTableModel: joinModel, - baseTable: baseTable, - rel: j.Rel, - - dstValues: dstValues, - columns: make(map[string]string), - } - if !m.sliceOfPtr { - m.strct = reflect.New(m.table.Type).Elem() - } - return m -} - -func (m *m2mModel) NewModel() ColumnScanner { - if m.sliceOfPtr { - m.strct = reflect.New(m.table.Type).Elem() - } else { - m.strct.Set(m.table.zeroStruct) - } - m.structInited = false - m.structTableModel.NewModel() - return m -} - -func (m *m2mModel) AddModel(model ColumnScanner) error { - m.buf = modelIdMap(m.buf[:0], m.columns, m.rel.BaseFKs) - dstValues, ok := m.dstValues[string(m.buf)] - if !ok { - return fmt.Errorf( - "pg: relation=%q has no base %s with id=%q (check join conditions)", - m.rel.Field.GoName, m.baseTable, m.buf) - } - - for _, v := range dstValues { - if m.sliceOfPtr { - v.Set(reflect.Append(v, m.strct.Addr())) - } else { - v.Set(reflect.Append(v, m.strct)) - } - } - - return nil -} - -func modelIdMap(b []byte, m map[string]string, columns []string) []byte { - for i, col := range columns { - if i > 0 { - b = append(b, ',') - } - b = append(b, m[col]...) - } - return b -} - -func (m *m2mModel) AfterQuery(db DB) error { - if !m.rel.JoinTable.HasFlag(AfterQueryHookFlag) { - return nil - } - - var retErr error - for _, slices := range m.dstValues { - for _, slice := range slices { - err := callAfterQueryHookSlice(slice, m.sliceOfPtr, db) - if err != nil && retErr == nil { - retErr = err - } - } - } - return retErr -} - -func (m *m2mModel) AfterSelect(db DB) error { - return nil -} - -func (m *m2mModel) BeforeInsert(db DB) error { - return nil -} - -func (m *m2mModel) AfterInsert(db DB) error { - return nil -} - -func (m *m2mModel) BeforeUpdate(db DB) error { - return nil -} - -func (m *m2mModel) AfterUpdate(db DB) error { - return nil -} - -func (m *m2mModel) BeforeDelete(db DB) error { - return nil -} - -func (m *m2mModel) AfterDelete(db DB) error { - return nil -} - -func (m *m2mModel) ScanColumn(colIdx int, colName string, b []byte) error { - ok, err := m.sliceTableModel.scanColumn(colIdx, colName, b) - if ok { - return err - } - - m.columns[colName] = string(b) - return nil -} diff --git a/vendor/github.com/go-pg/pg/orm/model_table_many.go b/vendor/github.com/go-pg/pg/orm/model_table_many.go deleted file mode 100644 index 41af7ee2d..000000000 --- a/vendor/github.com/go-pg/pg/orm/model_table_many.go +++ /dev/null @@ -1,113 +0,0 @@ -package orm - -import ( - "fmt" - "reflect" -) - -type manyModel struct { - *sliceTableModel - baseTable *Table - rel *Relation - - buf []byte - dstValues map[string][]reflect.Value -} - -var _ tableModel = (*manyModel)(nil) - -func newManyModel(j *join) *manyModel { - baseTable := j.BaseModel.Table() - joinModel := j.JoinModel.(*sliceTableModel) - dstValues := dstValues(joinModel, j.Rel.FKValues) - if len(dstValues) == 0 { - return nil - } - m := manyModel{ - sliceTableModel: joinModel, - baseTable: baseTable, - rel: j.Rel, - - dstValues: dstValues, - } - if !m.sliceOfPtr { - m.strct = reflect.New(m.table.Type).Elem() - } - return &m -} - -func (m *manyModel) NewModel() ColumnScanner { - if m.sliceOfPtr { - m.strct = reflect.New(m.table.Type).Elem() - } else { - m.strct.Set(m.table.zeroStruct) - } - m.structInited = false - m.structTableModel.NewModel() - return m -} - -func (m *manyModel) AddModel(model ColumnScanner) error { - m.buf = modelId(m.buf[:0], m.strct, m.rel.FKs) - dstValues, ok := m.dstValues[string(m.buf)] - if !ok { - return fmt.Errorf( - "pg: relation=%q has no base model=%q with id=%q (check join conditions)", - m.rel.Field.GoName, m.baseTable.TypeName, m.buf) - } - - for _, v := range dstValues { - if m.sliceOfPtr { - v.Set(reflect.Append(v, m.strct.Addr())) - } else { - v.Set(reflect.Append(v, m.strct)) - } - } - - return nil -} - -func (m *manyModel) AfterQuery(db DB) error { - if !m.rel.JoinTable.HasFlag(AfterQueryHookFlag) { - return nil - } - - var retErr error - for _, slices := range m.dstValues { - for _, slice := range slices { - err := callAfterQueryHookSlice(slice, m.sliceOfPtr, db) - if err != nil && retErr == nil { - retErr = err - } - } - } - return retErr -} - -func (m *manyModel) AfterSelect(db DB) error { - return nil -} - -func (m *manyModel) BeforeInsert(db DB) error { - return nil -} - -func (m *manyModel) AfterInsert(db DB) error { - return nil -} - -func (m *manyModel) BeforeUpdate(db DB) error { - return nil -} - -func (m *manyModel) AfterUpdate(db DB) error { - return nil -} - -func (m *manyModel) BeforeDelete(db DB) error { - return nil -} - -func (m *manyModel) AfterDelete(db DB) error { - return nil -} diff --git a/vendor/github.com/go-pg/pg/orm/model_table_slice.go b/vendor/github.com/go-pg/pg/orm/model_table_slice.go deleted file mode 100644 index 8b63ac6d9..000000000 --- a/vendor/github.com/go-pg/pg/orm/model_table_slice.go +++ /dev/null @@ -1,152 +0,0 @@ -package orm - -import ( - "reflect" - "time" -) - -type sliceTableModel struct { - structTableModel - - slice reflect.Value - sliceOfPtr bool -} - -var _ tableModel = (*sliceTableModel)(nil) - -func (m *sliceTableModel) init(sliceType reflect.Type) { - switch sliceType.Elem().Kind() { - case reflect.Ptr, reflect.Interface: - m.sliceOfPtr = true - } -} - -func (sliceTableModel) useQueryOne() {} - -func (m *sliceTableModel) AppendParam(b []byte, f QueryFormatter, name string) ([]byte, bool) { - if field, ok := m.table.FieldsMap[name]; ok { - b = append(b, "_data."...) - b = append(b, field.Column...) - return b, true - } - - return m.structTableModel.AppendParam(b, f, name) -} - -func (m *sliceTableModel) Join(name string, apply func(*Query) (*Query, error)) *join { - return m.join(m.Value(), name, apply) -} - -func (m *sliceTableModel) Bind(bind reflect.Value) { - m.slice = bind.Field(m.index[len(m.index)-1]) -} - -func (m *sliceTableModel) Kind() reflect.Kind { - return reflect.Slice -} - -func (m *sliceTableModel) Value() reflect.Value { - return m.slice -} - -func (m *sliceTableModel) Init() error { - if m.slice.IsValid() && m.slice.Len() > 0 { - m.slice.Set(m.slice.Slice(0, 0)) - } - return nil -} - -func (m *sliceTableModel) NewModel() ColumnScanner { - m.strct = m.nextElem() - m.structInited = false - return m -} - -func (m *sliceTableModel) AfterQuery(db DB) error { - if !m.table.HasFlag(AfterQueryHookFlag) { - return nil - } - return callAfterQueryHookSlice(m.slice, m.sliceOfPtr, db) -} - -func (m *sliceTableModel) AfterSelect(db DB) error { - if !m.table.HasFlag(AfterSelectHookFlag) { - return nil - } - return callAfterSelectHookSlice(m.slice, m.sliceOfPtr, db) -} - -func (m *sliceTableModel) BeforeInsert(db DB) error { - if !m.table.HasFlag(BeforeInsertHookFlag) { - return nil - } - return callBeforeInsertHookSlice(m.slice, m.sliceOfPtr, db) -} - -func (m *sliceTableModel) AfterInsert(db DB) error { - if !m.table.HasFlag(AfterInsertHookFlag) { - return nil - } - return callAfterInsertHookSlice(m.slice, m.sliceOfPtr, db) -} - -func (m *sliceTableModel) BeforeUpdate(db DB) error { - if !m.table.HasFlag(BeforeUpdateHookFlag) { - return nil - } - return callBeforeUpdateHookSlice(m.slice, m.sliceOfPtr, db) -} - -func (m *sliceTableModel) AfterUpdate(db DB) error { - if !m.table.HasFlag(AfterUpdateHookFlag) { - return nil - } - return callAfterUpdateHookSlice(m.slice, m.sliceOfPtr, db) -} - -func (m *sliceTableModel) BeforeDelete(db DB) error { - if !m.table.HasFlag(BeforeDeleteHookFlag) { - return nil - } - return callBeforeDeleteHookSlice(m.slice, m.sliceOfPtr, db) -} - -func (m *sliceTableModel) AfterDelete(db DB) error { - if !m.table.HasFlag(AfterDeleteHookFlag) { - return nil - } - return callAfterDeleteHookSlice(m.slice, m.sliceOfPtr, db) -} - -func (m *sliceTableModel) nextElem() reflect.Value { - if m.slice.Len() < m.slice.Cap() { - m.slice.Set(m.slice.Slice(0, m.slice.Len()+1)) - elem := m.slice.Index(m.slice.Len() - 1) - if m.sliceOfPtr { - if elem.IsNil() { - elem.Set(reflect.New(elem.Type().Elem())) - } - return elem.Elem() - } - return elem - } - - if m.sliceOfPtr { - elem := reflect.New(m.table.Type) - m.slice.Set(reflect.Append(m.slice, elem)) - return elem.Elem() - } - - m.slice.Set(reflect.Append(m.slice, m.table.zeroStruct)) - return m.slice.Index(m.slice.Len() - 1) -} - -func (m *sliceTableModel) setDeletedAt() { - field := m.table.FieldsMap["deleted_at"] - now := time.Now() - for i := 0; i < m.slice.Len(); i++ { - strct := indirect(m.slice.Index(i)) - value := field.Value(strct) - value.Set(reflect.ValueOf(now)) - } -} diff --git a/vendor/github.com/go-pg/pg/orm/model_table_struct.go b/vendor/github.com/go-pg/pg/orm/model_table_struct.go deleted file mode 100644 index 44e77eb65..000000000 --- a/vendor/github.com/go-pg/pg/orm/model_table_struct.go +++ /dev/null @@ -1,363 +0,0 @@ -package orm - -import ( - "errors" - "fmt" - "reflect" - "strings" - "time" -) - -type structTableModel struct { - table *Table - rel *Relation - joins []join - - root reflect.Value - index []int - - strct reflect.Value - structInited bool - structInitErr error -} - -var _ tableModel = (*structTableModel)(nil) - -func newStructTableModelValue(v reflect.Value) *structTableModel { - return &structTableModel{ - table: GetTable(v.Type()), - root: v, - strct: v, - } -} - -func newStructTableModelType(typ reflect.Type) *structTableModel { - return &structTableModel{ - table: GetTable(typ), - } -} - -func (structTableModel) useQueryOne() bool { - return true -} - -func (m *structTableModel) Table() *Table { - return m.table -} - -func (m *structTableModel) Relation() *Relation { - return m.rel -} - -func (m *structTableModel) AppendParam(b []byte, f QueryFormatter, name string) ([]byte, bool) { - b, ok := m.table.AppendParam(b, m.strct, name) - if ok { - return b, true - } - - switch name { - case "TableName": - b = f.FormatQuery(b, string(m.table.Name)) - return b, true - case "TableAlias": - b = append(b, m.table.Alias...) - return b, true - case "TableColumns": - b = appendColumns(b, m.table.Alias, m.table.Fields) - return b, true - case "Columns": - b = appendColumns(b, "", m.table.Fields) - return b, true - } - - return b, false -} - -func (m *structTableModel) Root() reflect.Value { - return m.root -} - -func (m *structTableModel) Index() []int { - return m.index -} - -func (m *structTableModel) ParentIndex() []int { - return m.index[:len(m.index)-len(m.rel.Field.Index)] -} - -func (m *structTableModel) Kind() reflect.Kind { - return reflect.Struct -} - -func (m *structTableModel) Value() reflect.Value { - return m.strct -} - -func (m *structTableModel) Mount(host reflect.Value) { - m.strct = host.FieldByIndex(m.rel.Field.Index) - m.structInited = false -} - -func (m *structTableModel) initStruct() error { - if m.structInited { - return m.structInitErr - } - m.structInited = true - - switch m.strct.Kind() { - case reflect.Invalid: - m.structInitErr = errors.New("pg: Model(nil)") - return m.structInitErr - case reflect.Interface: - m.strct = m.strct.Elem() - } - - if m.strct.Kind() == reflect.Ptr { - if m.strct.IsNil() { - m.strct.Set(reflect.New(m.strct.Type().Elem())) - m.strct = m.strct.Elem() - } else { - m.strct = m.strct.Elem() - } - } - - m.mountJoins() - - return nil -} - -func (m *structTableModel) mountJoins() { - for i := range m.joins { - j := &m.joins[i] - switch j.Rel.Type { - case HasOneRelation, BelongsToRelation: - j.JoinModel.Mount(m.strct) - } - } -} - -func (structTableModel) Init() error { - return nil -} - -func (m *structTableModel) NewModel() ColumnScanner { - return m -} - -func (m *structTableModel) AddModel(_ ColumnScanner) error { - return nil -} - -func (m *structTableModel) AfterQuery(db DB) error { - if !m.table.HasFlag(AfterQueryHookFlag) { - return nil - } - return callAfterQueryHook(m.strct.Addr(), db) -} - -func (m *structTableModel) BeforeSelectQuery(db DB, q *Query) (*Query, error) { - if !m.table.HasFlag(BeforeSelectQueryHookFlag) { - return q, nil - } - return callBeforeSelectQueryHook(m.table.zeroStruct.Addr(), db, q) -} - -func (m *structTableModel) AfterSelect(db DB) error { - if !m.table.HasFlag(AfterSelectHookFlag) { - return nil - } - return callAfterSelectHook(m.strct.Addr(), db) -} - -func (m *structTableModel) BeforeInsert(db DB) error { - if !m.table.HasFlag(BeforeInsertHookFlag) { - return nil - } - return callBeforeInsertHook(m.strct.Addr(), db) -} - -func (m *structTableModel) AfterInsert(db DB) error { - if !m.table.HasFlag(AfterInsertHookFlag) { - return nil - } - return callAfterInsertHook(m.strct.Addr(), db) -} - -func (m *structTableModel) BeforeUpdate(db DB) error { - if !m.table.HasFlag(BeforeUpdateHookFlag) { - return nil - } - return callBeforeUpdateHook(m.strct.Addr(), db) -} - -func (m *structTableModel) AfterUpdate(db DB) error { - if !m.table.HasFlag(AfterUpdateHookFlag) { - return nil - } - return callAfterUpdateHook(m.strct.Addr(), db) -} - -func (m *structTableModel) BeforeDelete(db DB) error { - if !m.table.HasFlag(BeforeDeleteHookFlag) { - return nil - } - return callBeforeDeleteHook(m.strct.Addr(), db) -} - -func (m *structTableModel) AfterDelete(db DB) error { - if !m.table.HasFlag(AfterDeleteHookFlag) { - return nil - } - return callAfterDeleteHook(m.strct.Addr(), db) -} - -func (m *structTableModel) ScanColumn(colIdx int, colName string, b []byte) error { - ok, err := m.scanColumn(colIdx, colName, b) - if ok { - return err - } - if m.table.HasFlag(discardUnknownColumns) { - return nil - } - return fmt.Errorf("pg: can't find column=%s in %s (try discard_unknown_columns)", - colName, m.table) -} - -func (m *structTableModel) scanColumn( - colIdx int, colName string, b []byte, -) (bool, error) { - // Don't init nil struct when value is NULL. - if b == nil && - !m.structInited && - m.strct.Kind() == reflect.Ptr && - m.strct.IsNil() { - return true, nil - } - - err := m.initStruct() - if err != nil { - return true, err - } - - joinName, fieldName := splitColumn(colName) - if joinName != "" { - if join := m.GetJoin(joinName); join != nil { - return join.JoinModel.scanColumn(colIdx, fieldName, b) - } - if m.table.ModelName == joinName { - return m.scanColumn(colIdx, fieldName, b) - } - } - - field, ok := m.table.FieldsMap[colName] - if !ok { - return false, nil - } - - return true, field.ScanValue(m.strct, b) -} - -func (m *structTableModel) GetJoin(name string) *join { - for i := range m.joins { - j := &m.joins[i] - if j.Rel.Field.GoName == name || j.Rel.Field.SQLName == name { - return j - } - } - return nil -} - -func (m *structTableModel) GetJoins() []join { - return m.joins -} - -func (m *structTableModel) AddJoin(j join) *join { - m.joins = append(m.joins, j) - return &m.joins[len(m.joins)-1] -} - -func (m *structTableModel) Join(name string, apply func(*Query) (*Query, error)) *join { - return m.join(m.Value(), name, apply) -} - -func (m *structTableModel) join( - bind reflect.Value, name string, apply func(*Query) (*Query, error), -) *join { - path := strings.Split(name, ".") - index := make([]int, 0, len(path)) - - currJoin := join{ - BaseModel: m, - JoinModel: m, - } - var lastJoin *join - var hasColumnName bool - - for _, name := range path { - rel, ok := currJoin.JoinModel.Table().Relations[name] - if !ok { - hasColumnName = true - break - } - currJoin.Rel = rel - index = append(index, rel.Field.Index...) - - if j := currJoin.JoinModel.GetJoin(name); j != nil { - currJoin.BaseModel = j.BaseModel - currJoin.JoinModel = j.JoinModel - - lastJoin = j - } else { - model, err := newTableModelIndex(bind, index, rel) - if err != nil { - return nil - } - - currJoin.Parent = lastJoin - currJoin.BaseModel = currJoin.JoinModel - currJoin.JoinModel = model - - lastJoin = currJoin.BaseModel.AddJoin(currJoin) - } - } - - // No joins with such name. - if lastJoin == nil { - return nil - } - if apply != nil { - lastJoin.ApplyQuery = apply - } - - if hasColumnName { - column := path[len(path)-1] - if column == "_" { - if lastJoin.Columns == nil { - lastJoin.Columns = make([]string, 0) - } - } else { - lastJoin.Columns = append(lastJoin.Columns, column) - } - } - - return lastJoin -} - -func (m *structTableModel) setDeletedAt() { - field := m.table.FieldsMap["deleted_at"] - value := field.Value(m.strct) - if value.Kind() == reflect.Ptr { - now := time.Now() - value.Set(reflect.ValueOf(&now)) - } else { - value.Set(reflect.ValueOf(time.Now())) - } -} - -func splitColumn(s string) (string, string) { - ind := strings.Index(s, "__") - if ind == -1 { - return "", s - } - return s[:ind], s[ind+2:] -} diff --git a/vendor/github.com/go-pg/pg/orm/orm.go b/vendor/github.com/go-pg/pg/orm/orm.go deleted file mode 100644 index 02d2d3ab9..000000000 --- a/vendor/github.com/go-pg/pg/orm/orm.go +++ /dev/null @@ -1,46 +0,0 @@ -package orm - -import ( - "context" - "io" -) - -// ColumnScanner is used to scan column values. -type ColumnScanner interface { - // Scan assigns a column value from a row. - // - // An error should be returned if the value can not be stored - // without loss of information. - ScanColumn(colIdx int, colName string, b []byte) error -} - -type QueryAppender interface { - Copy() QueryAppender - Query() *Query - AppendQuery(dst []byte) ([]byte, error) -} - -type QueryFormatter interface { - FormatQuery(b []byte, query string, params ...interface{}) []byte -} - -// DB is a common interface for pg.DB and pg.Tx types. -type DB interface { - Model(model ...interface{}) *Query - Select(model interface{}) error - Insert(model ...interface{}) error - Update(model interface{}) error - Delete(model interface{}) error - ForceDelete(model interface{}) error - - Exec(query interface{}, params ...interface{}) (Result, error) - ExecOne(query interface{}, params ...interface{}) (Result, error) - Query(coll, query interface{}, params ...interface{}) (Result, error) - QueryOne(model, query interface{}, params ...interface{}) (Result, error) - - CopyFrom(r io.Reader, query interface{}, params ...interface{}) (Result, error) - CopyTo(w io.Writer, query interface{}, params ...interface{}) (Result, error) - - Context() context.Context - QueryFormatter -} diff --git a/vendor/github.com/go-pg/pg/orm/pager.go b/vendor/github.com/go-pg/pg/orm/pager.go deleted file mode 100644 index 10ec72732..000000000 --- a/vendor/github.com/go-pg/pg/orm/pager.go +++ /dev/null @@ -1,111 +0,0 @@ -package orm - -import ( - "net/url" -) - -type Pager struct { - Limit int - Offset int - - // Default max limit is 1000. - MaxLimit int - // Default max offset is 1000000. - MaxOffset int - - stickyErr error -} - -func NewPager(values url.Values) *Pager { - p := new(Pager) - p.SetURLValues(values) - return p -} - -func (p *Pager) SetURLValues(urlValues url.Values) { - values := URLValues(urlValues) - - if values.Has("limit") { - limit, err := values.Int("limit") - if err != nil { - p.stickyErr = err - return - } - p.Limit = int(limit) - } - - if values.Has("page") { - page, err := values.Int("page") - if err != nil { - p.stickyErr = err - return - } - p.SetPage(int(page)) - } -} - -func (p *Pager) maxLimit() int { - if p.MaxLimit > 0 { - return p.MaxLimit - } - return 1000 -} - -func (p *Pager) maxOffset() int { - if p.MaxOffset > 0 { - return p.MaxOffset - } - return 1000000 -} - -func (p *Pager) GetLimit() int { - const defaultLimit = 100 - - if p.Limit < 0 { - return p.Limit - } - if p.Limit == 0 { - return defaultLimit - } - if p.Limit > p.maxLimit() { - return p.maxLimit() - } - return p.Limit -} - -func (p *Pager) GetOffset() int { - if p.Offset > p.maxOffset() { - return p.maxOffset() - } - return p.Offset -} - -func (p *Pager) SetPage(page int) { - if page < 1 { - page = 1 - } - p.Offset = (page - 1) * p.GetLimit() -} - -func (p *Pager) GetPage() int { - return (p.GetOffset() / p.GetLimit()) + 1 -} - -func (p *Pager) Paginate(q *Query) (*Query, error) { - if p == nil { - return q, nil - } - if p.stickyErr != nil { - return nil, p.stickyErr - } - - q = q.Limit(p.GetLimit()).Offset(p.GetOffset()) - return q, nil -} - -// Pagination is used with Query.Apply to set LIMIT and OFFSET from the URL values: -// - ?limit=10 - sets q.Limit(10), max limit is 1000. -// - ?page=5 - sets q.Offset((page - 1) * limit), max offset is 1000000. -func Pagination(values url.Values) func(*Query) (*Query, error) { - return NewPager(values).Paginate -} diff --git a/vendor/github.com/go-pg/pg/orm/query.go b/vendor/github.com/go-pg/pg/orm/query.go deleted file mode 100644 index b44bc7e14..000000000 --- a/vendor/github.com/go-pg/pg/orm/query.go +++ /dev/null @@ -1,1302 +0,0 @@ -package orm - -import ( - "errors" - "fmt" - "io" - "reflect" - "strings" - "sync" - "time" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/types" -) - -type withQuery struct { - name string - query *Query -} - -type joinQuery struct { - join *queryParamsAppender - on []*condAppender -} - -func (q *joinQuery) AppendOn(app *condAppender) { - q.on = append(q.on, app) -} - -type Query struct { - db DB - stickyErr error - - model tableModel - ignoreModel bool - deleted bool - - with []withQuery - tables []FormatAppender - columns []FormatAppender - set []FormatAppender - modelValues map[string]*queryParamsAppender - where []sepFormatAppender - updWhere []sepFormatAppender - joins []*joinQuery - joinAppendOn func(app *condAppender) - group []FormatAppender - having []*queryParamsAppender - order []FormatAppender - onConflict *queryParamsAppender - returning []*queryParamsAppender - limit int - offset int - selFor *queryParamsAppender -} - -var _ queryAppender = (*Query)(nil) - -func NewQuery(db DB, model ...interface{}) *Query { - return (&Query{}).DB(db).Model(model...) -} - -// New returns new zero Query binded to the current db and model. -func (q *Query) New() *Query { - return &Query{ - db: q.db, - model: q.model, - ignoreModel: true, - deleted: q.deleted, - } -} - -func (q *Query) AppendQuery(b []byte) ([]byte, error) { - return selectQuery{q: q}.AppendQuery(b) -} - -// Copy returns copy of the Query. -func (q *Query) Copy() *Query { - var modelValues map[string]*queryParamsAppender - if len(q.modelValues) > 0 { - modelValues = make(map[string]*queryParamsAppender, len(q.modelValues)) - for k, v := range q.modelValues { - modelValues[k] = v - } - } - - copy := &Query{ - db: q.db, - stickyErr: q.stickyErr, - - model: q.model, - ignoreModel: q.ignoreModel, - deleted: q.deleted, - - tables: q.tables[:len(q.tables):len(q.tables)], - columns: q.columns[:len(q.columns):len(q.columns)], - set: q.set[:len(q.set):len(q.set)], - modelValues: modelValues, - where: q.where[:len(q.where):len(q.where)], - updWhere: q.updWhere[:len(q.updWhere):len(q.updWhere)], - joins: q.joins[:len(q.joins):len(q.joins)], - group: q.group[:len(q.group):len(q.group)], - having: q.having[:len(q.having):len(q.having)], - order: q.order[:len(q.order):len(q.order)], - onConflict: q.onConflict, - returning: q.returning[:len(q.returning):len(q.returning)], - limit: q.limit, - offset: q.offset, - selFor: q.selFor, - } - for _, with := range q.with { - copy = copy.With(with.name, with.query.Copy()) - } - return copy -} - -func (q *Query) err(err error) *Query { - if q.stickyErr == nil { - q.stickyErr = err - } - return q -} - -func (q *Query) DB(db DB) *Query { - q.db = db - for _, with := range q.with { - with.query.db = db - } - return q -} - -func (q *Query) Model(model ...interface{}) *Query { - var err error - switch l := len(model); { - case l == 0: - q.model = nil - case l == 1: - q.model, err = newTableModel(model[0]) - case l > 1: - q.model, err = newTableModel(&model) - } - if err != nil { - q = q.err(err) - } - if q.ignoreModel { - q.ignoreModel = false - } - return q -} - -func (q *Query) softDelete() bool { - if q.model != nil { - return q.model.Table().HasFlag(softDelete) - } - return false -} - -// Deleted adds `WHERE deleted_at IS NOT NULL` clause for soft deleted models. -func (q *Query) Deleted() *Query { - if q.model != nil { - if err := q.model.Table().mustSoftDelete(); err != nil { - return q.err(err) - } - } - q.deleted = true - return q -} - -// With adds subq as common table expression with the given name. -func (q *Query) With(name string, subq *Query) *Query { - q.with = append(q.with, withQuery{name, subq}) - return q -} - -// WrapWith creates new Query and adds to it current query as -// common table expression with the given name. -func (q *Query) WrapWith(name string) *Query { - wrapper := q.New() - wrapper.with = q.with - q.with = nil - wrapper = wrapper.With(name, q) - return wrapper -} - -func (q *Query) Table(tables ...string) *Query { - for _, table := range tables { - q.tables = append(q.tables, fieldAppender{table}) - } - return q -} - -func (q *Query) TableExpr(expr string, params ...interface{}) *Query { - q.tables = append(q.tables, &queryParamsAppender{expr, params}) - return q -} - -// Column adds a column to the Query quoting it according to PostgreSQL rules. Does not expand params like ?TableAlias etc. -// ColumnExpr can be used to bypass quoting restriction or for params expansion. Column name can be: -// - column_name, -// - table_alias.column_name, -// - table_alias.*. -func (q *Query) Column(columns ...string) *Query { - for _, column := range columns { - if column == "_" { - if q.columns == nil { - q.columns = make([]FormatAppender, 0) - } - continue - } - - if q.model != nil { - if j := q.model.Join(column, nil); j != nil { - continue - } - } - - q.columns = append(q.columns, fieldAppender{column}) - } - return q -} - -// ColumnExpr adds column expression to the Query. -func (q *Query) ColumnExpr(expr string, params ...interface{}) *Query { - q.columns = append(q.columns, &queryParamsAppender{expr, params}) - return q -} - -// ExcludeColumn excludes a column from the list of to be selected columns. -func (q *Query) ExcludeColumn(columns ...string) *Query { - if q.columns == nil { - for _, f := range q.model.Table().Fields { - q.columns = append(q.columns, fieldAppender{f.SQLName}) - } - } - - for _, col := range columns { - if !q.excludeColumn(col) { - return q.err(fmt.Errorf("pg: can't find column=%q", col)) - } - } - return q -} - -func (q *Query) excludeColumn(column string) bool { - for i := 0; i < len(q.columns); i++ { - app, ok := q.columns[i].(fieldAppender) - if ok && app.field == column { - q.columns = append(q.columns[:i], q.columns[i+1:]...) - return true - } - } - return false -} - -func (q *Query) getFields() ([]*Field, error) { - return q._getFields(false) -} - -func (q *Query) getDataFields() ([]*Field, error) { - return q._getFields(true) -} - -func (q *Query) _getFields(omitPKs bool) ([]*Field, error) { - table := q.model.Table() - var columns []*Field - for _, col := range q.columns { - f, ok := col.(fieldAppender) - if !ok { - continue - } - - field, err := table.GetField(f.field) - if err != nil { - return nil, err - } - - if omitPKs && field.HasFlag(PrimaryKeyFlag) { - continue - } - - columns = append(columns, field) - } - return columns, nil -} - -// Relation adds a relation to the query. Relation name can be: -// - RelationName to select all columns, -// - RelationName.column_name, -// - RelationName._ to join relation without selecting relation columns. -func (q *Query) Relation(name string, apply ...func(*Query) (*Query, error)) *Query { - var fn func(*Query) (*Query, error) - if len(apply) == 1 { - fn = apply[0] - } else if len(apply) > 1 { - panic("only one apply function is supported") - } - - join := q.model.Join(name, fn) - if join == nil { - return q.err(fmt.Errorf("%s does not have relation=%q", - q.model.Table(), name)) - } - - if fn == nil { - return q - } - - switch join.Rel.Type { - case HasOneRelation, BelongsToRelation: - q.joinAppendOn = join.AppendOn - return q.Apply(fn) - default: - q.joinAppendOn = nil - return q - } -} - -func (q *Query) Set(set string, params ...interface{}) *Query { - q.set = append(q.set, &queryParamsAppender{set, params}) - return q -} - -// Value overwrites model value for the column in INSERT and UPDATE queries. -func (q *Query) Value(column string, value string, params ...interface{}) *Query { - if !q.hasModel() { - q.err(errors.New("pg: Model(nil)")) - return q - } - - table := q.model.Table() - if _, ok := table.FieldsMap[column]; !ok { - q.err(fmt.Errorf("%s does not have column=%q", table, column)) - return q - } - - if q.modelValues == nil { - q.modelValues = make(map[string]*queryParamsAppender) - } - q.modelValues[column] = &queryParamsAppender{value, params} - return q -} - -func (q *Query) Where(condition string, params ...interface{}) *Query { - q.addWhere(&condAppender{ - sep: " AND ", - cond: condition, - params: params, - }) - return q -} - -func (q *Query) WhereOr(condition string, params ...interface{}) *Query { - q.addWhere(&condAppender{ - sep: " OR ", - cond: condition, - params: params, - }) - return q -} - -// WhereGroup encloses conditions added in the function in parentheses. -// -// q.Where("TRUE"). -// WhereGroup(func(q *orm.Query) (*orm.Query, error)) { -// q = q.WhereOr("FALSE").WhereOr("TRUE"). -// return q, nil -// }) -// -// generates -// -// WHERE TRUE AND (FALSE OR TRUE) -func (q *Query) WhereGroup(fn func(*Query) (*Query, error)) *Query { - return q.whereGroup(" AND ", fn) -} - -// WhereOrGroup encloses conditions added in the function in parentheses. -// -// q.Where("TRUE"). -// WhereOrGroup(func(q *orm.Query) (*orm.Query, error)) { -// q = q.Where("FALSE").Where("TRUE"). -// return q, nil -// }) -// -// generates -// -// WHERE TRUE OR (FALSE AND TRUE) -func (q *Query) WhereOrGroup(fn func(*Query) (*Query, error)) *Query { - return q.whereGroup(" OR ", fn) -} - -func (q *Query) whereGroup(conj string, fn func(*Query) (*Query, error)) *Query { - saved := q.where - q.where = nil - - newq, err := fn(q) - if err != nil { - q.err(err) - return q - } - - if len(newq.where) == 0 { - newq.where = saved - return newq - } - - f := &condGroupAppender{ - sep: conj, - cond: newq.where, - } - newq.where = saved - newq.addWhere(f) - - return newq -} - -// WhereIn is a shortcut for Where and pg.In to work with IN operator: -// -// WhereIn("id IN (?)", 1, 2, 3) -func (q *Query) WhereIn(where string, values ...interface{}) *Query { - return q.Where(where, types.InSlice(values)) -} - -func (q *Query) addWhere(f sepFormatAppender) { - if q.onConflictDoUpdate() { - q.updWhere = append(q.updWhere, f) - } else { - q.where = append(q.where, f) - } -} - -// WherePK adds condition based on the model primary key. -// Typically it is the same as: -// -// Where("id = ?id") -func (q *Query) WherePK() *Query { - if !q.hasModel() { - q.err(errors.New("pg: Model(nil)")) - return q - } - if q.model.Kind() == reflect.Slice { - q.err(errors.New("pg: WherePK requires struct Model")) - return q - } - if err := q.model.Table().checkPKs(); err != nil { - q.err(err) - return q - } - q.where = append(q.where, wherePKQuery{q}) - return q -} - -func (q *Query) Join(join string, params ...interface{}) *Query { - j := &joinQuery{ - join: &queryParamsAppender{join, params}, - } - q.joins = append(q.joins, j) - q.joinAppendOn = j.AppendOn - return q -} - -// JoinOn appends join condition to the last join. -func (q *Query) JoinOn(condition string, params ...interface{}) *Query { - if q.joinAppendOn == nil { - q.err(errors.New("pg: no joins to apply JoinOn")) - return q - } - q.joinAppendOn(&condAppender{ - sep: " AND ", - cond: condition, - params: params, - }) - return q -} - -func (q *Query) JoinOnOr(condition string, params ...interface{}) *Query { - if q.joinAppendOn == nil { - q.err(errors.New("pg: no joins to apply JoinOn")) - return q - } - q.joinAppendOn(&condAppender{ - sep: " OR ", - cond: condition, - params: params, - }) - return q -} - -func (q *Query) Group(columns ...string) *Query { - for _, column := range columns { - q.group = append(q.group, fieldAppender{column}) - } - return q -} - -func (q *Query) GroupExpr(group string, params ...interface{}) *Query { - q.group = append(q.group, &queryParamsAppender{group, params}) - return q -} - -func (q *Query) Having(having string, params ...interface{}) *Query { - q.having = append(q.having, &queryParamsAppender{having, params}) - return q -} - -// Order adds sort order to the Query quoting column name. Does not expand params like ?TableAlias etc. -// OrderExpr can be used to bypass quoting restriction or for params expansion. -func (q *Query) Order(orders ...string) *Query { -loop: - for _, order := range orders { - if order == "" { - continue - } - ind := strings.Index(order, " ") - if ind != -1 { - field := order[:ind] - sort := order[ind+1:] - switch internal.UpperString(sort) { - case "ASC", "DESC", "ASC NULLS FIRST", "DESC NULLS FIRST", - "ASC NULLS LAST", "DESC NULLS LAST": - q = q.OrderExpr("? ?", types.F(field), types.Q(sort)) - continue loop - } - } - - q.order = append(q.order, fieldAppender{order}) - } - return q -} - -// Order adds sort order to the Query. -func (q *Query) OrderExpr(order string, params ...interface{}) *Query { - if order != "" { - q.order = append(q.order, &queryParamsAppender{order, params}) - } - return q -} - -func (q *Query) Limit(n int) *Query { - q.limit = n - return q -} - -func (q *Query) Offset(n int) *Query { - q.offset = n - return q -} - -func (q *Query) OnConflict(s string, params ...interface{}) *Query { - q.onConflict = &queryParamsAppender{s, params} - return q -} - -func (q *Query) onConflictDoUpdate() bool { - return q.onConflict != nil && - strings.HasSuffix(internal.UpperString(q.onConflict.query), "DO UPDATE") -} - -func (q *Query) Returning(s string, params ...interface{}) *Query { - q.returning = append(q.returning, &queryParamsAppender{s, params}) - return q -} - -func (q *Query) For(s string, params ...interface{}) *Query { - q.selFor = &queryParamsAppender{s, params} - return q -} - -// Apply calls the fn passing the Query as an argument. -func (q *Query) Apply(fn func(*Query) (*Query, error)) *Query { - qq, err := fn(q) - if err != nil { - q.err(err) - return q - } - return qq -} - -// Count returns number of rows matching the query using count aggregate function. -func (q *Query) Count() (int, error) { - if q.stickyErr != nil { - return 0, q.stickyErr - } - - var count int - _, err := q.db.QueryOne( - Scan(&count), - q.countSelectQuery("count(*)"), - q.model, - ) - return count, err -} - -func (q *Query) countSelectQuery(column string) selectQuery { - return selectQuery{ - q: q, - count: column, - } -} - -// First sorts rows by primary key and selects the first row. -// It is a shortcut for: -// -// q.OrderExpr("id ASC").Limit(1) -func (q *Query) First() error { - err := q.model.Table().checkPKs() - if err != nil { - return err - } - - b := appendColumns(nil, q.model.Table().Alias, q.model.Table().PKs) - return q.OrderExpr(internal.BytesToString(b)).Limit(1).Select() -} - -// Last sorts rows by primary key and selects the last row. -// It is a shortcut for: -// -// q.OrderExpr("id DESC").Limit(1) -func (q *Query) Last() error { - err := q.model.Table().checkPKs() - if err != nil { - return err - } - - // TODO: fix for multi columns - b := appendColumns(nil, q.model.Table().Alias, q.model.Table().PKs) - b = append(b, " DESC"...) - return q.OrderExpr(internal.BytesToString(b)).Limit(1).Select() -} - -// Select selects the model. -func (q *Query) Select(values ...interface{}) error { - if q.stickyErr != nil { - return q.stickyErr - } - - model, err := q.newModel(values...) - if err != nil { - return err - } - - q, err = model.BeforeSelectQuery(q.db, q) - if err != nil { - return err - } - - res, err := q.query(model, selectQuery{q: q}) - if err != nil { - return err - } - - if res.RowsReturned() > 0 { - if q.model != nil { - if err := q.selectJoins(q.model.GetJoins()); err != nil { - return err - } - } - if err := model.AfterSelect(q.db); err != nil { - return err - } - } - - return nil -} - -func (q *Query) newModel(values ...interface{}) (Model, error) { - if len(values) > 0 { - return NewModel(values...) - } - return q.model, nil -} - -func (q *Query) query(model Model, query interface{}) (Result, error) { - if _, ok := model.(useQueryOne); ok { - return q.db.QueryOne(model, query, q.model) - } - return q.db.Query(model, query, q.model) -} - -// SelectAndCount runs Select and Count in two goroutines, -// waits for them to finish and returns the result. If query limit is -1 -// it does not select any data and only counts the results. -func (q *Query) SelectAndCount(values ...interface{}) (count int, firstErr error) { - if q.stickyErr != nil { - return 0, q.stickyErr - } - - var wg sync.WaitGroup - var mu sync.Mutex - - if q.limit >= 0 { - wg.Add(1) - go func() { - defer wg.Done() - err := q.Select(values...) - if err != nil { - mu.Lock() - if firstErr == nil { - firstErr = err - } - mu.Unlock() - } - }() - } - - wg.Add(1) - go func() { - defer wg.Done() - var err error - count, err = q.Count() - if err != nil { - mu.Lock() - if firstErr == nil { - firstErr = err - } - mu.Unlock() - } - }() - - wg.Wait() - return count, firstErr -} - -// SelectAndCountEstimate runs Select and CountEstimate in two goroutines, -// waits for them to finish and returns the result. If query limit is -1 -// it does not select any data and only counts the results. -func (q *Query) SelectAndCountEstimate(threshold int, values ...interface{}) (count int, firstErr error) { - if q.stickyErr != nil { - return 0, q.stickyErr - } - - var wg sync.WaitGroup - var mu sync.Mutex - - if q.limit >= 0 { - wg.Add(1) - go func() { - defer wg.Done() - err := q.Select(values...) - if err != nil { - mu.Lock() - if firstErr == nil { - firstErr = err - } - mu.Unlock() - } - }() - } - - wg.Add(1) - go func() { - defer wg.Done() - var err error - count, err = q.CountEstimate(threshold) - if err != nil { - mu.Lock() - if firstErr == nil { - firstErr = err - } - mu.Unlock() - } - }() - - wg.Wait() - return count, firstErr -} - -// ForEach calls the function for each row returned by the query -// without loading all rows into the memory. -// Function accepts a struct, pointer to a struct, orm.Model, -// or values for columns in a row. Function must return an error. -func (q *Query) ForEach(fn interface{}) error { - m := newFuncModel(fn) - return q.Select(m) -} - -func (q *Query) forEachHasOneJoin(fn func(*join)) { - if q.model == nil { - return - } - q._forEachHasOneJoin(fn, q.model.GetJoins()) -} - -func (q *Query) _forEachHasOneJoin(fn func(*join), joins []join) { - for i := range joins { - j := &joins[i] - switch j.Rel.Type { - case HasOneRelation, BelongsToRelation: - fn(j) - q._forEachHasOneJoin(fn, j.JoinModel.GetJoins()) - } - } -} - -func (q *Query) selectJoins(joins []join) error { - var err error - for i := range joins { - j := &joins[i] - if j.Rel.Type == HasOneRelation || j.Rel.Type == BelongsToRelation { - err = q.selectJoins(j.JoinModel.GetJoins()) - } else { - err = j.Select(q.New()) - } - if err != nil { - return err - } - } - return nil -} - -// Insert inserts the model. -func (q *Query) Insert(values ...interface{}) (Result, error) { - if q.stickyErr != nil { - return nil, q.stickyErr - } - - model, err := q.newModel(values...) - if err != nil { - return nil, err - } - - if q.model != nil && q.model.Table().HasFlag(BeforeInsertHookFlag) { - err = q.model.BeforeInsert(q.db) - if err != nil { - return nil, err - } - } - - query := &insertQuery{q: q} - res, err := q.returningQuery(model, query) - if err != nil { - return nil, err - } - - if q.model != nil { - err = q.model.AfterInsert(q.db) - if err != nil { - return nil, err - } - } - - return res, nil -} - -// SelectOrInsert selects the model inserting one if it does not exist. -// It returns true when model was inserted. -func (q *Query) SelectOrInsert(values ...interface{}) (inserted bool, _ error) { - if q.stickyErr != nil { - return false, q.stickyErr - } - - insertq := q - if len(insertq.columns) > 0 { - insertq = insertq.Copy() - insertq.columns = nil - } - - var insertErr error - for i := 0; i < 5; i++ { - if i >= 2 { - time.Sleep(internal.RetryBackoff(i-2, 250*time.Millisecond, 5*time.Second)) - } - - err := q.Select(values...) - if err == nil { - return false, nil - } - if err != internal.ErrNoRows { - return false, err - } - - res, err := insertq.Insert(values...) - if err != nil { - insertErr = err - if err == internal.ErrNoRows { - continue - } - if pgErr, ok := err.(internal.PGError); ok { - if pgErr.IntegrityViolation() { - continue - } - if pgErr.Field('C') == "55000" { - // Retry on "#55000 attempted to delete invisible tuple". - continue - } - } - return false, err - } - if res.RowsAffected() == 1 { - return true, nil - } - } - - err := fmt.Errorf( - "pg: SelectOrInsert: select returns no rows (insert fails with err=%q)", - insertErr, - ) - return false, err -} - -// Update updates the model. -func (q *Query) Update(scan ...interface{}) (Result, error) { - return q.update(scan, false) -} - -// Update updates the model omitting null columns. -func (q *Query) UpdateNotNull(scan ...interface{}) (Result, error) { - return q.update(scan, true) -} - -func (q *Query) update(scan []interface{}, omitZero bool) (Result, error) { - if q.stickyErr != nil { - return nil, q.stickyErr - } - - model, err := q.newModel(scan...) - if err != nil { - return nil, err - } - - if q.model != nil { - err = q.model.BeforeUpdate(q.db) - if err != nil { - return nil, err - } - } - - query := updateQuery{q: q, omitZero: omitZero} - res, err := q.returningQuery(model, query) - if err != nil { - return nil, err - } - - if q.model != nil { - err = q.model.AfterUpdate(q.db) - if err != nil { - return nil, err - } - } - - return res, nil -} - -func (q *Query) returningQuery(model Model, query interface{}) (Result, error) { - if len(q.returning) == 0 { - return q.db.Query(model, query, q.model) - } - if _, ok := model.(useQueryOne); ok { - return q.db.QueryOne(model, query, q.model) - } - return q.db.Query(model, query, q.model) -} - -// Delete deletes the model. When model has deleted_at column the row -// is soft deleted instead. -func (q *Query) Delete(values ...interface{}) (Result, error) { - if q.softDelete() { - q.model.setDeletedAt() - columns := q.columns - q.columns = nil - res, err := q.Column("deleted_at").Update(values...) - q.columns = columns - return res, err - } - return q.ForceDelete(values...) -} - -// Delete forces delete of the model with deleted_at column. -func (q *Query) ForceDelete(values ...interface{}) (Result, error) { - if q.stickyErr != nil { - return nil, q.stickyErr - } - if q.model == nil { - return nil, errors.New("pg: Model(nil)") - } - q.deleted = true - - model, err := q.newModel(values...) - if err != nil { - return nil, err - } - - if q.model != nil { - err = q.model.BeforeDelete(q.db) - if err != nil { - return nil, err - } - } - - res, err := q.returningQuery(model, deleteQuery{q}) - if err != nil { - return nil, err - } - - if q.model != nil { - err = q.model.AfterDelete(q.db) - if err != nil { - return nil, err - } - } - - return res, nil -} - -// Exec is an alias for DB.Exec. -func (q *Query) Exec(query interface{}, params ...interface{}) (Result, error) { - params = append(params, q.model) - return q.db.Exec(query, params...) -} - -// ExecOne is an alias for DB.ExecOne. -func (q *Query) ExecOne(query interface{}, params ...interface{}) (Result, error) { - params = append(params, q.model) - return q.db.ExecOne(query, params...) -} - -// Query is an alias for DB.Query. -func (q *Query) Query(model, query interface{}, params ...interface{}) (Result, error) { - params = append(params, q.model) - return q.db.Query(model, query, params...) -} - -// QueryOne is an alias for DB.QueryOne. -func (q *Query) QueryOne(model, query interface{}, params ...interface{}) (Result, error) { - params = append(params, q.model) - return q.db.QueryOne(model, query, params...) -} - -// CopyFrom is an alias from DB.CopyFrom. -func (q *Query) CopyFrom(r io.Reader, query interface{}, params ...interface{}) (Result, error) { - params = append(params, q.model) - return q.db.CopyFrom(r, query, params...) -} - -// CopyTo is an alias from DB.CopyTo. -func (q *Query) CopyTo(w io.Writer, query interface{}, params ...interface{}) (Result, error) { - params = append(params, q.model) - return q.db.CopyTo(w, query, params...) -} - -func (q *Query) FormatQuery(b []byte, query string, params ...interface{}) []byte { - params = append(params, q.model) - if q.db != nil { - return q.db.FormatQuery(b, query, params...) - } - return formatter.Append(b, query, params...) -} - -// Exists returns true or false depending if there are any rows matching the query. -func (q *Query) Exists() (bool, error) { - cp := q.Copy() // copy to not change original query - cp.columns = []FormatAppender{fieldAppender{"1"}} - cp.order = nil - cp.limit = 1 - res, err := q.db.Exec(selectQuery{q: q}) - if err != nil { - return false, err - } - return res.RowsAffected() > 0, nil -} - -func (q *Query) hasModel() bool { - return !q.ignoreModel && q.model != nil -} - -func (q *Query) hasTables() bool { - return q.hasModel() || len(q.tables) > 0 -} - -func (q *Query) appendTableName(b []byte) []byte { - return q.FormatQuery(b, string(q.model.Table().Name)) -} - -func (q *Query) appendTableNameWithAlias(b []byte) []byte { - b = q.appendTableName(b) - b = append(b, " AS "...) - b = append(b, q.model.Table().Alias...) - return b -} - -func (q *Query) appendFirstTable(b []byte) []byte { - if q.hasModel() { - return q.appendTableName(b) - } - if len(q.tables) > 0 { - b = q.tables[0].AppendFormat(b, q) - } - return b -} - -func (q *Query) appendFirstTableWithAlias(b []byte) []byte { - if q.hasModel() { - return q.appendTableNameWithAlias(b) - } - if len(q.tables) > 0 { - b = q.tables[0].AppendFormat(b, q) - } - return b -} - -func (q *Query) hasMultiTables() bool { - if q.hasModel() { - return len(q.tables) > 0 - } - return len(q.tables) > 1 -} - -func (q *Query) appendOtherTables(b []byte) []byte { - tables := q.tables - if !q.hasModel() { - tables = tables[1:] - } - for i, f := range tables { - if i > 0 { - b = append(b, ", "...) - } - b = f.AppendFormat(b, q) - } - return b -} - -func (q *Query) appendColumns(b []byte) []byte { - for i, f := range q.columns { - if i > 0 { - b = append(b, ", "...) - } - b = f.AppendFormat(b, q) - } - return b -} - -func (q *Query) hasWhere() bool { - return len(q.where) > 0 || q.softDelete() -} - -func (q *Query) mustAppendWhere(b []byte) ([]byte, error) { - if q.hasWhere() { - b = q.appendWhere(b) - return b, nil - } - - if q.model == nil { - return nil, errors.New("pg: Model(nil)") - } - err := errors.New( - "pg: Update and Delete queries require Where clause (try WherePK)") - return nil, err -} - -func (q *Query) appendWhere(b []byte) []byte { - b = q._appendWhere(b, q.where) - if q.softDelete() { - if len(q.where) > 0 { - b = append(b, " AND "...) - } - b = append(b, q.model.Table().Alias...) - b = q.appendSoftDelete(b) - } - return b -} - -func (q *Query) appendSoftDelete(b []byte) []byte { - if q.deleted { - b = append(b, ".deleted_at IS NOT NULL"...) - } else { - b = append(b, ".deleted_at IS NULL"...) - } - return b -} - -func (q *Query) appendUpdWhere(b []byte) []byte { - return q._appendWhere(b, q.updWhere) -} - -func (q *Query) _appendWhere(b []byte, where []sepFormatAppender) []byte { - for i, f := range where { - if i > 0 { - b = f.AppendSep(b) - } - b = f.AppendFormat(b, q) - } - return b -} - -func (q *Query) appendSet(b []byte) []byte { - b = append(b, " SET "...) - for i, f := range q.set { - if i > 0 { - b = append(b, ", "...) - } - b = f.AppendFormat(b, q) - } - return b -} - -func (q *Query) appendReturning(b []byte) []byte { - b = append(b, " RETURNING "...) - for i, f := range q.returning { - if i > 0 { - b = append(b, ", "...) - } - b = f.AppendFormat(b, q) - } - return b -} - -func (q *Query) appendWith(b []byte) ([]byte, error) { - var err error - b = append(b, "WITH "...) - for i, with := range q.with { - if i > 0 { - b = append(b, ", "...) - } - b = types.AppendField(b, with.name, 1) - b = append(b, " AS ("...) - - b, err = selectQuery{q: with.query}.AppendQuery(b) - if err != nil { - return nil, err - } - - b = append(b, ')') - } - b = append(b, ' ') - return b, nil -} - -func (q *Query) isSliceModel() bool { - if !q.hasModel() { - return false - } - return q.model.Kind() == reflect.Slice && q.model.Value().Len() > 0 -} - -//------------------------------------------------------------------------------ - -type wherePKQuery struct { - *Query -} - -func (wherePKQuery) AppendSep(b []byte) []byte { - return append(b, " AND "...) -} - -func (q wherePKQuery) AppendFormat(b []byte, f QueryFormatter) []byte { - table := q.model.Table() - value := q.model.Value() - return appendColumnAndValue(b, value, table.Alias, table.PKs) -} - -func appendColumnAndValue(b []byte, v reflect.Value, alias types.Q, fields []*Field) []byte { - for i, f := range fields { - if i > 0 { - b = append(b, " AND "...) - } - b = append(b, alias...) - b = append(b, '.') - b = append(b, f.Column...) - b = append(b, " = "...) - b = f.AppendValue(b, v, 1) - } - return b -} - -func appendColumnAndSliceValue(b []byte, slice reflect.Value, alias types.Q, fields []*Field) []byte { - if slice.Len() == 0 { - return append(b, "1 = 2"...) - } - - if len(fields) > 1 { - b = append(b, '(') - } - b = appendColumns(b, alias, fields) - if len(fields) > 1 { - b = append(b, ')') - } - - b = append(b, " IN ("...) - - for i := 0; i < slice.Len(); i++ { - if i > 0 { - b = append(b, ", "...) - } - - el := indirect(slice.Index(i)) - - if len(fields) > 1 { - b = append(b, '(') - } - for i, f := range fields { - if i > 0 { - b = append(b, ", "...) - } - b = f.AppendValue(b, el, 1) - } - if len(fields) > 1 { - b = append(b, ')') - } - } - b = append(b, ')') - - return b -} diff --git a/vendor/github.com/go-pg/pg/orm/relation.go b/vendor/github.com/go-pg/pg/orm/relation.go deleted file mode 100644 index 720e6ad7e..000000000 --- a/vendor/github.com/go-pg/pg/orm/relation.go +++ /dev/null @@ -1,32 +0,0 @@ -package orm - -import ( - "fmt" - - "github.com/go-pg/pg/types" -) - -const ( - HasOneRelation = 1 << iota - BelongsToRelation - HasManyRelation - Many2ManyRelation -) - -type Relation struct { - Type int - Field *Field - JoinTable *Table - FKs []*Field - Polymorphic *Field - FKValues []*Field - - M2MTableName types.Q - M2MTableAlias types.Q - BaseFKs []string - JoinFKs []string -} - -func (r *Relation) String() string { - return fmt.Sprintf("relation=%s", r.Field.GoName) -} diff --git a/vendor/github.com/go-pg/pg/orm/result.go b/vendor/github.com/go-pg/pg/orm/result.go deleted file mode 100644 index 6f81245ce..000000000 --- a/vendor/github.com/go-pg/pg/orm/result.go +++ /dev/null @@ -1,14 +0,0 @@ -package orm - -// A Result summarizes an executed SQL command. -type Result interface { - Model() Model - - // RowsAffected returns the number of rows affected by SELECT, INSERT, UPDATE, - // or DELETE queries. It returns -1 if query can't possibly affect any rows, - // e.g. in case of CREATE or SHOW queries. - RowsAffected() int - - // RowsReturned returns the number of rows returned by the query. - RowsReturned() int -} diff --git a/vendor/github.com/go-pg/pg/orm/select.go b/vendor/github.com/go-pg/pg/orm/select.go deleted file mode 100644 index faa15e3f2..000000000 --- a/vendor/github.com/go-pg/pg/orm/select.go +++ /dev/null @@ -1,201 +0,0 @@ -package orm - -import ( - "strconv" - "strings" -) - -func Select(db DB, model interface{}) error { - return NewQuery(db, model).WherePK().Select() -} - -type selectQuery struct { - q *Query - - count string -} - -var _ QueryAppender = (*selectQuery)(nil) - -func (q selectQuery) Copy() QueryAppender { - return selectQuery{ - q: q.q.Copy(), - count: q.count, - } -} - -func (q selectQuery) Query() *Query { - return q.q -} - -func (q selectQuery) AppendQuery(b []byte) ([]byte, error) { - if q.q.stickyErr != nil { - return nil, q.q.stickyErr - } - - var err error - - cteCount := q.count != "" && (len(q.q.group) > 0 || q.isDistinct()) - if cteCount { - b = append(b, `WITH "_count_wrapper" AS (`...) - } - - if len(q.q.with) > 0 { - b, err = q.q.appendWith(b) - if err != nil { - return nil, err - } - } - - b = append(b, "SELECT "...) - if q.count != "" && !cteCount { - b = append(b, q.count...) - } else { - b = q.appendColumns(b) - } - - if q.q.hasTables() { - b = append(b, " FROM "...) - b = q.appendTables(b) - } - - q.q.forEachHasOneJoin(func(j *join) { - b = append(b, ' ') - b = j.appendHasOneJoin(q.q, b) - }) - if len(q.q.joins) > 0 { - for _, j := range q.q.joins { - b = append(b, ' ') - b = j.join.AppendFormat(b, q.q) - if len(j.on) > 0 { - b = append(b, " ON "...) - } - for i, on := range j.on { - if i > 0 { - b = on.AppendSep(b) - } - b = on.AppendFormat(b, q.q) - } - } - } - - if q.q.hasWhere() { - b = append(b, " WHERE "...) - b = q.q.appendWhere(b) - } - - if len(q.q.group) > 0 { - b = append(b, " GROUP BY "...) - for i, f := range q.q.group { - if i > 0 { - b = append(b, ", "...) - } - b = f.AppendFormat(b, q.q) - } - } - - if len(q.q.having) > 0 { - b = append(b, " HAVING "...) - for i, f := range q.q.having { - if i > 0 { - b = append(b, " AND "...) - } - b = append(b, '(') - b = f.AppendFormat(b, q.q) - b = append(b, ')') - } - } - - if q.count == "" { - if len(q.q.order) > 0 { - b = append(b, " ORDER BY "...) - for i, f := range q.q.order { - if i > 0 { - b = append(b, ", "...) - } - b = f.AppendFormat(b, q.q) - } - } - - if q.q.limit != 0 { - b = append(b, " LIMIT "...) - b = strconv.AppendInt(b, int64(q.q.limit), 10) - } - - if q.q.offset != 0 { - b = append(b, " OFFSET "...) - b = strconv.AppendInt(b, int64(q.q.offset), 10) - } - - if q.q.selFor != nil { - b = append(b, " FOR "...) - b = q.q.selFor.AppendFormat(b, q.q) - } - } else if cteCount { - b = append(b, `) SELECT `...) - b = append(b, q.count...) - b = append(b, ` FROM "_count_wrapper"`...) - } - - return b, nil -} - -func (q selectQuery) appendColumns(b []byte) []byte { - start := len(b) - - if q.q.columns != nil { - b = q.q.appendColumns(b) - } else if q.q.hasModel() { - table := q.q.model.Table() - b = appendColumns(b, table.Alias, table.Fields) - } else { - b = append(b, '*') - } - - q.q.forEachHasOneJoin(func(j *join) { - if len(b) != start { - b = append(b, ", "...) - start = len(b) - } - - b = j.appendHasOneColumns(b) - - if len(b) == start { - b = b[:len(b)-2] - } - }) - - return b -} - -func (q selectQuery) isDistinct() bool { - for _, column := range q.q.columns { - column, ok := column.(*queryParamsAppender) - if ok { - if strings.Contains(column.query, "DISTINCT") || - strings.Contains(column.query, "distinct") { - return true - } - } - } - return false -} - -func (q selectQuery) appendTables(b []byte) []byte { - if q.q.hasModel() { - b = q.q.FormatQuery(b, string(q.q.model.Table().NameForSelects)) - b = append(b, " AS "...) - b = append(b, q.q.model.Table().Alias...) - - if len(q.q.tables) > 0 { - b = append(b, ", "...) - } - } - for i, f := range q.q.tables { - if i > 0 { - b = append(b, ", "...) - } - b = f.AppendFormat(b, q.q) - } - return b -} diff --git a/vendor/github.com/go-pg/pg/orm/table.go b/vendor/github.com/go-pg/pg/orm/table.go deleted file mode 100644 index cef782509..000000000 --- a/vendor/github.com/go-pg/pg/orm/table.go +++ /dev/null @@ -1,891 +0,0 @@ -package orm - -import ( - "bytes" - "database/sql" - "encoding/json" - "fmt" - "net" - "reflect" - "strings" - "time" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/types" -) - -const ( - AfterQueryHookFlag = uint16(1) << iota - BeforeSelectQueryHookFlag - AfterSelectHookFlag - BeforeInsertHookFlag - AfterInsertHookFlag - BeforeUpdateHookFlag - AfterUpdateHookFlag - BeforeDeleteHookFlag - AfterDeleteHookFlag - discardUnknownColumns - softDelete -) - -var timeType = reflect.TypeOf((*time.Time)(nil)).Elem() -var ipType = reflect.TypeOf((*net.IP)(nil)).Elem() -var ipNetType = reflect.TypeOf((*net.IPNet)(nil)).Elem() -var scannerType = reflect.TypeOf((*sql.Scanner)(nil)).Elem() -var nullBoolType = reflect.TypeOf((*sql.NullBool)(nil)).Elem() -var nullFloatType = reflect.TypeOf((*sql.NullFloat64)(nil)).Elem() -var nullIntType = reflect.TypeOf((*sql.NullInt64)(nil)).Elem() -var nullStringType = reflect.TypeOf((*sql.NullString)(nil)).Elem() - -// Table represents a SQL table created from Go struct. -type Table struct { - Type reflect.Type - zeroStruct reflect.Value - - TypeName string - Name types.Q - NameForSelects types.Q - Alias types.Q - ModelName string - - allFields []*Field // read only - skippedFields []*Field - - Fields []*Field // PKs + DataFields - PKs []*Field - DataFields []*Field - FieldsMap map[string]*Field - - Methods map[string]*Method - Relations map[string]*Relation - Unique map[string][]*Field - - flags uint16 -} - -func (t *Table) setName(name types.Q) { - t.Name = name - t.NameForSelects = name -} - -func newTable(typ reflect.Type) *Table { - t := new(Table) - t.Type = typ - t.zeroStruct = reflect.New(t.Type).Elem() - t.TypeName = internal.ToExported(t.Type.Name()) - t.ModelName = internal.Underscore(t.Type.Name()) - tableName := quoteTableName(tableNameInflector(t.ModelName)) - t.setName(types.Q(types.AppendField(nil, tableName, 1))) - t.Alias = types.Q(types.AppendField(nil, t.ModelName, 1)) - - typ = reflect.PtrTo(t.Type) - if typ.Implements(afterQueryHookType) { - t.SetFlag(AfterQueryHookFlag) - } - if typ.Implements(beforeSelectQueryHookType) { - t.SetFlag(BeforeSelectQueryHookFlag) - } - if typ.Implements(afterSelectHookType) { - t.SetFlag(AfterSelectHookFlag) - } - if typ.Implements(beforeInsertHookType) { - t.SetFlag(BeforeInsertHookFlag) - } - if typ.Implements(afterInsertHookType) { - t.SetFlag(AfterInsertHookFlag) - } - if typ.Implements(beforeUpdateHookType) { - t.SetFlag(BeforeUpdateHookFlag) - } - if typ.Implements(afterUpdateHookType) { - t.SetFlag(AfterUpdateHookFlag) - } - if typ.Implements(beforeDeleteHookType) { - t.SetFlag(BeforeDeleteHookFlag) - } - if typ.Implements(afterDeleteHookType) { - t.SetFlag(AfterDeleteHookFlag) - } - - t.initFields() - t.initMethods() - - return t -} - -func (t *Table) String() string { - return "model=" + t.TypeName -} - -func (t *Table) SetFlag(flag uint16) { - t.flags |= flag -} - -func (t *Table) HasFlag(flag uint16) bool { - if t == nil { - return false - } - return t.flags&flag != 0 -} - -func (t *Table) HasField(field string) bool { - _, err := t.GetField(field) - return err == nil -} - -func (t *Table) checkPKs() error { - if len(t.PKs) == 0 { - return fmt.Errorf("pg: %s does not have primary keys", t) - } - return nil -} - -func (t *Table) mustSoftDelete() error { - if !t.HasFlag(softDelete) { - return fmt.Errorf("pg: %s does not support soft deletes", t) - } - return nil -} - -func (t *Table) AddField(field *Field) { - t.allFields = append(t.allFields, field) - t.Fields = append(t.Fields, field) - if field.HasFlag(PrimaryKeyFlag) { - t.PKs = append(t.PKs, field) - } else { - t.DataFields = append(t.DataFields, field) - } - t.FieldsMap[field.SQLName] = field -} - -func (t *Table) RemoveField(field *Field) { - t.Fields = removeField(t.Fields, field) - if field.HasFlag(PrimaryKeyFlag) { - t.PKs = removeField(t.PKs, field) - } else { - t.DataFields = removeField(t.DataFields, field) - } - delete(t.FieldsMap, field.SQLName) -} - -func removeField(fields []*Field, field *Field) []*Field { - for i, f := range fields { - if f == field { - fields = append(fields[:i], fields[i+1:]...) - } - } - return fields -} - -func (t *Table) GetField(fieldName string) (*Field, error) { - field, ok := t.FieldsMap[fieldName] - if !ok { - return nil, fmt.Errorf("can't find column=%s in %s", fieldName, t) - } - return field, nil -} - -func (t *Table) AppendParam(b []byte, strct reflect.Value, name string) ([]byte, bool) { - field, ok := t.FieldsMap[name] - if ok { - b = field.AppendValue(b, strct, 1) - return b, true - } - - method, ok := t.Methods[name] - if ok { - b = method.AppendValue(b, strct.Addr(), 1) - return b, true - } - - return b, false -} - -func (t *Table) initFields() { - t.Fields = make([]*Field, 0, t.Type.NumField()) - t.FieldsMap = make(map[string]*Field, t.Type.NumField()) - t.addFields(t.Type, nil) -} - -func (t *Table) addFields(typ reflect.Type, baseIndex []int) { - for i := 0; i < typ.NumField(); i++ { - f := typ.Field(i) - - // Make a copy so slice is not shared between fields. - index := make([]int, len(baseIndex)) - copy(index, baseIndex) - - if f.Anonymous { - sqlTag := f.Tag.Get("sql") - if sqlTag == "-" { - continue - } - - fieldType := indirectType(f.Type) - t.addFields(fieldType, append(index, f.Index...)) - - pgTag := parseTag(f.Tag.Get("pg")) - _, inherit := pgTag.Options["inherit"] - _, override := pgTag.Options["override"] - if inherit || override { - embeddedTable := newTable(fieldType) - t.TypeName = embeddedTable.TypeName - t.Name = embeddedTable.Name - t.NameForSelects = embeddedTable.NameForSelects - t.Alias = embeddedTable.Alias - t.ModelName = embeddedTable.ModelName - } - - continue - } - - field := t.newField(f, index) - if field != nil { - t.AddField(field) - } - } -} - -func (t *Table) newField(f reflect.StructField, index []int) *Field { - sqlTag := parseTag(f.Tag.Get("sql")) - - switch f.Name { - case "tableName", "TableName": - if len(index) > 0 { - return nil - } - - if sqlTag.Name != "" { - s, _ := unquoteTagValue(sqlTag.Name) - t.setName(types.Q(quoteTableName(s))) - } - - if v, ok := sqlTag.Options["select"]; ok { - v, _ = unquoteTagValue(v) - t.NameForSelects = types.Q(quoteTableName(v)) - } - - if v, ok := sqlTag.Options["alias"]; ok { - v, _ = unquoteTagValue(v) - t.Alias = types.Q(quoteTableName(v)) - } - - pgTag := parseTag(f.Tag.Get("pg")) - if _, ok := pgTag.Options["discard_unknown_columns"]; ok { - t.SetFlag(discardUnknownColumns) - } - - return nil - } - - if f.PkgPath != "" { - return nil - } - - skip := sqlTag.Name == "-" - if skip || sqlTag.Name == "" { - sqlTag.Name = internal.Underscore(f.Name) - } - - index = append(index, f.Index...) - if field, ok := t.FieldsMap[sqlTag.Name]; ok { - if indexEqual(field.Index, index) { - return field - } - t.RemoveField(field) - } - - field := &Field{ - Field: f, - Type: indirectType(f.Type), - - GoName: f.Name, - SQLName: sqlTag.Name, - Column: types.Q(types.AppendField(nil, sqlTag.Name, 1)), - - Index: index, - } - - if _, ok := sqlTag.Options["notnull"]; ok { - field.SetFlag(NotNullFlag) - } - if v, ok := sqlTag.Options["unique"]; ok { - if v == "" { - field.SetFlag(UniqueFlag) - } else { - if t.Unique == nil { - t.Unique = make(map[string][]*Field) - } - t.Unique[v] = append(t.Unique[v], field) - } - } - if v, ok := sqlTag.Options["default"]; ok { - v, ok = unquoteTagValue(v) - if ok { - field.Default = types.Q(types.AppendString(nil, v, 1)) - } else { - field.Default = types.Q(v) - } - } - - if _, ok := sqlTag.Options["pk"]; ok { - field.SetFlag(PrimaryKeyFlag) - } else if strings.HasSuffix(field.SQLName, "_id") || - strings.HasSuffix(field.SQLName, "_uuid") { - field.SetFlag(ForeignKeyFlag) - } else if strings.HasPrefix(field.SQLName, "fk_") { - field.SetFlag(ForeignKeyFlag) - } else if len(t.PKs) == 0 { - if field.SQLName == "id" || - field.SQLName == "uuid" || - field.SQLName == "pk_"+t.ModelName { - field.SetFlag(PrimaryKeyFlag) - } - } - - pgTag := parseTag(f.Tag.Get("pg")) - - if _, ok := sqlTag.Options["array"]; ok { - field.SetFlag(ArrayFlag) - } else if _, ok := pgTag.Options["array"]; ok { - field.SetFlag(ArrayFlag) - } - - field.SQLType = fieldSQLType(field, pgTag, sqlTag) - if strings.HasSuffix(field.SQLType, "[]") { - field.SetFlag(ArrayFlag) - } - - if v, ok := sqlTag.Options["on_delete"]; ok { - field.OnDelete = v - } - - if v, ok := sqlTag.Options["composite"]; ok { - field.SQLType = v - field.append = compositeAppender(f.Type) - field.scan = compositeScanner(f.Type) - } else if _, ok := pgTag.Options["json_use_number"]; ok { - field.append = types.Appender(f.Type) - field.scan = scanJSONValue - } else if field.HasFlag(ArrayFlag) { - field.append = types.ArrayAppender(f.Type) - field.scan = types.ArrayScanner(f.Type) - } else if _, ok := sqlTag.Options["hstore"]; ok { - field.append = types.HstoreAppender(f.Type) - field.scan = types.HstoreScanner(f.Type) - } else if _, ok := pgTag.Options["hstore"]; ok { - field.append = types.HstoreAppender(f.Type) - field.scan = types.HstoreScanner(f.Type) - } else { - field.append = types.Appender(f.Type) - field.scan = types.Scanner(f.Type) - } - field.isZero = isZeroFunc(f.Type) - - if skip { - t.skippedFields = append(t.skippedFields, field) - t.FieldsMap[field.SQLName] = field - return nil - } - - switch field.SQLName { - case "deleted_at": - if _, ok := pgTag.Options["soft_delete"]; ok && field.Type == timeType { - t.SetFlag(softDelete) - } - } - - return field -} - -func (t *Table) initMethods() { - t.Methods = make(map[string]*Method) - typ := reflect.PtrTo(t.Type) - for i := 0; i < typ.NumMethod(); i++ { - m := typ.Method(i) - if m.PkgPath != "" { - continue - } - if m.Type.NumIn() > 1 { - continue - } - if m.Type.NumOut() != 1 { - continue - } - - retType := m.Type.Out(0) - t.Methods[m.Name] = &Method{ - Index: m.Index, - - appender: types.Appender(retType), - } - } -} - -func (t *Table) init() { - t.initRelations() - t.initInlines() -} - -func (t *Table) initRelations() { - for i := 0; i < len(t.Fields); { - f := t.Fields[i] - if t.tryRelation(f) { - t.Fields = removeField(t.Fields, f) - t.DataFields = removeField(t.DataFields, f) - } else { - i++ - } - } -} - -func (t *Table) initInlines() { - for _, f := range t.skippedFields { - if f.Type.Kind() == reflect.Struct { - joinTable := _tables.get(f.Type, true) - t.inlineFields(f, joinTable.allFields) - } - } -} - -func (t *Table) tryRelation(field *Field) bool { - if isColumn(field.Type) { - return false - } - - switch field.Type.Kind() { - case reflect.Slice: - return t.tryRelationSlice(field) - case reflect.Struct: - return t.tryRelationStruct(field) - } - return false -} - -func (t *Table) tryRelationSlice(field *Field) bool { - elemType := indirectType(field.Type.Elem()) - if elemType.Kind() != reflect.Struct { - return false - } - - pgTag := parseTag(field.Field.Tag.Get("pg")) - joinTable := _tables.get(elemType, true) - - fk, fkOK := pgTag.Options["fk"] - if fkOK { - if fk == "-" { - return false - } - fk = tryUnderscorePrefix(fk) - } - - if m2mTableName, _ := pgTag.Options["many2many"]; m2mTableName != "" { - m2mTable := _tables.getByName(m2mTableName) - - var m2mTableAlias types.Q - if m2mTable != nil { - m2mTableAlias = m2mTable.Alias - } else if ind := strings.IndexByte(m2mTableName, '.'); ind >= 0 { - m2mTableAlias = types.Q(m2mTableName[ind+1:]) - } else { - m2mTableAlias = types.Q(m2mTableName) - } - - var fks []string - if !fkOK { - fk = t.ModelName + "_" - } - if m2mTable != nil { - keys := foreignKeys(t, m2mTable, fk, fkOK) - if len(keys) == 0 { - return false - } - for _, fk := range keys { - fks = append(fks, fk.SQLName) - } - } else { - if fkOK && len(t.PKs) == 1 { - fks = append(fks, fk) - } else { - for _, pk := range t.PKs { - fks = append(fks, fk+pk.SQLName) - } - } - } - - joinFK, joinFKOK := pgTag.Options["joinFK"] - if joinFKOK { - joinFK = tryUnderscorePrefix(joinFK) - } else { - joinFK = joinTable.ModelName + "_" - } - var joinFKs []string - if m2mTable != nil { - keys := foreignKeys(joinTable, m2mTable, joinFK, joinFKOK) - if len(keys) == 0 { - return false - } - for _, fk := range keys { - joinFKs = append(joinFKs, fk.SQLName) - } - } else { - if joinFKOK && len(joinTable.PKs) == 1 { - joinFKs = append(joinFKs, joinFK) - } else { - for _, pk := range joinTable.PKs { - joinFKs = append(joinFKs, joinFK+pk.SQLName) - } - } - } - - t.addRelation(&Relation{ - Type: Many2ManyRelation, - Field: field, - JoinTable: joinTable, - M2MTableName: types.Q(m2mTableName), - M2MTableAlias: m2mTableAlias, - BaseFKs: fks, - JoinFKs: joinFKs, - }) - return true - } - - s, polymorphic := pgTag.Options["polymorphic"] - var typeField *Field - if polymorphic { - fk = tryUnderscorePrefix(s) - - typeField = joinTable.getField(fk + "type") - if typeField == nil { - return false - } - } else if !fkOK { - fk = t.ModelName + "_" - } - - fks := foreignKeys(t, joinTable, fk, fkOK || polymorphic) - if len(fks) == 0 { - return false - } - - var fkValues []*Field - fkValue, ok := pgTag.Options["fk_value"] - if ok { - if len(fks) > 1 { - panic(fmt.Errorf("got fk_value, but there are %d fks", len(fks))) - } - - f := t.getField(fkValue) - if f == nil { - panic(fmt.Errorf("fk_value=%q not found in %s", fkValue, t)) - } - fkValues = append(fkValues, f) - } else { - fkValues = t.PKs - } - - if len(fks) > 0 { - t.addRelation(&Relation{ - Type: HasManyRelation, - Field: field, - JoinTable: joinTable, - FKs: fks, - Polymorphic: typeField, - FKValues: fkValues, - }) - return true - } - - return false -} - -func (t *Table) tryRelationStruct(field *Field) bool { - pgTag := parseTag(field.Field.Tag.Get("pg")) - joinTable := _tables.get(field.Type, true) - if len(joinTable.allFields) == 0 { - return false - } - - res := t.tryHasOne(joinTable, field, pgTag) || - t.tryBelongsToOne(joinTable, field, pgTag) - t.inlineFields(field, joinTable.allFields) - return res -} - -func (t *Table) inlineFields(strct *Field, structFields []*Field) { - for _, f := range structFields { - f = f.Copy() - f.GoName = strct.GoName + "_" + f.GoName - f.SQLName = strct.SQLName + "__" + f.SQLName - f.Column = types.Q(types.AppendField(nil, f.SQLName, 1)) - f.Index = appendNew(strct.Index, f.Index...) - if _, ok := t.FieldsMap[f.SQLName]; !ok { - t.FieldsMap[f.SQLName] = f - } - } -} - -func appendNew(dst []int, src ...int) []int { - cp := make([]int, len(dst)+len(src)) - copy(cp, dst) - copy(cp[len(dst):], src) - return cp -} - -func isPostgresKeyword(s string) bool { - switch strings.ToLower(s) { - case "user", "group", "constraint", "limit", - "member", "placing", "references", "table": - return true - default: - return false - } -} - -func isColumn(typ reflect.Type) bool { - return typ.Implements(scannerType) || reflect.PtrTo(typ).Implements(scannerType) -} - -func fieldSQLType(field *Field, pgTag, sqlTag *tag) string { - if typ, ok := sqlTag.Options["type"]; ok { - field.SetFlag(customTypeFlag) - typ, _ = unquoteTagValue(typ) - return typ - } - - if _, ok := sqlTag.Options["hstore"]; ok { - field.SetFlag(customTypeFlag) - return "hstore" - } else if _, ok := pgTag.Options["hstore"]; ok { - field.SetFlag(customTypeFlag) - return "hstore" - } - - if field.HasFlag(ArrayFlag) { - sqlType := sqlType(field.Type.Elem()) - return sqlType + "[]" - } - - sqlType := sqlType(field.Type) - if field.HasFlag(PrimaryKeyFlag) { - return pkSQLType(sqlType) - } - - switch sqlType { - case "timestamptz": - field.SetFlag(customTypeFlag) - } - - return sqlType -} - -func sqlType(typ reflect.Type) string { - switch typ { - case timeType: - return "timestamptz" - case ipType: - return "inet" - case ipNetType: - return "cidr" - case nullBoolType: - return "boolean" - case nullFloatType: - return "double precision" - case nullIntType: - return "bigint" - case nullStringType: - return "text" - } - - switch typ.Kind() { - case reflect.Int8, reflect.Uint8, reflect.Int16: - return "smallint" - case reflect.Uint16, reflect.Int32: - return "integer" - case reflect.Uint32, reflect.Int64, reflect.Int: - return "bigint" - case reflect.Uint, reflect.Uint64: - // The lesser of two evils. - return "bigint" - case reflect.Float32: - return "real" - case reflect.Float64: - return "double precision" - case reflect.Bool: - return "boolean" - case reflect.String: - return "text" - case reflect.Map, reflect.Struct: - return "jsonb" - case reflect.Array, reflect.Slice: - if typ.Elem().Kind() == reflect.Uint8 { - return "bytea" - } - return "jsonb" - default: - return typ.Kind().String() - } -} - -func pkSQLType(s string) string { - switch s { - case "smallint": - return "smallserial" - case "integer": - return "serial" - case "bigint": - return "bigserial" - } - return s -} - -func sqlTypeEqual(a, b string) bool { - if a == b { - return true - } - return pkSQLType(a) == pkSQLType(b) -} - -func (t *Table) tryHasOne(joinTable *Table, field *Field, tag *tag) bool { - fk, fkOK := tag.Options["fk"] - if fkOK { - if fk == "-" { - return false - } - fk = tryUnderscorePrefix(fk) - } else { - fk = internal.Underscore(field.GoName) + "_" - } - - fks := foreignKeys(joinTable, t, fk, fkOK) - if len(fks) > 0 { - t.addRelation(&Relation{ - Type: HasOneRelation, - Field: field, - FKs: fks, - JoinTable: joinTable, - }) - return true - } - return false -} - -func (t *Table) tryBelongsToOne(joinTable *Table, field *Field, tag *tag) bool { - fk, fkOK := tag.Options["fk"] - if fkOK { - if fk == "-" { - return false - } - fk = tryUnderscorePrefix(fk) - } else { - fk = internal.Underscore(t.TypeName) + "_" - } - - fks := foreignKeys(t, joinTable, fk, fkOK) - if len(fks) > 0 { - t.addRelation(&Relation{ - Type: BelongsToRelation, - Field: field, - FKs: fks, - JoinTable: joinTable, - }) - return true - } - return false -} - -func (t *Table) addRelation(rel *Relation) { - if t.Relations == nil { - t.Relations = make(map[string]*Relation) - } - _, ok := t.Relations[rel.Field.GoName] - if ok { - panic(fmt.Errorf("%s already has %s", t, rel)) - } - t.Relations[rel.Field.GoName] = rel -} - -func foreignKeys(base, join *Table, fk string, tryFK bool) []*Field { - var fks []*Field - - for _, pk := range base.PKs { - fkName := fk + pk.SQLName - f := join.getField(fkName) - if f != nil && sqlTypeEqual(pk.SQLType, f.SQLType) { - fks = append(fks, f) - } - } - if len(fks) > 0 { - return fks - } - - for _, pk := range base.PKs { - if !strings.HasPrefix(pk.SQLName, "pk_") { - continue - } - fkName := "fk_" + pk.SQLName[3:] - f := join.getField(fkName) - if f != nil && sqlTypeEqual(pk.SQLType, f.SQLType) { - fks = append(fks, f) - } - } - if len(fks) > 0 { - return fks - } - - if fk == "" || len(base.PKs) != 1 { - return nil - } - - if tryFK { - f := join.getField(fk) - if f != nil && sqlTypeEqual(base.PKs[0].SQLType, f.SQLType) { - fks = append(fks, f) - return fks - } - } - - for _, suffix := range []string{"id", "uuid"} { - f := join.getField(fk + suffix) - if f != nil && sqlTypeEqual(base.PKs[0].SQLType, f.SQLType) { - fks = append(fks, f) - return fks - } - } - - return nil -} - -func (t *Table) getField(name string) *Field { - return t.FieldsMap[name] -} - -func scanJSONValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(non-pointer %s)", v.Type()) - } - if b == nil { - v.Set(reflect.New(v.Type()).Elem()) - return nil - } - dec := json.NewDecoder(bytes.NewReader(b)) - dec.UseNumber() - return dec.Decode(v.Addr().Interface()) -} - -func tryUnderscorePrefix(s string) string { - if s == "" { - return s - } - if c := s[0]; internal.IsUpper(c) { - return internal.Underscore(s) + "_" - } - return s -} - -func quoteTableName(s string) string { - if isPostgresKeyword(s) { - return `"` + s + `"` - } - return s -} diff --git a/vendor/github.com/go-pg/pg/orm/table_create.go b/vendor/github.com/go-pg/pg/orm/table_create.go deleted file mode 100644 index c3bdda382..000000000 --- a/vendor/github.com/go-pg/pg/orm/table_create.go +++ /dev/null @@ -1,155 +0,0 @@ -package orm - -import ( - "errors" - "strconv" -) - -type CreateTableOptions struct { - Temp bool - IfNotExists bool - Varchar int // replaces PostgreSQL data type `text` with `varchar(n)` - - // FKConstraints causes CreateTable to create foreign key constraints - // for has one relations. ON DELETE hook can be added using tag - // `sql:"on_delete:RESTRICT"` on foreign key field. - FKConstraints bool -} - -func CreateTable(db DB, model interface{}, opt *CreateTableOptions) error { - q := NewQuery(db, model) - _, err := q.db.Exec(createTableQuery{ - q: q, - opt: opt, - }) - return err -} - -type createTableQuery struct { - q *Query - opt *CreateTableOptions -} - -func (q createTableQuery) Copy() QueryAppender { - return q -} - -func (q createTableQuery) Query() *Query { - return q.q -} - -func (q createTableQuery) AppendQuery(b []byte) ([]byte, error) { - if q.q.stickyErr != nil { - return nil, q.q.stickyErr - } - if q.q.model == nil { - return nil, errors.New("pg: Model(nil)") - } - - table := q.q.model.Table() - - b = append(b, "CREATE "...) - if q.opt != nil && q.opt.Temp { - b = append(b, "TEMP "...) - } - b = append(b, "TABLE "...) - if q.opt != nil && q.opt.IfNotExists { - b = append(b, "IF NOT EXISTS "...) - } - b = q.q.appendTableName(b) - b = append(b, " ("...) - - for i, field := range table.Fields { - if i > 0 { - b = append(b, ", "...) - } - - b = append(b, field.Column...) - b = append(b, " "...) - if q.opt != nil && q.opt.Varchar > 0 && - field.SQLType == "text" && !field.HasFlag(customTypeFlag) { - b = append(b, "varchar("...) - b = strconv.AppendInt(b, int64(q.opt.Varchar), 10) - b = append(b, ")"...) - } else { - b = append(b, field.SQLType...) - } - if field.HasFlag(NotNullFlag) { - b = append(b, " NOT NULL"...) - } - if field.HasFlag(UniqueFlag) { - b = append(b, " UNIQUE"...) - } - if field.Default != "" { - b = append(b, " DEFAULT "...) - b = append(b, field.Default...) - } - } - - b = appendPKConstraint(b, table.PKs) - for _, fields := range table.Unique { - b = appendUnique(b, fields) - } - - if q.opt != nil && q.opt.FKConstraints { - for _, rel := range table.Relations { - b = q.appendFKConstraint(b, table, rel) - } - } - - b = append(b, ")"...) - - return b, nil -} - -func appendPKConstraint(b []byte, pks []*Field) []byte { - if len(pks) == 0 { - return b - } - - b = append(b, ", PRIMARY KEY ("...) - b = appendColumns(b, "", pks) - b = append(b, ")"...) - return b -} - -func appendUnique(b []byte, fields []*Field) []byte { - b = append(b, ", UNIQUE ("...) - b = appendColumns(b, "", fields) - b = append(b, ")"...) - return b -} - -func (q createTableQuery) appendFKConstraint(b []byte, table *Table, rel *Relation) []byte { - if rel.Type != HasOneRelation { - return b - } - - b = append(b, ", FOREIGN KEY ("...) - b = appendColumns(b, "", rel.FKs) - b = append(b, ")"...) - - b = append(b, " REFERENCES "...) - b = q.q.FormatQuery(b, string(rel.JoinTable.Name)) - b = append(b, " ("...) - b = appendColumns(b, "", rel.JoinTable.PKs) - b = append(b, ")"...) - - if s := onDelete(rel.FKs); s != "" { - b = append(b, " ON DELETE "...) - b = append(b, s...) - } - - return b -} - -func onDelete(fks []*Field) string { - var onDelete string - for _, f := range fks { - if f.OnDelete != "" { - onDelete = f.OnDelete - break - } - } - return onDelete -} diff --git a/vendor/github.com/go-pg/pg/orm/table_drop.go b/vendor/github.com/go-pg/pg/orm/table_drop.go deleted file mode 100644 index de509fd25..000000000 --- a/vendor/github.com/go-pg/pg/orm/table_drop.go +++ /dev/null @@ -1,50 +0,0 @@ -package orm - -import "errors" - -type DropTableOptions struct { - IfExists bool - Cascade bool -} - -func DropTable(db DB, model interface{}, opt *DropTableOptions) error { - q := NewQuery(db, model) - _, err := q.db.Exec(dropTableQuery{ - q: q, - opt: opt, - }) - return err -} - -type dropTableQuery struct { - q *Query - opt *DropTableOptions -} - -func (q dropTableQuery) Copy() QueryAppender { - return q -} - -func (q dropTableQuery) Query() *Query { - return q.q -} - -func (q dropTableQuery) AppendQuery(b []byte) ([]byte, error) { - if q.q.stickyErr != nil { - return nil, q.q.stickyErr - } - if q.q.model == nil { - return nil, errors.New("pg: Model(nil)") - } - - b = append(b, "DROP TABLE "...) - if q.opt != nil && q.opt.IfExists { - b = append(b, "IF EXISTS "...) - } - b = q.q.appendTableName(b) - if q.opt != nil && q.opt.Cascade { - b = append(b, " CASCADE"...) - } - - return b, nil -} diff --git a/vendor/github.com/go-pg/pg/orm/table_params.go b/vendor/github.com/go-pg/pg/orm/table_params.go deleted file mode 100644 index db3437a50..000000000 --- a/vendor/github.com/go-pg/pg/orm/table_params.go +++ /dev/null @@ -1,29 +0,0 @@ -package orm - -import "reflect" - -type tableParams struct { - table *Table - strct reflect.Value -} - -func newTableParams(strct interface{}) (*tableParams, bool) { - v := reflect.ValueOf(strct) - if !v.IsValid() { - return nil, false - } - - v = reflect.Indirect(v) - if v.Kind() != reflect.Struct { - return nil, false - } - - return &tableParams{ - table: GetTable(v.Type()), - strct: v, - }, true -} - -func (m tableParams) AppendParam(b []byte, f QueryFormatter, name string) ([]byte, bool) { - return m.table.AppendParam(b, m.strct, name) -} diff --git a/vendor/github.com/go-pg/pg/orm/tables.go b/vendor/github.com/go-pg/pg/orm/tables.go deleted file mode 100644 index 0a01b030c..000000000 --- a/vendor/github.com/go-pg/pg/orm/tables.go +++ /dev/null @@ -1,112 +0,0 @@ -package orm - -import ( - "fmt" - "reflect" - "sync" -) - -var _tables = newTables() - -type tableInProgress struct { - table *Table - wg sync.WaitGroup -} - -// GetTable returns a Table for a struct type. -func GetTable(typ reflect.Type) *Table { - return _tables.Get(typ) -} - -// RegisterTable registers a struct as SQL table. -// It is usually used to register intermediate table -// in many to many relationship. -func RegisterTable(strct interface{}) { - _tables.Register(strct) -} - -type tables struct { - mu sync.RWMutex - inProgress map[reflect.Type]*tableInProgress - tables map[reflect.Type]*Table -} - -func newTables() *tables { - return &tables{ - inProgress: make(map[reflect.Type]*tableInProgress), - tables: make(map[reflect.Type]*Table), - } -} - -func (t *tables) Register(strct interface{}) { - typ := reflect.TypeOf(strct) - if typ.Kind() == reflect.Ptr { - typ = typ.Elem() - } - _ = t.Get(typ) -} - -func (t *tables) get(typ reflect.Type, allowInProgress bool) *Table { - if typ.Kind() != reflect.Struct { - panic(fmt.Errorf("got %s, wanted %s", typ.Kind(), reflect.Struct)) - } - - t.mu.RLock() - table, ok := t.tables[typ] - t.mu.RUnlock() - if ok { - return table - } - - t.mu.Lock() - - table, ok = t.tables[typ] - if ok { - t.mu.Unlock() - return table - } - - inProgress := t.inProgress[typ] - if inProgress != nil { - t.mu.Unlock() - if !allowInProgress { - inProgress.wg.Wait() - } - return inProgress.table - } - - table = newTable(typ) - inProgress = &tableInProgress{ - table: table, - } - inProgress.wg.Add(1) - t.inProgress[typ] = inProgress - - t.mu.Unlock() - table.init() - inProgress.wg.Done() - t.mu.Lock() - - delete(t.inProgress, typ) - t.tables[typ] = table - - t.mu.Unlock() - return table -} - -func (t *tables) Get(typ reflect.Type) *Table { - return t.get(typ, false) -} - -func (t *tables) getByName(name string) *Table { - t.mu.RLock() - defer t.mu.RUnlock() - - for _, t := range t.tables { - if string(t.Name) == name || t.ModelName == name { - return t - } - } - - return nil -} diff --git a/vendor/github.com/go-pg/pg/orm/tag.go b/vendor/github.com/go-pg/pg/orm/tag.go deleted file mode 100644 index 8d630d646..000000000 --- a/vendor/github.com/go-pg/pg/orm/tag.go +++ /dev/null @@ -1,145 +0,0 @@ -package orm - -import ( - "github.com/go-pg/pg/internal/parser" -) - -type tag struct { - Name string - Options map[string]string -} - -func parseTag(s string) *tag { - p := &tagParser{ - Parser: parser.NewString(s), - } - p.parseKey() - return &p.tag -} - -type tagParser struct { - *parser.Parser - - tag tag - hasName bool - key string -} - -func (p *tagParser) setTagOption(key, value string) { - if !p.hasName { - p.hasName = true - if key == "" { - p.tag.Name = value - return - } - } - if p.tag.Options == nil { - p.tag.Options = make(map[string]string) - } - if key == "" { - p.tag.Options[value] = "" - } else { - p.tag.Options[key] = value - } -} - -func (p *tagParser) parseKey() { - p.key = "" - - var b []byte - for p.Valid() { - c := p.Read() - switch c { - case ',': - p.Skip(' ') - p.setTagOption("", string(b)) - p.parseKey() - return - case ':': - p.key = string(b) - p.parseValue() - return - case '\'': - p.parseQuotedValue() - return - default: - b = append(b, c) - } - } - - if len(b) > 0 { - p.setTagOption("", string(b)) - } -} - -func (p *tagParser) parseValue() { - const quote = '\'' - - c := p.Peek() - if c == quote { - p.Skip(quote) - p.parseQuotedValue() - return - } - - var b []byte - for p.Valid() { - c = p.Read() - switch c { - case '\\': - c = p.Read() - b = append(b, c) - case ',': - p.Skip(' ') - p.setTagOption(p.key, string(b)) - p.parseKey() - return - default: - b = append(b, c) - } - } - p.setTagOption(p.key, string(b)) -} - -func (p *tagParser) parseQuotedValue() { - const quote = '\'' - - var b []byte - b = append(b, quote) - - for p.Valid() { - bb, ok := p.ReadSep(quote) - if !ok { - b = append(b, bb...) - break - } - - if len(bb) > 0 && bb[len(bb)-1] == '\\' { - b = append(b, bb[:len(bb)-1]...) - b = append(b, quote) - continue - } - - b = append(b, bb...) - b = append(b, quote) - break - } - - p.setTagOption(p.key, string(b)) - if p.Skip(',') { - p.Skip(' ') - } - p.parseKey() -} - -func unquoteTagValue(s string) (string, bool) { - const quote = '\'' - - if len(s) < 2 { - return s, false - } - if s[0] == quote && s[len(s)-1] == quote { - return s[1 : len(s)-1], true - } - return s, false -} diff --git a/vendor/github.com/go-pg/pg/orm/update.go b/vendor/github.com/go-pg/pg/orm/update.go deleted file mode 100644 index 492262f80..000000000 --- a/vendor/github.com/go-pg/pg/orm/update.go +++ /dev/null @@ -1,257 +0,0 @@ -package orm - -import ( - "errors" - "fmt" - "reflect" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/types" -) - -func Update(db DB, model interface{}) error { - res, err := NewQuery(db, model).WherePK().Update() - if err != nil { - return err - } - return internal.AssertOneRow(res.RowsAffected()) -} - -type updateQuery struct { - q *Query - omitZero bool -} - -var _ QueryAppender = (*updateQuery)(nil) - -func (q updateQuery) Copy() QueryAppender { - return updateQuery{ - q: q.q.Copy(), - } -} - -func (q updateQuery) Query() *Query { - return q.q -} - -func (q updateQuery) AppendQuery(b []byte) ([]byte, error) { - if q.q.stickyErr != nil { - return nil, q.q.stickyErr - } - - var err error - - if len(q.q.with) > 0 { - b, err = q.q.appendWith(b) - if err != nil { - return nil, err - } - } - - b = append(b, "UPDATE "...) - b = q.q.appendFirstTableWithAlias(b) - - b, err = q.mustAppendSet(b) - if err != nil { - return nil, err - } - - isSliceModel := q.q.isSliceModel() - if q.q.hasMultiTables() || isSliceModel { - b = append(b, " FROM "...) - b = q.q.appendOtherTables(b) - - if isSliceModel { - b, err = q.appendSliceModelData(b) - if err != nil { - return nil, err - } - } - } - - b = append(b, " WHERE "...) - if isSliceModel { - table := q.q.model.Table() - b = appendWhereColumnAndColumn(b, table.Alias, table.PKs) - - if q.q.hasWhere() { - b = append(b, " AND "...) - b = q.q.appendWhere(b) - } - } else { - b, err = q.q.mustAppendWhere(b) - if err != nil { - return nil, err - } - } - - if len(q.q.returning) > 0 { - b = q.q.appendReturning(b) - } - - return b, nil -} - -func (q updateQuery) mustAppendSet(b []byte) ([]byte, error) { - if len(q.q.set) > 0 { - b = q.q.appendSet(b) - return b, nil - } - - if q.q.model == nil { - return nil, errors.New("pg: Model(nil)") - } - - b = append(b, " SET "...) - - value := q.q.model.Value() - var err error - if value.Kind() == reflect.Struct { - b, err = q.appendSetStruct(b, value) - } else { - if value.Len() > 0 { - b, err = q.appendSetSlice(b, value) - } else { - err = fmt.Errorf("pg: can't bulk-update empty slice %s", value.Type()) - } - } - if err != nil { - return nil, err - } - - return b, nil -} - -func (q updateQuery) appendSetStruct(b []byte, strct reflect.Value) ([]byte, error) { - fields, err := q.q.getFields() - if err != nil { - return nil, err - } - - if len(fields) == 0 { - fields = q.q.model.Table().DataFields - } - - pos := len(b) - for _, f := range fields { - omitZero := f.OmitZero() && f.IsZero(strct) - if omitZero && q.omitZero { - continue - } - - if len(b) != pos { - b = append(b, ", "...) - pos = len(b) - } - - b = append(b, f.Column...) - b = append(b, " = "...) - - app, ok := q.q.modelValues[f.SQLName] - if ok { - b = app.AppendFormat(b, q.q) - continue - } - - if f.OmitZero() && f.IsZero(strct) { - b = append(b, "NULL"...) - } else { - b = f.AppendValue(b, strct, 1) - } - } - - return b, nil -} - -func (q updateQuery) appendSetSlice(b []byte, slice reflect.Value) ([]byte, error) { - fields, err := q.q.getFields() - if err != nil { - return nil, err - } - - if len(fields) == 0 { - fields = q.q.model.Table().DataFields - } - - for i, f := range fields { - if i > 0 { - b = append(b, ", "...) - } - - b = append(b, f.Column...) - b = append(b, " = "...) - b = append(b, "_data."...) - b = append(b, f.Column...) - } - - return b, nil -} - -func (q updateQuery) appendSliceModelData(b []byte) ([]byte, error) { - columns, err := q.q.getDataFields() - if err != nil { - return nil, err - } - - if len(columns) > 0 { - columns = append(columns, q.q.model.Table().PKs...) - } else { - columns = q.q.model.Table().Fields - } - - return q.appendSliceValues(b, columns, q.q.model.Value()), nil -} - -func (q updateQuery) appendSliceValues(b []byte, fields []*Field, slice reflect.Value) []byte { - b = append(b, "(VALUES ("...) - for i := 0; i < slice.Len(); i++ { - el := indirect(slice.Index(i)) - b = q.appendValues(b, fields, el) - if i != slice.Len()-1 { - b = append(b, "), ("...) - } - } - b = append(b, ")) AS _data("...) - b = appendColumns(b, "", fields) - b = append(b, ")"...) - return b -} - -func (q updateQuery) appendValues(b []byte, fields []*Field, strct reflect.Value) []byte { - for i, f := range fields { - if i > 0 { - b = append(b, ", "...) - } - - app, ok := q.q.modelValues[f.SQLName] - if ok { - b = app.AppendFormat(b, q.q) - continue - } - - if f.OmitZero() && f.IsZero(strct) { - b = append(b, "NULL"...) - } else { - b = f.AppendValue(b, strct, 1) - } - if f.HasFlag(customTypeFlag) { - b = append(b, "::"...) - b = append(b, f.SQLType...) - } - } - return b -} - -func appendWhereColumnAndColumn(b []byte, alias types.Q, fields []*Field) []byte { - for i, f := range fields { - if i > 0 { - b = append(b, " AND "...) - } - b = append(b, alias...) - b = append(b, '.') - b = append(b, f.Column...) - b = append(b, " = _data."...) - b = append(b, f.Column...) - } - return b -} diff --git a/vendor/github.com/go-pg/pg/orm/url_filter.go b/vendor/github.com/go-pg/pg/orm/url_filter.go deleted file mode 100644 index c3da83b47..000000000 --- a/vendor/github.com/go-pg/pg/orm/url_filter.go +++ /dev/null @@ -1,114 +0,0 @@ -package orm - -import ( - "net/url" - "strings" - - "github.com/go-pg/pg/types" -) - -// URLFilter is used with Query.Apply to add WHERE clauses from the URL values: -// - ?foo=bar - Where(`"foo" = 'bar'`) -// - ?foo=hello&foo=world - Where(`"foo" IN ('hello','world')`) -// - ?foo__exclude=bar - Where(`"foo" != 'bar'`) -// - ?foo__ieq=bar - Where(`"foo" ILIKE 'bar'`) -// - ?foo__match=bar - Where(`"foo" SIMILAR TO 'bar'`) -// - ?foo__gt=42 - Where(`"foo" > 42`) -// - ?foo__gte=42 - Where(`"foo" >= 42`) -// - ?foo__lt=42 - Where(`"foo" < 42`) -// - ?foo__lte=42 - Where(`"foo" <= 42`) -type URLFilter struct { - values URLValues - allowed map[string]struct{} -} - -func NewURLFilter(values url.Values) *URLFilter { - return &URLFilter{ - values: URLValues(values), - } -} - -// Values returns URL values. -func (f *URLFilter) Values() URLValues { - return f.values -} - -func (f *URLFilter) Allow(filter string) { - if f.allowed == nil { - f.allowed = make(map[string]struct{}) - } - f.allowed[filter] = struct{}{} -} - -func (f *URLFilter) isAllowed(filter string) bool { - if len(f.allowed) == 0 { - return true - } - _, ok := f.allowed[filter] - return ok -} - -func (f *URLFilter) Filters(q *Query) (*Query, error) { - if f == nil { - return q, nil - } - - for filter, values := range f.values { - if !f.isAllowed(filter) { - continue - } - - var operation string - if i := strings.Index(filter, "__"); i != -1 { - filter, operation = filter[:i], filter[i+2:] - } - - if q.model.Table().HasField(filter) { - q = addOperator(q, filter, operation, values) - } - } - return q, nil -} - -// URLFilters is a shortcut for NewURLFilter(urlValues).Filters. -func URLFilters(urlValues url.Values) func(*Query) (*Query, error) { - return NewURLFilter(urlValues).Filters -} - -func addOperator(q *Query, field, operator string, values []string) *Query { - switch operator { - case "gt": - q = forEachValue(q, field, values, "? > ?") - case "gte": - q = forEachValue(q, field, values, "? >= ?") - case "lt": - q = forEachValue(q, field, values, "? < ?") - case "lte": - q = forEachValue(q, field, values, "? <= ?") - case "ieq": - q = forEachValue(q, field, values, "? ILIKE ?") - case "match": - q = forEachValue(q, field, values, "? SIMILAR TO ?") - case "exclude": - q = forAllValues(q, field, values, "? != ?", "? NOT IN (?)") - case "", "include": - q = forAllValues(q, field, values, "? = ?", "? IN (?)") - } - return q -} - -func forEachValue(q *Query, field string, values []string, queryTemplate string) *Query { - for _, value := range values { - q = q.Where(queryTemplate, types.F(field), value) - } - return q -} - -func forAllValues(q *Query, field string, values []string, queryTemplate, queryArrayTemplate string) *Query { - if len(values) > 1 { - q = q.Where(queryArrayTemplate, types.F(field), types.InSlice(values)) - } else { - q = q.Where(queryTemplate, types.F(field), values[0]) - } - return q -} diff --git a/vendor/github.com/go-pg/pg/orm/url_values.go b/vendor/github.com/go-pg/pg/orm/url_values.go deleted file mode 100644 index 9ba600075..000000000 --- a/vendor/github.com/go-pg/pg/orm/url_values.go +++ /dev/null @@ -1,106 +0,0 @@ -package orm - -import ( - "net/url" - "strconv" - "time" - - "github.com/go-pg/pg/types" -) - -type URLValues map[string][]string - -func (v URLValues) Has(name string) bool { - _, ok := v[name] - return ok -} - -func (v URLValues) SetDefault(name string, values ...string) { - if !v.Has(name) { - v[name] = values - } -} - -func (v URLValues) Strings(name string) []string { - return v[name] -} - -func (v URLValues) String(name string) string { - values := v.Strings(name) - if len(values) == 0 { - return "" - } - return values[0] -} - -func (v URLValues) Bool(name string) (bool, error) { - if !v.Has(name) { - return false, nil - } - s := v.String(name) - if s == "" { - return true, nil - } - return strconv.ParseBool(s) -} - -func (v URLValues) Int(name string) (int, error) { - s := v.String(name) - if s == "" { - return 0, nil - } - return strconv.Atoi(s) -} - -func (v URLValues) MaybeInt(name string) int { - n, _ := v.Int(name) - return n -} - -func (v URLValues) Int64(name string) (int64, error) { - s := v.String(name) - if s == "" { - return 0, nil - } - return strconv.ParseInt(s, 10, 64) -} - -func (v URLValues) MaybeInt64(name string) int64 { - n, _ := v.Int64(name) - return n -} - -func (v URLValues) Time(name string) (time.Time, error) { - s := v.String(name) - if s == "" { - return time.Time{}, nil - } - - n, err := strconv.ParseInt(s, 10, 64) - if err == nil { - return time.Unix(n, 0), nil - } - return types.ParseTimeString(s) -} - -func (v URLValues) MaybeTime(name string) time.Time { - tm, _ := v.Time(name) - return tm -} - -func (v URLValues) Duration(name string) (time.Duration, error) { - s := v.String(name) - if s == "" { - return 0, nil - } - return time.ParseDuration(s) -} - -func (v URLValues) MaybeDuration(name string) time.Duration { - dur, _ := v.Duration(name) - return dur -} - -func (v URLValues) Pager() *Pager { - return NewPager(url.Values(v)) -} diff --git a/vendor/github.com/go-pg/pg/orm/util.go b/vendor/github.com/go-pg/pg/orm/util.go deleted file mode 100644 index 73b1a7f76..000000000 --- a/vendor/github.com/go-pg/pg/orm/util.go +++ /dev/null @@ -1,127 +0,0 @@ -package orm - -import ( - "reflect" - - "github.com/go-pg/pg/types" -) - -func indirect(v reflect.Value) reflect.Value { - switch v.Kind() { - case reflect.Interface: - return indirect(v.Elem()) - case reflect.Ptr: - return v.Elem() - default: - return v - } -} - -func indirectType(t reflect.Type) reflect.Type { - if t.Kind() == reflect.Ptr { - t = t.Elem() - } - return t -} - -func sliceElemType(v reflect.Value) reflect.Type { - elemType := v.Type().Elem() - if elemType.Kind() == reflect.Interface && v.Len() > 0 { - return indirect(v.Index(0).Elem()).Type() - } else { - return indirectType(elemType) - } -} - -func typeByIndex(t reflect.Type, index []int) reflect.Type { - for _, x := range index { - switch t.Kind() { - case reflect.Ptr: - t = t.Elem() - case reflect.Slice: - t = indirectType(t.Elem()) - } - t = t.Field(x).Type - } - return indirectType(t) -} - -func fieldByIndex(v reflect.Value, index []int) reflect.Value { - for i, x := range index { - if i > 0 { - v = indirectNew(v) - } - v = v.Field(x) - } - return v -} - -func indirectNew(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Ptr { - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - v = v.Elem() - } - return v -} - -func walk(v reflect.Value, index []int, fn func(reflect.Value)) { - v = reflect.Indirect(v) - switch v.Kind() { - case reflect.Slice: - for i := 0; i < v.Len(); i++ { - visitField(v.Index(i), index, fn) - } - default: - visitField(v, index, fn) - } -} - -func visitField(v reflect.Value, index []int, fn func(reflect.Value)) { - v = reflect.Indirect(v) - if len(index) > 0 { - v = v.Field(index[0]) - if v.Kind() == reflect.Ptr && v.IsNil() { - return - } - walk(v, index[1:], fn) - } else { - fn(v) - } -} - -func dstValues(model tableModel, fields []*Field) map[string][]reflect.Value { - mp := make(map[string][]reflect.Value) - var id []byte - walk(model.Root(), model.ParentIndex(), func(v reflect.Value) { - id = modelId(id[:0], v, fields) - mp[string(id)] = append(mp[string(id)], v.FieldByIndex(model.Relation().Field.Index)) - }) - return mp -} - -func modelId(b []byte, v reflect.Value, fields []*Field) []byte { - for i, f := range fields { - if i > 0 { - b = append(b, ',') - } - b = f.AppendValue(b, v, 0) - } - return b -} - -func appendColumns(b []byte, table types.Q, fields []*Field) []byte { - for i, f := range fields { - if i > 0 { - b = append(b, ", "...) - } - - if len(table) > 0 { - b = append(b, table...) - b = append(b, '.') - } - b = types.AppendField(b, f.SQLName, 1) - } - return b -} diff --git a/vendor/github.com/go-pg/pg/orm/zero.go b/vendor/github.com/go-pg/pg/orm/zero.go deleted file mode 100644 index 659293f01..000000000 --- a/vendor/github.com/go-pg/pg/orm/zero.go +++ /dev/null @@ -1,119 +0,0 @@ -package orm - -import ( - "database/sql/driver" - "reflect" - - "github.com/go-pg/pg/types" -) - -var driverValuerType = reflect.TypeOf((*driver.Valuer)(nil)).Elem() -var appenderType = reflect.TypeOf((*types.ValueAppender)(nil)).Elem() -var isZeroerType = reflect.TypeOf((*isZeroer)(nil)).Elem() - -type isZeroer interface { - IsZero() bool -} - -func isZeroFunc(typ reflect.Type) func(reflect.Value) bool { - if typ.Implements(isZeroerType) { - return isZero - } - - switch typ.Kind() { - case reflect.Array: - if typ.Elem().Kind() == reflect.Uint8 { - return isZeroBytes - } - return isZeroLen - case reflect.Map, reflect.Slice, reflect.String: - return isZeroLen - case reflect.Bool: - return isZeroBool - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return isZeroInt - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return isZeroUint - case reflect.Float32, reflect.Float64: - return isZeroFloat - case reflect.Interface, reflect.Ptr: - return isZeroNil - } - - if typ.Implements(appenderType) { - return isZeroAppenderValue - } - if typ.Implements(driverValuerType) { - return isZeroDriverValue - } - - return isZeroFalse -} - -func isZero(v reflect.Value) bool { - if v.Kind() == reflect.Ptr { - return v.IsNil() - } - return v.Interface().(isZeroer).IsZero() -} - -func isZeroAppenderValue(v reflect.Value) bool { - if v.Kind() == reflect.Ptr { - return v.IsNil() - } - - appender := v.Interface().(types.ValueAppender) - value := appender.AppendValue(nil, 0) - return value == nil -} - -func isZeroDriverValue(v reflect.Value) bool { - if v.Kind() == reflect.Ptr { - return v.IsNil() - } - - valuer := v.Interface().(driver.Valuer) - value, err := valuer.Value() - if err != nil { - return false - } - return value == nil -} - -func isZeroLen(v reflect.Value) bool { - return v.Len() == 0 -} - -func isZeroNil(v reflect.Value) bool { - return v.IsNil() -} - -func isZeroBool(v reflect.Value) bool { - return !v.Bool() -} - -func isZeroInt(v reflect.Value) bool { - return v.Int() == 0 -} - -func isZeroUint(v reflect.Value) bool { - return v.Uint() == 0 -} - -func isZeroFloat(v reflect.Value) bool { - return v.Float() == 0 -} - -func isZeroBytes(v reflect.Value) bool { - b := v.Slice(0, v.Len()).Bytes() - for _, c := range b { - if c != 0 { - return false - } - } - return true -} - -func isZeroFalse(v reflect.Value) bool { - return false -} diff --git a/vendor/github.com/go-pg/pg/pg.go b/vendor/github.com/go-pg/pg/pg.go deleted file mode 100644 index adae48663..000000000 --- a/vendor/github.com/go-pg/pg/pg.go +++ /dev/null @@ -1,209 +0,0 @@ -package pg - -import ( - "log" - "os" - "strconv" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/orm" - "github.com/go-pg/pg/types" -) - -// Discard is used with Query and QueryOne to discard rows. -var Discard orm.Discard - -func init() { - SetLogger(log.New(os.Stderr, "pg: ", log.LstdFlags|log.Lshortfile)) -} - -// Model returns new query for the optional model. -func Model(model ...interface{}) *orm.Query { - return orm.NewQuery(nil, model...) -} - -// Scan returns ColumnScanner that copies the columns in the -// row into the values. -func Scan(values ...interface{}) orm.ColumnScanner { - return orm.Scan(values...) -} - -// Q replaces any placeholders found in the query. -func Q(query string, params ...interface{}) types.ValueAppender { - return orm.Q(query, params...) -} - -// F quotes a SQL identifier such as a table or column name replacing any -// placeholders found in the field. -func F(field string) types.ValueAppender { - return types.F(field) -} - -// In accepts a slice and returns a wrapper that can be used with PostgreSQL -// IN operator: -// -// Where("id IN (?)", pg.In([]int{1, 2, 3, 4})) -// -// produces -// -// WHERE id IN (1, 2, 3, 4) -func In(slice interface{}) types.ValueAppender { - return types.InSlice(slice) -} - -// InMulti accepts multiple values and returns a wrapper that can be used -// with PostgreSQL IN operator: -// -// Where("(id1, id2) IN (?)", pg.InMulti([]int{1, 2}, []int{3, 4})) -// -// produces -// -// WHERE (id1, id2) IN ((1, 2), (3, 4)) -func InMulti(values ...interface{}) types.ValueAppender { - return types.In(values...) -} - -// Array accepts a slice and returns a wrapper for working with PostgreSQL -// array data type. -// -// For struct fields you can use array tag: -// -// Emails []string `sql:",array"` -func Array(v interface{}) *types.Array { - return types.NewArray(v) -} - -// Hstore accepts a map and returns a wrapper for working with hstore data type. -// Supported map types are: -// - map[string]string -// -// For struct fields you can use hstore tag: -// -// Attrs map[string]string `sql:",hstore"` -func Hstore(v interface{}) *types.Hstore { - return types.NewHstore(v) -} - -func SetLogger(logger *log.Logger) { - internal.Logger = logger -} - -//------------------------------------------------------------------------------ - -type Strings []string - -var _ orm.HooklessModel = (*Strings)(nil) -var _ types.ValueAppender = (*Strings)(nil) - -func (strings *Strings) Init() error { - if s := *strings; len(s) > 0 { - *strings = s[:0] - } - return nil -} - -func (strings *Strings) NewModel() orm.ColumnScanner { - return strings -} - -func (Strings) AddModel(_ orm.ColumnScanner) error { - return nil -} - -func (strings *Strings) ScanColumn(colIdx int, _ string, b []byte) error { - *strings = append(*strings, string(b)) - return nil -} - -func (strings Strings) AppendValue(dst []byte, quote int) []byte { - if len(strings) <= 0 { - return dst - } - - for _, s := range strings { - dst = types.AppendString(dst, s, 1) - dst = append(dst, ',') - } - dst = dst[:len(dst)-1] - return dst -} - -//------------------------------------------------------------------------------ - -type Ints []int64 - -var _ orm.HooklessModel = (*Ints)(nil) -var _ types.ValueAppender = (*Ints)(nil) - -func (ints *Ints) Init() error { - if s := *ints; len(s) > 0 { - *ints = s[:0] - } - return nil -} - -func (ints *Ints) NewModel() orm.ColumnScanner { - return ints -} - -func (Ints) AddModel(_ orm.ColumnScanner) error { - return nil -} - -func (ints *Ints) ScanColumn(colIdx int, colName string, b []byte) error { - n, err := strconv.ParseInt(internal.BytesToString(b), 10, 64) - if err != nil { - return err - } - *ints = append(*ints, n) - return nil -} - -func (ints Ints) AppendValue(dst []byte, quote int) []byte { - if len(ints) <= 0 { - return dst - } - - for _, v := range ints { - dst = strconv.AppendInt(dst, v, 10) - dst = append(dst, ',') - } - dst = dst[:len(dst)-1] - return dst -} - -//------------------------------------------------------------------------------ - -type IntSet map[int64]struct{} - -var _ orm.HooklessModel = (*IntSet)(nil) - -func (set *IntSet) Init() error { - if len(*set) > 0 { - *set = make(map[int64]struct{}) - } - return nil -} - -func (set *IntSet) NewModel() orm.ColumnScanner { - return set -} - -func (IntSet) AddModel(_ orm.ColumnScanner) error { - return nil -} - -func (setptr *IntSet) ScanColumn(colIdx int, colName string, b []byte) error { - set := *setptr - if set == nil { - *setptr = make(IntSet) - set = *setptr - } - - n, err := strconv.ParseInt(internal.BytesToString(b), 10, 64) - if err != nil { - return err - } - set[n] = struct{}{} - return nil -} diff --git a/vendor/github.com/go-pg/pg/result.go b/vendor/github.com/go-pg/pg/result.go deleted file mode 100644 index 3a61b3b9a..000000000 --- a/vendor/github.com/go-pg/pg/result.go +++ /dev/null @@ -1,49 +0,0 @@ -package pg - -import ( - "bytes" - "strconv" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/orm" -) - -// A result summarizes an executed SQL command. -type result struct { - model orm.Model - - affected int - returned int -} - -var _ orm.Result = (*result)(nil) - -func (res *result) parse(b []byte) error { - res.affected = -1 - - ind := bytes.LastIndexByte(b, ' ') - if ind == -1 { - return nil - } - - s := internal.BytesToString(b[ind+1 : len(b)-1]) - - affected, err := strconv.Atoi(s) - if err == nil { - res.affected = affected - } - - return nil -} - -func (res *result) Model() orm.Model { - return res.model -} - -func (res *result) RowsAffected() int { - return res.affected -} - -func (res *result) RowsReturned() int { - return res.returned -} diff --git a/vendor/github.com/go-pg/pg/stmt.go b/vendor/github.com/go-pg/pg/stmt.go deleted file mode 100644 index af96df78b..000000000 --- a/vendor/github.com/go-pg/pg/stmt.go +++ /dev/null @@ -1,278 +0,0 @@ -package pg - -import ( - "errors" - "sync" - "time" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/internal/pool" - "github.com/go-pg/pg/orm" -) - -var errStmtClosed = errors.New("pg: statement is closed") - -// Stmt is a prepared statement. Stmt is safe for concurrent use by -// multiple goroutines. -type Stmt struct { - db *DB - - mu sync.Mutex - _cn *pool.Conn - inTx bool - - q string - name string - columns [][]byte - - stickyErr error -} - -// Prepare creates a prepared statement for later queries or -// executions. Multiple queries or executions may be run concurrently -// from the returned statement. -func (db *DB) Prepare(q string) (*Stmt, error) { - cn, err := db.conn() - if err != nil { - return nil, err - } - - stmt, err := prepare(db, cn, q) - if err != nil { - db.freeConn(cn, err) - return nil, err - } - - return stmt, nil -} - -func (stmt *Stmt) conn() (*pool.Conn, error) { - if stmt._cn == nil { - if stmt.stickyErr != nil { - return nil, stmt.stickyErr - } - return nil, errStmtClosed - } - return stmt._cn, nil -} - -func (stmt *Stmt) exec(params ...interface{}) (orm.Result, error) { - stmt.mu.Lock() - defer stmt.mu.Unlock() - - cn, err := stmt.conn() - if err != nil { - return nil, err - } - return stmt.extQuery(cn, stmt.name, params...) -} - -// Exec executes a prepared statement with the given parameters. -func (stmt *Stmt) Exec(params ...interface{}) (res orm.Result, err error) { - for attempt := 0; attempt <= stmt.db.opt.MaxRetries; attempt++ { - if attempt >= 1 { - time.Sleep(stmt.db.retryBackoff(attempt - 1)) - } - - start := time.Now() - res, err = stmt.exec(params...) - stmt.db.queryProcessed(stmt.db, start, stmt.q, params, attempt, res, err) - - if !stmt.db.shouldRetry(err) { - break - } - } - if err != nil { - stmt.setErr(err) - } - return -} - -// ExecOne acts like Exec, but query must affect only one row. It -// returns ErrNoRows error when query returns zero rows or -// ErrMultiRows when query returns multiple rows. -func (stmt *Stmt) ExecOne(params ...interface{}) (orm.Result, error) { - res, err := stmt.Exec(params...) - if err != nil { - return nil, err - } - - if err := internal.AssertOneRow(res.RowsAffected()); err != nil { - return nil, err - } - return res, nil -} - -func (stmt *Stmt) query(model interface{}, params ...interface{}) (orm.Result, error) { - stmt.mu.Lock() - defer stmt.mu.Unlock() - - cn, err := stmt.conn() - if err != nil { - return nil, err - } - - res, err := stmt.extQueryData(cn, stmt.name, model, stmt.columns, params...) - if err != nil { - return nil, err - } - - if mod := res.Model(); mod != nil && res.RowsReturned() > 0 { - if err = mod.AfterQuery(stmt.db); err != nil { - return res, err - } - } - - return res, nil -} - -// Query executes a prepared query statement with the given parameters. -func (stmt *Stmt) Query(model interface{}, params ...interface{}) (res orm.Result, err error) { - for attempt := 0; attempt <= stmt.db.opt.MaxRetries; attempt++ { - if attempt >= 1 { - time.Sleep(stmt.db.retryBackoff(attempt - 1)) - } - - start := time.Now() - res, err = stmt.query(model, params...) - stmt.db.queryProcessed(stmt.db, start, stmt.q, params, attempt, res, err) - - if !stmt.db.shouldRetry(err) { - break - } - } - if err != nil { - stmt.setErr(err) - } - return -} - -// QueryOne acts like Query, but query must return only one row. It -// returns ErrNoRows error when query returns zero rows or -// ErrMultiRows when query returns multiple rows. -func (stmt *Stmt) QueryOne(model interface{}, params ...interface{}) (orm.Result, error) { - mod, err := orm.NewModel(model) - if err != nil { - return nil, err - } - - res, err := stmt.Query(mod, params...) - if err != nil { - return nil, err - } - - if err := internal.AssertOneRow(res.RowsAffected()); err != nil { - return nil, err - } - return res, nil -} - -func (stmt *Stmt) setErr(e error) { - if stmt.stickyErr == nil { - stmt.stickyErr = e - } -} - -// Close closes the statement. -func (stmt *Stmt) Close() error { - stmt.mu.Lock() - defer stmt.mu.Unlock() - - if stmt._cn == nil { - return errStmtClosed - } - - err := stmt.closeStmt(stmt._cn, stmt.name) - if !stmt.inTx { - stmt.db.freeConn(stmt._cn, err) - } - stmt._cn = nil - return err -} - -func prepare(db *DB, cn *pool.Conn, q string) (*Stmt, error) { - name := cn.NextId() - err := cn.WithWriter(db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - writeParseDescribeSyncMsg(wb, name, q) - return nil - }) - if err != nil { - return nil, err - } - - var columns [][]byte - cn.WithReader(db.opt.ReadTimeout, func(rd *pool.Reader) error { - columns, err = readParseDescribeSync(rd) - return err - }) - if err != nil { - return nil, err - } - - stmt := &Stmt{ - db: db, - _cn: cn, - q: q, - name: name, - columns: columns, - } - return stmt, nil -} - -func (stmt *Stmt) extQuery(cn *pool.Conn, name string, params ...interface{}) (orm.Result, error) { - err := cn.WithWriter(stmt.db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - return writeBindExecuteMsg(wb, name, params...) - }) - if err != nil { - return nil, err - } - - var res orm.Result - err = cn.WithReader(stmt.db.opt.ReadTimeout, func(rd *pool.Reader) error { - res, err = readExtQuery(rd) - return err - }) - if err != nil { - return nil, err - } - - return res, nil -} - -func (stmt *Stmt) extQueryData( - cn *pool.Conn, name string, model interface{}, columns [][]byte, params ...interface{}, -) (orm.Result, error) { - err := cn.WithWriter(stmt.db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - return writeBindExecuteMsg(wb, name, params...) - }) - if err != nil { - return nil, err - } - - var res orm.Result - err = cn.WithReader(stmt.db.opt.ReadTimeout, func(rd *pool.Reader) error { - res, err = readExtQueryData(rd, model, columns) - return err - }) - if err != nil { - return nil, err - } - - return res, nil -} - -func (stmt *Stmt) closeStmt(cn *pool.Conn, name string) error { - err := cn.WithWriter(stmt.db.opt.WriteTimeout, func(wb *pool.WriteBuffer) error { - writeCloseMsg(wb, name) - writeFlushMsg(wb) - return nil - }) - if err != nil { - return err - } - - err = cn.WithReader(stmt.db.opt.ReadTimeout, func(rd *pool.Reader) error { - return readCloseCompleteMsg(rd) - }) - return err -} diff --git a/vendor/github.com/go-pg/pg/time.go b/vendor/github.com/go-pg/pg/time.go deleted file mode 100644 index 66964fad6..000000000 --- a/vendor/github.com/go-pg/pg/time.go +++ /dev/null @@ -1,58 +0,0 @@ -package pg - -import ( - "bytes" - "database/sql" - "encoding/json" - "time" - - "github.com/go-pg/pg/types" -) - -var jsonNull = []byte("null") - -// NullTime is a time.Time wrapper that marshals zero time as JSON null and -// PostgreSQL NULL. -type NullTime struct { - time.Time -} - -var _ json.Marshaler = (*NullTime)(nil) -var _ json.Unmarshaler = (*NullTime)(nil) -var _ sql.Scanner = (*NullTime)(nil) -var _ types.ValueAppender = (*NullTime)(nil) - -func (tm NullTime) MarshalJSON() ([]byte, error) { - if tm.IsZero() { - return jsonNull, nil - } - return tm.Time.MarshalJSON() -} - -func (tm *NullTime) UnmarshalJSON(b []byte) error { - if bytes.Equal(b, jsonNull) { - tm.Time = time.Time{} - return nil - } - return tm.Time.UnmarshalJSON(b) -} - -func (tm NullTime) AppendValue(b []byte, quote int) []byte { - if tm.IsZero() { - return types.AppendNull(b, quote) - } - return types.AppendTime(b, tm.Time, quote) -} - -func (tm *NullTime) Scan(b interface{}) error { - if b == nil { - tm.Time = time.Time{} - return nil - } - newtm, err := types.ParseTime(b.([]byte)) - if err != nil { - return err - } - tm.Time = newtm - return nil -} diff --git a/vendor/github.com/go-pg/pg/tx.go b/vendor/github.com/go-pg/pg/tx.go deleted file mode 100644 index de2024c88..000000000 --- a/vendor/github.com/go-pg/pg/tx.go +++ /dev/null @@ -1,338 +0,0 @@ -package pg - -import ( - "context" - "errors" - "io" - "sync" - "time" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/internal/pool" - "github.com/go-pg/pg/orm" -) - -var errTxDone = errors.New("pg: transaction has already been committed or rolled back") - -// Tx is an in-progress database transaction. It is safe for concurrent use -// by multiple goroutines. -// -// A transaction must end with a call to Commit or Rollback. -// -// After a call to Commit or Rollback, all operations on the transaction fail -// with ErrTxDone. -// -// The statements prepared for a transaction by calling the transaction's -// Prepare or Stmt methods are closed by the call to Commit or Rollback. -type Tx struct { - db *DB - - mu sync.Mutex - cn *pool.Conn - stmts []*Stmt -} - -var _ orm.DB = (*Tx)(nil) - -// Begin starts a transaction. Most callers should use RunInTransaction instead. -func (db *DB) Begin() (*Tx, error) { - tx := &Tx{ - db: db, - } - - cn, err := db.conn() - if err != nil { - return nil, err - } - tx.cn = cn - - if err := tx.begin(); err != nil { - return nil, err - } - - return tx, nil -} - -// RunInTransaction runs a function in a transaction. If function -// returns an error transaction is rollbacked, otherwise transaction -// is committed. -func (db *DB) RunInTransaction(fn func(*Tx) error) error { - tx, err := db.Begin() - if err != nil { - return err - } - return tx.RunInTransaction(fn) -} - -// DB returns a DB which started the Tx. -func (tx *Tx) DB() *DB { - return tx.db -} - -// Begin returns the transaction. -func (tx *Tx) Begin() (*Tx, error) { - return tx, nil -} - -// RunInTransaction runs a function in the transaction. If function -// returns an error transaction is rollbacked, otherwise transaction -// is committed. -func (tx *Tx) RunInTransaction(fn func(*Tx) error) error { - defer func() { - if err := recover(); err != nil { - _ = tx.Rollback() - panic(err) - } - }() - if err := fn(tx); err != nil { - _ = tx.Rollback() - return err - } - return tx.Commit() -} - -func (tx *Tx) conn() (*pool.Conn, error) { - if tx.cn == nil { - return nil, errTxDone - } - return tx.cn, nil -} - -func (tx *Tx) freeConn(cn *pool.Conn, err error) {} - -// Stmt returns a transaction-specific prepared statement -// from an existing statement. -func (tx *Tx) Stmt(stmt *Stmt) *Stmt { - stmt, err := tx.Prepare(stmt.q) - if err != nil { - return &Stmt{stickyErr: err} - } - return stmt -} - -// Prepare creates a prepared statement for use within a transaction. -// -// The returned statement operates within the transaction and can no longer -// be used once the transaction has been committed or rolled back. -// -// To use an existing prepared statement on this transaction, see Tx.Stmt. -func (tx *Tx) Prepare(q string) (*Stmt, error) { - tx.mu.Lock() - defer tx.mu.Unlock() - - cn, err := tx.conn() - if err != nil { - return nil, err - } - - stmt, err := prepare(tx.db, cn, q) - tx.freeConn(cn, err) - if err != nil { - return nil, err - } - - stmt.inTx = true - tx.stmts = append(tx.stmts, stmt) - - return stmt, nil -} - -// Exec is an alias for DB.Exec. -func (tx *Tx) Exec(query interface{}, params ...interface{}) (orm.Result, error) { - tx.mu.Lock() - defer tx.mu.Unlock() - return tx.exec(query, params...) -} - -func (tx *Tx) exec(query interface{}, params ...interface{}) (orm.Result, error) { - cn, err := tx.conn() - if err != nil { - return nil, err - } - - start := time.Now() - res, err := tx.db.simpleQuery(cn, query, params...) - tx.freeConn(cn, err) - tx.db.queryProcessed(tx, start, query, params, 0, res, err) - - return res, err -} - -// ExecOne is an alias for DB.ExecOne. -func (tx *Tx) ExecOne(query interface{}, params ...interface{}) (orm.Result, error) { - res, err := tx.Exec(query, params...) - if err != nil { - return nil, err - } - - if err := internal.AssertOneRow(res.RowsAffected()); err != nil { - return nil, err - } - return res, nil -} - -// Query is an alias for DB.Query. -func (tx *Tx) Query(model interface{}, query interface{}, params ...interface{}) (orm.Result, error) { - tx.mu.Lock() - defer tx.mu.Unlock() - - cn, err := tx.conn() - if err != nil { - return nil, err - } - - start := time.Now() - res, err := tx.db.simpleQueryData(cn, model, query, params...) - tx.freeConn(cn, err) - tx.db.queryProcessed(tx, start, query, params, 0, res, err) - - if err != nil { - return nil, err - } - - if mod := res.Model(); mod != nil && res.RowsReturned() > 0 { - if err = mod.AfterQuery(tx); err != nil { - return res, err - } - } - - return res, err -} - -// QueryOne is an alias for DB.QueryOne. -func (tx *Tx) QueryOne(model interface{}, query interface{}, params ...interface{}) (orm.Result, error) { - mod, err := orm.NewModel(model) - if err != nil { - return nil, err - } - - res, err := tx.Query(mod, query, params...) - if err != nil { - return nil, err - } - - if err := internal.AssertOneRow(res.RowsAffected()); err != nil { - return nil, err - } - return res, nil -} - -// Model is an alias for DB.Model. -func (tx *Tx) Model(model ...interface{}) *orm.Query { - return orm.NewQuery(tx, model...) -} - -// Select is an alias for DB.Select. -func (tx *Tx) Select(model interface{}) error { - return orm.Select(tx, model) -} - -// Insert is an alias for DB.Insert. -func (tx *Tx) Insert(model ...interface{}) error { - return orm.Insert(tx, model...) -} - -// Update is an alias for DB.Update. -func (tx *Tx) Update(model interface{}) error { - return orm.Update(tx, model) -} - -// Delete is an alias for DB.Delete. -func (tx *Tx) Delete(model interface{}) error { - return orm.Delete(tx, model) -} - -// Delete forces delete of the model with deleted_at column. -func (tx *Tx) ForceDelete(model interface{}) error { - return orm.ForceDelete(tx, model) -} - -// CreateTable is an alias for DB.CreateTable. -func (tx *Tx) CreateTable(model interface{}, opt *orm.CreateTableOptions) error { - return orm.CreateTable(tx, model, opt) -} - -// DropTable is an alias for DB.DropTable. -func (tx *Tx) DropTable(model interface{}, opt *orm.DropTableOptions) error { - return orm.DropTable(tx, model, opt) -} - -// CopyFrom is an alias for DB.CopyFrom. -func (tx *Tx) CopyFrom(r io.Reader, query interface{}, params ...interface{}) (orm.Result, error) { - tx.mu.Lock() - defer tx.mu.Unlock() - - cn, err := tx.conn() - if err != nil { - return nil, err - } - - res, err := tx.db.copyFrom(cn, r, query, params...) - tx.freeConn(cn, err) - return res, err -} - -// CopyTo is an alias for DB.CopyTo. -func (tx *Tx) CopyTo(w io.Writer, query interface{}, params ...interface{}) (orm.Result, error) { - tx.mu.Lock() - defer tx.mu.Unlock() - - cn, err := tx.conn() - if err != nil { - return nil, err - } - - res, err := tx.db.copyTo(cn, w, query, params...) - tx.freeConn(cn, err) - return res, err -} - -func (tx *Tx) FormatQuery(dst []byte, query string, params ...interface{}) []byte { - return tx.db.FormatQuery(dst, query, params...) -} - -func (tx *Tx) begin() error { - _, err := tx.Exec("BEGIN") - if err != nil { - tx.close(err) - } - return err -} - -// Commit commits the transaction. -func (tx *Tx) Commit() error { - tx.mu.Lock() - defer tx.mu.Unlock() - - _, err := tx.exec("COMMIT") - tx.close(err) - return err -} - -// Rollback aborts the transaction. -func (tx *Tx) Rollback() error { - tx.mu.Lock() - defer tx.mu.Unlock() - - _, err := tx.exec("ROLLBACK") - tx.close(err) - return err -} - -func (tx *Tx) close(lastErr error) { - if tx.cn == nil { - return - } - - for _, stmt := range tx.stmts { - _ = stmt.Close() - } - tx.stmts = nil - - tx.db.freeConn(tx.cn, lastErr) - tx.cn = nil -} - -func (tx *Tx) Context() context.Context { - return tx.db.Context() -} diff --git a/vendor/github.com/go-pg/pg/types/append.go b/vendor/github.com/go-pg/pg/types/append.go deleted file mode 100644 index e80d124fa..000000000 --- a/vendor/github.com/go-pg/pg/types/append.go +++ /dev/null @@ -1,202 +0,0 @@ -package types - -import ( - "database/sql/driver" - "encoding/hex" - "math" - "reflect" - "strconv" - "time" -) - -func Append(b []byte, v interface{}, quote int) []byte { - switch v := v.(type) { - case nil: - return AppendNull(b, quote) - case bool: - return appendBool(b, v) - case int8: - return strconv.AppendInt(b, int64(v), 10) - case int16: - return strconv.AppendInt(b, int64(v), 10) - case int32: - return strconv.AppendInt(b, int64(v), 10) - case int64: - return strconv.AppendInt(b, int64(v), 10) - case int: - return strconv.AppendInt(b, int64(v), 10) - case uint8: - return strconv.AppendUint(b, uint64(v), 10) - case uint16: - return strconv.AppendUint(b, uint64(v), 10) - case uint32: - return strconv.AppendUint(b, uint64(v), 10) - case uint64: - return strconv.AppendUint(b, v, 10) - case uint: - return strconv.AppendUint(b, uint64(v), 10) - case float32: - return appendFloat(b, float64(v), quote) - case float64: - return appendFloat(b, v, quote) - case string: - return AppendString(b, v, quote) - case time.Time: - return AppendTime(b, v, quote) - case []byte: - return AppendBytes(b, v, quote) - case ValueAppender: - return appendAppender(b, v, quote) - case driver.Valuer: - return appendDriverValuer(b, v, quote) - default: - return appendValue(b, reflect.ValueOf(v), quote) - } -} - -func AppendError(b []byte, err error) []byte { - b = append(b, "?!("...) - b = append(b, err.Error()...) - b = append(b, ')') - return b -} - -func AppendNull(b []byte, quote int) []byte { - if quote == 1 { - return append(b, "NULL"...) - } else { - return nil - } -} - -func appendBool(dst []byte, v bool) []byte { - if v { - return append(dst, "TRUE"...) - } - return append(dst, "FALSE"...) -} - -func appendFloat(dst []byte, v float64, quote int) []byte { - switch { - case math.IsNaN(v): - if quote == 1 { - return append(dst, "'NaN'"...) - } - return append(dst, "NaN"...) - case math.IsInf(v, 1): - if quote == 1 { - return append(dst, "'Infinity'"...) - } - return append(dst, "Infinity"...) - case math.IsInf(v, -1): - if quote == 1 { - return append(dst, "'-Infinity'"...) - } - return append(dst, "-Infinity"...) - default: - return strconv.AppendFloat(dst, v, 'f', -1, 64) - } -} - -func AppendString(b []byte, s string, quote int) []byte { - if quote == 2 { - b = append(b, '"') - } else if quote == 1 { - b = append(b, '\'') - } - - for i := 0; i < len(s); i++ { - c := s[i] - - if c == '\000' { - continue - } - - if quote >= 1 { - if c == '\'' { - b = append(b, '\'', '\'') - continue - } - } - - if quote == 2 { - if c == '"' { - b = append(b, '\\', '"') - continue - } - if c == '\\' { - b = append(b, '\\', '\\') - continue - } - } - - b = append(b, c) - } - - if quote >= 2 { - b = append(b, '"') - } else if quote == 1 { - b = append(b, '\'') - } - - return b -} - -func AppendBytes(b []byte, bytes []byte, quote int) []byte { - if bytes == nil { - return AppendNull(b, quote) - } - - if quote == 1 { - b = append(b, '\'') - } - - tmp := make([]byte, hex.EncodedLen(len(bytes))) - hex.Encode(tmp, bytes) - b = append(b, "\\x"...) - b = append(b, tmp...) - - if quote == 1 { - b = append(b, '\'') - } - - return b -} - -func AppendStringStringMap(b []byte, m map[string]string, quote int) []byte { - if m == nil { - return AppendNull(b, quote) - } - - if quote == 1 { - b = append(b, '\'') - } - - for key, value := range m { - b = AppendString(b, key, 2) - b = append(b, '=', '>') - b = AppendString(b, value, 2) - b = append(b, ',') - } - if len(m) > 0 { - b = b[:len(b)-1] // Strip trailing comma. - } - - if quote == 1 { - b = append(b, '\'') - } - - return b -} - -func appendDriverValuer(b []byte, v driver.Valuer, quote int) []byte { - value, err := v.Value() - if err != nil { - return AppendError(b, err) - } - return Append(b, value, quote) -} - -func appendAppender(b []byte, v ValueAppender, quote int) []byte { - return v.AppendValue(b, quote) -} diff --git a/vendor/github.com/go-pg/pg/types/append_array.go b/vendor/github.com/go-pg/pg/types/append_array.go deleted file mode 100644 index f554eef12..000000000 --- a/vendor/github.com/go-pg/pg/types/append_array.go +++ /dev/null @@ -1,190 +0,0 @@ -package types - -import ( - "reflect" - "strconv" -) - -var stringType = reflect.TypeOf((*string)(nil)).Elem() -var sliceStringType = reflect.TypeOf([]string(nil)) - -var intType = reflect.TypeOf((*int)(nil)).Elem() -var sliceIntType = reflect.TypeOf([]int(nil)) - -var int64Type = reflect.TypeOf((*int64)(nil)).Elem() -var sliceInt64Type = reflect.TypeOf([]int64(nil)) - -var float64Type = reflect.TypeOf((*float64)(nil)).Elem() -var sliceFloat64Type = reflect.TypeOf([]float64(nil)) - -func ArrayAppender(typ reflect.Type) AppenderFunc { - elemType := typ.Elem() - - switch elemType { - case stringType: - return appendSliceStringValue - case intType: - return appendSliceIntValue - case int64Type: - return appendSliceInt64Value - case float64Type: - return appendSliceFloat64Value - } - - appendElem := appender(elemType, true) - return func(b []byte, v reflect.Value, quote int) []byte { - if v.IsNil() { - return AppendNull(b, quote) - } - - if quote == 1 { - b = append(b, '\'') - } - - b = append(b, '{') - for i := 0; i < v.Len(); i++ { - elem := v.Index(i) - b = appendElem(b, elem, 2) - b = append(b, ',') - } - if v.Len() > 0 { - b[len(b)-1] = '}' // Replace trailing comma. - } else { - b = append(b, '}') - } - - if quote == 1 { - b = append(b, '\'') - } - - return b - } -} - -func appendSliceStringValue(b []byte, v reflect.Value, quote int) []byte { - ss := v.Convert(sliceStringType).Interface().([]string) - return appendSliceString(b, ss, quote) -} - -func appendSliceString(b []byte, ss []string, quote int) []byte { - if ss == nil { - return AppendNull(b, quote) - } - - if quote == 1 { - b = append(b, '\'') - } - - b = append(b, '{') - for _, s := range ss { - b = AppendString(b, s, 2) - b = append(b, ',') - } - if len(ss) > 0 { - b[len(b)-1] = '}' // Replace trailing comma. - } else { - b = append(b, '}') - } - - if quote == 1 { - b = append(b, '\'') - } - - return b -} - -func appendSliceIntValue(b []byte, v reflect.Value, quote int) []byte { - ints := v.Convert(sliceIntType).Interface().([]int) - return appendSliceInt(b, ints, quote) -} - -func appendSliceInt(b []byte, ints []int, quote int) []byte { - if ints == nil { - return AppendNull(b, quote) - } - - if quote == 1 { - b = append(b, '\'') - } - - b = append(b, '{') - for _, n := range ints { - b = strconv.AppendInt(b, int64(n), 10) - b = append(b, ',') - } - if len(ints) > 0 { - b[len(b)-1] = '}' // Replace trailing comma. - } else { - b = append(b, '}') - } - - if quote == 1 { - b = append(b, '\'') - } - - return b -} - -func appendSliceInt64Value(b []byte, v reflect.Value, quote int) []byte { - ints := v.Convert(sliceInt64Type).Interface().([]int64) - return appendSliceInt64(b, ints, quote) -} - -func appendSliceInt64(b []byte, ints []int64, quote int) []byte { - if ints == nil { - return AppendNull(b, quote) - } - - if quote == 1 { - b = append(b, '\'') - } - - b = append(b, '{') - for _, n := range ints { - b = strconv.AppendInt(b, n, 10) - b = append(b, ',') - } - if len(ints) > 0 { - b[len(b)-1] = '}' // Replace trailing comma. - } else { - b = append(b, '}') - } - - if quote == 1 { - b = append(b, '\'') - } - - return b -} - -func appendSliceFloat64Value(b []byte, v reflect.Value, quote int) []byte { - floats := v.Convert(sliceFloat64Type).Interface().([]float64) - return appendSliceFloat64(b, floats, quote) -} - -func appendSliceFloat64(b []byte, floats []float64, quote int) []byte { - if floats == nil { - return AppendNull(b, quote) - } - - if quote == 1 { - b = append(b, '\'') - } - - b = append(b, '{') - for _, n := range floats { - b = appendFloat(b, n, 2) - b = append(b, ',') - } - if len(floats) > 0 { - b[len(b)-1] = '}' // Replace trailing comma. - } else { - b = append(b, '}') - } - - if quote == 1 { - b = append(b, '\'') - } - - return b -} diff --git a/vendor/github.com/go-pg/pg/types/append_field.go b/vendor/github.com/go-pg/pg/types/append_field.go deleted file mode 100644 index 2fa86dcef..000000000 --- a/vendor/github.com/go-pg/pg/types/append_field.go +++ /dev/null @@ -1,52 +0,0 @@ -package types - -import "github.com/go-pg/pg/internal/parser" - -func AppendField(b []byte, field string, quote int) []byte { - return appendField(b, parser.NewString(field), quote) -} - -func AppendFieldBytes(b []byte, field []byte, quote int) []byte { - return appendField(b, parser.New(field), quote) -} - -func appendField(b []byte, p *parser.Parser, quote int) []byte { - var quoted bool - for p.Valid() { - c := p.Read() - switch c { - case '*': - if !quoted { - b = append(b, '*') - continue - } - case '.': - if quoted && quote == 1 { - b = append(b, '"') - quoted = false - } - b = append(b, '.') - if p.Skip('*') { - b = append(b, '*') - } else if quote == 1 { - b = append(b, '"') - quoted = true - } - continue - } - - if !quoted && quote == 1 { - b = append(b, '"') - quoted = true - } - if c == '"' { - b = append(b, '"', '"') - } else { - b = append(b, c) - } - } - if quoted && quote == 1 { - b = append(b, '"') - } - return b -} diff --git a/vendor/github.com/go-pg/pg/types/append_hstore.go b/vendor/github.com/go-pg/pg/types/append_hstore.go deleted file mode 100644 index 954907433..000000000 --- a/vendor/github.com/go-pg/pg/types/append_hstore.go +++ /dev/null @@ -1,49 +0,0 @@ -package types - -import ( - "fmt" - "reflect" -) - -var mapStringStringType = reflect.TypeOf(map[string]string(nil)) - -func HstoreAppender(typ reflect.Type) AppenderFunc { - if typ.Key() == stringType && typ.Elem() == stringType { - return appendMapStringStringValue - } - return func(b []byte, v reflect.Value, quote int) []byte { - err := fmt.Errorf("pg.Hstore(unsupported %s)", v.Type()) - return AppendError(b, err) - } -} - -func appendMapStringString(b []byte, m map[string]string, quote int) []byte { - if m == nil { - return AppendNull(b, quote) - } - - if quote == 1 { - b = append(b, '\'') - } - - for key, value := range m { - b = AppendString(b, key, 2) - b = append(b, '=', '>') - b = AppendString(b, value, 2) - b = append(b, ',') - } - if len(m) > 0 { - b = b[:len(b)-1] // Strip trailing comma. - } - - if quote == 1 { - b = append(b, '\'') - } - - return b -} - -func appendMapStringStringValue(b []byte, v reflect.Value, quote int) []byte { - m := v.Convert(mapStringStringType).Interface().(map[string]string) - return appendMapStringString(b, m, quote) -} diff --git a/vendor/github.com/go-pg/pg/types/append_jsonb.go b/vendor/github.com/go-pg/pg/types/append_jsonb.go deleted file mode 100644 index 3bede711f..000000000 --- a/vendor/github.com/go-pg/pg/types/append_jsonb.go +++ /dev/null @@ -1,41 +0,0 @@ -package types - -import "github.com/go-pg/pg/internal/parser" - -func AppendJSONB(b, jsonb []byte, quote int) []byte { - if quote == 1 { - b = append(b, '\'') - } - - p := parser.New(jsonb) - for p.Valid() { - c := p.Read() - switch c { - case '\'': - if quote == 1 { - b = append(b, '\'', '\'') - } else { - b = append(b, '\'') - } - case '\000': - continue - case '\\': - if p.SkipBytes([]byte("u0000")) { - b = append(b, "\\\\u0000"...) - } else { - b = append(b, '\\') - if p.Valid() { - b = append(b, p.Read()) - } - } - default: - b = append(b, c) - } - } - - if quote == 1 { - b = append(b, '\'') - } - - return b -} diff --git a/vendor/github.com/go-pg/pg/types/append_value.go b/vendor/github.com/go-pg/pg/types/append_value.go deleted file mode 100644 index bd1d54338..000000000 --- a/vendor/github.com/go-pg/pg/types/append_value.go +++ /dev/null @@ -1,181 +0,0 @@ -package types - -import ( - "database/sql/driver" - "encoding/json" - "net" - "reflect" - "strconv" - "time" -) - -var driverValuerType = reflect.TypeOf((*driver.Valuer)(nil)).Elem() -var appenderType = reflect.TypeOf((*ValueAppender)(nil)).Elem() - -type AppenderFunc func([]byte, reflect.Value, int) []byte - -var valueAppenders []AppenderFunc - -func init() { - valueAppenders = []AppenderFunc{ - reflect.Bool: appendBoolValue, - reflect.Int: appendIntValue, - reflect.Int8: appendIntValue, - reflect.Int16: appendIntValue, - reflect.Int32: appendIntValue, - reflect.Int64: appendIntValue, - reflect.Uint: appendUintValue, - reflect.Uint8: appendUintValue, - reflect.Uint16: appendUintValue, - reflect.Uint32: appendUintValue, - reflect.Uint64: appendUintValue, - reflect.Uintptr: nil, - reflect.Float32: appendFloatValue, - reflect.Float64: appendFloatValue, - reflect.Complex64: nil, - reflect.Complex128: nil, - reflect.Array: nil, - reflect.Chan: nil, - reflect.Func: nil, - reflect.Interface: appendIfaceValue, - reflect.Map: appendJSONValue, - reflect.Ptr: nil, - reflect.Slice: appendJSONValue, - reflect.String: appendStringValue, - reflect.Struct: appendStructValue, - reflect.UnsafePointer: nil, - } -} - -func Appender(typ reflect.Type) AppenderFunc { - return appender(typ, false) -} - -func appender(typ reflect.Type, pgArray bool) AppenderFunc { - switch typ { - case timeType: - return appendTimeValue - case ipType: - return appendIPValue - case ipNetType: - return appendIPNetValue - } - - if typ.Implements(appenderType) { - return appendAppenderValue - } - - if typ.Implements(driverValuerType) { - return appendDriverValuerValue - } - - kind := typ.Kind() - switch kind { - case reflect.Ptr: - return ptrAppenderFunc(typ) - case reflect.Slice: - if typ.Elem().Kind() == reflect.Uint8 { - return appendBytesValue - } - if pgArray { - return ArrayAppender(typ) - } - case reflect.Array: - if typ.Elem().Kind() == reflect.Uint8 { - return appendArrayBytesValue - } - } - return valueAppenders[kind] -} - -func ptrAppenderFunc(typ reflect.Type) AppenderFunc { - appender := Appender(typ.Elem()) - return func(b []byte, v reflect.Value, quote int) []byte { - if v.IsNil() { - return AppendNull(b, quote) - } - return appender(b, v.Elem(), quote) - } -} - -func appendValue(b []byte, v reflect.Value, quote int) []byte { - if v.Kind() == reflect.Ptr { - if v.IsNil() { - return AppendNull(b, quote) - } - return appendValue(b, v.Elem(), quote) - } - - appender := Appender(v.Type()) - return appender(b, v, quote) -} - -func appendIfaceValue(b []byte, v reflect.Value, quote int) []byte { - return Append(b, v.Interface(), quote) -} - -func appendBoolValue(b []byte, v reflect.Value, _ int) []byte { - return appendBool(b, v.Bool()) -} - -func appendIntValue(b []byte, v reflect.Value, _ int) []byte { - return strconv.AppendInt(b, v.Int(), 10) -} - -func appendUintValue(b []byte, v reflect.Value, _ int) []byte { - return strconv.AppendUint(b, v.Uint(), 10) -} - -func appendFloatValue(b []byte, v reflect.Value, quote int) []byte { - return appendFloat(b, v.Float(), quote) -} - -func appendBytesValue(b []byte, v reflect.Value, quote int) []byte { - return AppendBytes(b, v.Bytes(), quote) -} - -func appendArrayBytesValue(b []byte, v reflect.Value, quote int) []byte { - return AppendBytes(b, v.Slice(0, v.Len()).Bytes(), quote) -} - -func appendStringValue(b []byte, v reflect.Value, quote int) []byte { - return AppendString(b, v.String(), quote) -} - -func appendStructValue(b []byte, v reflect.Value, quote int) []byte { - if v.Type() == timeType { - return appendTimeValue(b, v, quote) - } - return appendJSONValue(b, v, quote) -} - -func appendJSONValue(b []byte, v reflect.Value, quote int) []byte { - bytes, err := json.Marshal(v.Interface()) - if err != nil { - return AppendError(b, err) - } - return AppendJSONB(b, bytes, quote) -} - -func appendTimeValue(b []byte, v reflect.Value, quote int) []byte { - tm := v.Interface().(time.Time) - return AppendTime(b, tm, quote) -} - -func appendIPValue(b []byte, v reflect.Value, quote int) []byte { - ip := v.Interface().(net.IP) - return AppendString(b, ip.String(), quote) -} - -func appendIPNetValue(b []byte, v reflect.Value, quote int) []byte { - ipnet := v.Interface().(net.IPNet) - return AppendString(b, ipnet.String(), quote) -} - -func appendAppenderValue(b []byte, v reflect.Value, quote int) []byte { - return appendAppender(b, v.Interface().(ValueAppender), quote) -} - -func appendDriverValuerValue(b []byte, v reflect.Value, quote int) []byte { - return appendDriverValuer(b, v.Interface().(driver.Valuer), quote) -} diff --git a/vendor/github.com/go-pg/pg/types/array.go b/vendor/github.com/go-pg/pg/types/array.go deleted file mode 100644 index 613b6c97b..000000000 --- a/vendor/github.com/go-pg/pg/types/array.go +++ /dev/null @@ -1,52 +0,0 @@ -package types - -import ( - "database/sql" - "fmt" - "reflect" -) - -type Array struct { - v reflect.Value - - append AppenderFunc - scan ScannerFunc -} - -var _ ValueAppender = (*Array)(nil) -var _ sql.Scanner = (*Array)(nil) - -func NewArray(vi interface{}) *Array { - v := reflect.ValueOf(vi) - if !v.IsValid() { - panic(fmt.Errorf("pg.Array(nil)")) - } - v = reflect.Indirect(v) - if v.Kind() != reflect.Slice { - panic(fmt.Errorf("pg.Array(unsupported %s)", v.Type())) - } - return &Array{ - v: v, - - append: ArrayAppender(v.Type()), - scan: ArrayScanner(v.Type()), - } -} - -func (a *Array) Value() interface{} { - if a.v.IsValid() { - return a.v.Interface() - } - return nil -} - -func (a *Array) AppendValue(b []byte, quote int) []byte { - return a.append(b, a.v, quote) -} - -func (a *Array) Scan(b interface{}) error { - if b == nil { - return a.scan(a.v, nil) - } - return a.scan(a.v, b.([]byte)) -} diff --git a/vendor/github.com/go-pg/pg/types/hstore.go b/vendor/github.com/go-pg/pg/types/hstore.go deleted file mode 100644 index b6241e67e..000000000 --- a/vendor/github.com/go-pg/pg/types/hstore.go +++ /dev/null @@ -1,52 +0,0 @@ -package types - -import ( - "database/sql" - "fmt" - "reflect" -) - -type Hstore struct { - v reflect.Value - - append AppenderFunc - scan ScannerFunc -} - -var _ ValueAppender = (*Hstore)(nil) -var _ sql.Scanner = (*Hstore)(nil) - -func NewHstore(vi interface{}) *Hstore { - v := reflect.ValueOf(vi) - if !v.IsValid() { - panic(fmt.Errorf("pg.Hstore(nil)")) - } - v = reflect.Indirect(v) - if v.Kind() != reflect.Map { - panic(fmt.Errorf("pg.Hstore(unsupported %s)", v.Type())) - } - return &Hstore{ - v: v, - - append: HstoreAppender(v.Type()), - scan: HstoreScanner(v.Type()), - } -} - -func (h *Hstore) Value() interface{} { - if h.v.IsValid() { - return h.v.Interface() - } - return nil -} - -func (h *Hstore) AppendValue(b []byte, quote int) []byte { - return h.append(b, h.v, quote) -} - -func (h *Hstore) Scan(b interface{}) error { - if b == nil { - return h.scan(h.v, nil) - } - return h.scan(h.v, b.([]byte)) -} diff --git a/vendor/github.com/go-pg/pg/types/in_op.go b/vendor/github.com/go-pg/pg/types/in_op.go deleted file mode 100644 index bfe395c67..000000000 --- a/vendor/github.com/go-pg/pg/types/in_op.go +++ /dev/null @@ -1,49 +0,0 @@ -package types - -import ( - "reflect" -) - -type inOp struct { - slice reflect.Value -} - -var _ ValueAppender = (*inOp)(nil) - -func In(values ...interface{}) ValueAppender { - return &inOp{ - slice: reflect.ValueOf(values), - } -} - -func InSlice(slice interface{}) ValueAppender { - return &inOp{ - slice: reflect.ValueOf(slice), - } -} - -func (in *inOp) AppendValue(b []byte, quote int) []byte { - return appendIn(b, in.slice, quote) -} - -func appendIn(b []byte, slice reflect.Value, quote int) []byte { - for i := 0; i < slice.Len(); i++ { - if i > 0 { - b = append(b, ',') - } - - elem := slice.Index(i) - if elem.Kind() == reflect.Interface { - elem = elem.Elem() - } - - if elem.Kind() == reflect.Slice { - b = append(b, '(') - b = appendIn(b, elem, quote) - b = append(b, ')') - } else { - b = appendValue(b, elem, quote) - } - } - return b -} diff --git a/vendor/github.com/go-pg/pg/types/interface.go b/vendor/github.com/go-pg/pg/types/interface.go deleted file mode 100644 index b62ad7e52..000000000 --- a/vendor/github.com/go-pg/pg/types/interface.go +++ /dev/null @@ -1,27 +0,0 @@ -package types - -type ValueAppender interface { - AppendValue(b []byte, quote int) []byte -} - -//------------------------------------------------------------------------------ - -// Q represents safe SQL query. -type Q string - -var _ ValueAppender = Q("") - -func (q Q) AppendValue(b []byte, quote int) []byte { - return append(b, q...) -} - -//------------------------------------------------------------------------------ - -// F represents a SQL field, e.g. table or column name. -type F string - -var _ ValueAppender = F("") - -func (f F) AppendValue(b []byte, quote int) []byte { - return AppendField(b, string(f), quote) -} diff --git a/vendor/github.com/go-pg/pg/types/scan.go b/vendor/github.com/go-pg/pg/types/scan.go deleted file mode 100644 index 602f84810..000000000 --- a/vendor/github.com/go-pg/pg/types/scan.go +++ /dev/null @@ -1,83 +0,0 @@ -package types - -import ( - "database/sql" - "encoding/hex" - "errors" - "fmt" - "reflect" - "time" - - "github.com/go-pg/pg/internal" -) - -func Scan(v interface{}, b []byte) error { - switch v := v.(type) { - case *string: - *v = string(b) - return nil - case *[]byte: - if b == nil { - *v = nil - return nil - } - var err error - *v, err = ScanBytes(b) - return err - case *int: - if b == nil { - *v = 0 - return nil - } - var err error - *v, err = internal.Atoi(b) - return err - case *int64: - if b == nil { - *v = 0 - return nil - } - var err error - *v, err = internal.ParseInt(b, 10, 64) - return err - case *time.Time: - if b == nil { - *v = time.Time{} - return nil - } - var err error - *v, err = ParseTime(b) - return err - } - - vv := reflect.ValueOf(v) - if !vv.IsValid() { - return errors.New("pg: Scan(nil)") - } - if vv.Kind() != reflect.Ptr { - return fmt.Errorf("pg: Scan(nonsettable %T)", v) - } - vv = vv.Elem() - if !vv.IsValid() { - return fmt.Errorf("pg: Scan(nonsettable %T)", v) - } - return ScanValue(vv, b) -} - -func scanSQLScanner(scanner sql.Scanner, b []byte) error { - if b == nil { - return scanner.Scan(nil) - } - return scanner.Scan(b) -} - -func ScanBytes(b []byte) ([]byte, error) { - if len(b) < 2 { - return nil, fmt.Errorf("pg: can't parse bytes: %q", b) - } - - b = b[2:] // Trim off "\\x". - tmp := make([]byte, hex.DecodedLen(len(b))) - _, err := hex.Decode(tmp, b) - return tmp, err -} diff --git a/vendor/github.com/go-pg/pg/types/scan_array.go b/vendor/github.com/go-pg/pg/types/scan_array.go deleted file mode 100644 index 2f000a444..000000000 --- a/vendor/github.com/go-pg/pg/types/scan_array.go +++ /dev/null @@ -1,197 +0,0 @@ -package types - -import ( - "fmt" - "reflect" - - "github.com/go-pg/pg/internal" - "github.com/go-pg/pg/internal/parser" -) - -func ArrayScanner(typ reflect.Type) ScannerFunc { - elemType := typ.Elem() - - switch elemType { - case stringType: - return scanSliceStringValue - case intType: - return scanSliceIntValue - case int64Type: - return scanSliceInt64Value - case float64Type: - return scanSliceFloat64Value - } - - scanElem := scanner(elemType, true) - return func(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - - if b == nil { - if !v.IsNil() { - v.Set(reflect.Zero(v.Type())) - } - return nil - } - - if v.IsNil() { - v.Set(reflect.MakeSlice(v.Type(), 0, 0)) - } else if v.Len() > 0 { - v.Set(v.Slice(0, 0)) - } - - p := parser.NewArrayParser(b) - nextValue := internal.MakeSliceNextElemFunc(v) - for p.Valid() { - elem, err := p.NextElem() - if err != nil { - return err - } - - elemValue := nextValue() - err = scanElem(elemValue, elem) - if err != nil { - return err - } - } - - return nil - } -} - -func scanSliceStringValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - strings, err := decodeSliceString(b) - if err != nil { - return err - } - v.Set(reflect.ValueOf(strings)) - return nil -} - -func decodeSliceString(b []byte) ([]string, error) { - if b == nil { - return nil, nil - } - p := parser.NewArrayParser(b) - s := make([]string, 0) - for p.Valid() { - elem, err := p.NextElem() - if err != nil { - return nil, err - } - s = append(s, string(elem)) - } - return s, nil -} - -func scanSliceIntValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - ints, err := decodeSliceInt(b) - if err != nil { - return err - } - v.Set(reflect.ValueOf(ints)) - return nil -} - -func decodeSliceInt(b []byte) ([]int, error) { - if b == nil { - return nil, nil - } - p := parser.NewArrayParser(b) - slice := make([]int, 0) - for p.Valid() { - elem, err := p.NextElem() - if err != nil { - return nil, err - } - if elem == nil { - slice = append(slice, 0) - continue - } - n, err := internal.Atoi(elem) - if err != nil { - return nil, err - } - slice = append(slice, n) - } - return slice, nil -} - -func scanSliceInt64Value(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - ints, err := decodeSliceInt64(b) - if err != nil { - return err - } - v.Set(reflect.ValueOf(ints)) - return nil -} - -func decodeSliceInt64(b []byte) ([]int64, error) { - if b == nil { - return nil, nil - } - p := parser.NewArrayParser(b) - slice := make([]int64, 0) - for p.Valid() { - elem, err := p.NextElem() - if err != nil { - return nil, err - } - if elem == nil { - slice = append(slice, 0) - continue - } - n, err := internal.ParseInt(elem, 10, 64) - if err != nil { - return nil, err - } - slice = append(slice, n) - } - return slice, nil -} - -func scanSliceFloat64Value(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - floats, err := decodeSliceFloat64(b) - if err != nil { - return err - } - v.Set(reflect.ValueOf(floats)) - return nil -} - -func decodeSliceFloat64(b []byte) ([]float64, error) { - if b == nil { - return nil, nil - } - p := parser.NewArrayParser(b) - slice := make([]float64, 0) - for p.Valid() { - elem, err := p.NextElem() - if err != nil { - return nil, err - } - if elem == nil { - slice = append(slice, 0) - continue - } - n, err := internal.ParseFloat(elem, 64) - if err != nil { - return nil, err - } - slice = append(slice, n) - } - return slice, nil -} diff --git a/vendor/github.com/go-pg/pg/types/scan_hstore.go b/vendor/github.com/go-pg/pg/types/scan_hstore.go deleted file mode 100644 index ee5b62833..000000000 --- a/vendor/github.com/go-pg/pg/types/scan_hstore.go +++ /dev/null @@ -1,58 +0,0 @@ -package types - -import ( - "fmt" - "reflect" - - "github.com/go-pg/pg/internal/parser" -) - -func HstoreScanner(typ reflect.Type) ScannerFunc { - if typ.Key() == stringType && typ.Elem() == stringType { - return scanMapStringStringValue - } - return func(v reflect.Value, b []byte) error { - return fmt.Errorf("pg.Hstore(unsupported %s)", v.Type()) - } -} - -func scanMapStringString(b []byte) (map[string]string, error) { - if b == nil { - return nil, nil - } - - p := parser.NewHstoreParser(b) - m := make(map[string]string) - for p.Valid() { - key, err := p.NextKey() - if err != nil { - return nil, err - } - if key == nil { - return nil, fmt.Errorf("pg: unexpected NULL: %q", b) - } - - value, err := p.NextValue() - if err != nil { - return nil, err - } - if value == nil { - return nil, fmt.Errorf("pg: unexpected NULL: %q", b) - } - - m[string(key)] = string(value) - } - return m, nil -} - -func scanMapStringStringValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - m, err := scanMapStringString(b) - if err != nil { - return err - } - v.Set(reflect.ValueOf(m)) - return nil -} diff --git a/vendor/github.com/go-pg/pg/types/scan_value.go b/vendor/github.com/go-pg/pg/types/scan_value.go deleted file mode 100644 index 0ff35f444..000000000 --- a/vendor/github.com/go-pg/pg/types/scan_value.go +++ /dev/null @@ -1,304 +0,0 @@ -package types - -import ( - "database/sql" - "encoding/json" - "errors" - "fmt" - "net" - "reflect" - "time" - - "github.com/go-pg/pg/internal" -) - -var scannerType = reflect.TypeOf((*sql.Scanner)(nil)).Elem() -var timeType = reflect.TypeOf((*time.Time)(nil)).Elem() -var ipType = reflect.TypeOf((*net.IP)(nil)).Elem() -var ipNetType = reflect.TypeOf((*net.IPNet)(nil)).Elem() - -type ScannerFunc func(reflect.Value, []byte) error - -var valueScanners []ScannerFunc - -func init() { - valueScanners = []ScannerFunc{ - reflect.Bool: scanBoolValue, - reflect.Int: scanIntValue, - reflect.Int8: scanIntValue, - reflect.Int16: scanIntValue, - reflect.Int32: scanIntValue, - reflect.Int64: scanIntValue, - reflect.Uint: scanUintValue, - reflect.Uint8: scanUintValue, - reflect.Uint16: scanUintValue, - reflect.Uint32: scanUintValue, - reflect.Uint64: scanUintValue, - reflect.Uintptr: nil, - reflect.Float32: scanFloatValue, - reflect.Float64: scanFloatValue, - reflect.Complex64: nil, - reflect.Complex128: nil, - reflect.Array: nil, - reflect.Chan: nil, - reflect.Func: nil, - reflect.Interface: scanIfaceValue, - reflect.Map: scanJSONValue, - reflect.Ptr: nil, - reflect.Slice: scanJSONValue, - reflect.String: scanStringValue, - reflect.Struct: scanJSONValue, - reflect.UnsafePointer: nil, - } -} - -func Scanner(typ reflect.Type) ScannerFunc { - return scanner(typ, false) -} - -func scanner(typ reflect.Type, pgArray bool) ScannerFunc { - switch typ { - case timeType: - return scanTimeValue - case ipType: - return scanIPValue - case ipNetType: - return scanIPNetValue - } - - if typ.Implements(scannerType) { - return scanSQLScannerValue - } - if reflect.PtrTo(typ).Implements(scannerType) { - return scanSQLScannerAddrValue - } - - kind := typ.Kind() - switch kind { - case reflect.Ptr: - return ptrScannerFunc(typ) - case reflect.Slice: - if typ.Elem().Kind() == reflect.Uint8 { - return scanBytesValue - } - if pgArray { - return ArrayScanner(typ) - } - } - return valueScanners[kind] -} - -func ptrScannerFunc(typ reflect.Type) ScannerFunc { - scanner := Scanner(typ.Elem()) - return func(v reflect.Value, b []byte) error { - if scanner == nil { - return fmt.Errorf("pg: Scan(unsupported %s)", v.Type()) - } - if b == nil { - if v.IsNil() { - return nil - } - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - v.Set(reflect.Zero(v.Type())) - return nil - } - if v.IsNil() { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - v.Set(reflect.New(v.Type().Elem())) - } - return scanner(v.Elem(), b) - } -} - -func scanIfaceValue(v reflect.Value, b []byte) error { - if v.IsNil() { - return scanJSONValue(v, b) - } - return ScanValue(v.Elem(), b) -} - -func ScanValue(v reflect.Value, b []byte) error { - if !v.IsValid() { - return errors.New("pg: Scan(nil)") - } - - scanner := Scanner(v.Type()) - if scanner != nil { - return scanner(v, b) - } - - if v.Kind() == reflect.Interface { - return errors.New("pg: Scan(nil)") - } - return fmt.Errorf("pg: Scan(unsupported %s)", v.Type()) -} - -func scanBoolValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - if b == nil { - v.SetBool(false) - return nil - } - v.SetBool(len(b) == 1 && (b[0] == 't' || b[0] == '1')) - return nil -} - -func scanIntValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - if b == nil { - v.SetInt(0) - return nil - } - n, err := internal.ParseInt(b, 10, 64) - if err != nil { - return err - } - v.SetInt(n) - return nil -} - -func scanUintValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - if b == nil { - v.SetUint(0) - return nil - } - n, err := internal.ParseUint(b, 10, 64) - if err != nil { - return err - } - v.SetUint(n) - return nil -} - -func scanFloatValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - if b == nil { - v.SetFloat(0) - return nil - } - n, err := internal.ParseFloat(b, 64) - if err != nil { - return err - } - v.SetFloat(n) - return nil -} - -func scanStringValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - v.SetString(string(b)) - return nil -} - -func scanJSONValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - if b == nil { - v.Set(reflect.New(v.Type()).Elem()) - return nil - } - return json.Unmarshal(b, v.Addr().Interface()) -} - -var zeroTimeValue = reflect.ValueOf(time.Time{}) - -func scanTimeValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - if b == nil { - v.Set(zeroTimeValue) - return nil - } - tm, err := ParseTime(b) - if err != nil { - return err - } - v.Set(reflect.ValueOf(tm)) - return nil -} - -func scanIPValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - if b == nil { - return nil - } - ip := net.ParseIP(internal.BytesToString(b)) - if ip == nil { - return fmt.Errorf("pg: invalid ip=%q", b) - } - v.Set(reflect.ValueOf(ip)) - return nil -} - -var zeroIPNetValue = reflect.ValueOf(net.IPNet{}) - -func scanIPNetValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - if b == nil { - v.Set(zeroIPNetValue) - return nil - } - _, ipnet, err := net.ParseCIDR(internal.BytesToString(b)) - if err != nil { - return err - } - v.Set(reflect.ValueOf(*ipnet)) - return nil -} - -func scanBytesValue(v reflect.Value, b []byte) error { - if !v.CanSet() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - if b == nil { - v.SetBytes(nil) - return nil - } - bs, err := ScanBytes(b) - if err != nil { - return err - } - v.SetBytes(bs) - return nil -} - -func scanSQLScannerValue(v reflect.Value, b []byte) error { - if b == nil { - if v.IsNil() { - return nil - } - return scanSQLScanner(v.Interface().(sql.Scanner), nil) - } - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - return scanSQLScanner(v.Interface().(sql.Scanner), b) -} - -func scanSQLScannerAddrValue(v reflect.Value, b []byte) error { - if !v.CanAddr() { - return fmt.Errorf("pg: Scan(nonsettable %s)", v.Type()) - } - return scanSQLScanner(v.Addr().Interface().(sql.Scanner), b) -} diff --git a/vendor/github.com/go-pg/pg/types/time.go b/vendor/github.com/go-pg/pg/types/time.go deleted file mode 100644 index 30c3ed260..000000000 --- a/vendor/github.com/go-pg/pg/types/time.go +++ /dev/null @@ -1,56 +0,0 @@ -package types - -import ( - "time" - - "github.com/go-pg/pg/internal" -) - -const ( - dateFormat = "2006-01-02" - timeFormat = "15:04:05.999999999" - timestampFormat = "2006-01-02 15:04:05.999999999" - timestamptzFormat = "2006-01-02 15:04:05.999999999-07:00:00" - timestamptzFormat2 = "2006-01-02 15:04:05.999999999-07:00" - timestamptzFormat3 = "2006-01-02 15:04:05.999999999-07" -) - -func ParseTime(b []byte) (time.Time, error) { - s := internal.BytesToString(b) - return ParseTimeString(s) -} - -func ParseTimeString(s string) (time.Time, error) { - switch l := len(s); { - case l <= len(timeFormat): - if s[2] == ':' { - return time.ParseInLocation(timeFormat, s, time.UTC) - } - return time.ParseInLocation(dateFormat, s, time.UTC) - default: - if s[10] == 'T' { - return time.Parse(time.RFC3339Nano, s) - } - if c := s[l-9]; c == '+' || c == '-' { - return time.Parse(timestamptzFormat, s) - } - if c := s[l-6]; c == '+' || c == '-' { - return time.Parse(timestamptzFormat2, s) - } - if c := s[l-3]; c == '+' || c == '-' { - return time.Parse(timestamptzFormat3, s) - } - return time.ParseInLocation(timestampFormat, s, time.UTC) - } -} - -func AppendTime(b []byte, tm time.Time, quote int) []byte { - if quote == 1 { - b = append(b, '\'') - } - b = tm.UTC().AppendFormat(b, timestamptzFormat) - if quote == 1 { - b = append(b, '\'') - } - return b -} diff --git a/vendor/github.com/go-toolsmith/astcast/LICENSE b/vendor/github.com/go-toolsmith/astcast/LICENSE deleted file mode 100644 index eef17180f..000000000 --- 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 19ca0e71d..000000000 --- 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 746d568aa..000000000 --- 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 eef17180f..000000000 --- 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 7adc66525..000000000 --- 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 72bc58ce6..000000000 --- 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 1b748bae5..000000000 --- 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 72f800acc..000000000 --- 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 f38c2b852..000000000 --- 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 717f894f5..000000000 --- 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 db5e3a8c9..000000000 --- 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 d1a04e942..000000000 --- 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 cd69b4525..000000000 --- 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 eef17180f..000000000 --- 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 00f790fd2..000000000 --- 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 ca993e033..000000000 --- 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 eef17180f..000000000 --- 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 cf5197e81..000000000 --- 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 4654ad95c..000000000 --- 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 adf9668ce..000000000 --- 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 19645d212..000000000 --- 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 eef17180f..000000000 --- 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 ac04d516f..000000000 --- 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 894c7ebac..000000000 --- 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 eef17180f..000000000 --- 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 77478c443..000000000 --- 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 990bc402c..000000000 --- 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 b07325a72..000000000 --- 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 d5835d97b..000000000 --- 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 61e7d5b7f..000000000 --- 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 1f664d13a..000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/.editorconfig +++ /dev/null @@ -1,18 +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 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 2e0f9f5f7..000000000 --- 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 470e7ca2b..000000000 --- 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 763143aa7..000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/.golangci.yaml +++ /dev/null @@ -1,23 +0,0 @@ -run: - timeout: 5m - -linters-settings: - gci: - sections: - - standard - - default - - prefix(github.com/go-viper/mapstructure) - golint: - min-confidence: 0 - goimports: - local-prefixes: github.com/go-viper/maptstructure - -linters: - disable-all: true - enable: - - gci - - gofmt - - gofumpt - - goimports - - staticcheck - # - stylecheck 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 afd44e5f5..000000000 --- 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 f9c841a51..000000000 --- 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 dd5ec69dd..000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/README.md +++ /dev/null @@ -1,80 +0,0 @@ -# mapstructure - -[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/go-viper/mapstructure/ci.yaml?branch=main&style=flat-square)](https://github.com/go-viper/mapstructure/actions?query=workflow%3ACI) -[![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) -![Go Version](https://img.shields.io/badge/go%20version-%3E=1.18-61CFDD.svg?style=flat-square) - -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 2523c6ad9..000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go +++ /dev/null @@ -1,609 +0,0 @@ -package mapstructure - -import ( - "encoding" - "errors" - "fmt" - "net" - "net/netip" - "reflect" - "strconv" - "strings" - "time" -) - -// typedDecodeHook takes a raw DecodeHookFunc (an interface{}) 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 := []interface{}{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 interface{}) 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) (interface{}, error) { - switch f := typedDecodeHook(raw).(type) { - case DecodeHookFuncType: - return func(from reflect.Value, to reflect.Value) (interface{}, error) { - return f(from.Type(), to.Type(), from.Interface()) - } - case DecodeHookFuncKind: - return func(from reflect.Value, to reflect.Value) (interface{}, error) { - return f(from.Kind(), to.Kind(), from.Interface()) - } - case DecodeHookFuncValue: - return func(from reflect.Value, to reflect.Value) (interface{}, error) { - return f(from, to) - } - default: - return func(from reflect.Value, to reflect.Value) (interface{}, 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, -) (interface{}, 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) (interface{}, error), 0, len(fs)) - for _, f := range fs { - cached = append(cached, cachedDecodeHook(f)) - } - return func(f reflect.Value, t reflect.Value) (interface{}, error) { - var err error - data := f.Interface() - - newFrom := f - for _, c := range cached { - data, err = c(newFrom, t) - if err != nil { - return nil, err - } - 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) (interface{}, error), 0, len(ff)) - for _, f := range ff { - cached = append(cached, cachedDecodeHook(f)) - } - return func(a, b reflect.Value) (interface{}, error) { - var allErrs string - var out interface{} - 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 interface{}, - ) (interface{}, 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 - } -} - -// StringToTimeDurationHookFunc returns a DecodeHookFunc that converts -// strings to time.Duration. -func StringToTimeDurationHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data interface{}, - ) (interface{}, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(time.Duration(5)) { - return data, nil - } - - // Convert it by parsing - return time.ParseDuration(data.(string)) - } -} - -// StringToIPHookFunc returns a DecodeHookFunc that converts -// strings to net.IP -func StringToIPHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data interface{}, - ) (interface{}, 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 %v", data) - } - - 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 interface{}, - ) (interface{}, 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, 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 interface{}, - ) (interface{}, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(time.Time{}) { - return data, nil - } - - // Convert it by parsing - return time.Parse(layout, data.(string)) - } -} - -// 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 interface{}, -) (interface{}, 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) (interface{}, error) { - if f.Kind() != reflect.Struct { - return f.Interface(), nil - } - - var i interface{} = struct{}{} - if t.Type() != reflect.TypeOf(&i).Elem() { - return f.Interface(), nil - } - - m := make(map[string]interface{}) - 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 interface{}, - ) (interface{}, 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 interface{}, - ) (interface{}, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(netip.Addr{}) { - return data, nil - } - - // Convert it by parsing - return netip.ParseAddr(data.(string)) - } -} - -// StringToNetIPAddrPortHookFunc returns a DecodeHookFunc that converts -// strings to netip.AddrPort. -func StringToNetIPAddrPortHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data interface{}, - ) (interface{}, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(netip.AddrPort{}) { - return data, nil - } - - // Convert it by parsing - return netip.ParseAddrPort(data.(string)) - } -} - -// 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 interface{}) (interface{}, 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), err - } -} - -// StringToUint8HookFunc returns a DecodeHookFunc that converts -// strings to uint8. -func StringToUint8HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, 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), err - } -} - -// StringToInt16HookFunc returns a DecodeHookFunc that converts -// strings to int16. -func StringToInt16HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, 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), err - } -} - -// StringToUint16HookFunc returns a DecodeHookFunc that converts -// strings to uint16. -func StringToUint16HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, 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), err - } -} - -// StringToInt32HookFunc returns a DecodeHookFunc that converts -// strings to int32. -func StringToInt32HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, 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), err - } -} - -// StringToUint32HookFunc returns a DecodeHookFunc that converts -// strings to uint32. -func StringToUint32HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, 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), err - } -} - -// StringToInt64HookFunc returns a DecodeHookFunc that converts -// strings to int64. -func StringToInt64HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Int64 { - return data, nil - } - - // Convert it by parsing - return strconv.ParseInt(data.(string), 0, 64) - } -} - -// StringToUint64HookFunc returns a DecodeHookFunc that converts -// strings to uint64. -func StringToUint64HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Uint64 { - return data, nil - } - - // Convert it by parsing - return strconv.ParseUint(data.(string), 0, 64) - } -} - -// StringToIntHookFunc returns a DecodeHookFunc that converts -// strings to int. -func StringToIntHookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, 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), err - } -} - -// StringToUintHookFunc returns a DecodeHookFunc that converts -// strings to uint. -func StringToUintHookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, 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), err - } -} - -// StringToFloat32HookFunc returns a DecodeHookFunc that converts -// strings to float32. -func StringToFloat32HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, 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), err - } -} - -// StringToFloat64HookFunc returns a DecodeHookFunc that converts -// strings to float64. -func StringToFloat64HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Float64 { - return data, nil - } - - // Convert it by parsing - return strconv.ParseFloat(data.(string), 64) - } -} - -// StringToBoolHookFunc returns a DecodeHookFunc that converts -// strings to bool. -func StringToBoolHookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Bool { - return data, nil - } - - // Convert it by parsing - return strconv.ParseBool(data.(string)) - } -} - -// 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 interface{}) (interface{}, 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), err - } -} - -// StringToComplex128HookFunc returns a DecodeHookFunc that converts -// strings to complex128. -func StringToComplex128HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Complex128 { - return data, nil - } - - // Convert it by parsing - return strconv.ParseComplex(data.(string), 128) - } -} 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 4bea8154e..000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/flake.lock +++ /dev/null @@ -1,472 +0,0 @@ -{ - "nodes": { - "cachix": { - "inputs": { - "devenv": "devenv_2", - "flake-compat": [ - "devenv", - "flake-compat" - ], - "nixpkgs": [ - "devenv", - "nixpkgs" - ], - "pre-commit-hooks": [ - "devenv", - "pre-commit-hooks" - ] - }, - "locked": { - "lastModified": 1712055811, - "narHash": "sha256-7FcfMm5A/f02yyzuavJe06zLa9hcMHsagE28ADcmQvk=", - "owner": "cachix", - "repo": "cachix", - "rev": "02e38da89851ec7fec3356a5c04bc8349cae0e30", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "cachix", - "type": "github" - } - }, - "devenv": { - "inputs": { - "cachix": "cachix", - "flake-compat": "flake-compat_2", - "nix": "nix_2", - "nixpkgs": "nixpkgs_2", - "pre-commit-hooks": "pre-commit-hooks" - }, - "locked": { - "lastModified": 1717245169, - "narHash": "sha256-+mW3rTBjGU8p1THJN0lX/Dd/8FbnF+3dB+mJuSaxewE=", - "owner": "cachix", - "repo": "devenv", - "rev": "c3f9f053c077c6f88a3de5276d9178c62baa3fc3", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "devenv", - "type": "github" - } - }, - "devenv_2": { - "inputs": { - "flake-compat": [ - "devenv", - "cachix", - "flake-compat" - ], - "nix": "nix", - "nixpkgs": "nixpkgs", - "poetry2nix": "poetry2nix", - "pre-commit-hooks": [ - "devenv", - "cachix", - "pre-commit-hooks" - ] - }, - "locked": { - "lastModified": 1708704632, - "narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=", - "owner": "cachix", - "repo": "devenv", - "rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "python-rewrite", - "repo": "devenv", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_2": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib" - }, - "locked": { - "lastModified": 1717285511, - "narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1689068808, - "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_2": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "devenv", - "pre-commit-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" - } - }, - "nix": { - "inputs": { - "flake-compat": "flake-compat", - "nixpkgs": [ - "devenv", - "cachix", - "devenv", - "nixpkgs" - ], - "nixpkgs-regression": "nixpkgs-regression" - }, - "locked": { - "lastModified": 1712911606, - "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", - "owner": "domenkozar", - "repo": "nix", - "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", - "type": "github" - }, - "original": { - "owner": "domenkozar", - "ref": "devenv-2.21", - "repo": "nix", - "type": "github" - } - }, - "nix-github-actions": { - "inputs": { - "nixpkgs": [ - "devenv", - "cachix", - "devenv", - "poetry2nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1688870561, - "narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=", - "owner": "nix-community", - "repo": "nix-github-actions", - "rev": "165b1650b753316aa7f1787f3005a8d2da0f5301", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nix-github-actions", - "type": "github" - } - }, - "nix_2": { - "inputs": { - "flake-compat": [ - "devenv", - "flake-compat" - ], - "nixpkgs": [ - "devenv", - "nixpkgs" - ], - "nixpkgs-regression": "nixpkgs-regression_2" - }, - "locked": { - "lastModified": 1712911606, - "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", - "owner": "domenkozar", - "repo": "nix", - "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", - "type": "github" - }, - "original": { - "owner": "domenkozar", - "ref": "devenv-2.21", - "repo": "nix", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1692808169, - "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-lib": { - "locked": { - "lastModified": 1717284937, - "narHash": "sha256-lIbdfCsf8LMFloheeE6N31+BMIeixqyQWbSr2vk79EQ=", - "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz" - }, - "original": { - "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz" - } - }, - "nixpkgs-regression": { - "locked": { - "lastModified": 1643052045, - "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - } - }, - "nixpkgs-regression_2": { - "locked": { - "lastModified": 1643052045, - "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - } - }, - "nixpkgs-stable": { - "locked": { - "lastModified": 1710695816, - "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "614b4613980a522ba49f0d194531beddbb7220d3", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1713361204, - "narHash": "sha256-TA6EDunWTkc5FvDCqU3W2T3SFn0gRZqh6D/hJnM02MM=", - "owner": "cachix", - "repo": "devenv-nixpkgs", - "rev": "285676e87ad9f0ca23d8714a6ab61e7e027020c6", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "rolling", - "repo": "devenv-nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1717112898, - "narHash": "sha256-7R2ZvOnvd9h8fDd65p0JnB7wXfUvreox3xFdYWd1BnY=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "6132b0f6e344ce2fe34fc051b72fb46e34f668e0", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "poetry2nix": { - "inputs": { - "flake-utils": "flake-utils", - "nix-github-actions": "nix-github-actions", - "nixpkgs": [ - "devenv", - "cachix", - "devenv", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1692876271, - "narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=", - "owner": "nix-community", - "repo": "poetry2nix", - "rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "poetry2nix", - "type": "github" - } - }, - "pre-commit-hooks": { - "inputs": { - "flake-compat": [ - "devenv", - "flake-compat" - ], - "flake-utils": "flake-utils_2", - "gitignore": "gitignore", - "nixpkgs": [ - "devenv", - "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable" - }, - "locked": { - "lastModified": 1713775815, - "narHash": "sha256-Wu9cdYTnGQQwtT20QQMg7jzkANKQjwBD9iccfGKkfls=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "2ac4dcbf55ed43f3be0bae15e181f08a57af24a4", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, - "root": { - "inputs": { - "devenv": "devenv", - "flake-parts": "flake-parts", - "nixpkgs": "nixpkgs_3" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_2": { - "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/go-viper/mapstructure/v2/flake.nix b/vendor/github.com/go-viper/mapstructure/v2/flake.nix deleted file mode 100644 index 4ed0f5331..000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/flake.nix +++ /dev/null @@ -1,39 +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 = { config, self', inputs', pkgs, system, ... }: 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 d1c15e474..000000000 --- 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 d74e3a0b5..000000000 --- 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 700b40229..000000000 --- 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 1cd6204bb..000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go +++ /dev/null @@ -1,1593 +0,0 @@ -// Package mapstructure exposes functionality to convert one arbitrary -// Go type into another, typically to convert a map[string]interface{} -// 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]interface{}{ -// "person": map[string]interface{}{"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]interface{}{ -// "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]interface{}{ -// "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]interface{}" or "map[interface{}]interface{}". -// See example below: -// -// type Friend struct { -// Name string -// Other map[string]interface{} `mapstructure:",remain"` -// } -// -// Given the input below, Other would be populated with the other -// values that weren't used (everything but "name"): -// -// map[string]interface{}{ -// "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. 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. -// -// type Source struct { -// Age int `mapstructure:",omitempty"` -// } -// -// # 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]interface{}{ -// "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 interface{} - -// DecodeHookFuncType is a DecodeHookFunc which has complete information about -// the source and target types. -type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error) - -// DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the -// source and target types. -type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, 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) (interface{}, 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 - - // 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 interface{} - - // 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 -} - -// 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) (interface{}, 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 interface{}, output interface{}) 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 interface{}) 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 interface{}, output interface{}, 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 interface{}, output interface{}, 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 interface{}) 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 -} - -// Decodes an unknown data type into a specific reflection value. -func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error { - var inputVal reflect.Value - if input != nil { - inputVal = reflect.ValueOf(input) - - // We need to check here if input is a typed nil. Typed nils won't - // match the "input == nil" below so we check that here. - if inputVal.Kind() == reflect.Ptr && inputVal.IsNil() { - 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) - } - } - return nil - } - - if !inputVal.IsValid() { - // 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 - } - - 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 fmt.Errorf("error decoding '%s': %w", name, err) - } - } - - var err error - outputKind := getKind(outVal) - 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 fmt.Errorf("%s: unsupported type: %s", name, 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 interface{}, 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 fmt.Errorf( - "'%s' expected type '%s', got '%s'", - name, val.Type(), dataValType) - } - - val.Set(dataVal) - return nil -} - -func (d *Decoder) decodeString(name string, data interface{}, 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 fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", - name, val.Type(), dataVal.Type(), data) - } - - return nil -} - -func (d *Decoder) decodeInt(name string, data interface{}, 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 fmt.Errorf("cannot parse '%s' as int: %s", name, err) - } - case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": - jn := data.(json.Number) - i, err := jn.Int64() - if err != nil { - return fmt.Errorf( - "error decoding json.Number into %s: %s", name, err) - } - val.SetInt(i) - default: - return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", - name, val.Type(), dataVal.Type(), data) - } - - return nil -} - -func (d *Decoder) decodeUint(name string, data interface{}, 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 fmt.Errorf("cannot parse '%s', %d overflows uint", - name, 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 fmt.Errorf("cannot parse '%s', %f overflows uint", - name, 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 fmt.Errorf("cannot parse '%s' as uint: %s", name, 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 fmt.Errorf( - "error decoding json.Number into %s: %s", name, err) - } - val.SetUint(i) - default: - return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", - name, val.Type(), dataVal.Type(), data) - } - - return nil -} - -func (d *Decoder) decodeBool(name string, data interface{}, 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 fmt.Errorf("cannot parse '%s' as bool: %s", name, err) - } - default: - return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", - name, val.Type(), dataVal.Type(), data) - } - - return nil -} - -func (d *Decoder) decodeFloat(name string, data interface{}, 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 fmt.Errorf("cannot parse '%s' as float: %s", name, err) - } - case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": - jn := data.(json.Number) - i, err := jn.Float64() - if err != nil { - return fmt.Errorf( - "error decoding json.Number into %s: %s", name, err) - } - val.SetFloat(i) - default: - return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", - name, val.Type(), dataVal.Type(), data) - } - - return nil -} - -func (d *Decoder) decodeComplex(name string, data interface{}, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - - switch { - case dataKind == reflect.Complex64: - val.SetComplex(dataVal.Complex()) - default: - return fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", - name, val.Type(), dataVal.Type(), data) - } - - return nil -} - -func (d *Decoder) decodeMap(name string, data interface{}, 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 fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) - } -} - -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 fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", 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 "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 fmt.Errorf("cannot squash non-struct type '%s'", v.Type()) - } - } else { - if strings.Index(tagValue[index+1:], "remain") != -1 { - if v.Kind() != reflect.Map { - return fmt.Errorf("error remain-tag field with invalid type: '%s'", 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 interface{}, 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 interface{}, 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 fmt.Errorf( - "'%s' expected type '%s', got unconvertible type '%s', value: '%v'", - name, val.Type(), dataVal.Type(), data) - } - val.Set(dataVal) - return nil -} - -func (d *Decoder) decodeSlice(name string, data interface{}, 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, []interface{}{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, []interface{}{data}, val) - } - } - - return fmt.Errorf( - "'%s': source data must be an array or slice, got %s", name, 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 interface{}, 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, []interface{}{data}, val) - } - } - - return fmt.Errorf( - "'%s': source data must be an array or slice, got %s", name, dataValKind) - - } - if dataVal.Len() > arrayType.Len() { - return fmt.Errorf( - "'%s': expected source data to have length less or equal to %d, got %d", name, 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 interface{}, 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]interface{})(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 fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) - } -} - -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 fmt.Errorf( - "'%s' needs a map with string keys, has '%s' keys", - name, dataValType.Key().Kind()) - } - - dataValKeys := make(map[reflect.Value]struct{}) - dataValKeysUnused := make(map[interface{}]struct{}) - for _, dataValKey := range dataVal.MapKeys() { - dataValKeys[dataValKey] = struct{}{} - dataValKeysUnused[dataValKey.Interface()] = struct{}{} - } - - targetValKeysUnused := make(map[interface{}]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, fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, 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. - 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[interface{}]interface{}{} - 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) - - err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", ")) - errs = append(errs, err) - } - - 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) - - err := fmt.Errorf("'%s' has unset fields: %s", name, strings.Join(keys, ", ")) - errs = append(errs, err) - } - - 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 d0913fff6..000000000 --- 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 f8255a1b1..000000000 --- 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 890776ab7..000000000 --- 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 9f661ea2d..000000000 --- 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 4245e5ad7..000000000 --- a/vendor/github.com/go-xmlfmt/xmlfmt/xmlfmt.go +++ /dev/null @@ -1,92 +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(`<([/!]?)([^>]+?)(/?)>`) - // 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] - } - reXmlComments := regexp.MustCompile(`(?s)()`) - src := regexp.MustCompile(`(?s)>\s+<`).ReplaceAllString(xmls, "><") - if nestedTagsInComment { - src = reXmlComments.ReplaceAllStringFunc(src, func(m string) string { - parts := reXmlComments.FindStringSubmatch(m) - p2 := regexp.MustCompile(`\r*\n`).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 02e7de80a..000000000 --- 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 2afde343a..000000000 --- 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 514a9a5c4..000000000 --- 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 8e65356cd..000000000 --- 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 a8130e93e..000000000 --- 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 0998e95b0..000000000 --- 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 7c968ee36..000000000 --- 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 7fd763ecd..000000000 --- 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 f80e007fb..000000000 --- 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 d72f69eff..000000000 --- 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 db57ac8eb..000000000 --- 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 0d4ecd36b..000000000 --- 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 a7347250e..000000000 --- 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 8ee58fe1b..000000000 --- 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 8208085a1..000000000 --- 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 ce30245a4..000000000 --- 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 4379042e4..000000000 --- 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 9ea6f3094..000000000 --- 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 ee6e3954c..000000000 --- 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 85bea8c68..000000000 --- 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 c5106f819..000000000 --- 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 3875950bb..000000000 --- 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 0a17616d3..000000000 --- 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 f58144e73..000000000 --- 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 3220a694a..000000000 --- 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 429b40943..000000000 --- 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 a1c8d1962..000000000 --- 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 2797c4e83..000000000 --- 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 1d168b148..000000000 --- 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 a72355641..000000000 --- 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 e8ee1920b..000000000 --- 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/gofrs/flock/.gitignore b/vendor/github.com/gofrs/flock/.gitignore deleted file mode 100644 index daf913b1b..000000000 --- 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 3ad88a38f..000000000 --- a/vendor/github.com/gofrs/flock/.golangci.yml +++ /dev/null @@ -1,114 +0,0 @@ -run: - timeout: 10m - -linters: - enable: - - asasalint - - bidichk - - dogsled - - dupword - - durationcheck - - err113 - - errname - - errorlint - - fatcontext - - forbidigo - - gocheckcompilerdirectives - - gochecknoinits - - gocritic - - godot - - godox - - gofumpt - - goheader - - goimports - - gomoddirectives - - goprintffuncname - - gosec - - inamedparam - - interfacebloat - - ireturn - - mirror - - misspell - - nolintlint - - revive - - stylecheck - - tenv - - testifylint - - thelper - - unconvert - - unparam - - usestdlibvars - - whitespace - -linters-settings: - misspell: - locale: US - 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. - gofumpt: - extra-rules: true - gocritic: - enabled-tags: - - diagnostic - - style - - performance - disabled-checks: - - paramTypeCombine # already handle by gofumpt.extra-rules - - whyNoLint # already handle by nonolint - - unnamedResult - - hugeParam - - sloppyReassign - - rangeValCopy - - octalLiteral - - ptrToRefParam - - appendAssign - - ruleguard - - httpNoBody - - exposedSyncMutex - - 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 - -issues: - exclude-use-default: true - max-issues-per-linter: 0 - max-same-issues: 0 - -output: - show-stats: true - sort-results: true - sort-order: - - linter - - file diff --git a/vendor/github.com/gofrs/flock/LICENSE b/vendor/github.com/gofrs/flock/LICENSE deleted file mode 100644 index 7de525bf0..000000000 --- a/vendor/github.com/gofrs/flock/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2018-2024, 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 65c139d68..000000000 --- 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 f7ca0dd9c..000000000 --- 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 01419bd59..000000000 --- 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 60f7809f0..000000000 --- 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 ff942b228..000000000 --- a/vendor/github.com/gofrs/flock/flock.go +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2024 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 -} - -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): - // try again - } - } -} - -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 18b14f1bd..000000000 --- a/vendor/github.com/gofrs/flock/flock_others.go +++ /dev/null @@ -1,40 +0,0 @@ -//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 cf8919c7a..000000000 --- a/vendor/github.com/gofrs/flock/flock_unix.go +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2024 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 ea007b47d..000000000 --- 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-2024 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 dfd31e15f..000000000 --- a/vendor/github.com/gofrs/flock/flock_windows.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2024 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. -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-jwt/jwt/v5/.gitignore b/vendor/github.com/golang-jwt/jwt/v5/.gitignore deleted file mode 100644 index 09573e016..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.DS_Store -bin -.idea/ - diff --git a/vendor/github.com/golang-jwt/jwt/v5/LICENSE b/vendor/github.com/golang-jwt/jwt/v5/LICENSE deleted file mode 100644 index 35dbc2520..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (c) 2012 Dave Grijalva -Copyright (c) 2021 golang-jwt maintainers - -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/golang-jwt/jwt/v5/MIGRATION_GUIDE.md b/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md deleted file mode 100644 index ff9c57e1d..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md +++ /dev/null @@ -1,195 +0,0 @@ -# Migration Guide (v5.0.0) - -Version `v5` contains a major rework of core functionalities in the `jwt-go` -library. This includes support for several validation options as well as a -re-design of the `Claims` interface. Lastly, we reworked how errors work under -the hood, which should provide a better overall developer experience. - -Starting from [v5.0.0](https://github.com/golang-jwt/jwt/releases/tag/v5.0.0), -the import path will be: - - "github.com/golang-jwt/jwt/v5" - -For most users, changing the import path *should* suffice. However, since we -intentionally changed and cleaned some of the public API, existing programs -might need to be updated. The following sections describe significant changes -and corresponding updates for existing programs. - -## Parsing and Validation Options - -Under the hood, a new `Validator` struct takes care of validating the claims. A -long awaited feature has been the option to fine-tune the validation of tokens. -This is now possible with several `ParserOption` functions that can be appended -to most `Parse` functions, such as `ParseWithClaims`. The most important options -and changes are: - * Added `WithLeeway` to support specifying the leeway that is allowed when - validating time-based claims, such as `exp` or `nbf`. - * Changed default behavior to not check the `iat` claim. Usage of this claim - is OPTIONAL according to the JWT RFC. The claim itself is also purely - informational according to the RFC, so a strict validation failure is not - recommended. If you want to check for sensible values in these claims, - please use the `WithIssuedAt` parser option. - * Added `WithAudience`, `WithSubject` and `WithIssuer` to support checking for - expected `aud`, `sub` and `iss`. - * Added `WithStrictDecoding` and `WithPaddingAllowed` options to allow - previously global settings to enable base64 strict encoding and the parsing - of base64 strings with padding. The latter is strictly speaking against the - standard, but unfortunately some of the major identity providers issue some - of these incorrect tokens. Both options are disabled by default. - -## Changes to the `Claims` interface - -### Complete Restructuring - -Previously, the claims interface was satisfied with an implementation of a -`Valid() error` function. This had several issues: - * The different claim types (struct claims, map claims, etc.) then contained - similar (but not 100 % identical) code of how this validation was done. This - lead to a lot of (almost) duplicate code and was hard to maintain - * It was not really semantically close to what a "claim" (or a set of claims) - really is; which is a list of defined key/value pairs with a certain - semantic meaning. - -Since all the validation functionality is now extracted into the validator, all -`VerifyXXX` and `Valid` functions have been removed from the `Claims` interface. -Instead, the interface now represents a list of getters to retrieve values with -a specific meaning. This allows us to completely decouple the validation logic -with the underlying storage representation of the claim, which could be a -struct, a map or even something stored in a database. - -```go -type Claims interface { - GetExpirationTime() (*NumericDate, error) - GetIssuedAt() (*NumericDate, error) - GetNotBefore() (*NumericDate, error) - GetIssuer() (string, error) - GetSubject() (string, error) - GetAudience() (ClaimStrings, error) -} -``` - -Users that previously directly called the `Valid` function on their claims, -e.g., to perform validation independently of parsing/verifying a token, can now -use the `jwt.NewValidator` function to create a `Validator` independently of the -`Parser`. - -```go -var v = jwt.NewValidator(jwt.WithLeeway(5*time.Second)) -v.Validate(myClaims) -``` - -### Supported Claim Types and Removal of `StandardClaims` - -The two standard claim types supported by this library, `MapClaims` and -`RegisteredClaims` both implement the necessary functions of this interface. The -old `StandardClaims` struct, which has already been deprecated in `v4` is now -removed. - -Users using custom claims, in most cases, will not experience any changes in the -behavior as long as they embedded `RegisteredClaims`. If they created a new -claim type from scratch, they now need to implemented the proper getter -functions. - -### Migrating Application Specific Logic of the old `Valid` - -Previously, users could override the `Valid` method in a custom claim, for -example to extend the validation with application-specific claims. However, this -was always very dangerous, since once could easily disable the standard -validation and signature checking. - -In order to avoid that, while still supporting the use-case, a new -`ClaimsValidator` interface has been introduced. This interface consists of the -`Validate() error` function. If the validator sees, that a `Claims` struct -implements this interface, the errors returned to the `Validate` function will -be *appended* to the regular standard validation. It is not possible to disable -the standard validation anymore (even only by accident). - -Usage examples can be found in [example_test.go](./example_test.go), to build -claims structs like the following. - -```go -// MyCustomClaims includes all registered claims, plus Foo. -type MyCustomClaims struct { - Foo string `json:"foo"` - jwt.RegisteredClaims -} - -// Validate can be used to execute additional application-specific claims -// validation. -func (m MyCustomClaims) Validate() error { - if m.Foo != "bar" { - return errors.New("must be foobar") - } - - return nil -} -``` - -## Changes to the `Token` and `Parser` struct - -The previously global functions `DecodeSegment` and `EncodeSegment` were moved -to the `Parser` and `Token` struct respectively. This will allow us in the -future to configure the behavior of these two based on options supplied on the -parser or the token (creation). This also removes two previously global -variables and moves them to parser options `WithStrictDecoding` and -`WithPaddingAllowed`. - -In order to do that, we had to adjust the way signing methods work. Previously -they were given a base64 encoded signature in `Verify` and were expected to -return a base64 encoded version of the signature in `Sign`, both as a `string`. -However, this made it necessary to have `DecodeSegment` and `EncodeSegment` -global and was a less than perfect design because we were repeating -encoding/decoding steps for all signing methods. Now, `Sign` and `Verify` -operate on a decoded signature as a `[]byte`, which feels more natural for a -cryptographic operation anyway. Lastly, `Parse` and `SignedString` take care of -the final encoding/decoding part. - -In addition to that, we also changed the `Signature` field on `Token` from a -`string` to `[]byte` and this is also now populated with the decoded form. This -is also more consistent, because the other parts of the JWT, mainly `Header` and -`Claims` were already stored in decoded form in `Token`. Only the signature was -stored in base64 encoded form, which was redundant with the information in the -`Raw` field, which contains the complete token as base64. - -```go -type Token struct { - Raw string // Raw contains the raw token - Method SigningMethod // Method is the signing method used or to be used - Header map[string]interface{} // Header is the first segment of the token in decoded form - Claims Claims // Claims is the second segment of the token in decoded form - Signature []byte // Signature is the third segment of the token in decoded form - Valid bool // Valid specifies if the token is valid -} -``` - -Most (if not all) of these changes should not impact the normal usage of this -library. Only users directly accessing the `Signature` field as well as -developers of custom signing methods should be affected. - -# Migration Guide (v4.0.0) - -Starting from [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0), -the import path will be: - - "github.com/golang-jwt/jwt/v4" - -The `/v4` version will be backwards compatible with existing `v3.x.y` tags in -this repo, as well as `github.com/dgrijalva/jwt-go`. For most users this should -be a drop-in replacement, if you're having troubles migrating, please open an -issue. - -You can replace all occurrences of `github.com/dgrijalva/jwt-go` or -`github.com/golang-jwt/jwt` with `github.com/golang-jwt/jwt/v4`, either manually -or by using tools such as `sed` or `gofmt`. - -And then you'd typically run: - -``` -go get github.com/golang-jwt/jwt/v4 -go mod tidy -``` - -# Older releases (before v3.2.0) - -The original migration guide for older releases can be found at -https://github.com/dgrijalva/jwt-go/blob/master/MIGRATION_GUIDE.md. diff --git a/vendor/github.com/golang-jwt/jwt/v5/README.md b/vendor/github.com/golang-jwt/jwt/v5/README.md deleted file mode 100644 index 964598a31..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/README.md +++ /dev/null @@ -1,167 +0,0 @@ -# jwt-go - -[![build](https://github.com/golang-jwt/jwt/actions/workflows/build.yml/badge.svg)](https://github.com/golang-jwt/jwt/actions/workflows/build.yml) -[![Go -Reference](https://pkg.go.dev/badge/github.com/golang-jwt/jwt/v5.svg)](https://pkg.go.dev/github.com/golang-jwt/jwt/v5) -[![Coverage Status](https://coveralls.io/repos/github/golang-jwt/jwt/badge.svg?branch=main)](https://coveralls.io/github/golang-jwt/jwt?branch=main) - -A [go](http://www.golang.org) (or 'golang' for search engine friendliness) -implementation of [JSON Web -Tokens](https://datatracker.ietf.org/doc/html/rfc7519). - -Starting with [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0) -this project adds Go module support, but maintains backwards compatibility with -older `v3.x.y` tags and upstream `github.com/dgrijalva/jwt-go`. See the -[`MIGRATION_GUIDE.md`](./MIGRATION_GUIDE.md) for more information. Version -v5.0.0 introduces major improvements to the validation of tokens, but is not -entirely backwards compatible. - -> After the original author of the library suggested migrating the maintenance -> of `jwt-go`, a dedicated team of open source maintainers decided to clone the -> existing library into this repository. See -> [dgrijalva/jwt-go#462](https://github.com/dgrijalva/jwt-go/issues/462) for a -> detailed discussion on this topic. - - -**SECURITY NOTICE:** Some older versions of Go have a security issue in the -crypto/elliptic. Recommendation is to upgrade to at least 1.15 See issue -[dgrijalva/jwt-go#216](https://github.com/dgrijalva/jwt-go/issues/216) for more -detail. - -**SECURITY NOTICE:** It's important that you [validate the `alg` presented is -what you -expect](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/). -This library attempts to make it easy to do the right thing by requiring key -types match the expected alg, but you should take the extra step to verify it in -your usage. See the examples provided. - -### Supported Go versions - -Our support of Go versions is aligned with Go's [version release -policy](https://golang.org/doc/devel/release#policy). So we will support a major -version of Go until there are two newer major releases. We no longer support -building jwt-go with unsupported Go versions, as these contain security -vulnerabilities which will not be fixed. - -## What the heck is a JWT? - -JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web -Tokens. - -In short, it's a signed JSON object that does something useful (for example, -authentication). It's commonly used for `Bearer` tokens in Oauth 2. A token is -made of three parts, separated by `.`'s. The first two parts are JSON objects, -that have been [base64url](https://datatracker.ietf.org/doc/html/rfc4648) -encoded. The last part is the signature, encoded the same way. - -The first part is called the header. It contains the necessary information for -verifying the last part, the signature. For example, which encryption method -was used for signing and what key was used. - -The part in the middle is the interesting bit. It's called the Claims and -contains the actual stuff you care about. Refer to [RFC -7519](https://datatracker.ietf.org/doc/html/rfc7519) for information about -reserved keys and the proper way to add your own. - -## What's in the box? - -This library supports the parsing and verification as well as the generation and -signing of JWTs. Current supported signing algorithms are HMAC SHA, RSA, -RSA-PSS, and ECDSA, though hooks are present for adding your own. - -## Installation Guidelines - -1. To install the jwt package, you first need to have - [Go](https://go.dev/doc/install) installed, then you can use the command - below to add `jwt-go` as a dependency in your Go program. - -```sh -go get -u github.com/golang-jwt/jwt/v5 -``` - -2. Import it in your code: - -```go -import "github.com/golang-jwt/jwt/v5" -``` - -## Usage - -A detailed usage guide, including how to sign and verify tokens can be found on -our [documentation website](https://golang-jwt.github.io/jwt/usage/create/). - -## Examples - -See [the project documentation](https://pkg.go.dev/github.com/golang-jwt/jwt/v5) -for examples of usage: - -* [Simple example of parsing and validating a - token](https://pkg.go.dev/github.com/golang-jwt/jwt/v5#example-Parse-Hmac) -* [Simple example of building and signing a - token](https://pkg.go.dev/github.com/golang-jwt/jwt/v5#example-New-Hmac) -* [Directory of - Examples](https://pkg.go.dev/github.com/golang-jwt/jwt/v5#pkg-examples) - -## Compliance - -This library was last reviewed to comply with [RFC -7519](https://datatracker.ietf.org/doc/html/rfc7519) dated May 2015 with a few -notable differences: - -* In order to protect against accidental use of [Unsecured - JWTs](https://datatracker.ietf.org/doc/html/rfc7519#section-6), tokens using - `alg=none` will only be accepted if the constant - `jwt.UnsafeAllowNoneSignatureType` is provided as the key. - -## Project Status & Versioning - -This library is considered production ready. Feedback and feature requests are -appreciated. The API should be considered stable. There should be very few -backwards-incompatible changes outside of major version updates (and only with -good reason). - -This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull -requests will land on `main`. Periodically, versions will be tagged from -`main`. You can find all the releases on [the project releases -page](https://github.com/golang-jwt/jwt/releases). - -**BREAKING CHANGES:*** A full list of breaking changes is available in -`VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating -your code. - -## Extensions - -This library publishes all the necessary components for adding your own signing -methods or key functions. Simply implement the `SigningMethod` interface and -register a factory method using `RegisterSigningMethod` or provide a -`jwt.Keyfunc`. - -A common use case would be integrating with different 3rd party signature -providers, like key management services from various cloud providers or Hardware -Security Modules (HSMs) or to implement additional standards. - -| Extension | Purpose | Repo | -| --------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| GCP | Integrates with multiple Google Cloud Platform signing tools (AppEngine, IAM API, Cloud KMS) | https://github.com/someone1/gcp-jwt-go | -| AWS | Integrates with AWS Key Management Service, KMS | https://github.com/matelang/jwt-go-aws-kms | -| JWKS | Provides support for JWKS ([RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517)) as a `jwt.Keyfunc` | https://github.com/MicahParks/keyfunc | - -*Disclaimer*: Unless otherwise specified, these integrations are maintained by -third parties and should not be considered as a primary offer by any of the -mentioned cloud providers - -## More - -Go package documentation can be found [on -pkg.go.dev](https://pkg.go.dev/github.com/golang-jwt/jwt/v5). Additional -documentation can be found on [our project -page](https://golang-jwt.github.io/jwt/). - -The command line utility included in this project (cmd/jwt) provides a -straightforward example of token creation and parsing as well as a useful tool -for debugging your own integration. You'll also find several implementation -examples in the documentation. - -[golang-jwt](https://github.com/orgs/golang-jwt) incorporates a modified version -of the JWT logo, which is distributed under the terms of the [MIT -License](https://github.com/jsonwebtoken/jsonwebtoken.github.io/blob/master/LICENSE.txt). diff --git a/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md b/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md deleted file mode 100644 index b08402c34..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md +++ /dev/null @@ -1,19 +0,0 @@ -# Security Policy - -## Supported Versions - -As of February 2022 (and until this document is updated), the latest version `v4` is supported. - -## Reporting a Vulnerability - -If you think you found a vulnerability, and even if you are not sure, please report it to jwt-go-security@googlegroups.com or one of the other [golang-jwt maintainers](https://github.com/orgs/golang-jwt/people). Please try be explicit, describe steps to reproduce the security issue with code example(s). - -You will receive a response within a timely manner. If the issue is confirmed, we will do our best to release a patch as soon as possible given the complexity of the problem. - -## Public Discussions - -Please avoid publicly discussing a potential security vulnerability. - -Let's take this offline and find a solution first, this limits the potential impact as much as possible. - -We appreciate your help! diff --git a/vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md b/vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md deleted file mode 100644 index b5039e49c..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md +++ /dev/null @@ -1,137 +0,0 @@ -# `jwt-go` Version History - -The following version history is kept for historic purposes. To retrieve the current changes of each version, please refer to the change-log of the specific release versions on https://github.com/golang-jwt/jwt/releases. - -## 4.0.0 - -* Introduces support for Go modules. The `v4` version will be backwards compatible with `v3.x.y`. - -## 3.2.2 - -* Starting from this release, we are adopting the policy to support the most 2 recent versions of Go currently available. By the time of this release, this is Go 1.15 and 1.16 ([#28](https://github.com/golang-jwt/jwt/pull/28)). -* Fixed a potential issue that could occur when the verification of `exp`, `iat` or `nbf` was not required and contained invalid contents, i.e. non-numeric/date. Thanks for @thaJeztah for making us aware of that and @giorgos-f3 for originally reporting it to the formtech fork ([#40](https://github.com/golang-jwt/jwt/pull/40)). -* Added support for EdDSA / ED25519 ([#36](https://github.com/golang-jwt/jwt/pull/36)). -* Optimized allocations ([#33](https://github.com/golang-jwt/jwt/pull/33)). - -## 3.2.1 - -* **Import Path Change**: See MIGRATION_GUIDE.md for tips on updating your code - * Changed the import path from `github.com/dgrijalva/jwt-go` to `github.com/golang-jwt/jwt` -* Fixed type confusing issue between `string` and `[]string` in `VerifyAudience` ([#12](https://github.com/golang-jwt/jwt/pull/12)). This fixes CVE-2020-26160 - -#### 3.2.0 - -* Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation -* HMAC signing method returns `ErrInvalidKeyType` instead of `ErrInvalidKey` where appropriate -* Added options to `request.ParseFromRequest`, which allows for an arbitrary list of modifiers to parsing behavior. Initial set include `WithClaims` and `WithParser`. Existing usage of this function will continue to work as before. -* Deprecated `ParseFromRequestWithClaims` to simplify API in the future. - -#### 3.1.0 - -* Improvements to `jwt` command line tool -* Added `SkipClaimsValidation` option to `Parser` -* Documentation updates - -#### 3.0.0 - -* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code - * Dropped support for `[]byte` keys when using RSA signing methods. This convenience feature could contribute to security vulnerabilities involving mismatched key types with signing methods. - * `ParseFromRequest` has been moved to `request` subpackage and usage has changed - * The `Claims` property on `Token` is now type `Claims` instead of `map[string]interface{}`. The default value is type `MapClaims`, which is an alias to `map[string]interface{}`. This makes it possible to use a custom type when decoding claims. -* Other Additions and Changes - * Added `Claims` interface type to allow users to decode the claims into a custom type - * Added `ParseWithClaims`, which takes a third argument of type `Claims`. Use this function instead of `Parse` if you have a custom type you'd like to decode into. - * Dramatically improved the functionality and flexibility of `ParseFromRequest`, which is now in the `request` subpackage - * Added `ParseFromRequestWithClaims` which is the `FromRequest` equivalent of `ParseWithClaims` - * Added new interface type `Extractor`, which is used for extracting JWT strings from http requests. Used with `ParseFromRequest` and `ParseFromRequestWithClaims`. - * Added several new, more specific, validation errors to error type bitmask - * Moved examples from README to executable example files - * Signing method registry is now thread safe - * Added new property to `ValidationError`, which contains the raw error returned by calls made by parse/verify (such as those returned by keyfunc or json parser) - -#### 2.7.0 - -This will likely be the last backwards compatible release before 3.0.0, excluding essential bug fixes. - -* Added new option `-show` to the `jwt` command that will just output the decoded token without verifying -* Error text for expired tokens includes how long it's been expired -* Fixed incorrect error returned from `ParseRSAPublicKeyFromPEM` -* Documentation updates - -#### 2.6.0 - -* Exposed inner error within ValidationError -* Fixed validation errors when using UseJSONNumber flag -* Added several unit tests - -#### 2.5.0 - -* Added support for signing method none. You shouldn't use this. The API tries to make this clear. -* Updated/fixed some documentation -* Added more helpful error message when trying to parse tokens that begin with `BEARER ` - -#### 2.4.0 - -* Added new type, Parser, to allow for configuration of various parsing parameters - * You can now specify a list of valid signing methods. Anything outside this set will be rejected. - * You can now opt to use the `json.Number` type instead of `float64` when parsing token JSON -* Added support for [Travis CI](https://travis-ci.org/dgrijalva/jwt-go) -* Fixed some bugs with ECDSA parsing - -#### 2.3.0 - -* Added support for ECDSA signing methods -* Added support for RSA PSS signing methods (requires go v1.4) - -#### 2.2.0 - -* Gracefully handle a `nil` `Keyfunc` being passed to `Parse`. Result will now be the parsed token and an error, instead of a panic. - -#### 2.1.0 - -Backwards compatible API change that was missed in 2.0.0. - -* The `SignedString` method on `Token` now takes `interface{}` instead of `[]byte` - -#### 2.0.0 - -There were two major reasons for breaking backwards compatibility with this update. The first was a refactor required to expand the width of the RSA and HMAC-SHA signing implementations. There will likely be no required code changes to support this change. - -The second update, while unfortunately requiring a small change in integration, is required to open up this library to other signing methods. Not all keys used for all signing methods have a single standard on-disk representation. Requiring `[]byte` as the type for all keys proved too limiting. Additionally, this implementation allows for pre-parsed tokens to be reused, which might matter in an application that parses a high volume of tokens with a small set of keys. Backwards compatibilty has been maintained for passing `[]byte` to the RSA signing methods, but they will also accept `*rsa.PublicKey` and `*rsa.PrivateKey`. - -It is likely the only integration change required here will be to change `func(t *jwt.Token) ([]byte, error)` to `func(t *jwt.Token) (interface{}, error)` when calling `Parse`. - -* **Compatibility Breaking Changes** - * `SigningMethodHS256` is now `*SigningMethodHMAC` instead of `type struct` - * `SigningMethodRS256` is now `*SigningMethodRSA` instead of `type struct` - * `KeyFunc` now returns `interface{}` instead of `[]byte` - * `SigningMethod.Sign` now takes `interface{}` instead of `[]byte` for the key - * `SigningMethod.Verify` now takes `interface{}` instead of `[]byte` for the key -* Renamed type `SigningMethodHS256` to `SigningMethodHMAC`. Specific sizes are now just instances of this type. - * Added public package global `SigningMethodHS256` - * Added public package global `SigningMethodHS384` - * Added public package global `SigningMethodHS512` -* Renamed type `SigningMethodRS256` to `SigningMethodRSA`. Specific sizes are now just instances of this type. - * Added public package global `SigningMethodRS256` - * Added public package global `SigningMethodRS384` - * Added public package global `SigningMethodRS512` -* Moved sample private key for HMAC tests from an inline value to a file on disk. Value is unchanged. -* Refactored the RSA implementation to be easier to read -* Exposed helper methods `ParseRSAPrivateKeyFromPEM` and `ParseRSAPublicKeyFromPEM` - -## 1.0.2 - -* Fixed bug in parsing public keys from certificates -* Added more tests around the parsing of keys for RS256 -* Code refactoring in RS256 implementation. No functional changes - -## 1.0.1 - -* Fixed panic if RS256 signing method was passed an invalid key - -## 1.0.0 - -* First versioned release -* API stabilized -* Supports creating, signing, parsing, and validating JWT tokens -* Supports RS256 and HS256 signing methods diff --git a/vendor/github.com/golang-jwt/jwt/v5/claims.go b/vendor/github.com/golang-jwt/jwt/v5/claims.go deleted file mode 100644 index d50ff3dad..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/claims.go +++ /dev/null @@ -1,16 +0,0 @@ -package jwt - -// Claims represent any form of a JWT Claims Set according to -// https://datatracker.ietf.org/doc/html/rfc7519#section-4. In order to have a -// common basis for validation, it is required that an implementation is able to -// supply at least the claim names provided in -// https://datatracker.ietf.org/doc/html/rfc7519#section-4.1 namely `exp`, -// `iat`, `nbf`, `iss`, `sub` and `aud`. -type Claims interface { - GetExpirationTime() (*NumericDate, error) - GetIssuedAt() (*NumericDate, error) - GetNotBefore() (*NumericDate, error) - GetIssuer() (string, error) - GetSubject() (string, error) - GetAudience() (ClaimStrings, error) -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/doc.go b/vendor/github.com/golang-jwt/jwt/v5/doc.go deleted file mode 100644 index a86dc1a3b..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html -// -// See README.md for more info. -package jwt diff --git a/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go b/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go deleted file mode 100644 index c929e4a02..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go +++ /dev/null @@ -1,134 +0,0 @@ -package jwt - -import ( - "crypto" - "crypto/ecdsa" - "crypto/rand" - "errors" - "math/big" -) - -var ( - // Sadly this is missing from crypto/ecdsa compared to crypto/rsa - ErrECDSAVerification = errors.New("crypto/ecdsa: verification error") -) - -// SigningMethodECDSA implements the ECDSA family of signing methods. -// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification -type SigningMethodECDSA struct { - Name string - Hash crypto.Hash - KeySize int - CurveBits int -} - -// Specific instances for EC256 and company -var ( - SigningMethodES256 *SigningMethodECDSA - SigningMethodES384 *SigningMethodECDSA - SigningMethodES512 *SigningMethodECDSA -) - -func init() { - // ES256 - SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256} - RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod { - return SigningMethodES256 - }) - - // ES384 - SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384} - RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod { - return SigningMethodES384 - }) - - // ES512 - SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521} - RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod { - return SigningMethodES512 - }) -} - -func (m *SigningMethodECDSA) Alg() string { - return m.Name -} - -// Verify implements token verification for the SigningMethod. -// For this verify method, key must be an ecdsa.PublicKey struct -func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key interface{}) error { - // Get the key - var ecdsaKey *ecdsa.PublicKey - switch k := key.(type) { - case *ecdsa.PublicKey: - ecdsaKey = k - default: - return newError("ECDSA verify expects *ecdsa.PublicKey", ErrInvalidKeyType) - } - - if len(sig) != 2*m.KeySize { - return ErrECDSAVerification - } - - r := big.NewInt(0).SetBytes(sig[:m.KeySize]) - s := big.NewInt(0).SetBytes(sig[m.KeySize:]) - - // Create hasher - if !m.Hash.Available() { - return ErrHashUnavailable - } - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - // Verify the signature - if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus { - return nil - } - - return ErrECDSAVerification -} - -// Sign implements token signing for the SigningMethod. -// For this signing method, key must be an ecdsa.PrivateKey struct -func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) ([]byte, error) { - // Get the key - var ecdsaKey *ecdsa.PrivateKey - switch k := key.(type) { - case *ecdsa.PrivateKey: - ecdsaKey = k - default: - return nil, newError("ECDSA sign expects *ecdsa.PrivateKey", ErrInvalidKeyType) - } - - // Create the hasher - if !m.Hash.Available() { - return nil, ErrHashUnavailable - } - - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - // Sign the string and return r, s - if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil { - curveBits := ecdsaKey.Curve.Params().BitSize - - if m.CurveBits != curveBits { - return nil, ErrInvalidKey - } - - keyBytes := curveBits / 8 - if curveBits%8 > 0 { - keyBytes += 1 - } - - // We serialize the outputs (r and s) into big-endian byte arrays - // padded with zeros on the left to make sure the sizes work out. - // Output must be 2*keyBytes long. - out := make([]byte, 2*keyBytes) - r.FillBytes(out[0:keyBytes]) // r is assigned to the first half of output. - s.FillBytes(out[keyBytes:]) // s is assigned to the second half of output. - - return out, nil - } else { - return nil, err - } -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go b/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go deleted file mode 100644 index 5700636d3..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go +++ /dev/null @@ -1,69 +0,0 @@ -package jwt - -import ( - "crypto/ecdsa" - "crypto/x509" - "encoding/pem" - "errors" -) - -var ( - ErrNotECPublicKey = errors.New("key is not a valid ECDSA public key") - ErrNotECPrivateKey = errors.New("key is not a valid ECDSA private key") -) - -// ParseECPrivateKeyFromPEM parses a PEM encoded Elliptic Curve Private Key Structure -func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - // Parse the key - var parsedKey interface{} - if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil { - if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { - return nil, err - } - } - - var pkey *ecdsa.PrivateKey - var ok bool - if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok { - return nil, ErrNotECPrivateKey - } - - return pkey, nil -} - -// ParseECPublicKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 public key -func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - // Parse the key - var parsedKey interface{} - if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { - if cert, err := x509.ParseCertificate(block.Bytes); err == nil { - parsedKey = cert.PublicKey - } else { - return nil, err - } - } - - var pkey *ecdsa.PublicKey - var ok bool - if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok { - return nil, ErrNotECPublicKey - } - - return pkey, nil -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/ed25519.go b/vendor/github.com/golang-jwt/jwt/v5/ed25519.go deleted file mode 100644 index c2138119e..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/ed25519.go +++ /dev/null @@ -1,79 +0,0 @@ -package jwt - -import ( - "crypto" - "crypto/ed25519" - "crypto/rand" - "errors" -) - -var ( - ErrEd25519Verification = errors.New("ed25519: verification error") -) - -// SigningMethodEd25519 implements the EdDSA family. -// Expects ed25519.PrivateKey for signing and ed25519.PublicKey for verification -type SigningMethodEd25519 struct{} - -// Specific instance for EdDSA -var ( - SigningMethodEdDSA *SigningMethodEd25519 -) - -func init() { - SigningMethodEdDSA = &SigningMethodEd25519{} - RegisterSigningMethod(SigningMethodEdDSA.Alg(), func() SigningMethod { - return SigningMethodEdDSA - }) -} - -func (m *SigningMethodEd25519) Alg() string { - return "EdDSA" -} - -// Verify implements token verification for the SigningMethod. -// For this verify method, key must be an ed25519.PublicKey -func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key interface{}) error { - var ed25519Key ed25519.PublicKey - var ok bool - - if ed25519Key, ok = key.(ed25519.PublicKey); !ok { - return newError("Ed25519 verify expects ed25519.PublicKey", ErrInvalidKeyType) - } - - if len(ed25519Key) != ed25519.PublicKeySize { - return ErrInvalidKey - } - - // Verify the signature - if !ed25519.Verify(ed25519Key, []byte(signingString), sig) { - return ErrEd25519Verification - } - - return nil -} - -// Sign implements token signing for the SigningMethod. -// For this signing method, key must be an ed25519.PrivateKey -func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) ([]byte, error) { - var ed25519Key crypto.Signer - var ok bool - - if ed25519Key, ok = key.(crypto.Signer); !ok { - return nil, newError("Ed25519 sign expects crypto.Signer", ErrInvalidKeyType) - } - - if _, ok := ed25519Key.Public().(ed25519.PublicKey); !ok { - return nil, ErrInvalidKey - } - - // Sign the string and return the result. ed25519 performs a two-pass hash - // as part of its algorithm. Therefore, we need to pass a non-prehashed - // message into the Sign function, as indicated by crypto.Hash(0) - sig, err := ed25519Key.Sign(rand.Reader, []byte(signingString), crypto.Hash(0)) - if err != nil { - return nil, err - } - - return sig, nil -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go b/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go deleted file mode 100644 index cdb5e68e8..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go +++ /dev/null @@ -1,64 +0,0 @@ -package jwt - -import ( - "crypto" - "crypto/ed25519" - "crypto/x509" - "encoding/pem" - "errors" -) - -var ( - ErrNotEdPrivateKey = errors.New("key is not a valid Ed25519 private key") - ErrNotEdPublicKey = errors.New("key is not a valid Ed25519 public key") -) - -// ParseEdPrivateKeyFromPEM parses a PEM-encoded Edwards curve private key -func ParseEdPrivateKeyFromPEM(key []byte) (crypto.PrivateKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - // Parse the key - var parsedKey interface{} - if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { - return nil, err - } - - var pkey ed25519.PrivateKey - var ok bool - if pkey, ok = parsedKey.(ed25519.PrivateKey); !ok { - return nil, ErrNotEdPrivateKey - } - - return pkey, nil -} - -// ParseEdPublicKeyFromPEM parses a PEM-encoded Edwards curve public key -func ParseEdPublicKeyFromPEM(key []byte) (crypto.PublicKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - // Parse the key - var parsedKey interface{} - if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { - return nil, err - } - - var pkey ed25519.PublicKey - var ok bool - if pkey, ok = parsedKey.(ed25519.PublicKey); !ok { - return nil, ErrNotEdPublicKey - } - - return pkey, nil -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/errors.go b/vendor/github.com/golang-jwt/jwt/v5/errors.go deleted file mode 100644 index 23bb616dd..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/errors.go +++ /dev/null @@ -1,49 +0,0 @@ -package jwt - -import ( - "errors" - "strings" -) - -var ( - ErrInvalidKey = errors.New("key is invalid") - ErrInvalidKeyType = errors.New("key is of invalid type") - ErrHashUnavailable = errors.New("the requested hash function is unavailable") - ErrTokenMalformed = errors.New("token is malformed") - ErrTokenUnverifiable = errors.New("token is unverifiable") - ErrTokenSignatureInvalid = errors.New("token signature is invalid") - ErrTokenRequiredClaimMissing = errors.New("token is missing required claim") - ErrTokenInvalidAudience = errors.New("token has invalid audience") - ErrTokenExpired = errors.New("token is expired") - ErrTokenUsedBeforeIssued = errors.New("token used before issued") - ErrTokenInvalidIssuer = errors.New("token has invalid issuer") - ErrTokenInvalidSubject = errors.New("token has invalid subject") - ErrTokenNotValidYet = errors.New("token is not valid yet") - ErrTokenInvalidId = errors.New("token has invalid id") - ErrTokenInvalidClaims = errors.New("token has invalid claims") - ErrInvalidType = errors.New("invalid type for claim") -) - -// joinedError is an error type that works similar to what [errors.Join] -// produces, with the exception that it has a nice error string; mainly its -// error messages are concatenated using a comma, rather than a newline. -type joinedError struct { - errs []error -} - -func (je joinedError) Error() string { - msg := []string{} - for _, err := range je.errs { - msg = append(msg, err.Error()) - } - - return strings.Join(msg, ", ") -} - -// joinErrors joins together multiple errors. Useful for scenarios where -// multiple errors next to each other occur, e.g., in claims validation. -func joinErrors(errs ...error) error { - return &joinedError{ - errs: errs, - } -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/errors_go1_20.go b/vendor/github.com/golang-jwt/jwt/v5/errors_go1_20.go deleted file mode 100644 index a893d355e..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/errors_go1_20.go +++ /dev/null @@ -1,47 +0,0 @@ -//go:build go1.20 -// +build go1.20 - -package jwt - -import ( - "fmt" -) - -// Unwrap implements the multiple error unwrapping for this error type, which is -// possible in Go 1.20. -func (je joinedError) Unwrap() []error { - return je.errs -} - -// newError creates a new error message with a detailed error message. The -// message will be prefixed with the contents of the supplied error type. -// Additionally, more errors, that provide more context can be supplied which -// will be appended to the message. This makes use of Go 1.20's possibility to -// include more than one %w formatting directive in [fmt.Errorf]. -// -// For example, -// -// newError("no keyfunc was provided", ErrTokenUnverifiable) -// -// will produce the error string -// -// "token is unverifiable: no keyfunc was provided" -func newError(message string, err error, more ...error) error { - var format string - var args []any - if message != "" { - format = "%w: %s" - args = []any{err, message} - } else { - format = "%w" - args = []any{err} - } - - for _, e := range more { - format += ": %w" - args = append(args, e) - } - - err = fmt.Errorf(format, args...) - return err -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/errors_go_other.go b/vendor/github.com/golang-jwt/jwt/v5/errors_go_other.go deleted file mode 100644 index 2ad542f00..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/errors_go_other.go +++ /dev/null @@ -1,78 +0,0 @@ -//go:build !go1.20 -// +build !go1.20 - -package jwt - -import ( - "errors" - "fmt" -) - -// Is implements checking for multiple errors using [errors.Is], since multiple -// error unwrapping is not possible in versions less than Go 1.20. -func (je joinedError) Is(err error) bool { - for _, e := range je.errs { - if errors.Is(e, err) { - return true - } - } - - return false -} - -// wrappedErrors is a workaround for wrapping multiple errors in environments -// where Go 1.20 is not available. It basically uses the already implemented -// functionality of joinedError to handle multiple errors with supplies a -// custom error message that is identical to the one we produce in Go 1.20 using -// multiple %w directives. -type wrappedErrors struct { - msg string - joinedError -} - -// Error returns the stored error string -func (we wrappedErrors) Error() string { - return we.msg -} - -// newError creates a new error message with a detailed error message. The -// message will be prefixed with the contents of the supplied error type. -// Additionally, more errors, that provide more context can be supplied which -// will be appended to the message. Since we cannot use of Go 1.20's possibility -// to include more than one %w formatting directive in [fmt.Errorf], we have to -// emulate that. -// -// For example, -// -// newError("no keyfunc was provided", ErrTokenUnverifiable) -// -// will produce the error string -// -// "token is unverifiable: no keyfunc was provided" -func newError(message string, err error, more ...error) error { - // We cannot wrap multiple errors here with %w, so we have to be a little - // bit creative. Basically, we are using %s instead of %w to produce the - // same error message and then throw the result into a custom error struct. - var format string - var args []any - if message != "" { - format = "%s: %s" - args = []any{err, message} - } else { - format = "%s" - args = []any{err} - } - errs := []error{err} - - for _, e := range more { - format += ": %s" - args = append(args, e) - errs = append(errs, e) - } - - err = &wrappedErrors{ - msg: fmt.Sprintf(format, args...), - joinedError: joinedError{errs: errs}, - } - return err -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/hmac.go b/vendor/github.com/golang-jwt/jwt/v5/hmac.go deleted file mode 100644 index aca600ce1..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/hmac.go +++ /dev/null @@ -1,104 +0,0 @@ -package jwt - -import ( - "crypto" - "crypto/hmac" - "errors" -) - -// SigningMethodHMAC implements the HMAC-SHA family of signing methods. -// Expects key type of []byte for both signing and validation -type SigningMethodHMAC struct { - Name string - Hash crypto.Hash -} - -// Specific instances for HS256 and company -var ( - SigningMethodHS256 *SigningMethodHMAC - SigningMethodHS384 *SigningMethodHMAC - SigningMethodHS512 *SigningMethodHMAC - ErrSignatureInvalid = errors.New("signature is invalid") -) - -func init() { - // HS256 - SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256} - RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod { - return SigningMethodHS256 - }) - - // HS384 - SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384} - RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod { - return SigningMethodHS384 - }) - - // HS512 - SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512} - RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod { - return SigningMethodHS512 - }) -} - -func (m *SigningMethodHMAC) Alg() string { - return m.Name -} - -// Verify implements token verification for the SigningMethod. Returns nil if -// the signature is valid. Key must be []byte. -// -// Note it is not advised to provide a []byte which was converted from a 'human -// readable' string using a subset of ASCII characters. To maximize entropy, you -// should ideally be providing a []byte key which was produced from a -// cryptographically random source, e.g. crypto/rand. Additional information -// about this, and why we intentionally are not supporting string as a key can -// be found on our usage guide -// https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types. -func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key interface{}) error { - // Verify the key is the right type - keyBytes, ok := key.([]byte) - if !ok { - return newError("HMAC verify expects []byte", ErrInvalidKeyType) - } - - // Can we use the specified hashing method? - if !m.Hash.Available() { - return ErrHashUnavailable - } - - // This signing method is symmetric, so we validate the signature - // by reproducing the signature from the signing string and key, then - // comparing that against the provided signature. - hasher := hmac.New(m.Hash.New, keyBytes) - hasher.Write([]byte(signingString)) - if !hmac.Equal(sig, hasher.Sum(nil)) { - return ErrSignatureInvalid - } - - // No validation errors. Signature is good. - return nil -} - -// Sign implements token signing for the SigningMethod. Key must be []byte. -// -// Note it is not advised to provide a []byte which was converted from a 'human -// readable' string using a subset of ASCII characters. To maximize entropy, you -// should ideally be providing a []byte key which was produced from a -// cryptographically random source, e.g. crypto/rand. Additional information -// about this, and why we intentionally are not supporting string as a key can -// be found on our usage guide https://golang-jwt.github.io/jwt/usage/signing_methods/. -func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) ([]byte, error) { - if keyBytes, ok := key.([]byte); ok { - if !m.Hash.Available() { - return nil, ErrHashUnavailable - } - - hasher := hmac.New(m.Hash.New, keyBytes) - hasher.Write([]byte(signingString)) - - return hasher.Sum(nil), nil - } - - return nil, newError("HMAC sign expects []byte", ErrInvalidKeyType) -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/map_claims.go b/vendor/github.com/golang-jwt/jwt/v5/map_claims.go deleted file mode 100644 index b2b51a1f8..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/map_claims.go +++ /dev/null @@ -1,109 +0,0 @@ -package jwt - -import ( - "encoding/json" - "fmt" -) - -// MapClaims is a claims type that uses the map[string]interface{} for JSON -// decoding. This is the default claims type if you don't supply one -type MapClaims map[string]interface{} - -// GetExpirationTime implements the Claims interface. -func (m MapClaims) GetExpirationTime() (*NumericDate, error) { - return m.parseNumericDate("exp") -} - -// GetNotBefore implements the Claims interface. -func (m MapClaims) GetNotBefore() (*NumericDate, error) { - return m.parseNumericDate("nbf") -} - -// GetIssuedAt implements the Claims interface. -func (m MapClaims) GetIssuedAt() (*NumericDate, error) { - return m.parseNumericDate("iat") -} - -// GetAudience implements the Claims interface. -func (m MapClaims) GetAudience() (ClaimStrings, error) { - return m.parseClaimsString("aud") -} - -// GetIssuer implements the Claims interface. -func (m MapClaims) GetIssuer() (string, error) { - return m.parseString("iss") -} - -// GetSubject implements the Claims interface. -func (m MapClaims) GetSubject() (string, error) { - return m.parseString("sub") -} - -// parseNumericDate tries to parse a key in the map claims type as a number -// date. This will succeed, if the underlying type is either a [float64] or a -// [json.Number]. Otherwise, nil will be returned. -func (m MapClaims) parseNumericDate(key string) (*NumericDate, error) { - v, ok := m[key] - if !ok { - return nil, nil - } - - switch exp := v.(type) { - case float64: - if exp == 0 { - return nil, nil - } - - return newNumericDateFromSeconds(exp), nil - case json.Number: - v, _ := exp.Float64() - - return newNumericDateFromSeconds(v), nil - } - - return nil, newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType) -} - -// parseClaimsString tries to parse a key in the map claims type as a -// [ClaimsStrings] type, which can either be a string or an array of string. -func (m MapClaims) parseClaimsString(key string) (ClaimStrings, error) { - var cs []string - switch v := m[key].(type) { - case string: - cs = append(cs, v) - case []string: - cs = v - case []interface{}: - for _, a := range v { - vs, ok := a.(string) - if !ok { - return nil, newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType) - } - cs = append(cs, vs) - } - } - - return cs, nil -} - -// parseString tries to parse a key in the map claims type as a [string] type. -// If the key does not exist, an empty string is returned. If the key has the -// wrong type, an error is returned. -func (m MapClaims) parseString(key string) (string, error) { - var ( - ok bool - raw interface{} - iss string - ) - raw, ok = m[key] - if !ok { - return "", nil - } - - iss, ok = raw.(string) - if !ok { - return "", newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType) - } - - return iss, nil -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/none.go b/vendor/github.com/golang-jwt/jwt/v5/none.go deleted file mode 100644 index 685c2ea30..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/none.go +++ /dev/null @@ -1,50 +0,0 @@ -package jwt - -// SigningMethodNone implements the none signing method. This is required by the spec -// but you probably should never use it. -var SigningMethodNone *signingMethodNone - -const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed" - -var NoneSignatureTypeDisallowedError error - -type signingMethodNone struct{} -type unsafeNoneMagicConstant string - -func init() { - SigningMethodNone = &signingMethodNone{} - NoneSignatureTypeDisallowedError = newError("'none' signature type is not allowed", ErrTokenUnverifiable) - - RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod { - return SigningMethodNone - }) -} - -func (m *signingMethodNone) Alg() string { - return "none" -} - -// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key -func (m *signingMethodNone) Verify(signingString string, sig []byte, key interface{}) (err error) { - // Key must be UnsafeAllowNoneSignatureType to prevent accidentally - // accepting 'none' signing method - if _, ok := key.(unsafeNoneMagicConstant); !ok { - return NoneSignatureTypeDisallowedError - } - // If signing method is none, signature must be an empty string - if len(sig) != 0 { - return newError("'none' signing method with non-empty signature", ErrTokenUnverifiable) - } - - // Accept 'none' signing method. - return nil -} - -// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key -func (m *signingMethodNone) Sign(signingString string, key interface{}) ([]byte, error) { - if _, ok := key.(unsafeNoneMagicConstant); ok { - return []byte{}, nil - } - - return nil, NoneSignatureTypeDisallowedError -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/parser.go b/vendor/github.com/golang-jwt/jwt/v5/parser.go deleted file mode 100644 index ecf99af78..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/parser.go +++ /dev/null @@ -1,238 +0,0 @@ -package jwt - -import ( - "bytes" - "encoding/base64" - "encoding/json" - "fmt" - "strings" -) - -type Parser struct { - // If populated, only these methods will be considered valid. - validMethods []string - - // Use JSON Number format in JSON decoder. - useJSONNumber bool - - // Skip claims validation during token parsing. - skipClaimsValidation bool - - validator *Validator - - decodeStrict bool - - decodePaddingAllowed bool -} - -// NewParser creates a new Parser with the specified options -func NewParser(options ...ParserOption) *Parser { - p := &Parser{ - validator: &Validator{}, - } - - // Loop through our parsing options and apply them - for _, option := range options { - option(p) - } - - return p -} - -// Parse parses, validates, verifies the signature and returns the parsed token. -// keyFunc will receive the parsed token and should return the key for validating. -func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { - return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc) -} - -// ParseWithClaims parses, validates, and verifies like Parse, but supplies a default object implementing the Claims -// interface. This provides default values which can be overridden and allows a caller to use their own type, rather -// than the default MapClaims implementation of Claims. -// -// Note: If you provide a custom claim implementation that embeds one of the standard claims (such as RegisteredClaims), -// make sure that a) you either embed a non-pointer version of the claims or b) if you are using a pointer, allocate the -// proper memory for it before passing in the overall claims, otherwise you might run into a panic. -func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { - token, parts, err := p.ParseUnverified(tokenString, claims) - if err != nil { - return token, err - } - - // Verify signing method is in the required set - if p.validMethods != nil { - var signingMethodValid = false - var alg = token.Method.Alg() - for _, m := range p.validMethods { - if m == alg { - signingMethodValid = true - break - } - } - if !signingMethodValid { - // signing method is not in the listed set - return token, newError(fmt.Sprintf("signing method %v is invalid", alg), ErrTokenSignatureInvalid) - } - } - - // Decode signature - token.Signature, err = p.DecodeSegment(parts[2]) - if err != nil { - return token, newError("could not base64 decode signature", ErrTokenMalformed, err) - } - text := strings.Join(parts[0:2], ".") - - // Lookup key(s) - if keyFunc == nil { - // keyFunc was not provided. short circuiting validation - return token, newError("no keyfunc was provided", ErrTokenUnverifiable) - } - - got, err := keyFunc(token) - if err != nil { - return token, newError("error while executing keyfunc", ErrTokenUnverifiable, err) - } - - switch have := got.(type) { - case VerificationKeySet: - if len(have.Keys) == 0 { - return token, newError("keyfunc returned empty verification key set", ErrTokenUnverifiable) - } - // Iterate through keys and verify signature, skipping the rest when a match is found. - // Return the last error if no match is found. - for _, key := range have.Keys { - if err = token.Method.Verify(text, token.Signature, key); err == nil { - break - } - } - default: - err = token.Method.Verify(text, token.Signature, have) - } - if err != nil { - return token, newError("", ErrTokenSignatureInvalid, err) - } - - // Validate Claims - if !p.skipClaimsValidation { - // Make sure we have at least a default validator - if p.validator == nil { - p.validator = NewValidator() - } - - if err := p.validator.Validate(claims); err != nil { - return token, newError("", ErrTokenInvalidClaims, err) - } - } - - // No errors so far, token is valid. - token.Valid = true - - return token, nil -} - -// ParseUnverified parses the token but doesn't validate the signature. -// -// WARNING: Don't use this method unless you know what you're doing. -// -// It's only ever useful in cases where you know the signature is valid (since it has already -// been or will be checked elsewhere in the stack) and you want to extract values from it. -func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) { - parts = strings.Split(tokenString, ".") - if len(parts) != 3 { - return nil, parts, newError("token contains an invalid number of segments", ErrTokenMalformed) - } - - token = &Token{Raw: tokenString} - - // parse Header - var headerBytes []byte - if headerBytes, err = p.DecodeSegment(parts[0]); err != nil { - return token, parts, newError("could not base64 decode header", ErrTokenMalformed, err) - } - if err = json.Unmarshal(headerBytes, &token.Header); err != nil { - return token, parts, newError("could not JSON decode header", ErrTokenMalformed, err) - } - - // parse Claims - token.Claims = claims - - claimBytes, err := p.DecodeSegment(parts[1]) - if err != nil { - return token, parts, newError("could not base64 decode claim", ErrTokenMalformed, err) - } - - // If `useJSONNumber` is enabled then we must use *json.Decoder to decode - // the claims. However, this comes with a performance penalty so only use - // it if we must and, otherwise, simple use json.Unmarshal. - if !p.useJSONNumber { - // JSON Unmarshal. Special case for map type to avoid weird pointer behavior. - if c, ok := token.Claims.(MapClaims); ok { - err = json.Unmarshal(claimBytes, &c) - } else { - err = json.Unmarshal(claimBytes, &claims) - } - } else { - dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) - dec.UseNumber() - // JSON Decode. Special case for map type to avoid weird pointer behavior. - if c, ok := token.Claims.(MapClaims); ok { - err = dec.Decode(&c) - } else { - err = dec.Decode(&claims) - } - } - if err != nil { - return token, parts, newError("could not JSON decode claim", ErrTokenMalformed, err) - } - - // Lookup signature method - if method, ok := token.Header["alg"].(string); ok { - if token.Method = GetSigningMethod(method); token.Method == nil { - return token, parts, newError("signing method (alg) is unavailable", ErrTokenUnverifiable) - } - } else { - return token, parts, newError("signing method (alg) is unspecified", ErrTokenUnverifiable) - } - - return token, parts, nil -} - -// DecodeSegment decodes a JWT specific base64url encoding. This function will -// take into account whether the [Parser] is configured with additional options, -// such as [WithStrictDecoding] or [WithPaddingAllowed]. -func (p *Parser) DecodeSegment(seg string) ([]byte, error) { - encoding := base64.RawURLEncoding - - if p.decodePaddingAllowed { - if l := len(seg) % 4; l > 0 { - seg += strings.Repeat("=", 4-l) - } - encoding = base64.URLEncoding - } - - if p.decodeStrict { - encoding = encoding.Strict() - } - return encoding.DecodeString(seg) -} - -// Parse parses, validates, verifies the signature and returns the parsed token. -// keyFunc will receive the parsed token and should return the cryptographic key -// for verifying the signature. The caller is strongly encouraged to set the -// WithValidMethods option to validate the 'alg' claim in the token matches the -// expected algorithm. For more details about the importance of validating the -// 'alg' claim, see -// https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ -func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { - return NewParser(options...).Parse(tokenString, keyFunc) -} - -// ParseWithClaims is a shortcut for NewParser().ParseWithClaims(). -// -// Note: If you provide a custom claim implementation that embeds one of the -// standard claims (such as RegisteredClaims), make sure that a) you either -// embed a non-pointer version of the claims or b) if you are using a pointer, -// allocate the proper memory for it before passing in the overall claims, -// otherwise you might run into a panic. -func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { - return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc) -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/parser_option.go b/vendor/github.com/golang-jwt/jwt/v5/parser_option.go deleted file mode 100644 index 88a780fbd..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/parser_option.go +++ /dev/null @@ -1,128 +0,0 @@ -package jwt - -import "time" - -// ParserOption is used to implement functional-style options that modify the -// behavior of the parser. To add new options, just create a function (ideally -// beginning with With or Without) that returns an anonymous function that takes -// a *Parser type as input and manipulates its configuration accordingly. -type ParserOption func(*Parser) - -// WithValidMethods is an option to supply algorithm methods that the parser -// will check. Only those methods will be considered valid. It is heavily -// encouraged to use this option in order to prevent attacks such as -// https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/. -func WithValidMethods(methods []string) ParserOption { - return func(p *Parser) { - p.validMethods = methods - } -} - -// WithJSONNumber is an option to configure the underlying JSON parser with -// UseNumber. -func WithJSONNumber() ParserOption { - return func(p *Parser) { - p.useJSONNumber = true - } -} - -// WithoutClaimsValidation is an option to disable claims validation. This -// option should only be used if you exactly know what you are doing. -func WithoutClaimsValidation() ParserOption { - return func(p *Parser) { - p.skipClaimsValidation = true - } -} - -// WithLeeway returns the ParserOption for specifying the leeway window. -func WithLeeway(leeway time.Duration) ParserOption { - return func(p *Parser) { - p.validator.leeway = leeway - } -} - -// WithTimeFunc returns the ParserOption for specifying the time func. The -// primary use-case for this is testing. If you are looking for a way to account -// for clock-skew, WithLeeway should be used instead. -func WithTimeFunc(f func() time.Time) ParserOption { - return func(p *Parser) { - p.validator.timeFunc = f - } -} - -// WithIssuedAt returns the ParserOption to enable verification -// of issued-at. -func WithIssuedAt() ParserOption { - return func(p *Parser) { - p.validator.verifyIat = true - } -} - -// WithExpirationRequired returns the ParserOption to make exp claim required. -// By default exp claim is optional. -func WithExpirationRequired() ParserOption { - return func(p *Parser) { - p.validator.requireExp = true - } -} - -// WithAudience configures the validator to require the specified audience in -// the `aud` claim. Validation will fail if the audience is not listed in the -// token or the `aud` claim is missing. -// -// NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is -// application-specific. Since this validation API is helping developers in -// writing secure application, we decided to REQUIRE the existence of the claim, -// if an audience is expected. -func WithAudience(aud string) ParserOption { - return func(p *Parser) { - p.validator.expectedAud = aud - } -} - -// WithIssuer configures the validator to require the specified issuer in the -// `iss` claim. Validation will fail if a different issuer is specified in the -// token or the `iss` claim is missing. -// -// NOTE: While the `iss` claim is OPTIONAL in a JWT, the handling of it is -// application-specific. Since this validation API is helping developers in -// writing secure application, we decided to REQUIRE the existence of the claim, -// if an issuer is expected. -func WithIssuer(iss string) ParserOption { - return func(p *Parser) { - p.validator.expectedIss = iss - } -} - -// WithSubject configures the validator to require the specified subject in the -// `sub` claim. Validation will fail if a different subject is specified in the -// token or the `sub` claim is missing. -// -// NOTE: While the `sub` claim is OPTIONAL in a JWT, the handling of it is -// application-specific. Since this validation API is helping developers in -// writing secure application, we decided to REQUIRE the existence of the claim, -// if a subject is expected. -func WithSubject(sub string) ParserOption { - return func(p *Parser) { - p.validator.expectedSub = sub - } -} - -// WithPaddingAllowed will enable the codec used for decoding JWTs to allow -// padding. Note that the JWS RFC7515 states that the tokens will utilize a -// Base64url encoding with no padding. Unfortunately, some implementations of -// JWT are producing non-standard tokens, and thus require support for decoding. -func WithPaddingAllowed() ParserOption { - return func(p *Parser) { - p.decodePaddingAllowed = true - } -} - -// WithStrictDecoding will switch the codec used for decoding JWTs into strict -// mode. In this mode, the decoder requires that trailing padding bits are zero, -// as described in RFC 4648 section 3.5. -func WithStrictDecoding() ParserOption { - return func(p *Parser) { - p.decodeStrict = true - } -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/registered_claims.go b/vendor/github.com/golang-jwt/jwt/v5/registered_claims.go deleted file mode 100644 index 77951a531..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/registered_claims.go +++ /dev/null @@ -1,63 +0,0 @@ -package jwt - -// RegisteredClaims are a structured version of the JWT Claims Set, -// restricted to Registered Claim Names, as referenced at -// https://datatracker.ietf.org/doc/html/rfc7519#section-4.1 -// -// This type can be used on its own, but then additional private and -// public claims embedded in the JWT will not be parsed. The typical use-case -// therefore is to embedded this in a user-defined claim type. -// -// See examples for how to use this with your own claim types. -type RegisteredClaims struct { - // the `iss` (Issuer) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1 - Issuer string `json:"iss,omitempty"` - - // the `sub` (Subject) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2 - Subject string `json:"sub,omitempty"` - - // the `aud` (Audience) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3 - Audience ClaimStrings `json:"aud,omitempty"` - - // the `exp` (Expiration Time) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4 - ExpiresAt *NumericDate `json:"exp,omitempty"` - - // the `nbf` (Not Before) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5 - NotBefore *NumericDate `json:"nbf,omitempty"` - - // the `iat` (Issued At) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6 - IssuedAt *NumericDate `json:"iat,omitempty"` - - // the `jti` (JWT ID) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7 - ID string `json:"jti,omitempty"` -} - -// GetExpirationTime implements the Claims interface. -func (c RegisteredClaims) GetExpirationTime() (*NumericDate, error) { - return c.ExpiresAt, nil -} - -// GetNotBefore implements the Claims interface. -func (c RegisteredClaims) GetNotBefore() (*NumericDate, error) { - return c.NotBefore, nil -} - -// GetIssuedAt implements the Claims interface. -func (c RegisteredClaims) GetIssuedAt() (*NumericDate, error) { - return c.IssuedAt, nil -} - -// GetAudience implements the Claims interface. -func (c RegisteredClaims) GetAudience() (ClaimStrings, error) { - return c.Audience, nil -} - -// GetIssuer implements the Claims interface. -func (c RegisteredClaims) GetIssuer() (string, error) { - return c.Issuer, nil -} - -// GetSubject implements the Claims interface. -func (c RegisteredClaims) GetSubject() (string, error) { - return c.Subject, nil -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa.go b/vendor/github.com/golang-jwt/jwt/v5/rsa.go deleted file mode 100644 index 83cbee6ae..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/rsa.go +++ /dev/null @@ -1,93 +0,0 @@ -package jwt - -import ( - "crypto" - "crypto/rand" - "crypto/rsa" -) - -// SigningMethodRSA implements the RSA family of signing methods. -// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation -type SigningMethodRSA struct { - Name string - Hash crypto.Hash -} - -// Specific instances for RS256 and company -var ( - SigningMethodRS256 *SigningMethodRSA - SigningMethodRS384 *SigningMethodRSA - SigningMethodRS512 *SigningMethodRSA -) - -func init() { - // RS256 - SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256} - RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod { - return SigningMethodRS256 - }) - - // RS384 - SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384} - RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod { - return SigningMethodRS384 - }) - - // RS512 - SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512} - RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod { - return SigningMethodRS512 - }) -} - -func (m *SigningMethodRSA) Alg() string { - return m.Name -} - -// Verify implements token verification for the SigningMethod -// For this signing method, must be an *rsa.PublicKey structure. -func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key interface{}) error { - var rsaKey *rsa.PublicKey - var ok bool - - if rsaKey, ok = key.(*rsa.PublicKey); !ok { - return newError("RSA verify expects *rsa.PublicKey", ErrInvalidKeyType) - } - - // Create hasher - if !m.Hash.Available() { - return ErrHashUnavailable - } - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - // Verify the signature - return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig) -} - -// Sign implements token signing for the SigningMethod -// For this signing method, must be an *rsa.PrivateKey structure. -func (m *SigningMethodRSA) Sign(signingString string, key interface{}) ([]byte, error) { - var rsaKey *rsa.PrivateKey - var ok bool - - // Validate type of key - if rsaKey, ok = key.(*rsa.PrivateKey); !ok { - return nil, newError("RSA sign expects *rsa.PrivateKey", ErrInvalidKeyType) - } - - // Create the hasher - if !m.Hash.Available() { - return nil, ErrHashUnavailable - } - - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - // Sign the string and return the encoded bytes - if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil { - return sigBytes, nil - } else { - return nil, err - } -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go b/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go deleted file mode 100644 index 28c386ec4..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go +++ /dev/null @@ -1,135 +0,0 @@ -//go:build go1.4 -// +build go1.4 - -package jwt - -import ( - "crypto" - "crypto/rand" - "crypto/rsa" -) - -// SigningMethodRSAPSS implements the RSAPSS family of signing methods signing methods -type SigningMethodRSAPSS struct { - *SigningMethodRSA - Options *rsa.PSSOptions - // VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS. - // Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow - // https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously. - // See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details. - VerifyOptions *rsa.PSSOptions -} - -// Specific instances for RS/PS and company. -var ( - SigningMethodPS256 *SigningMethodRSAPSS - SigningMethodPS384 *SigningMethodRSAPSS - SigningMethodPS512 *SigningMethodRSAPSS -) - -func init() { - // PS256 - SigningMethodPS256 = &SigningMethodRSAPSS{ - SigningMethodRSA: &SigningMethodRSA{ - Name: "PS256", - Hash: crypto.SHA256, - }, - Options: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthEqualsHash, - }, - VerifyOptions: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthAuto, - }, - } - RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod { - return SigningMethodPS256 - }) - - // PS384 - SigningMethodPS384 = &SigningMethodRSAPSS{ - SigningMethodRSA: &SigningMethodRSA{ - Name: "PS384", - Hash: crypto.SHA384, - }, - Options: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthEqualsHash, - }, - VerifyOptions: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthAuto, - }, - } - RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod { - return SigningMethodPS384 - }) - - // PS512 - SigningMethodPS512 = &SigningMethodRSAPSS{ - SigningMethodRSA: &SigningMethodRSA{ - Name: "PS512", - Hash: crypto.SHA512, - }, - Options: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthEqualsHash, - }, - VerifyOptions: &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthAuto, - }, - } - RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod { - return SigningMethodPS512 - }) -} - -// Verify implements token verification for the SigningMethod. -// For this verify method, key must be an rsa.PublicKey struct -func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key interface{}) error { - var rsaKey *rsa.PublicKey - switch k := key.(type) { - case *rsa.PublicKey: - rsaKey = k - default: - return newError("RSA-PSS verify expects *rsa.PublicKey", ErrInvalidKeyType) - } - - // Create hasher - if !m.Hash.Available() { - return ErrHashUnavailable - } - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - opts := m.Options - if m.VerifyOptions != nil { - opts = m.VerifyOptions - } - - return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts) -} - -// Sign implements token signing for the SigningMethod. -// For this signing method, key must be an rsa.PrivateKey struct -func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) ([]byte, error) { - var rsaKey *rsa.PrivateKey - - switch k := key.(type) { - case *rsa.PrivateKey: - rsaKey = k - default: - return nil, newError("RSA-PSS sign expects *rsa.PrivateKey", ErrInvalidKeyType) - } - - // Create the hasher - if !m.Hash.Available() { - return nil, ErrHashUnavailable - } - - hasher := m.Hash.New() - hasher.Write([]byte(signingString)) - - // Sign the string and return the encoded bytes - if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil { - return sigBytes, nil - } else { - return nil, err - } -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go b/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go deleted file mode 100644 index b3aeebbe1..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go +++ /dev/null @@ -1,107 +0,0 @@ -package jwt - -import ( - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "errors" -) - -var ( - ErrKeyMustBePEMEncoded = errors.New("invalid key: Key must be a PEM encoded PKCS1 or PKCS8 key") - ErrNotRSAPrivateKey = errors.New("key is not a valid RSA private key") - ErrNotRSAPublicKey = errors.New("key is not a valid RSA public key") -) - -// ParseRSAPrivateKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 private key -func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - var parsedKey interface{} - if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { - if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { - return nil, err - } - } - - var pkey *rsa.PrivateKey - var ok bool - if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { - return nil, ErrNotRSAPrivateKey - } - - return pkey, nil -} - -// ParseRSAPrivateKeyFromPEMWithPassword parses a PEM encoded PKCS1 or PKCS8 private key protected with password -// -// Deprecated: This function is deprecated and should not be used anymore. It uses the deprecated x509.DecryptPEMBlock -// function, which was deprecated since RFC 1423 is regarded insecure by design. Unfortunately, there is no alternative -// in the Go standard library for now. See https://github.com/golang/go/issues/8860. -func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - var parsedKey interface{} - - var blockDecrypted []byte - if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil { - return nil, err - } - - if parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil { - if parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil { - return nil, err - } - } - - var pkey *rsa.PrivateKey - var ok bool - if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { - return nil, ErrNotRSAPrivateKey - } - - return pkey, nil -} - -// ParseRSAPublicKeyFromPEM parses a certificate or a PEM encoded PKCS1 or PKIX public key -func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) { - var err error - - // Parse PEM block - var block *pem.Block - if block, _ = pem.Decode(key); block == nil { - return nil, ErrKeyMustBePEMEncoded - } - - // Parse the key - var parsedKey interface{} - if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { - if cert, err := x509.ParseCertificate(block.Bytes); err == nil { - parsedKey = cert.PublicKey - } else { - if parsedKey, err = x509.ParsePKCS1PublicKey(block.Bytes); err != nil { - return nil, err - } - } - } - - var pkey *rsa.PublicKey - var ok bool - if pkey, ok = parsedKey.(*rsa.PublicKey); !ok { - return nil, ErrNotRSAPublicKey - } - - return pkey, nil -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/signing_method.go b/vendor/github.com/golang-jwt/jwt/v5/signing_method.go deleted file mode 100644 index 0d73631c1..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/signing_method.go +++ /dev/null @@ -1,49 +0,0 @@ -package jwt - -import ( - "sync" -) - -var signingMethods = map[string]func() SigningMethod{} -var signingMethodLock = new(sync.RWMutex) - -// SigningMethod can be used add new methods for signing or verifying tokens. It -// takes a decoded signature as an input in the Verify function and produces a -// signature in Sign. The signature is then usually base64 encoded as part of a -// JWT. -type SigningMethod interface { - Verify(signingString string, sig []byte, key interface{}) error // Returns nil if signature is valid - Sign(signingString string, key interface{}) ([]byte, error) // Returns signature or error - Alg() string // returns the alg identifier for this method (example: 'HS256') -} - -// RegisterSigningMethod registers the "alg" name and a factory function for signing method. -// This is typically done during init() in the method's implementation -func RegisterSigningMethod(alg string, f func() SigningMethod) { - signingMethodLock.Lock() - defer signingMethodLock.Unlock() - - signingMethods[alg] = f -} - -// GetSigningMethod retrieves a signing method from an "alg" string -func GetSigningMethod(alg string) (method SigningMethod) { - signingMethodLock.RLock() - defer signingMethodLock.RUnlock() - - if methodF, ok := signingMethods[alg]; ok { - method = methodF() - } - return -} - -// GetAlgorithms returns a list of registered "alg" names -func GetAlgorithms() (algs []string) { - signingMethodLock.RLock() - defer signingMethodLock.RUnlock() - - for alg := range signingMethods { - algs = append(algs, alg) - } - return -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/staticcheck.conf b/vendor/github.com/golang-jwt/jwt/v5/staticcheck.conf deleted file mode 100644 index 53745d51d..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/staticcheck.conf +++ /dev/null @@ -1 +0,0 @@ -checks = ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1023"] diff --git a/vendor/github.com/golang-jwt/jwt/v5/token.go b/vendor/github.com/golang-jwt/jwt/v5/token.go deleted file mode 100644 index 352873a2d..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/token.go +++ /dev/null @@ -1,100 +0,0 @@ -package jwt - -import ( - "crypto" - "encoding/base64" - "encoding/json" -) - -// Keyfunc will be used by the Parse methods as a callback function to supply -// the key for verification. The function receives the parsed, but unverified -// Token. This allows you to use properties in the Header of the token (such as -// `kid`) to identify which key to use. -// -// The returned interface{} may be a single key or a VerificationKeySet containing -// multiple keys. -type Keyfunc func(*Token) (interface{}, error) - -// VerificationKey represents a public or secret key for verifying a token's signature. -type VerificationKey interface { - crypto.PublicKey | []uint8 -} - -// VerificationKeySet is a set of public or secret keys. It is used by the parser to verify a token. -type VerificationKeySet struct { - Keys []VerificationKey -} - -// Token represents a JWT Token. Different fields will be used depending on -// whether you're creating or parsing/verifying a token. -type Token struct { - Raw string // Raw contains the raw token. Populated when you [Parse] a token - Method SigningMethod // Method is the signing method used or to be used - Header map[string]interface{} // Header is the first segment of the token in decoded form - Claims Claims // Claims is the second segment of the token in decoded form - Signature []byte // Signature is the third segment of the token in decoded form. Populated when you Parse a token - Valid bool // Valid specifies if the token is valid. Populated when you Parse/Verify a token -} - -// New creates a new [Token] with the specified signing method and an empty map -// of claims. Additional options can be specified, but are currently unused. -func New(method SigningMethod, opts ...TokenOption) *Token { - return NewWithClaims(method, MapClaims{}, opts...) -} - -// NewWithClaims creates a new [Token] with the specified signing method and -// claims. Additional options can be specified, but are currently unused. -func NewWithClaims(method SigningMethod, claims Claims, opts ...TokenOption) *Token { - return &Token{ - Header: map[string]interface{}{ - "typ": "JWT", - "alg": method.Alg(), - }, - Claims: claims, - Method: method, - } -} - -// SignedString creates and returns a complete, signed JWT. The token is signed -// using the SigningMethod specified in the token. Please refer to -// https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types -// for an overview of the different signing methods and their respective key -// types. -func (t *Token) SignedString(key interface{}) (string, error) { - sstr, err := t.SigningString() - if err != nil { - return "", err - } - - sig, err := t.Method.Sign(sstr, key) - if err != nil { - return "", err - } - - return sstr + "." + t.EncodeSegment(sig), nil -} - -// SigningString generates the signing string. This is the most expensive part -// of the whole deal. Unless you need this for something special, just go -// straight for the SignedString. -func (t *Token) SigningString() (string, error) { - h, err := json.Marshal(t.Header) - if err != nil { - return "", err - } - - c, err := json.Marshal(t.Claims) - if err != nil { - return "", err - } - - return t.EncodeSegment(h) + "." + t.EncodeSegment(c), nil -} - -// EncodeSegment encodes a JWT specific base64url encoding with padding -// stripped. In the future, this function might take into account a -// [TokenOption]. Therefore, this function exists as a method of [Token], rather -// than a global function. -func (*Token) EncodeSegment(seg []byte) string { - return base64.RawURLEncoding.EncodeToString(seg) -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/token_option.go b/vendor/github.com/golang-jwt/jwt/v5/token_option.go deleted file mode 100644 index b4ae3badf..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/token_option.go +++ /dev/null @@ -1,5 +0,0 @@ -package jwt - -// TokenOption is a reserved type, which provides some forward compatibility, -// if we ever want to introduce token creation-related options. -type TokenOption func(*Token) diff --git a/vendor/github.com/golang-jwt/jwt/v5/types.go b/vendor/github.com/golang-jwt/jwt/v5/types.go deleted file mode 100644 index b2655a9e6..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/types.go +++ /dev/null @@ -1,149 +0,0 @@ -package jwt - -import ( - "encoding/json" - "fmt" - "math" - "strconv" - "time" -) - -// TimePrecision sets the precision of times and dates within this library. This -// has an influence on the precision of times when comparing expiry or other -// related time fields. Furthermore, it is also the precision of times when -// serializing. -// -// For backwards compatibility the default precision is set to seconds, so that -// no fractional timestamps are generated. -var TimePrecision = time.Second - -// MarshalSingleStringAsArray modifies the behavior of the ClaimStrings type, -// especially its MarshalJSON function. -// -// If it is set to true (the default), it will always serialize the type as an -// array of strings, even if it just contains one element, defaulting to the -// behavior of the underlying []string. If it is set to false, it will serialize -// to a single string, if it contains one element. Otherwise, it will serialize -// to an array of strings. -var MarshalSingleStringAsArray = true - -// NumericDate represents a JSON numeric date value, as referenced at -// https://datatracker.ietf.org/doc/html/rfc7519#section-2. -type NumericDate struct { - time.Time -} - -// NewNumericDate constructs a new *NumericDate from a standard library time.Time struct. -// It will truncate the timestamp according to the precision specified in TimePrecision. -func NewNumericDate(t time.Time) *NumericDate { - return &NumericDate{t.Truncate(TimePrecision)} -} - -// newNumericDateFromSeconds creates a new *NumericDate out of a float64 representing a -// UNIX epoch with the float fraction representing non-integer seconds. -func newNumericDateFromSeconds(f float64) *NumericDate { - round, frac := math.Modf(f) - return NewNumericDate(time.Unix(int64(round), int64(frac*1e9))) -} - -// MarshalJSON is an implementation of the json.RawMessage interface and serializes the UNIX epoch -// represented in NumericDate to a byte array, using the precision specified in TimePrecision. -func (date NumericDate) MarshalJSON() (b []byte, err error) { - var prec int - if TimePrecision < time.Second { - prec = int(math.Log10(float64(time.Second) / float64(TimePrecision))) - } - truncatedDate := date.Truncate(TimePrecision) - - // For very large timestamps, UnixNano would overflow an int64, but this - // function requires nanosecond level precision, so we have to use the - // following technique to get round the issue: - // - // 1. Take the normal unix timestamp to form the whole number part of the - // output, - // 2. Take the result of the Nanosecond function, which returns the offset - // within the second of the particular unix time instance, to form the - // decimal part of the output - // 3. Concatenate them to produce the final result - seconds := strconv.FormatInt(truncatedDate.Unix(), 10) - nanosecondsOffset := strconv.FormatFloat(float64(truncatedDate.Nanosecond())/float64(time.Second), 'f', prec, 64) - - output := append([]byte(seconds), []byte(nanosecondsOffset)[1:]...) - - return output, nil -} - -// UnmarshalJSON is an implementation of the json.RawMessage interface and -// deserializes a [NumericDate] from a JSON representation, i.e. a -// [json.Number]. This number represents an UNIX epoch with either integer or -// non-integer seconds. -func (date *NumericDate) UnmarshalJSON(b []byte) (err error) { - var ( - number json.Number - f float64 - ) - - if err = json.Unmarshal(b, &number); err != nil { - return fmt.Errorf("could not parse NumericData: %w", err) - } - - if f, err = number.Float64(); err != nil { - return fmt.Errorf("could not convert json number value to float: %w", err) - } - - n := newNumericDateFromSeconds(f) - *date = *n - - return nil -} - -// ClaimStrings is basically just a slice of strings, but it can be either -// serialized from a string array or just a string. This type is necessary, -// since the "aud" claim can either be a single string or an array. -type ClaimStrings []string - -func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) { - var value interface{} - - if err = json.Unmarshal(data, &value); err != nil { - return err - } - - var aud []string - - switch v := value.(type) { - case string: - aud = append(aud, v) - case []string: - aud = ClaimStrings(v) - case []interface{}: - for _, vv := range v { - vs, ok := vv.(string) - if !ok { - return ErrInvalidType - } - aud = append(aud, vs) - } - case nil: - return nil - default: - return ErrInvalidType - } - - *s = aud - - return -} - -func (s ClaimStrings) MarshalJSON() (b []byte, err error) { - // This handles a special case in the JWT RFC. If the string array, e.g. - // used by the "aud" field, only contains one element, it MAY be serialized - // as a single string. This may or may not be desired based on the ecosystem - // of other JWT library used, so we make it configurable by the variable - // MarshalSingleStringAsArray. - if len(s) == 1 && !MarshalSingleStringAsArray { - return json.Marshal(s[0]) - } - - return json.Marshal([]string(s)) -} diff --git a/vendor/github.com/golang-jwt/jwt/v5/validator.go b/vendor/github.com/golang-jwt/jwt/v5/validator.go deleted file mode 100644 index 008ecd871..000000000 --- a/vendor/github.com/golang-jwt/jwt/v5/validator.go +++ /dev/null @@ -1,316 +0,0 @@ -package jwt - -import ( - "crypto/subtle" - "fmt" - "time" -) - -// ClaimsValidator is an interface that can be implemented by custom claims who -// wish to execute any additional claims validation based on -// application-specific logic. The Validate function is then executed in -// addition to the regular claims validation and any error returned is appended -// to the final validation result. -// -// type MyCustomClaims struct { -// Foo string `json:"foo"` -// jwt.RegisteredClaims -// } -// -// func (m MyCustomClaims) Validate() error { -// if m.Foo != "bar" { -// return errors.New("must be foobar") -// } -// return nil -// } -type ClaimsValidator interface { - Claims - Validate() error -} - -// Validator is the core of the new Validation API. It is automatically used by -// a [Parser] during parsing and can be modified with various parser options. -// -// The [NewValidator] function should be used to create an instance of this -// struct. -type Validator struct { - // leeway is an optional leeway that can be provided to account for clock skew. - leeway time.Duration - - // timeFunc is used to supply the current time that is needed for - // validation. If unspecified, this defaults to time.Now. - timeFunc func() time.Time - - // requireExp specifies whether the exp claim is required - requireExp bool - - // verifyIat specifies whether the iat (Issued At) claim will be verified. - // According to https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6 this - // only specifies the age of the token, but no validation check is - // necessary. However, if wanted, it can be checked if the iat is - // unrealistic, i.e., in the future. - verifyIat bool - - // expectedAud contains the audience this token expects. Supplying an empty - // string will disable aud checking. - expectedAud string - - // expectedIss contains the issuer this token expects. Supplying an empty - // string will disable iss checking. - expectedIss string - - // expectedSub contains the subject this token expects. Supplying an empty - // string will disable sub checking. - expectedSub string -} - -// NewValidator can be used to create a stand-alone validator with the supplied -// options. This validator can then be used to validate already parsed claims. -// -// Note: Under normal circumstances, explicitly creating a validator is not -// needed and can potentially be dangerous; instead functions of the [Parser] -// class should be used. -// -// The [Validator] is only checking the *validity* of the claims, such as its -// expiration time, but it does NOT perform *signature verification* of the -// token. -func NewValidator(opts ...ParserOption) *Validator { - p := NewParser(opts...) - return p.validator -} - -// Validate validates the given claims. It will also perform any custom -// validation if claims implements the [ClaimsValidator] interface. -// -// Note: It will NOT perform any *signature verification* on the token that -// contains the claims and expects that the [Claim] was already successfully -// verified. -func (v *Validator) Validate(claims Claims) error { - var ( - now time.Time - errs []error = make([]error, 0, 6) - err error - ) - - // Check, if we have a time func - if v.timeFunc != nil { - now = v.timeFunc() - } else { - now = time.Now() - } - - // We always need to check the expiration time, but usage of the claim - // itself is OPTIONAL by default. requireExp overrides this behavior - // and makes the exp claim mandatory. - if err = v.verifyExpiresAt(claims, now, v.requireExp); err != nil { - errs = append(errs, err) - } - - // We always need to check not-before, but usage of the claim itself is - // OPTIONAL. - if err = v.verifyNotBefore(claims, now, false); err != nil { - errs = append(errs, err) - } - - // Check issued-at if the option is enabled - if v.verifyIat { - if err = v.verifyIssuedAt(claims, now, false); err != nil { - errs = append(errs, err) - } - } - - // If we have an expected audience, we also require the audience claim - if v.expectedAud != "" { - if err = v.verifyAudience(claims, v.expectedAud, true); err != nil { - errs = append(errs, err) - } - } - - // If we have an expected issuer, we also require the issuer claim - if v.expectedIss != "" { - if err = v.verifyIssuer(claims, v.expectedIss, true); err != nil { - errs = append(errs, err) - } - } - - // If we have an expected subject, we also require the subject claim - if v.expectedSub != "" { - if err = v.verifySubject(claims, v.expectedSub, true); err != nil { - errs = append(errs, err) - } - } - - // Finally, we want to give the claim itself some possibility to do some - // additional custom validation based on a custom Validate function. - cvt, ok := claims.(ClaimsValidator) - if ok { - if err := cvt.Validate(); err != nil { - errs = append(errs, err) - } - } - - if len(errs) == 0 { - return nil - } - - return joinErrors(errs...) -} - -// verifyExpiresAt compares the exp claim in claims against cmp. This function -// will succeed if cmp < exp. Additional leeway is taken into account. -// -// If exp is not set, it will succeed if the claim is not required, -// otherwise ErrTokenRequiredClaimMissing will be returned. -// -// Additionally, if any error occurs while retrieving the claim, e.g., when its -// the wrong type, an ErrTokenUnverifiable error will be returned. -func (v *Validator) verifyExpiresAt(claims Claims, cmp time.Time, required bool) error { - exp, err := claims.GetExpirationTime() - if err != nil { - return err - } - - if exp == nil { - return errorIfRequired(required, "exp") - } - - return errorIfFalse(cmp.Before((exp.Time).Add(+v.leeway)), ErrTokenExpired) -} - -// verifyIssuedAt compares the iat claim in claims against cmp. This function -// will succeed if cmp >= iat. Additional leeway is taken into account. -// -// If iat is not set, it will succeed if the claim is not required, -// otherwise ErrTokenRequiredClaimMissing will be returned. -// -// Additionally, if any error occurs while retrieving the claim, e.g., when its -// the wrong type, an ErrTokenUnverifiable error will be returned. -func (v *Validator) verifyIssuedAt(claims Claims, cmp time.Time, required bool) error { - iat, err := claims.GetIssuedAt() - if err != nil { - return err - } - - if iat == nil { - return errorIfRequired(required, "iat") - } - - return errorIfFalse(!cmp.Before(iat.Add(-v.leeway)), ErrTokenUsedBeforeIssued) -} - -// verifyNotBefore compares the nbf claim in claims against cmp. This function -// will return true if cmp >= nbf. Additional leeway is taken into account. -// -// If nbf is not set, it will succeed if the claim is not required, -// otherwise ErrTokenRequiredClaimMissing will be returned. -// -// Additionally, if any error occurs while retrieving the claim, e.g., when its -// the wrong type, an ErrTokenUnverifiable error will be returned. -func (v *Validator) verifyNotBefore(claims Claims, cmp time.Time, required bool) error { - nbf, err := claims.GetNotBefore() - if err != nil { - return err - } - - if nbf == nil { - return errorIfRequired(required, "nbf") - } - - return errorIfFalse(!cmp.Before(nbf.Add(-v.leeway)), ErrTokenNotValidYet) -} - -// verifyAudience compares the aud claim against cmp. -// -// If aud is not set or an empty list, it will succeed if the claim is not required, -// otherwise ErrTokenRequiredClaimMissing will be returned. -// -// Additionally, if any error occurs while retrieving the claim, e.g., when its -// the wrong type, an ErrTokenUnverifiable error will be returned. -func (v *Validator) verifyAudience(claims Claims, cmp string, required bool) error { - aud, err := claims.GetAudience() - if err != nil { - return err - } - - if len(aud) == 0 { - return errorIfRequired(required, "aud") - } - - // use a var here to keep constant time compare when looping over a number of claims - result := false - - var stringClaims string - for _, a := range aud { - if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 { - result = true - } - stringClaims = stringClaims + a - } - - // case where "" is sent in one or many aud claims - if stringClaims == "" { - return errorIfRequired(required, "aud") - } - - return errorIfFalse(result, ErrTokenInvalidAudience) -} - -// verifyIssuer compares the iss claim in claims against cmp. -// -// If iss is not set, it will succeed if the claim is not required, -// otherwise ErrTokenRequiredClaimMissing will be returned. -// -// Additionally, if any error occurs while retrieving the claim, e.g., when its -// the wrong type, an ErrTokenUnverifiable error will be returned. -func (v *Validator) verifyIssuer(claims Claims, cmp string, required bool) error { - iss, err := claims.GetIssuer() - if err != nil { - return err - } - - if iss == "" { - return errorIfRequired(required, "iss") - } - - return errorIfFalse(iss == cmp, ErrTokenInvalidIssuer) -} - -// verifySubject compares the sub claim against cmp. -// -// If sub is not set, it will succeed if the claim is not required, -// otherwise ErrTokenRequiredClaimMissing will be returned. -// -// Additionally, if any error occurs while retrieving the claim, e.g., when its -// the wrong type, an ErrTokenUnverifiable error will be returned. -func (v *Validator) verifySubject(claims Claims, cmp string, required bool) error { - sub, err := claims.GetSubject() - if err != nil { - return err - } - - if sub == "" { - return errorIfRequired(required, "sub") - } - - return errorIfFalse(sub == cmp, ErrTokenInvalidSubject) -} - -// errorIfFalse returns the error specified in err, if the value is true. -// Otherwise, nil is returned. -func errorIfFalse(value bool, err error) error { - if value { - return nil - } else { - return err - } -} - -// errorIfRequired returns an ErrTokenRequiredClaimMissing error if required is -// true. Otherwise, nil is returned. -func errorIfRequired(required bool, claim string) error { - if required { - return newError(fmt.Sprintf("%s claim is required", claim), ErrTokenRequiredClaimMissing) - } else { - return nil - } -} diff --git a/vendor/github.com/golangci/dupl/.travis.yml b/vendor/github.com/golangci/dupl/.travis.yml deleted file mode 100644 index 33de24c0f..000000000 --- a/vendor/github.com/golangci/dupl/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: go -go: - - 1.3 - - 1.8 - - 1.9 diff --git a/vendor/github.com/golangci/dupl/LICENSE b/vendor/github.com/golangci/dupl/LICENSE deleted file mode 100644 index ab317d841..000000000 --- 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/README.md b/vendor/github.com/golangci/dupl/README.md deleted file mode 100644 index f34901d7a..000000000 --- a/vendor/github.com/golangci/dupl/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# dupl [![Build Status](https://travis-ci.org/mibk/dupl.png)](https://travis-ci.org/mibk/dupl) - -**dupl** is a tool written in Go for finding code clones. So far it can find clones only -in the Go source files. The method uses suffix tree for serialized ASTs. It ignores values -of AST nodes. It just operates with their types (e.g. `if a == 13 {}` and `if x == 100 {}` are -considered the same provided it exceeds the minimal token sequence size). - -Due to the used method dupl can report so called "false positives" on the output. These are -the ones we do not consider clones (whether they are too small, or the values of the matched -tokens are completely different). - -## Installation - -```bash -go get -u github.com/golangci/dupl -``` - -## Usage - -``` -Usage of dupl: - dupl [flags] [paths] - -Paths: - If the given path is a file, dupl will use it regardless of - the file extension. If it is a directory it will recursively - search for *.go files in that directory. - - If no path is given dupl will recursively search for *.go - files in the current directory. - -Flags: - -files - read file names from stdin one at each line - -html - output the results as HTML, including duplicate code fragments - -plumbing - plumbing (easy-to-parse) output for consumption by scripts or tools - -t, -threshold size - minimum token sequence size as a clone (default 15) - -vendor - check files in vendor directory - -v, -verbose - explain what is being done - -Examples: - dupl -t 100 - Search clones in the current directory of size at least - 100 tokens. - dupl $(find app/ -name '*_test.go') - Search for clones in tests in the app directory. - find app/ -name '*_test.go' |dupl -files - The same as above. -``` - -## Example - -The reduced output of this command with the following parameters for the [Docker](https://www.docker.com) source code -looks like [this](http://htmlpreview.github.io/?https://github.com/golangci/dupl/blob/master/_output_example/docker.html). - -```bash -$ dupl -t 200 -html >docker.html -``` 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 e9aad54c0..000000000 --- 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 eb9d7c625..000000000 --- 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/main.go b/vendor/github.com/golangci/dupl/main.go deleted file mode 100644 index 3030a97ae..000000000 --- a/vendor/github.com/golangci/dupl/main.go +++ /dev/null @@ -1,148 +0,0 @@ -package dupl - -import ( - "flag" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "sort" - - "github.com/golangci/dupl/job" - "github.com/golangci/dupl/printer" - "github.com/golangci/dupl/syntax" -) - -const defaultThreshold = 15 - -var ( - paths = []string{"."} - vendor = flag.Bool("dupl.vendor", false, "") - verbose = flag.Bool("dupl.verbose", false, "") - files = flag.Bool("dupl.files", false, "") - - html = flag.Bool("dupl.html", false, "") - plumbing = flag.Bool("dupl.plumbing", false, "") -) - -const ( - vendorDirPrefix = "vendor" + string(filepath.Separator) - vendorDirInPath = string(filepath.Separator) + vendorDirPrefix -) - -func init() { - flag.BoolVar(verbose, "dupl.v", false, "alias for -verbose") -} - -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.NewPlumbing(ioutil.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 -} - -func usage() { - fmt.Fprintln(os.Stderr, `Usage: dupl [flags] [paths] - -Paths: - If the given path is a file, dupl will use it regardless of - the file extension. If it is a directory, it will recursively - search for *.go files in that directory. - - If no path is given, dupl will recursively search for *.go - files in the current directory. - -Flags: - -files - read file names from stdin one at each line - -html - output the results as HTML, including duplicate code fragments - -plumbing - plumbing (easy-to-parse) output for consumption by scripts or tools - -t, -threshold size - minimum token sequence size as a clone (default 15) - -vendor - check files in vendor directory - -v, -verbose - explain what is being done - -Examples: - dupl -t 100 - Search clones in the current directory of size at least - 100 tokens. - dupl $(find app/ -name '*_test.go') - Search for clones in tests in the app directory. - find app/ -name '*_test.go' |dupl -files - The same as above.`) - os.Exit(2) -} 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 5ad9e25c7..000000000 --- a/vendor/github.com/golangci/dupl/printer/html.go +++ /dev/null @@ -1,120 +0,0 @@ -package printer - -import ( - "bytes" - "fmt" - "io" - "regexp" - "sort" - - "github.com/golangci/dupl/syntax" -) - -type html struct { - iota int - w io.Writer - ReadFile -} - -func NewHTML(w io.Writer, fread ReadFile) Printer { - return &html{w: w, ReadFile: fread} -} - -func (p *html) PrintHeader() error { - _, err := fmt.Fprint(p.w, ` - -Duplicates - -`) - return err -} - -func (p *html) 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, cl.fragment) - } - return nil -} - -func (*html) 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/plumbing.go b/vendor/github.com/golangci/dupl/printer/plumbing.go deleted file mode 100644 index cf39d01b7..000000000 --- a/vendor/github.com/golangci/dupl/printer/plumbing.go +++ /dev/null @@ -1,50 +0,0 @@ -package printer - -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 Plumbing struct { - ReadFile -} - -func NewPlumbing(fread ReadFile) *Plumbing { - return &Plumbing{fread} -} - -func (p *Plumbing) 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/printer.go b/vendor/github.com/golangci/dupl/printer/printer.go deleted file mode 100644 index 385217bfc..000000000 --- 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 8359fa76f..000000000 --- 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 ab145b4f3..000000000 --- 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 738015025..000000000 --- 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 a0b1e77e1..000000000 --- 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 e2c750afd..000000000 --- a/vendor/github.com/golangci/dupl/syntax/syntax.go +++ /dev/null @@ -1,175 +0,0 @@ -package syntax - -import ( - "crypto/sha1" - - "github.com/golangci/dupl/suffixtree" -) - -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 _, child := range n.Children { - 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/gofmt/gofmt/LICENSE b/vendor/github.com/golangci/gofmt/gofmt/LICENSE deleted file mode 100644 index 6a66aea5e..000000000 --- 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 d0a458021..000000000 --- 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 909d37657..000000000 --- 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/golangci/gofmt/gofmt/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 a69611e1d..000000000 --- a/vendor/github.com/golangci/gofmt/gofmt/golangci.go +++ /dev/null @@ -1,100 +0,0 @@ -package gofmt - -import ( - "bytes" - "fmt" - "go/ast" - "go/parser" - "go/printer" - "go/token" - "os" - "path/filepath" - "sync" - - "github.com/golangci/gofmt/gofmt/internal/diff" -) - -var parserModeMu sync.RWMutex - -type RewriteRule struct { - Pattern string - Replacement string -} - -// Run runs gofmt. -// Deprecated: use RunRewrite instead. -func Run(filename string, needSimplify bool) ([]byte, error) { - return RunRewrite(filename, needSimplify, nil) -} - -// RunRewrite runs gofmt. -// empty string `rewrite` will be ignored. -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 -} - -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 231a25091..000000000 --- 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/internal/diff/diff.go b/vendor/github.com/golangci/gofmt/gofmt/internal/diff/diff.go deleted file mode 100644 index 6a40b23fc..000000000 --- a/vendor/github.com/golangci/gofmt/gofmt/internal/diff/diff.go +++ /dev/null @@ -1,261 +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" - "fmt" - "sort" - "strings" -) - -// A pair is a pair of values tracked for both the x and y side of a diff. -// It is typically a pair of line indexes. -type pair struct{ x, y int } - -// Diff returns an anchored diff of the two texts old and new -// in the “unified diff” format. If old and new are identical, -// Diff returns a nil slice (no output). -// -// Unix diff implementations typically look for a diff with -// the smallest number of lines inserted and removed, -// which can in the worst case take time quadratic in the -// number of lines in the texts. As a result, many implementations -// either can be made to run for a long time or cut off the search -// after a predetermined amount of work. -// -// In contrast, this implementation looks for a diff with the -// smallest number of “unique” lines inserted and removed, -// where unique means a line that appears just once in both old and new. -// We call this an “anchored diff” because the unique lines anchor -// the chosen matching regions. An anchored diff is usually clearer -// than a standard diff, because the algorithm does not try to -// reuse unrelated blank lines or closing braces. -// The algorithm also guarantees to run in O(n log n) time -// instead of the standard O(n²) time. -// -// Some systems call this approach a “patience diff,” named for -// the “patience sorting” algorithm, itself named for a solitaire card game. -// We avoid that name for two reasons. First, the name has been used -// for a few different variants of the algorithm, so it is imprecise. -// Second, the name is frequently interpreted as meaning that you have -// to wait longer (to be patient) for the diff, meaning that it is a slower algorithm, -// when in fact the algorithm is faster than the standard one. -func Diff(oldName string, old []byte, newName string, new []byte) []byte { - if bytes.Equal(old, new) { - return nil - } - x := lines(old) - y := lines(new) - - // Print diff header. - var out bytes.Buffer - fmt.Fprintf(&out, "diff %s %s\n", oldName, newName) - fmt.Fprintf(&out, "--- %s\n", oldName) - fmt.Fprintf(&out, "+++ %s\n", newName) - - // Loop over matches to consider, - // expanding each match to include surrounding lines, - // and then printing diff chunks. - // To avoid setup/teardown cases outside the loop, - // tgs returns a leading {0,0} and trailing {len(x), len(y)} pair - // in the sequence of matches. - var ( - done pair // printed up to x[:done.x] and y[:done.y] - chunk pair // start lines of current chunk - count pair // number of lines from each side in current chunk - ctext []string // lines for current chunk - ) - for _, m := range tgs(x, y) { - if m.x < done.x { - // Already handled scanning forward from earlier match. - continue - } - - // Expand matching lines as far as possible, - // establishing that x[start.x:end.x] == y[start.y:end.y]. - // Note that on the first (or last) iteration we may (or definitely do) - // have an empty match: start.x==end.x and start.y==end.y. - start := m - for start.x > done.x && start.y > done.y && x[start.x-1] == y[start.y-1] { - start.x-- - start.y-- - } - end := m - for end.x < len(x) && end.y < len(y) && x[end.x] == y[end.y] { - end.x++ - end.y++ - } - - // Emit the mismatched lines before start into this chunk. - // (No effect on first sentinel iteration, when start = {0,0}.) - for _, s := range x[done.x:start.x] { - ctext = append(ctext, "-"+s) - count.x++ - } - for _, s := range y[done.y:start.y] { - ctext = append(ctext, "+"+s) - count.y++ - } - - // If we're not at EOF and have too few common lines, - // the chunk includes all the common lines and continues. - const C = 3 // number of context lines - if (end.x < len(x) || end.y < len(y)) && - (end.x-start.x < C || (len(ctext) > 0 && end.x-start.x < 2*C)) { - for _, s := range x[start.x:end.x] { - ctext = append(ctext, " "+s) - count.x++ - count.y++ - } - done = end - continue - } - - // End chunk with common lines for context. - if len(ctext) > 0 { - n := end.x - start.x - if n > C { - n = C - } - for _, s := range x[start.x : start.x+n] { - ctext = append(ctext, " "+s) - count.x++ - count.y++ - } - done = pair{start.x + n, start.y + n} - - // Format and emit chunk. - // Convert line numbers to 1-indexed. - // Special case: empty file shows up as 0,0 not 1,0. - if count.x > 0 { - chunk.x++ - } - if count.y > 0 { - chunk.y++ - } - fmt.Fprintf(&out, "@@ -%d,%d +%d,%d @@\n", chunk.x, count.x, chunk.y, count.y) - for _, s := range ctext { - out.WriteString(s) - } - count.x = 0 - count.y = 0 - ctext = ctext[:0] - } - - // If we reached EOF, we're done. - if end.x >= len(x) && end.y >= len(y) { - break - } - - // Otherwise start a new chunk. - chunk = pair{end.x - C, end.y - C} - for _, s := range x[chunk.x:end.x] { - ctext = append(ctext, " "+s) - count.x++ - count.y++ - } - done = end - } - - return out.Bytes() -} - -// lines returns the lines in the file x, including newlines. -// If the file does not end in a newline, one is supplied -// along with a warning about the missing newline. -func lines(x []byte) []string { - l := strings.SplitAfter(string(x), "\n") - if l[len(l)-1] == "" { - l = l[:len(l)-1] - } else { - // Treat last line as having a message about the missing newline attached, - // using the same text as BSD/GNU diff (including the leading backslash). - l[len(l)-1] += "\n\\ No newline at end of file\n" - } - return l -} - -// tgs returns the pairs of indexes of the longest common subsequence -// of unique lines in x and y, where a unique line is one that appears -// once in x and once in y. -// -// The longest common subsequence algorithm is as described in -// Thomas G. Szymanski, “A Special Case of the Maximal Common -// Subsequence Problem,” Princeton TR #170 (January 1975), -// available at https://research.swtch.com/tgs170.pdf. -func tgs(x, y []string) []pair { - // Count the number of times each string appears in a and b. - // We only care about 0, 1, many, counted as 0, -1, -2 - // for the x side and 0, -4, -8 for the y side. - // Using negative numbers now lets us distinguish positive line numbers later. - m := make(map[string]int) - for _, s := range x { - if c := m[s]; c > -2 { - m[s] = c - 1 - } - } - for _, s := range y { - if c := m[s]; c > -8 { - m[s] = c - 4 - } - } - - // Now unique strings can be identified by m[s] = -1+-4. - // - // Gather the indexes of those strings in x and y, building: - // xi[i] = increasing indexes of unique strings in x. - // yi[i] = increasing indexes of unique strings in y. - // inv[i] = index j such that x[xi[i]] = y[yi[j]]. - var xi, yi, inv []int - for i, s := range y { - if m[s] == -1+-4 { - m[s] = len(yi) - yi = append(yi, i) - } - } - for i, s := range x { - if j, ok := m[s]; ok && j >= 0 { - xi = append(xi, i) - inv = append(inv, j) - } - } - - // Apply Algorithm A from Szymanski's paper. - // In those terms, A = J = inv and B = [0, n). - // We add sentinel pairs {0,0}, and {len(x),len(y)} - // to the returned sequence, to help the processing loop. - J := inv - n := len(xi) - T := make([]int, n) - L := make([]int, n) - for i := range T { - T[i] = n + 1 - } - for i := 0; i < n; i++ { - k := sort.Search(n, func(k int) bool { - return T[k] >= J[i] - }) - T[k] = J[i] - L[i] = k + 1 - } - k := 0 - for _, v := range L { - if k < v { - k = v - } - } - seq := make([]pair, 2+k) - seq[1+k] = pair{len(x), len(y)} // sentinel at end - lastj := n - for i := n - 1; i >= 0; i-- { - if L[i] == k && J[i] < lastj { - seq[k] = pair{xi[i], yi[J[i]]} - k-- - } - } - seq[0] = pair{0, 0} // sentinel at start - return seq -} 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 be08179e6..000000000 --- a/vendor/github.com/golangci/gofmt/gofmt/readme.md +++ /dev/null @@ -1,16 +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/txtar -- https://github.com/golang/go/blob/master/src/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 c95d44f61..000000000 --- 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 3b34d562b..000000000 --- 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/gofmt/goimports/LICENSE b/vendor/github.com/golangci/gofmt/goimports/LICENSE deleted file mode 100644 index 6a66aea5e..000000000 --- a/vendor/github.com/golangci/gofmt/goimports/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/goimports/goimports.go b/vendor/github.com/golangci/gofmt/goimports/goimports.go deleted file mode 100644 index 556f2bd7e..000000000 --- a/vendor/github.com/golangci/gofmt/goimports/goimports.go +++ /dev/null @@ -1,88 +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. - -package goimports - -import ( - "bytes" - "fmt" - "os" - "os/exec" - "path/filepath" - "runtime" -) - -// Extracted from golang.org/x/tools@v0.24.0/cmd/goimports/goimports.go - -func writeTempFile(dir, prefix string, data []byte) (string, error) { - file, err := os.CreateTemp(dir, prefix) - if err != nil { - return "", err - } - _, err = file.Write(data) - if err1 := file.Close(); err == nil { - err = err1 - } - if err != nil { - os.Remove(file.Name()) - return "", err - } - return file.Name(), nil -} - -func diff(b1, b2 []byte, filename string) (data []byte, err error) { - f1, err := writeTempFile("", "gofmt", b1) - if err != nil { - return - } - defer os.Remove(f1) - - f2, err := writeTempFile("", "gofmt", b2) - if err != nil { - return - } - defer os.Remove(f2) - - cmd := "diff" - if runtime.GOOS == "plan9" { - cmd = "/bin/ape/diff" - } - - data, err = exec.Command(cmd, "-u", f1, f2).CombinedOutput() - if len(data) > 0 { - // diff exits with a non-zero status when the files don't match. - // Ignore that failure as long as we get output. - return replaceTempFilename(data, filename) - } - return -} - -// replaceTempFilename replaces temporary filenames in diff with actual one. -// -// --- /tmp/gofmt316145376 2017-02-03 19:13:00.280468375 -0500 -// +++ /tmp/gofmt617882815 2017-02-03 19:13:00.280468375 -0500 -// ... -// -> -// --- path/to/file.go.orig 2017-02-03 19:13:00.280468375 -0500 -// +++ path/to/file.go 2017-02-03 19:13:00.280468375 -0500 -// ... -func replaceTempFilename(diff []byte, filename string) ([]byte, error) { - bs := bytes.SplitN(diff, []byte{'\n'}, 3) - if len(bs) < 3 { - return nil, fmt.Errorf("got unexpected diff for %s", filename) - } - // Preserve timestamps. - var t0, t1 []byte - if i := bytes.LastIndexByte(bs[0], '\t'); i != -1 { - t0 = bs[0][i:] - } - if i := bytes.LastIndexByte(bs[1], '\t'); i != -1 { - t1 = bs[1][i:] - } - // Always print filepath with slash separator. - f := filepath.ToSlash(filename) - bs[0] = []byte(fmt.Sprintf("--- %s%s", f+".orig", t0)) - bs[1] = []byte(fmt.Sprintf("+++ %s%s", f, t1)) - return bytes.Join(bs, []byte{'\n'}), nil -} diff --git a/vendor/github.com/golangci/gofmt/goimports/golangci.go b/vendor/github.com/golangci/gofmt/goimports/golangci.go deleted file mode 100644 index 6ff286ae0..000000000 --- a/vendor/github.com/golangci/gofmt/goimports/golangci.go +++ /dev/null @@ -1,35 +0,0 @@ -package goimports - -import ( - "bytes" - "fmt" - "os" - - "golang.org/x/tools/imports" -) - -// Run runs goimports. -// The local prefixes (comma separated) must be defined through the global variable imports.LocalPrefix. -func Run(filename string) ([]byte, error) { - src, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - - res, err := imports.Process(filename, src, nil) - if err != nil { - return nil, err - } - - if bytes.Equal(src, res) { - return nil, nil - } - - // formatting has changed - data, err := diff(src, res, filename) - if err != nil { - return nil, fmt.Errorf("error computing diff: %s", err) - } - - return data, nil -} diff --git a/vendor/github.com/golangci/gofmt/goimports/readme.md b/vendor/github.com/golangci/gofmt/goimports/readme.md deleted file mode 100644 index 23eecf82f..000000000 --- a/vendor/github.com/golangci/gofmt/goimports/readme.md +++ /dev/null @@ -1,10 +0,0 @@ -# Hard Fork of goimports - -- https://github.com/golang/tools/tree/master/cmd/goimports - -## Updates - -- 2024-08-17: Sync with golang.org/x/tools v0.24.0 -- 2024-02-28: Sync with golang.org/x/tools v0.18.0 -- 2023-10-04: Sync with golang.org/x/tools v0.13.0 -- 2022-08-31: Sync with golang.org/x/tools v0.1.12 diff --git a/vendor/github.com/golangci/golangci-lint/LICENSE b/vendor/github.com/golangci/golangci-lint/LICENSE deleted file mode 100644 index e72bfddab..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/cmd/golangci-lint/main.go b/vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/main.go deleted file mode 100644 index 413e071d6..000000000 --- a/vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/main.go +++ /dev/null @@ -1,81 +0,0 @@ -package main - -import ( - "fmt" - "os" - "runtime/debug" - - "github.com/golangci/golangci-lint/pkg/commands" - "github.com/golangci/golangci-lint/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, "Failed executing command with 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 - - 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 - } - } - - if revision == "" { - revision = "unknown" - } - - if modified == "" { - modified = "?" - } - - if info.Date == "" { - info.Date = "(unknown)" - } - - info.Commit = fmt.Sprintf("(%s, modified: %s, mod sum: %q)", revision, modified, buildInfo.Main.Sum) - - return info -} diff --git a/vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/plugins.go b/vendor/github.com/golangci/golangci-lint/cmd/golangci-lint/plugins.go deleted file mode 100644 index 541ff7624..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/internal/cache/cache.go b/vendor/github.com/golangci/golangci-lint/internal/cache/cache.go deleted file mode 100644 index 299fd5279..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/cache/cache.go +++ /dev/null @@ -1,525 +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" - "os" - "path/filepath" - "strconv" - "strings" - "time" - - "github.com/golangci/golangci-lint/internal/renameio" - "github.com/golangci/golangci-lint/internal/robustio" -) - -// 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 - -// A Cache is a package cache, backed by a file system directory tree. -type Cache 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) (*Cache, error) { - info, err := os.Stat(dir) - if err != nil { - return nil, err - } - if !info.IsDir() { - return nil, &os.PathError{Op: "open", Path: dir, Err: errors.New("not a directory")} - } - for i := 0; i < 256; i++ { - name := filepath.Join(dir, fmt.Sprintf("%02x", i)) - if err := os.MkdirAll(name, 0744); err != nil { - return nil, err - } - } - c := &Cache{ - dir: dir, - now: time.Now, - } - return c, nil -} - -// fileName returns the name of the file corresponding to the given id. -func (c *Cache) fileName(id [HashSize]byte, key string) string { - return filepath.Join(c.dir, fmt.Sprintf("%02x", id[0]), fmt.Sprintf("%x", id)+"-"+key) -} - -var errMissing = errors.New("cache entry not found") - -func IsErrMissing(err error) bool { - return errors.Is(err, errMissing) -} - -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 - -// DebugTest is set when GODEBUG=gocachetest=1 is in the environment. -var DebugTest = false - -func init() { initEnv() } - -func initEnv() { - verify = false - debugHash = false - debug := strings.Split(os.Getenv("GODEBUG"), ",") - for _, f := range debug { - if f == "gocacheverify=1" { - verify = true - } - if f == "gocachehash=1" { - debugHash = true - } - if f == "gocachetest=1" { - 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 *Cache) Get(id ActionID) (Entry, error) { - if verify { - return Entry{}, errMissing - } - return c.get(id) -} - -type Entry struct { - OutputID OutputID - Size int64 - Time time.Time -} - -// get is Get but does not respect verify mode, so that Put can use it. -func (c *Cache) get(id ActionID) (Entry, error) { - missing := func() (Entry, error) { - return Entry{}, errMissing - } - failed := func(err error) (Entry, error) { - return Entry{}, err - } - fileName := c.fileName(id, "a") - f, err := os.Open(fileName) - if err != nil { - if os.IsNotExist(err) { - return missing() - } - return failed(err) - } - defer f.Close() - entry := make([]byte, entrySize+1) // +1 to detect whether f is too long - if n, readErr := io.ReadFull(f, entry); n != entrySize || readErr != io.ErrUnexpectedEOF { - return failed(fmt.Errorf("read %d/%d bytes from %s with error %w", n, entrySize, fileName, readErr)) - } - 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 failed(fmt.Errorf("bad data in %s", fileName)) - } - 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[1 : 1+20] - var buf [HashSize]byte - if _, err = hex.Decode(buf[:], eid); err != nil || buf != id { - return failed(fmt.Errorf("failed to hex decode eid data in %s: %w", fileName, err)) - } - if _, err = hex.Decode(buf[:], eout); err != nil { - return failed(fmt.Errorf("failed to hex decode eout data in %s: %w", fileName, err)) - } - i := 0 - for i < len(esize) && esize[i] == ' ' { - i++ - } - size, err := strconv.ParseInt(string(esize[i:]), 10, 64) - if err != nil || size < 0 { - return failed(fmt.Errorf("failed to parse esize int from %s with error %w", fileName, err)) - } - i = 0 - for i < len(etime) && etime[i] == ' ' { - i++ - } - tm, err := strconv.ParseInt(string(etime[i:]), 10, 64) - if err != nil || tm < 0 { - return failed(fmt.Errorf("failed to parse etime int from %s with error %w", fileName, err)) - } - - if err = c.used(fileName); err != nil { - return failed(fmt.Errorf("failed to mark %s as used: %w", fileName, err)) - } - - return Entry{buf, size, time.Unix(0, tm)}, 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 (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) { - entry, err := c.Get(id) - if err != nil { - return nil, entry, err - } - outputFile, err := c.OutputFile(entry.OutputID) - if err != nil { - return nil, entry, err - } - - data, err := robustio.ReadFile(outputFile) - if err != nil { - return nil, entry, err - } - - if sha256.Sum256(data) != entry.OutputID { - return nil, entry, errMissing - } - return data, entry, nil -} - -// OutputFile returns the name of the cache file storing output with the given OutputID. -func (c *Cache) OutputFile(out OutputID) (string, error) { - file := c.fileName(out, "d") - if err := c.used(file); err != nil { - return "", err - } - return file, nil -} - -// 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 -) - -// used 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 the mtime updates that would otherwise happen, -// while still keeping the mtimes useful for cache trimming. -func (c *Cache) used(file string) error { - info, err := os.Stat(file) - if err != nil { - if os.IsNotExist(err) { - return errMissing - } - return fmt.Errorf("failed to stat file %s: %w", file, err) - } - - if c.now().Sub(info.ModTime()) < mtimeInterval { - return nil - } - - if err := os.Chtimes(file, c.now(), c.now()); err != nil { - return fmt.Errorf("failed to change time of file %s: %w", file, err) - } - - return nil -} - -// Trim removes old cache entries that are likely not to be reused. -func (c *Cache) Trim() { - 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. - data, _ := renameio.ReadFile(filepath.Join(c.dir, "trim.txt")) - t, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64) - if err == nil && now.Sub(time.Unix(t, 0)) < trimInterval { - return - } - - // 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. - _ = renameio.WriteFile(filepath.Join(c.dir, "trim.txt"), []byte(fmt.Sprintf("%d", now.Unix())), 0666) -} - -// trimSubdir trims a single cache subdirectory. -func (c *Cache) 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) { - 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 *Cache) 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, 0666) - 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 - } - if err = os.Chtimes(file, c.now(), c.now()); err != nil { // mainly for tests - return fmt.Errorf("failed to change time of file %s: %w", file, err) - } - - return nil -} - -// 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 *Cache) Put(id ActionID, file io.ReadSeeker) (OutputID, int64, error) { - return c.put(id, file, true) -} - -// 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 (c *Cache) PutNoVerify(id ActionID, file io.ReadSeeker) (OutputID, int64, error) { - return c.put(id, file, false) -} - -func (c *Cache) put(id ActionID, 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). - if err := c.copyFile(file, out, size); 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 (c *Cache) PutBytes(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 *Cache) copyFile(file io.ReadSeeker, out OutputID, size int64) error { - name := c.fileName(out, "d") - info, err := os.Stat(name) - if err == nil && info.Size() == size { - // Check hash. - if f, openErr := os.Open(name); openErr == nil { - h := sha256.New() - if _, copyErr := io.Copy(h, f); 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, 0666) - if err != 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 - } - if n, wErr := h.Write(buf); 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 errors.New("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 - } - if err = os.Chtimes(name, c.now(), c.now()); err != nil { // mainly for tests - return fmt.Errorf("failed to change time of file %s: %w", name, err) - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/internal/cache/default.go b/vendor/github.com/golangci/golangci-lint/internal/cache/default.go deleted file mode 100644 index 399cc84cf..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/cache/default.go +++ /dev/null @@ -1,88 +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" - "log" - "os" - "path/filepath" - "sync" -) - -const envGolangciLintCache = "GOLANGCI_LINT_CACHE" - -// Default returns the default cache to use. -func Default() (*Cache, error) { - defaultOnce.Do(initDefaultCache) - return defaultCache, defaultDirErr -} - -var ( - defaultOnce sync.Once - defaultCache *Cache -) - -// 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() { - dir := DefaultDir() - if err := os.MkdirAll(dir, 0744); err != nil { - log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) - } - if _, err := os.Stat(filepath.Join(dir, "README")); err != nil { - // Best effort. - if wErr := os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666); wErr != nil { - log.Fatalf("Failed to write README file to cache dir %s: %s", dir, err) - } - } - - c, err := Open(dir) - if err != nil { - log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) - } - defaultCache = c -} - -var ( - defaultDirOnce sync.Once - defaultDir string - defaultDirErr error -) - -// DefaultDir returns the effective GOLANGCI_LINT_CACHE setting. -func DefaultDir() string { - // Save the result of the first call to DefaultDir for later use in - // initDefaultCache. cmd/go/main.go explicitly sets GOCACHE 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 filepath.IsAbs(defaultDir) { - return - } - if defaultDir != "" { - defaultDirErr = fmt.Errorf("%s is not an absolute path", envGolangciLintCache) - return - } - - // Compute default location. - dir, err := os.UserCacheDir() - if err != nil { - defaultDirErr = fmt.Errorf("%s is not defined and %w", envGolangciLintCache, err) - return - } - defaultDir = filepath.Join(dir, "golangci-lint") - }) - - return defaultDir -} diff --git a/vendor/github.com/golangci/golangci-lint/internal/cache/hash.go b/vendor/github.com/golangci/golangci-lint/internal/cache/hash.go deleted file mode 100644 index 4ce79e325..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/cache/hash.go +++ /dev/null @@ -1,186 +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" - "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 - -func SetSalt(b []byte) { - hashSalt = b -} - -// 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() - const subkeyPrefix = "subkey:" - if n, err := h.Write([]byte(subkeyPrefix)); n != len(subkeyPrefix) { - return ActionID{}, fmt.Errorf("wrote %d/%d bytes of subkey prefix with error %s", n, len(subkeyPrefix), err) - } - if n, err := h.Write(parent[:]); n != len(parent) { - return ActionID{}, fmt.Errorf("wrote %d/%d bytes of parent with error %s", n, len(parent), err) - } - if n, err := h.Write([]byte(desc)); 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) - } - if n, err := h.Write(hashSalt); 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/internal/cache/readme.md b/vendor/github.com/golangci/golangci-lint/internal/cache/readme.md deleted file mode 100644 index b469711ed..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/cache/readme.md +++ /dev/null @@ -1,18 +0,0 @@ -# cache - -Extracted from go/src/cmd/go/internal/cache/ -I don't know what version of Go this package was pulled from. - -Adapted for golangci-lint: -- https://github.com/golangci/golangci-lint/pull/699 -- https://github.com/golangci/golangci-lint/pull/779 -- https://github.com/golangci/golangci-lint/pull/788 -- https://github.com/golangci/golangci-lint/pull/808 -- https://github.com/golangci/golangci-lint/pull/1063 -- https://github.com/golangci/golangci-lint/pull/1070 -- https://github.com/golangci/golangci-lint/pull/1162 -- https://github.com/golangci/golangci-lint/pull/2318 -- https://github.com/golangci/golangci-lint/pull/2352 -- https://github.com/golangci/golangci-lint/pull/3012 -- https://github.com/golangci/golangci-lint/pull/3096 -- https://github.com/golangci/golangci-lint/pull/3204 diff --git a/vendor/github.com/golangci/golangci-lint/internal/errorutil/errors.go b/vendor/github.com/golangci/golangci-lint/internal/errorutil/errors.go deleted file mode 100644 index c8a3a0357..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/internal/pkgcache/pkgcache.go b/vendor/github.com/golangci/golangci-lint/internal/pkgcache/pkgcache.go deleted file mode 100644 index 3b3422eb7..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/pkgcache/pkgcache.go +++ /dev/null @@ -1,229 +0,0 @@ -package pkgcache - -import ( - "bytes" - "encoding/gob" - "encoding/hex" - "errors" - "fmt" - "runtime" - "sort" - "sync" - - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/internal/cache" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/timeutils" -) - -type HashMode int - -const ( - HashModeNeedOnlySelf HashMode = iota - HashModeNeedDirectDeps - HashModeNeedAllDeps -) - -// 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 // not used now, but may be needed for future debugging purposes - ioSem chan struct{} // semaphore limiting parallel IO -} - -func NewCache(sw *timeutils.Stopwatch, log logutils.Log) (*Cache, error) { - c, err := cache.Default() - if err != nil { - return nil, err - } - return &Cache{ - lowLevelCache: c, - sw: sw, - log: log, - ioSem: make(chan struct{}, runtime.GOMAXPROCS(-1)), - }, nil -} - -func (c *Cache) Trim() { - c.sw.TrackStage("trim", func() { - c.lowLevelCache.Trim() - }) -} - -func (c *Cache) Put(pkg *packages.Package, mode HashMode, key string, data any) error { - var err error - buf := &bytes.Buffer{} - c.sw.TrackStage("gob", func() { - err = gob.NewEncoder(buf).Encode(data) - }) - if err != nil { - return fmt.Errorf("failed to gob encode: %w", err) - } - - var aID cache.ActionID - - c.sw.TrackStage("key build", func() { - aID, err = c.pkgActionID(pkg, mode) - if err == nil { - subkey, subkeyErr := cache.Subkey(aID, key) - if subkeyErr != nil { - err = fmt.Errorf("failed to build subkey: %w", subkeyErr) - } - aID = subkey - } - }) - if err != nil { - return fmt.Errorf("failed to calculate package %s action id: %w", pkg.Name, err) - } - c.ioSem <- struct{}{} - c.sw.TrackStage("cache io", func() { - err = c.lowLevelCache.PutBytes(aID, buf.Bytes()) - }) - <-c.ioSem - 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 -} - -var ErrMissing = errors.New("missing data") - -func (c *Cache) Get(pkg *packages.Package, mode HashMode, key string, data any) error { - var aID cache.ActionID - var err error - c.sw.TrackStage("key build", func() { - aID, err = c.pkgActionID(pkg, mode) - if err == nil { - subkey, subkeyErr := cache.Subkey(aID, key) - if subkeyErr != nil { - err = fmt.Errorf("failed to build subkey: %w", subkeyErr) - } - aID = subkey - } - }) - if err != nil { - return fmt.Errorf("failed to calculate package %s action id: %w", pkg.Name, err) - } - - var b []byte - c.ioSem <- struct{}{} - c.sw.TrackStage("cache io", func() { - b, _, err = c.lowLevelCache.GetBytes(aID) - }) - <-c.ioSem - 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) - } - - c.sw.TrackStage("gob", func() { - err = gob.NewDecoder(bytes.NewReader(b)).Decode(data) - }) - if err != nil { - return fmt.Errorf("failed to gob decode: %w", err) - } - - return 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 -} - -// packageHash 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) packageHash(pkg *packages.Package, mode HashMode) (string, error) { - type hashResults map[HashMode]string - hashResI, ok := c.pkgHashes.Load(pkg) - if ok { - hashRes := hashResI.(hashResults) - if _, ok := hashRes[mode]; !ok { - return "", fmt.Errorf("no mode %d in hash result", mode) - } - return hashRes[mode], nil - } - - hashRes := hashResults{} - - key, err := cache.NewHash("package hash") - if err != nil { - return "", fmt.Errorf("failed to make a hash: %w", err) - } - - fmt.Fprintf(key, "pkgpath %s\n", pkg.PkgPath) - for _, f := range pkg.CompiledGoFiles { - c.ioSem <- struct{}{} - h, fErr := cache.FileHash(f) - <-c.ioSem - if fErr != nil { - return "", 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 := make([]*packages.Package, 0, len(pkg.Imports)) - for _, imp := range pkg.Imports { - imps = append(imps, imp) - } - sort.Slice(imps, func(i, j int) bool { - return imps[i].PkgPath < imps[j].PkgPath - }) - - calcDepsHash := func(depMode HashMode) error { - for _, dep := range imps { - if dep.PkgPath == "unsafe" { - continue - } - - depHash, depErr := c.packageHash(dep, depMode) - if depErr != nil { - return fmt.Errorf("failed to calculate hash for dependency %s with mode %d: %w", dep.Name, depMode, depErr) - } - - fmt.Fprintf(key, "import %s %s\n", dep.PkgPath, depHash) - } - return nil - } - - if err := calcDepsHash(HashModeNeedOnlySelf); err != nil { - return "", err - } - - curSum = key.Sum() - hashRes[HashModeNeedDirectDeps] = hex.EncodeToString(curSum[:]) - - if err := calcDepsHash(HashModeNeedAllDeps); err != nil { - return "", err - } - curSum = key.Sum() - hashRes[HashModeNeedAllDeps] = hex.EncodeToString(curSum[:]) - - if _, ok := hashRes[mode]; !ok { - return "", fmt.Errorf("invalid mode %d", mode) - } - - c.pkgHashes.Store(pkg, hashRes) - return hashRes[mode], nil -} diff --git a/vendor/github.com/golangci/golangci-lint/internal/renameio/readme.md b/vendor/github.com/golangci/golangci-lint/internal/renameio/readme.md deleted file mode 100644 index 36ec6ed49..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/renameio/readme.md +++ /dev/null @@ -1,10 +0,0 @@ -# renameio - -Extracted from go/src/cmd/go/internal/renameio/ -I don't know what version of Go this package was pulled from. - -Adapted for golangci-lint: -- https://github.com/golangci/golangci-lint/pull/699 -- https://github.com/golangci/golangci-lint/pull/808 -- https://github.com/golangci/golangci-lint/pull/1063 -- https://github.com/golangci/golangci-lint/pull/3204 diff --git a/vendor/github.com/golangci/golangci-lint/internal/renameio/renameio.go b/vendor/github.com/golangci/golangci-lint/internal/renameio/renameio.go deleted file mode 100644 index 2f88f4f7c..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/renameio/renameio.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 renameio writes files atomically by renaming temporary files. -package renameio - -import ( - "bytes" - "io" - "math/rand" - "os" - "path/filepath" - "strconv" - - "github.com/golangci/golangci-lint/internal/robustio" -) - -const patternSuffix = ".tmp" - -// Pattern returns a glob pattern that matches the unrenamed temporary files -// created when writing to filename. -func Pattern(filename string) string { - return filepath.Join(filepath.Dir(filename), filepath.Base(filename)+patternSuffix) -} - -// WriteFile is like os.WriteFile, but first writes data to an arbitrary -// file in the same directory as filename, then renames it atomically to the -// final name. -// -// That ensures that the final location, if it exists, is always a complete file. -func WriteFile(filename string, data []byte, perm os.FileMode) (err error) { - return WriteToFile(filename, bytes.NewReader(data), perm) -} - -// WriteToFile is a variant of WriteFile that accepts the data as an io.Reader -// instead of a slice. -func WriteToFile(filename string, data io.Reader, perm os.FileMode) (err error) { - f, err := tempFile(filepath.Dir(filename), filepath.Base(filename), perm) - if err != nil { - return err - } - defer func() { - // Only call os.Remove on f.Name() if we failed to rename it: otherwise, - // some other process may have created a new file with the same name after - // that. - if err != nil { - f.Close() - os.Remove(f.Name()) - } - }() - - if _, err := io.Copy(f, data); err != nil { - return err - } - // Sync the file before renaming it: otherwise, after a crash the reader may - // observe a 0-length file instead of the actual contents. - // See https://golang.org/issue/22397#issuecomment-380831736. - if err := f.Sync(); err != nil { - return err - } - if err := f.Close(); err != nil { - return err - } - - return robustio.Rename(f.Name(), filename) -} - -// tempFile creates a new temporary file with given permission bits. -func tempFile(dir, prefix string, perm os.FileMode) (f *os.File, err error) { - for i := 0; i < 10000; i++ { - name := filepath.Join(dir, prefix+strconv.Itoa(rand.Intn(1000000000))+patternSuffix) - f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm) - if os.IsExist(err) { - continue - } - break - } - return -} - -// ReadFile is like os.ReadFile, but on Windows retries spurious errors that -// may occur if the file is concurrently replaced. -// -// Errors are classified heuristically and retries are bounded, so even this -// function may occasionally return a spurious error on Windows. -// If so, the error will likely wrap one of: -// - syscall.ERROR_ACCESS_DENIED -// - syscall.ERROR_FILE_NOT_FOUND -// - internal/syscall/windows.ERROR_SHARING_VIOLATION -func ReadFile(filename string) ([]byte, error) { - return robustio.ReadFile(filename) -} diff --git a/vendor/github.com/golangci/golangci-lint/internal/robustio/readme.md b/vendor/github.com/golangci/golangci-lint/internal/robustio/readme.md deleted file mode 100644 index 7c7ba0483..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/robustio/readme.md +++ /dev/null @@ -1,6 +0,0 @@ -# robustio - -Extracted from go1.19.1/src/cmd/go/internal/robustio - -There is only one modification: -- ERROR_SHARING_VIOLATION extracted from go1.19.1/src/internal/syscall/windows/syscall_windows.go to remove the dependencies to `internal/syscall/windows` diff --git a/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio.go b/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio.go deleted file mode 100644 index 15b33773c..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio.go +++ /dev/null @@ -1,53 +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 robustio wraps I/O functions that are prone to failure on Windows, -// transparently retrying errors up to an arbitrary timeout. -// -// Errors are classified heuristically and retries are bounded, so the functions -// in this package do not completely eliminate spurious errors. However, they do -// significantly reduce the rate of failure in practice. -// -// If so, the error will likely wrap one of: -// The functions in this package do not completely eliminate spurious errors, -// but substantially reduce their rate of occurrence in practice. -package robustio - -// Rename is like os.Rename, but on Windows retries errors that may occur if the -// file is concurrently read or overwritten. -// -// (See golang.org/issue/31247 and golang.org/issue/32188.) -func Rename(oldpath, newpath string) error { - return rename(oldpath, newpath) -} - -// ReadFile is like os.ReadFile, but on Windows retries errors that may -// occur if the file is concurrently replaced. -// -// (See golang.org/issue/31247 and golang.org/issue/32188.) -func ReadFile(filename string) ([]byte, error) { - return readFile(filename) -} - -// RemoveAll is like os.RemoveAll, but on Windows retries errors that may occur -// if an executable file in the directory has recently been executed. -// -// (See golang.org/issue/19491.) -func RemoveAll(path string) error { - return removeAll(path) -} - -// IsEphemeralError reports whether err is one of the errors that the functions -// in this package attempt to mitigate. -// -// Errors considered ephemeral include: -// - syscall.ERROR_ACCESS_DENIED -// - syscall.ERROR_FILE_NOT_FOUND -// - internal/syscall/windows.ERROR_SHARING_VIOLATION -// -// This set may be expanded in the future; programs must not rely on the -// non-ephemerality of any given error. -func IsEphemeralError(err error) bool { - return isEphemeralError(err) -} diff --git a/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_darwin.go b/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_darwin.go deleted file mode 100644 index 99fd8ebc2..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_darwin.go +++ /dev/null @@ -1,21 +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 robustio - -import ( - "errors" - "syscall" -) - -const errFileNotFound = syscall.ENOENT - -// isEphemeralError returns true if err may be resolved by waiting. -func isEphemeralError(err error) bool { - var errno syscall.Errno - if errors.As(err, &errno) { - return errno == errFileNotFound - } - return false -} diff --git a/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_flaky.go b/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_flaky.go deleted file mode 100644 index c56e36ca6..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_flaky.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. - -//go:build windows || darwin - -package robustio - -import ( - "errors" - "math/rand" - "os" - "syscall" - "time" -) - -const arbitraryTimeout = 2000 * time.Millisecond - -// retry retries ephemeral errors from f up to an arbitrary timeout -// to work around filesystem flakiness on Windows and Darwin. -func retry(f func() (err error, mayRetry bool)) error { - var ( - bestErr error - lowestErrno syscall.Errno - start time.Time - nextSleep time.Duration = 1 * time.Millisecond - ) - for { - err, mayRetry := f() - if err == nil || !mayRetry { - return err - } - - var errno syscall.Errno - if errors.As(err, &errno) && (lowestErrno == 0 || errno < lowestErrno) { - bestErr = err - lowestErrno = errno - } else if bestErr == nil { - bestErr = err - } - - if start.IsZero() { - start = time.Now() - } else if d := time.Since(start) + nextSleep; d >= arbitraryTimeout { - break - } - time.Sleep(nextSleep) - nextSleep += time.Duration(rand.Int63n(int64(nextSleep))) - } - - return bestErr -} - -// rename is like os.Rename, but retries ephemeral errors. -// -// On Windows it wraps os.Rename, which (as of 2019-06-04) uses MoveFileEx with -// MOVEFILE_REPLACE_EXISTING. -// -// Windows also provides a different system call, ReplaceFile, -// that provides similar semantics, but perhaps preserves more metadata. (The -// documentation on the differences between the two is very sparse.) -// -// Empirical error rates with MoveFileEx are lower under modest concurrency, so -// for now we're sticking with what the os package already provides. -func rename(oldpath, newpath string) (err error) { - return retry(func() (err error, mayRetry bool) { - err = os.Rename(oldpath, newpath) - return err, isEphemeralError(err) - }) -} - -// readFile is like os.ReadFile, but retries ephemeral errors. -func readFile(filename string) ([]byte, error) { - var b []byte - err := retry(func() (err error, mayRetry bool) { - b, err = os.ReadFile(filename) - - // Unlike in rename, we do not retry errFileNotFound here: it can occur - // as a spurious error, but the file may also genuinely not exist, so the - // increase in robustness is probably not worth the extra latency. - return err, isEphemeralError(err) && !errors.Is(err, errFileNotFound) - }) - return b, err -} - -func removeAll(path string) error { - return retry(func() (err error, mayRetry bool) { - err = os.RemoveAll(path) - return err, isEphemeralError(err) - }) -} diff --git a/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_other.go b/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_other.go deleted file mode 100644 index da9a46e4f..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_other.go +++ /dev/null @@ -1,27 +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. - -//go:build !windows && !darwin - -package robustio - -import ( - "os" -) - -func rename(oldpath, newpath string) error { - return os.Rename(oldpath, newpath) -} - -func readFile(filename string) ([]byte, error) { - return os.ReadFile(filename) -} - -func removeAll(path string) error { - return os.RemoveAll(path) -} - -func isEphemeralError(err error) bool { - return false -} diff --git a/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_windows.go b/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_windows.go deleted file mode 100644 index fe1728954..000000000 --- a/vendor/github.com/golangci/golangci-lint/internal/robustio/robustio_windows.go +++ /dev/null @@ -1,30 +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 robustio - -import ( - "errors" - "syscall" -) - -const errFileNotFound = syscall.ERROR_FILE_NOT_FOUND - -// ERROR_SHARING_VIOLATION (ldez) extract from go1.19.1/src/internal/syscall/windows/syscall_windows.go. -// This is the only modification of this file. -const ERROR_SHARING_VIOLATION syscall.Errno = 32 - -// isEphemeralError returns true if err may be resolved by waiting. -func isEphemeralError(err error) bool { - var errno syscall.Errno - if errors.As(err, &errno) { - switch errno { - case syscall.ERROR_ACCESS_DENIED, - syscall.ERROR_FILE_NOT_FOUND, - ERROR_SHARING_VIOLATION: - return true - } - } - return false -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/cache.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/cache.go deleted file mode 100644 index cc6c0eacd..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/commands/cache.go +++ /dev/null @@ -1,82 +0,0 @@ -package commands - -import ( - "fmt" - "os" - "path/filepath" - - "github.com/spf13/cobra" - - "github.com/golangci/golangci-lint/internal/cache" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/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/pkg/commands/config.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/config.go deleted file mode 100644 index 935ec5e86..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/commands/config.go +++ /dev/null @@ -1,122 +0,0 @@ -package commands - -import ( - "fmt" - "os" - - "github.com/fatih/color" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/exitcodes" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/logutils" -) - -type configCommand struct { - viper *viper.Viper - cmd *cobra.Command - - opts config.LoaderOptions - verifyOpts verifyOptions - - 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: "Config file information", - 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, - } - - configCmd.AddCommand( - &cobra.Command{ - Use: "path", - Short: "Print used config path", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - Run: c.executePath, - }, - 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") - - 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.NewLoader(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) { - usedConfigFile := c.getUsedConfig() - if usedConfigFile == "" { - c.log.Warnf("No config file detected") - os.Exit(exitcodes.NoConfigFileDetected) - } - - cmd.Println(usedConfigFile) -} - -// 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/pkg/commands/config_verify.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/config_verify.go deleted file mode 100644 index 89017e9bf..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/commands/config_verify.go +++ /dev/null @@ -1,179 +0,0 @@ -package commands - -import ( - "errors" - "fmt" - "net/http" - "os" - "path/filepath" - "strings" - "time" - - hcversion "github.com/hashicorp/go-version" - "github.com/pelletier/go-toml/v2" - "github.com/santhosh-tekuri/jsonschema/v5" - "github.com/santhosh-tekuri/jsonschema/v5/httploader" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "gopkg.in/yaml.v3" - - "github.com/golangci/golangci-lint/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) - } - - detail := v.DetailedOutput() - - printValidationDetail(cmd, &detail) - - 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) - } - - schemaURL = fmt.Sprintf("https://golangci-lint.run/jsonschema/golangci.v%d.%d.jsonschema.json", - version.Segments()[0], version.Segments()[1]) - - case buildInfo.Commit != "" && buildInfo.Commit != "?": - 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 - } - - schemaURL = fmt.Sprintf("https://raw.githubusercontent.com/golangci/golangci-lint/%s/jsonschema/golangci.next.jsonschema.json", - commit) - - default: - return "", errors.New("version not found") - } - - return schemaURL, nil -} - -func validateConfiguration(schemaPath, targetFile string) error { - httploader.Client = &http.Client{Timeout: 2 * time.Second} - - compiler := jsonschema.NewCompiler() - compiler.Draft = 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.Detailed) { - if detail.Error != "" { - cmd.PrintErrf("jsonschema: %q does not validate with %q: %s\n", - strings.ReplaceAll(strings.TrimPrefix(detail.InstanceLocation, "/"), "/", "."), detail.KeywordLocation, detail.Error) - } - - 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 -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/custom.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/custom.go deleted file mode 100644 index 1bc9f9014..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/commands/internal" - "github.com/golangci/golangci-lint/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/pkg/commands/flagsets.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/flagsets.go deleted file mode 100644 index 608f6b9de..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/commands/flagsets.go +++ /dev/null @@ -1,146 +0,0 @@ -package commands - -import ( - "fmt" - "strings" - - "github.com/fatih/color" - "github.com/spf13/pflag" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/pkg/commands/internal" - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/exitcodes" - "github.com/golangci/golangci-lint/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/pkg/result/processors" -) - -const defaultMaxIssuesPerLinter = 50 - -func setupLintersFlagSet(v *viper.Viper, fs *pflag.FlagSet) { - internal.AddHackedStringSliceP(fs, "disable", "D", color.GreenString("Disable specific linter")) - internal.AddFlagAndBind(v, fs, fs.Bool, "disable-all", "linters.disable-all", false, color.GreenString("Disable all linters")) - - internal.AddHackedStringSliceP(fs, "enable", "E", color.GreenString("Enable specific linter")) - internal.AddFlagAndBind(v, fs, fs.Bool, "enable-all", "linters.enable-all", false, color.GreenString("Enable all linters")) - - internal.AddFlagAndBind(v, fs, fs.Bool, "fast", "linters.fast", false, - color.GreenString("Enable only fast linters from enabled linters set (first run won't be fast)")) - - internal.AddHackedStringSliceP(fs, "presets", "p", - color.GreenString(fmt.Sprintf("Enable presets (%s) of linters.\n"+ - "Run 'golangci-lint help linters' to see them.\n"+ - "This option implies option --disable-all", - strings.Join(lintersdb.AllPresets(), "|"), - ))) - - fs.StringSlice("enable-only", nil, - color.GreenString("Override linters configuration section to only run the specific linter(s)")) // Flags only. -} - -func setupRunFlagSet(v *viper.Viper, fs *pflag.FlagSet) { - internal.AddFlagAndBindP(v, fs, fs.IntP, "concurrency", "j", "run.concurrency", getDefaultConcurrency(), - color.GreenString("Number of CPUs to use (Default: number of logical CPUs)")) - - 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.AddFlagAndBind(v, fs, fs.String, "go", "run.go", "", color.GreenString("Targeted Go version")) - 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")) - - 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")) - internal.AddDeprecatedFlagAndBind(v, fs, fs.Bool, "skip-dirs-use-default", "run.skip-dirs-use-default", true, - getDefaultDirectoryExcludeHelp()) - - 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, "out-format", "output.formats", config.OutFormatColoredLineNumber, - color.GreenString(fmt.Sprintf("Formats of output: %s", strings.Join(config.AllOutputFormats, "|")))) - internal.AddFlagAndBind(v, fs, fs.Bool, "print-issued-lines", "output.print-issued-lines", true, - color.GreenString("Print lines of code with issue")) - internal.AddFlagAndBind(v, fs, fs.Bool, "print-linter-name", "output.print-linter-name", true, - color.GreenString("Print linter name in issue line")) - internal.AddFlagAndBind(v, fs, fs.Bool, "uniq-by-line", "output.uniq-by-line", true, - color.GreenString("Make issues output unique by line")) - internal.AddFlagAndBind(v, fs, fs.Bool, "sort-results", "output.sort-results", false, - color.GreenString("Sort linter results")) - internal.AddFlagAndBind(v, fs, fs.StringSlice, "sort-order", "output.sort-order", nil, - color.GreenString("Sort order of linter results")) - internal.AddFlagAndBind(v, fs, fs.String, "path-prefix", "output.path-prefix", "", - color.GreenString("Path prefix to add to output")) - internal.AddFlagAndBind(v, fs, fs.Bool, "show-stats", "output.show-stats", false, color.GreenString("Show statistics per linter")) -} - -//nolint:gomnd // magic numbers here is ok -func setupIssuesFlagSet(v *viper.Viper, fs *pflag.FlagSet) { - internal.AddHackedStringSliceP(fs, "exclude", "e", color.GreenString("Exclude issue by regexp")) - internal.AddFlagAndBind(v, fs, fs.Bool, "exclude-use-default", "issues.exclude-use-default", true, - getDefaultIssueExcludeHelp()) - internal.AddFlagAndBind(v, fs, fs.Bool, "exclude-case-sensitive", "issues.exclude-case-sensitive", false, - color.GreenString("If set to true exclude and exclude rules regular expressions are case-sensitive")) - - 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.AddHackedStringSlice(fs, "exclude-files", color.GreenString("Regexps of files to exclude")) - internal.AddHackedStringSlice(fs, "exclude-dirs", color.GreenString("Regexps of directories to exclude")) - internal.AddFlagAndBind(v, fs, fs.Bool, "exclude-dirs-use-default", "issues.exclude-dirs-use-default", true, - getDefaultDirectoryExcludeHelp()) - - internal.AddFlagAndBind(v, fs, fs.String, "exclude-generated", "issues.exclude-generated", processors.AutogeneratedModeLax, - color.GreenString("Mode of the generated files analysis")) - - 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.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("Fix found issues (if it's supported by the linter)")) -} - -func getDefaultIssueExcludeHelp() string { - parts := []string{color.GreenString("Use or not use default excludes:")} - - for _, ep := range config.DefaultExcludePatterns { - parts = append(parts, - fmt.Sprintf(" - %s (%s): %s", color.BlueString(ep.ID), color.CyanString(ep.Linter), ep.Why), - fmt.Sprintf(` Pattern: %s`, color.YellowString(`'`+ep.Pattern+`'`)), - ) - } - - return strings.Join(parts, "\n") -} - -func getDefaultDirectoryExcludeHelp() string { - parts := []string{color.GreenString("Use or not use default excluded directories:")} - for _, dir := range processors.StdExcludeDirRegexps { - parts = append(parts, fmt.Sprintf(" - %s", color.YellowString(dir))) - } - parts = append(parts, "") - return strings.Join(parts, "\n") -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/help.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/help.go deleted file mode 100644 index 094e5d190..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/commands/help.go +++ /dev/null @@ -1,142 +0,0 @@ -package commands - -import ( - "fmt" - "slices" - "sort" - "strings" - - "github.com/fatih/color" - "github.com/spf13/cobra" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/pkg/logutils" -) - -type helpCommand struct { - cmd *cobra.Command - - dbManager *lintersdb.Manager - - log logutils.Log -} - -func newHelpCommand(logger logutils.Log) *helpCommand { - c := &helpCommand{log: logger} - - helpCmd := &cobra.Command{ - Use: "help", - Short: "Help", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, _ []string) error { - return cmd.Help() - }, - } - - helpCmd.AddCommand( - &cobra.Command{ - Use: "linters", - Short: "Help about linters", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - Run: c.execute, - PreRunE: c.preRunE, - }, - ) - - c.cmd = helpCmd - - return c -} - -func (c *helpCommand) preRunE(_ *cobra.Command, _ []string) error { - // The command doesn't depend on the real configuration. - // It just needs the list of all plugins and all presets. - 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) execute(_ *cobra.Command, _ []string) { - var enabledLCs, disabledLCs []*linter.Config - for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() { - if lc.Internal { - continue - } - - if lc.EnabledByDefault { - 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) - - color.Green("\nLinters presets:") - c.printPresets() -} - -func (c *helpCommand) printPresets() { - for _, p := range lintersdb.AllPresets() { - linters := c.dbManager.GetAllLinterConfigsForPreset(p) - - var linterNames []string - for _, lc := range linters { - if lc.Internal { - continue - } - - linterNames = append(linterNames, lc.Name()) - } - sort.Strings(linterNames) - - _, _ = fmt.Fprintf(logutils.StdOut, "%s: %s\n", color.YellowString(p), strings.Join(linterNames, ", ")) - } -} - -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 { - // If the linter description spans multiple lines, truncate everything following the first newline - linterDescription := lc.Linter.Desc() - firstNewline := strings.IndexRune(linterDescription, '\n') - if firstNewline > 0 { - linterDescription = linterDescription[:firstNewline] - } - - deprecatedMark := "" - if lc.IsDeprecated() { - deprecatedMark = " [" + color.RedString("deprecated") + "]" - } - - _, _ = fmt.Fprintf(logutils.StdOut, "%s%s: %s [fast: %t, auto-fix: %t]\n", - color.YellowString(lc.Name()), deprecatedMark, linterDescription, !lc.IsSlowLinter(), lc.CanAutoFix) - } -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/internal/builder.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/internal/builder.go deleted file mode 100644 index f0e259fb0..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/commands/internal/builder.go +++ /dev/null @@ -1,250 +0,0 @@ -package internal - -import ( - "context" - "fmt" - "io" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" - "time" - "unicode" - - "github.com/golangci/golangci-lint/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 { - //nolint:gosec // the variable is sanitized. - cmd := exec.CommandContext(ctx, "go", "build", - "-ldflags", - fmt.Sprintf( - "-s -w -X 'main.version=%s-custom-gcl' -X 'main.date=%s'", - sanitizeVersion(b.cfg.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 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/pkg/commands/internal/configuration.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/internal/configuration.go deleted file mode 100644 index f9de4c47a..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/commands/internal/imports.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/internal/imports.go deleted file mode 100644 index 3bebf596b..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/commands/internal/vibra.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/internal/vibra.go deleted file mode 100644 index ece2483fe..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/commands/linters.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/linters.go deleted file mode 100644 index a93814f0f..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/commands/linters.go +++ /dev/null @@ -1,107 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/fatih/color" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/pkg/logutils" -) - -type lintersOptions struct { - config.LoaderOptions -} - -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) - - c.cmd = lintersCmd - - return c -} - -func (c *lintersCommand) preRunE(cmd *cobra.Command, args []string) error { - loader := config.NewLoader(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 disabledLCs []*linter.Config - - for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() { - if lc.Internal { - continue - } - - if enabledLintersMap[lc.Name()] == nil { - disabledLCs = append(disabledLCs, lc) - } else { - enabledLinters = append(enabledLinters, lc) - } - } - - color.Green("Enabled by your configuration linters:\n") - printLinters(enabledLinters) - color.Red("\nDisabled by your configuration linters:\n") - printLinters(disabledLCs) - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/root.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/root.go deleted file mode 100644 index cbb838aac..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/commands/root.go +++ /dev/null @@ -1,167 +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/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, - newRunCommand(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) - } - - 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.ParseErrorsWhitelist = pflag.ParseErrorsWhitelist{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/pkg/commands/run.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/run.go deleted file mode 100644 index f289bfdd7..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/commands/run.go +++ /dev/null @@ -1,691 +0,0 @@ -package commands - -import ( - "bytes" - "context" - "crypto/sha256" - "errors" - "fmt" - "io" - "log" - "os" - "path/filepath" - "runtime" - "runtime/pprof" - "runtime/trace" - "sort" - "strconv" - "strings" - "time" - - "github.com/fatih/color" - "github.com/gofrs/flock" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "github.com/spf13/viper" - "go.uber.org/automaxprocs/maxprocs" - "golang.org/x/exp/maps" - "gopkg.in/yaml.v3" - - "github.com/golangci/golangci-lint/internal/cache" - "github.com/golangci/golangci-lint/internal/pkgcache" - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/exitcodes" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/pkg/goutil" - "github.com/golangci/golangci-lint/pkg/lint" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/printers" - "github.com/golangci/golangci-lint/pkg/report" - "github.com/golangci/golangci-lint/pkg/result" - "github.com/golangci/golangci-lint/pkg/timeutils" -) - -const defaultTimeout = time.Minute - -const ( - // envFailOnWarnings value: "1" - envFailOnWarnings = "FAIL_ON_WARNINGS" - // envMemLogEvery value: "1" - envMemLogEvery = "GL_MEM_LOG_EVERY" -) - -const ( - // envHelpRun value: "1". - envHelpRun = "HELP_RUN" - 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: "Run the linters", - 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.NewLoader(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 { - 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 - - printer, err := printers.NewPrinter(c.log, &c.cfg.Output, c.reportData) - if err != nil { - return err - } - - c.printer = printer - - 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 := pkgcache.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, c.fileCache, pkgCache, guard) - - if err = initHashSalt(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, args []string) { - needTrackResources := logutils.IsVerbose() || c.opts.PrintResourcesUsage - - trackResourcesEndCh := make(chan struct{}) - defer func() { // XXX: this defer must be before ctx.cancel defer - if needTrackResources { // wait until resource tracking finished to print properly - <-trackResourcesEndCh - } - }() - - ctx, cancel := context.WithTimeout(context.Background(), c.cfg.Run.Timeout) - defer cancel() - - if needTrackResources { - go watchResources(ctx, trackResourcesEndCh, c.log, c.debugf) - } - - if err := c.runAndPrint(ctx, args); 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, args []string) 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, args) - 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, lc.EnabledByDefault) - } - - 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, args []string) ([]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, args, - 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) - } -} - -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 := maps.Keys(stats) - sort.Strings(keys) - - 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.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 getDefaultConcurrency() int { - if os.Getenv(envHelpRun) == "1" { - // Make stable concurrency for generating help documentation. - const prettyConcurrency = 8 - return prettyConcurrency - } - - return runtime.NumCPU() -} - -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(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) - } - - b := bytes.NewBuffer(binSalt) - b.Write(configSalt) - cache.SetSalt(b.Bytes()) - 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.LintersSettings) - 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 -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/commands/version.go b/vendor/github.com/golangci/golangci-lint/pkg/commands/version.go deleted file mode 100644 index ac665f4c5..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/commands/version.go +++ /dev/null @@ -1,102 +0,0 @@ -package commands - -import ( - "encoding/json" - "fmt" - "io" - "os" - "runtime/debug" - "strings" - - "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"` -} - -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 versionInfo struct { - Info BuildInfo - BuildInfo *debug.BuildInfo -} - -type versionOptions struct { - Format string - Debug 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: "Version", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - RunE: c.execute, - } - - fs := versionCmd.Flags() - fs.SortFlags = false // sort them as they are defined here - - fs.StringVar(&c.opts.Format, "format", "", color.GreenString("The version's format can be: 'short', 'json'")) - fs.BoolVar(&c.opts.Debug, "debug", false, color.GreenString("Add build information")) - - c.cmd = versionCmd - - return c -} - -func (c *versionCommand) execute(_ *cobra.Command, _ []string) error { - if c.opts.Debug { - info, ok := debug.ReadBuildInfo() - if !ok { - return nil - } - - switch strings.ToLower(c.opts.Format) { - case "json": - return json.NewEncoder(os.Stdout).Encode(versionInfo{ - Info: c.info, - BuildInfo: info, - }) - - default: - fmt.Println(info.String()) - return printVersion(os.Stdout, c.info) - } - } - - switch strings.ToLower(c.opts.Format) { - case "short": - fmt.Println(c.info.Version) - return nil - - case "json": - return json.NewEncoder(os.Stdout).Encode(c.info) - - default: - 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/pkg/config/config.go b/vendor/github.com/golangci/golangci-lint/pkg/config/config.go deleted file mode 100644 index 93b331bec..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/config/config.go +++ /dev/null @@ -1,90 +0,0 @@ -package config - -import ( - "os" - "strings" - - hcversion "github.com/hashicorp/go-version" - "github.com/ldez/gomoddirectives" -) - -// Config encapsulates the config data specified in the golangci-lint YAML config file. -type Config struct { - cfgDir string // The directory containing the golangci-lint 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"` - - 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 config file. -func (c *Config) GetConfigDir() string { - return c.cfgDir -} - -func (c *Config) Validate() error { - validators := []func() error{ - c.Run.Validate, - c.Output.Validate, - c.LintersSettings.Validate, - c.Linters.Validate, - c.Issues.Validate, - c.Severity.Validate, - } - - for _, v := range validators { - if err := v(); err != nil { - return err - } - } - - return nil -} - -func NewDefault() *Config { - return &Config{ - LintersSettings: defaultLintersSettings, - } -} - -type Version struct { - Format string `mapstructure:"format"` - Debug bool `mapstructure:"debug"` -} - -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() string { - file, _ := gomoddirectives.GetModuleFile() - - if file != nil && file.Go != nil && file.Go.Version != "" { - return file.Go.Version - } - - v := os.Getenv("GOVERSION") - if v != "" { - return v - } - - return "1.17" -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/issues.go b/vendor/github.com/golangci/golangci-lint/pkg/config/issues.go deleted file mode 100644 index 2ee9364aa..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/config/issues.go +++ /dev/null @@ -1,246 +0,0 @@ -package config - -import ( - "errors" - "fmt" - "regexp" -) - -const excludeRuleMinConditionsCount = 2 - -var DefaultExcludePatterns = []ExcludePattern{ - { - ID: "EXC0001", - Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close" + - "|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked", - Linter: "errcheck", - Why: "Almost all programs ignore errors on these functions and in most cases it's ok.", - }, - { - ID: "EXC0002", // TODO(ldez): should be remove in v2 - Pattern: "(comment on exported (method|function|type|const)|" + - "should have( a package)? comment|comment should be of the form)", - Linter: "golint", - Why: "Annoying issue about not having a comment. The rare codebase has such comments.", - }, - { - ID: "EXC0003", // TODO(ldez): should be remove in v2 - Pattern: "func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this", - Linter: "golint", - Why: "False positive when tests are defined in package 'test'.", - }, - { - ID: "EXC0004", - Pattern: "(possible misuse of unsafe.Pointer|should have signature)", - Linter: "govet", - Why: "Common false positives.", - }, - { - ID: "EXC0005", - Pattern: "SA4011", // CheckScopedBreak - Linter: "staticcheck", - Why: "Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore.", - }, - { - ID: "EXC0006", - Pattern: "G103: Use of unsafe calls should be audited", - Linter: "gosec", - Why: "Too many false-positives on 'unsafe' usage.", - }, - { - ID: "EXC0007", - Pattern: "G204: Subprocess launched with variable", - Linter: "gosec", - Why: "Too many false-positives for parametrized shell calls.", - }, - { - ID: "EXC0008", - Pattern: "G104", // Errors unhandled. - Linter: "gosec", - Why: "Duplicated errcheck checks.", - }, - { - ID: "EXC0009", - Pattern: "(G301|G302|G307): Expect (directory permissions to be 0750|file permissions to be 0600) or less", - Linter: "gosec", - Why: "Too many issues in popular repos.", - }, - { - ID: "EXC0010", - Pattern: "G304: Potential file inclusion via variable", - Linter: "gosec", - Why: "False positive is triggered by 'src, err := ioutil.ReadFile(filename)'.", - }, - { - ID: "EXC0011", - Pattern: "(ST1000|ST1020|ST1021|ST1022)", // CheckPackageComment, CheckExportedFunctionDocs, CheckExportedTypeDocs, CheckExportedVarDocs - Linter: "stylecheck", - Why: "Annoying issue about not having a comment. The rare codebase has such comments.", - }, - { - ID: "EXC0012", - Pattern: `exported (.+) should have comment( \(or a comment on this block\))? or be unexported`, // rule: exported - Linter: "revive", - Why: "Annoying issue about not having a comment. The rare codebase has such comments.", - }, - { - ID: "EXC0013", - Pattern: `package comment should be of the form "(.+)..."`, // rule: package-comments - Linter: "revive", - Why: "Annoying issue about not having a comment. The rare codebase has such comments.", - }, - { - ID: "EXC0014", - Pattern: `comment on exported (.+) should be of the form "(.+)..."`, // rule: exported - Linter: "revive", - Why: "Annoying issue about not having a comment. The rare codebase has such comments.", - }, - { - ID: "EXC0015", - Pattern: `should have a package comment`, // rule: package-comments - Linter: "revive", - Why: "Annoying issue about not having a comment. The rare codebase has such comments.", - }, -} - -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"` - - DiffFromRevision string `mapstructure:"new-from-rev"` - DiffPatchFilePath string `mapstructure:"new-from-patch"` - WholeFiles bool `mapstructure:"whole-files"` - Diff bool `mapstructure:"new"` - - NeedFix bool `mapstructure:"fix"` - - ExcludeGeneratedStrict bool `mapstructure:"exclude-generated-strict"` // Deprecated: use ExcludeGenerated instead. -} - -func (i *Issues) Validate() error { - for i, rule := range i.ExcludeRules { - if err := rule.Validate(); err != nil { - return fmt.Errorf("error in exclude rule #%d: %w", i, err) - } - } - - return nil -} - -type ExcludeRule struct { - BaseRule `mapstructure:",squash"` -} - -func (e *ExcludeRule) Validate() error { - return e.BaseRule.Validate(excludeRuleMinConditionsCount) -} - -type BaseRule struct { - Linters []string - Path string - PathExcept string `mapstructure:"path-except"` - Text string - Source string -} - -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 -} - -type ExcludePattern struct { - ID string - Pattern string - Linter string - Why string -} - -func GetDefaultExcludePatternsStrings() []string { - ret := make([]string, len(DefaultExcludePatterns)) - for i, p := range DefaultExcludePatterns { - ret[i] = p.Pattern - } - return ret -} - -// TODO(ldez): this behavior must be changed in v2, because this is confusing. -func GetExcludePatterns(include []string) []ExcludePattern { - includeMap := make(map[string]struct{}, len(include)) - for _, inc := range include { - includeMap[inc] = struct{}{} - } - - var ret []ExcludePattern - for _, p := range DefaultExcludePatterns { - if _, ok := includeMap[p.ID]; !ok { - ret = append(ret, p) - } - } - - return ret -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/linters.go b/vendor/github.com/golangci/golangci-lint/pkg/config/linters.go deleted file mode 100644 index 5c2628272..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/config/linters.go +++ /dev/null @@ -1,65 +0,0 @@ -package config - -import ( - "errors" - "fmt" -) - -type Linters struct { - Enable []string - Disable []string - EnableAll bool `mapstructure:"enable-all"` - DisableAll bool `mapstructure:"disable-all"` - Fast bool - - Presets []string -} - -func (l *Linters) Validate() error { - if err := l.validateAllDisableEnableOptions(); err != nil { - return err - } - - if err := l.validateDisabledAndEnabledAtOneMoment(); err != nil { - return err - } - - return nil -} - -func (l *Linters) validateAllDisableEnableOptions() error { - if l.EnableAll && l.DisableAll { - return errors.New("--enable-all and --disable-all options must not be combined") - } - - if l.DisableAll { - if len(l.Enable) == 0 && len(l.Presets) == 0 { - return errors.New("all linters were disabled, but no one linter was enabled: must enable at least one") - } - - if len(l.Disable) != 0 { - return errors.New("can't combine options --disable-all and --disable") - } - } - - if l.EnableAll && len(l.Enable) != 0 && !l.Fast { - return errors.New("can't combine options --enable-all and --enable") - } - - return nil -} - -func (l *Linters) validateDisabledAndEnabledAtOneMoment() error { - enabledLintersSet := map[string]bool{} - for _, name := range l.Enable { - enabledLintersSet[name] = true - } - - for _, name := range l.Disable { - if enabledLintersSet[name] { - return fmt.Errorf("linter %q can't be disabled and enabled at one moment", name) - } - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/linters_settings.go b/vendor/github.com/golangci/golangci-lint/pkg/config/linters_settings.go deleted file mode 100644 index 109de4243..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/config/linters_settings.go +++ /dev/null @@ -1,1034 +0,0 @@ -package config - -import ( - "encoding" - "errors" - "fmt" - "runtime" - - "gopkg.in/yaml.v3" -) - -var defaultLintersSettings = LintersSettings{ - 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, - }, - ErrorLint: ErrorLintSettings{ - Errorf: true, - ErrorfMulti: true, - Asserts: true, - Comparison: true, - }, - Exhaustive: ExhaustiveSettings{ - Check: []string{"switch"}, - CheckGenerated: false, - DefaultSignifiesExhaustive: false, - IgnoreEnumMembers: "", - PackageScopeOnly: false, - ExplicitExhaustiveMap: false, - ExplicitExhaustiveSwitch: false, - }, - Forbidigo: ForbidigoSettings{ - ExcludeGodocExamples: true, - }, - Gci: GciSettings{ - Sections: []string{"standard", "default"}, - SkipGenerated: 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, - }, - Gofmt: GoFmtSettings{ - Simplify: true, - }, - Gofumpt: GofumptSettings{ - LangVersion: "", - ModulePath: "", - ExtraRules: false, - }, - Gosec: GoSecSettings{ - Concurrency: runtime.NumCPU(), - }, - Gosmopolitan: GosmopolitanSettings{ - AllowTimeLocal: false, - EscapeHatches: []string{}, - IgnoreTests: true, - 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, - 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{ - IntConversion: true, - ErrError: false, - ErrorF: true, - SprintF1: true, - StrConcat: true, - }, - Prealloc: PreallocSettings{ - Simple: true, - RangeLoops: true, - ForLoops: false, - }, - Predeclared: PredeclaredSettings{ - Ignore: "", - 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"}, - }, - Unparam: UnparamSettings{ - Algo: "cha", - }, - Unused: UnusedSettings{ - FieldWritesAreUses: true, - PostStatementsAreReads: false, - ExportedIsUsed: true, - ExportedFieldsAreUsed: true, - ParametersAreUsed: true, - LocalVariablesAreUsed: true, - GeneratedIsUsed: true, - }, - UseStdlibVars: UseStdlibVarsSettings{ - HTTPMethod: true, - HTTPStatusCode: true, - }, - Varnamelen: VarnamelenSettings{ - MaxDistance: 5, - MinNameLength: 3, - }, - WSL: WSLSettings{ - StrictAppend: true, - AllowAssignAndCallCuddle: true, - AllowAssignAndAnythingCuddle: false, - AllowMultiLineAssignCuddle: true, - ForceCaseTrailingWhitespaceLimit: 0, - AllowTrailingComment: false, - AllowSeparatedLeadingComment: false, - AllowCuddleDeclaration: false, - AllowCuddleWithCalls: []string{"Lock", "RLock"}, - AllowCuddleWithRHS: []string{"Unlock", "RUnlock"}, - ForceCuddleErrCheckAndAssign: false, - ErrorVariableNames: []string{"err"}, - ForceExclusiveShortDeclarations: false, - }, -} - -type LintersSettings struct { - Asasalint AsasalintSettings - BiDiChk BiDiChkSettings - CopyLoopVar CopyLoopVarSettings - Cyclop Cyclop - Decorder DecorderSettings - Depguard DepGuardSettings - Dogsled DogsledSettings - Dupl DuplSettings - DupWord DupWordSettings - Errcheck ErrcheckSettings - ErrChkJSON ErrChkJSONSettings - ErrorLint ErrorLintSettings - Exhaustive ExhaustiveSettings - Exhaustruct ExhaustructSettings - Forbidigo ForbidigoSettings - Funlen FunlenSettings - Gci GciSettings - GinkgoLinter GinkgoLinterSettings - Gocognit GocognitSettings - Goconst GoConstSettings - Gocritic GoCriticSettings - Gocyclo GoCycloSettings - Godot GodotSettings - Godox GodoxSettings - Gofmt GoFmtSettings - Gofumpt GofumptSettings - Goheader GoHeaderSettings - Goimports GoImportsSettings - Gomnd GoMndSettings - GoModDirectives GoModDirectivesSettings - Gomodguard GoModGuardSettings - Gosec GoSecSettings - Gosimple StaticCheckSettings - Gosmopolitan GosmopolitanSettings - Govet GovetSettings - Grouper GrouperSettings - ImportAs ImportAsSettings - Inamedparam INamedParamSettings - InterfaceBloat InterfaceBloatSettings - Ireturn IreturnSettings - Lll LllSettings - LoggerCheck LoggerCheckSettings - MaintIdx MaintIdxSettings - Makezero MakezeroSettings - Misspell MisspellSettings - Mnd MndSettings - MustTag MustTagSettings - Nakedret NakedretSettings - Nestif NestifSettings - NilNil NilNilSettings - Nlreturn NlreturnSettings - NoLintLint NoLintLintSettings - NoNamedReturns NoNamedReturnsSettings - ParallelTest ParallelTestSettings - PerfSprint PerfSprintSettings - Prealloc PreallocSettings - Predeclared PredeclaredSettings - Promlinter PromlinterSettings - ProtoGetter ProtoGetterSettings - Reassign ReassignSettings - Revive ReviveSettings - RowsErrCheck RowsErrCheckSettings - SlogLint SlogLintSettings - Spancheck SpancheckSettings - Staticcheck StaticCheckSettings - Stylecheck StaticCheckSettings - TagAlign TagAlignSettings - Tagliatelle TagliatelleSettings - Tenv TenvSettings - Testifylint TestifylintSettings - Testpackage TestpackageSettings - Thelper ThelperSettings - Unconvert UnconvertSettings - Unparam UnparamSettings - Unused UnusedSettings - UseStdlibVars UseStdlibVarsSettings - Varnamelen VarnamelenSettings - Whitespace WhitespaceSettings - Wrapcheck WrapcheckSettings - WSL WSLSettings - - Custom map[string]CustomLinterSettings -} - -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"` - 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 { - IgnoreAlias bool `mapstructure:"ignore-alias"` // Deprecated: use CheckAlias - CheckAlias bool `mapstructure:"check-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 -} - -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 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 = 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 p.patternString != "" { - return []byte(p.patternString), nil - } - - return yaml.Marshal(p) -} - -type FunlenSettings struct { - Lines int - Statements int - IgnoreComments bool `mapstructure:"ignore-comments"` -} - -type GciSettings struct { - Sections []string `mapstructure:"sections"` - 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 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"` -} - -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 -} - -type GoFmtSettings struct { - Simplify bool - RewriteRules []GoFmtRewriteRule `mapstructure:"rewrite-rules"` -} - -type GoFmtRewriteRule struct { - Pattern string - Replacement string -} - -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 GoHeaderSettings struct { - Values map[string]map[string]string `mapstructure:"values"` - Template string `mapstructure:"template"` - TemplatePath string `mapstructure:"template-path"` -} - -type GoImportsSettings struct { - LocalPrefixes string `mapstructure:"local-prefixes"` -} - -// Deprecated: use MndSettings. -type GoMndSettings struct { - MndSettings `mapstructure:",squash"` - - // Deprecated: use root level settings instead. - Settings map[string]map[string]any -} - -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"` -} - -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 - Disable []string - EnableAll bool `mapstructure:"enable-all"` - DisableAll bool `mapstructure:"disable-all"` - - Settings map[string]map[string]any - - // Deprecated: the linter should be enabled inside Enable. - CheckShadowing bool `mapstructure:"check-shadowing"` -} - -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 ImportAsSettings struct { - Alias []ImportAsAlias - NoUnaliased bool `mapstructure:"no-unaliased"` - NoExtraAliases bool `mapstructure:"no-extra-aliases"` -} - -type ImportAsAlias struct { - Pkg string - Alias string -} - -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"` - 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 -} - -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 { - 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 { - IntConversion bool `mapstructure:"int-conversion"` - ErrError bool `mapstructure:"err-error"` - ErrorF bool `mapstructure:"errorf"` - SprintF1 bool `mapstructure:"sprintf1"` - StrConcat bool `mapstructure:"strconcat"` -} - -type PreallocSettings struct { - Simple bool - 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 ReviveSettings struct { - Go string `mapstructure:"-"` - MaxOpenFiles int `mapstructure:"max-open-files"` - IgnoreGeneratedHeader bool `mapstructure:"ignore-generated-header"` - Confidence float64 - Severity string - EnableAllRules bool `mapstructure:"enable-all-rules"` - Rules []struct { - Name string - Arguments []any - Severity string - Disabled bool - Exclude []string - } - ErrorCode int `mapstructure:"error-code"` - WarningCode int `mapstructure:"warning-code"` - Directives []struct { - Name string - Severity string - } -} - -type RowsErrCheckSettings struct { - Packages []string -} - -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"` - - // Deprecated: use Context instead. - ContextOnly bool `mapstructure:"context-only"` -} - -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 - - // Deprecated: use the global `run.go` instead. - GoVersion string `mapstructure:"go"` -} - -func (s *StaticCheckSettings) HasConfiguration() bool { - return len(s.Initialisms) > 0 || len(s.HTTPStatusCodeWhitelist) > 0 || len(s.DotImportWhitelist) > 0 || len(s.Checks) > 0 -} - -type TagAlignSettings struct { - Align bool `mapstructure:"align"` - Sort bool `mapstructure:"sort"` - Order []string `mapstructure:"order"` - Strict bool `mapstructure:"strict"` -} - -type TagliatelleSettings struct { - Case struct { - Rules map[string]string - UseFieldName bool `mapstructure:"use-field-name"` - } -} - -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"` - OSDevNull bool `mapstructure:"os-dev-null"` // Deprecated - SQLIsolationLevel bool `mapstructure:"sql-isolation-level"` - TLSSignatureScheme bool `mapstructure:"tls-signature-scheme"` - ConstantKind bool `mapstructure:"constant-kind"` - SyslogPriority bool `mapstructure:"syslog-priority"` // Deprecated -} - -type UnconvertSettings struct { - FastMath bool `mapstructure:"fast-math"` - Safe bool `mapstructure:"safe"` -} - -type UnparamSettings struct { - CheckExported bool `mapstructure:"check-exported"` - Algo string -} - -type UnusedSettings struct { - FieldWritesAreUses bool `mapstructure:"field-writes-are-uses"` - PostStatementsAreReads bool `mapstructure:"post-statements-are-reads"` - ExportedIsUsed bool `mapstructure:"exported-is-used"` // Deprecated - 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 { - // 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 - - // Description describes the purpose of the private linter. - Description string - // 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 -} - -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/pkg/config/loader.go b/vendor/github.com/golangci/golangci-lint/pkg/config/loader.go deleted file mode 100644 index efdbfce1f..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/config/loader.go +++ /dev/null @@ -1,496 +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/pflag" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/pkg/exitcodes" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/goutil" - "github.com/golangci/golangci-lint/pkg/logutils" -) - -var errConfigDisabled = errors.New("config is disabled by --no-config") - -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 { - opts LoaderOptions - - viper *viper.Viper - fs *pflag.FlagSet - - log logutils.Log - - cfg *Config - args []string -} - -func NewLoader(log logutils.Log, v *viper.Viper, fs *pflag.FlagSet, opts LoaderOptions, cfg *Config, args []string) *Loader { - return &Loader{ - opts: opts, - viper: v, - fs: fs, - log: log, - cfg: cfg, - args: args, - } -} - -func (l *Loader) Load(opts LoadOptions) error { - err := l.setConfigFile() - if err != nil { - return err - } - - err = l.parseConfig() - if err != nil { - return err - } - - l.applyStringSliceHack() - - if opts.CheckDeprecation { - err = l.handleDeprecation() - if err != nil { - return err - } - } - - l.handleGoVersion() - - err = goutil.CheckGoVersion(l.cfg.Run.Go) - if err != nil { - return err - } - - err = l.handleEnableOnlyOption() - if err != nil { - return err - } - - if opts.Validation { - err = l.cfg.Validate() - if err != nil { - return err - } - } - - return nil -} - -func (l *Loader) 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 *Loader) 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 *Loader) 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 *Loader) 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 *Loader) 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.InternalTest { // just for testing purposes: to detect config file usage - _, _ = fmt.Fprintln(logutils.StdOut, "test") - os.Exit(exitcodes.Success) - } - - return nil -} - -func (l *Loader) 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.cfgDir = usedConfigDir - - 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("presets", &l.cfg.Linters.Presets) - l.appendStringSlice("build-tags", &l.cfg.Run.BuildTags) - l.appendStringSlice("exclude", &l.cfg.Issues.ExcludePatterns) - - l.appendStringSlice("skip-dirs", &l.cfg.Run.SkipDirs) - l.appendStringSlice("skip-files", &l.cfg.Run.SkipFiles) - l.appendStringSlice("exclude-dirs", &l.cfg.Issues.ExcludeDirs) - l.appendStringSlice("exclude-files", &l.cfg.Issues.ExcludeFiles) -} - -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) handleGoVersion() { - if l.cfg.Run.Go == "" { - l.cfg.Run.Go = detectGoVersion() - } - - l.cfg.LintersSettings.Govet.Go = l.cfg.Run.Go - - l.cfg.LintersSettings.ParallelTest.Go = l.cfg.Run.Go - - if l.cfg.LintersSettings.Gofumpt.LangVersion == "" { - l.cfg.LintersSettings.Gofumpt.LangVersion = l.cfg.Run.Go - } - - trimmedGoVersion := goutil.TrimGoVersion(l.cfg.Run.Go) - - l.cfg.LintersSettings.Revive.Go = trimmedGoVersion - - l.cfg.LintersSettings.Gocritic.Go = trimmedGoVersion - - // staticcheck related linters. - if l.cfg.LintersSettings.Staticcheck.GoVersion == "" { - l.cfg.LintersSettings.Staticcheck.GoVersion = trimmedGoVersion - } - if l.cfg.LintersSettings.Gosimple.GoVersion == "" { - l.cfg.LintersSettings.Gosimple.GoVersion = trimmedGoVersion - } - if l.cfg.LintersSettings.Stylecheck.GoVersion == "" { - l.cfg.LintersSettings.Stylecheck.GoVersion = 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 - } - - // Deprecated since v1.57.0 - if len(l.cfg.Run.SkipFiles) > 0 { - l.log.Warnf("The configuration option `run.skip-files` is deprecated, please use `issues.exclude-files`.") - l.cfg.Issues.ExcludeFiles = l.cfg.Run.SkipFiles - } - - // Deprecated since v1.57.0 - if len(l.cfg.Run.SkipDirs) > 0 { - l.log.Warnf("The configuration option `run.skip-dirs` is deprecated, please use `issues.exclude-dirs`.") - l.cfg.Issues.ExcludeDirs = l.cfg.Run.SkipDirs - } - - // The 2 options are true by default. - // Deprecated since v1.57.0 - if !l.cfg.Run.UseDefaultSkipDirs { - l.log.Warnf("The configuration option `run.skip-dirs-use-default` is deprecated, please use `issues.exclude-dirs-use-default`.") - } - l.cfg.Issues.UseDefaultExcludeDirs = l.cfg.Run.UseDefaultSkipDirs && l.cfg.Issues.UseDefaultExcludeDirs - - // The 2 options are false by default. - // Deprecated since v1.57.0 - if l.cfg.Run.ShowStats { - l.log.Warnf("The configuration option `run.show-stats` is deprecated, please use `output.show-stats`") - } - l.cfg.Output.ShowStats = l.cfg.Run.ShowStats || l.cfg.Output.ShowStats - - // Deprecated since v1.57.0 - if l.cfg.Output.Format != "" { - l.log.Warnf("The configuration option `output.format` is deprecated, please use `output.formats`") - - var f OutputFormats - err := f.UnmarshalText([]byte(l.cfg.Output.Format)) - if err != nil { - return fmt.Errorf("unmarshal output format: %w", err) - } - - l.cfg.Output.Formats = f - } - - for _, format := range l.cfg.Output.Formats { - if format.Format == OutFormatGithubActions { - l.log.Warnf("The output format `%s` is deprecated, please use `%s`", OutFormatGithubActions, OutFormatColoredLineNumber) - break // To avoid repeating the message if there are several usages of github-actions format. - } - } - - // Deprecated since v1.59.0 - if l.cfg.Issues.ExcludeGeneratedStrict { - l.log.Warnf("The configuration option `issues.exclude-generated-strict` is deprecated, please use `issues.exclude-generated`") - l.cfg.Issues.ExcludeGenerated = "strict" // Don't use the constants to avoid cyclic dependencies. - } - - l.handleLinterOptionDeprecations() - - return nil -} - -//nolint:gocyclo // the complexity cannot be reduced. -func (l *Loader) handleLinterOptionDeprecations() { - // Deprecated since v1.57.0, - // but it was unofficially deprecated since v1.19 (2019) (https://github.com/golangci/golangci-lint/pull/697). - if l.cfg.LintersSettings.Govet.CheckShadowing { - l.log.Warnf("The configuration option `linters.govet.check-shadowing` is deprecated. " + - "Please enable `shadow` instead, if you are not using `enable-all`.") - } - - if l.cfg.LintersSettings.CopyLoopVar.IgnoreAlias { - l.log.Warnf("The configuration option `linters.copyloopvar.ignore-alias` is deprecated and ignored," + - "please use `linters.copyloopvar.check-alias`.") - } - - // Deprecated since v1.42.0. - if l.cfg.LintersSettings.Errcheck.Exclude != "" { - l.log.Warnf("The configuration option `linters.errcheck.exclude` is deprecated, please use `linters.errcheck.exclude-functions`.") - } - - // Deprecated since v1.59.0, - // but it was unofficially deprecated since v1.13 (2018) (https://github.com/golangci/golangci-lint/pull/332). - if l.cfg.LintersSettings.Errcheck.Ignore != "" { - l.log.Warnf("The configuration option `linters.errcheck.ignore` is deprecated, please use `linters.errcheck.exclude-functions`.") - } - - // Deprecated since v1.44.0. - if l.cfg.LintersSettings.Gci.LocalPrefixes != "" { - l.log.Warnf("The configuration option `linters.gci.local-prefixes` is deprecated, please use `prefix()` inside `linters.gci.sections`.") - } - - // Deprecated since v1.33.0. - if l.cfg.LintersSettings.Godot.CheckAll { - l.log.Warnf("The configuration option `linters.godot.check-all` is deprecated, please use `linters.godot.scope: all`.") - } - - // Deprecated since v1.44.0. - if len(l.cfg.LintersSettings.Gomnd.Settings) > 0 { - l.log.Warnf("The configuration option `linters.gomnd.settings` is deprecated. Please use the options " + - "`linters.gomnd.checks`,`linters.gomnd.ignored-numbers`,`linters.gomnd.ignored-files`,`linters.gomnd.ignored-functions`.") - } - - // Deprecated since v1.47.0 - if l.cfg.LintersSettings.Gofumpt.LangVersion != "" { - l.log.Warnf("The configuration option `linters.gofumpt.lang-version` is deprecated, please use global `run.go`.") - } - - // Deprecated since v1.47.0 - if l.cfg.LintersSettings.Staticcheck.GoVersion != "" { - l.log.Warnf("The configuration option `linters.staticcheck.go` is deprecated, please use global `run.go`.") - } - - // Deprecated since v1.47.0 - if l.cfg.LintersSettings.Gosimple.GoVersion != "" { - l.log.Warnf("The configuration option `linters.gosimple.go` is deprecated, please use global `run.go`.") - } - - // Deprecated since v1.47.0 - if l.cfg.LintersSettings.Stylecheck.GoVersion != "" { - l.log.Warnf("The configuration option `linters.stylecheck.go` is deprecated, please use global `run.go`.") - } - - // Deprecated since v1.60.0 - if !l.cfg.LintersSettings.Unused.ExportedIsUsed { - l.log.Warnf("The configuration option `linters.unused.exported-is-used` is deprecated.") - } - - // Deprecated since v1.58.0 - if l.cfg.LintersSettings.SlogLint.ContextOnly { - l.log.Warnf("The configuration option `linters.sloglint.context-only` is deprecated, please use `linters.sloglint.context`.") - if l.cfg.LintersSettings.SlogLint.Context == "" { - l.cfg.LintersSettings.SlogLint.Context = "all" - } - } - - // Deprecated since v1.51.0 - if l.cfg.LintersSettings.UseStdlibVars.OSDevNull { - l.log.Warnf("The configuration option `linters.usestdlibvars.os-dev-null` is deprecated.") - } - - // Deprecated since v1.51.0 - if l.cfg.LintersSettings.UseStdlibVars.SyslogPriority { - l.log.Warnf("The configuration option `linters.usestdlibvars.syslog-priority` is deprecated.") - } -} - -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{ - Enable: only, - DisableAll: true, - } - } - - return nil -} - -func customDecoderHook() viper.DecoderConfigOption { - return viper.DecodeHook(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/pkg/config/output.go b/vendor/github.com/golangci/golangci-lint/pkg/config/output.go deleted file mode 100644 index 6a26d5773..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/config/output.go +++ /dev/null @@ -1,117 +0,0 @@ -package config - -import ( - "errors" - "fmt" - "slices" - "strings" -) - -const ( - OutFormatJSON = "json" - OutFormatLineNumber = "line-number" - OutFormatColoredLineNumber = "colored-line-number" - OutFormatTab = "tab" - OutFormatColoredTab = "colored-tab" - OutFormatCheckstyle = "checkstyle" - OutFormatCodeClimate = "code-climate" - OutFormatHTML = "html" - OutFormatJunitXML = "junit-xml" - OutFormatJunitXMLExtended = "junit-xml-extended" - OutFormatGithubActions = "github-actions" // Deprecated - OutFormatTeamCity = "teamcity" - OutFormatSarif = "sarif" -) - -var AllOutputFormats = []string{ - OutFormatJSON, - OutFormatLineNumber, - OutFormatColoredLineNumber, - OutFormatTab, - OutFormatColoredTab, - OutFormatCheckstyle, - OutFormatCodeClimate, - OutFormatHTML, - OutFormatJunitXML, - OutFormatJunitXMLExtended, - OutFormatGithubActions, - OutFormatTeamCity, - OutFormatSarif, -} - -type Output struct { - Formats OutputFormats `mapstructure:"formats"` - PrintIssuedLine bool `mapstructure:"print-issued-lines"` - PrintLinterName bool `mapstructure:"print-linter-name"` - UniqByLine bool `mapstructure:"uniq-by-line"` - SortResults bool `mapstructure:"sort-results"` - SortOrder []string `mapstructure:"sort-order"` - PathPrefix string `mapstructure:"path-prefix"` - ShowStats bool `mapstructure:"show-stats"` - - // Deprecated: use Formats instead. - Format string `mapstructure:"format"` -} - -func (o *Output) Validate() error { - if !o.SortResults && len(o.SortOrder) > 0 { - return errors.New("sort-results should be 'true' to use sort-order") - } - - 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) - } - } - - for _, format := range o.Formats { - err := format.Validate() - if err != nil { - return err - } - } - - return nil -} - -type OutputFormat struct { - Format string `mapstructure:"format"` - Path string `mapstructure:"path"` -} - -func (o *OutputFormat) Validate() error { - if o.Format == "" { - return errors.New("the format is required") - } - - if !slices.Contains(AllOutputFormats, o.Format) { - return fmt.Errorf("unsupported output format %q", o.Format) - } - - return nil -} - -type OutputFormats []OutputFormat - -func (p *OutputFormats) UnmarshalText(text []byte) error { - formats := strings.Split(string(text), ",") - - for _, item := range formats { - format, path, _ := strings.Cut(item, ":") - - *p = append(*p, OutputFormat{ - Path: path, - Format: format, - }) - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/run.go b/vendor/github.com/golangci/golangci-lint/pkg/config/run.go deleted file mode 100644 index 2f6523c0b..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/config/run.go +++ /dev/null @@ -1,47 +0,0 @@ -package config - -import ( - "fmt" - "slices" - "strings" - "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"` - - 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"` - - // Deprecated: use Issues.ExcludeFiles instead. - SkipFiles []string `mapstructure:"skip-files"` - // Deprecated: use Issues.ExcludeDirs instead. - SkipDirs []string `mapstructure:"skip-dirs"` - // Deprecated: use Issues.UseDefaultExcludeDirs instead. - UseDefaultSkipDirs bool `mapstructure:"skip-dirs-use-default"` - - // Deprecated: use Output.ShowStats instead. - ShowStats bool `mapstructure:"show-stats"` -} - -func (r *Run) Validate() error { - // go help modules - allowedMods := []string{"mod", "readonly", "vendor"} - - if r.ModulesDownloadMode != "" && !slices.Contains(allowedMods, r.ModulesDownloadMode) { - return fmt.Errorf("invalid modules download path %s, only (%s) allowed", r.ModulesDownloadMode, strings.Join(allowedMods, "|")) - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/config/severity.go b/vendor/github.com/golangci/golangci-lint/pkg/config/severity.go deleted file mode 100644 index a6d2c9ec3..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/config/severity.go +++ /dev/null @@ -1,41 +0,0 @@ -package config - -import ( - "errors" - "fmt" -) - -const severityRuleMinConditionsCount = 1 - -type Severity struct { - Default string `mapstructure:"default-severity"` - CaseSensitive bool `mapstructure:"case-sensitive"` - 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 -} - -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/pkg/exitcodes/exitcodes.go b/vendor/github.com/golangci/golangci-lint/pkg/exitcodes/exitcodes.go deleted file mode 100644 index 83331dbe7..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/fsutils/filecache.go b/vendor/github.com/golangci/golangci-lint/pkg/fsutils/filecache.go deleted file mode 100644 index e8e5ba19b..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/filecache.go +++ /dev/null @@ -1,65 +0,0 @@ -package fsutils - -import ( - "fmt" - "os" - "sync" - - "github.com/golangci/golangci-lint/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/pkg/fsutils/files.go b/vendor/github.com/golangci/golangci-lint/pkg/fsutils/files.go deleted file mode 100644 index 4398ab9fc..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/files.go +++ /dev/null @@ -1,33 +0,0 @@ -package fsutils - -import "path/filepath" - -// Files combines different operations related to handling file paths and content. -type Files struct { - *LineCache - pathPrefix string -} - -func NewFiles(lc *LineCache, pathPrefix string) *Files { - return &Files{ - LineCache: lc, - pathPrefix: pathPrefix, - } -} - -// WithPathPrefix takes a path that is relative to the current directory (as used in issues) -// and adds the configured path prefix, if there is one. -// The resulting path then can be shown to the user or compared against paths specified in the configuration. -func (f *Files) WithPathPrefix(relativePath string) string { - return WithPathPrefix(f.pathPrefix, relativePath) -} - -// WithPathPrefix takes a path that is relative to the current directory (as used in issues) -// and adds the configured path prefix, if there is one. -// The resulting path then can be shown to the user or compared against paths specified in the configuration. -func WithPathPrefix(pathPrefix, relativePath string) string { - if pathPrefix == "" { - return relativePath - } - return filepath.Join(pathPrefix, relativePath) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/fsutils/fsutils.go b/vendor/github.com/golangci/golangci-lint/pkg/fsutils/fsutils.go deleted file mode 100644 index 80bb9c5b4..000000000 --- a/vendor/github.com/golangci/golangci-lint/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 - } - - evaledWd, err := EvalSymlinks(cachedWd) - if err != nil { - cachedWd, cachedWdError = "", fmt.Errorf("can't eval symlinks on wd %s: %w", cachedWd, err) - return - } - - cachedWd = evaledWd - }) - - 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 = filepath.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) - } - } - - evaledPath, err := EvalSymlinks(path) - if err != nil { - return "", fmt.Errorf("can't eval symlinks for path %s: %w", path, err) - } - path = evaledPath - - // 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/pkg/fsutils/linecache.go b/vendor/github.com/golangci/golangci-lint/pkg/fsutils/linecache.go deleted file mode 100644 index 2e9226484..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/fsutils/path_unix.go b/vendor/github.com/golangci/golangci-lint/pkg/fsutils/path_unix.go deleted file mode 100644 index 2a171ecc0..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/fsutils/path_windows.go b/vendor/github.com/golangci/golangci-lint/pkg/fsutils/path_windows.go deleted file mode 100644 index 650aae1e1..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/goanalysis/issue.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/issue.go deleted file mode 100644 index 15d8dd2b3..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/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 - Replacement *result.Replacement - ExpectNoLint bool - ExpectedNoLintLinter string -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/linter.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/linter.go deleted file mode 100644 index 13d3a09a5..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/linter.go +++ /dev/null @@ -1,217 +0,0 @@ -package goanalysis - -import ( - "context" - "errors" - "flag" - "fmt" - "strings" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const ( - TheOnlyAnalyzerName = "the_only_name" - TheOnlyanalyzerDoc = "the_only_doc" -) - -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 (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) 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/pkg/goanalysis/load/guard.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/load/guard.go deleted file mode 100644 index ab7775cc8..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/goanalysis/metalinter.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/metalinter.go deleted file mode 100644 index c2a794997..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/lint/linter" - "github.com/golangci/golangci-lint/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/pkg/goanalysis/pkgerrors/errors.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/errors.go deleted file mode 100644 index 7da659e80..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/errors.go +++ /dev/null @@ -1,56 +0,0 @@ -package pkgerrors - -import ( - "errors" - "fmt" - - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -type IllTypedError struct { - Pkg *packages.Package -} - -func (e *IllTypedError) Error() string { - return fmt.Sprintf("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 { - 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/pkg/goanalysis/pkgerrors/extract.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/extract.go deleted file mode 100644 index d1257e663..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/extract.go +++ /dev/null @@ -1,102 +0,0 @@ -package pkgerrors - -import ( - "fmt" - "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 - } - - seenErrors := map[string]bool{} - var uniqErrors []packages.Error - for _, err := range errors { - msg := stackCrusher(err.Error()) - if seenErrors[msg] { - continue - } - - if msg != err.Error() { - continue - } - - seenErrors[msg] = true - - uniqErrors = append(uniqErrors, err) - } - - 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/pkg/goanalysis/pkgerrors/parse.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors/parse.go deleted file mode 100644 index b25b50f71..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/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(:colon) - 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 { // no 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/pkg/goanalysis/runner.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner.go deleted file mode 100644 index c1274ec09..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner.go +++ /dev/null @@ -1,340 +0,0 @@ -// checker is a partial copy of https://github.com/golang/tools/blob/master/go/analysis/internal/checker -// 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 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 ( - "encoding/gob" - "fmt" - "go/token" - "runtime" - "sort" - "sync" - - "golang.org/x/exp/maps" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/internal/errorutil" - "github.com/golangci/golangci-lint/internal/pkgcache" - "github.com/golangci/golangci-lint/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/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 -} - -type runner struct { - log logutils.Log - prefix string // ensure unique analyzer names - pkgCache *pkgcache.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 *pkgcache.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) - defer r.pkgCache.Trim() - - 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.a = a - act.pkg = pkg - act.r = 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 := maps.Keys(pkg.Imports) - sort.Strings(paths) // 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 = 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.pkg] = append(actionPerPkg[act.pkg], 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.pkg) - } - - // Limit memory and IO usage. - gomaxprocs := runtime.GOMAXPROCS(-1) - debugf("Analyzing at most %d packages in parallel", gomaxprocs) - loadSem := make(chan struct{}, gomaxprocs) - - var wg sync.WaitGroup - debugf("There are %d initial and %d total packages", len(initialPkgs), len(loadingPackages)) - for _, lp := range loadingPackages { - if lp.isInitial { - wg.Add(1) - go func(lp *loadingPackage) { - lp.analyzeRecursive(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.a.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. - - posn := act.pkg.Fset.Position(diag.Pos) - k := key{posn, act.a, diag.Message} - if seen[k] { - continue // duplicate - } - seen[k] = true - - retDiag := Diagnostic{ - Diagnostic: diag, - Analyzer: act.a, - Position: posn, - Pkg: act.pkg, - } - retDiags = append(retDiags, retDiag) - } - } - } - visitAll(roots) - return retDiags, retErrors -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_action.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_action.go deleted file mode 100644 index 58ea297ea..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_action.go +++ /dev/null @@ -1,385 +0,0 @@ -package goanalysis - -import ( - "errors" - "fmt" - "go/types" - "io" - "reflect" - "runtime/debug" - "time" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - "golang.org/x/tools/go/types/objectpath" - - "github.com/golangci/golangci-lint/internal/errorutil" - "github.com/golangci/golangci-lint/internal/pkgcache" - "github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors" -) - -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 -} - -// 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 { - a *analysis.Analyzer - pkg *packages.Package - pass *analysis.Pass - deps []*action - objectFacts map[objectFactKey]analysis.Fact - packageFacts map[packageFactKey]analysis.Fact - result any - diagnostics []analysis.Diagnostic - err error - r *runner - analysisDoneCh chan struct{} - loadCachedFactsDone bool - loadCachedFactsOk bool - isroot bool - isInitialPkg bool - needAnalyzeSource bool -} - -func (act *action) String() string { - return fmt.Sprintf("%s@%s", act.a, act.pkg) -} - -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.a.FactTypes) == 0 { - return true // no need to load facts - } - - return act.loadPersistedFacts() - }() - act.loadCachedFactsDone = true - act.loadCachedFactsOk = res - return res -} - -func (act *action) waitUntilDependingAnalyzersWorked() { - for _, dep := range act.deps { - if dep.pkg == act.pkg { - <-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.r.log.Errorf("%s: panic during analysis: %v, %s", act.a.Name, p, string(debug.Stack())) - } - - act.err = errorutil.NewPanicError(fmt.Sprintf("%s: package %q (isInitialPkg: %t, needAnalyzeSource: %t): %s", - act.a.Name, act.pkg.Name, act.isInitialPkg, act.needAnalyzeSource, p), debug.Stack()) - } - }() - act.r.sw.TrackStage(act.a.Name, func() { - act.analyze() - }) -} - -func (act *action) analyze() { - defer close(act.analysisDoneCh) // unblock actions depending on this action - - if !act.needAnalyzeSource { - return - } - - defer func(now time.Time) { - analyzeDebugf("go/analysis: %s: %s: analyzed package %q in %s", act.r.prefix, act.a.Name, act.pkg.Name, time.Since(now)) - }(time.Now()) - - // Report an error if any dependency failures. - var depErrors error - for _, dep := range act.deps { - if dep.err == nil { - continue - } - - 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) - startedAt := time.Now() - for _, dep := range act.deps { - if dep.pkg == act.pkg { - // Same package, different analysis (horizontal edge): - // in-memory outputs of prerequisite analyzers - // become inputs to this analysis pass. - inputs[dep.a] = dep.result - } else if dep.a == act.a { // (always true) - // Same analysis, different package (vertical edge): - // serialized facts produced by prerequisite analysis - // become available to this analysis pass. - inheritFacts(act, dep) - } - } - factsDebugf("%s: Inherited facts in %s", act, time.Since(startedAt)) - - // Run the analysis. - pass := &analysis.Pass{ - Analyzer: act.a, - Fset: act.pkg.Fset, - Files: act.pkg.Syntax, - OtherFiles: act.pkg.OtherFiles, - Pkg: act.pkg.Types, - TypesInfo: act.pkg.TypesInfo, - TypesSizes: act.pkg.TypesSizes, - ResultOf: inputs, - Report: func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) }, - ImportObjectFact: act.importObjectFact, - ExportObjectFact: act.exportObjectFact, - ImportPackageFact: act.importPackageFact, - ExportPackageFact: act.exportPackageFact, - AllObjectFacts: act.allObjectFacts, - AllPackageFacts: act.allPackageFacts, - } - act.pass = pass - act.r.passToPkgGuard.Lock() - act.r.passToPkg[pass] = act.pkg - act.r.passToPkgGuard.Unlock() - - if act.pkg.IllTyped { - // 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. - act.err = fmt.Errorf("analysis skipped: %w", &pkgerrors.IllTypedError{Pkg: act.pkg}) - } else { - startedAt = time.Now() - act.result, act.err = pass.Analyzer.Run(pass) - analyzedIn := time.Since(startedAt) - if analyzedIn > time.Millisecond*10 { - debugf("%s: run analyzer in %s", act, analyzedIn) - } - } - - // disallow calls after Run - pass.ExportObjectFact = nil - pass.ExportPackageFact = nil - - if err := act.persistFactsToCache(); err != nil { - act.r.log.Warnf("Failed to persist facts to cache: %s", err) - } -} - -// importObjectFact implements Pass.ImportObjectFact. -// Given a non-nil pointer ptr of type *T, where *T satisfies Fact, -// importObjectFact copies the fact value to *ptr. -func (act *action) importObjectFact(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 -} - -// exportObjectFact implements Pass.ExportObjectFact. -func (act *action) exportObjectFact(obj types.Object, fact analysis.Fact) { - if obj.Pkg() != act.pkg.Types { - act.r.log.Panicf("internal error: in analysis %s of package %s: Fact.Set(%s, %T): can't set facts on objects belonging another package", - act.a, act.pkg, 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.pkg.Fset.Position(obj.Pos()), objstr, fact) - } -} - -func (act *action) allObjectFacts() []analysis.ObjectFact { - out := make([]analysis.ObjectFact, 0, len(act.objectFacts)) - for key, fact := range act.objectFacts { - out = append(out, analysis.ObjectFact{ - Object: key.obj, - Fact: fact, - }) - } - return out -} - -// importPackageFact implements Pass.ImportPackageFact. -// Given a non-nil pointer ptr of type *T, where *T satisfies Fact, -// fact copies the fact value to *ptr. -func (act *action) importPackageFact(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 -} - -// exportPackageFact implements Pass.ExportPackageFact. -func (act *action) exportPackageFact(fact analysis.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.pkg.Fset.Position(act.pass.Files[0].Pos()), act.pass.Pkg.Path(), fact) -} - -func (act *action) allPackageFacts() []analysis.PackageFact { - out := make([]analysis.PackageFact, 0, len(act.packageFacts)) - for key, fact := range act.packageFacts { - out = append(out, analysis.PackageFact{ - Package: key.pkg, - Fact: fact, - }) - } - return out -} - -func (act *action) factType(fact analysis.Fact) reflect.Type { - t := reflect.TypeOf(fact) - if t.Kind() != reflect.Ptr { - act.r.log.Fatalf("invalid Fact type: got %T, want pointer", t) - } - return t -} - -func (act *action) persistFactsToCache() error { - analyzer := act.a - 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.pkg.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.pkg.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.pkg.Name, act.a.Name) - - key := fmt.Sprintf("%s/facts", analyzer.Name) - return act.r.pkgCache.Put(act.pkg, pkgcache.HashModeNeedAllDeps, key, facts) -} - -func (act *action) loadPersistedFacts() bool { - var facts []Fact - key := fmt.Sprintf("%s/facts", act.a.Name) - if err := act.r.pkgCache.Get(act.pkg, pkgcache.HashModeNeedAllDeps, key, &facts); err != nil { - if !errors.Is(err, pkgcache.ErrMissing) && !errors.Is(err, io.EOF) { - act.r.log.Warnf("Failed to get persisted facts: %s", err) - } - - factsCacheDebugf("No cached facts for package %q and analyzer %s", act.pkg.Name, act.a.Name) - return false - } - - factsCacheDebugf("Loaded %d cached facts for package %q and analyzer %s", len(facts), act.pkg.Name, act.a.Name) - - for _, f := range facts { - if f.Path == "" { // this is a package fact - key := packageFactKey{act.pkg.Types, act.factType(f.Fact)} - act.packageFacts[key] = f.Fact - continue - } - obj, err := objectpath.Object(act.pkg.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 (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.pkg == act.pkg { - // 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/pkg/goanalysis/runner_facts.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_facts.go deleted file mode 100644 index 1d0fb974e..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_facts.go +++ /dev/null @@ -1,125 +0,0 @@ -package goanalysis - -import ( - "bytes" - "encoding/gob" - "fmt" - "go/types" - "reflect" - - "golang.org/x/tools/go/analysis" -) - -type objectFactKey struct { - obj types.Object - typ reflect.Type -} - -type packageFactKey struct { - pkg *types.Package - typ reflect.Type -} - -type Fact struct { - Path string // non-empty only for object facts - Fact analysis.Fact -} - -// inheritFacts populates act.facts with -// those it obtains from its dependency, dep. -func inheritFacts(act, dep *action) { - serialize := 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.pkg.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 serialize { - var err error - fact, err = codeFact(fact) - if err != nil { - act.r.log.Panicf("internal error: encoding of %T fact failed in %v", fact, act) - } - } - - 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. - - // Optionally serialize/deserialize fact - // to verify that it works across address spaces - // and is deterministic. - if serialize { - var err error - fact, err = codeFact(fact) - if err != nil { - act.r.log.Panicf("internal error: encoding of %T fact failed in %v", fact, act) - } - } - - factsInheritDebugf("%v: inherited %T fact for %s: %s", act, fact, key.pkg.Path(), fact) - act.packageFacts[key] = fact - } -} - -// 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 -} - -// 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 over-approximation 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: - return obj.Exported() && obj.Pkg() == pkg || - obj.IsField() - case *types.TypeName, *types.Const: - return true - } - return false // Nil, Builtin, Label, or PkgName -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_loadingpackage.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_loadingpackage.go deleted file mode 100644 index 8abe2b6c1..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runner_loadingpackage.go +++ /dev/null @@ -1,509 +0,0 @@ -package goanalysis - -import ( - "errors" - "fmt" - "go/ast" - "go/parser" - "go/scanner" - "go/types" - "os" - "reflect" - "sync" - "sync/atomic" - - "golang.org/x/tools/go/gcexportdata" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/pkg/goutil" - "github.com/golangci/golangci-lint/pkg/logutils" -) - -const unsafePkgName = "unsafe" - -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(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(loadMode, loadSem) - wg.Done() - }(imp) - } - wg.Wait() - lp.analyze(loadMode, loadSem) - }) -} - -func (lp *loadingPackage) analyze(loadMode LoadMode, loadSem chan struct{}) { - loadSem <- struct{}{} - defer func() { - <-loadSem - }() - - // Save memory on unused more fields. - defer lp.decUse(loadMode < LoadModeWholeProgram) - - if err := lp.loadWithFacts(loadMode); err != nil { - 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 - } - return - } - - var actsWg sync.WaitGroup - actsWg.Add(len(lp.actions)) - for _, act := range lp.actions { - go func(act *action) { - defer actsWg.Done() - - act.waitUntilDependingAnalyzersWorked() - - act.analyzeSafe() - }(act) - } - actsWg.Wait() -} - -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), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - } - - 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 - } - - // TODO(ldez) temporary workaround - rv, 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: rv, // TODO(ldez) temporary workaround - } - - _ = 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 fmt.Errorf("could not load export data: %w", err) - } - } - - 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.pkg = 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 - 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/pkg/goanalysis/runners.go b/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runners.go deleted file mode 100644 index 79e52f52a..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/goanalysis/runners.go +++ /dev/null @@ -1,274 +0,0 @@ -package goanalysis - -import ( - "fmt" - "runtime" - "sort" - "strings" - "sync" - "sync/atomic" - "time" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/internal/pkgcache" - "github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" - "github.com/golangci/golangci-lint/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 i := range reportedIssues { - issue := &reportedIssues[i].Issue - if issue.Pkg == nil { - issue.Pkg = passToPkg[reportedIssues[i].Pass] - } - retIssues = append(retIssues, *issue) - } - retIssues = append(retIssues, buildIssues(diags, cfg.getLinterNameForDiagnostic)...) - return retIssues - } - - 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 i := range diags { - diag := &diags[i] - 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) - } - - issues = append(issues, result.Issue{ - FromLinter: linterName, - Text: text, - Pos: diag.Position, - Pkg: diag.Pkg, - }) - - if len(diag.Related) > 0 { - for _, info := range diag.Related { - issues = append(issues, result.Issue{ - FromLinter: linterName, - Text: fmt.Sprintf("%s(related information): %s", diag.Analyzer.Name, info.Message), - Pos: diag.Pkg.Fset.Position(info.Pos), - Pkg: diag.Pkg, - }) - } - } - } - return issues -} - -func getIssuesCacheKey(analyzers []*analysis.Analyzer) string { - return "lint/result:" + analyzersHashID(analyzers) -} - -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 ind := range issues { - i := &issues[ind] - perPkgIssues[i.Pkg] = append(perPkgIssues[i.Pkg], *i) - } - - 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 i := 0; i < workerCount; i++ { - go func() { - defer wg.Done() - for pkg := range pkgCh { - pkgIssues := perPkgIssues[pkg] - encodedIssues := make([]EncodingIssue, 0, len(pkgIssues)) - for ind := range pkgIssues { - i := &pkgIssues[ind] - encodedIssues = append(encodedIssues, EncodingIssue{ - FromLinter: i.FromLinter, - Text: i.Text, - Severity: i.Severity, - Pos: i.Pos, - LineRange: i.LineRange, - Replacement: i.Replacement, - ExpectNoLint: i.ExpectNoLint, - ExpectedNoLintLinter: i.ExpectedNoLintLinter, - }) - } - - atomic.AddInt64(&savedIssuesCount, int64(len(encodedIssues))) - if err := lintCtx.PkgCache.Put(pkg, pkgcache.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() - - 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, pkgcache.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 i := range pkgIssues { - issue := &pkgIssues[i] - issues = append(issues, result.Issue{ - FromLinter: issue.FromLinter, - Text: issue.Text, - Severity: issue.Severity, - Pos: issue.Pos, - LineRange: issue.LineRange, - Replacement: issue.Replacement, - 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 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/pkg/golinters/asasalint/asasalint.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/asasalint/asasalint.go deleted file mode 100644 index 653a2d514..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/asasalint/asasalint.go +++ /dev/null @@ -1,31 +0,0 @@ -package asasalint - -import ( - "github.com/alingse/asasalint" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" -) - -func New(setting *config.AsasalintSettings) *goanalysis.Linter { - cfg := asasalint.LinterSetting{} - if setting != nil { - cfg.Exclude = setting.Exclude - cfg.NoBuiltinExclusions = !setting.UseBuiltinExclusions - cfg.IgnoreTest = setting.IgnoreTest - } - - a, err := asasalint.NewAnalyzer(cfg) - if err != nil { - internal.LinterLogger.Fatalf("asasalint: create analyzer: %v", err) - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/asciicheck/asciicheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/asciicheck/asciicheck.go deleted file mode 100644 index 675dfc478..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/asciicheck/asciicheck.go +++ /dev/null @@ -1,19 +0,0 @@ -package asciicheck - -import ( - "github.com/tdakkota/asciicheck" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := asciicheck.NewAnalyzer() - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/bidichk/bidichk.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/bidichk/bidichk.go deleted file mode 100644 index 4ced901e8..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/bidichk/bidichk.go +++ /dev/null @@ -1,59 +0,0 @@ -package bidichk - -import ( - "strings" - - "github.com/breml/bidichk/pkg/bidichk" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(cfg *config.BiDiChkSettings) *goanalysis.Linter { - a := bidichk.NewAnalyzer() - - cfgMap := map[string]map[string]any{} - if cfg != nil { - var opts []string - - if cfg.LeftToRightEmbedding { - opts = append(opts, "LEFT-TO-RIGHT-EMBEDDING") - } - if cfg.RightToLeftEmbedding { - opts = append(opts, "RIGHT-TO-LEFT-EMBEDDING") - } - if cfg.PopDirectionalFormatting { - opts = append(opts, "POP-DIRECTIONAL-FORMATTING") - } - if cfg.LeftToRightOverride { - opts = append(opts, "LEFT-TO-RIGHT-OVERRIDE") - } - if cfg.RightToLeftOverride { - opts = append(opts, "RIGHT-TO-LEFT-OVERRIDE") - } - if cfg.LeftToRightIsolate { - opts = append(opts, "LEFT-TO-RIGHT-ISOLATE") - } - if cfg.RightToLeftIsolate { - opts = append(opts, "RIGHT-TO-LEFT-ISOLATE") - } - if cfg.FirstStrongIsolate { - opts = append(opts, "FIRST-STRONG-ISOLATE") - } - if cfg.PopDirectionalIsolate { - opts = append(opts, "POP-DIRECTIONAL-ISOLATE") - } - - cfgMap[a.Name] = map[string]any{ - "disallowed-runes": strings.Join(opts, ","), - } - } - - return goanalysis.NewLinter( - a.Name, - "Checks for dangerous unicode character sequences", - []*analysis.Analyzer{a}, - cfgMap, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/bodyclose/bodyclose.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/bodyclose/bodyclose.go deleted file mode 100644 index f39814edc..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/bodyclose/bodyclose.go +++ /dev/null @@ -1,19 +0,0 @@ -package bodyclose - -import ( - "github.com/timakin/bodyclose/passes/bodyclose" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := bodyclose.Analyzer - - return goanalysis.NewLinter( - a.Name, - "checks whether HTTP response body is closed successfully", - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/canonicalheader/canonicalheader.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/canonicalheader/canonicalheader.go deleted file mode 100644 index d721916a4..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/canonicalheader/canonicalheader.go +++ /dev/null @@ -1,19 +0,0 @@ -package canonicalheader - -import ( - "github.com/lasiar/canonicalheader" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := canonicalheader.Analyzer - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/containedctx/containedctx.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/containedctx/containedctx.go deleted file mode 100644 index 6fdb4ea6e..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/containedctx/containedctx.go +++ /dev/null @@ -1,19 +0,0 @@ -package containedctx - -import ( - "github.com/sivchari/containedctx" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := containedctx.Analyzer - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/contextcheck/contextcheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/contextcheck/contextcheck.go deleted file mode 100644 index a34c518b2..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/contextcheck/contextcheck.go +++ /dev/null @@ -1,22 +0,0 @@ -package contextcheck - -import ( - "github.com/kkHAIKE/contextcheck" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" -) - -func New() *goanalysis.Linter { - analyzer := contextcheck.NewAnalyzer(contextcheck.Configuration{}) - - return goanalysis.NewLinter( - analyzer.Name, - analyzer.Doc, - []*analysis.Analyzer{analyzer}, - nil, - ).WithContextSetter(func(lintCtx *linter.Context) { - analyzer.Run = contextcheck.NewRun(lintCtx.Packages, false) - }).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/copyloopvar/copyloopvar.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/copyloopvar/copyloopvar.go deleted file mode 100644 index adb4ee728..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/copyloopvar/copyloopvar.go +++ /dev/null @@ -1,29 +0,0 @@ -package copyloopvar - -import ( - "github.com/karamaru-alpha/copyloopvar" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.CopyLoopVarSettings) *goanalysis.Linter { - a := copyloopvar.NewAnalyzer() - - var cfg map[string]map[string]any - if settings != nil { - cfg = map[string]map[string]any{ - a.Name: { - "check-alias": settings.CheckAlias, - }, - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/cyclop/cyclop.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/cyclop/cyclop.go deleted file mode 100644 index eb8c0577a..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/cyclop/cyclop.go +++ /dev/null @@ -1,37 +0,0 @@ -package cyclop - -import ( - "github.com/bkielbasa/cyclop/pkg/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.Cyclop) *goanalysis.Linter { - a := analyzer.NewAnalyzer() - - var cfg map[string]map[string]any - if settings != nil { - d := map[string]any{ - "skipTests": settings.SkipTests, - } - - if settings.MaxComplexity != 0 { - d["maxComplexity"] = settings.MaxComplexity - } - - if settings.PackageAverage != 0 { - d["packageAverage"] = settings.PackageAverage - } - - cfg = map[string]map[string]any{a.Name: d} - } - - return goanalysis.NewLinter( - a.Name, - "checks function and package cyclomatic complexity", - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/decorder/decorder.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/decorder/decorder.go deleted file mode 100644 index a05f6a325..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/decorder/decorder.go +++ /dev/null @@ -1,44 +0,0 @@ -package decorder - -import ( - "strings" - - "gitlab.com/bosi/decorder" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.DecorderSettings) *goanalysis.Linter { - a := decorder.Analyzer - - // 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.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - map[string]map[string]any{a.Name: cfg}, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/depguard/depguard.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/depguard/depguard.go deleted file mode 100644 index d2aedf252..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/depguard/depguard.go +++ /dev/null @@ -1,50 +0,0 @@ -package depguard - -import ( - "github.com/OpenPeeDeeP/depguard/v2" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" -) - -func New(settings *config.DepGuardSettings) *goanalysis.Linter { - conf := depguard.LinterSettings{} - - if settings != nil { - for s, rule := range settings.Rules { - list := &depguard.List{ - ListMode: rule.ListMode, - Files: rule.Files, - 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 - } - } - - a := depguard.NewUncompiledAnalyzer(&conf) - - return goanalysis.NewLinter( - a.Analyzer.Name, - a.Analyzer.Doc, - []*analysis.Analyzer{a.Analyzer}, - nil, - ).WithContextSetter(func(lintCtx *linter.Context) { - err := a.Compile() - if err != nil { - lintCtx.Log.Errorf("create analyzer: %v", err) - } - }).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/dogsled/dogsled.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/dogsled/dogsled.go deleted file mode 100644 index 49108f4f1..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/dogsled/dogsled.go +++ /dev/null @@ -1,110 +0,0 @@ -package dogsled - -import ( - "fmt" - "go/ast" - "go/token" - "sync" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "dogsled" - -func New(settings *config.DogsledSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues := runDogsled(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 assignments with too many blank identifiers (e.g. x, _, _, _, := f())", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runDogsled(pass *analysis.Pass, settings *config.DogsledSettings) []goanalysis.Issue { - var reports []goanalysis.Issue - for _, f := range pass.Files { - v := &returnsVisitor{ - maxBlanks: settings.MaxBlankIdentifiers, - f: pass.Fset, - } - - ast.Walk(v, f) - - for i := range v.issues { - reports = append(reports, goanalysis.NewIssue(&v.issues[i], pass)) - } - } - - return reports -} - -type returnsVisitor struct { - f *token.FileSet - maxBlanks int - issues []result.Issue -} - -func (v *returnsVisitor) Visit(node ast.Node) ast.Visitor { - funcDecl, ok := node.(*ast.FuncDecl) - if !ok { - return v - } - if funcDecl.Body == nil { - return v - } - - 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 > v.maxBlanks { - v.issues = append(v.issues, result.Issue{ - FromLinter: linterName, - Text: fmt.Sprintf("declaration has %v blank identifiers", numBlank), - Pos: v.f.Position(assgnStmt.Pos()), - }) - } - } - return v -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/dupl/dupl.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/dupl/dupl.go deleted file mode 100644 index 7abcb4c4f..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/dupl/dupl.go +++ /dev/null @@ -1,96 +0,0 @@ -package dupl - -import ( - "fmt" - "go/token" - "sync" - - duplAPI "github.com/golangci/dupl" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "dupl" - -func New(settings *config.DuplSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - 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 - }, - } - - return goanalysis.NewLinter( - linterName, - "Tool for code clone detection", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runDupl(pass *analysis.Pass, settings *config.DuplSettings) ([]goanalysis.Issue, error) { - fileNames := internal.GetFileNames(pass) - - issues, err := duplAPI.Run(fileNames, 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, nil)) - - 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/pkg/golinters/dupword/dupword.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/dupword/dupword.go deleted file mode 100644 index bba4fc9e1..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/dupword/dupword.go +++ /dev/null @@ -1,30 +0,0 @@ -package dupword - -import ( - "strings" - - "github.com/Abirdcfly/dupword" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(setting *config.DupWordSettings) *goanalysis.Linter { - a := dupword.NewAnalyzer() - - cfgMap := map[string]map[string]any{} - if setting != nil { - cfgMap[a.Name] = map[string]any{ - "keyword": strings.Join(setting.Keywords, ","), - "ignore": strings.Join(setting.Ignore, ","), - } - } - - return goanalysis.NewLinter( - a.Name, - "checks for duplicate words in the source code", - []*analysis.Analyzer{a}, - cfgMap, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/durationcheck/durationcheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/durationcheck/durationcheck.go deleted file mode 100644 index 88f22c27c..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/durationcheck/durationcheck.go +++ /dev/null @@ -1,19 +0,0 @@ -package durationcheck - -import ( - "github.com/charithe/durationcheck" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := durationcheck.Analyzer - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/err113/err113.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/err113/err113.go deleted file mode 100644 index 2600128be..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/err113/err113.go +++ /dev/null @@ -1,19 +0,0 @@ -package err113 - -import ( - "github.com/Djarvur/go-err113" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := err113.NewAnalyzer() - - return goanalysis.NewLinter( - a.Name, - "Go linter to check the errors handling expressions", - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errcheck/errcheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/errcheck/errcheck.go deleted file mode 100644 index 9a8a2aa87..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errcheck/errcheck.go +++ /dev/null @@ -1,271 +0,0 @@ -package errcheck - -import ( - "bufio" - "fmt" - "os" - "os/user" - "path/filepath" - "regexp" - "strings" - "sync" - - "github.com/kisielk/errcheck/errcheck" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/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: goanalysis.TheOnlyanalyzerDoc, - Run: goanalysis.DummyRun, - } - - return goanalysis.NewLinter( - linterName, - "errcheck is a program for checking for unchecked errors in Go code. "+ - "These unchecked errors can be critical bugs in some cases", - []*analysis.Analyzer{analyzer}, - nil, - ).WithContextSetter(func(lintCtx *linter.Context) { - // copied from errcheck - checker, err := getChecker(settings) - if err != nil { - lintCtx.Log.Errorf("failed to get checker: %v", err) - return - } - - checker.Tags = lintCtx.Cfg.Run.BuildTags - - analyzer.Run = func(pass *analysis.Pass) (any, error) { - issues := runErrCheck(lintCtx, pass, checker) - 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 runErrCheck(lintCtx *linter.Context, pass *analysis.Pass, checker *errcheck.Checker) []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 := err.SelectorName - if err.SelectorName == "" { - code = err.FuncName - } - - text = fmt.Sprintf("Error return value of %s is not checked", internal.FormatCode(code, lintCtx.Cfg)) - } - - issues[i] = goanalysis.NewIssue( - &result.Issue{ - FromLinter: linterName, - Text: text, - Pos: err.Pos, - }, - pass, - ) - } - - return issues -} - -// parseIgnoreConfig was taken from errcheck in order to keep the API identical. -// https://github.com/kisielk/errcheck/blob/1787c4bee836470bf45018cfbc783650db3c6501/main.go#L25-L60 -func parseIgnoreConfig(s string) (map[string]*regexp.Regexp, error) { - if s == "" { - return nil, nil - } - - cfg := map[string]*regexp.Regexp{} - - for _, pair := range strings.Split(s, ",") { - colonIndex := strings.Index(pair, ":") - var pkg, re string - if colonIndex == -1 { - pkg = "" - re = pair - } else { - pkg = pair[:colonIndex] - re = pair[colonIndex+1:] - } - regex, err := regexp.Compile(re) - if err != nil { - return nil, err - } - cfg[pkg] = regex - } - - return cfg, nil -} - -func getChecker(errCfg *config.ErrcheckSettings) (*errcheck.Checker, error) { - ignoreConfig, err := parseIgnoreConfig(errCfg.Ignore) - if err != nil { - return nil, fmt.Errorf("failed to parse 'ignore' directive: %w", err) - } - - 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...) - } - - for pkg, re := range ignoreConfig { - checker.Exclusions.SymbolRegexpsByPackage[pkg] = re - } - - if errCfg.Exclude != "" { - exclude, err := readExcludeFile(errCfg.Exclude) - if err != nil { - return nil, err - } - - checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, exclude...) - } - - checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, errCfg.ExcludeFunctions...) - - return &checker, nil -} - -func getFirstPathArg() string { - args := os.Args - - // skip all args ([golangci-lint, run/linters]) before files/dirs list - for len(args) != 0 { - if args[0] == "run" { - args = args[1:] - break - } - - args = args[1:] - } - - // find first file/dir arg - firstArg := "./..." - for _, arg := range args { - if !strings.HasPrefix(arg, "-") { - firstArg = arg - break - } - } - - return firstArg -} - -func setupConfigFileSearch(name string) []string { - if strings.HasPrefix(name, "~") { - if u, err := user.Current(); err == nil { - name = strings.Replace(name, "~", u.HomeDir, 1) - } - } - - if filepath.IsAbs(name) { - return []string{name} - } - - firstArg := getFirstPathArg() - - absStartPath, err := filepath.Abs(firstArg) - if err != nil { - absStartPath = filepath.Clean(firstArg) - } - - // start from it - var curDir string - if fsutils.IsDir(absStartPath) { - curDir = absStartPath - } else { - curDir = filepath.Dir(absStartPath) - } - - // find all dirs from it up to the root - configSearchPaths := []string{filepath.Join(".", name)} - for { - configSearchPaths = append(configSearchPaths, filepath.Join(curDir, name)) - newCurDir := filepath.Dir(curDir) - if curDir == newCurDir || newCurDir == "" { - break - } - curDir = newCurDir - } - - return configSearchPaths -} - -func readExcludeFile(name string) ([]string, error) { - var err error - var fh *os.File - - for _, path := range setupConfigFileSearch(name) { - if fh, err = os.Open(path); err == nil { - break - } - } - - if fh == nil { - return nil, fmt.Errorf("failed reading exclude file: %s: %w", name, err) - } - defer func() { _ = fh.Close() }() - - scanner := bufio.NewScanner(fh) - - var excludes []string - for scanner.Scan() { - excludes = append(excludes, scanner.Text()) - } - - if err := scanner.Err(); err != nil { - return nil, fmt.Errorf("failed scanning file: %s: %w", name, err) - } - - return excludes, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errchkjson/errchkjson.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/errchkjson/errchkjson.go deleted file mode 100644 index 8389a750c..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errchkjson/errchkjson.go +++ /dev/null @@ -1,31 +0,0 @@ -package errchkjson - -import ( - "github.com/breml/errchkjson" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(cfg *config.ErrChkJSONSettings) *goanalysis.Linter { - a := errchkjson.NewAnalyzer() - - cfgMap := map[string]map[string]any{} - cfgMap[a.Name] = map[string]any{ - "omit-safe": true, - } - if cfg != nil { - cfgMap[a.Name] = map[string]any{ - "omit-safe": !cfg.CheckErrorFreeEncoding, - "report-no-exported": cfg.ReportNoExported, - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfgMap, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errname/errname.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/errname/errname.go deleted file mode 100644 index f868854c1..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errname/errname.go +++ /dev/null @@ -1,19 +0,0 @@ -package errname - -import ( - "github.com/Antonboom/errname/pkg/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := analyzer.New() - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errorlint/errorlint.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/errorlint/errorlint.go deleted file mode 100644 index 86db8552d..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/errorlint/errorlint.go +++ /dev/null @@ -1,54 +0,0 @@ -package errorlint - -import ( - "github.com/polyfloyd/go-errorlint/errorlint" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(cfg *config.ErrorLintSettings) *goanalysis.Linter { - var opts []errorlint.Option - - if cfg != nil { - ae := toAllowPairs(cfg.AllowedErrors) - if len(ae) > 0 { - opts = append(opts, errorlint.WithAllowedErrors(ae)) - } - - aew := toAllowPairs(cfg.AllowedErrorsWildcard) - if len(aew) > 0 { - opts = append(opts, errorlint.WithAllowedWildcard(aew)) - } - } - - a := errorlint.NewAnalyzer(opts...) - - cfgMap := map[string]map[string]any{} - - if cfg != nil { - cfgMap[a.Name] = map[string]any{ - "errorf": cfg.Errorf, - "errorf-multi": cfg.ErrorfMulti, - "asserts": cfg.Asserts, - "comparison": cfg.Comparison, - } - } - - return goanalysis.NewLinter( - a.Name, - "errorlint is a linter for that can be used to find code "+ - "that will cause problems with the error wrapping scheme introduced in Go 1.13.", - []*analysis.Analyzer{a}, - cfgMap, - ).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/pkg/golinters/execinquery/execinquery.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/execinquery/execinquery.go deleted file mode 100644 index 3832873c6..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/execinquery/execinquery.go +++ /dev/null @@ -1,19 +0,0 @@ -package execinquery - -import ( - "github.com/lufeee/execinquery" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := execinquery.Analyzer - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustive/exhaustive.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustive/exhaustive.go deleted file mode 100644 index 9249efb69..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustive/exhaustive.go +++ /dev/null @@ -1,37 +0,0 @@ -package exhaustive - -import ( - "github.com/nishanths/exhaustive" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.ExhaustiveSettings) *goanalysis.Linter { - a := exhaustive.Analyzer - - var cfg map[string]map[string]any - if settings != nil { - cfg = map[string]map[string]any{ - a.Name: { - exhaustive.CheckFlag: settings.Check, - exhaustive.CheckGeneratedFlag: settings.CheckGenerated, - 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, - }, - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustruct/exhaustruct.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustruct/exhaustruct.go deleted file mode 100644 index 53ad87154..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exhaustruct/exhaustruct.go +++ /dev/null @@ -1,30 +0,0 @@ -package exhaustruct - -import ( - "github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" -) - -func New(settings *config.ExhaustructSettings) *goanalysis.Linter { - var include, exclude []string - if settings != nil { - include = settings.Include - exclude = settings.Exclude - } - - a, err := analyzer.NewAnalyzer(include, exclude) - if err != nil { - internal.LinterLogger.Fatalf("exhaustruct configuration: %v", err) - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exportloopref/exportloopref.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/exportloopref/exportloopref.go deleted file mode 100644 index e232f8045..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/exportloopref/exportloopref.go +++ /dev/null @@ -1,19 +0,0 @@ -package exportloopref - -import ( - "github.com/kyoh86/exportloopref" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := exportloopref.Analyzer - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/fatcontext/fatcontext.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/fatcontext/fatcontext.go deleted file mode 100644 index 378025a8c..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/fatcontext/fatcontext.go +++ /dev/null @@ -1,19 +0,0 @@ -package fatcontext - -import ( - "github.com/Crocmagnon/fatcontext/pkg/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := analyzer.Analyzer - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/forbidigo/forbidigo.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/forbidigo/forbidigo.go deleted file mode 100644 index 3572b60c2..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/forbidigo/forbidigo.go +++ /dev/null @@ -1,103 +0,0 @@ -package forbidigo - -import ( - "fmt" - "sync" - - "github.com/ashanbrown/forbidigo/forbidigo" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "forbidigo" - -func New(settings *config.ForbidigoSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues, err := runForbidigo(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 - }, - } - - // 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.NewLinter( - linterName, - "Forbids identifiers", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runForbidigo(pass *analysis.Pass, settings *config.ForbidigoSettings) ([]goanalysis.Issue, 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 := pattern.MarshalString() - if err != nil { - return nil, err - } - patterns = append(patterns, string(buffer)) - } - - forbid, err := forbidigo.NewLinter(patterns, options...) - if err != nil { - return nil, fmt.Errorf("failed to create linter %q: %w", linterName, err) - } - - var issues []goanalysis.Issue - for _, file := range pass.Files { - runConfig := forbidigo.RunConfig{ - Fset: pass.Fset, - DebugLog: logutils.Debug(logutils.DebugKeyForbidigo), - } - if settings != nil && settings.AnalyzeTypes { - runConfig.TypesInfo = pass.TypesInfo - } - hints, err := forbid.RunWithConfig(runConfig, file) - if err != nil { - return nil, fmt.Errorf("forbidigo linter failed on file %q: %w", file.Name.String(), err) - } - - for _, hint := range hints { - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - Pos: hint.Position(), - Text: hint.Details(), - FromLinter: linterName, - }, pass)) - } - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/forcetypeassert/forcetypeassert.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/forcetypeassert/forcetypeassert.go deleted file mode 100644 index 741b57cea..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/forcetypeassert/forcetypeassert.go +++ /dev/null @@ -1,19 +0,0 @@ -package forcetypeassert - -import ( - "github.com/gostaticanalysis/forcetypeassert" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := forcetypeassert.Analyzer - - return goanalysis.NewLinter( - a.Name, - "finds forced type assertions", - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/funlen/funlen.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/funlen/funlen.go deleted file mode 100644 index e43339394..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/funlen/funlen.go +++ /dev/null @@ -1,75 +0,0 @@ -package funlen - -import ( - "go/token" - "strings" - "sync" - - "github.com/ultraware/funlen" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "funlen" - -func New(settings *config.FunlenSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues := runFunlen(pass, settings) - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - } - - return goanalysis.NewLinter( - linterName, - "Tool for detection of long functions", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runFunlen(pass *analysis.Pass, settings *config.FunlenSettings) []goanalysis.Issue { - var lintIssues []funlen.Message - for _, file := range pass.Files { - fileIssues := funlen.Run(file, pass.Fset, settings.Lines, settings.Statements, settings.IgnoreComments) - lintIssues = append(lintIssues, fileIssues...) - } - - if len(lintIssues) == 0 { - return nil - } - - issues := make([]goanalysis.Issue, len(lintIssues)) - for k, i := range lintIssues { - issues[k] = goanalysis.NewIssue(&result.Issue{ - Pos: token.Position{ - Filename: i.Pos.Filename, - Line: i.Pos.Line, - }, - Text: strings.TrimRight(i.Message, "\n"), - FromLinter: linterName, - }, pass) - } - - return issues -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gci/gci.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gci/gci.go deleted file mode 100644 index a9afb6c89..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gci/gci.go +++ /dev/null @@ -1,250 +0,0 @@ -package gci - -import ( - "fmt" - "sort" - "strings" - "sync" - - gcicfg "github.com/daixiang0/gci/pkg/config" - "github.com/daixiang0/gci/pkg/gci" - "github.com/daixiang0/gci/pkg/io" - "github.com/daixiang0/gci/pkg/log" - "github.com/daixiang0/gci/pkg/section" - "github.com/golangci/modinfo" - "github.com/hexops/gotextdiff" - "github.com/hexops/gotextdiff/myers" - "github.com/hexops/gotextdiff/span" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" -) - -const linterName = "gci" - -func New(settings *config.GciSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: goanalysis.DummyRun, - Requires: []*analysis.Analyzer{ - modinfo.Analyzer, - }, - } - - var cfg *gcicfg.Config - if settings != nil { - rawCfg := gcicfg.YamlConfig{ - Cfg: gcicfg.BoolConfig{ - SkipGenerated: settings.SkipGenerated, - CustomOrder: settings.CustomOrder, - NoLexOrder: settings.NoLexOrder, - }, - SectionStrings: settings.Sections, - } - - if settings.LocalPrefixes != "" { - prefix := []string{"standard", "default", fmt.Sprintf("prefix(%s)", settings.LocalPrefixes)} - rawCfg.SectionStrings = prefix - } - - var err error - cfg, err = YamlConfig{origin: rawCfg}.Parse() - if err != nil { - internal.LinterLogger.Fatalf("gci: configuration parsing: %v", err) - } - } - - var lock sync.Mutex - - return goanalysis.NewLinter( - linterName, - "Gci controls Go package import order and makes it always deterministic.", - []*analysis.Analyzer{analyzer}, - nil, - ).WithContextSetter(func(lintCtx *linter.Context) { - analyzer.Run = func(pass *analysis.Pass) (any, error) { - var err error - cfg.Sections, err = hackSectionList(pass, cfg) - if err != nil { - return nil, err - } - - issues, err := runGci(pass, lintCtx, cfg, &lock) - 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 runGci(pass *analysis.Pass, lintCtx *linter.Context, cfg *gcicfg.Config, lock *sync.Mutex) ([]goanalysis.Issue, error) { - fileNames := internal.GetFileNames(pass) - - var diffs []string - err := diffFormattedFilesToArray(fileNames, *cfg, &diffs, lock) - if err != nil { - return nil, err - } - - var issues []goanalysis.Issue - - for _, diff := range diffs { - if diff == "" { - continue - } - - is, err := internal.ExtractIssuesFromPatch(diff, lintCtx, linterName, getIssuedTextGci) - if err != nil { - return nil, fmt.Errorf("can't extract issues from gci diff output %s: %w", diff, err) - } - - for i := range is { - issues = append(issues, goanalysis.NewIssue(&is[i], pass)) - } - } - - return issues, nil -} - -func getIssuedTextGci(settings *config.LintersSettings) string { - text := "File is not `gci`-ed" - - hasOptions := settings.Gci.SkipGenerated || len(settings.Gci.Sections) > 0 - if !hasOptions { - return text - } - - text += " with" - - if settings.Gci.SkipGenerated { - text += " --skip-generated" - } - - if len(settings.Gci.Sections) > 0 { - for _, sect := range settings.Gci.Sections { - text += " -s " + sect - } - } - - if settings.Gci.CustomOrder { - text += " --custom-order" - } - - return text -} - -func hackSectionList(pass *analysis.Pass, cfg *gcicfg.Config) (section.SectionList, error) { - var sections section.SectionList - - for _, sect := range cfg.Sections { - // local module hack - if v, ok := sect.(*section.LocalModule); ok { - info, err := modinfo.FindModuleFromPass(pass) - if err != nil { - return nil, err - } - - if info.Path == "" { - continue - } - - v.Path = info.Path - } - - sections = append(sections, sect) - } - - return sections, nil -} - -// diffFormattedFilesToArray is a copy of gci.DiffFormattedFilesToArray without io.StdInGenerator. -// gci.DiffFormattedFilesToArray uses gci.processStdInAndGoFilesInPaths that uses io.StdInGenerator but stdin is not active on CI. -// https://github.com/daixiang0/gci/blob/6f5cb16718ba07f0342a58de9b830ec5a6d58790/pkg/gci/gci.go#L63-L75 -// https://github.com/daixiang0/gci/blob/6f5cb16718ba07f0342a58de9b830ec5a6d58790/pkg/gci/gci.go#L80 -func diffFormattedFilesToArray(paths []string, cfg gcicfg.Config, diffs *[]string, lock *sync.Mutex) error { - log.InitLogger() - defer func() { _ = log.L().Sync() }() - - return gci.ProcessFiles(io.GoFilesInPathsGenerator(paths, true), 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 - }) -} - -// Code below this comment is borrowed and modified from gci. -// https://github.com/daixiang0/gci/blob/v0.13.5/pkg/config/config.go - -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 YamlConfig struct { - origin gcicfg.YamlConfig -} - -//nolint:gocritic // code borrowed from gci and modified to fix LocalModule section behavior. -func (g YamlConfig) Parse() (*gcicfg.Config, error) { - var err error - - sections, err := section.Parse(g.origin.SectionStrings) - if err != nil { - return nil, err - } - - if sections == nil { - sections = section.DefaultSections() - } - - // if default order sorted sections - if !g.origin.Cfg.CustomOrder { - sort.Slice(sections, func(i, j int) bool { - sectionI, sectionJ := sections[i].Type(), sections[j].Type() - - if g.origin.Cfg.NoLexOrder || strings.Compare(sectionI, sectionJ) != 0 { - return defaultOrder[sectionI] < defaultOrder[sectionJ] - } - - return strings.Compare(sections[i].String(), sections[j].String()) < 0 - }) - } - - sectionSeparators, err := section.Parse(g.origin.SectionSeparatorStrings) - if err != nil { - return nil, err - } - if sectionSeparators == nil { - sectionSeparators = section.DefaultSectionSeparators() - } - - return &gcicfg.Config{BoolConfig: g.origin.Cfg, Sections: sections, SectionSeparators: sectionSeparators}, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ginkgolinter/ginkgolinter.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/ginkgolinter/ginkgolinter.go deleted file mode 100644 index 54d207257..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ginkgolinter/ginkgolinter.go +++ /dev/null @@ -1,39 +0,0 @@ -package ginkgolinter - -import ( - "github.com/nunnatsa/ginkgolinter" - "github.com/nunnatsa/ginkgolinter/types" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.GinkgoLinterSettings) *goanalysis.Linter { - cfg := &types.Config{} - - if settings != nil { - cfg = &types.Config{ - SuppressLen: types.Boolean(settings.SuppressLenAssertion), - SuppressNil: types.Boolean(settings.SuppressNilAssertion), - SuppressErr: types.Boolean(settings.SuppressErrAssertion), - SuppressCompare: types.Boolean(settings.SuppressCompareAssertion), - SuppressAsync: types.Boolean(settings.SuppressAsyncAssertion), - ForbidFocus: types.Boolean(settings.ForbidFocusContainer), - SuppressTypeCompare: types.Boolean(settings.SuppressTypeCompareWarning), - AllowHaveLen0: types.Boolean(settings.AllowHaveLenZero), - ForceExpectTo: types.Boolean(settings.ForceExpectTo), - ValidateAsyncIntervals: types.Boolean(settings.ForbidSpecPollution), - ForbidSpecPollution: types.Boolean(settings.ValidateAsyncIntervals), - } - } - - a := ginkgolinter.NewAnalyzerWithConfig(cfg) - - return goanalysis.NewLinter( - a.Name, - "enforces standards of using ginkgo and gomega", - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go deleted file mode 100644 index be604d805..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go +++ /dev/null @@ -1,19 +0,0 @@ -package gocheckcompilerdirectives - -import ( - "4d63.com/gocheckcompilerdirectives/checkcompilerdirectives" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := checkcompilerdirectives.Analyzer() - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoglobals/gochecknoglobals.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoglobals/gochecknoglobals.go deleted file mode 100644 index af22b2f8e..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoglobals/gochecknoglobals.go +++ /dev/null @@ -1,26 +0,0 @@ -package gochecknoglobals - -import ( - "4d63.com/gochecknoglobals/checknoglobals" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := checknoglobals.Analyzer() - - // gochecknoglobals only lints test files if the `-t` flag is passed, - // so we pass the `t` 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 `--exclude-files`. - linterConfig := map[string]map[string]any{ - a.Name: {"t": true}, - } - - return goanalysis.NewLinter( - a.Name, - "Check that no global variables exist.", - []*analysis.Analyzer{a}, - linterConfig, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoinits/gochecknoinits.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoinits/gochecknoinits.go deleted file mode 100644 index 1345eb8c2..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecknoinits/gochecknoinits.go +++ /dev/null @@ -1,75 +0,0 @@ -package gochecknoinits - -import ( - "fmt" - "go/ast" - "go/token" - "sync" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "gochecknoinits" - -func New() *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - var res []goanalysis.Issue - for _, file := range pass.Files { - fileIssues := checkFileForInits(file, pass.Fset) - for i := range fileIssues { - res = append(res, goanalysis.NewIssue(&fileIssues[i], pass)) - } - } - if len(res) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, res...) - mu.Unlock() - - return nil, nil - }, - } - - return goanalysis.NewLinter( - linterName, - "Checks that no init functions are present in Go code", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func checkFileForInits(f *ast.File, fset *token.FileSet) []result.Issue { - var res []result.Issue - for _, decl := range f.Decls { - funcDecl, ok := decl.(*ast.FuncDecl) - if !ok { - continue - } - - fnName := funcDecl.Name.Name - if fnName == "init" && funcDecl.Recv.NumFields() == 0 { - res = append(res, result.Issue{ - Pos: fset.Position(funcDecl.Pos()), - Text: fmt.Sprintf("don't use %s function", internal.FormatCode(fnName, nil)), - FromLinter: linterName, - }) - } - } - - return res -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecksumtype/gochecksumtype.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecksumtype/gochecksumtype.go deleted file mode 100644 index 446f0e564..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gochecksumtype/gochecksumtype.go +++ /dev/null @@ -1,80 +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/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "gochecksumtype" - -func New() *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues, err := runGoCheckSumType(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 - }, - } - - return goanalysis.NewLinter( - linterName, - `Run exhaustiveness checks on Go "sum types"`, - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(_ *linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runGoCheckSumType(pass *analysis.Pass) ([]goanalysis.Issue, error) { - var resIssues []goanalysis.Issue - - pkg := &packages.Package{ - Fset: pass.Fset, - Syntax: pass.Files, - Types: pass.Pkg, - TypesInfo: pass.TypesInfo, - } - - var unknownError error - errors := gochecksumtype.Run([]*packages.Package{pkg}) - 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/pkg/golinters/gocognit/gocognit.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocognit/gocognit.go deleted file mode 100644 index 5fe0f90f0..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocognit/gocognit.go +++ /dev/null @@ -1,80 +0,0 @@ -package gocognit - -import ( - "fmt" - "sort" - "sync" - - "github.com/uudashr/gocognit" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "gocognit" - -func New(settings *config.GocognitSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: goanalysis.TheOnlyAnalyzerName, - Doc: goanalysis.TheOnlyanalyzerDoc, - 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 - }, - } - - return goanalysis.NewLinter( - linterName, - "Computes and checks the cognitive complexity of functions", - []*analysis.Analyzer{analyzer}, - 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, nil), settings.MinComplexity), - FromLinter: linterName, - }, pass)) - } - - return issues -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goconst/goconst.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/goconst/goconst.go deleted file mode 100644 index 07bed301f..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goconst/goconst.go +++ /dev/null @@ -1,98 +0,0 @@ -package goconst - -import ( - "fmt" - "sync" - - goconstAPI "github.com/jgautheron/goconst" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "goconst" - -func New(settings *config.GoConstSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - 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 - }, - } - - return goanalysis.NewLinter( - linterName, - "Finds repeated strings that could be replaced by a constant", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runGoconst(pass *analysis.Pass, settings *config.GoConstSettings) ([]goanalysis.Issue, error) { - cfg := goconstAPI.Config{ - IgnoreStrings: settings.IgnoreStrings, - IgnoreTests: settings.IgnoreTests, - MatchWithConstants: settings.MatchWithConstants, - MinStringLength: settings.MinStringLen, - MinOccurrences: settings.MinOccurrencesCount, - ParseNumbers: settings.ParseNumbers, - NumberMin: settings.NumberMin, - NumberMax: settings.NumberMax, - ExcludeTypes: map[goconstAPI.Type]bool{}, - } - - if settings.IgnoreCalls { - cfg.ExcludeTypes[goconstAPI.Call] = true - } - - lintIssues, err := goconstAPI.Run(pass.Files, pass.Fset, &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 { - text := fmt.Sprintf("string %s has %d occurrences", internal.FormatCode(i.Str, nil), i.OccurrencesCount) - - if i.MatchingConst == "" { - text += ", make it a constant" - } else { - text += fmt.Sprintf(", but such constant %s already exists", internal.FormatCode(i.MatchingConst, nil)) - } - - res = append(res, goanalysis.NewIssue(&result.Issue{ - Pos: i.Pos, - Text: text, - FromLinter: linterName, - }, pass)) - } - - return res, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocritic/gocritic.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocritic/gocritic.go deleted file mode 100644 index 68cc338e4..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocritic/gocritic.go +++ /dev/null @@ -1,590 +0,0 @@ -package gocritic - -import ( - "errors" - "fmt" - "go/ast" - "go/types" - "path/filepath" - "reflect" - "runtime" - "sort" - "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/exp/maps" - "golang.org/x/exp/slices" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "gocritic" - -var ( - debugf = logutils.Debug(logutils.DebugKeyGoCritic) - isDebug = logutils.HaveDebugTag(logutils.DebugKeyGoCritic) -) - -func New(settings *config.GoCriticSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - wrapper := &goCriticWrapper{ - sizes: types.SizesFor("gc", runtime.GOARCH), - } - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues, err := wrapper.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 - }, - } - - return goanalysis.NewLinter( - linterName, - `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.`, - []*analysis.Analyzer{analyzer}, - nil, - ). - WithContextSetter(func(context *linter.Context) { - wrapper.configDir = context.Cfg.GetConfigDir() - - wrapper.init(context.Log, settings) - }). - WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -type goCriticWrapper struct { - settingsWrapper *settingsWrapper - configDir string - sizes types.Sizes - once sync.Once -} - -func (w *goCriticWrapper) init(logger logutils.Log, settings *config.GoCriticSettings) { - 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(settings, logger) - settingsWrapper.InferEnabledChecks() - // Validate must be after InferEnabledChecks, not before. - // Because it uses gathered information about tags set and finally enabled checks. - if err := settingsWrapper.Validate(); err != nil { - logger.Fatalf("%s: invalid settings: %s", linterName, err) - } - - w.settingsWrapper = settingsWrapper -} - -func (w *goCriticWrapper) run(pass *analysis.Pass) ([]goanalysis.Issue, error) { - if w.settingsWrapper == nil { - return nil, 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 nil, err - } - - linterCtx.SetPackageInfo(pass.TypesInfo, pass.Pkg) - - pkgIssues := runOnPackage(linterCtx, enabledCheckers, pass.Files) - - issues := make([]goanalysis.Issue, 0, len(pkgIssues)) - for i := range pkgIssues { - issues = append(issues, goanalysis.NewIssue(&pkgIssues[i], pass)) - } - - return issues, 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 - } - - if err := w.configureCheckerInfo(info, allLowerCasedParams); 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 (w *goCriticWrapper) configureCheckerInfo( - 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 = w.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) - } - - supportedKeys := maps.Keys(info.Params) - sort.Strings(supportedKeys) - - return fmt.Errorf("checker %s config param %s doesn't exist, all existing: %s", - info.Name, k, supportedKeys) - } - - return nil -} - -// 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 (w *goCriticWrapper) 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 strings.ReplaceAll(rv.String(), "${configDir}", w.configDir) - default: - return p - } -} - -func runOnPackage(linterCtx *gocriticlinter.Context, checks []*gocriticlinter.Checker, files []*ast.File) []result.Issue { - var res []result.Issue - for _, f := range files { - filename := filepath.Base(linterCtx.FileSet.Position(f.Pos()).Filename) - linterCtx.SetFileInfo(filename, f) - - issues := runOnFile(linterCtx, f, checks) - res = append(res, issues...) - } - return res -} - -func runOnFile(linterCtx *gocriticlinter.Context, f *ast.File, checks []*gocriticlinter.Checker) []result.Issue { - var res []result.Issue - - 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) { - pos := linterCtx.FileSet.Position(warn.Pos) - issue := result.Issue{ - Pos: pos, - Text: fmt.Sprintf("%s: %s", c.Info.Name, warn.Text), - FromLinter: linterName, - } - - if warn.HasQuickFix() { - issue.Replacement = &result.Replacement{ - Inline: &result.InlineFix{ - StartCol: pos.Column - 1, - Length: int(warn.Suggestion.To - warn.Suggestion.From), - NewString: string(warn.Suggestion.Replacement), - }, - } - } - - res = append(res, issue) - } - } - - return res -} - -type goCriticChecks[T any] map[string]T - -func (m goCriticChecks[T]) has(name string) bool { - _, ok := m[name] - return ok -} - -type settingsWrapper struct { - *config.GoCriticSettings - - 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(settings *config.GoCriticSettings, logger logutils.Log) *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) - } - } - - allTagsSorted := maps.Keys(allChecksByTag) - sort.Strings(allTagsSorted) - - return &settingsWrapper{ - GoCriticSettings: settings, - logger: logger, - allCheckers: allCheckers, - allChecks: allChecks, - allChecksLowerCased: allChecksLowerCased, - allChecksByTag: allChecksByTag, - allTagsSorted: allTagsSorted, - inferredEnabledChecks: make(goCriticChecks[struct{}]), - 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) -} - -// InferEnabledChecks tries to be consistent with (lintersdb.Manager).build. -func (s *settingsWrapper) InferEnabledChecks() { - s.debugChecksInitialState() - - enabledByDefaultChecks, disabledByDefaultChecks := s.buildEnabledAndDisabledByDefaultChecks() - debugChecksListf(enabledByDefaultChecks, "Enabled by default") - debugChecksListf(disabledByDefaultChecks, "Disabled by default") - - enabledChecks := make(goCriticChecks[struct{}]) - - if s.EnableAll { - enabledChecks = make(goCriticChecks[struct{}], len(s.allCheckers)) - for _, info := range s.allCheckers { - enabledChecks[info.Name] = struct{}{} - } - } else if !s.DisableAll { - // enable-all/disable-all revokes the default settings. - 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", sprintSortedStrings(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", sprintSortedStrings(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 enabledByDef := isEnabledByDefaultGoCriticChecker(info); enabledByDef { - 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) 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 { - check := checker.Name - if s.inferredEnabledChecks.has(check) { - enabledChecks = append(enabledChecks, check) - } else { - disabledChecks = append(disabledChecks, check) - } - } - - debugChecksListf(enabledChecks, "Final used") - - if len(disabledChecks) == 0 { - debugf("All checks are enabled") - } else { - debugChecksListf(disabledChecks, "Final not used") - } -} - -// 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 { - if s.DisableAll { - return errors.New("enable-all and disable-all options must not be combined") - } - - 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") - } - } - - if 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 -} - -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) -} - -func debugChecksListf(checks []string, format string, args ...any) { - if !isDebug { - return - } - - debugf("%s checks (%d): %s", fmt.Sprintf(format, args...), len(checks), sprintSortedStrings(checks)) -} - -func sprintSortedStrings(v []string) string { - sort.Strings(slices.Clone(v)) - return fmt.Sprint(v) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocyclo/gocyclo.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocyclo/gocyclo.go deleted file mode 100644 index 51333dc15..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gocyclo/gocyclo.go +++ /dev/null @@ -1,76 +0,0 @@ -package gocyclo - -import ( - "fmt" - "sync" - - "github.com/fzipp/gocyclo" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "gocyclo" - -func New(settings *config.GoCycloSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - 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 - }, - } - - return goanalysis.NewLinter( - linterName, - "Computes and checks the cyclomatic complexity of functions", - []*analysis.Analyzer{analyzer}, - 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, nil), 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/pkg/golinters/godot/godot.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/godot/godot.go deleted file mode 100644 index fc51b5bb8..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/godot/godot.go +++ /dev/null @@ -1,101 +0,0 @@ -package godot - -import ( - "sync" - - "github.com/tetafro/godot" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "godot" - -func New(settings *config.GodotSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - var dotSettings godot.Settings - - if settings != nil { - dotSettings = godot.Settings{ - Scope: godot.Scope(settings.Scope), - Exclude: settings.Exclude, - Period: settings.Period, - Capital: settings.Capital, - } - - // Convert deprecated setting - if settings.CheckAll { - dotSettings.Scope = godot.AllScope - } - } - - if dotSettings.Scope == "" { - dotSettings.Scope = godot.DeclScope - } - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues, err := runGodot(pass, dotSettings) - if err != nil { - return nil, err - } - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - } - - return goanalysis.NewLinter( - linterName, - "Check if comments end in a period", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runGodot(pass *analysis.Pass, settings godot.Settings) ([]goanalysis.Issue, error) { - var lintIssues []godot.Issue - for _, file := range pass.Files { - iss, err := godot.Run(file, pass.Fset, settings) - if err != nil { - return nil, err - } - lintIssues = append(lintIssues, iss...) - } - - if len(lintIssues) == 0 { - return nil, nil - } - - issues := make([]goanalysis.Issue, len(lintIssues)) - for k, i := range lintIssues { - issue := result.Issue{ - Pos: i.Pos, - Text: i.Message, - FromLinter: linterName, - Replacement: &result.Replacement{ - NewLines: []string{i.Replacement}, - }, - } - - issues[k] = goanalysis.NewIssue(&issue, pass) - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/godox/godox.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/godox/godox.go deleted file mode 100644 index d8de026ba..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/godox/godox.go +++ /dev/null @@ -1,75 +0,0 @@ -package godox - -import ( - "go/token" - "strings" - "sync" - - "github.com/matoous/godox" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "godox" - -func New(settings *config.GodoxSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues := runGodox(pass, settings) - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - } - - return goanalysis.NewLinter( - linterName, - "Tool for detection of FIXME, TODO and other comment keywords", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runGodox(pass *analysis.Pass, settings *config.GodoxSettings) []goanalysis.Issue { - var messages []godox.Message - for _, file := range pass.Files { - messages = append(messages, godox.Run(file, pass.Fset, settings.Keywords...)...) - } - - if len(messages) == 0 { - return nil - } - - issues := make([]goanalysis.Issue, len(messages)) - - for k, i := range messages { - issues[k] = goanalysis.NewIssue(&result.Issue{ - Pos: token.Position{ - Filename: i.Pos.Filename, - Line: i.Pos.Line, - }, - Text: strings.TrimRight(i.Message, "\n"), - FromLinter: linterName, - }, pass) - } - - return issues -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gofmt/gofmt.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gofmt/gofmt.go deleted file mode 100644 index 289ceab8a..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gofmt/gofmt.go +++ /dev/null @@ -1,98 +0,0 @@ -package gofmt - -import ( - "fmt" - "sync" - - gofmtAPI "github.com/golangci/gofmt/gofmt" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" -) - -const linterName = "gofmt" - -func New(settings *config.GoFmtSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: goanalysis.DummyRun, - } - - return goanalysis.NewLinter( - linterName, - "Gofmt checks whether code was gofmt-ed. By default "+ - "this tool runs with -s option to check for code simplification", - []*analysis.Analyzer{analyzer}, - nil, - ).WithContextSetter(func(lintCtx *linter.Context) { - analyzer.Run = func(pass *analysis.Pass) (any, error) { - issues, err := runGofmt(lintCtx, 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 runGofmt(lintCtx *linter.Context, pass *analysis.Pass, settings *config.GoFmtSettings) ([]goanalysis.Issue, error) { - fileNames := internal.GetFileNames(pass) - - var rewriteRules []gofmtAPI.RewriteRule - for _, rule := range settings.RewriteRules { - rewriteRules = append(rewriteRules, gofmtAPI.RewriteRule(rule)) - } - - var issues []goanalysis.Issue - - for _, f := range fileNames { - diff, err := gofmtAPI.RunRewrite(f, settings.Simplify, rewriteRules) - if err != nil { // TODO: skip - return nil, err - } - if diff == nil { - continue - } - - is, err := internal.ExtractIssuesFromPatch(string(diff), lintCtx, linterName, getIssuedTextGoFmt) - if err != nil { - return nil, fmt.Errorf("can't extract issues from gofmt diff output %q: %w", string(diff), err) - } - - for i := range is { - issues = append(issues, goanalysis.NewIssue(&is[i], pass)) - } - } - - return issues, nil -} - -func getIssuedTextGoFmt(settings *config.LintersSettings) string { - text := "File is not `gofmt`-ed" - if settings.Gofmt.Simplify { - text += " with `-s`" - } - for _, rule := range settings.Gofmt.RewriteRules { - text += fmt.Sprintf(" `-r '%s -> %s'`", rule.Pattern, rule.Replacement) - } - - return text -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gofumpt/gofumpt.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gofumpt/gofumpt.go deleted file mode 100644 index 3bb7df12e..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gofumpt/gofumpt.go +++ /dev/null @@ -1,132 +0,0 @@ -package gofumpt - -import ( - "bytes" - "fmt" - "io" - "os" - "strings" - "sync" - - "github.com/shazow/go-diff/difflib" - "golang.org/x/tools/go/analysis" - "mvdan.cc/gofumpt/format" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" -) - -const linterName = "gofumpt" - -type differ interface { - Diff(out io.Writer, a io.ReadSeeker, b io.ReadSeeker) error -} - -func New(settings *config.GofumptSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - diff := difflib.New() - - var options format.Options - - if settings != nil { - options = format.Options{ - LangVersion: getLangVersion(settings), - ModulePath: settings.ModulePath, - ExtraRules: settings.ExtraRules, - } - } - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: goanalysis.DummyRun, - } - - return goanalysis.NewLinter( - linterName, - "Gofumpt checks whether code was gofumpt-ed.", - []*analysis.Analyzer{analyzer}, - nil, - ).WithContextSetter(func(lintCtx *linter.Context) { - analyzer.Run = func(pass *analysis.Pass) (any, error) { - issues, err := runGofumpt(lintCtx, pass, diff, options) - 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 runGofumpt(lintCtx *linter.Context, pass *analysis.Pass, diff differ, options format.Options) ([]goanalysis.Issue, error) { - fileNames := internal.GetFileNames(pass) - - var issues []goanalysis.Issue - - for _, f := range fileNames { - input, err := os.ReadFile(f) - if err != nil { - return nil, fmt.Errorf("unable to open file %s: %w", f, err) - } - - output, err := format.Source(input, options) - if err != nil { - return nil, fmt.Errorf("error while running gofumpt: %w", err) - } - - if !bytes.Equal(input, output) { - out := bytes.NewBufferString(fmt.Sprintf("--- %[1]s\n+++ %[1]s\n", f)) - - err := diff.Diff(out, bytes.NewReader(input), bytes.NewReader(output)) - if err != nil { - return nil, fmt.Errorf("error while running gofumpt: %w", err) - } - - diff := out.String() - is, err := internal.ExtractIssuesFromPatch(diff, lintCtx, linterName, getIssuedTextGoFumpt) - if err != nil { - return nil, fmt.Errorf("can't extract issues from gofumpt diff output %q: %w", diff, err) - } - - for i := range is { - issues = append(issues, goanalysis.NewIssue(&is[i], pass)) - } - } - } - - return issues, nil -} - -func getLangVersion(settings *config.GofumptSettings) string { - if settings == nil || settings.LangVersion == "" { - // TODO: defaults to "1.15", in the future (v2) must be removed. - return "go1.15" - } - - return "go" + strings.TrimPrefix(settings.LangVersion, "go") -} - -func getIssuedTextGoFumpt(settings *config.LintersSettings) string { - text := "File is not `gofumpt`-ed" - - if settings.Gofumpt.ExtraRules { - text += " with `-extra`" - } - - return text -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goheader/goheader.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/goheader/goheader.go deleted file mode 100644 index 14d517fb3..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goheader/goheader.go +++ /dev/null @@ -1,115 +0,0 @@ -package goheader - -import ( - "go/token" - "sync" - - goheader "github.com/denis-tingaikin/go-header" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "goheader" - -func New(settings *config.GoHeaderSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - conf := &goheader.Configuration{} - if settings != nil { - conf = &goheader.Configuration{ - Values: settings.Values, - Template: settings.Template, - TemplatePath: settings.TemplatePath, - } - } - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues, err := runGoHeader(pass, conf) - if err != nil { - return nil, err - } - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - } - - return goanalysis.NewLinter( - linterName, - "Checks is file header matches to pattern", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runGoHeader(pass *analysis.Pass, conf *goheader.Configuration) ([]goanalysis.Issue, error) { - if conf.TemplatePath == "" && conf.Template == "" { - // User did not pass template, so then do not run go-header linter - return nil, nil - } - - template, err := conf.GetTemplate() - if err != nil { - return nil, err - } - - values, err := conf.GetValues() - if err != nil { - return nil, err - } - - a := goheader.New(goheader.WithTemplate(template), goheader.WithValues(values)) - - var issues []goanalysis.Issue - for _, file := range pass.Files { - path := pass.Fset.Position(file.Pos()).Filename - - i := a.Analyze(&goheader.Target{File: file, Path: path}) - - if i == nil { - continue - } - - issue := result.Issue{ - Pos: token.Position{ - Line: i.Location().Line + 1, - Column: i.Location().Position, - Filename: path, - }, - Text: i.Message(), - FromLinter: linterName, - } - - if fix := i.Fix(); fix != nil { - issue.LineRange = &result.Range{ - From: issue.Line(), - To: issue.Line() + len(fix.Actual) - 1, - } - issue.Replacement = &result.Replacement{ - NeedOnlyDelete: len(fix.Expected) == 0, - NewLines: fix.Expected, - } - } - - issues = append(issues, goanalysis.NewIssue(&issue, pass)) - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goimports/goimports.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/goimports/goimports.go deleted file mode 100644 index de965d5c8..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goimports/goimports.go +++ /dev/null @@ -1,94 +0,0 @@ -package goimports - -import ( - "fmt" - "sync" - - goimportsAPI "github.com/golangci/gofmt/goimports" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/imports" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" -) - -const linterName = "goimports" - -func New(settings *config.GoImportsSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: goanalysis.DummyRun, - } - - return goanalysis.NewLinter( - linterName, - "Check import statements are formatted according to the 'goimport' command. "+ - "Reformat imports in autofix mode.", - []*analysis.Analyzer{analyzer}, - nil, - ).WithContextSetter(func(lintCtx *linter.Context) { - imports.LocalPrefix = settings.LocalPrefixes - - analyzer.Run = func(pass *analysis.Pass) (any, error) { - issues, err := runGoImports(lintCtx, 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) -} - -func runGoImports(lintCtx *linter.Context, pass *analysis.Pass) ([]goanalysis.Issue, error) { - fileNames := internal.GetFileNames(pass) - - var issues []goanalysis.Issue - - for _, f := range fileNames { - diff, err := goimportsAPI.Run(f) - if err != nil { // TODO: skip - return nil, err - } - if diff == nil { - continue - } - - is, err := internal.ExtractIssuesFromPatch(string(diff), lintCtx, linterName, getIssuedTextGoImports) - if err != nil { - return nil, fmt.Errorf("can't extract issues from gofmt diff output %q: %w", string(diff), err) - } - - for i := range is { - issues = append(issues, goanalysis.NewIssue(&is[i], pass)) - } - } - - return issues, nil -} - -func getIssuedTextGoImports(settings *config.LintersSettings) string { - text := "File is not `goimports`-ed" - - if settings.Goimports.LocalPrefixes != "" { - text += " with -local " + settings.Goimports.LocalPrefixes - } - - return text -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gomoddirectives/gomoddirectives.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gomoddirectives/gomoddirectives.go deleted file mode 100644 index 9cde7e26c..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gomoddirectives/gomoddirectives.go +++ /dev/null @@ -1,64 +0,0 @@ -package gomoddirectives - -import ( - "sync" - - "github.com/ldez/gomoddirectives" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/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 - } - - analyzer := &analysis.Analyzer{ - Name: goanalysis.TheOnlyAnalyzerName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: goanalysis.DummyRun, - } - - return goanalysis.NewLinter( - linterName, - "Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod.", - []*analysis.Analyzer{analyzer}, - nil, - ).WithContextSetter(func(lintCtx *linter.Context) { - analyzer.Run = func(pass *analysis.Pass) (any, error) { - once.Do(func() { - results, err := gomoddirectives.Analyze(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/pkg/golinters/gomodguard/gomodguard.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gomodguard/gomodguard.go deleted file mode 100644 index 8f1036b0f..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gomodguard/gomodguard.go +++ /dev/null @@ -1,94 +0,0 @@ -package gomodguard - -import ( - "sync" - - "github.com/ryancurrah/gomodguard" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const ( - name = "gomodguard" - desc = "Allow and block list linter for direct Go module dependencies. " + - "This is different from depguard where there are different block " + - "types for example version constraints and module recommendations." -) - -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: goanalysis.TheOnlyAnalyzerName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: goanalysis.DummyRun, - } - - return goanalysis.NewLinter( - name, - desc, - []*analysis.Analyzer{analyzer}, - nil, - ).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.GetFileNames(pass)) - - mu.Lock() - defer mu.Unlock() - - for _, gomodguardIssue := range gomodguardIssues { - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - FromLinter: name, - 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/pkg/golinters/goprintffuncname/goprintffuncname.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/goprintffuncname/goprintffuncname.go deleted file mode 100644 index 85154a9b3..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/goprintffuncname/goprintffuncname.go +++ /dev/null @@ -1,19 +0,0 @@ -package goprintffuncname - -import ( - "github.com/jirfag/go-printf-func-name/pkg/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := analyzer.Analyzer - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosec/gosec.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosec/gosec.go deleted file mode 100644 index a5367399b..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosec/gosec.go +++ /dev/null @@ -1,247 +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/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/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: goanalysis.TheOnlyanalyzerDoc, - Run: goanalysis.DummyRun, - } - - return goanalysis.NewLinter( - linterName, - "Inspects source code for security problems", - []*analysis.Analyzer{analyzer}, - nil, - ).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, settings.ExcludeGenerated, 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 { - conf.SetGlobal(gosec.GlobalOption(k), 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/pkg/golinters/gosimple/gosimple.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosimple/gosimple.go deleted file mode 100644 index c03871adf..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosimple/gosimple.go +++ /dev/null @@ -1,22 +0,0 @@ -package gosimple - -import ( - "honnef.co/go/tools/simple" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" -) - -func New(settings *config.StaticCheckSettings) *goanalysis.Linter { - cfg := internal.StaticCheckConfig(settings) - - analyzers := internal.SetupStaticCheckAnalyzers(simple.Analyzers, cfg.Checks) - - return goanalysis.NewLinter( - "gosimple", - "Linter for Go source code that specializes in simplifying code", - analyzers, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosmopolitan/gosmopolitan.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosmopolitan/gosmopolitan.go deleted file mode 100644 index 4f6fb8035..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/gosmopolitan/gosmopolitan.go +++ /dev/null @@ -1,32 +0,0 @@ -package gosmopolitan - -import ( - "strings" - - "github.com/xen0n/gosmopolitan" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(s *config.GosmopolitanSettings) *goanalysis.Linter { - a := gosmopolitan.NewAnalyzer() - - cfgMap := map[string]map[string]any{} - if s != nil { - cfgMap[a.Name] = map[string]any{ - "allowtimelocal": s.AllowTimeLocal, - "escapehatches": strings.Join(s.EscapeHatches, ","), - "lookattests": !s.IgnoreTests, - "watchforscripts": strings.Join(s.WatchForScripts, ","), - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfgMap, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/govet/govet.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/govet/govet.go deleted file mode 100644 index eb63a5d33..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/govet/govet.go +++ /dev/null @@ -1,223 +0,0 @@ -package govet - -import ( - "slices" - "sort" - - "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/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/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" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/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, - 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, - stringintconv.Analyzer, - structtag.Analyzer, - testinggoroutine.Analyzer, - tests.Analyzer, - timeformat.Analyzer, - unmarshal.Analyzer, - unreachable.Analyzer, - unsafeptr.Analyzer, - unusedresult.Analyzer, - unusedwrite.Analyzer, - } - - // https://github.com/golang/go/blob/b56645a87b28840a180d64077877cb46570b4176/src/cmd/vet/main.go#L49-L81 - 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, - httpresponse.Analyzer, - ifaceassert.Analyzer, - loopclosure.Analyzer, - lostcancel.Analyzer, - nilfunc.Analyzer, - printf.Analyzer, - shift.Analyzer, - sigchanyzer.Analyzer, - slog.Analyzer, - stdmethods.Analyzer, - stringintconv.Analyzer, - structtag.Analyzer, - testinggoroutine.Analyzer, - tests.Analyzer, - timeformat.Analyzer, - unmarshal.Analyzer, - unreachable.Analyzer, - unsafeptr.Analyzer, - unusedresult.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 { - debugAnalyzersListf(allAnalyzers, "All available analyzers") - debugAnalyzersListf(defaultAnalyzers, "Default analyzers") - - if settings == nil { - return defaultAnalyzers - } - - var enabledAnalyzers []*analysis.Analyzer - for _, a := range allAnalyzers { - if isAnalyzerEnabled(a.Name, settings, defaultAnalyzers) { - enabledAnalyzers = append(enabledAnalyzers, a) - } - } - - debugAnalyzersListf(enabledAnalyzers, "Enabled by config analyzers") - - 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 - } - - // Keeping for backward compatibility. - if cfg.CheckShadowing && name == shadow.Analyzer.Name { - return true - } - - 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 debugAnalyzersListf(analyzers []*analysis.Analyzer, message string) { - if !isDebug { - return - } - - analyzerNames := make([]string, 0, len(analyzers)) - for _, a := range analyzers { - analyzerNames = append(analyzerNames, a.Name) - } - - sort.Strings(analyzerNames) - - debugf("%s (%d): %s", message, len(analyzerNames), analyzerNames) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/grouper/grouper.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/grouper/grouper.go deleted file mode 100644 index aa6ce1ceb..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/grouper/grouper.go +++ /dev/null @@ -1,34 +0,0 @@ -package grouper - -import ( - grouper "github.com/leonklingele/grouper/pkg/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.GrouperSettings) *goanalysis.Linter { - a := grouper.New() - - linterCfg := map[string]map[string]any{} - if settings != nil { - linterCfg[a.Name] = 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.NewLinter( - a.Name, - "Analyze expression groups.", - []*analysis.Analyzer{a}, - linterCfg, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/importas/importas.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/importas/importas.go deleted file mode 100644 index 45117c9a4..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/importas/importas.go +++ /dev/null @@ -1,67 +0,0 @@ -package importas - -import ( - "fmt" - "strconv" - "strings" - - "github.com/julz/importas" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" -) - -func New(settings *config.ImportAsSettings) *goanalysis.Linter { - analyzer := importas.Analyzer - - return goanalysis.NewLinter( - analyzer.Name, - analyzer.Doc, - []*analysis.Analyzer{analyzer}, - nil, - ).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 - } - - // skip the duplication check when the alias is a regular expression replacement pattern (ie. contains `$`). - if v, ok := uniqAliases[a.Alias]; ok && !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/pkg/golinters/inamedparam/inamedparam.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/inamedparam/inamedparam.go deleted file mode 100644 index 5cf06a08c..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/inamedparam/inamedparam.go +++ /dev/null @@ -1,30 +0,0 @@ -package inamedparam - -import ( - "github.com/macabu/inamedparam" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.INamedParamSettings) *goanalysis.Linter { - a := inamedparam.Analyzer - - var cfg map[string]map[string]any - - if settings != nil { - cfg = map[string]map[string]any{ - a.Name: { - "skip-single-param": settings.SkipSingleParam, - }, - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ineffassign/ineffassign.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/ineffassign/ineffassign.go deleted file mode 100644 index ba86fb90e..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ineffassign/ineffassign.go +++ /dev/null @@ -1,19 +0,0 @@ -package ineffassign - -import ( - "github.com/gordonklaus/ineffassign/pkg/ineffassign" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := ineffassign.Analyzer - - return goanalysis.NewLinter( - a.Name, - "Detects when assignments to existing variables are not used", - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/interfacebloat/interfacebloat.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/interfacebloat/interfacebloat.go deleted file mode 100644 index 88927a3d9..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/interfacebloat/interfacebloat.go +++ /dev/null @@ -1,29 +0,0 @@ -package interfacebloat - -import ( - "github.com/sashamelentyev/interfacebloat/pkg/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.InterfaceBloatSettings) *goanalysis.Linter { - a := analyzer.New() - - var cfg map[string]map[string]any - if settings != nil { - cfg = map[string]map[string]any{ - a.Name: { - analyzer.InterfaceMaxMethodsFlag: settings.Max, - }, - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/commons.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/commons.go deleted file mode 100644 index c21dd0092..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/commons.go +++ /dev/null @@ -1,6 +0,0 @@ -package internal - -import "github.com/golangci/golangci-lint/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/pkg/golinters/internal/diff.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/diff.go deleted file mode 100644 index f919c5b2a..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/diff.go +++ /dev/null @@ -1,264 +0,0 @@ -package internal - -import ( - "bytes" - "fmt" - "go/token" - "strings" - - diffpkg "github.com/sourcegraph/go-diff/diff" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -type Change struct { - LineRange result.Range - Replacement result.Replacement -} - -type diffLineType string - -const ( - diffLineAdded diffLineType = "added" - diffLineOriginal diffLineType = "original" - diffLineDeleted diffLineType = "deleted" -) - -type fmtTextFormatter func(settings *config.LintersSettings) string - -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 - - lines []diffLine - - ret []Change -} - -func (p *hunkChangesParser) parseDiffLines(h *diffpkg.Hunk) { - lines := bytes.Split(h.Body, []byte{'\n'}) - currentOriginalLineNumber := int(h.OrigStartLine) - var ret []diffLine - - for i, line := range lines { - dl := diffLine{ - originalNumber: currentOriginalLineNumber, - } - - lineStr := string(line) - - if strings.HasPrefix(lineStr, "-") { - dl.typ = diffLineDeleted - dl.data = strings.TrimPrefix(lineStr, "-") - currentOriginalLineNumber++ - } else if strings.HasPrefix(lineStr, "+") { - dl.typ = diffLineAdded - dl.data = strings.TrimPrefix(lineStr, "+") - } else { - if i == len(lines)-1 && lineStr == "" { - // handle last \n: don't add an empty original line - break - } - - dl.typ = diffLineOriginal - dl.data = strings.TrimPrefix(lineStr, " ") - currentOriginalLineNumber++ - } - - ret = append(ret, 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: "", - } - ret = append(ret, dl) - } - - p.lines = ret -} - -func (p *hunkChangesParser) handleOriginalLine(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(p.lines) && p.lines[*i].typ == diffLineAdded; *i++ { - followingAddedLines = append(followingAddedLines, p.lines[*i].data) - } - - p.ret = append(p.ret, Change{ - LineRange: result.Range{ - From: line.originalNumber, - To: line.originalNumber, - }, - Replacement: result.Replacement{ - NewLines: append(p.replacementLinesToPrepend, append([]string{line.data}, followingAddedLines...)...), - }, - }) - p.replacementLinesToPrepend = nil - p.lastOriginalLine = &line -} - -func (p *hunkChangesParser) handleDeletedLines(deletedLines []diffLine, addedLines []string) { - change := Change{ - LineRange: result.Range{ - From: deletedLines[0].originalNumber, - To: deletedLines[len(deletedLines)-1].originalNumber, - }, - } - - if len(addedLines) != 0 { - change.Replacement.NewLines = append([]string{}, p.replacementLinesToPrepend...) - change.Replacement.NewLines = append(change.Replacement.NewLines, addedLines...) - if len(p.replacementLinesToPrepend) != 0 { - p.replacementLinesToPrepend = nil - } - - p.ret = append(p.ret, change) - return - } - - // delete-only change with possible prepending - if len(p.replacementLinesToPrepend) != 0 { - change.Replacement.NewLines = p.replacementLinesToPrepend - p.replacementLinesToPrepend = nil - } else { - change.Replacement.NeedOnlyDelete = true - } - - p.ret = append(p.ret, 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 - p.ret = append(p.ret, Change{ - LineRange: result.Range{ - From: p.lastOriginalLine.originalNumber, - To: p.lastOriginalLine.originalNumber, - }, - Replacement: result.Replacement{ - NewLines: append(p.replacementLinesToPrepend, append([]string{p.lastOriginalLine.data}, addedLines...)...), - }, - }) - p.replacementLinesToPrepend = nil -} - -func (p *hunkChangesParser) parse(h *diffpkg.Hunk) []Change { - p.parseDiffLines(h) - - for i := 0; i < len(p.lines); { - line := p.lines[i] - if line.typ == diffLineOriginal { - p.handleOriginalLine(line, &i) - continue - } - - var deletedLines []diffLine - for ; i < len(p.lines) && p.lines[i].typ == diffLineDeleted; i++ { - deletedLines = append(deletedLines, p.lines[i]) - } - - var addedLines []string - for ; i < len(p.lines) && p.lines[i].typ == diffLineAdded; i++ { - addedLines = append(addedLines, p.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", p.lines) - return nil - } - - return p.ret -} - -func ExtractIssuesFromPatch(patch string, lintCtx *linter.Context, linterName string, formatter fmtTextFormatter) ([]result.Issue, error) { - diffs, err := diffpkg.ParseMultiFileDiff([]byte(patch)) - if err != nil { - return nil, fmt.Errorf("can't parse patch: %w", err) - } - - if len(diffs) == 0 { - return nil, fmt.Errorf("got no diffs from patch parser: %v", patch) - } - - var issues []result.Issue - for _, d := range diffs { - if len(d.Hunks) == 0 { - lintCtx.Log.Warnf("Got no hunks in diff %+v", d) - continue - } - - for _, hunk := range d.Hunks { - p := hunkChangesParser{log: lintCtx.Log} - - changes := p.parse(hunk) - - for _, change := range changes { - i := result.Issue{ - FromLinter: linterName, - Pos: token.Position{ - Filename: d.NewName, - Line: change.LineRange.From, - }, - Text: formatter(lintCtx.Settings()), - Replacement: &change.Replacement, - } - if change.LineRange.From != change.LineRange.To { - i.LineRange = &change.LineRange - } - - issues = append(issues, i) - } - } - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/staticcheck_common.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/staticcheck_common.go deleted file mode 100644 index 958013d0d..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/staticcheck_common.go +++ /dev/null @@ -1,154 +0,0 @@ -package internal - -import ( - "strings" - "unicode" - - "golang.org/x/tools/go/analysis" - "honnef.co/go/tools/analysis/lint" - scconfig "honnef.co/go/tools/config" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/logutils" -) - -var debugf = logutils.Debug(logutils.DebugKeyMegacheck) - -func SetupStaticCheckAnalyzers(src []*lint.Analyzer, checks []string) []*analysis.Analyzer { - var names []string - for _, a := range src { - names = append(names, a.Analyzer.Name) - } - - filter := filterAnalyzerNames(names, checks) - - var ret []*analysis.Analyzer - for _, a := range src { - if filter[a.Analyzer.Name] { - ret = append(ret, a.Analyzer) - } - } - - return ret -} - -func SetAnalyzerGoVersion(a *analysis.Analyzer, goVersion string) { - if v := a.Flags.Lookup("go"); v != nil { - if err := v.Value.Set(goVersion); err != nil { - debugf("Failed to set go version: %s", err) - } - } -} - -func StaticCheckConfig(settings *config.StaticCheckSettings) *scconfig.Config { - var cfg *scconfig.Config - - if settings == nil || !settings.HasConfiguration() { - return &scconfig.Config{ - Checks: []string{"*"}, // override for compatibility reason. Must drop in the next major version. - 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 len(cfg.Checks) == 0 { - cfg.Checks = append(cfg.Checks, "*") // override for compatibility reason. Must drop in the next major version. - } - - if len(cfg.Initialisms) == 0 { - cfg.Initialisms = append(cfg.Initialisms, scconfig.DefaultConfig.Initialisms...) - } - - if len(cfg.DotImportWhitelist) == 0 { - cfg.DotImportWhitelist = append(cfg.DotImportWhitelist, scconfig.DefaultConfig.DotImportWhitelist...) - } - - if len(cfg.HTTPStatusCodeWhitelist) == 0 { - 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/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 -} - -// 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 -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/util.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/util.go deleted file mode 100644 index 80b194dd2..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/internal/util.go +++ /dev/null @@ -1,33 +0,0 @@ -package internal - -import ( - "fmt" - "path/filepath" - "strings" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" -) - -func FormatCode(code string, _ *config.Config) string { - if strings.Contains(code, "`") { - return code // TODO: properly escape or remove - } - - return fmt.Sprintf("`%s`", code) -} - -func GetFileNames(pass *analysis.Pass) []string { - var fileNames []string - for _, f := range pass.Files { - fileName := pass.Fset.PositionFor(f.Pos(), true).Filename - ext := filepath.Ext(fileName) - if ext != "" && ext != ".go" { - // position has been adjusted to a non-go file, revert to original file - fileName = pass.Fset.PositionFor(f.Pos(), false).Filename - } - fileNames = append(fileNames, fileName) - } - return fileNames -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/intrange/intrange.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/intrange/intrange.go deleted file mode 100644 index d5ffd4345..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/intrange/intrange.go +++ /dev/null @@ -1,19 +0,0 @@ -package intrange - -import ( - "github.com/ckaznocha/intrange" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := intrange.Analyzer - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ireturn/ireturn.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/ireturn/ireturn.go deleted file mode 100644 index 57de57111..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/ireturn/ireturn.go +++ /dev/null @@ -1,31 +0,0 @@ -package ireturn - -import ( - "strings" - - "github.com/butuzov/ireturn/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.IreturnSettings) *goanalysis.Linter { - a := analyzer.NewAnalyzer() - - cfg := map[string]map[string]any{} - if settings != nil { - cfg[a.Name] = map[string]any{ - "allow": strings.Join(settings.Allow, ","), - "reject": strings.Join(settings.Reject, ","), - "nonolint": true, - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/lll/lll.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/lll/lll.go deleted file mode 100644 index 67f89eecb..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/lll/lll.go +++ /dev/null @@ -1,157 +0,0 @@ -package lll - -import ( - "bufio" - "errors" - "fmt" - "go/token" - "os" - "strings" - "sync" - "unicode/utf8" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "lll" - -const goCommentDirectivePrefix = "//go:" - -func New(settings *config.LllSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues, err := runLll(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 - }, - } - - return goanalysis.NewLinter( - linterName, - "Reports long lines", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runLll(pass *analysis.Pass, settings *config.LllSettings) ([]goanalysis.Issue, error) { - fileNames := internal.GetFileNames(pass) - - spaces := strings.Repeat(" ", settings.TabWidth) - - var issues []goanalysis.Issue - for _, f := range fileNames { - lintIssues, err := getLLLIssuesForFile(f, settings.LineLength, spaces) - if err != nil { - return nil, err - } - - for i := range lintIssues { - issues = append(issues, goanalysis.NewIssue(&lintIssues[i], pass)) - } - } - - return issues, nil -} - -func getLLLIssuesForFile(filename string, maxLineLen int, tabSpaces string) ([]result.Issue, error) { - var res []result.Issue - - f, err := os.Open(filename) - if err != nil { - return nil, fmt.Errorf("can't open file %s: %w", filename, err) - } - defer f.Close() - - 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 { - res = append(res, result.Issue{ - Pos: token.Position{ - Filename: filename, - Line: lineNumber, - }, - Text: fmt.Sprintf("the line is %d characters long, which exceeds the maximum of %d characters.", lineLen, maxLineLen), - FromLinter: linterName, - }) - } - } - - if err := scanner.Err(); err != nil { - if errors.Is(err, bufio.ErrTooLong) && maxLineLen < bufio.MaxScanTokenSize { - // 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. - res = append(res, result.Issue{ - Pos: token.Position{ - Filename: filename, - Line: lineNumber, - Column: 1, - }, - Text: fmt.Sprintf("line is more than %d characters", bufio.MaxScanTokenSize), - FromLinter: linterName, - }) - } else { - return nil, fmt.Errorf("can't scan file %s: %w", filename, err) - } - } - - return res, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/loggercheck/loggercheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/loggercheck/loggercheck.go deleted file mode 100644 index 077e8a512..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/loggercheck/loggercheck.go +++ /dev/null @@ -1,44 +0,0 @@ -package loggercheck - -import ( - "github.com/timonwong/loggercheck" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/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.Zap { - disable = append(disable, "zap") - } - - opts = []loggercheck.Option{ - loggercheck.WithDisable(disable), - loggercheck.WithRequireStringKey(settings.RequireStringKey), - loggercheck.WithRules(settings.Rules), - loggercheck.WithNoPrintfLike(settings.NoPrintfLike), - } - } - - analyzer := loggercheck.NewAnalyzer(opts...) - return goanalysis.NewLinter( - analyzer.Name, - analyzer.Doc, - []*analysis.Analyzer{analyzer}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/maintidx/maintidx.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/maintidx/maintidx.go deleted file mode 100644 index 08f12369e..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/maintidx/maintidx.go +++ /dev/null @@ -1,30 +0,0 @@ -package maintidx - -import ( - "github.com/yagipy/maintidx" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(cfg *config.MaintIdxSettings) *goanalysis.Linter { - analyzer := maintidx.Analyzer - - cfgMap := map[string]map[string]any{ - analyzer.Name: {"under": 20}, - } - - if cfg != nil { - cfgMap[analyzer.Name] = map[string]any{ - "under": cfg.Under, - } - } - - return goanalysis.NewLinter( - analyzer.Name, - analyzer.Doc, - []*analysis.Analyzer{analyzer}, - cfgMap, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/makezero/makezero.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/makezero/makezero.go deleted file mode 100644 index ae4bf2184..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/makezero/makezero.go +++ /dev/null @@ -1,74 +0,0 @@ -package makezero - -import ( - "fmt" - "sync" - - "github.com/ashanbrown/makezero/makezero" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "makezero" - -func New(settings *config.MakezeroSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues, err := runMakeZero(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 - }, - } - - return goanalysis.NewLinter( - linterName, - "Finds slice declarations with non-zero initial length", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runMakeZero(pass *analysis.Pass, settings *config.MakezeroSettings) ([]goanalysis.Issue, error) { - zero := makezero.NewLinter(settings.Always) - - var issues []goanalysis.Issue - - for _, file := range pass.Files { - hints, err := zero.Run(pass.Fset, pass.TypesInfo, file) - if err != nil { - return nil, fmt.Errorf("makezero linter failed on file %q: %w", file.Name.String(), err) - } - - for _, hint := range hints { - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - Pos: hint.Position(), - Text: hint.Details(), - FromLinter: linterName, - }, pass)) - } - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/mirror/mirror.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/mirror/mirror.go deleted file mode 100644 index 34b880b52..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/mirror/mirror.go +++ /dev/null @@ -1,70 +0,0 @@ -package mirror - -import ( - "sync" - - "github.com/butuzov/mirror" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -func New() *goanalysis.Linter { - var ( - mu sync.Mutex - issues []goanalysis.Issue - ) - - a := mirror.NewAnalyzer() - a.Run = func(pass *analysis.Pass) (any, error) { - // 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) - violations := mirror.Run(pass, true) - - if len(violations) == 0 { - return nil, nil - } - - for index := range violations { - i := violations[index].Issue(pass.Fset) - - issue := result.Issue{ - FromLinter: a.Name, - Text: i.Message, - Pos: i.Start, - } - - if i.InlineFix != "" { - issue.Replacement = &result.Replacement{ - Inline: &result.InlineFix{ - StartCol: i.Start.Column - 1, - Length: len(i.Original), - NewString: i.InlineFix, - }, - } - } - - mu.Lock() - issues = append(issues, goanalysis.NewIssue(&issue, pass)) - mu.Unlock() - } - - return nil, nil - } - - analyzer := goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return issues - }).WithLoadMode(goanalysis.LoadModeTypesInfo) - - return analyzer -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/misspell/misspell.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/misspell/misspell.go deleted file mode 100644 index 44409cec9..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/misspell/misspell.go +++ /dev/null @@ -1,189 +0,0 @@ -package misspell - -import ( - "fmt" - "go/token" - "strings" - "sync" - "unicode" - - "github.com/golangci/misspell" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "misspell" - -func New(settings *config.MisspellSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: goanalysis.DummyRun, - } - - return goanalysis.NewLinter( - linterName, - "Finds commonly misspelled English words", - []*analysis.Analyzer{analyzer}, - nil, - ).WithContextSetter(func(lintCtx *linter.Context) { - replacer, ruleErr := createMisspellReplacer(settings) - - analyzer.Run = func(pass *analysis.Pass) (any, error) { - if ruleErr != nil { - return nil, ruleErr - } - - issues, err := runMisspell(lintCtx, pass, replacer, settings.Mode) - 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 runMisspell(lintCtx *linter.Context, pass *analysis.Pass, replacer *misspell.Replacer, mode string) ([]goanalysis.Issue, error) { - fileNames := internal.GetFileNames(pass) - - var issues []goanalysis.Issue - for _, filename := range fileNames { - lintIssues, err := runMisspellOnFile(lintCtx, filename, replacer, mode) - if err != nil { - return nil, err - } - - for i := range lintIssues { - issues = append(issues, goanalysis.NewIssue(&lintIssues[i], pass)) - } - } - - return issues, nil -} - -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.IgnoreWords) != 0 { - replacer.RemoveRule(settings.IgnoreWords) - } - - // It can panic. - replacer.Compile() - - return replacer, nil -} - -func runMisspellOnFile(lintCtx *linter.Context, filename string, replacer *misspell.Replacer, mode string) ([]result.Issue, error) { - fileContent, err := lintCtx.FileCache.GetFileBytes(filename) - if err != nil { - return nil, fmt.Errorf("can't get file %s contents: %w", 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 - } - - _, diffs := replace(string(fileContent)) - - var res []result.Issue - - for _, diff := range diffs { - text := fmt.Sprintf("`%s` is a misspelling of `%s`", diff.Original, diff.Corrected) - - pos := token.Position{ - Filename: filename, - Line: diff.Line, - Column: diff.Column + 1, - } - - replacement := &result.Replacement{ - Inline: &result.InlineFix{ - StartCol: diff.Column, - Length: len(diff.Original), - NewString: diff.Corrected, - }, - } - - res = append(res, result.Issue{ - Pos: pos, - Text: text, - FromLinter: linterName, - Replacement: replacement, - }) - } - - return res, 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/pkg/golinters/mnd/mnd.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/mnd/mnd.go deleted file mode 100644 index 9aa8692ff..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/mnd/mnd.go +++ /dev/null @@ -1,63 +0,0 @@ -package mnd - -import ( - mnd "github.com/tommy-muehle/go-mnd/v2" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.MndSettings) *goanalysis.Linter { - return newMND(mnd.Analyzer, settings, nil) -} - -func NewGoMND(settings *config.GoMndSettings) *goanalysis.Linter { - // shallow copy because mnd.Analyzer is a global variable. - a := new(analysis.Analyzer) - *a = *mnd.Analyzer - - // Used to force the analyzer name to use the same name as the linter. - // This is required to avoid displaying the analyzer name inside the issue text. - a.Name = "gomnd" - - var linterCfg map[string]map[string]any - - if settings != nil && len(settings.Settings) > 0 { - // Convert deprecated setting. - linterCfg = map[string]map[string]any{ - a.Name: settings.Settings["mnd"], - } - } - - return newMND(a, &settings.MndSettings, linterCfg) -} - -func newMND(a *analysis.Analyzer, settings *config.MndSettings, linterCfg map[string]map[string]any) *goanalysis.Linter { - if len(linterCfg) == 0 && settings != nil { - cfg := make(map[string]any) - 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 - } - - linterCfg = map[string]map[string]any{ - a.Name: cfg, - } - } - - return goanalysis.NewLinter( - a.Name, - "An analyzer to detect magic numbers.", - []*analysis.Analyzer{a}, - linterCfg, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/musttag/musttag.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/musttag/musttag.go deleted file mode 100644 index 30047abfc..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/musttag/musttag.go +++ /dev/null @@ -1,29 +0,0 @@ -package musttag - -import ( - "go-simpler.org/musttag" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(setting *config.MustTagSettings) *goanalysis.Linter { - var funcs []musttag.Func - - if setting != nil { - for _, fn := range setting.Functions { - funcs = append(funcs, musttag.Func{ - Name: fn.Name, - Tag: fn.Tag, - ArgPos: fn.ArgPos, - }) - } - } - - a := musttag.New(funcs...) - - return goanalysis. - NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, nil). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nakedret/nakedret.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/nakedret/nakedret.go deleted file mode 100644 index beabf2cd8..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nakedret/nakedret.go +++ /dev/null @@ -1,25 +0,0 @@ -package nakedret - -import ( - "github.com/alexkohler/nakedret/v2" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.NakedretSettings) *goanalysis.Linter { - var maxLines uint - if settings != nil { - maxLines = settings.MaxFuncLines - } - - a := nakedret.NakedReturnAnalyzer(maxLines) - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nestif/nestif.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/nestif/nestif.go deleted file mode 100644 index 43be973b0..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nestif/nestif.go +++ /dev/null @@ -1,78 +0,0 @@ -package nestif - -import ( - "sort" - "sync" - - "github.com/nakabonne/nestif" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "nestif" - -func New(settings *config.NestifSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: goanalysis.TheOnlyAnalyzerName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues := runNestIf(pass, settings) - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - } - - return goanalysis.NewLinter( - linterName, - "Reports deeply nested if statements", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runNestIf(pass *analysis.Pass, settings *config.NestifSettings) []goanalysis.Issue { - checker := &nestif.Checker{ - MinComplexity: settings.MinComplexity, - } - - var lintIssues []nestif.Issue - for _, f := range pass.Files { - lintIssues = append(lintIssues, checker.Check(f, pass.Fset)...) - } - - if len(lintIssues) == 0 { - return nil - } - - sort.SliceStable(lintIssues, func(i, j int) bool { - return lintIssues[i].Complexity > lintIssues[j].Complexity - }) - - issues := make([]goanalysis.Issue, 0, len(lintIssues)) - for _, i := range lintIssues { - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - Pos: i.Pos, - Text: i.Message, - FromLinter: linterName, - }, pass)) - } - - return issues -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilerr/nilerr.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilerr/nilerr.go deleted file mode 100644 index c9e466905..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilerr/nilerr.go +++ /dev/null @@ -1,19 +0,0 @@ -package nilerr - -import ( - "github.com/gostaticanalysis/nilerr" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := nilerr.Analyzer - - return goanalysis.NewLinter( - a.Name, - "Finds the code that returns nil even if it checks that the error is not nil.", - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilnil/nilnil.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilnil/nilnil.go deleted file mode 100644 index c9237035d..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nilnil/nilnil.go +++ /dev/null @@ -1,30 +0,0 @@ -package nilnil - -import ( - "strings" - - "github.com/Antonboom/nilnil/pkg/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(cfg *config.NilNilSettings) *goanalysis.Linter { - a := analyzer.New() - - cfgMap := make(map[string]map[string]any) - if cfg != nil && len(cfg.CheckedTypes) != 0 { - cfgMap[a.Name] = map[string]any{ - "checked-types": strings.Join(cfg.CheckedTypes, ","), - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfgMap, - ). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nlreturn/nlreturn.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/nlreturn/nlreturn.go deleted file mode 100644 index 509218808..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nlreturn/nlreturn.go +++ /dev/null @@ -1,27 +0,0 @@ -package nlreturn - -import ( - "github.com/ssgreg/nlreturn/v2/pkg/nlreturn" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.NlreturnSettings) *goanalysis.Linter { - a := nlreturn.NewAnalyzer() - - cfg := map[string]map[string]any{} - if settings != nil { - cfg[a.Name] = map[string]any{ - "block-size": settings.BlockSize, - } - } - - return goanalysis.NewLinter( - a.Name, - "nlreturn checks for a new line before return and branch statements to increase code clarity", - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/noctx/noctx.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/noctx/noctx.go deleted file mode 100644 index 8a063c613..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/noctx/noctx.go +++ /dev/null @@ -1,19 +0,0 @@ -package noctx - -import ( - "github.com/sonatard/noctx" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := noctx.Analyzer - - return goanalysis.NewLinter( - a.Name, - "Finds sending http request without context.Context", - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/README.md b/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/README.md deleted file mode 100644 index e4d48f012..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/golinters/nolintlint/internal/nolintlint.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/nolintlint.go deleted file mode 100644 index 08dd74378..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal/nolintlint.go +++ /dev/null @@ -1,311 +0,0 @@ -// Package internal provides a linter to ensure that all //nolint directives are followed by explanations -package internal - -import ( - "fmt" - "go/ast" - "go/token" - "regexp" - "strings" - "unicode" - - "github.com/golangci/golangci-lint/pkg/result" -) - -type BaseIssue struct { - fullDirective string - directiveWithOptionalLeadingSpace string - position token.Position - replacement *result.Replacement -} - -//nolint:gocritic // TODO(ldez) must be change in the future. -func (b BaseIssue) Position() token.Position { - return b.position -} - -//nolint:gocritic // TODO(ldez) must be change in the future. -func (b BaseIssue) Replacement() *result.Replacement { - return b.replacement -} - -type ExtraLeadingSpace struct { - BaseIssue -} - -//nolint:gocritic // TODO(ldez) must be change in the future. -func (i ExtraLeadingSpace) Details() string { - return fmt.Sprintf("directive `%s` should not have more than one leading space", i.fullDirective) -} - -func (i ExtraLeadingSpace) String() string { return toString(i) } - -type NotMachine struct { - BaseIssue -} - -//nolint:gocritic // TODO(ldez) must be change in the future. -func (i NotMachine) Details() string { - expected := i.fullDirective[:2] + strings.TrimLeftFunc(i.fullDirective[2:], unicode.IsSpace) - return fmt.Sprintf("directive `%s` should be written without leading space as `%s`", - i.fullDirective, expected) -} - -func (i NotMachine) String() string { return toString(i) } - -type NotSpecific struct { - BaseIssue -} - -//nolint:gocritic // TODO(ldez) must be change in the future. -func (i NotSpecific) Details() string { - return fmt.Sprintf("directive `%s` should mention specific linter such as `%s:my-linter`", - i.fullDirective, i.directiveWithOptionalLeadingSpace) -} - -func (i NotSpecific) String() string { return toString(i) } - -type ParseError struct { - BaseIssue -} - -//nolint:gocritic // TODO(ldez) must be change in the future. -func (i ParseError) Details() string { - return fmt.Sprintf("directive `%s` should match `%s[:] [// ]`", - i.fullDirective, - i.directiveWithOptionalLeadingSpace) -} - -func (i ParseError) String() string { return toString(i) } - -type NoExplanation struct { - BaseIssue - fullDirectiveWithoutExplanation string -} - -//nolint:gocritic // TODO(ldez) must be change in the future. -func (i NoExplanation) Details() string { - return fmt.Sprintf("directive `%s` should provide explanation such as `%s // this is why`", - i.fullDirective, i.fullDirectiveWithoutExplanation) -} - -func (i NoExplanation) String() string { return toString(i) } - -type UnusedCandidate struct { - BaseIssue - ExpectedLinter string -} - -//nolint:gocritic // TODO(ldez) must be change in the future. -func (i UnusedCandidate) Details() string { - details := fmt.Sprintf("directive `%s` is unused", i.fullDirective) - if i.ExpectedLinter != "" { - details += fmt.Sprintf(" for linter %q", i.ExpectedLinter) - } - return details -} - -func (i UnusedCandidate) String() string { return toString(i) } - -func toString(issue Issue) string { - return fmt.Sprintf("%s at %s", issue.Details(), issue.Position()) -} - -type Issue interface { - Details() string - Position() token.Position - String() string - Replacement() *result.Replacement -} - -type Needs uint - -const ( - NeedsMachineOnly Needs = 1 << iota - NeedsSpecific - NeedsExplanation - NeedsUnused - NeedsAll = NeedsMachineOnly | NeedsSpecific | NeedsExplanation -) - -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(fset *token.FileSet, nodes ...ast.Node) ([]Issue, error) { - var issues []Issue - - for _, node := range nodes { - file, ok := node.(*ast.File) - if !ok { - continue - } - - 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 := "//" - if leadingSpace != "" { - directiveWithOptionalLeadingSpace += " " - } - - split := strings.Split(strings.SplitN(comment.Text, ":", 2)[0], "//") - directiveWithOptionalLeadingSpace += strings.TrimSpace(split[1]) - - pos := fset.Position(comment.Pos()) - end := fset.Position(comment.End()) - - base := BaseIssue{ - fullDirective: comment.Text, - directiveWithOptionalLeadingSpace: directiveWithOptionalLeadingSpace, - position: pos, - } - - // check for, report and eliminate leading spaces, so we can check for other issues - if leadingSpace != "" { - removeWhitespace := &result.Replacement{ - Inline: &result.InlineFix{ - StartCol: pos.Column + 1, - Length: len(leadingSpace), - NewString: "", - }, - } - if (l.needs & NeedsMachineOnly) != 0 { - issue := NotMachine{BaseIssue: base} - issue.BaseIssue.replacement = removeWhitespace - issues = append(issues, issue) - } else if len(leadingSpace) > 1 { - issue := ExtraLeadingSpace{BaseIssue: base} - issue.BaseIssue.replacement = removeWhitespace - issue.BaseIssue.replacement.Inline.NewString = " " // assume a single space was intended - issues = append(issues, issue) - } - } - - fullMatches := fullDirectivePattern.FindStringSubmatch(comment.Text) - if len(fullMatches) == 0 { - issues = append(issues, ParseError{BaseIssue: base}) - 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("//") + 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 { - issues = append(issues, NotSpecific{BaseIssue: base}) - } - } - - // when detecting unused directives, we send all the directives through and filter them out in the nolint processor - if (l.needs & NeedsUnused) != 0 { - removeNolintCompletely := &result.Replacement{} - - startCol := pos.Column - 1 - - if startCol == 0 { - // if the directive starts from a new line, remove the line - removeNolintCompletely.NeedOnlyDelete = true - } else { - removeNolintCompletely.Inline = &result.InlineFix{ - StartCol: startCol, - Length: end.Column - pos.Column, - NewString: "", - } - } - - if len(linters) == 0 { - issue := UnusedCandidate{BaseIssue: base} - issue.replacement = removeNolintCompletely - issues = append(issues, issue) - } else { - for _, linter := range linters { - issue := UnusedCandidate{BaseIssue: base, ExpectedLinter: linter} - // only offer replacement if there is a single linter - // because of issues around commas and the possibility of all - // linters being removed - if len(linters) == 1 { - issue.replacement = removeNolintCompletely - } - issues = append(issues, issue) - } - } - } - - if (l.needs&NeedsExplanation) != 0 && (explanation == "" || strings.TrimSpace(explanation) == "//") { - 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, "") - issues = append(issues, NoExplanation{ - BaseIssue: base, - fullDirectiveWithoutExplanation: fullDirectiveWithoutExplanation, - }) - } - } - } - } - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/nolintlint.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/nolintlint.go deleted file mode 100644 index 9f04454a5..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nolintlint/nolintlint.go +++ /dev/null @@ -1,104 +0,0 @@ -package nolintlint - -import ( - "fmt" - "go/ast" - "sync" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/nolintlint/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const LinterName = "nolintlint" - -func New(settings *config.NoLintLintSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: LinterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues, err := runNoLintLint(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 - }, - } - - return goanalysis.NewLinter( - LinterName, - "Reports ill-formed or insufficient nolint directives", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runNoLintLint(pass *analysis.Pass, settings *config.NoLintLintSettings) ([]goanalysis.Issue, error) { - var needs internal.Needs - if settings.RequireExplanation { - needs |= internal.NeedsExplanation - } - if settings.RequireSpecific { - needs |= internal.NeedsSpecific - } - if !settings.AllowUnused { - needs |= internal.NeedsUnused - } - - lnt, err := internal.NewLinter(needs, settings.AllowNoExplanation) - if err != nil { - return nil, err - } - - nodes := make([]ast.Node, 0, len(pass.Files)) - for _, n := range pass.Files { - nodes = append(nodes, n) - } - - lintIssues, err := lnt.Run(pass.Fset, nodes...) - if err != nil { - return nil, fmt.Errorf("linter failed to run: %w", err) - } - - var issues []goanalysis.Issue - - for _, i := range lintIssues { - expectNoLint := false - var expectedNolintLinter string - if ii, ok := i.(internal.UnusedCandidate); ok { - expectedNolintLinter = ii.ExpectedLinter - expectNoLint = true - } - - issue := &result.Issue{ - FromLinter: LinterName, - Text: i.Details(), - Pos: i.Position(), - ExpectNoLint: expectNoLint, - ExpectedNoLintLinter: expectedNolintLinter, - Replacement: i.Replacement(), - } - - issues = append(issues, goanalysis.NewIssue(issue, pass)) - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nonamedreturns/nonamedreturns.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/nonamedreturns/nonamedreturns.go deleted file mode 100644 index 42a618e64..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nonamedreturns/nonamedreturns.go +++ /dev/null @@ -1,29 +0,0 @@ -package nonamedreturns - -import ( - "github.com/firefart/nonamedreturns/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.NoNamedReturnsSettings) *goanalysis.Linter { - a := analyzer.Analyzer - - var cfg map[string]map[string]any - if settings != nil { - cfg = map[string]map[string]any{ - a.Name: { - analyzer.FlagReportErrorInDefer: settings.ReportErrorInDefer, - }, - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nosprintfhostport/nosprintfhostport.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/nosprintfhostport/nosprintfhostport.go deleted file mode 100644 index 8f06ae1f6..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/nosprintfhostport/nosprintfhostport.go +++ /dev/null @@ -1,19 +0,0 @@ -package nosprintfhostport - -import ( - "github.com/stbenjam/no-sprintf-host-port/pkg/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := analyzer.Analyzer - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/paralleltest/paralleltest.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/paralleltest/paralleltest.go deleted file mode 100644 index 0c908fa38..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/paralleltest/paralleltest.go +++ /dev/null @@ -1,34 +0,0 @@ -package paralleltest - -import ( - "github.com/kunwardeep/paralleltest/pkg/paralleltest" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.ParallelTestSettings) *goanalysis.Linter { - a := paralleltest.NewAnalyzer() - - var cfg map[string]map[string]any - if settings != nil { - d := map[string]any{ - "i": settings.IgnoreMissing, - "ignoremissingsubtests": settings.IgnoreMissingSubtests, - } - - if config.IsGoGreaterThanOrEqual(settings.Go, "1.22") { - d["ignoreloopVar"] = true - } - - cfg = map[string]map[string]any{a.Name: d} - } - - return goanalysis.NewLinter( - a.Name, - "Detects missing usage of t.Parallel() method in your Go test", - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/perfsprint/perfsprint.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/perfsprint/perfsprint.go deleted file mode 100644 index a4ead1914..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/perfsprint/perfsprint.go +++ /dev/null @@ -1,32 +0,0 @@ -package perfsprint - -import ( - "github.com/catenacyber/perfsprint/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.PerfSprintSettings) *goanalysis.Linter { - a := analyzer.New() - - cfg := map[string]map[string]any{ - a.Name: {"fiximports": false}, - } - - if settings != nil { - cfg[a.Name]["int-conversion"] = settings.IntConversion - cfg[a.Name]["err-error"] = settings.ErrError - cfg[a.Name]["errorf"] = settings.ErrorF - cfg[a.Name]["sprintf1"] = settings.SprintF1 - cfg[a.Name]["strconcat"] = settings.StrConcat - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/prealloc/prealloc.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/prealloc/prealloc.go deleted file mode 100644 index ce7ff9d59..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/prealloc/prealloc.go +++ /dev/null @@ -1,65 +0,0 @@ -package prealloc - -import ( - "fmt" - "sync" - - "github.com/alexkohler/prealloc/pkg" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "prealloc" - -func New(settings *config.PreallocSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues := runPreAlloc(pass, settings) - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - } - - return goanalysis.NewLinter( - linterName, - "Finds slice declarations that could potentially be pre-allocated", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runPreAlloc(pass *analysis.Pass, settings *config.PreallocSettings) []goanalysis.Issue { - var issues []goanalysis.Issue - - hints := pkg.Check(pass.Files, settings.Simple, settings.RangeLoops, settings.ForLoops) - - for _, hint := range hints { - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - Pos: pass.Fset.Position(hint.Pos), - Text: fmt.Sprintf("Consider pre-allocating %s", internal.FormatCode(hint.DeclaredSliceName, nil)), - FromLinter: linterName, - }, pass)) - } - - return issues -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/predeclared/predeclared.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/predeclared/predeclared.go deleted file mode 100644 index b8d189fd5..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/predeclared/predeclared.go +++ /dev/null @@ -1,26 +0,0 @@ -package predeclared - -import ( - "github.com/nishanths/predeclared/passes/predeclared" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.PredeclaredSettings) *goanalysis.Linter { - a := predeclared.Analyzer - - var cfg map[string]map[string]any - if settings != nil { - cfg = map[string]map[string]any{ - a.Name: { - predeclared.IgnoreFlag: settings.Ignore, - predeclared.QualifiedFlag: settings.Qualified, - }, - } - } - - return goanalysis.NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/promlinter/promlinter.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/promlinter/promlinter.go deleted file mode 100644 index 5decbbc7c..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/promlinter/promlinter.go +++ /dev/null @@ -1,77 +0,0 @@ -package promlinter - -import ( - "fmt" - "sync" - - "github.com/yeya24/promlinter" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/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, - } - } - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - 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 - }, - } - - return goanalysis.NewLinter( - linterName, - "Check Prometheus metrics naming via promlint", - []*analysis.Analyzer{analyzer}, - 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/pkg/golinters/protogetter/protogetter.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/protogetter/protogetter.go deleted file mode 100644 index 302ce67b8..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/protogetter/protogetter.go +++ /dev/null @@ -1,74 +0,0 @@ -package protogetter - -import ( - "sync" - - "github.com/ghostiam/protogetter" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -func New(settings *config.ProtoGetterSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - var cfg protogetter.Config - if settings != nil { - cfg = protogetter.Config{ - SkipGeneratedBy: settings.SkipGeneratedBy, - SkipFiles: settings.SkipFiles, - SkipAnyGenerated: settings.SkipAnyGenerated, - ReplaceFirstArgInAppend: settings.ReplaceFirstArgInAppend, - } - } - cfg.Mode = protogetter.GolangciLintMode - - a := protogetter.NewAnalyzer(&cfg) - a.Run = func(pass *analysis.Pass) (any, error) { - pgIssues, err := protogetter.Run(pass, &cfg) - if err != nil { - return nil, err - } - - issues := make([]goanalysis.Issue, len(pgIssues)) - for i, issue := range pgIssues { - report := &result.Issue{ - FromLinter: a.Name, - Pos: issue.Pos, - Text: issue.Message, - Replacement: &result.Replacement{ - Inline: &result.InlineFix{ - StartCol: issue.InlineFix.StartCol, - Length: issue.InlineFix.Length, - NewString: issue.InlineFix.NewString, - }, - }, - } - - issues[i] = goanalysis.NewIssue(report, pass) - } - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/reassign/reassign.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/reassign/reassign.go deleted file mode 100644 index cfc85635e..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/reassign/reassign.go +++ /dev/null @@ -1,32 +0,0 @@ -package reassign - -import ( - "fmt" - "strings" - - "github.com/curioswitch/go-reassign" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.ReassignSettings) *goanalysis.Linter { - a := reassign.NewAnalyzer() - - var cfg map[string]map[string]any - if settings != nil && len(settings.Patterns) > 0 { - cfg = map[string]map[string]any{ - a.Name: { - reassign.FlagPattern: fmt.Sprintf("^(%s)$", strings.Join(settings.Patterns, "|")), - }, - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/revive/revive.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/revive/revive.go deleted file mode 100644 index 90ce15db6..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/revive/revive.go +++ /dev/null @@ -1,433 +0,0 @@ -package revive - -import ( - "bytes" - "encoding/json" - "fmt" - "go/token" - "os" - "reflect" - "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/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "revive" - -var debugf = logutils.Debug(logutils.DebugKeyRevive) - -// jsonObject defines a JSON object of a failure -type jsonObject struct { - Severity lint.Severity - lint.Failure `json:",inline"` -} - -func New(settings *config.ReviveSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: goanalysis.TheOnlyAnalyzerName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: goanalysis.DummyRun, - } - - return goanalysis.NewLinter( - linterName, - "Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint.", - []*analysis.Analyzer{analyzer}, - nil, - ).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(lintCtx, 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 - formatter lint.Formatter - lintingRules []lint.Rule - conf *lint.Config -} - -func newWrapper(settings *config.ReviveSettings) (*wrapper, error) { - conf, err := getConfig(settings) - if err != nil { - return nil, err - } - - conf.GoVersion, err = hcversion.NewVersion(settings.Go) - if err != nil { - return nil, err - } - - formatter, err := reviveConfig.GetFormatter("json") - 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), - formatter: formatter, - lintingRules: lintingRules, - conf: conf, - }, nil -} - -func (w *wrapper) run(lintCtx *linter.Context, pass *analysis.Pass) ([]goanalysis.Issue, error) { - packages := [][]string{internal.GetFileNames(pass)} - - failures, err := w.revive.Lint(packages, w.lintingRules, *w.conf) - if err != nil { - return nil, err - } - - formatChan := make(chan lint.Failure) - exitChan := make(chan bool) - - var output string - go func() { - output, err = w.formatter.Format(formatChan, *w.conf) - if err != nil { - lintCtx.Log.Errorf("Format error: %v", err) - } - exitChan <- true - }() - - for f := range failures { - if f.Confidence < w.conf.Confidence { - continue - } - - formatChan <- f - } - - close(formatChan) - <-exitChan - - var results []jsonObject - err = json.Unmarshal([]byte(output), &results) - if err != nil { - return nil, err - } - - var issues []goanalysis.Issue - for i := range results { - issues = append(issues, toIssue(pass, &results[i])) - } - - return issues, nil -} - -func toIssue(pass *analysis.Pass, object *jsonObject) goanalysis.Issue { - lineRangeTo := object.Position.End.Line - if object.RuleName == (&rule.ExportedRule{}).Name() { - lineRangeTo = object.Position.Start.Line - } - - return goanalysis.NewIssue(&result.Issue{ - Severity: string(object.Severity), - Text: fmt.Sprintf("%s: %s", object.RuleName, object.Failure.Failure), - Pos: token.Position{ - Filename: object.Position.Start.Filename, - Line: object.Position.Start.Line, - Offset: object.Position.Start.Offset, - Column: object.Position.Start.Column, - }, - LineRange: &result.Range{ - From: object.Position.Start.Line, - To: lineRangeTo, - }, - FromLinter: linterName, - }, 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.3.7/config/config.go#L217 -// https://github.com/mgechev/revive/blob/v1.3.7/config/config.go#L169-L174 -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 - } - - debugf("revive configuration: %#v", conf) - - return conf, nil -} - -func createConfigMap(cfg *config.ReviveSettings) map[string]any { - rawRoot := map[string]any{ - "ignoreGeneratedHeader": cfg.IgnoreGeneratedHeader, - "confidence": cfg.Confidence, - "severity": cfg.Severity, - "errorCode": cfg.ErrorCode, - "warningCode": cfg.WarningCode, - "enableAllRules": cfg.EnableAllRules, - } - - 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.3.9/config/config.go#L15 -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.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{}, -}, 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.1.4/config/config.go#L145 -func normalizeConfig(cfg *lint.Config) { - // NOTE(ldez): this custom section for golangci-lint should be kept. - // --- - if cfg.Confidence == 0 { - cfg.Confidence = defaultConfidence - } - if cfg.Severity == "" { - 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.1.4/config/config.go#L214 -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/golangci/golangci-lint/pkg/golinters/rowserrcheck/rowserrcheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/rowserrcheck/rowserrcheck.go deleted file mode 100644 index 3fe824467..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/rowserrcheck/rowserrcheck.go +++ /dev/null @@ -1,25 +0,0 @@ -package rowserrcheck - -import ( - "github.com/jingyugao/rowserrcheck/passes/rowserr" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.RowsErrCheckSettings) *goanalysis.Linter { - var pkgs []string - if settings != nil { - pkgs = settings.Packages - } - - a := rowserr.NewAnalyzer(pkgs...) - - return goanalysis.NewLinter( - a.Name, - "checks whether Rows.Err of rows is checked successfully", - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/sloglint/sloglint.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/sloglint/sloglint.go deleted file mode 100644 index 486662577..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/sloglint/sloglint.go +++ /dev/null @@ -1,33 +0,0 @@ -package sloglint - -import ( - "go-simpler.org/sloglint" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/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, - NoRawKeys: settings.NoRawKeys, - KeyNamingCase: settings.KeyNamingCase, - ForbiddenKeys: settings.ForbiddenKeys, - ArgsOnSepLines: settings.ArgsOnSepLines, - } - } - - a := sloglint.New(opts) - - return goanalysis. - NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, nil). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/spancheck/spancheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/spancheck/spancheck.go deleted file mode 100644 index a800a1705..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/spancheck/spancheck.go +++ /dev/null @@ -1,33 +0,0 @@ -package spancheck - -import ( - "github.com/jjti/go-spancheck" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.SpancheckSettings) *goanalysis.Linter { - cfg := spancheck.NewDefaultConfig() - - if settings != nil { - if settings.Checks != nil { - cfg.EnabledChecks = settings.Checks - } - - if settings.IgnoreCheckSignatures != nil { - cfg.IgnoreChecksSignaturesSlice = settings.IgnoreCheckSignatures - } - - if settings.ExtraStartSpanSignatures != nil { - cfg.StartSpanMatchersSlice = settings.ExtraStartSpanSignatures - } - } - - a := spancheck.NewAnalyzerWithConfig(cfg) - - return goanalysis. - NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, nil). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/sqlclosecheck/sqlclosecheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/sqlclosecheck/sqlclosecheck.go deleted file mode 100644 index 5eb32ff9d..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/sqlclosecheck/sqlclosecheck.go +++ /dev/null @@ -1,19 +0,0 @@ -package sqlclosecheck - -import ( - "github.com/ryanrolds/sqlclosecheck/pkg/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := analyzer.NewAnalyzer() - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/staticcheck/staticcheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/staticcheck/staticcheck.go deleted file mode 100644 index 79394bdb7..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/staticcheck/staticcheck.go +++ /dev/null @@ -1,22 +0,0 @@ -package staticcheck - -import ( - "honnef.co/go/tools/staticcheck" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" -) - -func New(settings *config.StaticCheckSettings) *goanalysis.Linter { - cfg := internal.StaticCheckConfig(settings) - analyzers := internal.SetupStaticCheckAnalyzers(staticcheck.Analyzers, cfg.Checks) - - return goanalysis.NewLinter( - "staticcheck", - "It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary."+ - " The author of staticcheck doesn't support or approve the use of staticcheck as a library inside golangci-lint.", - analyzers, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/stylecheck/stylecheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/stylecheck/stylecheck.go deleted file mode 100644 index 60859f28a..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/stylecheck/stylecheck.go +++ /dev/null @@ -1,31 +0,0 @@ -package stylecheck - -import ( - "golang.org/x/tools/go/analysis" - scconfig "honnef.co/go/tools/config" - "honnef.co/go/tools/stylecheck" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" -) - -func New(settings *config.StaticCheckSettings) *goanalysis.Linter { - cfg := internal.StaticCheckConfig(settings) - - // `scconfig.Analyzer` is a singleton, then it's not possible to have more than one instance for all staticcheck "sub-linters". - // When we will merge the 4 "sub-linters", the problem will disappear: https://github.com/golangci/golangci-lint/issues/357 - // Currently only stylecheck analyzer has a configuration in staticcheck. - scconfig.Analyzer.Run = func(_ *analysis.Pass) (any, error) { - return cfg, nil - } - - analyzers := internal.SetupStaticCheckAnalyzers(stylecheck.Analyzers, cfg.Checks) - - return goanalysis.NewLinter( - "stylecheck", - "Stylecheck is a replacement for golint", - analyzers, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tagalign/tagalign.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/tagalign/tagalign.go deleted file mode 100644 index f438c51b5..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tagalign/tagalign.go +++ /dev/null @@ -1,75 +0,0 @@ -package tagalign - -import ( - "sync" - - "github.com/4meepo/tagalign" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -func New(settings *config.TagAlignSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - options := []tagalign.Option{tagalign.WithMode(tagalign.GolangciLintMode)} - - 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()) - } - } - - analyzer := tagalign.NewAnalyzer(options...) - analyzer.Run = func(pass *analysis.Pass) (any, error) { - taIssues := tagalign.Run(pass, options...) - - issues := make([]goanalysis.Issue, len(taIssues)) - for i, issue := range taIssues { - report := &result.Issue{ - FromLinter: analyzer.Name, - Pos: issue.Pos, - Text: issue.Message, - Replacement: &result.Replacement{ - Inline: &result.InlineFix{ - StartCol: issue.InlineFix.StartCol, - Length: issue.InlineFix.Length, - NewString: issue.InlineFix.NewString, - }, - }, - } - - issues[i] = goanalysis.NewIssue(report, pass) - } - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - } - - return goanalysis.NewLinter( - analyzer.Name, - analyzer.Doc, - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tagliatelle/tagliatelle.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/tagliatelle/tagliatelle.go deleted file mode 100644 index d1674c3e9..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tagliatelle/tagliatelle.go +++ /dev/null @@ -1,35 +0,0 @@ -package tagliatelle - -import ( - "github.com/ldez/tagliatelle" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.TagliatelleSettings) *goanalysis.Linter { - cfg := tagliatelle.Config{ - Rules: map[string]string{ - "json": "camel", - "yaml": "camel", - "header": "header", - }, - } - - if settings != nil { - for k, v := range settings.Case.Rules { - cfg.Rules[k] = v - } - cfg.UseFieldName = settings.Case.UseFieldName - } - - a := tagliatelle.New(cfg) - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tenv/tenv.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/tenv/tenv.go deleted file mode 100644 index b80a783b6..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tenv/tenv.go +++ /dev/null @@ -1,29 +0,0 @@ -package tenv - -import ( - "github.com/sivchari/tenv" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.TenvSettings) *goanalysis.Linter { - a := tenv.Analyzer - - var cfg map[string]map[string]any - if settings != nil { - cfg = map[string]map[string]any{ - a.Name: { - tenv.A: settings.All, - }, - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testableexamples/testableexamples.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/testableexamples/testableexamples.go deleted file mode 100644 index 6b76271db..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testableexamples/testableexamples.go +++ /dev/null @@ -1,19 +0,0 @@ -package testableexamples - -import ( - "github.com/maratori/testableexamples/pkg/testableexamples" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := testableexamples.NewAnalyzer() - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testifylint/testifylint.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/testifylint/testifylint.go deleted file mode 100644 index b3f2f0bd4..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testifylint/testifylint.go +++ /dev/null @@ -1,51 +0,0 @@ -package testifylint - -import ( - "github.com/Antonboom/testifylint/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.TestifylintSettings) *goanalysis.Linter { - a := analyzer.New() - - cfg := make(map[string]map[string]any) - if settings != nil { - cfg[a.Name] = 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, - "go-require.ignore-http-handlers": settings.GoRequire.IgnoreHTTPHandlers, - } - if len(settings.EnabledCheckers) > 0 { - cfg[a.Name]["enable"] = settings.EnabledCheckers - } - if len(settings.DisabledCheckers) > 0 { - cfg[a.Name]["disable"] = settings.DisabledCheckers - } - - if b := settings.Formatter.CheckFormatString; b != nil { - cfg[a.Name]["formatter.check-format-string"] = *b - } - if p := settings.ExpectedActual.ExpVarPattern; p != "" { - cfg[a.Name]["expected-actual.pattern"] = p - } - if p := settings.RequireError.FnPattern; p != "" { - cfg[a.Name]["require-error.fn-pattern"] = p - } - if m := settings.SuiteExtraAssertCall.Mode; m != "" { - cfg[a.Name]["suite-extra-assert-call.mode"] = m - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfg, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testpackage/testpackage.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/testpackage/testpackage.go deleted file mode 100644 index 632152712..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/testpackage/testpackage.go +++ /dev/null @@ -1,28 +0,0 @@ -package testpackage - -import ( - "strings" - - "github.com/maratori/testpackage/pkg/testpackage" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(cfg *config.TestpackageSettings) *goanalysis.Linter { - a := testpackage.NewAnalyzer() - - var settings map[string]map[string]any - if cfg != nil { - settings = map[string]map[string]any{ - a.Name: { - testpackage.SkipRegexpFlagName: cfg.SkipRegexp, - testpackage.AllowPackagesFlagName: strings.Join(cfg.AllowPackages, ","), - }, - } - } - - return goanalysis.NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, settings). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/thelper/thelper.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/thelper/thelper.go deleted file mode 100644 index cc6ea755c..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/thelper/thelper.go +++ /dev/null @@ -1,81 +0,0 @@ -package thelper - -import ( - "strings" - - "github.com/kulti/thelper/pkg/analyzer" - "golang.org/x/exp/maps" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" -) - -func New(cfg *config.ThelperSettings) *goanalysis.Linter { - a := analyzer.NewAnalyzer() - - 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 cfg != nil { - applyTHelperOptions(cfg.Test, "t_", opts) - applyTHelperOptions(cfg.Fuzz, "f_", opts) - applyTHelperOptions(cfg.Benchmark, "b_", opts) - applyTHelperOptions(cfg.TB, "tb_", opts) - } - - if len(opts) == 0 { - internal.LinterLogger.Fatalf("thelper: at least one option must be enabled") - } - - args := maps.Keys(opts) - - cfgMap := map[string]map[string]any{ - a.Name: { - "checks": strings.Join(args, ","), - }, - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfgMap, - ).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/pkg/golinters/tparallel/tparallel.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/tparallel/tparallel.go deleted file mode 100644 index 4f7c43a99..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/tparallel/tparallel.go +++ /dev/null @@ -1,18 +0,0 @@ -package tparallel - -import ( - "github.com/moricho/tparallel" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := tparallel.Analyzer - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/typecheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/typecheck.go deleted file mode 100644 index d0eaa00d0..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/typecheck.go +++ /dev/null @@ -1,24 +0,0 @@ -package golinters - -import ( - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func NewTypecheck() *goanalysis.Linter { - const linterName = "typecheck" - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: goanalysis.DummyRun, - } - - return goanalysis.NewLinter( - linterName, - "Like the front-end of a Go compiler, parses and type-checks Go code", - []*analysis.Analyzer{analyzer}, - nil, - ).WithLoadMode(goanalysis.LoadModeNone) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/unconvert/unconvert.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/unconvert/unconvert.go deleted file mode 100644 index 954cc9eb3..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/unconvert/unconvert.go +++ /dev/null @@ -1,62 +0,0 @@ -package unconvert - -import ( - "sync" - - "github.com/golangci/unconvert" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "unconvert" - -func New(settings *config.UnconvertSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Run: func(pass *analysis.Pass) (any, error) { - issues := runUnconvert(pass, settings) - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - } - - return goanalysis.NewLinter( - linterName, - "Remove unnecessary type conversions", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runUnconvert(pass *analysis.Pass, settings *config.UnconvertSettings) []goanalysis.Issue { - positions := unconvert.Run(pass, settings.FastMath, settings.Safe) - - 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/pkg/golinters/unparam/unparam.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/unparam/unparam.go deleted file mode 100644 index 0fe184736..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/unparam/unparam.go +++ /dev/null @@ -1,90 +0,0 @@ -package unparam - -import ( - "sync" - - "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/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "unparam" - -func New(settings *config.UnparamSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: goanalysis.TheOnlyanalyzerDoc, - Requires: []*analysis.Analyzer{buildssa.Analyzer}, - Run: func(pass *analysis.Pass) (any, error) { - issues, err := runUnparam(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 - }, - } - - return goanalysis.NewLinter( - linterName, - "Reports unused function parameters", - []*analysis.Analyzer{analyzer}, - nil, - ).WithContextSetter(func(lintCtx *linter.Context) { - if settings.Algo != "cha" { - lintCtx.Log.Warnf("`linters-settings.unparam.algo` isn't supported by the newest `unparam`") - } - }).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runUnparam(pass *analysis.Pass, settings *config.UnparamSettings) ([]goanalysis.Issue, 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 nil, err - } - - var issues []goanalysis.Issue - for _, i := range unparamIssues { - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - Pos: pass.Fset.Position(i.Pos()), - Text: i.Message(), - FromLinter: linterName, - }, pass)) - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/unused/unused.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/unused/unused.go deleted file mode 100644 index 7b2b478fc..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/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/pkg/golinters/usestdlibvars/usestdlibvars.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/usestdlibvars/usestdlibvars.go deleted file mode 100644 index 050e47f24..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/usestdlibvars/usestdlibvars.go +++ /dev/null @@ -1,38 +0,0 @@ -package usestdlibvars - -import ( - "github.com/sashamelentyev/usestdlibvars/pkg/analyzer" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(cfg *config.UseStdlibVarsSettings) *goanalysis.Linter { - a := analyzer.New() - - cfgMap := make(map[string]map[string]any) - if cfg != nil { - cfgMap[a.Name] = map[string]any{ - analyzer.ConstantKindFlag: cfg.ConstantKind, - analyzer.CryptoHashFlag: cfg.CryptoHash, - analyzer.HTTPMethodFlag: cfg.HTTPMethod, - analyzer.HTTPStatusCodeFlag: cfg.HTTPStatusCode, - analyzer.OSDevNullFlag: cfg.OSDevNull, - analyzer.RPCDefaultPathFlag: cfg.DefaultRPCPath, - analyzer.SQLIsolationLevelFlag: cfg.SQLIsolationLevel, - analyzer.SyslogPriorityFlag: cfg.SyslogPriority, - analyzer.TimeLayoutFlag: cfg.TimeLayout, - analyzer.TimeMonthFlag: cfg.TimeMonth, - analyzer.TimeWeekdayFlag: cfg.TimeWeekday, - analyzer.TLSSignatureSchemeFlag: cfg.TLSSignatureScheme, - } - } - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - cfgMap, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/varnamelen/varnamelen.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/varnamelen/varnamelen.go deleted file mode 100644 index 6cb57ffa5..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/varnamelen/varnamelen.go +++ /dev/null @@ -1,46 +0,0 @@ -package varnamelen - -import ( - "strconv" - "strings" - - "github.com/blizzy78/varnamelen" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.VarnamelenSettings) *goanalysis.Linter { - analyzer := varnamelen.NewAnalyzer() - cfg := map[string]map[string]any{} - - if settings != nil { - vnlCfg := 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 { - vnlCfg["maxDistance"] = strconv.Itoa(settings.MaxDistance) - } - if settings.MinNameLength > 0 { - vnlCfg["minNameLength"] = strconv.Itoa(settings.MinNameLength) - } - - cfg[analyzer.Name] = vnlCfg - } - - return goanalysis.NewLinter( - analyzer.Name, - "checks that the length of a variable's name matches its scope", - []*analysis.Analyzer{analyzer}, - cfg, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wastedassign/wastedassign.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/wastedassign/wastedassign.go deleted file mode 100644 index 094fa95c2..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wastedassign/wastedassign.go +++ /dev/null @@ -1,19 +0,0 @@ -package wastedassign - -import ( - "github.com/sanposhiho/wastedassign/v2" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := wastedassign.Analyzer - - return goanalysis.NewLinter( - a.Name, - "Finds wasted assignment statements", - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/whitespace/whitespace.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/whitespace/whitespace.go deleted file mode 100644 index 721bfada1..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/whitespace/whitespace.go +++ /dev/null @@ -1,102 +0,0 @@ -package whitespace - -import ( - "fmt" - "sync" - - "github.com/ultraware/whitespace" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/result" -) - -const linterName = "whitespace" - -func New(settings *config.WhitespaceSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []goanalysis.Issue - - var wsSettings whitespace.Settings - if settings != nil { - wsSettings = whitespace.Settings{ - Mode: whitespace.RunningModeGolangCI, - MultiIf: settings.MultiIf, - MultiFunc: settings.MultiFunc, - } - } - - a := whitespace.NewAnalyzer(&wsSettings) - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithContextSetter(func(_ *linter.Context) { - a.Run = func(pass *analysis.Pass) (any, error) { - issues, err := runWhitespace(pass, wsSettings) - 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 runWhitespace(pass *analysis.Pass, wsSettings whitespace.Settings) ([]goanalysis.Issue, error) { - lintIssues := whitespace.Run(pass, &wsSettings) - - issues := make([]goanalysis.Issue, len(lintIssues)) - for i, issue := range lintIssues { - report := &result.Issue{ - FromLinter: linterName, - Pos: pass.Fset.PositionFor(issue.Diagnostic, false), - Text: issue.Message, - } - - switch issue.MessageType { - case whitespace.MessageTypeRemove: - if len(issue.LineNumbers) == 0 { - continue - } - - report.LineRange = &result.Range{ - From: issue.LineNumbers[0], - To: issue.LineNumbers[len(issue.LineNumbers)-1], - } - - report.Replacement = &result.Replacement{NeedOnlyDelete: true} - - case whitespace.MessageTypeAdd: - report.Pos = pass.Fset.PositionFor(issue.FixStart, false) - report.Replacement = &result.Replacement{ - Inline: &result.InlineFix{ - StartCol: 0, - Length: 1, - NewString: "\n\t", - }, - } - - default: - return nil, fmt.Errorf("unknown message type: %v", issue.MessageType) - } - - issues[i] = goanalysis.NewIssue(report, pass) - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wrapcheck/wrapcheck.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/wrapcheck/wrapcheck.go deleted file mode 100644 index 96ec2eeae..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wrapcheck/wrapcheck.go +++ /dev/null @@ -1,36 +0,0 @@ -package wrapcheck - -import ( - "github.com/tomarrell/wrapcheck/v2/wrapcheck" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.WrapcheckSettings) *goanalysis.Linter { - cfg := wrapcheck.NewDefaultConfig() - if settings != nil { - 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 - } - } - - a := wrapcheck.NewAnalyzer(cfg) - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wsl/wsl.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/wsl/wsl.go deleted file mode 100644 index c728340ec..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/wsl/wsl.go +++ /dev/null @@ -1,40 +0,0 @@ -package wsl - -import ( - "github.com/bombsimon/wsl/v4" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New(settings *config.WSLSettings) *goanalysis.Linter { - var conf *wsl.Configuration - if settings != nil { - conf = &wsl.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, - ErrorVariableNames: settings.ErrorVariableNames, - ForceExclusiveShortDeclarations: settings.ForceExclusiveShortDeclarations, - IncludeGenerated: true, // force to true because golangci-lint already have a way to filter generated files. - } - } - - a := wsl.NewAnalyzer(conf) - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/zerologlint/zerologlint.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/zerologlint/zerologlint.go deleted file mode 100644 index 6ca74020c..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/zerologlint/zerologlint.go +++ /dev/null @@ -1,19 +0,0 @@ -package zerologlint - -import ( - "github.com/ykadowak/zerologlint" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - a := zerologlint.Analyzer - - return goanalysis.NewLinter( - a.Name, - a.Doc, - []*analysis.Analyzer{a}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/goutil/env.go b/vendor/github.com/golangci/golangci-lint/pkg/goutil/env.go deleted file mode 100644 index 7b748d8e9..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/goutil/env.go +++ /dev/null @@ -1,63 +0,0 @@ -package goutil - -import ( - "context" - "encoding/json" - "fmt" - "os" - "os/exec" - "strings" - "time" - - "github.com/golangci/golangci-lint/pkg/logutils" -) - -type EnvKey string - -const ( - EnvGoCache EnvKey = "GOCACHE" - EnvGoRoot EnvKey = "GOROOT" -) - -type Env struct { - vars map[string]string - log logutils.Log - debugf logutils.DebugFunc -} - -func NewEnv(log logutils.Log) *Env { - return &Env{ - vars: map[string]string{}, - log: log, - debugf: logutils.Debug(logutils.DebugKeyEnv), - } -} - -func (e Env) Discover(ctx context.Context) error { - startedAt := time.Now() - - //nolint:gosec // Everything is static here. - cmd := exec.CommandContext(ctx, "go", "env", "-json", string(EnvGoCache), string(EnvGoRoot)) - - out, err := cmd.Output() - if err != nil { - return fmt.Errorf("failed to run '%s': %w", strings.Join(cmd.Args, " "), err) - } - - if err = json.Unmarshal(out, &e.vars); err != nil { - return fmt.Errorf("failed to parse '%s' json: %w", strings.Join(cmd.Args, " "), err) - } - - e.debugf("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/pkg/goutil/version.go b/vendor/github.com/golangci/golangci-lint/pkg/goutil/version.go deleted file mode 100644 index 4f42ebd1b..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/goutil/version.go +++ /dev/null @@ -1,75 +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) { - parts := strings.Fields(rv) - - for _, part := range parts { - // 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/pkg/lint/context.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/context.go deleted file mode 100644 index 160620338..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/lint/context.go +++ /dev/null @@ -1,64 +0,0 @@ -package lint - -import ( - "context" - "fmt" - - "github.com/golangci/golangci-lint/internal/pkgcache" - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/exitcodes" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/logutils" -) - -type ContextBuilder struct { - cfg *config.Config - - pkgLoader *PackageLoader - - fileCache *fsutils.FileCache - pkgCache *pkgcache.Cache - - loadGuard *load.Guard -} - -func NewContextBuilder(cfg *config.Config, pkgLoader *PackageLoader, - fileCache *fsutils.FileCache, pkgCache *pkgcache.Cache, loadGuard *load.Guard, -) *ContextBuilder { - return &ContextBuilder{ - cfg: cfg, - pkgLoader: pkgLoader, - fileCache: fileCache, - 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, - FileCache: cl.fileCache, - PkgCache: cl.pkgCache, - LoadGuard: cl.loadGuard, - } - - return ret, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/config.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/config.go deleted file mode 100644 index 57c51fa75..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/config.go +++ /dev/null @@ -1,181 +0,0 @@ -package linter - -import ( - "fmt" - - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/pkg/config" -) - -const ( - PresetBugs = "bugs" // Related to bugs detection. - PresetComment = "comment" // Related to comments analysis. - PresetComplexity = "complexity" // Related to code complexity analysis. - PresetError = "error" // Related to error handling analysis. - PresetFormatting = "format" // Related to code formatting. - PresetImport = "import" // Related to imports analysis. - PresetMetaLinter = "metalinter" // Related to linter that contains multiple rules or multiple linters. - PresetModule = "module" // Related to Go modules analysis. - PresetPerformance = "performance" // Related to performance. - PresetSQL = "sql" // Related to SQL. - PresetStyle = "style" // Related to coding style. - PresetTest = "test" // Related to the analysis of the code of the tests. - PresetUnused = "unused" // Related to the detection of unused code. -) - -// 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 -} - -type Config struct { - Linter Linter - EnabledByDefault bool - - LoadMode packages.LoadMode - - InPresets []string - 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 (lc *Config) WithEnabledByDefault() *Config { - lc.EnabledByDefault = true - return lc -} - -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 - 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) WithPresets(presets ...string) *Config { - lc.InPresets = presets - return lc -} - -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, replacement string, level DeprecationLevel) *Config { - lc.Deprecation = &Deprecation{ - Since: version, - Message: message, - Replacement: replacement, - Level: level, - } - return lc -} - -func (lc *Config) DeprecatedWarning(message, version, replacement string) *Config { - return lc.Deprecated(message, version, replacement, DeprecationWarning) -} - -func (lc *Config) DeprecatedError(message, version, replacement string) *Config { - return lc.Deprecated(message, version, replacement, DeprecationError) -} - -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 IsGoLowerThanGo122() func(cfg *config.Config) error { - return func(cfg *config.Config) error { - if cfg == nil || config.IsGoGreaterThanOrEqual(cfg.Run.Go, "1.22") { - return nil - } - - return fmt.Errorf("this linter is disabled because the Go version (%s) of your project is lower than Go 1.22", cfg.Run.Go) - } -} - -func NewConfig(linter Linter) *Config { - lc := &Config{ - Linter: linter, - } - return lc.WithLoadFiles() -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/context.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/context.go deleted file mode 100644 index 5c03630b2..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/context.go +++ /dev/null @@ -1,48 +0,0 @@ -package linter - -import ( - "go/ast" - - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/internal/pkgcache" - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/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 - FileCache *fsutils.FileCache - Log logutils.Log - - PkgCache *pkgcache.Cache - LoadGuard *load.Guard -} - -func (c *Context) Settings() *config.LintersSettings { - return &c.Cfg.LintersSettings -} - -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/pkg/lint/linter/linter.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/linter.go deleted file mode 100644 index 088aa3d78..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/lint/linter/linter.go +++ /dev/null @@ -1,67 +0,0 @@ -package linter - -import ( - "context" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/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/pkg/lint/lintersdb/builder_linter.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_linter.go deleted file mode 100644 index c06cd9a03..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_linter.go +++ /dev/null @@ -1,843 +0,0 @@ -package lintersdb - -import ( - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/golinters" - "github.com/golangci/golangci-lint/pkg/golinters/asasalint" - "github.com/golangci/golangci-lint/pkg/golinters/asciicheck" - "github.com/golangci/golangci-lint/pkg/golinters/bidichk" - "github.com/golangci/golangci-lint/pkg/golinters/bodyclose" - "github.com/golangci/golangci-lint/pkg/golinters/canonicalheader" - "github.com/golangci/golangci-lint/pkg/golinters/containedctx" - "github.com/golangci/golangci-lint/pkg/golinters/contextcheck" - "github.com/golangci/golangci-lint/pkg/golinters/copyloopvar" - "github.com/golangci/golangci-lint/pkg/golinters/cyclop" - "github.com/golangci/golangci-lint/pkg/golinters/decorder" - "github.com/golangci/golangci-lint/pkg/golinters/depguard" - "github.com/golangci/golangci-lint/pkg/golinters/dogsled" - "github.com/golangci/golangci-lint/pkg/golinters/dupl" - "github.com/golangci/golangci-lint/pkg/golinters/dupword" - "github.com/golangci/golangci-lint/pkg/golinters/durationcheck" - "github.com/golangci/golangci-lint/pkg/golinters/err113" - "github.com/golangci/golangci-lint/pkg/golinters/errcheck" - "github.com/golangci/golangci-lint/pkg/golinters/errchkjson" - "github.com/golangci/golangci-lint/pkg/golinters/errname" - "github.com/golangci/golangci-lint/pkg/golinters/errorlint" - "github.com/golangci/golangci-lint/pkg/golinters/execinquery" - "github.com/golangci/golangci-lint/pkg/golinters/exhaustive" - "github.com/golangci/golangci-lint/pkg/golinters/exhaustruct" - "github.com/golangci/golangci-lint/pkg/golinters/exportloopref" - "github.com/golangci/golangci-lint/pkg/golinters/fatcontext" - "github.com/golangci/golangci-lint/pkg/golinters/forbidigo" - "github.com/golangci/golangci-lint/pkg/golinters/forcetypeassert" - "github.com/golangci/golangci-lint/pkg/golinters/funlen" - "github.com/golangci/golangci-lint/pkg/golinters/gci" - "github.com/golangci/golangci-lint/pkg/golinters/ginkgolinter" - "github.com/golangci/golangci-lint/pkg/golinters/gocheckcompilerdirectives" - "github.com/golangci/golangci-lint/pkg/golinters/gochecknoglobals" - "github.com/golangci/golangci-lint/pkg/golinters/gochecknoinits" - "github.com/golangci/golangci-lint/pkg/golinters/gochecksumtype" - "github.com/golangci/golangci-lint/pkg/golinters/gocognit" - "github.com/golangci/golangci-lint/pkg/golinters/goconst" - "github.com/golangci/golangci-lint/pkg/golinters/gocritic" - "github.com/golangci/golangci-lint/pkg/golinters/gocyclo" - "github.com/golangci/golangci-lint/pkg/golinters/godot" - "github.com/golangci/golangci-lint/pkg/golinters/godox" - "github.com/golangci/golangci-lint/pkg/golinters/gofmt" - "github.com/golangci/golangci-lint/pkg/golinters/gofumpt" - "github.com/golangci/golangci-lint/pkg/golinters/goheader" - "github.com/golangci/golangci-lint/pkg/golinters/goimports" - "github.com/golangci/golangci-lint/pkg/golinters/gomoddirectives" - "github.com/golangci/golangci-lint/pkg/golinters/gomodguard" - "github.com/golangci/golangci-lint/pkg/golinters/goprintffuncname" - "github.com/golangci/golangci-lint/pkg/golinters/gosec" - "github.com/golangci/golangci-lint/pkg/golinters/gosimple" - "github.com/golangci/golangci-lint/pkg/golinters/gosmopolitan" - "github.com/golangci/golangci-lint/pkg/golinters/govet" - "github.com/golangci/golangci-lint/pkg/golinters/grouper" - "github.com/golangci/golangci-lint/pkg/golinters/importas" - "github.com/golangci/golangci-lint/pkg/golinters/inamedparam" - "github.com/golangci/golangci-lint/pkg/golinters/ineffassign" - "github.com/golangci/golangci-lint/pkg/golinters/interfacebloat" - "github.com/golangci/golangci-lint/pkg/golinters/intrange" - "github.com/golangci/golangci-lint/pkg/golinters/ireturn" - "github.com/golangci/golangci-lint/pkg/golinters/lll" - "github.com/golangci/golangci-lint/pkg/golinters/loggercheck" - "github.com/golangci/golangci-lint/pkg/golinters/maintidx" - "github.com/golangci/golangci-lint/pkg/golinters/makezero" - "github.com/golangci/golangci-lint/pkg/golinters/mirror" - "github.com/golangci/golangci-lint/pkg/golinters/misspell" - "github.com/golangci/golangci-lint/pkg/golinters/mnd" - "github.com/golangci/golangci-lint/pkg/golinters/musttag" - "github.com/golangci/golangci-lint/pkg/golinters/nakedret" - "github.com/golangci/golangci-lint/pkg/golinters/nestif" - "github.com/golangci/golangci-lint/pkg/golinters/nilerr" - "github.com/golangci/golangci-lint/pkg/golinters/nilnil" - "github.com/golangci/golangci-lint/pkg/golinters/nlreturn" - "github.com/golangci/golangci-lint/pkg/golinters/noctx" - "github.com/golangci/golangci-lint/pkg/golinters/nolintlint" - "github.com/golangci/golangci-lint/pkg/golinters/nonamedreturns" - "github.com/golangci/golangci-lint/pkg/golinters/nosprintfhostport" - "github.com/golangci/golangci-lint/pkg/golinters/paralleltest" - "github.com/golangci/golangci-lint/pkg/golinters/perfsprint" - "github.com/golangci/golangci-lint/pkg/golinters/prealloc" - "github.com/golangci/golangci-lint/pkg/golinters/predeclared" - "github.com/golangci/golangci-lint/pkg/golinters/promlinter" - "github.com/golangci/golangci-lint/pkg/golinters/protogetter" - "github.com/golangci/golangci-lint/pkg/golinters/reassign" - "github.com/golangci/golangci-lint/pkg/golinters/revive" - "github.com/golangci/golangci-lint/pkg/golinters/rowserrcheck" - "github.com/golangci/golangci-lint/pkg/golinters/sloglint" - "github.com/golangci/golangci-lint/pkg/golinters/spancheck" - "github.com/golangci/golangci-lint/pkg/golinters/sqlclosecheck" - "github.com/golangci/golangci-lint/pkg/golinters/staticcheck" - "github.com/golangci/golangci-lint/pkg/golinters/stylecheck" - "github.com/golangci/golangci-lint/pkg/golinters/tagalign" - "github.com/golangci/golangci-lint/pkg/golinters/tagliatelle" - "github.com/golangci/golangci-lint/pkg/golinters/tenv" - "github.com/golangci/golangci-lint/pkg/golinters/testableexamples" - "github.com/golangci/golangci-lint/pkg/golinters/testifylint" - "github.com/golangci/golangci-lint/pkg/golinters/testpackage" - "github.com/golangci/golangci-lint/pkg/golinters/thelper" - "github.com/golangci/golangci-lint/pkg/golinters/tparallel" - "github.com/golangci/golangci-lint/pkg/golinters/unconvert" - "github.com/golangci/golangci-lint/pkg/golinters/unparam" - "github.com/golangci/golangci-lint/pkg/golinters/unused" - "github.com/golangci/golangci-lint/pkg/golinters/usestdlibvars" - "github.com/golangci/golangci-lint/pkg/golinters/varnamelen" - "github.com/golangci/golangci-lint/pkg/golinters/wastedassign" - "github.com/golangci/golangci-lint/pkg/golinters/whitespace" - "github.com/golangci/golangci-lint/pkg/golinters/wrapcheck" - "github.com/golangci/golangci-lint/pkg/golinters/wsl" - "github.com/golangci/golangci-lint/pkg/golinters/zerologlint" - "github.com/golangci/golangci-lint/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 - } - - const megacheckName = "megacheck" - - // 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(asasalint.New(&cfg.LintersSettings.Asasalint)). - WithSince("1.47.0"). - WithPresets(linter.PresetBugs). - WithLoadForGoAnalysis(). - WithURL("https://github.com/alingse/asasalint"), - - linter.NewConfig(asciicheck.New()). - WithSince("v1.26.0"). - WithPresets(linter.PresetBugs, linter.PresetStyle). - WithURL("https://github.com/tdakkota/asciicheck"), - - linter.NewConfig(bidichk.New(&cfg.LintersSettings.BiDiChk)). - WithSince("1.43.0"). - WithPresets(linter.PresetBugs). - WithURL("https://github.com/breml/bidichk"), - - linter.NewConfig(bodyclose.New()). - WithSince("v1.18.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetPerformance, linter.PresetBugs). - WithURL("https://github.com/timakin/bodyclose"), - - linter.NewConfig(canonicalheader.New()). - WithSince("v1.58.0"). - WithPresets(linter.PresetStyle). - WithLoadForGoAnalysis(). - WithURL("https://github.com/lasiar/canonicalHeader"), - - linter.NewConfig(containedctx.New()). - WithSince("1.44.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/sivchari/containedctx"), - - linter.NewConfig(contextcheck.New()). - WithSince("v1.43.0"). - WithPresets(linter.PresetBugs). - WithLoadForGoAnalysis(). - WithURL("https://github.com/kkHAIKE/contextcheck"), - - linter.NewConfig(copyloopvar.New(&cfg.LintersSettings.CopyLoopVar)). - WithSince("v1.57.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/karamaru-alpha/copyloopvar"). - WithNoopFallback(cfg, linter.IsGoLowerThanGo122()), - - linter.NewConfig(cyclop.New(&cfg.LintersSettings.Cyclop)). - WithSince("v1.37.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetComplexity). - WithURL("https://github.com/bkielbasa/cyclop"), - - linter.NewConfig(decorder.New(&cfg.LintersSettings.Decorder)). - WithSince("v1.44.0"). - WithPresets(linter.PresetFormatting, linter.PresetStyle). - WithURL("https://gitlab.com/bosi/decorder"), - - linter.NewConfig(linter.NewNoopDeprecated("deadcode", cfg, linter.DeprecationError)). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetUnused). - WithURL("https://github.com/remyoudompheng/go-misc/tree/master/deadcode"). - DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"), - - linter.NewConfig(depguard.New(&cfg.LintersSettings.Depguard)). - WithSince("v1.4.0"). - WithPresets(linter.PresetStyle, linter.PresetImport, linter.PresetModule). - WithURL("https://github.com/OpenPeeDeeP/depguard"), - - linter.NewConfig(dogsled.New(&cfg.LintersSettings.Dogsled)). - WithSince("v1.19.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/alexkohler/dogsled"), - - linter.NewConfig(dupl.New(&cfg.LintersSettings.Dupl)). - WithSince("v1.0.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/mibk/dupl"), - - linter.NewConfig(dupword.New(&cfg.LintersSettings.DupWord)). - WithSince("1.50.0"). - WithPresets(linter.PresetComment). - WithURL("https://github.com/Abirdcfly/dupword"), - - linter.NewConfig(durationcheck.New()). - WithSince("v1.37.0"). - WithPresets(linter.PresetBugs). - WithLoadForGoAnalysis(). - WithURL("https://github.com/charithe/durationcheck"), - - linter.NewConfig(errcheck.New(&cfg.LintersSettings.Errcheck)). - WithEnabledByDefault(). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetBugs, linter.PresetError). - WithURL("https://github.com/kisielk/errcheck"), - - linter.NewConfig(errchkjson.New(&cfg.LintersSettings.ErrChkJSON)). - WithSince("1.44.0"). - WithPresets(linter.PresetBugs). - WithLoadForGoAnalysis(). - WithURL("https://github.com/breml/errchkjson"), - - linter.NewConfig(errname.New()). - WithSince("v1.42.0"). - WithPresets(linter.PresetStyle). - WithLoadForGoAnalysis(). - WithURL("https://github.com/Antonboom/errname"), - - linter.NewConfig(errorlint.New(&cfg.LintersSettings.ErrorLint)). - WithSince("v1.32.0"). - WithPresets(linter.PresetBugs, linter.PresetError). - WithLoadForGoAnalysis(). - WithURL("https://github.com/polyfloyd/go-errorlint"), - - linter.NewConfig(execinquery.New()). - WithSince("v1.46.0"). - WithPresets(linter.PresetSQL). - WithLoadForGoAnalysis(). - WithURL("https://github.com/1uf3/execinquery"). - DeprecatedWarning("The repository of the linter has been archived by the owner.", "v1.58.0", ""), - - linter.NewConfig(exhaustive.New(&cfg.LintersSettings.Exhaustive)). - WithSince(" v1.28.0"). - WithPresets(linter.PresetBugs). - WithLoadForGoAnalysis(). - WithURL("https://github.com/nishanths/exhaustive"), - - linter.NewConfig(linter.NewNoopDeprecated("exhaustivestruct", cfg, linter.DeprecationError)). - WithSince("v1.32.0"). - WithPresets(linter.PresetStyle, linter.PresetTest). - WithLoadForGoAnalysis(). - WithURL("https://github.com/mbilski/exhaustivestruct"). - DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.46.0", "exhaustruct"), - - linter.NewConfig(exhaustruct.New(&cfg.LintersSettings.Exhaustruct)). - WithSince("v1.46.0"). - WithPresets(linter.PresetStyle, linter.PresetTest). - WithLoadForGoAnalysis(). - WithURL("https://github.com/GaijinEntertainment/go-exhaustruct"), - - linter.NewConfig(exportloopref.New()). - WithSince("v1.28.0"). - WithPresets(linter.PresetBugs). - WithLoadForGoAnalysis(). - WithURL("https://github.com/kyoh86/exportloopref"). - DeprecatedWarning("Since Go1.22 (loopvar) this linter is no longer relevant.", "v1.60.2", "copyloopvar"), - - linter.NewConfig(forbidigo.New(&cfg.LintersSettings.Forbidigo)). - WithSince("v1.34.0"). - WithPresets(linter.PresetStyle). - // 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"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/gostaticanalysis/forcetypeassert"), - - linter.NewConfig(fatcontext.New()). - WithSince("1.58.0"). - WithPresets(linter.PresetPerformance). - WithLoadForGoAnalysis(). - WithURL("https://github.com/Crocmagnon/fatcontext"), - - linter.NewConfig(funlen.New(&cfg.LintersSettings.Funlen)). - WithSince("v1.18.0"). - WithPresets(linter.PresetComplexity). - WithURL("https://github.com/ultraware/funlen"), - - linter.NewConfig(gci.New(&cfg.LintersSettings.Gci)). - WithSince("v1.30.0"). - WithPresets(linter.PresetFormatting, linter.PresetImport). - WithAutoFix(). - WithURL("https://github.com/daixiang0/gci"), - - linter.NewConfig(ginkgolinter.New(&cfg.LintersSettings.GinkgoLinter)). - WithSince("v1.51.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/nunnatsa/ginkgolinter"), - - linter.NewConfig(gocheckcompilerdirectives.New()). - WithSince("v1.51.0"). - WithPresets(linter.PresetBugs). - WithURL("https://github.com/leighmcculloch/gocheckcompilerdirectives"), - - linter.NewConfig(gochecknoglobals.New()). - WithSince("v1.12.0"). - WithPresets(linter.PresetStyle). - WithLoadForGoAnalysis(). - WithURL("https://github.com/leighmcculloch/gochecknoglobals"), - - linter.NewConfig(gochecknoinits.New()). - WithSince("v1.12.0"). - WithPresets(linter.PresetStyle), - - linter.NewConfig(gochecksumtype.New()). - WithSince("v1.55.0"). - WithPresets(linter.PresetBugs). - WithLoadForGoAnalysis(). - WithURL("https://github.com/alecthomas/go-check-sumtype"), - - linter.NewConfig(gocognit.New(&cfg.LintersSettings.Gocognit)). - WithSince("v1.20.0"). - WithPresets(linter.PresetComplexity). - WithURL("https://github.com/uudashr/gocognit"), - - linter.NewConfig(goconst.New(&cfg.LintersSettings.Goconst)). - WithSince("v1.0.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/jgautheron/goconst"), - - linter.NewConfig(gocritic.New(&cfg.LintersSettings.Gocritic)). - WithSince("v1.12.0"). - WithPresets(linter.PresetStyle, linter.PresetMetaLinter). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/go-critic/go-critic"), - - linter.NewConfig(gocyclo.New(&cfg.LintersSettings.Gocyclo)). - WithSince("v1.0.0"). - WithPresets(linter.PresetComplexity). - WithURL("https://github.com/fzipp/gocyclo"), - - linter.NewConfig(godot.New(&cfg.LintersSettings.Godot)). - WithSince("v1.25.0"). - WithPresets(linter.PresetStyle, linter.PresetComment). - WithAutoFix(). - WithURL("https://github.com/tetafro/godot"), - - linter.NewConfig(godox.New(&cfg.LintersSettings.Godox)). - WithSince("v1.19.0"). - WithPresets(linter.PresetStyle, linter.PresetComment). - WithURL("https://github.com/matoous/godox"), - - linter.NewConfig(err113.New()). - WithSince("v1.26.0"). - WithPresets(linter.PresetStyle, linter.PresetError). - WithLoadForGoAnalysis(). - WithAlternativeNames("goerr113"). - WithURL("https://github.com/Djarvur/go-err113"), - - linter.NewConfig(gofmt.New(&cfg.LintersSettings.Gofmt)). - WithSince("v1.0.0"). - WithPresets(linter.PresetFormatting). - WithAutoFix(). - WithURL("https://pkg.go.dev/cmd/gofmt"), - - linter.NewConfig(gofumpt.New(&cfg.LintersSettings.Gofumpt)). - WithSince("v1.28.0"). - WithPresets(linter.PresetFormatting). - WithAutoFix(). - WithURL("https://github.com/mvdan/gofumpt"), - - linter.NewConfig(goheader.New(&cfg.LintersSettings.Goheader)). - WithSince("v1.28.0"). - WithPresets(linter.PresetStyle). - WithAutoFix(). - WithURL("https://github.com/denis-tingaikin/go-header"), - - linter.NewConfig(goimports.New(&cfg.LintersSettings.Goimports)). - WithSince("v1.20.0"). - WithPresets(linter.PresetFormatting, linter.PresetImport). - WithAutoFix(). - WithURL("https://pkg.go.dev/golang.org/x/tools/cmd/goimports"), - - linter.NewConfig(linter.NewNoopDeprecated("golint", cfg, linter.DeprecationError)). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/golang/lint"). - DeprecatedError("The repository of the linter has been archived by the owner.", "v1.41.0", "revive"), - - linter.NewConfig(mnd.New(&cfg.LintersSettings.Mnd)). - WithSince("v1.22.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/tommy-muehle/go-mnd"), - - linter.NewConfig(mnd.NewGoMND(&cfg.LintersSettings.Gomnd)). - WithSince("v1.22.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/tommy-muehle/go-mnd"). - DeprecatedWarning("The linter has been renamed.", "v1.58.0", "mnd"), - - linter.NewConfig(gomoddirectives.New(&cfg.LintersSettings.GoModDirectives)). - WithSince("v1.39.0"). - WithPresets(linter.PresetStyle, linter.PresetModule). - WithURL("https://github.com/ldez/gomoddirectives"), - - linter.NewConfig(gomodguard.New(&cfg.LintersSettings.Gomodguard)). - WithSince("v1.25.0"). - WithPresets(linter.PresetStyle, linter.PresetImport, linter.PresetModule). - WithURL("https://github.com/ryancurrah/gomodguard"), - - linter.NewConfig(goprintffuncname.New()). - WithSince("v1.23.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/jirfag/go-printf-func-name"), - - linter.NewConfig(gosec.New(&cfg.LintersSettings.Gosec)). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetBugs). - WithURL("https://github.com/securego/gosec"). - WithAlternativeNames("gas"), - - linter.NewConfig(gosimple.New(&cfg.LintersSettings.Gosimple)). - WithEnabledByDefault(). - WithSince("v1.20.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle). - WithAlternativeNames(megacheckName). - WithURL("https://github.com/dominikh/go-tools/tree/master/simple"), - - linter.NewConfig(gosmopolitan.New(&cfg.LintersSettings.Gosmopolitan)). - WithSince("v1.53.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetBugs). - WithURL("https://github.com/xen0n/gosmopolitan"), - - linter.NewConfig(govet.New(&cfg.LintersSettings.Govet)). - WithEnabledByDefault(). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetBugs, linter.PresetMetaLinter). - WithAlternativeNames("vet", "vetshadow"). - WithURL("https://pkg.go.dev/cmd/vet"), - - linter.NewConfig(grouper.New(&cfg.LintersSettings.Grouper)). - WithSince("v1.44.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/leonklingele/grouper"), - - linter.NewConfig(linter.NewNoopDeprecated("ifshort", cfg, linter.DeprecationError)). - WithSince("v1.36.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/esimonov/ifshort"). - DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.48.0", ""), - - linter.NewConfig(importas.New(&cfg.LintersSettings.ImportAs)). - WithSince("v1.38.0"). - WithPresets(linter.PresetStyle). - WithLoadForGoAnalysis(). - WithURL("https://github.com/julz/importas"), - - linter.NewConfig(inamedparam.New(&cfg.LintersSettings.Inamedparam)). - WithSince("v1.55.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/macabu/inamedparam"), - - linter.NewConfig(ineffassign.New()). - WithEnabledByDefault(). - WithSince("v1.0.0"). - WithPresets(linter.PresetUnused). - WithURL("https://github.com/gordonklaus/ineffassign"), - - linter.NewConfig(interfacebloat.New(&cfg.LintersSettings.InterfaceBloat)). - WithSince("v1.49.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/sashamelentyev/interfacebloat"), - - linter.NewConfig(linter.NewNoopDeprecated("interfacer", cfg, linter.DeprecationError)). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/mvdan/interfacer"). - DeprecatedError("The repository of the linter has been archived by the owner.", "v1.38.0", ""), - - linter.NewConfig(intrange.New()). - WithSince("v1.57.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/ckaznocha/intrange"). - WithNoopFallback(cfg, linter.IsGoLowerThanGo122()), - - linter.NewConfig(ireturn.New(&cfg.LintersSettings.Ireturn)). - WithSince("v1.43.0"). - WithPresets(linter.PresetStyle). - WithLoadForGoAnalysis(). - WithURL("https://github.com/butuzov/ireturn"), - - linter.NewConfig(lll.New(&cfg.LintersSettings.Lll)). - WithSince("v1.8.0"). - WithPresets(linter.PresetStyle), - - linter.NewConfig(loggercheck.New(&cfg.LintersSettings.LoggerCheck)). - WithSince("v1.49.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle, linter.PresetBugs). - WithAlternativeNames("logrlint"). - WithURL("https://github.com/timonwong/loggercheck"), - - linter.NewConfig(maintidx.New(&cfg.LintersSettings.MaintIdx)). - WithSince("v1.44.0"). - WithPresets(linter.PresetComplexity). - WithURL("https://github.com/yagipy/maintidx"), - - linter.NewConfig(makezero.New(&cfg.LintersSettings.Makezero)). - WithSince("v1.34.0"). - WithPresets(linter.PresetStyle, linter.PresetBugs). - WithLoadForGoAnalysis(). - WithURL("https://github.com/ashanbrown/makezero"), - - linter.NewConfig(linter.NewNoopDeprecated("maligned", cfg, linter.DeprecationError)). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetPerformance). - WithURL("https://github.com/mdempsky/maligned"). - DeprecatedError("The repository of the linter has been archived by the owner.", "v1.38.0", "govet 'fieldalignment'"), - - linter.NewConfig(mirror.New()). - WithSince("v1.53.0"). - WithPresets(linter.PresetStyle). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/butuzov/mirror"), - - linter.NewConfig(misspell.New(&cfg.LintersSettings.Misspell)). - WithSince("v1.8.0"). - WithPresets(linter.PresetStyle, linter.PresetComment). - WithAutoFix(). - WithURL("https://github.com/client9/misspell"), - - linter.NewConfig(musttag.New(&cfg.LintersSettings.MustTag)). - WithSince("v1.51.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle, linter.PresetBugs). - WithURL("https://github.com/go-simpler/musttag"), - - linter.NewConfig(nakedret.New(&cfg.LintersSettings.Nakedret)). - WithSince("v1.19.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/alexkohler/nakedret"), - - linter.NewConfig(nestif.New(&cfg.LintersSettings.Nestif)). - WithSince("v1.25.0"). - WithPresets(linter.PresetComplexity). - WithURL("https://github.com/nakabonne/nestif"), - - linter.NewConfig(nilerr.New()). - WithSince("v1.38.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetBugs). - WithURL("https://github.com/gostaticanalysis/nilerr"), - - linter.NewConfig(nilnil.New(&cfg.LintersSettings.NilNil)). - WithSince("v1.43.0"). - WithPresets(linter.PresetStyle). - WithLoadForGoAnalysis(). - WithURL("https://github.com/Antonboom/nilnil"), - - linter.NewConfig(nlreturn.New(&cfg.LintersSettings.Nlreturn)). - WithSince("v1.30.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/ssgreg/nlreturn"), - - linter.NewConfig(noctx.New()). - WithSince("v1.28.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetPerformance, linter.PresetBugs). - WithURL("https://github.com/sonatard/noctx"), - - linter.NewConfig(nonamedreturns.New(&cfg.LintersSettings.NoNamedReturns)). - WithSince("v1.46.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/firefart/nonamedreturns"), - - linter.NewConfig(linter.NewNoopDeprecated("nosnakecase", cfg, linter.DeprecationError)). - WithSince("v1.47.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/sivchari/nosnakecase"). - DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.48.1", "revive 'var-naming'"), - - linter.NewConfig(nosprintfhostport.New()). - WithSince("v1.46.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/stbenjam/no-sprintf-host-port"), - - linter.NewConfig(paralleltest.New(&cfg.LintersSettings.ParallelTest)). - WithSince("v1.33.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle, linter.PresetTest). - WithURL("https://github.com/kunwardeep/paralleltest"), - - linter.NewConfig(perfsprint.New(&cfg.LintersSettings.PerfSprint)). - WithSince("v1.55.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetPerformance). - WithURL("https://github.com/catenacyber/perfsprint"), - - linter.NewConfig(prealloc.New(&cfg.LintersSettings.Prealloc)). - WithSince("v1.19.0"). - WithPresets(linter.PresetPerformance). - WithURL("https://github.com/alexkohler/prealloc"), - - linter.NewConfig(predeclared.New(&cfg.LintersSettings.Predeclared)). - WithSince("v1.35.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/nishanths/predeclared"), - - linter.NewConfig(promlinter.New(&cfg.LintersSettings.Promlinter)). - WithSince("v1.40.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/yeya24/promlinter"), - - linter.NewConfig(protogetter.New(&cfg.LintersSettings.ProtoGetter)). - WithSince("v1.55.0"). - WithPresets(linter.PresetBugs). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/ghostiam/protogetter"), - - linter.NewConfig(reassign.New(&cfg.LintersSettings.Reassign)). - WithSince("1.49.0"). - WithPresets(linter.PresetBugs). - WithLoadForGoAnalysis(). - WithURL("https://github.com/curioswitch/go-reassign"), - - linter.NewConfig(revive.New(&cfg.LintersSettings.Revive)). - WithSince("v1.37.0"). - WithPresets(linter.PresetStyle, linter.PresetMetaLinter). - ConsiderSlow(). - WithURL("https://github.com/mgechev/revive"), - - linter.NewConfig(rowserrcheck.New(&cfg.LintersSettings.RowsErrCheck)). - WithSince("v1.23.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetBugs, linter.PresetSQL). - WithURL("https://github.com/jingyugao/rowserrcheck"), - - linter.NewConfig(sloglint.New(&cfg.LintersSettings.SlogLint)). - WithSince("v1.55.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle, linter.PresetFormatting). - WithURL("https://github.com/go-simpler/sloglint"), - - linter.NewConfig(linter.NewNoopDeprecated("scopelint", cfg, linter.DeprecationError)). - WithSince("v1.12.0"). - WithPresets(linter.PresetBugs). - WithURL("https://github.com/kyoh86/scopelint"). - DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.39.0", "exportloopref"), - - linter.NewConfig(sqlclosecheck.New()). - WithSince("v1.28.0"). - WithPresets(linter.PresetBugs, linter.PresetSQL). - WithLoadForGoAnalysis(). - WithURL("https://github.com/ryanrolds/sqlclosecheck"), - - linter.NewConfig(spancheck.New(&cfg.LintersSettings.Spancheck)). - WithSince("v1.56.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetBugs). - WithURL("https://github.com/jjti/go-spancheck"), - - linter.NewConfig(staticcheck.New(&cfg.LintersSettings.Staticcheck)). - WithEnabledByDefault(). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetBugs, linter.PresetMetaLinter). - WithAlternativeNames(megacheckName). - WithURL("https://staticcheck.io/"), - - linter.NewConfig(linter.NewNoopDeprecated("structcheck", cfg, linter.DeprecationError)). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetUnused). - WithURL("https://github.com/opennota/check"). - DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"), - - linter.NewConfig(stylecheck.New(&cfg.LintersSettings.Stylecheck)). - WithSince("v1.20.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/dominikh/go-tools/tree/master/stylecheck"), - - linter.NewConfig(tagalign.New(&cfg.LintersSettings.TagAlign)). - WithSince("v1.53.0"). - WithPresets(linter.PresetStyle, linter.PresetFormatting). - WithAutoFix(). - WithURL("https://github.com/4meepo/tagalign"), - - linter.NewConfig(tagliatelle.New(&cfg.LintersSettings.Tagliatelle)). - WithSince("v1.40.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/ldez/tagliatelle"), - - linter.NewConfig(tenv.New(&cfg.LintersSettings.Tenv)). - WithSince("v1.43.0"). - WithPresets(linter.PresetTest). - WithLoadForGoAnalysis(). - WithURL("https://github.com/sivchari/tenv"), - - linter.NewConfig(testableexamples.New()). - WithSince("v1.50.0"). - WithPresets(linter.PresetTest). - WithURL("https://github.com/maratori/testableexamples"), - - linter.NewConfig(testifylint.New(&cfg.LintersSettings.Testifylint)). - WithSince("v1.55.0"). - WithPresets(linter.PresetTest, linter.PresetBugs). - WithLoadForGoAnalysis(). - WithURL("https://github.com/Antonboom/testifylint"), - - linter.NewConfig(testpackage.New(&cfg.LintersSettings.Testpackage)). - WithSince("v1.25.0"). - WithPresets(linter.PresetStyle, linter.PresetTest). - WithURL("https://github.com/maratori/testpackage"), - - linter.NewConfig(thelper.New(&cfg.LintersSettings.Thelper)). - WithSince("v1.34.0"). - WithPresets(linter.PresetTest). - WithLoadForGoAnalysis(). - WithURL("https://github.com/kulti/thelper"), - - linter.NewConfig(tparallel.New()). - WithSince("v1.32.0"). - WithPresets(linter.PresetStyle, linter.PresetTest). - WithLoadForGoAnalysis(). - WithURL("https://github.com/moricho/tparallel"), - - linter.NewConfig(golinters.NewTypecheck()). - WithInternal(). - WithEnabledByDefault(). - WithSince("v1.3.0"), - - linter.NewConfig(unconvert.New(&cfg.LintersSettings.Unconvert)). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/mdempsky/unconvert"), - - linter.NewConfig(unparam.New(&cfg.LintersSettings.Unparam)). - WithSince("v1.9.0"). - WithPresets(linter.PresetUnused). - WithLoadForGoAnalysis(). - WithURL("https://github.com/mvdan/unparam"), - - linter.NewConfig(unused.New(&cfg.LintersSettings.Unused)). - WithEnabledByDefault(). - WithSince("v1.20.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetUnused). - WithAlternativeNames(megacheckName). - ConsiderSlow(). - WithChangeTypes(). - WithURL("https://github.com/dominikh/go-tools/tree/master/unused"), - - linter.NewConfig(usestdlibvars.New(&cfg.LintersSettings.UseStdlibVars)). - WithSince("v1.48.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/sashamelentyev/usestdlibvars"), - - linter.NewConfig(linter.NewNoopDeprecated("varcheck", cfg, linter.DeprecationError)). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithPresets(linter.PresetUnused). - WithURL("https://github.com/opennota/check"). - DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"), - - linter.NewConfig(varnamelen.New(&cfg.LintersSettings.Varnamelen)). - WithSince("v1.43.0"). - WithPresets(linter.PresetStyle). - WithLoadForGoAnalysis(). - WithURL("https://github.com/blizzy78/varnamelen"), - - linter.NewConfig(wastedassign.New()). - WithSince("v1.38.0"). - WithPresets(linter.PresetStyle). - WithLoadForGoAnalysis(). - WithURL("https://github.com/sanposhiho/wastedassign"), - - linter.NewConfig(whitespace.New(&cfg.LintersSettings.Whitespace)). - WithSince("v1.19.0"). - WithPresets(linter.PresetStyle). - WithAutoFix(). - WithURL("https://github.com/ultraware/whitespace"), - - linter.NewConfig(wrapcheck.New(&cfg.LintersSettings.Wrapcheck)). - WithSince("v1.32.0"). - WithPresets(linter.PresetStyle, linter.PresetError). - WithLoadForGoAnalysis(). - WithURL("https://github.com/tomarrell/wrapcheck"), - - linter.NewConfig(wsl.New(&cfg.LintersSettings.WSL)). - WithSince("v1.20.0"). - WithPresets(linter.PresetStyle). - WithURL("https://github.com/bombsimon/wsl"), - - linter.NewConfig(zerologlint.New()). - WithSince("v1.53.0"). - WithPresets(linter.PresetBugs). - 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.LintersSettings.NoLintLint)). - WithSince("v1.26.0"). - WithPresets(linter.PresetStyle). - WithAutoFix(). - WithURL("https://github.com/golangci/golangci-lint/blob/master/pkg/golinters/nolintlint/README.md"), - }, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_go.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_go.go deleted file mode 100644 index 88f3e2ae3..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_go.go +++ /dev/null @@ -1,136 +0,0 @@ -package lintersdb - -import ( - "errors" - "fmt" - "path/filepath" - "plugin" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/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.LintersSettings.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). - WithEnabledByDefault(). - 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) { - // resolve non-absolute paths relative to config file's directory - path = filepath.Join(cfg.GetConfigDir(), 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/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/pkg/lint/lintersdb/builder_plugin_module.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/builder_plugin_module.go deleted file mode 100644 index 60fb58d8c..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/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.LintersSettings.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). - WithEnabledByDefault(). - 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/pkg/lint/lintersdb/manager.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/manager.go deleted file mode 100644 index 75ab53d7c..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/manager.go +++ /dev/null @@ -1,313 +0,0 @@ -package lintersdb - -import ( - "fmt" - "os" - "slices" - "sort" - - "golang.org/x/exp/maps" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/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) GetAllLinterConfigsForPreset(p string) []*linter.Config { - var ret []*linter.Config - for _, lc := range m.linters { - if lc.IsDeprecated() { - continue - } - - if slices.Contains(lc.InPresets, p) { - ret = append(ret, lc) - } - } - - return ret -} - -func (m *Manager) GetEnabledLintersMap() (map[string]*linter.Config, error) { - enabledLinters := m.build(m.GetAllEnabledByDefaultLinters()) - - 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 := m.build(m.GetAllEnabledByDefaultLinters()) - m.verbosePrintLintersStatus(resultLintersSet) - - m.combineGoAnalysisLinters(resultLintersSet) - - resultLinters := maps.Values(resultLintersSet) - - // Make order of execution of linters (go/analysis metalinter and unused) stable. - sort.Slice(resultLinters, func(i, j int) bool { - a, b := resultLinters[i], resultLinters[j] - - if b.Name() == linter.LastLinter { - return true - } - - if a.Name() == linter.LastLinter { - return false - } - - if a.DoesChangeTypes != b.DoesChangeTypes { - return b.DoesChangeTypes // move type-changing linters to the end to optimize speed - } - return a.Name() < b.Name() - }) - - return resultLinters, nil -} - -func (m *Manager) GetAllEnabledByDefaultLinters() []*linter.Config { - var ret []*linter.Config - for _, lc := range m.linters { - if lc.EnabledByDefault { - ret = append(ret, lc) - } - } - - return ret -} - -//nolint:gocyclo // the complexity cannot be reduced. -func (m *Manager) build(enabledByDefaultLinters []*linter.Config) map[string]*linter.Config { - m.debugf("Linters config: %#v", m.cfg.Linters) - - resultLintersSet := map[string]*linter.Config{} - switch { - case m.cfg.Linters.DisableAll: - // no default linters - case len(m.cfg.Linters.Presets) != 0: - // imply --disable-all - case m.cfg.Linters.EnableAll: - resultLintersSet = linterConfigsToMap(m.linters) - default: - resultLintersSet = linterConfigsToMap(enabledByDefaultLinters) - } - - // --presets can only add linters to default set - for _, p := range m.cfg.Linters.Presets { - for _, lc := range m.GetAllLinterConfigsForPreset(p) { - resultLintersSet[lc.Name()] = lc - } - } - - // --fast removes slow linters from current set. - // It should be after --presets to be able to run only fast linters in preset. - // It should be before --enable and --disable to be able to enable or disable specific linter. - if m.cfg.Linters.Fast { - for name, lc := range resultLintersSet { - if lc.IsSlowLinter() { - delete(resultLintersSet, name) - } - } - } - - for _, name := range m.cfg.Linters.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()) - } - } - - // 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 -} - -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() - } - - mlConfig.InPresets = append(mlConfig.InPresets, lc.InPresets...) - - 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) - - sort.Strings(mlConfig.InPresets) - mlConfig.InPresets = slices.Compact(mlConfig.InPresets) - - 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) - - if len(m.cfg.Linters.Presets) != 0 { - sort.Strings(m.cfg.Linters.Presets) - m.log.Infof("Active presets: %s", m.cfg.Linters.Presets) - } -} - -func AllPresets() []string { - return []string{ - linter.PresetBugs, - linter.PresetComment, - linter.PresetComplexity, - linter.PresetError, - linter.PresetFormatting, - linter.PresetImport, - linter.PresetMetaLinter, - linter.PresetModule, - linter.PresetPerformance, - linter.PresetSQL, - linter.PresetStyle, - linter.PresetTest, - linter.PresetUnused, - } -} - -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 - } - - ret[lc.Name()] = lc - } - - return ret -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/validator.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/validator.go deleted file mode 100644 index 264d063aa..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/lint/lintersdb/validator.go +++ /dev/null @@ -1,120 +0,0 @@ -package lintersdb - -import ( - "errors" - "fmt" - "os" - "slices" - "strings" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/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.validatePresets, - 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/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 (Validator) validatePresets(cfg *config.Linters) error { - presets := AllPresets() - - for _, p := range cfg.Presets { - if !slices.Contains(presets, p) { - return fmt.Errorf("no such preset %q: only next presets exist: (%s)", - p, strings.Join(presets, "|")) - } - } - - if len(cfg.Presets) != 0 && cfg.EnableAll { - return errors.New("--presets is incompatible with --enable-all") - } - - 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/pkg/lint/package.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/package.go deleted file mode 100644 index c314166ca..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/lint/package.go +++ /dev/null @@ -1,283 +0,0 @@ -package lint - -import ( - "context" - "fmt" - "go/build" - "go/token" - "os" - "path/filepath" - "regexp" - "strings" - "time" - - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/exitcodes" - "github.com/golangci/golangci-lint/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/pkg/goutil" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/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, goenv *goutil.Env, loadGuard *load.Guard) *PackageLoader { - return &PackageLoader{ - cfg: cfg, - args: args, - log: log, - debugf: logutils.Debug(logutils.DebugKeyLoader), - goenv: goenv, - 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(goutil.EnvGoRoot) - if goroot == "" { - return - } - - os.Setenv(string(goutil.EnvGoRoot), 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/pkg/lint/runner.go b/vendor/github.com/golangci/golangci-lint/pkg/lint/runner.go deleted file mode 100644 index c3b983ff6..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/lint/runner.go +++ /dev/null @@ -1,242 +0,0 @@ -package lint - -import ( - "context" - "errors" - "fmt" - "runtime/debug" - "strings" - - "github.com/golangci/golangci-lint/internal/errorutil" - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/goutil" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" - "github.com/golangci/golangci-lint/pkg/result/processors" - "github.com/golangci/golangci-lint/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, args []string, goenv *goutil.Env, - lineCache *fsutils.LineCache, fileCache *fsutils.FileCache, - dbManager *lintersdb.Manager, lintCtx *linter.Context, -) (*Runner, error) { - // Beware that some processors need to add the path prefix when working with paths - // because they get invoked before the path prefixer (exclude and severity rules) - // or process other paths (skip files). - files := fsutils.NewFiles(lineCache, cfg.Output.PathPrefix) - - skipFilesProcessor, err := processors.NewSkipFiles(cfg.Issues.ExcludeFiles, cfg.Output.PathPrefix) - if err != nil { - return nil, err - } - - skipDirs := cfg.Issues.ExcludeDirs - if cfg.Issues.UseDefaultExcludeDirs { - skipDirs = append(skipDirs, processors.StdExcludeDirRegexps...) - } - - skipDirsProcessor, err := processors.NewSkipDirs(log.Child(logutils.DebugKeySkipDirs), skipDirs, args, cfg.Output.PathPrefix) - if err != nil { - return nil, err - } - - enabledLinters, err := dbManager.GetEnabledLintersMap() - if err != nil { - return nil, fmt.Errorf("failed to get enabled linters: %w", err) - } - - return &Runner{ - Processors: []processors.Processor{ - processors.NewCgo(goenv), - - // Must go after Cgo. - processors.NewFilenameUnadjuster(lintCtx.Packages, log.Child(logutils.DebugKeyFilenameUnadjuster)), - - // Must go after FilenameUnadjuster. - processors.NewInvalidIssue(log.Child(logutils.DebugKeyInvalidIssue)), - - // Must be before diff, nolint and exclude autogenerated processor at least. - processors.NewPathPrettifier(), - skipFilesProcessor, - skipDirsProcessor, // must be after path prettifier - - processors.NewAutogeneratedExclude(cfg.Issues.ExcludeGenerated), - - // Must be before exclude because users see already marked output and configure excluding by it. - processors.NewIdentifierMarker(), - - processors.NewExclude(&cfg.Issues), - processors.NewExcludeRules(log.Child(logutils.DebugKeyExcludeRules), files, &cfg.Issues), - processors.NewNolint(log.Child(logutils.DebugKeyNolint), dbManager, enabledLinters), - - processors.NewUniqByLine(cfg), - processors.NewDiff(&cfg.Issues), - processors.NewMaxPerFileFromLinter(cfg), - processors.NewMaxSameIssues(cfg.Issues.MaxSameIssues, log.Child(logutils.DebugKeyMaxSameIssues), cfg), - processors.NewMaxFromLinter(cfg.Issues.MaxIssuesPerLinter, log.Child(logutils.DebugKeyMaxFromLinter), cfg), - processors.NewSourceCode(lineCache, log.Child(logutils.DebugKeySourceCode)), - processors.NewPathShortener(), - processors.NewSeverity(log.Child(logutils.DebugKeySeverityRules), files, &cfg.Severity), - - // The fixer still needs to see paths for the issues that are relative to the current directory. - processors.NewFixer(cfg, log, fileCache), - - // Now we can modify the issues for output. - processors.NewPathPrefixer(cfg.Output.PathPrefix), - processors.NewSortResults(cfg), - }, - 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 { - sw.TrackStage(lc.Name(), func() { - linterIssues, err := 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) - - return - } - - 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(), func() { - 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 { - var newIssues []result.Issue - var err error - sw.TrackStage(p.Name(), func() { - newIssues, err = p.Process(issues) - }) - - if err != nil { - r.Log.Warnf("Can't process result 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/pkg/logutils/log.go b/vendor/github.com/golangci/golangci-lint/pkg/logutils/log.go deleted file mode 100644 index 16067e490..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/logutils/logutils.go b/vendor/github.com/golangci/golangci-lint/pkg/logutils/logutils.go deleted file mode 100644 index e4bb98109..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/logutils/logutils.go +++ /dev/null @@ -1,118 +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 ( - DebugKeyAutogenExclude = "autogen_exclude" // Debugs a filter excluding autogenerated source code. - DebugKeyBinSalt = "bin_salt" - DebugKeyConfigReader = "config_reader" - DebugKeyEmpty = "" - DebugKeyEnabledLinters = "enabled_linters" - DebugKeyEnv = "env" // Debugs `go env` command. - DebugKeyExcludeRules = "exclude_rules" - DebugKeyExec = "exec" - DebugKeyFilenameUnadjuster = "filename_unadjuster" - DebugKeyInvalidIssue = "invalid_issue" - DebugKeyForbidigo = "forbidigo" - DebugKeyGoEnv = "goenv" - DebugKeyLinter = "linter" - DebugKeyLintersContext = "linters_context" - DebugKeyLintersDB = "lintersdb" - DebugKeyLintersOutput = "linters_output" - DebugKeyLoader = "loader" // Debugs packages loading (including `go/packages` internal debugging). - DebugKeyMaxFromLinter = "max_from_linter" - DebugKeyMaxSameIssues = "max_same_issues" - DebugKeyPkgCache = "pkgcache" - DebugKeyRunner = "runner" - DebugKeySeverityRules = "severity_rules" - DebugKeySkipDirs = "skip_dirs" - DebugKeySourceCode = "source_code" - DebugKeyStopwatch = "stopwatch" - DebugKeyTabPrinter = "tab_printer" - DebugKeyTest = "test" - DebugKeyTextPrinter = "text_printer" -) - -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" -) - -const ( - DebugKeyGoCritic = "gocritic" // Debugs `go-critic` linter. - DebugKeyGovet = "govet" // Debugs `govet` linter. - DebugKeyMegacheck = "megacheck" // Debugs `staticcheck` related linters. - DebugKeyNolint = "nolint" // Debugs a filter excluding issues by `//nolint` comments. - DebugKeyRevive = "revive" // Debugs `revive` linter. -) - -func getEnabledDebugs() map[string]bool { - ret := map[string]bool{} - debugVar := os.Getenv(envDebug) - if debugVar == "" { - return ret - } - - for _, tag := range strings.Split(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/pkg/logutils/mock.go b/vendor/github.com/golangci/golangci-lint/pkg/logutils/mock.go deleted file mode 100644 index bddcf8552..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/logutils/out.go b/vendor/github.com/golangci/golangci-lint/pkg/logutils/out.go deleted file mode 100644 index ef1375486..000000000 --- a/vendor/github.com/golangci/golangci-lint/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/pkg/logutils/stderr_log.go b/vendor/github.com/golangci/golangci-lint/pkg/logutils/stderr_log.go deleted file mode 100644 index 569a177a7..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/logutils/stderr_log.go +++ /dev/null @@ -1,129 +0,0 @@ -package logutils - -import ( - "fmt" - "os" - "time" - - "github.com/sirupsen/logrus" - - "github.com/golangci/golangci-lint/pkg/exitcodes" -) - -const ( - // envLogLevel values: "error", "err", "warning", "warn","info" - envLogLevel = "LOG_LEVEL" - // envLogTimestamp value: "1" - envLogTimestamp = "LOG_TIMESTAMP" -) - -type StderrLog struct { - name string - logger *logrus.Logger - level LogLevel -} - -var _ Log = NewStderrLog(DebugKeyEmpty) - -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 - 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 - } - sl.logger.Formatter = formatter - - 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 -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/checkstyle.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/checkstyle.go deleted file mode 100644 index e32eef7f5..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/printers/checkstyle.go +++ /dev/null @@ -1,95 +0,0 @@ -package printers - -import ( - "encoding/xml" - "fmt" - "io" - "sort" - - "github.com/go-xmlfmt/xmlfmt" - "golang.org/x/exp/maps" - - "github.com/golangci/golangci-lint/pkg/result" -) - -const defaultCheckstyleSeverity = "error" - -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"` -} - -type Checkstyle struct { - w io.Writer -} - -func NewCheckstyle(w io.Writer) *Checkstyle { - return &Checkstyle{w: w} -} - -func (p Checkstyle) Print(issues []result.Issue) error { - out := checkstyleOutput{ - Version: "5.0", - } - - files := map[string]*checkstyleFile{} - - for i := range issues { - issue := &issues[i] - file, ok := files[issue.FilePath()] - if !ok { - file = &checkstyleFile{ - Name: issue.FilePath(), - } - - files[issue.FilePath()] = file - } - - severity := defaultCheckstyleSeverity - if issue.Severity != "" { - severity = issue.Severity - } - - newError := &checkstyleError{ - Column: issue.Column(), - Line: issue.Line(), - Message: issue.Text, - Source: issue.FromLinter, - Severity: severity, - } - - file.Errors = append(file.Errors, newError) - } - - out.Files = maps.Values(files) - - sort.Slice(out.Files, func(i, j int) bool { - return out.Files[i].Name < out.Files[j].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 -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/codeclimate.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/codeclimate.go deleted file mode 100644 index 50d6dcff3..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/printers/codeclimate.go +++ /dev/null @@ -1,59 +0,0 @@ -package printers - -import ( - "encoding/json" - "io" - - "github.com/golangci/golangci-lint/pkg/result" -) - -const defaultCodeClimateSeverity = "critical" - -// CodeClimateIssue is a subset of the Code Climate spec. -// https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#data-types -// It is just enough to support GitLab CI Code Quality. -// https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html -type CodeClimateIssue struct { - Description string `json:"description"` - 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"` -} - -type CodeClimate struct { - w io.Writer -} - -func NewCodeClimate(w io.Writer) *CodeClimate { - return &CodeClimate{w: w} -} - -func (p CodeClimate) Print(issues []result.Issue) error { - codeClimateIssues := make([]CodeClimateIssue, 0, len(issues)) - for i := range issues { - issue := &issues[i] - codeClimateIssue := CodeClimateIssue{} - codeClimateIssue.Description = issue.Description() - codeClimateIssue.Location.Path = issue.Pos.Filename - codeClimateIssue.Location.Lines.Begin = issue.Pos.Line - codeClimateIssue.Fingerprint = issue.Fingerprint() - codeClimateIssue.Severity = defaultCodeClimateSeverity - - if issue.Severity != "" { - codeClimateIssue.Severity = issue.Severity - } - - codeClimateIssues = append(codeClimateIssues, codeClimateIssue) - } - - err := json.NewEncoder(p.w).Encode(codeClimateIssues) - if err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/githubaction.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/githubaction.go deleted file mode 100644 index d9cdb1e6e..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/printers/githubaction.go +++ /dev/null @@ -1,52 +0,0 @@ -package printers - -import ( - "fmt" - "io" - "path/filepath" - - "github.com/golangci/golangci-lint/pkg/result" -) - -const defaultGithubSeverity = "error" - -type GitHubAction struct { - w io.Writer -} - -// NewGitHubAction output format outputs issues according to GitHub Action. -// Deprecated -func NewGitHubAction(w io.Writer) *GitHubAction { - return &GitHubAction{w: w} -} - -func (p *GitHubAction) Print(issues []result.Issue) error { - for ind := range issues { - _, err := fmt.Fprintln(p.w, formatIssueAsGitHub(&issues[ind])) - if err != nil { - return err - } - } - return nil -} - -// print each line as: ::error file=app.js,line=10,col=15::Something went wrong -func formatIssueAsGitHub(issue *result.Issue) string { - severity := defaultGithubSeverity - if issue.Severity != "" { - severity = issue.Severity - } - - // Convert backslashes to forward slashes. - // This is needed when running on windows. - // Otherwise, GitHub won't be able to show the annotations pointing to the file path with backslashes. - file := filepath.ToSlash(issue.FilePath()) - - ret := fmt.Sprintf("::%s file=%s,line=%d", severity, file, issue.Line()) - if issue.Pos.Column != 0 { - ret += fmt.Sprintf(",col=%d", issue.Pos.Column) - } - - ret += fmt.Sprintf("::%s (%s)", issue.Text, issue.FromLinter) - return ret -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/html.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/html.go deleted file mode 100644 index 7dd1e5c62..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/printers/html.go +++ /dev/null @@ -1,156 +0,0 @@ -package printers - -import ( - "fmt" - "html/template" - "io" - "strings" - - "github.com/golangci/golangci-lint/pkg/result" -) - -const templateContent = ` - - - - golangci-lint - - - - - - - - - - -
-
-
-
-
- - - -` - -type htmlIssue struct { - Title string - Pos string - Linter string - Code string -} - -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 i := range issues { - pos := fmt.Sprintf("%s:%d", issues[i].FilePath(), issues[i].Line()) - if issues[i].Pos.Column != 0 { - pos += fmt.Sprintf(":%d", issues[i].Pos.Column) - } - - htmlIssues = append(htmlIssues, htmlIssue{ - Title: strings.TrimSpace(issues[i].Text), - Pos: pos, - Linter: issues[i].FromLinter, - Code: strings.Join(issues[i].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/pkg/printers/json.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/json.go deleted file mode 100644 index 28509cac4..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/printers/json.go +++ /dev/null @@ -1,38 +0,0 @@ -package printers - -import ( - "encoding/json" - "io" - - "github.com/golangci/golangci-lint/pkg/report" - "github.com/golangci/golangci-lint/pkg/result" -) - -type JSON struct { - rd *report.Data // TODO(ldez) should be drop in v2. Only use by JSON reporter. - w io.Writer -} - -func NewJSON(rd *report.Data, w io.Writer) *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/pkg/printers/junitxml.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/junitxml.go deleted file mode 100644 index 7d0a703b0..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/printers/junitxml.go +++ /dev/null @@ -1,99 +0,0 @@ -package printers - -import ( - "encoding/xml" - "fmt" - "io" - "sort" - "strings" - - "golang.org/x/exp/maps" - - "github.com/golangci/golangci-lint/pkg/result" -) - -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"` -} - -type JunitXML struct { - extended bool - w io.Writer -} - -func NewJunitXML(extended bool, w io.Writer) *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 ind := range issues { - i := &issues[ind] - suiteName := i.FilePath() - testSuite := suites[suiteName] - testSuite.Suite = i.FilePath() - testSuite.Tests++ - testSuite.Failures++ - - tc := testCaseXML{ - Name: i.FromLinter, - ClassName: i.Pos.String(), - Failure: failureXML{ - Type: i.Severity, - Message: i.Pos.String() + ": " + i.Text, - Content: fmt.Sprintf("%s: %s\nCategory: %s\nFile: %s\nLine: %d\nDetails: %s", - i.Severity, i.Text, i.FromLinter, i.Pos.Filename, i.Pos.Line, strings.Join(i.SourceLines, "\n")), - }, - } - - if p.extended { - tc.File = i.Pos.Filename - tc.Line = i.Pos.Line - } - - testSuite.TestCases = append(testSuite.TestCases, tc) - suites[suiteName] = testSuite - } - - var res testSuitesXML - res.TestSuites = maps.Values(suites) - - sort.Slice(res.TestSuites, func(i, j int) bool { - return res.TestSuites[i].Suite < res.TestSuites[j].Suite - }) - - enc := xml.NewEncoder(p.w) - enc.Indent("", " ") - if err := enc.Encode(res); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/printer.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/printer.go deleted file mode 100644 index 20be02e01..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/printers/printer.go +++ /dev/null @@ -1,145 +0,0 @@ -package printers - -import ( - "errors" - "fmt" - "io" - "os" - "path/filepath" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/report" - "github.com/golangci/golangci-lint/pkg/result" -) - -const defaultFileMode = 0o644 - -type issuePrinter interface { - Print(issues []result.Issue) error -} - -// Printer prints issues -type Printer struct { - cfg *config.Output - reportData *report.Data - - log logutils.Log - - stdOut io.Writer - stdErr io.Writer -} - -// NewPrinter creates a new Printer. -func NewPrinter(log logutils.Log, cfg *config.Output, reportData *report.Data) (*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, - log: log, - stdOut: logutils.StdOut, - stdErr: logutils.StdErr, - }, nil -} - -// Print prints issues based on the formats defined -func (c *Printer) Print(issues []result.Issue) error { - for _, format := range c.cfg.Formats { - err := c.printReports(issues, format) - if err != nil { - return err - } - } - - return nil -} - -func (c *Printer) printReports(issues []result.Issue, format config.OutputFormat) error { - w, shouldClose, err := c.createWriter(format.Path) - if err != nil { - return fmt.Errorf("can't create output for %s: %w", format.Path, err) - } - - defer func() { - if file, ok := w.(io.Closer); shouldClose && ok { - _ = file.Close() - } - }() - - p, err := c.createPrinter(format.Format, w) - if err != nil { - return err - } - - if err = p.Print(issues); err != nil { - return fmt.Errorf("can't print %d issues: %w", len(issues), err) - } - - return nil -} - -func (c *Printer) createWriter(path string) (io.Writer, bool, error) { - if path == "" || path == "stdout" { - return c.stdOut, false, nil - } - - if path == "stderr" { - return c.stdErr, false, nil - } - - err := os.MkdirAll(filepath.Dir(path), os.ModePerm) - if err != nil { - return nil, false, err - } - - f, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, defaultFileMode) - if err != nil { - return nil, false, err - } - - return f, true, nil -} - -func (c *Printer) createPrinter(format string, w io.Writer) (issuePrinter, error) { - var p issuePrinter - - switch format { - case config.OutFormatJSON: - p = NewJSON(c.reportData, w) - case config.OutFormatLineNumber, config.OutFormatColoredLineNumber: - p = NewText(c.cfg.PrintIssuedLine, - format == config.OutFormatColoredLineNumber, c.cfg.PrintLinterName, - c.log.Child(logutils.DebugKeyTextPrinter), w) - case config.OutFormatTab, config.OutFormatColoredTab: - p = NewTab(c.cfg.PrintLinterName, - format == config.OutFormatColoredTab, - c.log.Child(logutils.DebugKeyTabPrinter), w) - case config.OutFormatCheckstyle: - p = NewCheckstyle(w) - case config.OutFormatCodeClimate: - p = NewCodeClimate(w) - case config.OutFormatHTML: - p = NewHTML(w) - case config.OutFormatJunitXML, config.OutFormatJunitXMLExtended: - p = NewJunitXML(format == config.OutFormatJunitXMLExtended, w) - case config.OutFormatGithubActions: - p = NewGitHubAction(w) - case config.OutFormatTeamCity: - p = NewTeamCity(w) - case config.OutFormatSarif: - p = NewSarif(w) - default: - return nil, fmt.Errorf("unknown output format %q", format) - } - - return p, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/sarif.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/sarif.go deleted file mode 100644 index 8b1dd2ee2..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/printers/sarif.go +++ /dev/null @@ -1,117 +0,0 @@ -package printers - -import ( - "encoding/json" - "io" - - "github.com/golangci/golangci-lint/pkg/result" -) - -const ( - sarifVersion = "2.1.0" - sarifSchemaURI = "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.6.json" -) - -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"` -} - -type Sarif struct { - w io.Writer -} - -func NewSarif(w io.Writer) *Sarif { - return &Sarif{w: w} -} - -func (p Sarif) Print(issues []result.Issue) error { - run := sarifRun{} - run.Tool.Driver.Name = "golangci-lint" - run.Results = make([]sarifResult, 0) - - for i := range issues { - issue := issues[i] - - severity := issue.Severity - - switch severity { - // https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790898 - case "none", "note", "warning", "error": - // Valid levels. - default: - severity = "error" - } - - sr := sarifResult{ - RuleID: issue.FromLinter, - Level: 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) - } - - output := SarifOutput{ - Version: sarifVersion, - Schema: sarifSchemaURI, - Runs: []sarifRun{run}, - } - - return json.NewEncoder(p.w).Encode(output) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/tab.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/tab.go deleted file mode 100644 index c6d390d18..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/printers/tab.go +++ /dev/null @@ -1,67 +0,0 @@ -package printers - -import ( - "fmt" - "io" - "text/tabwriter" - - "github.com/fatih/color" - - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -type Tab struct { - printLinterName bool - useColors bool - - log logutils.Log - w io.Writer -} - -func NewTab(printLinterName, useColors bool, log logutils.Log, w io.Writer) *Tab { - return &Tab{ - printLinterName: printLinterName, - useColors: useColors, - log: log, - w: w, - } -} - -func (p *Tab) SprintfColored(ca color.Attribute, format string, args ...any) string { - c := color.New(ca) - - if !p.useColors { - 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 i := range issues { - p.printIssue(&issues[i], 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/pkg/printers/teamcity.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/teamcity.go deleted file mode 100644 index 1d1c9f7d3..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/printers/teamcity.go +++ /dev/null @@ -1,122 +0,0 @@ -package printers - -import ( - "fmt" - "io" - "strings" - "unicode/utf8" - - "github.com/golangci/golangci-lint/pkg/result" -) - -// Field limits. -const ( - smallLimit = 255 - largeLimit = 4000 -) - -// TeamCity printer for TeamCity format. -type TeamCity struct { - w io.Writer - escaper *strings.Replacer -} - -// NewTeamCity output format outputs issues according to TeamCity service message format. -func NewTeamCity(w io.Writer) *TeamCity { - return &TeamCity{ - w: w, - // https://www.jetbrains.com/help/teamcity/service-messages.html#Escaped+Values - escaper: strings.NewReplacer( - "'", "|'", - "\n", "|n", - "\r", "|r", - "|", "||", - "[", "|[", - "]", "|]", - ), - } -} - -func (p *TeamCity) Print(issues []result.Issue) error { - uniqLinters := map[string]struct{}{} - - for i := range issues { - issue := issues[i] - - _, 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: issue.Severity, - } - - _, err := instance.Print(p.w, p.escaper) - if err != nil { - return 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, strings.ToUpper(i.severity)) -} - -func cutVal(s string, limit int) string { - var size, count int - for i := 0; i < limit && count < len(s); i++ { - _, size = utf8.DecodeRuneInString(s[count:]) - count += size - } - - return s[:count] -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/printers/text.go b/vendor/github.com/golangci/golangci-lint/pkg/printers/text.go deleted file mode 100644 index 56cced769..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/printers/text.go +++ /dev/null @@ -1,94 +0,0 @@ -package printers - -import ( - "fmt" - "io" - "strings" - - "github.com/fatih/color" - - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -type Text struct { - printIssuedLine bool - printLinterName bool - useColors bool - - log logutils.Log - w io.Writer -} - -func NewText(printIssuedLine, useColors, printLinterName bool, log logutils.Log, w io.Writer) *Text { - return &Text{ - printIssuedLine: printIssuedLine, - printLinterName: printLinterName, - useColors: useColors, - log: log, - w: w, - } -} - -func (p *Text) SprintfColored(ca color.Attribute, format string, args ...any) string { - c := color.New(ca) - - if !p.useColors { - c.DisableColor() - } - - return c.Sprintf(format, args...) -} - -func (p *Text) Print(issues []result.Issue) error { - for i := range issues { - p.printIssue(&issues[i]) - - if !p.printIssuedLine { - continue - } - - p.printSourceCode(&issues[i]) - p.printUnderLinePointer(&issues[i]) - } - - 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/pkg/report/data.go b/vendor/github.com/golangci/golangci-lint/pkg/report/data.go deleted file mode 100644 index f083fa9f5..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/report/data.go +++ /dev/null @@ -1,26 +0,0 @@ -package report - -type Warning struct { - Tag string `json:",omitempty"` - Text string -} - -type LinterData struct { - Name string - Enabled bool `json:",omitempty"` - EnabledByDefault 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, enabledByDefault bool) { - d.Linters = append(d.Linters, LinterData{ - Name: name, - Enabled: enabled, - EnabledByDefault: enabledByDefault, - }) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/report/log.go b/vendor/github.com/golangci/golangci-lint/pkg/report/log.go deleted file mode 100644 index 61665f28b..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/report/log.go +++ /dev/null @@ -1,64 +0,0 @@ -package report - -import ( - "fmt" - "strings" - - "github.com/golangci/golangci-lint/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 = append([]string{}, 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/pkg/result/issue.go b/vendor/github.com/golangci/golangci-lint/pkg/result/issue.go deleted file mode 100644 index 32246a6df..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/issue.go +++ /dev/null @@ -1,98 +0,0 @@ -package result - -import ( - "crypto/md5" //nolint:gosec // for md5 hash - "fmt" - "go/token" - - "golang.org/x/tools/go/packages" -) - -type Range struct { - From, To int -} - -type Replacement struct { - NeedOnlyDelete bool // need to delete all lines of the issue without replacement with new lines - NewLines []string // if NeedDelete is false it's the replacement lines - Inline *InlineFix -} - -type InlineFix struct { - StartCol int // zero-based - Length int // length of chunk to be replaced - NewString string -} - -type Issue struct { - FromLinter string - Text string - - Severity string - - // Source lines of a code with the issue to show - SourceLines []string - - // If we know how to fix the issue we can provide replacement lines - Replacement *Replacement - - // Pkg is needed for proper caching of linting results - Pkg *packages.Package `json:"-"` - - LineRange *Range `json:",omitempty"` - - Pos token.Position - - // HunkPos is used only when golangci-lint is run over a diff - HunkPos int `json:",omitempty"` - - // If we are expecting a nolint (because this is from nolintlint), record the expected linter - ExpectNoLint bool - ExpectedNoLintLinter string -} - -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/pkg/result/processors/autogenerated_exclude.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/autogenerated_exclude.go deleted file mode 100644 index 82316f6a0..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/autogenerated_exclude.go +++ /dev/null @@ -1,177 +0,0 @@ -package processors - -import ( - "fmt" - "go/parser" - "go/token" - "path/filepath" - "regexp" - "strings" - - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -const ( - AutogeneratedModeLax = "lax" - AutogeneratedModeStrict = "strict" - AutogeneratedModeDisable = "disable" -) - -// 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 " -) - -var _ Processor = (*AutogeneratedExclude)(nil) - -type fileSummary struct { - generated bool -} - -type AutogeneratedExclude struct { - debugf logutils.DebugFunc - - mode string - strictPattern *regexp.Regexp - - fileSummaryCache map[string]*fileSummary -} - -func NewAutogeneratedExclude(mode string) *AutogeneratedExclude { - return &AutogeneratedExclude{ - debugf: logutils.Debug(logutils.DebugKeyAutogenExclude), - mode: mode, - strictPattern: regexp.MustCompile(`^// Code generated .* DO NOT EDIT\.$`), - fileSummaryCache: map[string]*fileSummary{}, - } -} - -func (*AutogeneratedExclude) Name() string { - return "autogenerated_exclude" -} - -func (p *AutogeneratedExclude) Process(issues []result.Issue) ([]result.Issue, error) { - if p.mode == AutogeneratedModeDisable { - return issues, nil - } - - return filterIssuesErr(issues, p.shouldPassIssue) -} - -func (*AutogeneratedExclude) Finish() {} - -func (p *AutogeneratedExclude) 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 - - if p.mode == AutogeneratedModeStrict { - var err error - fs.generated, err = p.isGeneratedFileStrict(issue.FilePath()) - if err != nil { - return false, fmt.Errorf("failed to get doc (strict) of file %s: %w", issue.FilePath(), err) - } - } else { - doc, err := getComments(issue.FilePath()) - if err != nil { - return false, fmt.Errorf("failed to get doc (lax) of file %s: %w", issue.FilePath(), err) - } - - fs.generated = p.isGeneratedFileLax(doc) - } - - p.debugf("file %q is generated: %t", issue.FilePath(), fs.generated) - - // don't report issues for autogenerated files - return !fs.generated, 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 *AutogeneratedExclude) 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 (p *AutogeneratedExclude) isGeneratedFileStrict(filePath string) (bool, error) { - file, err := parser.ParseFile(token.NewFileSet(), filePath, nil, parser.PackageClauseOnly|parser.ParseComments) - if err != nil { - return false, fmt.Errorf("failed to parse file: %w", err) - } - - if file == nil || len(file.Comments) == 0 { - return false, nil - } - - for _, comment := range file.Comments { - if comment.Pos() > file.Package { - return false, nil - } - - for _, line := range comment.List { - generated := p.strictPattern.MatchString(line.Text) - if generated { - p.debugf("doc contains ignore expression: file is generated") - - return true, nil - } - } - } - - return false, nil -} - -func getComments(filePath string) (string, error) { - fset := token.NewFileSet() - syntax, err := parser.ParseFile(fset, filePath, nil, parser.PackageClauseOnly|parser.ParseComments) - if err != nil { - return "", fmt.Errorf("failed to parse file: %w", err) - } - - var docLines []string - for _, c := range syntax.Comments { - docLines = append(docLines, strings.TrimSpace(c.Text())) - } - - return strings.Join(docLines, "\n"), nil -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/base_rule.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/base_rule.go deleted file mode 100644 index d7a4f0ec4..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/base_rule.go +++ /dev/null @@ -1,68 +0,0 @@ -package processors - -import ( - "regexp" - - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -const caseInsensitivePrefix = "(?i)" - -type baseRule struct { - text *regexp.Regexp - source *regexp.Regexp - path *regexp.Regexp - pathExcept *regexp.Regexp - linters []string -} - -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, files *fsutils.Files, 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(files.WithPathPrefix(issue.FilePath())) { - return false - } - if r.pathExcept != nil && r.pathExcept.MatchString(issue.FilePath()) { - return false - } - if len(r.linters) != 0 && !r.matchLinter(issue) { - return false - } - - // the most heavyweight checking last - if r.source != nil && !r.matchSource(issue, files.LineCache, log) { - return false - } - - return true -} - -func (r *baseRule) matchLinter(issue *result.Issue) bool { - for _, linter := range r.linters { - if linter == issue.FromLinter { - return true - } - } - - return false -} - -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) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/cgo.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/cgo.go deleted file mode 100644 index 0e659f0f3..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/cgo.go +++ /dev/null @@ -1,59 +0,0 @@ -package processors - -import ( - "fmt" - "path/filepath" - "strings" - - "github.com/golangci/golangci-lint/pkg/goutil" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*Cgo)(nil) - -type Cgo struct { - goCacheDir string -} - -func NewCgo(goenv *goutil.Env) *Cgo { - return &Cgo{ - goCacheDir: goenv.Get(goutil.EnvGoCache), - } -} - -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) { - // some linters (e.g. gosec, deadcode) return incorrect filepaths for cgo issues, - // also cgo files have strange issues looking like false positives. - - // cache dir contains all preprocessed files including cgo files - - issueFilePath := issue.FilePath() - if !filepath.IsAbs(issue.FilePath()) { - absPath, err := filepath.Abs(issue.FilePath()) - if err != nil { - return false, fmt.Errorf("failed to build abs path for %q: %w", issue.FilePath(), err) - } - issueFilePath = absPath - } - - if p.goCacheDir != "" && strings.HasPrefix(issueFilePath, 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/pkg/result/processors/diff.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/diff.go deleted file mode 100644 index c602cdc65..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/diff.go +++ /dev/null @@ -1,84 +0,0 @@ -package processors - -import ( - "bytes" - "fmt" - "io" - "os" - "strings" - - "github.com/golangci/revgrep" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/result" -) - -const envGolangciDiffProcessorPatch = "GOLANGCI_DIFF_PROCESSOR_PATCH" - -var _ Processor = (*Diff)(nil) - -type Diff struct { - onlyNew bool - fromRev string - patchFilePath string - wholeFiles bool - patch string -} - -func NewDiff(cfg *config.Issues) *Diff { - return &Diff{ - onlyNew: cfg.Diff, - fromRev: cfg.DiffFromRevision, - 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.patchFilePath == "" && p.patch == "" { // no need to work - return issues, nil - } - - var patchReader io.Reader - if 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) - } else if p.patch != "" { - patchReader = strings.NewReader(p.patch) - } - - c := revgrep.Checker{ - Patch: patchReader, - RevisionFrom: p.fromRev, - WholeFiles: p.wholeFiles, - } - if err := c.Prepare(); 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 := c.IsNewIssue(issue) - if !isNew { - return nil - } - - newIssue := *issue - newIssue.HunkPos = hunkPos - return &newIssue - }), nil -} - -func (Diff) Finish() {} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclude.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclude.go deleted file mode 100644 index 543120450..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclude.go +++ /dev/null @@ -1,55 +0,0 @@ -package processors - -import ( - "fmt" - "regexp" - "strings" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*Exclude)(nil) - -type Exclude struct { - name string - - pattern *regexp.Regexp -} - -func NewExclude(cfg *config.Issues) *Exclude { - p := &Exclude{name: "exclude"} - - var pattern string - if len(cfg.ExcludePatterns) != 0 { - pattern = fmt.Sprintf("(%s)", strings.Join(cfg.ExcludePatterns, "|")) - } - - prefix := caseInsensitivePrefix - if cfg.ExcludeCaseSensitive { - p.name = "exclude-case-sensitive" - prefix = "" - } - - if pattern != "" { - p.pattern = regexp.MustCompile(prefix + pattern) - } - - return p -} - -func (p Exclude) Name() string { - return p.name -} - -func (p Exclude) Process(issues []result.Issue) ([]result.Issue, error) { - if p.pattern == nil { - return issues, nil - } - - return filterIssues(issues, func(issue *result.Issue) bool { - return !p.pattern.MatchString(issue.Text) - }), nil -} - -func (Exclude) Finish() {} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclude_rules.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclude_rules.go deleted file mode 100644 index bf255ae82..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/exclude_rules.go +++ /dev/null @@ -1,105 +0,0 @@ -package processors - -import ( - "regexp" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*ExcludeRules)(nil) - -type excludeRule struct { - baseRule -} - -type ExcludeRules struct { - name string - - log logutils.Log - files *fsutils.Files - - rules []excludeRule -} - -func NewExcludeRules(log logutils.Log, files *fsutils.Files, cfg *config.Issues) *ExcludeRules { - p := &ExcludeRules{ - name: "exclude-rules", - files: files, - log: log, - } - - prefix := caseInsensitivePrefix - if cfg.ExcludeCaseSensitive { - prefix = "" - p.name = "exclude-rules-case-sensitive" - } - - excludeRules := cfg.ExcludeRules - - if cfg.UseDefaultExcludes { - for _, r := range config.GetExcludePatterns(cfg.IncludeDefaultExcludes) { - excludeRules = append(excludeRules, config.ExcludeRule{ - BaseRule: config.BaseRule{ - Text: r.Pattern, - Linters: []string{r.Linter}, - }, - }) - } - } - - p.rules = createRules(excludeRules, prefix) - - return p -} - -func (p ExcludeRules) Name() string { return p.name } - -func (p ExcludeRules) 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.files, p.log) { - return false - } - } - - return true - }), nil -} - -func (ExcludeRules) Finish() {} - -func createRules(rules []config.ExcludeRule, prefix string) []excludeRule { - parsedRules := make([]excludeRule, 0, len(rules)) - - for _, rule := range rules { - parsedRule := excludeRule{} - parsedRule.linters = rule.Linters - - if rule.Text != "" { - parsedRule.text = regexp.MustCompile(prefix + rule.Text) - } - - if rule.Source != "" { - parsedRule.source = regexp.MustCompile(prefix + rule.Source) - } - - if rule.Path != "" { - parsedRule.path = regexp.MustCompile(fsutils.NormalizePathInRegex(rule.Path)) - } - - if rule.PathExcept != "" { - parsedRule.pathExcept = regexp.MustCompile(fsutils.NormalizePathInRegex(rule.PathExcept)) - } - - parsedRules = append(parsedRules, parsedRule) - } - - return parsedRules -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/filename_unadjuster.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/filename_unadjuster.go deleted file mode 100644 index 6a1387c87..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/filename_unadjuster.go +++ /dev/null @@ -1,133 +0,0 @@ -package processors - -import ( - "go/parser" - "go/token" - "path/filepath" - "strings" - "sync" - "time" - - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*FilenameUnadjuster)(nil) - -type posMapper func(pos token.Position) token.Position - -type adjustMap struct { - sync.Mutex - m map[string]posMapper -} - -// FilenameUnadjuster is needed because 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. -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 { - issueFilePath := issue.FilePath() - if !filepath.IsAbs(issue.FilePath()) { - absPath, err := filepath.Abs(issue.FilePath()) - if err != nil { - p.log.Warnf("failed to build abs path for %q: %s", issue.FilePath(), err) - return issue - } - issueFilePath = absPath - } - - mapper := p.m[issueFilePath] - 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/pkg/result/processors/fixer.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/fixer.go deleted file mode 100644 index 4915dc479..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/fixer.go +++ /dev/null @@ -1,261 +0,0 @@ -package processors - -import ( - "bytes" - "fmt" - "os" - "path/filepath" - "sort" - "strings" - - "github.com/golangci/golangci-lint/internal/robustio" - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" - "github.com/golangci/golangci-lint/pkg/timeutils" -) - -var _ Processor = (*Fixer)(nil) - -type Fixer struct { - cfg *config.Config - log logutils.Log - fileCache *fsutils.FileCache - sw *timeutils.Stopwatch -} - -func NewFixer(cfg *config.Config, log logutils.Log, fileCache *fsutils.FileCache) *Fixer { - return &Fixer{ - cfg: cfg, - log: log, - fileCache: fileCache, - sw: timeutils.NewStopwatch("fixer", log), - } -} - -func (Fixer) Name() string { - return "fixer" -} - -func (p Fixer) Process(issues []result.Issue) ([]result.Issue, error) { - if !p.cfg.Issues.NeedFix { - return issues, nil - } - - outIssues := make([]result.Issue, 0, len(issues)) - issuesToFixPerFile := map[string][]result.Issue{} - for i := range issues { - issue := &issues[i] - if issue.Replacement == nil { - outIssues = append(outIssues, *issue) - continue - } - - issuesToFixPerFile[issue.FilePath()] = append(issuesToFixPerFile[issue.FilePath()], *issue) - } - - for file, issuesToFix := range issuesToFixPerFile { - var err error - p.sw.TrackStage("all", func() { - err = p.fixIssuesInFile(file, issuesToFix) - }) - if err != nil { - p.log.Errorf("Failed to fix issues in file %s: %s", file, err) - - // show issues only if can't fix them - outIssues = append(outIssues, issuesToFix...) - } - } - - p.printStat() - - return outIssues, nil -} - -func (Fixer) Finish() {} - -func (p Fixer) fixIssuesInFile(filePath string, issues []result.Issue) error { - // TODO: don't read the whole file into memory: read line by line; - // can't just use bufio.scanner: it has a line length limit - origFileData, err := p.fileCache.GetFileBytes(filePath) - if err != nil { - return fmt.Errorf("failed to get file bytes for %s: %w", filePath, err) - } - - origFileLines := bytes.Split(origFileData, []byte("\n")) - - tmpFileName := filepath.Join(filepath.Dir(filePath), fmt.Sprintf(".%s.golangci_fix", filepath.Base(filePath))) - - tmpOutFile, err := os.Create(tmpFileName) - if err != nil { - return fmt.Errorf("failed to make file %s: %w", tmpFileName, err) - } - - // merge multiple issues per line into one issue - issuesPerLine := map[int][]result.Issue{} - for i := range issues { - issue := &issues[i] - issuesPerLine[issue.Line()] = append(issuesPerLine[issue.Line()], *issue) - } - - issues = issues[:0] // reuse the same memory - for line, lineIssues := range issuesPerLine { - if mergedIssue := p.mergeLineIssues(line, lineIssues, origFileLines); mergedIssue != nil { - issues = append(issues, *mergedIssue) - } - } - - issues = p.findNotIntersectingIssues(issues) - - if err = p.writeFixedFile(origFileLines, issues, tmpOutFile); err != nil { - tmpOutFile.Close() - _ = robustio.RemoveAll(tmpOutFile.Name()) - return err - } - - tmpOutFile.Close() - - if err = robustio.Rename(tmpOutFile.Name(), filePath); err != nil { - _ = robustio.RemoveAll(tmpOutFile.Name()) - return fmt.Errorf("failed to rename %s -> %s: %w", tmpOutFile.Name(), filePath, err) - } - - return nil -} - -func (p Fixer) mergeLineIssues(lineNum int, lineIssues []result.Issue, origFileLines [][]byte) *result.Issue { - origLine := origFileLines[lineNum-1] // lineNum is 1-based - - if len(lineIssues) == 1 && lineIssues[0].Replacement.Inline == nil { - return &lineIssues[0] - } - - // check issues first - for ind := range lineIssues { - li := &lineIssues[ind] - - if li.LineRange != nil { - p.log.Infof("Line %d has multiple issues but at least one of them is ranged: %#v", lineNum, lineIssues) - return &lineIssues[0] - } - - inline := li.Replacement.Inline - - if inline == nil || len(li.Replacement.NewLines) != 0 || li.Replacement.NeedOnlyDelete { - p.log.Infof("Line %d has multiple issues but at least one of them isn't inline: %#v", lineNum, lineIssues) - return li - } - - if inline.StartCol < 0 || inline.Length <= 0 || inline.StartCol+inline.Length > len(origLine) { - p.log.Warnf("Line %d (%q) has invalid inline fix: %#v, %#v", lineNum, origLine, li, inline) - return nil - } - } - - return p.applyInlineFixes(lineIssues, origLine, lineNum) -} - -func (p Fixer) applyInlineFixes(lineIssues []result.Issue, origLine []byte, lineNum int) *result.Issue { - sort.Slice(lineIssues, func(i, j int) bool { - return lineIssues[i].Replacement.Inline.StartCol < lineIssues[j].Replacement.Inline.StartCol - }) - - var newLineBuf bytes.Buffer - newLineBuf.Grow(len(origLine)) - - //nolint:misspell // misspelling is intentional - // example: origLine="it's becouse of them", StartCol=5, Length=7, NewString="because" - - curOrigLinePos := 0 - for i := range lineIssues { - fix := lineIssues[i].Replacement.Inline - if fix.StartCol < curOrigLinePos { - p.log.Warnf("Line %d has multiple intersecting issues: %#v", lineNum, lineIssues) - return nil - } - - if curOrigLinePos != fix.StartCol { - newLineBuf.Write(origLine[curOrigLinePos:fix.StartCol]) - } - newLineBuf.WriteString(fix.NewString) - curOrigLinePos = fix.StartCol + fix.Length - } - if curOrigLinePos != len(origLine) { - newLineBuf.Write(origLine[curOrigLinePos:]) - } - - mergedIssue := lineIssues[0] // use text from the first issue (it's not really used) - mergedIssue.Replacement = &result.Replacement{ - NewLines: []string{newLineBuf.String()}, - } - return &mergedIssue -} - -func (p Fixer) findNotIntersectingIssues(issues []result.Issue) []result.Issue { - sort.SliceStable(issues, func(i, j int) bool { - a, b := issues[i], issues[j] - return a.Line() < b.Line() - }) - - var ret []result.Issue - var currentEnd int - for i := range issues { - issue := &issues[i] - rng := issue.GetLineRange() - if rng.From <= currentEnd { - p.log.Infof("Skip issue %#v: intersects with end %d", issue, currentEnd) - continue // skip intersecting issue - } - p.log.Infof("Fix issue %#v with range %v", issue, issue.GetLineRange()) - ret = append(ret, *issue) - currentEnd = rng.To - } - - return ret -} - -func (p Fixer) writeFixedFile(origFileLines [][]byte, issues []result.Issue, tmpOutFile *os.File) error { - // issues aren't intersecting - - nextIssueIndex := 0 - for i := 0; i < len(origFileLines); i++ { - var outLine string - var nextIssue *result.Issue - if nextIssueIndex != len(issues) { - nextIssue = &issues[nextIssueIndex] - } - - origFileLineNumber := i + 1 - if nextIssue == nil || origFileLineNumber != nextIssue.GetLineRange().From { - outLine = string(origFileLines[i]) - } else { - nextIssueIndex++ - rng := nextIssue.GetLineRange() - if rng.From > rng.To { - // Maybe better decision is to skip such issues, re-evaluate if regressed. - p.log.Warnf("[fixer]: issue line range is probably invalid, fix can be incorrect (from=%d, to=%d, linter=%s)", - rng.From, rng.To, nextIssue.FromLinter, - ) - } - i += rng.To - rng.From - if nextIssue.Replacement.NeedOnlyDelete { - continue - } - outLine = strings.Join(nextIssue.Replacement.NewLines, "\n") - } - - if i < len(origFileLines)-1 { - outLine += "\n" - } - if _, err := tmpOutFile.WriteString(outLine); err != nil { - return fmt.Errorf("failed to write output line: %w", err) - } - } - - return nil -} - -func (p Fixer) printStat() { - p.sw.PrintStages() -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/identifier_marker.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/identifier_marker.go deleted file mode 100644 index 876fd3bd3..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/identifier_marker.go +++ /dev/null @@ -1,154 +0,0 @@ -package processors - -import ( - "regexp" - - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*IdentifierMarker)(nil) - -type replacePattern struct { - re string - repl string -} - -type replaceRegexp struct { - re *regexp.Regexp - repl string -} - -var replacePatterns = []replacePattern{ - // unparam - {`^(\S+) - (\S+) is unused$`, "`${1}` - `${2}` is unused"}, - {`^(\S+) - (\S+) always receives (\S+) \((.*)\)$`, "`${1}` - `${2}` always receives `${3}` (`${4}`)"}, - {`^(\S+) - (\S+) always receives (.*)$`, "`${1}` - `${2}` always receives `${3}`"}, - {`^(\S+) - result (\S+) is always (\S+)`, "`${1}` - result `${2}` is always `${3}`"}, - - // interfacer - {`^(\S+) can be (\S+)$`, "`${1}` can be `${2}`"}, - - // govet - {`^printf: (\S+) arg list ends with redundant newline$`, "printf: `${1}` arg list ends with redundant newline"}, - {`^composites: (\S+) composite literal uses unkeyed fields$`, "composites: `${1}` composite literal uses unkeyed fields"}, - - // gosec - { - `^(\S+): Blacklisted import (\S+): weak cryptographic primitive$`, - "${1}: Blacklisted import `${2}`: weak cryptographic primitive", - }, - {`^TLS InsecureSkipVerify set true.$`, "TLS `InsecureSkipVerify` set true."}, - - // gosimple - {`should replace loop with (.*)$`, "should replace loop with `${1}`"}, - { - `should use a simple channel send/receive instead of select with a single case`, - "should use a simple channel send/receive instead of `select` with a single case", - }, - { - `should omit comparison to bool constant, can be simplified to (.+)$`, - "should omit comparison to bool constant, can be simplified to `${1}`", - }, - {`should write (.+) instead of (.+)$`, "should write `${1}` instead of `${2}`"}, - {`redundant return statement$`, "redundant `return` statement"}, - { - `should replace this if statement with an unconditional strings.TrimPrefix`, - "should replace this `if` statement with an unconditional `strings.TrimPrefix`", - }, - - // staticcheck - {`this value of (\S+) is never used$`, "this value of `${1}` is never used"}, - { - `should use time.Since instead of time.Now\(\).Sub$`, - "should use `time.Since` instead of `time.Now().Sub`", - }, - { - `should check returned error before deferring response.Close\(\)$`, - "should check returned error before deferring `response.Close()`", - }, - {`no value of type uint is less than 0$`, "no value of type `uint` is less than `0`"}, - - // unused - {`(func|const|field|type|var) (\S+) is unused$`, "${1} `${2}` is unused"}, - - // typecheck - {`^unknown field (\S+) in struct literal$`, "unknown field `${1}` in struct literal"}, - { - `^invalid operation: (\S+) \(variable of type (\S+)\) has no field or method (\S+)$`, - "invalid operation: `${1}` (variable of type `${2}`) has no field or method `${3}`", - }, - {`^undeclared name: (\S+)$`, "undeclared name: `${1}`"}, - { - `^cannot use addr \(variable of type (\S+)\) as (\S+) value in argument to (\S+)$`, - "cannot use addr (variable of type `${1}`) as `${2}` value in argument to `${3}`", - }, - {`^other declaration of (\S+)$`, "other declaration of `${1}`"}, - {`^(\S+) redeclared in this block$`, "`${1}` redeclared in this block"}, - - // golint - { - `^exported (type|method|function|var|const) (\S+) should have comment or be unexported$`, - "exported ${1} `${2}` should have comment or be unexported", - }, - { - `^comment on exported (type|method|function|var|const) (\S+) should be of the form "(\S+) ..."$`, - "comment on exported ${1} `${2}` should be of the form `${3} ...`", - }, - {`^should replace (.+) with (.+)$`, "should replace `${1}` with `${2}`"}, - { - `^if block ends with a return statement, so drop this else and outdent its block$`, - "`if` block ends with a `return` statement, so drop this `else` and outdent its block", - }, - { - `^(struct field|var|range var|const|type|(?:func|method|interface method) (?:parameter|result)) (\S+) should be (\S+)$`, - "${1} `${2}` should be `${3}`", - }, - { - `^don't use underscores in Go names; var (\S+) should be (\S+)$`, - "don't use underscores in Go names; var `${1}` should be `${2}`", - }, -} - -type IdentifierMarker struct { - replaceRegexps []replaceRegexp -} - -func NewIdentifierMarker() *IdentifierMarker { - var replaceRegexps []replaceRegexp - for _, p := range replacePatterns { - r := replaceRegexp{ - re: regexp.MustCompile(p.re), - repl: p.repl, - } - replaceRegexps = append(replaceRegexps, r) - } - - return &IdentifierMarker{ - replaceRegexps: replaceRegexps, - } -} - -func (IdentifierMarker) Name() string { - return "identifier_marker" -} - -func (p IdentifierMarker) Process(issues []result.Issue) ([]result.Issue, error) { - return transformIssues(issues, func(issue *result.Issue) *result.Issue { - newIssue := *issue - newIssue.Text = p.markIdentifiers(newIssue.Text) - return &newIssue - }), nil -} - -func (IdentifierMarker) Finish() {} - -func (p IdentifierMarker) markIdentifiers(s string) string { - for _, rr := range p.replaceRegexps { - rs := rr.re.ReplaceAllString(s, rr.repl) - if rs != s { - return rs - } - } - - return s -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/invalid_issue.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/invalid_issue.go deleted file mode 100644 index 3f6cfc540..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/invalid_issue.go +++ /dev/null @@ -1,60 +0,0 @@ -package processors - -import ( - "path/filepath" - - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*InvalidIssue)(nil) - -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/pkg/result/processors/issues.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/issues.go deleted file mode 100644 index ab443b87d..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/issues.go +++ /dev/null @@ -1,69 +0,0 @@ -package processors - -import ( - "fmt" - - "github.com/golangci/golangci-lint/pkg/result" -) - -func filterIssues(issues []result.Issue, filter func(issue *result.Issue) bool) []result.Issue { - retIssues := make([]result.Issue, 0, len(issues)) - for i := range issues { - if issues[i].FromLinter == typeCheckName { - // don't hide typechecking errors in generated files: users expect to see why the project isn't compiling - retIssues = append(retIssues, issues[i]) - continue - } - - if filter(&issues[i]) { - retIssues = append(retIssues, issues[i]) - } - } - - return retIssues -} - -func filterIssuesUnsafe(issues []result.Issue, filter func(issue *result.Issue) bool) []result.Issue { - retIssues := make([]result.Issue, 0, len(issues)) - for i := range issues { - if filter(&issues[i]) { - retIssues = append(retIssues, issues[i]) - } - } - - 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 i := range issues { - if issues[i].FromLinter == typeCheckName { - // don't hide typechecking errors in generated files: users expect to see why the project isn't compiling - retIssues = append(retIssues, issues[i]) - continue - } - - ok, err := filter(&issues[i]) - if err != nil { - return nil, fmt.Errorf("can't filter issue %#v: %w", issues[i], err) - } - - if ok { - retIssues = append(retIssues, issues[i]) - } - } - - 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 i := range issues { - newIssue := transform(&issues[i]) - if newIssue != nil { - retIssues = append(retIssues, *newIssue) - } - } - - return retIssues -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_from_linter.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_from_linter.go deleted file mode 100644 index 0680c3f29..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_from_linter.go +++ /dev/null @@ -1,55 +0,0 @@ -package processors - -import ( - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*MaxFromLinter)(nil) - -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 { - if issue.Replacement != nil && p.cfg.Issues.NeedFix { - // we need to fix all issues at once => we need to return all of them - return true - } - - 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/pkg/result/processors/max_per_file_from_linter.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_per_file_from_linter.go deleted file mode 100644 index a39c98473..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_per_file_from_linter.go +++ /dev/null @@ -1,73 +0,0 @@ -package processors - -import ( - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*MaxPerFileFromLinter)(nil) - -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 - maxPerFileFromLinterConfig["gofmt"] = 1 - maxPerFileFromLinterConfig["goimports"] = 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/pkg/result/processors/max_same_issues.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_same_issues.go deleted file mode 100644 index 1647cace0..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/max_same_issues.go +++ /dev/null @@ -1,79 +0,0 @@ -package processors - -import ( - "sort" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*MaxSameIssues)(nil) - -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 { - if issue.Replacement != nil && p.cfg.Issues.NeedFix { - // we need to fix all issues at once => we need to return all of them - return true - } - - 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/pkg/result/processors/nolint.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/nolint.go deleted file mode 100644 index 7794bd3ec..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/nolint.go +++ /dev/null @@ -1,315 +0,0 @@ -package processors - -import ( - "go/ast" - "go/parser" - "go/token" - "regexp" - "sort" - "strings" - - "golang.org/x/exp/maps" - - "github.com/golangci/golangci-lint/pkg/golinters/nolintlint" - "github.com/golangci/golangci-lint/pkg/lint/linter" - "github.com/golangci/golangci-lint/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*Nolint)(nil) - -var nolintDebugf = logutils.Debug(logutils.DebugKeyNolint) - -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 -} - -type Nolint struct { - fileCache map[string]*fileData - dbManager *lintersdb.Manager - enabledLinters map[string]*linter.Config - log logutils.Log - - unknownLintersSet map[string]bool - - pattern *regexp.Regexp -} - -func NewNolint(log logutils.Log, dbManager *lintersdb.Manager, enabledLinters map[string]*linter.Config) *Nolint { - return &Nolint{ - fileCache: map[string]*fileData{}, - dbManager: dbManager, - enabledLinters: enabledLinters, - log: log, - unknownLintersSet: map[string]bool{}, - pattern: regexp.MustCompile(`^nolint( |:|$)`), - } -} - -func (*Nolint) Name() string { - return "nolint" -} - -func (p *Nolint) 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 *Nolint) Finish() { - if len(p.unknownLintersSet) == 0 { - return - } - - unknownLinters := maps.Keys(p.unknownLintersSet) - sort.Strings(unknownLinters) - - p.log.Warnf("Found unknown linters in //nolint directives: %s", strings.Join(unknownLinters, ", ")) -} - -func (p *Nolint) 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 *Nolint) 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 *Nolint) 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 := append([]ignoredRange{}, inlineRanges...) - allRanges = append(allRanges, e.expandedRanges...) - - return allRanges -} - -func (p *Nolint) 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 *Nolint) 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 - } - - // ignore specific linters - var linters []string - text = strings.Split(text, "//")[0] // allow another comment after this comment - linterItems := strings.Split(strings.TrimPrefix(text, "nolint:"), ",") - for _, item := range linterItems { - 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/pkg/result/processors/path_prefixer.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_prefixer.go deleted file mode 100644 index 8036e3fd6..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_prefixer.go +++ /dev/null @@ -1,36 +0,0 @@ -package processors - -import ( - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*PathPrefixer)(nil) - -// PathPrefixer adds a customizable prefix to every output path -type PathPrefixer struct { - prefix string -} - -// NewPathPrefixer returns a new path prefixer for the provided string -func NewPathPrefixer(prefix string) *PathPrefixer { - return &PathPrefixer{prefix: prefix} -} - -// Name returns the name of this processor -func (*PathPrefixer) Name() string { - return "path_prefixer" -} - -// Process adds the prefix to each path -func (p *PathPrefixer) Process(issues []result.Issue) ([]result.Issue, error) { - if p.prefix != "" { - for i := range issues { - issues[i].Pos.Filename = fsutils.WithPathPrefix(p.prefix, issues[i].Pos.Filename) - } - } - return issues, nil -} - -// Finish is implemented to satisfy the Processor interface -func (*PathPrefixer) Finish() {} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_prettifier.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_prettifier.go deleted file mode 100644 index c5c27357c..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_prettifier.go +++ /dev/null @@ -1,40 +0,0 @@ -package processors - -import ( - "path/filepath" - - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*PathPrettifier)(nil) - -type PathPrettifier struct { -} - -func NewPathPrettifier() *PathPrettifier { - return &PathPrettifier{} -} - -func (PathPrettifier) Name() string { - return "path_prettifier" -} - -func (PathPrettifier) Process(issues []result.Issue) ([]result.Issue, error) { - return transformIssues(issues, func(issue *result.Issue) *result.Issue { - if !filepath.IsAbs(issue.FilePath()) { - return issue - } - - rel, err := fsutils.ShortestRelPath(issue.FilePath(), "") - if err != nil { - return issue - } - - newIssue := issue - newIssue.Pos.Filename = rel - return newIssue - }), nil -} - -func (PathPrettifier) Finish() {} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_shortener.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_shortener.go deleted file mode 100644 index b161e86c2..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/path_shortener.go +++ /dev/null @@ -1,39 +0,0 @@ -package processors - -import ( - "fmt" - "strings" - - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*PathShortener)(nil) - -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/pkg/result/processors/processor.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/processor.go deleted file mode 100644 index 13e63d604..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/processor.go +++ /dev/null @@ -1,13 +0,0 @@ -package processors - -import ( - "github.com/golangci/golangci-lint/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/pkg/result/processors/severity.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/severity.go deleted file mode 100644 index 93a26586d..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/severity.go +++ /dev/null @@ -1,116 +0,0 @@ -package processors - -import ( - "regexp" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -const severityFromLinter = "@linter" - -var _ Processor = (*Severity)(nil) - -type severityRule struct { - baseRule - severity string -} - -type Severity struct { - name string - - log logutils.Log - - files *fsutils.Files - - defaultSeverity string - rules []severityRule -} - -func NewSeverity(log logutils.Log, files *fsutils.Files, cfg *config.Severity) *Severity { - p := &Severity{ - name: "severity-rules", - files: files, - log: log, - defaultSeverity: cfg.Default, - } - - prefix := caseInsensitivePrefix - if cfg.CaseSensitive { - prefix = "" - p.name = "severity-rules-case-sensitive" - } - - p.rules = createSeverityRules(cfg.Rules, prefix) - - 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.files, p.log) { - if rule.severity == severityFromLinter || (rule.severity == "" && p.defaultSeverity == severityFromLinter) { - return issue - } - - issue.Severity = rule.severity - if issue.Severity == "" { - issue.Severity = p.defaultSeverity - } - - return issue - } - } - - if p.defaultSeverity != severityFromLinter { - issue.Severity = p.defaultSeverity - } - - return issue -} - -func createSeverityRules(rules []config.SeverityRule, prefix string) []severityRule { - parsedRules := make([]severityRule, 0, len(rules)) - - for _, rule := range rules { - parsedRule := severityRule{} - parsedRule.linters = rule.Linters - parsedRule.severity = rule.Severity - - if rule.Text != "" { - parsedRule.text = regexp.MustCompile(prefix + rule.Text) - } - - if rule.Source != "" { - parsedRule.source = regexp.MustCompile(prefix + rule.Source) - } - - if rule.Path != "" { - path := fsutils.NormalizePathInRegex(rule.Path) - parsedRule.path = regexp.MustCompile(path) - } - - if rule.PathExcept != "" { - pathExcept := fsutils.NormalizePathInRegex(rule.PathExcept) - parsedRule.pathExcept = regexp.MustCompile(pathExcept) - } - - parsedRules = append(parsedRules, parsedRule) - } - - return parsedRules -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_dirs.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_dirs.go deleted file mode 100644 index 39dbfd1d3..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_dirs.go +++ /dev/null @@ -1,172 +0,0 @@ -package processors - -import ( - "fmt" - "path/filepath" - "regexp" - - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*SkipDirs)(nil) - -var StdExcludeDirRegexps = []string{ - normalizePathRegex("vendor"), - normalizePathRegex("third_party"), - normalizePathRegex("testdata"), - normalizePathRegex("examples"), - normalizePathRegex("Godeps"), - normalizePathRegex("builtin"), -} - -type skipStat struct { - pattern string - count int -} - -type SkipDirs struct { - patterns []*regexp.Regexp - log logutils.Log - skippedDirs map[string]*skipStat - absArgsDirs []string - skippedDirsCache map[string]bool - pathPrefix string -} - -func NewSkipDirs(log logutils.Log, patterns, args []string, pathPrefix string) (*SkipDirs, error) { - var patternsRe []*regexp.Regexp - for _, p := range patterns { - p = fsutils.NormalizePathInRegex(p) - patternRe, err := regexp.Compile(p) - if err != nil { - return nil, fmt.Errorf("can't compile regexp %q: %w", p, err) - } - patternsRe = append(patternsRe, patternRe) - } - - absArgsDirs, err := absDirs(args) - if err != nil { - return nil, err - } - - return &SkipDirs{ - patterns: patternsRe, - log: log, - skippedDirs: map[string]*skipStat{}, - absArgsDirs: absArgsDirs, - skippedDirsCache: map[string]bool{}, - pathPrefix: pathPrefix, - }, nil -} - -func (*SkipDirs) Name() string { - return "skip_dirs" -} - -func (p *SkipDirs) Process(issues []result.Issue) ([]result.Issue, error) { - if len(p.patterns) == 0 { - return issues, nil - } - - return filterIssues(issues, p.shouldPassIssue), nil -} - -func (p *SkipDirs) Finish() { - for dir, stat := range p.skippedDirs { - p.log.Infof("Skipped %d issues from dir %s by pattern %s", stat.count, dir, stat.pattern) - } -} - -func (p *SkipDirs) shouldPassIssue(issue *result.Issue) bool { - if filepath.IsAbs(issue.FilePath()) { - if isGoFile(issue.FilePath()) { - p.log.Warnf("Got abs path %s in skip dirs processor, it should be relative", issue.FilePath()) - } - return true - } - - issueRelDir := filepath.Dir(issue.FilePath()) - - if toPass, ok := p.skippedDirsCache[issueRelDir]; ok { - if !toPass { - p.skippedDirs[issueRelDir].count++ - } - return toPass - } - - issueAbsDir, err := filepath.Abs(issueRelDir) - if err != nil { - p.log.Warnf("Can't abs-ify path %q: %s", issueRelDir, err) - return true - } - - toPass := p.shouldPassIssueDirs(issueRelDir, issueAbsDir) - p.skippedDirsCache[issueRelDir] = toPass - return toPass -} - -func (p *SkipDirs) shouldPassIssueDirs(issueRelDir, issueAbsDir string) bool { - for _, absArgDir := range p.absArgsDirs { - if absArgDir == issueAbsDir { - // we must not skip issues if they are from explicitly set dirs - // even if they match skip patterns - return true - } - } - - // We use issueRelDir for matching: it's the relative to the current - // work dir path of directory of source file with the issue. It can lead - // to unexpected behavior if we're analyzing files out of current work dir. - // The alternative solution is to find relative to args path, but it has - // disadvantages (https://github.com/golangci/golangci-lint/pull/313). - - path := fsutils.WithPathPrefix(p.pathPrefix, issueRelDir) - for _, pattern := range p.patterns { - if pattern.MatchString(path) { - ps := pattern.String() - if p.skippedDirs[issueRelDir] == nil { - p.skippedDirs[issueRelDir] = &skipStat{ - pattern: ps, - } - } - p.skippedDirs[issueRelDir].count++ - return false - } - } - - return true -} - -func absDirs(args []string) ([]string, error) { - if len(args) == 0 { - args = append(args, "./...") - } - - var absArgsDirs []string - for _, arg := range args { - base := filepath.Base(arg) - if base == "..." || isGoFile(base) { - arg = filepath.Dir(arg) - } - - absArg, err := filepath.Abs(arg) - if err != nil { - return nil, fmt.Errorf("failed to abs-ify arg %q: %w", arg, err) - } - - absArgsDirs = append(absArgsDirs, absArg) - } - - return absArgsDirs, nil -} - -func normalizePathRegex(e string) string { - return createPathRegex(e, filepath.Separator) -} - -func createPathRegex(e string, sep rune) string { - escapedSep := regexp.QuoteMeta(string(sep)) // needed for windows sep '\\' - return fmt.Sprintf(`(^|%[1]s)%[2]s($|%[1]s)`, escapedSep, e) -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_files.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_files.go deleted file mode 100644 index 3b17a9f32..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/skip_files.go +++ /dev/null @@ -1,59 +0,0 @@ -package processors - -import ( - "fmt" - "regexp" - - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*SkipFiles)(nil) - -type SkipFiles struct { - patterns []*regexp.Regexp - pathPrefix string -} - -func NewSkipFiles(patterns []string, pathPrefix string) (*SkipFiles, error) { - var patternsRe []*regexp.Regexp - for _, p := range patterns { - p = fsutils.NormalizePathInRegex(p) - - patternRe, err := regexp.Compile(p) - if err != nil { - return nil, fmt.Errorf("can't compile regexp %q: %w", p, err) - } - - patternsRe = append(patternsRe, patternRe) - } - - return &SkipFiles{ - patterns: patternsRe, - pathPrefix: pathPrefix, - }, nil -} - -func (SkipFiles) Name() string { - return "skip_files" -} - -func (p SkipFiles) Process(issues []result.Issue) ([]result.Issue, error) { - if len(p.patterns) == 0 { - return issues, nil - } - - return filterIssues(issues, func(issue *result.Issue) bool { - path := fsutils.WithPathPrefix(p.pathPrefix, issue.FilePath()) - - for _, pattern := range p.patterns { - if pattern.MatchString(path) { - return false - } - } - - return true - }), nil -} - -func (SkipFiles) Finish() {} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/sort_results.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/sort_results.go deleted file mode 100644 index 4da73c72e..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/sort_results.go +++ /dev/null @@ -1,259 +0,0 @@ -package processors - -import ( - "errors" - "fmt" - "slices" - "sort" - "strings" - - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/result" -) - -// Base propose of this functionality to sort results (issues) -// produced by various linters by analyzing code. We're achieving this -// by sorting results.Issues using processor step, and chain based -// rules that can compare different properties of the Issues struct. - -const ( - orderNameFile = "file" - orderNameLinter = "linter" - orderNameSeverity = "severity" -) - -var _ Processor = (*SortResults)(nil) - -type SortResults struct { - cmps map[string]*comparator - - cfg *config.Output -} - -func NewSortResults(cfg *config.Config) *SortResults { - return &SortResults{ - cmps: map[string]*comparator{ - // For sorting we are comparing (in next order): - // file names, line numbers, position, and finally - giving up. - orderNameFile: byFileName().SetNext(byLine().SetNext(byColumn())), - // For sorting we are comparing: linter name - orderNameLinter: byLinter(), - // For sorting we are comparing: severity - orderNameSeverity: bySeverity(), - }, - cfg: &cfg.Output, - } -} - -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 !p.cfg.SortResults { - return issues, nil - } - - if len(p.cfg.SortOrder) == 0 { - p.cfg.SortOrder = []string{orderNameFile} - } - - var cmps []*comparator - 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) - } - - cmp, err := mergeComparators(cmps) - if err != nil { - return nil, err - } - - sort.Slice(issues, func(i, j int) bool { - return cmp.Compare(&issues[i], &issues[j]) == less - }) - - return issues, nil -} - -func (SortResults) Finish() {} - -type compareResult int - -const ( - less compareResult = iota - 1 - equal - greater - none -) - -func (c compareResult) isNeutral() bool { - // return true if compare result is incomparable or equal. - return c == none || c == equal -} - -func (c compareResult) String() string { - switch c { - case less: - return "less" - case equal: - return "equal" - case greater: - return "greater" - default: - return "none" - } -} - -// comparator describes how to implement compare for two "issues". -type comparator struct { - name string - compare func(a, b *result.Issue) compareResult - next *comparator -} - -func (cmp *comparator) Next() *comparator { return cmp.next } - -func (cmp *comparator) SetNext(c *comparator) *comparator { - cmp.next = c - return cmp -} - -func (cmp *comparator) String() string { - s := cmp.name - if cmp.Next() != nil { - s += " > " + cmp.Next().String() - } - - return s -} - -func (cmp *comparator) Compare(a, b *result.Issue) compareResult { - res := cmp.compare(a, b) - if !res.isNeutral() { - return res - } - - if next := cmp.Next(); next != nil { - return next.Compare(a, b) - } - - return res -} - -func byFileName() *comparator { - return &comparator{ - name: "byFileName", - compare: func(a, b *result.Issue) compareResult { - return compareResult(strings.Compare(a.FilePath(), b.FilePath())) - }, - } -} - -func byLine() *comparator { - return &comparator{ - name: "byLine", - compare: func(a, b *result.Issue) compareResult { - return numericCompare(a.Line(), b.Line()) - }, - } -} - -func byColumn() *comparator { - return &comparator{ - name: "byColumn", - compare: func(a, b *result.Issue) compareResult { - return numericCompare(a.Column(), b.Column()) - }, - } -} - -func byLinter() *comparator { - return &comparator{ - name: "byLinter", - compare: func(a, b *result.Issue) compareResult { - return compareResult(strings.Compare(a.FromLinter, b.FromLinter)) - }, - } -} - -func bySeverity() *comparator { - return &comparator{ - name: "bySeverity", - compare: func(a, b *result.Issue) compareResult { - return severityCompare(a.Severity, b.Severity) - }, - } -} - -func mergeComparators(cmps []*comparator) (*comparator, error) { - if len(cmps) == 0 { - return nil, errors.New("no comparator") - } - - for i := range len(cmps) - 1 { - findComparatorTip(cmps[i]).SetNext(cmps[i+1]) - } - - return cmps[0], nil -} - -func findComparatorTip(cmp *comparator) *comparator { - if cmp.Next() != nil { - return findComparatorTip(cmp.Next()) - } - - return cmp -} - -func severityCompare(a, b string) compareResult { - // 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) { - switch { - case slices.Index(classic, a) > slices.Index(classic, b): - return greater - case slices.Index(classic, a) < slices.Index(classic, b): - return less - default: - return equal - } - } - - if slices.Contains(classic, a) { - return greater - } - - if slices.Contains(classic, b) { - return less - } - - return compareResult(strings.Compare(a, b)) -} - -func numericCompare(a, b int) compareResult { - var ( - isValuesInvalid = a < 0 || b < 0 - isZeroValuesBoth = a == 0 && b == 0 - isEqual = a == b - isZeroValueInA = b > 0 && a == 0 - isZeroValueInB = a > 0 && b == 0 - ) - - switch { - case isZeroValuesBoth || isEqual: - return equal - case isValuesInvalid || isZeroValueInA || isZeroValueInB: - return none - case a > b: - return greater - case a < b: - return less - } - - return equal -} diff --git a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/source_code.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/source_code.go deleted file mode 100644 index 4a89fc73e..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/source_code.go +++ /dev/null @@ -1,50 +0,0 @@ -package processors - -import ( - "github.com/golangci/golangci-lint/pkg/fsutils" - "github.com/golangci/golangci-lint/pkg/logutils" - "github.com/golangci/golangci-lint/pkg/result" -) - -var _ Processor = (*SourceCode)(nil) - -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/pkg/result/processors/uniq_by_line.go b/vendor/github.com/golangci/golangci-lint/pkg/result/processors/uniq_by_line.go deleted file mode 100644 index 115196d9a..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/result/processors/uniq_by_line.go +++ /dev/null @@ -1,73 +0,0 @@ -package processors - -import ( - "github.com/golangci/golangci-lint/pkg/config" - "github.com/golangci/golangci-lint/pkg/result" -) - -const uniqByLineLimit = 1 - -var _ Processor = (*UniqByLine)(nil) - -type UniqByLine struct { - fileLineCounter fileLineCounter - cfg *config.Config -} - -func NewUniqByLine(cfg *config.Config) *UniqByLine { - return &UniqByLine{ - fileLineCounter: fileLineCounter{}, - cfg: cfg, - } -} - -func (*UniqByLine) Name() string { - return "uniq_by_line" -} - -func (p *UniqByLine) Process(issues []result.Issue) ([]result.Issue, error) { - if !p.cfg.Output.UniqByLine { - return issues, nil - } - - return filterIssuesUnsafe(issues, p.shouldPassIssue), nil -} - -func (*UniqByLine) Finish() {} - -func (p *UniqByLine) shouldPassIssue(issue *result.Issue) bool { - if issue.Replacement != nil && p.cfg.Issues.NeedFix { - // if issue will be auto-fixed we shouldn't collapse issues: - // e.g. one line can contain 2 misspellings, they will be in 2 issues and misspell should fix both of them. - return true - } - - 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/pkg/timeutils/stopwatch.go b/vendor/github.com/golangci/golangci-lint/pkg/timeutils/stopwatch.go deleted file mode 100644 index d944dea2e..000000000 --- a/vendor/github.com/golangci/golangci-lint/pkg/timeutils/stopwatch.go +++ /dev/null @@ -1,116 +0,0 @@ -package timeutils - -import ( - "fmt" - "sort" - "strings" - "sync" - "time" - - "github.com/golangci/golangci-lint/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() -} diff --git a/vendor/github.com/golangci/misspell/.gitignore b/vendor/github.com/golangci/misspell/.gitignore deleted file mode 100644 index 5e5c368f8..000000000 --- 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 2cfed442f..000000000 --- a/vendor/github.com/golangci/misspell/.golangci.yml +++ /dev/null @@ -1,107 +0,0 @@ -run: - timeout: 2m - -linters-settings: - govet: - enable-all: true - disable: - - fieldalignment - gocyclo: - min-complexity: 16 - goconst: - min-len: 3 - min-occurrences: 3 - misspell: - locale: US - funlen: - lines: -1 - statements: 40 - gofumpt: - extra-rules: true - 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 - godox: - keywords: - - FIXME - gocritic: - enabled-tags: - - diagnostic - - style - - performance - disabled-checks: - - sloppyReassign - - rangeValCopy - - octalLiteral - - paramTypeCombine # already handle by gofumpt.extra-rules - - exitAfterDefer # FIXME(ldez) must be fixed - - ifElseChain # FIXME(ldez) must be fixed - settings: - hugeParam: - sizeThreshold: 100 - forbidigo: - forbid: - - '^print(ln)?$' - - '^panic$' - - '^spew\.Print(f|ln)?$' - - '^spew\.Dump$' - -linters: - enable-all: true - disable: - - deadcode # deprecated - - exhaustivestruct # deprecated - - golint # deprecated - - ifshort # deprecated - - interfacer # deprecated - - maligned # deprecated - - nosnakecase # deprecated - - scopelint # deprecated - - scopelint # deprecated - - structcheck # deprecated - - varcheck # deprecated - - execinquery # not relevant (SQL) - - rowserrcheck # not relevant (SQL) - - sqlclosecheck # not relevant (SQL) - - cyclop # duplicate of gocyclo - - dupl - - exhaustive - - exhaustruct - - forbidigo - - gochecknoglobals - - gochecknoinits - - goerr113 - - gomnd - - lll - - nilnil - - nlreturn - - paralleltest - - prealloc - - testpackage - - tparallel - - varnamelen - - wrapcheck - - wsl - - misspell - - gosec # FIXME(ldez) must be fixed - - errcheck # FIXME(ldez) must be fixed - - nonamedreturns # FIXME(ldez) must be fixed - - nakedret # FIXME(ldez) must be fixed - -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' - - 'package-comments: should have a package comment' - exclude-rules: - - path: .*_test.go - linters: - - funlen - - goconst 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 5319a75eb..000000000 --- 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/Dockerfile b/vendor/github.com/golangci/misspell/Dockerfile deleted file mode 100644 index c85cd6875..000000000 --- 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 bfcfcd301..000000000 --- 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 fcda870ce..000000000 --- a/vendor/github.com/golangci/misspell/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -CONTAINER=golangci/misspell - -default: 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 - -# 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 d2c3e7527..000000000 --- a/vendor/github.com/golangci/misspell/README.md +++ /dev/null @@ -1,401 +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/master/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/master/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/master/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 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 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) -* [Golang 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 golang source files? - -yes, 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 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-seprated 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 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: - -``` -{{ .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 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 golang 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/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 is 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/golangci/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 on 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 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 55b52d962..000000000 --- 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 d60af5a8d..000000000 --- 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 := 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/golangci/misspell/case.go b/vendor/github.com/golangci/misspell/case.go deleted file mode 100644 index 0b580bedb..000000000 --- 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 := 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 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 2d2be1a75..000000000 --- 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 d6023e117..000000000 --- a/vendor/github.com/golangci/misspell/install-misspell.sh +++ /dev/null @@ -1,377 +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 - 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 f694f46dc..000000000 --- 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 b51dfa83b..000000000 --- a/vendor/github.com/golangci/misspell/replace.go +++ /dev/null @@ -1,245 +0,0 @@ -package misspell - -import ( - "bufio" - "bytes" - "io" - "regexp" - "slices" - "strings" - "text/scanner" -) - -func max(x, y int) int { - if x > y { - return x - } - return y -} - -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...) -} - -/* -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 += 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 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 := 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/golangci/misspell/stringreplacer.go b/vendor/github.com/golangci/misspell/stringreplacer.go deleted file mode 100644 index 46cb6c4b6..000000000 --- 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 := 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 -} - -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 -} - -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 -} - -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 70da997f6..000000000 --- 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 a91d1d967..000000000 --- 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 1603d87e6..000000000 --- a/vendor/github.com/golangci/misspell/words.go +++ /dev/null @@ -1,31194 +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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "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", "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", - "suppoted", "supported", - "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", - "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", "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", - "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", "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", - "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", "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", - "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", - "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/golangci/modinfo/.gitignore b/vendor/github.com/golangci/modinfo/.gitignore deleted file mode 100644 index 9f11b755a..000000000 --- a/vendor/github.com/golangci/modinfo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.idea/ diff --git a/vendor/github.com/golangci/modinfo/.golangci.yml b/vendor/github.com/golangci/modinfo/.golangci.yml deleted file mode 100644 index 9698182f2..000000000 --- a/vendor/github.com/golangci/modinfo/.golangci.yml +++ /dev/null @@ -1,157 +0,0 @@ -run: - timeout: 7m - -linters-settings: - govet: - enable: - - shadow - gocyclo: - min-complexity: 12 - goconst: - min-len: 3 - min-occurrences: 3 - funlen: - lines: -1 - statements: 50 - misspell: - locale: US - 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 - tagalign: - align: false - order: - - xml - - json - - yaml - - yml - - toml - - mapstructure - - url - godox: - keywords: - - FIXME - gocritic: - enabled-tags: - - diagnostic - - style - - performance - disabled-checks: - - paramTypeCombine # already handle by gofumpt.extra-rules - - whyNoLint # already handle by nonolint - - unnamedResult - - hugeParam - - sloppyReassign - - rangeValCopy - - octalLiteral - - ptrToRefParam - - appendAssign - - ruleguard - - httpNoBody - - exposedSyncMutex - 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 - disabled: true - - name: if-return - - name: increment-decrement - - name: var-naming - - name: var-declaration - - name: package-comments - disabled: true - - 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 - disabled: true - - name: unreachable-code - - name: redefines-builtin-id - - tagliatelle: - case: - rules: - json: pascal - yaml: camel - xml: camel - header: header - mapstructure: camel - env: upperSnake - envconfig: upperSnake - -linters: - enable-all: true - disable: - - deadcode # deprecated - - exhaustivestruct # deprecated - - golint # deprecated - - ifshort # deprecated - - interfacer # deprecated - - maligned # deprecated - - nosnakecase # deprecated - - scopelint # deprecated - - structcheck # deprecated - - varcheck # deprecated - - cyclop # duplicate of gocyclo - - sqlclosecheck # not relevant (SQL) - - rowserrcheck # not relevant (SQL) - - execinquery # not relevant (SQL) - - lll - - gosec - - dupl # not relevant - - prealloc # too many false-positive - - bodyclose # too many false-positive - - gomnd - - testpackage # not relevant - - tparallel # not relevant - - paralleltest # not relevant - - nestif # too many false-positive - - wrapcheck - - goerr113 # not relevant - - nlreturn # not relevant - - wsl # not relevant - - exhaustive # not relevant - - exhaustruct # not relevant - - makezero # not relevant - - forbidigo - - varnamelen # not relevant - - nilnil # not relevant - - ireturn # not relevant - - contextcheck # too many false-positive - - tenv # we already have a test "framework" to handle env vars - - noctx - - errchkjson - - nonamedreturns - - gosmopolitan # not relevant - - gochecknoglobals - -issues: - exclude-use-default: false - max-issues-per-linter: 0 - max-same-issues: 0 - exclude: - - 'Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked' - - 'ST1000: at least one file in a package should have a package comment' - exclude-rules: - - path: (.+)_test.go - linters: - - funlen - - goconst - - maintidx diff --git a/vendor/github.com/golangci/modinfo/LICENSE b/vendor/github.com/golangci/modinfo/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/vendor/github.com/golangci/modinfo/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/golangci/modinfo/Makefile b/vendor/github.com/golangci/modinfo/Makefile deleted file mode 100644 index df91018f1..000000000 --- a/vendor/github.com/golangci/modinfo/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -.PHONY: clean check test - -default: clean check test - -clean: - rm -rf dist/ cover.out - -test: clean - go test -v -cover ./... - -check: - golangci-lint run diff --git a/vendor/github.com/golangci/modinfo/module.go b/vendor/github.com/golangci/modinfo/module.go deleted file mode 100644 index ff0b21b9b..000000000 --- a/vendor/github.com/golangci/modinfo/module.go +++ /dev/null @@ -1,157 +0,0 @@ -package modinfo - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "os" - "os/exec" - "path/filepath" - "reflect" - "sort" - "strings" - "sync" - - "golang.org/x/mod/modfile" - "golang.org/x/tools/go/analysis" -) - -type ModInfo struct { - Path string `json:"Path"` - Dir string `json:"Dir"` - GoMod string `json:"GoMod"` - GoVersion string `json:"GoVersion"` - Main bool `json:"Main"` -} - -var ( - once sync.Once - information []ModInfo - errInfo error -) - -var Analyzer = &analysis.Analyzer{ - Name: "modinfo", - Doc: "Module information", - URL: "https://github.com/golangci/modinfo", - Run: runOnce, - ResultType: reflect.TypeOf([]ModInfo(nil)), -} - -func runOnce(pass *analysis.Pass) (any, error) { - _, ok := os.LookupEnv("MODINFO_DEBUG_DISABLE_ONCE") - if ok { - return GetModuleInfo(pass) - } - - once.Do(func() { - information, errInfo = GetModuleInfo(pass) - }) - - return information, errInfo -} - -// GetModuleInfo gets modules information. -// Always returns 1 element except for workspace (returns all the modules of the workspace). -// Based on `go list -m -json` behavior. -func GetModuleInfo(pass *analysis.Pass) ([]ModInfo, error) { - // https://github.com/golang/go/issues/44753#issuecomment-790089020 - cmd := exec.Command("go", "list", "-m", "-json") - for _, file := range pass.Files { - name := pass.Fset.File(file.Pos()).Name() - if filepath.Ext(name) != ".go" { - continue - } - - cmd.Dir = filepath.Dir(name) - break - } - - out, err := cmd.Output() - if err != nil { - return nil, fmt.Errorf("command go list: %w: %s", 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") - } - - sort.Slice(infos, func(i, j int) bool { - return len(infos[i].Path) > len(infos[j].Path) - }) - - return infos, nil -} - -// FindModuleFromPass finds the module related to the files of the pass. -func FindModuleFromPass(pass *analysis.Pass) (ModInfo, error) { - infos, ok := pass.ResultOf[Analyzer].([]ModInfo) - if !ok { - return ModInfo{}, errors.New("no modinfo analyzer result") - } - - var name string - for _, file := range pass.Files { - f := pass.Fset.File(file.Pos()).Name() - if filepath.Ext(f) != ".go" { - continue - } - - name = f - break - } - - // no Go file found in analysis pass - if name == "" { - name, _ = os.Getwd() - } - - for _, info := range infos { - if !strings.HasPrefix(name, info.Dir) { - continue - } - return info, nil - } - - return ModInfo{}, errors.New("module information not found") -} - -// ReadModuleFileFromPass read the `go.mod` file from the pass result. -func ReadModuleFileFromPass(pass *analysis.Pass) (*modfile.File, error) { - info, err := FindModuleFromPass(pass) - if err != nil { - return nil, err - } - - return ReadModuleFile(info) -} - -// ReadModuleFile read the `go.mod` file. -func ReadModuleFile(info ModInfo) (*modfile.File, error) { - raw, err := os.ReadFile(info.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/golangci/modinfo/readme.md b/vendor/github.com/golangci/modinfo/readme.md deleted file mode 100644 index 2175de8eb..000000000 --- a/vendor/github.com/golangci/modinfo/readme.md +++ /dev/null @@ -1,73 +0,0 @@ -# modinfo - -This module contains: -- an analyzer that returns module information. -- methods to find and read `go.mod` file - -## Examples - -```go -package main - -import ( - "fmt" - - "github.com/golangci/modinfo" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" -) - -var Analyzer = &analysis.Analyzer{ - Name: "example", - Doc: "Example", - Run: func(pass *analysis.Pass) (interface{}, error) { - file, err := modinfo.ReadModuleFileFromPass(pass) - if err != nil { - return nil, err - } - - fmt.Println("go.mod", file) - - // TODO - - return nil, nil - }, - Requires: []*analysis.Analyzer{ - inspect.Analyzer, - modinfo.Analyzer, - }, -} -``` - -```go -package main - -import ( - "fmt" - - "github.com/golangci/modinfo" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" -) - -var Analyzer = &analysis.Analyzer{ - Name: "example", - Doc: "Example", - Run: func(pass *analysis.Pass) (interface{}, error) { - info, err := modinfo.FindModuleFromPass(pass) - if err != nil { - return nil, err - } - - fmt.Println("Module", info.Dir) - - // TODO - - return nil, nil - }, - Requires: []*analysis.Analyzer{ - inspect.Analyzer, - modinfo.Analyzer, - }, -} -``` 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 e72bfddab..000000000 --- a/vendor/github.com/golangci/plugin-module-register/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/plugin-module-register/register/register.go b/vendor/github.com/golangci/plugin-module-register/register/register.go deleted file mode 100644 index 72ad7f46f..000000000 --- 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 0540fe2ca..000000000 --- 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 5239720ac..000000000 --- a/vendor/github.com/golangci/revgrep/.golangci.yml +++ /dev/null @@ -1,80 +0,0 @@ -run: - timeout: 2m - -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 - -linters: - enable-all: true - disable: - - deadcode # deprecated - - exhaustivestruct # deprecated - - golint # deprecated - - ifshort # deprecated - - interfacer # deprecated - - maligned # deprecated - - nosnakecase # deprecated - - scopelint # deprecated - - structcheck # deprecated - - varcheck # deprecated - - cyclop # duplicate of gocyclo - - sqlclosecheck # not relevant (SQL) - - rowserrcheck # not relevant (SQL) - - execinquery # not relevant (SQL) - - dupl - - lll - - nestif - - gomnd - - goerr113 - - nlreturn - - wsl - - exhaustive - - exhaustruct - - tparallel - - testpackage - - paralleltest - - ifshort - - forcetypeassert - - varnamelen - - prealloc # false-positives - - nosnakecase - - nonamedreturns - - nilerr - - depguard - -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 diff --git a/vendor/github.com/golangci/revgrep/LICENSE b/vendor/github.com/golangci/revgrep/LICENSE deleted file mode 100644 index 8dada3eda..000000000 --- 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 5ac8725d0..000000000 --- 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 97f25ffb3..000000000 --- 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 get -u github.com/golangci/revgrep/... -``` - -# 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/revgrep.go b/vendor/github.com/golangci/revgrep/revgrep.go deleted file mode 100644 index 1ef81b203..000000000 --- a/vendor/github.com/golangci/revgrep/revgrep.go +++ /dev/null @@ -1,483 +0,0 @@ -// Package revgrep filter static analysis tools to only lines changed based on a commit reference. -package revgrep - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "os" - "os/exec" - "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 - // 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 - // RevisionTo checks revision finishing at, leave blank for auto-detection ignored if patch is set. - RevisionTo string - // 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 IsNewIssue - changes map[string][]pos -} - -// 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 -} - -type pos struct { - lineNo int // line number - hunkPos int // position relative to first @@ in file -} - -func (i simpleInputIssue) FilePath() string { - return i.filePath -} - -func (i simpleInputIssue) Line() int { - return i.lineNumber -} - -// Prepare extracts a patch and changed lines. -func (c *Checker) Prepare() error { - returnErr := c.preparePatch() - c.changes = c.linesChanged() - return returnErr -} - -// IsNewIssue checks whether issue found by linter is new: it was found in changed lines. -func (c *Checker) IsNewIssue(i InputIssue) (hunkPos int, isNew bool) { - fchanges, ok := c.changes[filepath.ToSlash(i.FilePath())] - if !ok { // file wasn't changed - return 0, false - } - - if c.WholeFiles { - return i.Line(), true - } - - var ( - fpos pos - changed bool - ) - // found file, see if lines matched - for _, pos := range fchanges { - if pos.lineNo == i.Line() { - fpos = pos - changed = true - break - } - } - - if changed || fchanges == nil { - // either file changed or it's a new file - hunkPos := fpos.lineNo - if changed { // existing file changed - hunkPos = fpos.hunkPos - } - - return hunkPos, true - } - - return 0, false -} - -// 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(reader io.Reader, writer io.Writer) (issues []Issue, err error) { - returnErr := c.Prepare() - writeAll := returnErr != 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 { - returnErr = 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 { - returnErr = fmt.Errorf("error reading standard input: %w", err) - } - - return issues, returnErr -} - -func (c *Checker) debugf(format string, s ...interface{}) { - if c.Debug != nil { - _, _ = fmt.Fprint(c.Debug, "DEBUG: ") - _, _ = fmt.Fprintf(c.Debug, format+"\n", s...) - } -} - -func (c *Checker) preparePatch() error { - // Check if patch is supplied, if not, retrieve from VCS - if c.Patch == nil { - var err error - c.Patch, c.NewFiles, err = GitPatch(c.RevisionFrom, c.RevisionTo) - 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 -} - -// 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(revisionFrom, revisionTo string) (io.Reader, []string, error) { - // check if git repo exists - if err := exec.Command("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.Command("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 revisionFrom != "" { - args := []string{revisionFrom} - - if revisionTo != "" { - args = append(args, revisionTo) - } - - args = append(args, "--") - - patch, errDiff := gitDiff(args...) - if errDiff != nil { - return nil, nil, errDiff - } - - if revisionTo == "" { - return patch, newFiles, nil - } - - return patch, nil, nil - } - - // make a patch for unstaged changes - patch, err := gitDiff("--") - 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("HEAD~", "--") - if err != nil { - return nil, nil, err - } - - return patch, nil, nil -} - -func gitDiff(extraArgs ...string) (*bytes.Buffer, error) { - cmd := exec.Command("git", "diff", "--color=never", "--no-ext-diff") - - if isSupportedByGit(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(major, minor, patch int) bool { - output, err := exec.Command("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 -} diff --git a/vendor/github.com/golangci/unconvert/LICENSE b/vendor/github.com/golangci/unconvert/LICENSE deleted file mode 100644 index 744875676..000000000 --- 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 e9230c218..000000000 --- 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 306c44e5e..000000000 --- a/vendor/github.com/golangci/unconvert/golangci.go +++ /dev/null @@ -1,78 +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 Run(pass *analysis.Pass, fastMath, safe bool) []token.Position { - type res struct { - file string - edits editSet - } - - flagFastMath = pointer(fastMath) - flagSafe = pointer(safe) - - 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 222aeadf8..000000000 --- a/vendor/github.com/golangci/unconvert/unconvert.go +++ /dev/null @@ -1,650 +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" - "io/ioutil" - "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 = ioutil.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 := ioutil.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/google/go-cmp/LICENSE b/vendor/github.com/google/go-cmp/LICENSE deleted file mode 100644 index 32017f8fa..000000000 --- a/vendor/github.com/google/go-cmp/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2017 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/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go deleted file mode 100644 index 0f5b8a48c..000000000 --- a/vendor/github.com/google/go-cmp/cmp/compare.go +++ /dev/null @@ -1,671 +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 cmp determines equality of values. -// -// This package is intended to be a more powerful and safer alternative to -// [reflect.DeepEqual] for comparing whether two values are semantically equal. -// It is intended to only be used in tests, as performance is not a goal and -// it may panic if it cannot compare the values. Its propensity towards -// panicking means that its unsuitable for production environments where a -// spurious panic may be fatal. -// -// The primary features of cmp are: -// -// - When the default behavior of equality does not suit the test's needs, -// custom equality functions can override the equality operation. -// For example, an equality function may report floats as equal so long as -// they are within some tolerance of each other. -// -// - Types with an Equal method (e.g., [time.Time.Equal]) may use that method -// to determine equality. This allows package authors to determine -// the equality operation for the types that they define. -// -// - If no custom equality functions are used and no Equal method is defined, -// equality is determined by recursively comparing the primitive kinds on -// both values, much like [reflect.DeepEqual]. Unlike [reflect.DeepEqual], -// unexported fields are not compared by default; they result in panics -// unless suppressed by using an [Ignore] option -// (see [github.com/google/go-cmp/cmp/cmpopts.IgnoreUnexported]) -// or explicitly compared using the [Exporter] option. -package cmp - -import ( - "fmt" - "reflect" - "strings" - - "github.com/google/go-cmp/cmp/internal/diff" - "github.com/google/go-cmp/cmp/internal/function" - "github.com/google/go-cmp/cmp/internal/value" -) - -// TODO(≥go1.18): Use any instead of interface{}. - -// Equal reports whether x and y are equal by recursively applying the -// following rules in the given order to x and y and all of their sub-values: -// -// - Let S be the set of all [Ignore], [Transformer], and [Comparer] options that -// remain after applying all path filters, value filters, and type filters. -// If at least one [Ignore] exists in S, then the comparison is ignored. -// If the number of [Transformer] and [Comparer] options in S is non-zero, -// then Equal panics because it is ambiguous which option to use. -// If S contains a single [Transformer], then use that to transform -// the current values and recursively call Equal on the output values. -// If S contains a single [Comparer], then use that to compare the current values. -// Otherwise, evaluation proceeds to the next rule. -// -// - If the values have an Equal method of the form "(T) Equal(T) bool" or -// "(T) Equal(I) bool" where T is assignable to I, then use the result of -// x.Equal(y) even if x or y is nil. Otherwise, no such method exists and -// evaluation proceeds to the next rule. -// -// - Lastly, try to compare x and y based on their basic kinds. -// Simple kinds like booleans, integers, floats, complex numbers, strings, -// and channels are compared using the equivalent of the == operator in Go. -// Functions are only equal if they are both nil, otherwise they are unequal. -// -// Structs are equal if recursively calling Equal on all fields report equal. -// If a struct contains unexported fields, Equal panics unless an [Ignore] option -// (e.g., [github.com/google/go-cmp/cmp/cmpopts.IgnoreUnexported]) ignores that field -// or the [Exporter] option explicitly permits comparing the unexported field. -// -// Slices are equal if they are both nil or both non-nil, where recursively -// calling Equal on all non-ignored slice or array elements report equal. -// Empty non-nil slices and nil slices are not equal; to equate empty slices, -// consider using [github.com/google/go-cmp/cmp/cmpopts.EquateEmpty]. -// -// Maps are equal if they are both nil or both non-nil, where recursively -// calling Equal on all non-ignored map entries report equal. -// Map keys are equal according to the == operator. -// To use custom comparisons for map keys, consider using -// [github.com/google/go-cmp/cmp/cmpopts.SortMaps]. -// Empty non-nil maps and nil maps are not equal; to equate empty maps, -// consider using [github.com/google/go-cmp/cmp/cmpopts.EquateEmpty]. -// -// Pointers and interfaces are equal if they are both nil or both non-nil, -// where they have the same underlying concrete type and recursively -// calling Equal on the underlying values reports equal. -// -// Before recursing into a pointer, slice element, or map, the current path -// is checked to detect whether the address has already been visited. -// If there is a cycle, then the pointed at values are considered equal -// only if both addresses were previously visited in the same path step. -func Equal(x, y interface{}, opts ...Option) bool { - s := newState(opts) - s.compareAny(rootStep(x, y)) - return s.result.Equal() -} - -// Diff returns a human-readable report of the differences between two values: -// y - x. It returns an empty string if and only if Equal returns true for the -// same input values and options. -// -// The output is displayed as a literal in pseudo-Go syntax. -// At the start of each line, a "-" prefix indicates an element removed from x, -// a "+" prefix to indicates an element added from y, and the lack of a prefix -// indicates an element common to both x and y. If possible, the output -// uses fmt.Stringer.String or error.Error methods to produce more humanly -// readable outputs. In such cases, the string is prefixed with either an -// 's' or 'e' character, respectively, to indicate that the method was called. -// -// Do not depend on this output being stable. If you need the ability to -// programmatically interpret the difference, consider using a custom Reporter. -func Diff(x, y interface{}, opts ...Option) string { - s := newState(opts) - - // Optimization: If there are no other reporters, we can optimize for the - // common case where the result is equal (and thus no reported difference). - // This avoids the expensive construction of a difference tree. - if len(s.reporters) == 0 { - s.compareAny(rootStep(x, y)) - if s.result.Equal() { - return "" - } - s.result = diff.Result{} // Reset results - } - - r := new(defaultReporter) - s.reporters = append(s.reporters, reporter{r}) - s.compareAny(rootStep(x, y)) - d := r.String() - if (d == "") != s.result.Equal() { - panic("inconsistent difference and equality results") - } - return d -} - -// rootStep constructs the first path step. If x and y have differing types, -// then they are stored within an empty interface type. -func rootStep(x, y interface{}) PathStep { - vx := reflect.ValueOf(x) - vy := reflect.ValueOf(y) - - // If the inputs are different types, auto-wrap them in an empty interface - // so that they have the same parent type. - var t reflect.Type - if !vx.IsValid() || !vy.IsValid() || vx.Type() != vy.Type() { - t = anyType - if vx.IsValid() { - vvx := reflect.New(t).Elem() - vvx.Set(vx) - vx = vvx - } - if vy.IsValid() { - vvy := reflect.New(t).Elem() - vvy.Set(vy) - vy = vvy - } - } else { - t = vx.Type() - } - - return &pathStep{t, vx, vy} -} - -type state struct { - // These fields represent the "comparison state". - // Calling statelessCompare must not result in observable changes to these. - result diff.Result // The current result of comparison - curPath Path // The current path in the value tree - curPtrs pointerPath // The current set of visited pointers - reporters []reporter // Optional reporters - - // recChecker checks for infinite cycles applying the same set of - // transformers upon the output of itself. - recChecker recChecker - - // dynChecker triggers pseudo-random checks for option correctness. - // It is safe for statelessCompare to mutate this value. - dynChecker dynChecker - - // These fields, once set by processOption, will not change. - exporters []exporter // List of exporters for structs with unexported fields - opts Options // List of all fundamental and filter options -} - -func newState(opts []Option) *state { - // Always ensure a validator option exists to validate the inputs. - s := &state{opts: Options{validator{}}} - s.curPtrs.Init() - s.processOption(Options(opts)) - return s -} - -func (s *state) processOption(opt Option) { - switch opt := opt.(type) { - case nil: - case Options: - for _, o := range opt { - s.processOption(o) - } - case coreOption: - type filtered interface { - isFiltered() bool - } - if fopt, ok := opt.(filtered); ok && !fopt.isFiltered() { - panic(fmt.Sprintf("cannot use an unfiltered option: %v", opt)) - } - s.opts = append(s.opts, opt) - case exporter: - s.exporters = append(s.exporters, opt) - case reporter: - s.reporters = append(s.reporters, opt) - default: - panic(fmt.Sprintf("unknown option %T", opt)) - } -} - -// statelessCompare compares two values and returns the result. -// This function is stateless in that it does not alter the current result, -// or output to any registered reporters. -func (s *state) statelessCompare(step PathStep) diff.Result { - // We do not save and restore curPath and curPtrs because all of the - // compareX methods should properly push and pop from them. - // It is an implementation bug if the contents of the paths differ from - // when calling this function to when returning from it. - - oldResult, oldReporters := s.result, s.reporters - s.result = diff.Result{} // Reset result - s.reporters = nil // Remove reporters to avoid spurious printouts - s.compareAny(step) - res := s.result - s.result, s.reporters = oldResult, oldReporters - return res -} - -func (s *state) compareAny(step PathStep) { - // Update the path stack. - s.curPath.push(step) - defer s.curPath.pop() - for _, r := range s.reporters { - r.PushStep(step) - defer r.PopStep() - } - s.recChecker.Check(s.curPath) - - // Cycle-detection for slice elements (see NOTE in compareSlice). - t := step.Type() - vx, vy := step.Values() - if si, ok := step.(SliceIndex); ok && si.isSlice && vx.IsValid() && vy.IsValid() { - px, py := vx.Addr(), vy.Addr() - if eq, visited := s.curPtrs.Push(px, py); visited { - s.report(eq, reportByCycle) - return - } - defer s.curPtrs.Pop(px, py) - } - - // Rule 1: Check whether an option applies on this node in the value tree. - if s.tryOptions(t, vx, vy) { - return - } - - // Rule 2: Check whether the type has a valid Equal method. - if s.tryMethod(t, vx, vy) { - return - } - - // Rule 3: Compare based on the underlying kind. - switch t.Kind() { - case reflect.Bool: - s.report(vx.Bool() == vy.Bool(), 0) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - s.report(vx.Int() == vy.Int(), 0) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - s.report(vx.Uint() == vy.Uint(), 0) - case reflect.Float32, reflect.Float64: - s.report(vx.Float() == vy.Float(), 0) - case reflect.Complex64, reflect.Complex128: - s.report(vx.Complex() == vy.Complex(), 0) - case reflect.String: - s.report(vx.String() == vy.String(), 0) - case reflect.Chan, reflect.UnsafePointer: - s.report(vx.Pointer() == vy.Pointer(), 0) - case reflect.Func: - s.report(vx.IsNil() && vy.IsNil(), 0) - case reflect.Struct: - s.compareStruct(t, vx, vy) - case reflect.Slice, reflect.Array: - s.compareSlice(t, vx, vy) - case reflect.Map: - s.compareMap(t, vx, vy) - case reflect.Ptr: - s.comparePtr(t, vx, vy) - case reflect.Interface: - s.compareInterface(t, vx, vy) - default: - panic(fmt.Sprintf("%v kind not handled", t.Kind())) - } -} - -func (s *state) tryOptions(t reflect.Type, vx, vy reflect.Value) bool { - // Evaluate all filters and apply the remaining options. - if opt := s.opts.filter(s, t, vx, vy); opt != nil { - opt.apply(s, vx, vy) - return true - } - return false -} - -func (s *state) tryMethod(t reflect.Type, vx, vy reflect.Value) bool { - // Check if this type even has an Equal method. - m, ok := t.MethodByName("Equal") - if !ok || !function.IsType(m.Type, function.EqualAssignable) { - return false - } - - eq := s.callTTBFunc(m.Func, vx, vy) - s.report(eq, reportByMethod) - return true -} - -func (s *state) callTRFunc(f, v reflect.Value, step Transform) reflect.Value { - if !s.dynChecker.Next() { - return f.Call([]reflect.Value{v})[0] - } - - // Run the function twice and ensure that we get the same results back. - // We run in goroutines so that the race detector (if enabled) can detect - // unsafe mutations to the input. - c := make(chan reflect.Value) - go detectRaces(c, f, v) - got := <-c - want := f.Call([]reflect.Value{v})[0] - if step.vx, step.vy = got, want; !s.statelessCompare(step).Equal() { - // To avoid false-positives with non-reflexive equality operations, - // we sanity check whether a value is equal to itself. - if step.vx, step.vy = want, want; !s.statelessCompare(step).Equal() { - return want - } - panic(fmt.Sprintf("non-deterministic function detected: %s", function.NameOf(f))) - } - return want -} - -func (s *state) callTTBFunc(f, x, y reflect.Value) bool { - if !s.dynChecker.Next() { - return f.Call([]reflect.Value{x, y})[0].Bool() - } - - // Swapping the input arguments is sufficient to check that - // f is symmetric and deterministic. - // We run in goroutines so that the race detector (if enabled) can detect - // unsafe mutations to the input. - c := make(chan reflect.Value) - go detectRaces(c, f, y, x) - got := <-c - want := f.Call([]reflect.Value{x, y})[0].Bool() - if !got.IsValid() || got.Bool() != want { - panic(fmt.Sprintf("non-deterministic or non-symmetric function detected: %s", function.NameOf(f))) - } - return want -} - -func detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) { - var ret reflect.Value - defer func() { - recover() // Ignore panics, let the other call to f panic instead - c <- ret - }() - ret = f.Call(vs)[0] -} - -func (s *state) compareStruct(t reflect.Type, vx, vy reflect.Value) { - var addr bool - var vax, vay reflect.Value // Addressable versions of vx and vy - - var mayForce, mayForceInit bool - step := StructField{&structField{}} - for i := 0; i < t.NumField(); i++ { - step.typ = t.Field(i).Type - step.vx = vx.Field(i) - step.vy = vy.Field(i) - step.name = t.Field(i).Name - step.idx = i - step.unexported = !isExported(step.name) - if step.unexported { - if step.name == "_" { - continue - } - // Defer checking of unexported fields until later to give an - // Ignore a chance to ignore the field. - if !vax.IsValid() || !vay.IsValid() { - // For retrieveUnexportedField to work, the parent struct must - // be addressable. Create a new copy of the values if - // necessary to make them addressable. - addr = vx.CanAddr() || vy.CanAddr() - vax = makeAddressable(vx) - vay = makeAddressable(vy) - } - if !mayForceInit { - for _, xf := range s.exporters { - mayForce = mayForce || xf(t) - } - mayForceInit = true - } - step.mayForce = mayForce - step.paddr = addr - step.pvx = vax - step.pvy = vay - step.field = t.Field(i) - } - s.compareAny(step) - } -} - -func (s *state) compareSlice(t reflect.Type, vx, vy reflect.Value) { - isSlice := t.Kind() == reflect.Slice - if isSlice && (vx.IsNil() || vy.IsNil()) { - s.report(vx.IsNil() && vy.IsNil(), 0) - return - } - - // NOTE: It is incorrect to call curPtrs.Push on the slice header pointer - // since slices represents a list of pointers, rather than a single pointer. - // The pointer checking logic must be handled on a per-element basis - // in compareAny. - // - // A slice header (see reflect.SliceHeader) in Go is a tuple of a starting - // pointer P, a length N, and a capacity C. Supposing each slice element has - // a memory size of M, then the slice is equivalent to the list of pointers: - // [P+i*M for i in range(N)] - // - // For example, v[:0] and v[:1] are slices with the same starting pointer, - // but they are clearly different values. Using the slice pointer alone - // violates the assumption that equal pointers implies equal values. - - step := SliceIndex{&sliceIndex{pathStep: pathStep{typ: t.Elem()}, isSlice: isSlice}} - withIndexes := func(ix, iy int) SliceIndex { - if ix >= 0 { - step.vx, step.xkey = vx.Index(ix), ix - } else { - step.vx, step.xkey = reflect.Value{}, -1 - } - if iy >= 0 { - step.vy, step.ykey = vy.Index(iy), iy - } else { - step.vy, step.ykey = reflect.Value{}, -1 - } - return step - } - - // Ignore options are able to ignore missing elements in a slice. - // However, detecting these reliably requires an optimal differencing - // algorithm, for which diff.Difference is not. - // - // Instead, we first iterate through both slices to detect which elements - // would be ignored if standing alone. The index of non-discarded elements - // are stored in a separate slice, which diffing is then performed on. - var indexesX, indexesY []int - var ignoredX, ignoredY []bool - for ix := 0; ix < vx.Len(); ix++ { - ignored := s.statelessCompare(withIndexes(ix, -1)).NumDiff == 0 - if !ignored { - indexesX = append(indexesX, ix) - } - ignoredX = append(ignoredX, ignored) - } - for iy := 0; iy < vy.Len(); iy++ { - ignored := s.statelessCompare(withIndexes(-1, iy)).NumDiff == 0 - if !ignored { - indexesY = append(indexesY, iy) - } - ignoredY = append(ignoredY, ignored) - } - - // Compute an edit-script for slices vx and vy (excluding ignored elements). - edits := diff.Difference(len(indexesX), len(indexesY), func(ix, iy int) diff.Result { - return s.statelessCompare(withIndexes(indexesX[ix], indexesY[iy])) - }) - - // Replay the ignore-scripts and the edit-script. - var ix, iy int - for ix < vx.Len() || iy < vy.Len() { - var e diff.EditType - switch { - case ix < len(ignoredX) && ignoredX[ix]: - e = diff.UniqueX - case iy < len(ignoredY) && ignoredY[iy]: - e = diff.UniqueY - default: - e, edits = edits[0], edits[1:] - } - switch e { - case diff.UniqueX: - s.compareAny(withIndexes(ix, -1)) - ix++ - case diff.UniqueY: - s.compareAny(withIndexes(-1, iy)) - iy++ - default: - s.compareAny(withIndexes(ix, iy)) - ix++ - iy++ - } - } -} - -func (s *state) compareMap(t reflect.Type, vx, vy reflect.Value) { - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), 0) - return - } - - // Cycle-detection for maps. - if eq, visited := s.curPtrs.Push(vx, vy); visited { - s.report(eq, reportByCycle) - return - } - defer s.curPtrs.Pop(vx, vy) - - // We combine and sort the two map keys so that we can perform the - // comparisons in a deterministic order. - step := MapIndex{&mapIndex{pathStep: pathStep{typ: t.Elem()}}} - for _, k := range value.SortKeys(append(vx.MapKeys(), vy.MapKeys()...)) { - step.vx = vx.MapIndex(k) - step.vy = vy.MapIndex(k) - step.key = k - if !step.vx.IsValid() && !step.vy.IsValid() { - // It is possible for both vx and vy to be invalid if the - // key contained a NaN value in it. - // - // Even with the ability to retrieve NaN keys in Go 1.12, - // there still isn't a sensible way to compare the values since - // a NaN key may map to multiple unordered values. - // The most reasonable way to compare NaNs would be to compare the - // set of values. However, this is impossible to do efficiently - // since set equality is provably an O(n^2) operation given only - // an Equal function. If we had a Less function or Hash function, - // this could be done in O(n*log(n)) or O(n), respectively. - // - // Rather than adding complex logic to deal with NaNs, make it - // the user's responsibility to compare such obscure maps. - const help = "consider providing a Comparer to compare the map" - panic(fmt.Sprintf("%#v has map key with NaNs\n%s", s.curPath, help)) - } - s.compareAny(step) - } -} - -func (s *state) comparePtr(t reflect.Type, vx, vy reflect.Value) { - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), 0) - return - } - - // Cycle-detection for pointers. - if eq, visited := s.curPtrs.Push(vx, vy); visited { - s.report(eq, reportByCycle) - return - } - defer s.curPtrs.Pop(vx, vy) - - vx, vy = vx.Elem(), vy.Elem() - s.compareAny(Indirect{&indirect{pathStep{t.Elem(), vx, vy}}}) -} - -func (s *state) compareInterface(t reflect.Type, vx, vy reflect.Value) { - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), 0) - return - } - vx, vy = vx.Elem(), vy.Elem() - if vx.Type() != vy.Type() { - s.report(false, 0) - return - } - s.compareAny(TypeAssertion{&typeAssertion{pathStep{vx.Type(), vx, vy}}}) -} - -func (s *state) report(eq bool, rf resultFlags) { - if rf&reportByIgnore == 0 { - if eq { - s.result.NumSame++ - rf |= reportEqual - } else { - s.result.NumDiff++ - rf |= reportUnequal - } - } - for _, r := range s.reporters { - r.Report(Result{flags: rf}) - } -} - -// recChecker tracks the state needed to periodically perform checks that -// user provided transformers are not stuck in an infinitely recursive cycle. -type recChecker struct{ next int } - -// Check scans the Path for any recursive transformers and panics when any -// recursive transformers are detected. Note that the presence of a -// recursive Transformer does not necessarily imply an infinite cycle. -// As such, this check only activates after some minimal number of path steps. -func (rc *recChecker) Check(p Path) { - const minLen = 1 << 16 - if rc.next == 0 { - rc.next = minLen - } - if len(p) < rc.next { - return - } - rc.next <<= 1 - - // Check whether the same transformer has appeared at least twice. - var ss []string - m := map[Option]int{} - for _, ps := range p { - if t, ok := ps.(Transform); ok { - t := t.Option() - if m[t] == 1 { // Transformer was used exactly once before - tf := t.(*transformer).fnc.Type() - ss = append(ss, fmt.Sprintf("%v: %v => %v", t, tf.In(0), tf.Out(0))) - } - m[t]++ - } - } - if len(ss) > 0 { - const warning = "recursive set of Transformers detected" - const help = "consider using cmpopts.AcyclicTransformer" - set := strings.Join(ss, "\n\t") - panic(fmt.Sprintf("%s:\n\t%s\n%s", warning, set, help)) - } -} - -// dynChecker tracks the state needed to periodically perform checks that -// user provided functions are symmetric and deterministic. -// The zero value is safe for immediate use. -type dynChecker struct{ curr, next int } - -// Next increments the state and reports whether a check should be performed. -// -// Checks occur every Nth function call, where N is a triangular number: -// -// 0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ... -// -// See https://en.wikipedia.org/wiki/Triangular_number -// -// This sequence ensures that the cost of checks drops significantly as -// the number of functions calls grows larger. -func (dc *dynChecker) Next() bool { - ok := dc.curr == dc.next - if ok { - dc.curr = 0 - dc.next++ - } - dc.curr++ - return ok -} - -// makeAddressable returns a value that is always addressable. -// It returns the input verbatim if it is already addressable, -// otherwise it creates a new value and returns an addressable copy. -func makeAddressable(v reflect.Value) reflect.Value { - if v.CanAddr() { - return v - } - vc := reflect.New(v.Type()).Elem() - vc.Set(v) - return vc -} diff --git a/vendor/github.com/google/go-cmp/cmp/export.go b/vendor/github.com/google/go-cmp/cmp/export.go deleted file mode 100644 index 29f82fe6b..000000000 --- a/vendor/github.com/google/go-cmp/cmp/export.go +++ /dev/null @@ -1,31 +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 cmp - -import ( - "reflect" - "unsafe" -) - -// retrieveUnexportedField uses unsafe to forcibly retrieve any field from -// a struct such that the value has read-write permissions. -// -// The parent struct, v, must be addressable, while f must be a StructField -// describing the field to retrieve. If addr is false, -// then the returned value will be shallowed copied to be non-addressable. -func retrieveUnexportedField(v reflect.Value, f reflect.StructField, addr bool) reflect.Value { - ve := reflect.NewAt(f.Type, unsafe.Pointer(uintptr(unsafe.Pointer(v.UnsafeAddr()))+f.Offset)).Elem() - if !addr { - // A field is addressable if and only if the struct is addressable. - // If the original parent value was not addressable, shallow copy the - // value to make it non-addressable to avoid leaking an implementation - // detail of how forcibly exporting a field works. - if ve.Kind() == reflect.Interface && ve.IsNil() { - return reflect.Zero(f.Type) - } - return reflect.ValueOf(ve.Interface()).Convert(f.Type) - } - return ve -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go deleted file mode 100644 index 36062a604..000000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go +++ /dev/null @@ -1,18 +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. - -//go:build !cmp_debug -// +build !cmp_debug - -package diff - -var debug debugger - -type debugger struct{} - -func (debugger) Begin(_, _ int, f EqualFunc, _, _ *EditScript) EqualFunc { - return f -} -func (debugger) Update() {} -func (debugger) Finish() {} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go deleted file mode 100644 index a3b97a1ad..000000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go +++ /dev/null @@ -1,123 +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. - -//go:build cmp_debug -// +build cmp_debug - -package diff - -import ( - "fmt" - "strings" - "sync" - "time" -) - -// The algorithm can be seen running in real-time by enabling debugging: -// go test -tags=cmp_debug -v -// -// Example output: -// === RUN TestDifference/#34 -// ┌───────────────────────────────┐ -// │ \ · · · · · · · · · · · · · · │ -// │ · # · · · · · · · · · · · · · │ -// │ · \ · · · · · · · · · · · · · │ -// │ · · \ · · · · · · · · · · · · │ -// │ · · · X # · · · · · · · · · · │ -// │ · · · # \ · · · · · · · · · · │ -// │ · · · · · # # · · · · · · · · │ -// │ · · · · · # \ · · · · · · · · │ -// │ · · · · · · · \ · · · · · · · │ -// │ · · · · · · · · \ · · · · · · │ -// │ · · · · · · · · · \ · · · · · │ -// │ · · · · · · · · · · \ · · # · │ -// │ · · · · · · · · · · · \ # # · │ -// │ · · · · · · · · · · · # # # · │ -// │ · · · · · · · · · · # # # # · │ -// │ · · · · · · · · · # # # # # · │ -// │ · · · · · · · · · · · · · · \ │ -// └───────────────────────────────┘ -// [.Y..M.XY......YXYXY.|] -// -// The grid represents the edit-graph where the horizontal axis represents -// list X and the vertical axis represents list Y. The start of the two lists -// is the top-left, while the ends are the bottom-right. The '·' represents -// an unexplored node in the graph. The '\' indicates that the two symbols -// from list X and Y are equal. The 'X' indicates that two symbols are similar -// (but not exactly equal) to each other. The '#' indicates that the two symbols -// are different (and not similar). The algorithm traverses this graph trying to -// make the paths starting in the top-left and the bottom-right connect. -// -// The series of '.', 'X', 'Y', and 'M' characters at the bottom represents -// the currently established path from the forward and reverse searches, -// separated by a '|' character. - -const ( - updateDelay = 100 * time.Millisecond - finishDelay = 500 * time.Millisecond - ansiTerminal = true // ANSI escape codes used to move terminal cursor -) - -var debug debugger - -type debugger struct { - sync.Mutex - p1, p2 EditScript - fwdPath, revPath *EditScript - grid []byte - lines int -} - -func (dbg *debugger) Begin(nx, ny int, f EqualFunc, p1, p2 *EditScript) EqualFunc { - dbg.Lock() - dbg.fwdPath, dbg.revPath = p1, p2 - top := "┌─" + strings.Repeat("──", nx) + "┐\n" - row := "│ " + strings.Repeat("· ", nx) + "│\n" - btm := "└─" + strings.Repeat("──", nx) + "┘\n" - dbg.grid = []byte(top + strings.Repeat(row, ny) + btm) - dbg.lines = strings.Count(dbg.String(), "\n") - fmt.Print(dbg) - - // Wrap the EqualFunc so that we can intercept each result. - return func(ix, iy int) (r Result) { - cell := dbg.grid[len(top)+iy*len(row):][len("│ ")+len("· ")*ix:][:len("·")] - for i := range cell { - cell[i] = 0 // Zero out the multiple bytes of UTF-8 middle-dot - } - switch r = f(ix, iy); { - case r.Equal(): - cell[0] = '\\' - case r.Similar(): - cell[0] = 'X' - default: - cell[0] = '#' - } - return - } -} - -func (dbg *debugger) Update() { - dbg.print(updateDelay) -} - -func (dbg *debugger) Finish() { - dbg.print(finishDelay) - dbg.Unlock() -} - -func (dbg *debugger) String() string { - dbg.p1, dbg.p2 = *dbg.fwdPath, dbg.p2[:0] - for i := len(*dbg.revPath) - 1; i >= 0; i-- { - dbg.p2 = append(dbg.p2, (*dbg.revPath)[i]) - } - return fmt.Sprintf("%s[%v|%v]\n\n", dbg.grid, dbg.p1, dbg.p2) -} - -func (dbg *debugger) print(d time.Duration) { - if ansiTerminal { - fmt.Printf("\x1b[%dA", dbg.lines) // Reset terminal cursor - } - fmt.Print(dbg) - time.Sleep(d) -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go deleted file mode 100644 index a248e5436..000000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go +++ /dev/null @@ -1,402 +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 diff implements an algorithm for producing edit-scripts. -// The edit-script is a sequence of operations needed to transform one list -// of symbols into another (or vice-versa). The edits allowed are insertions, -// deletions, and modifications. The summation of all edits is called the -// Levenshtein distance as this problem is well-known in computer science. -// -// This package prioritizes performance over accuracy. That is, the run time -// is more important than obtaining a minimal Levenshtein distance. -package diff - -import ( - "math/rand" - "time" - - "github.com/google/go-cmp/cmp/internal/flags" -) - -// EditType represents a single operation within an edit-script. -type EditType uint8 - -const ( - // Identity indicates that a symbol pair is identical in both list X and Y. - Identity EditType = iota - // UniqueX indicates that a symbol only exists in X and not Y. - UniqueX - // UniqueY indicates that a symbol only exists in Y and not X. - UniqueY - // Modified indicates that a symbol pair is a modification of each other. - Modified -) - -// EditScript represents the series of differences between two lists. -type EditScript []EditType - -// String returns a human-readable string representing the edit-script where -// Identity, UniqueX, UniqueY, and Modified are represented by the -// '.', 'X', 'Y', and 'M' characters, respectively. -func (es EditScript) String() string { - b := make([]byte, len(es)) - for i, e := range es { - switch e { - case Identity: - b[i] = '.' - case UniqueX: - b[i] = 'X' - case UniqueY: - b[i] = 'Y' - case Modified: - b[i] = 'M' - default: - panic("invalid edit-type") - } - } - return string(b) -} - -// stats returns a histogram of the number of each type of edit operation. -func (es EditScript) stats() (s struct{ NI, NX, NY, NM int }) { - for _, e := range es { - switch e { - case Identity: - s.NI++ - case UniqueX: - s.NX++ - case UniqueY: - s.NY++ - case Modified: - s.NM++ - default: - panic("invalid edit-type") - } - } - return -} - -// Dist is the Levenshtein distance and is guaranteed to be 0 if and only if -// lists X and Y are equal. -func (es EditScript) Dist() int { return len(es) - es.stats().NI } - -// LenX is the length of the X list. -func (es EditScript) LenX() int { return len(es) - es.stats().NY } - -// LenY is the length of the Y list. -func (es EditScript) LenY() int { return len(es) - es.stats().NX } - -// EqualFunc reports whether the symbols at indexes ix and iy are equal. -// When called by Difference, the index is guaranteed to be within nx and ny. -type EqualFunc func(ix int, iy int) Result - -// Result is the result of comparison. -// NumSame is the number of sub-elements that are equal. -// NumDiff is the number of sub-elements that are not equal. -type Result struct{ NumSame, NumDiff int } - -// BoolResult returns a Result that is either Equal or not Equal. -func BoolResult(b bool) Result { - if b { - return Result{NumSame: 1} // Equal, Similar - } else { - return Result{NumDiff: 2} // Not Equal, not Similar - } -} - -// Equal indicates whether the symbols are equal. Two symbols are equal -// if and only if NumDiff == 0. If Equal, then they are also Similar. -func (r Result) Equal() bool { return r.NumDiff == 0 } - -// Similar indicates whether two symbols are similar and may be represented -// by using the Modified type. As a special case, we consider binary comparisons -// (i.e., those that return Result{1, 0} or Result{0, 1}) to be similar. -// -// The exact ratio of NumSame to NumDiff to determine similarity may change. -func (r Result) Similar() bool { - // Use NumSame+1 to offset NumSame so that binary comparisons are similar. - return r.NumSame+1 >= r.NumDiff -} - -var randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0 - -// Difference reports whether two lists of lengths nx and ny are equal -// given the definition of equality provided as f. -// -// This function returns an edit-script, which is a sequence of operations -// needed to convert one list into the other. The following invariants for -// the edit-script are maintained: -// - eq == (es.Dist()==0) -// - nx == es.LenX() -// - ny == es.LenY() -// -// This algorithm is not guaranteed to be an optimal solution (i.e., one that -// produces an edit-script with a minimal Levenshtein distance). This algorithm -// favors performance over optimality. The exact output is not guaranteed to -// be stable and may change over time. -func Difference(nx, ny int, f EqualFunc) (es EditScript) { - // This algorithm is based on traversing what is known as an "edit-graph". - // See Figure 1 from "An O(ND) Difference Algorithm and Its Variations" - // by Eugene W. Myers. Since D can be as large as N itself, this is - // effectively O(N^2). Unlike the algorithm from that paper, we are not - // interested in the optimal path, but at least some "decent" path. - // - // For example, let X and Y be lists of symbols: - // X = [A B C A B B A] - // Y = [C B A B A C] - // - // The edit-graph can be drawn as the following: - // A B C A B B A - // ┌─────────────┐ - // C │_|_|\|_|_|_|_│ 0 - // B │_|\|_|_|\|\|_│ 1 - // A │\|_|_|\|_|_|\│ 2 - // B │_|\|_|_|\|\|_│ 3 - // A │\|_|_|\|_|_|\│ 4 - // C │ | |\| | | | │ 5 - // └─────────────┘ 6 - // 0 1 2 3 4 5 6 7 - // - // List X is written along the horizontal axis, while list Y is written - // along the vertical axis. At any point on this grid, if the symbol in - // list X matches the corresponding symbol in list Y, then a '\' is drawn. - // The goal of any minimal edit-script algorithm is to find a path from the - // top-left corner to the bottom-right corner, while traveling through the - // fewest horizontal or vertical edges. - // A horizontal edge is equivalent to inserting a symbol from list X. - // A vertical edge is equivalent to inserting a symbol from list Y. - // A diagonal edge is equivalent to a matching symbol between both X and Y. - - // Invariants: - // - 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx - // - 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny - // - // In general: - // - fwdFrontier.X < revFrontier.X - // - fwdFrontier.Y < revFrontier.Y - // - // Unless, it is time for the algorithm to terminate. - fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)} - revPath := path{-1, point{nx, ny}, make(EditScript, 0)} - fwdFrontier := fwdPath.point // Forward search frontier - revFrontier := revPath.point // Reverse search frontier - - // Search budget bounds the cost of searching for better paths. - // The longest sequence of non-matching symbols that can be tolerated is - // approximately the square-root of the search budget. - searchBudget := 4 * (nx + ny) // O(n) - - // Running the tests with the "cmp_debug" build tag prints a visualization - // of the algorithm running in real-time. This is educational for - // understanding how the algorithm works. See debug_enable.go. - f = debug.Begin(nx, ny, f, &fwdPath.es, &revPath.es) - - // The algorithm below is a greedy, meet-in-the-middle algorithm for - // computing sub-optimal edit-scripts between two lists. - // - // The algorithm is approximately as follows: - // - Searching for differences switches back-and-forth between - // a search that starts at the beginning (the top-left corner), and - // a search that starts at the end (the bottom-right corner). - // The goal of the search is connect with the search - // from the opposite corner. - // - As we search, we build a path in a greedy manner, - // where the first match seen is added to the path (this is sub-optimal, - // but provides a decent result in practice). When matches are found, - // we try the next pair of symbols in the lists and follow all matches - // as far as possible. - // - When searching for matches, we search along a diagonal going through - // through the "frontier" point. If no matches are found, - // we advance the frontier towards the opposite corner. - // - This algorithm terminates when either the X coordinates or the - // Y coordinates of the forward and reverse frontier points ever intersect. - - // This algorithm is correct even if searching only in the forward direction - // or in the reverse direction. We do both because it is commonly observed - // that two lists commonly differ because elements were added to the front - // or end of the other list. - // - // Non-deterministically start with either the forward or reverse direction - // to introduce some deliberate instability so that we have the flexibility - // to change this algorithm in the future. - if flags.Deterministic || randBool { - goto forwardSearch - } else { - goto reverseSearch - } - -forwardSearch: - { - // Forward search from the beginning. - if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 { - goto finishSearch - } - for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ { - // Search in a diagonal pattern for a match. - z := zigzag(i) - p := point{fwdFrontier.X + z, fwdFrontier.Y - z} - switch { - case p.X >= revPath.X || p.Y < fwdPath.Y: - stop1 = true // Hit top-right corner - case p.Y >= revPath.Y || p.X < fwdPath.X: - stop2 = true // Hit bottom-left corner - case f(p.X, p.Y).Equal(): - // Match found, so connect the path to this point. - fwdPath.connect(p, f) - fwdPath.append(Identity) - // Follow sequence of matches as far as possible. - for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y { - if !f(fwdPath.X, fwdPath.Y).Equal() { - break - } - fwdPath.append(Identity) - } - fwdFrontier = fwdPath.point - stop1, stop2 = true, true - default: - searchBudget-- // Match not found - } - debug.Update() - } - // Advance the frontier towards reverse point. - if revPath.X-fwdFrontier.X >= revPath.Y-fwdFrontier.Y { - fwdFrontier.X++ - } else { - fwdFrontier.Y++ - } - goto reverseSearch - } - -reverseSearch: - { - // Reverse search from the end. - if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 { - goto finishSearch - } - for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ { - // Search in a diagonal pattern for a match. - z := zigzag(i) - p := point{revFrontier.X - z, revFrontier.Y + z} - switch { - case fwdPath.X >= p.X || revPath.Y < p.Y: - stop1 = true // Hit bottom-left corner - case fwdPath.Y >= p.Y || revPath.X < p.X: - stop2 = true // Hit top-right corner - case f(p.X-1, p.Y-1).Equal(): - // Match found, so connect the path to this point. - revPath.connect(p, f) - revPath.append(Identity) - // Follow sequence of matches as far as possible. - for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y { - if !f(revPath.X-1, revPath.Y-1).Equal() { - break - } - revPath.append(Identity) - } - revFrontier = revPath.point - stop1, stop2 = true, true - default: - searchBudget-- // Match not found - } - debug.Update() - } - // Advance the frontier towards forward point. - if revFrontier.X-fwdPath.X >= revFrontier.Y-fwdPath.Y { - revFrontier.X-- - } else { - revFrontier.Y-- - } - goto forwardSearch - } - -finishSearch: - // Join the forward and reverse paths and then append the reverse path. - fwdPath.connect(revPath.point, f) - for i := len(revPath.es) - 1; i >= 0; i-- { - t := revPath.es[i] - revPath.es = revPath.es[:i] - fwdPath.append(t) - } - debug.Finish() - return fwdPath.es -} - -type path struct { - dir int // +1 if forward, -1 if reverse - point // Leading point of the EditScript path - es EditScript -} - -// connect appends any necessary Identity, Modified, UniqueX, or UniqueY types -// to the edit-script to connect p.point to dst. -func (p *path) connect(dst point, f EqualFunc) { - if p.dir > 0 { - // Connect in forward direction. - for dst.X > p.X && dst.Y > p.Y { - switch r := f(p.X, p.Y); { - case r.Equal(): - p.append(Identity) - case r.Similar(): - p.append(Modified) - case dst.X-p.X >= dst.Y-p.Y: - p.append(UniqueX) - default: - p.append(UniqueY) - } - } - for dst.X > p.X { - p.append(UniqueX) - } - for dst.Y > p.Y { - p.append(UniqueY) - } - } else { - // Connect in reverse direction. - for p.X > dst.X && p.Y > dst.Y { - switch r := f(p.X-1, p.Y-1); { - case r.Equal(): - p.append(Identity) - case r.Similar(): - p.append(Modified) - case p.Y-dst.Y >= p.X-dst.X: - p.append(UniqueY) - default: - p.append(UniqueX) - } - } - for p.X > dst.X { - p.append(UniqueX) - } - for p.Y > dst.Y { - p.append(UniqueY) - } - } -} - -func (p *path) append(t EditType) { - p.es = append(p.es, t) - switch t { - case Identity, Modified: - p.add(p.dir, p.dir) - case UniqueX: - p.add(p.dir, 0) - case UniqueY: - p.add(0, p.dir) - } - debug.Update() -} - -type point struct{ X, Y int } - -func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy } - -// zigzag maps a consecutive sequence of integers to a zig-zag sequence. -// -// [0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...] -func zigzag(x int) int { - if x&1 != 0 { - x = ^x - } - return x >> 1 -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go b/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go deleted file mode 100644 index d8e459c9b..000000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go +++ /dev/null @@ -1,9 +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 flags - -// Deterministic controls whether the output of Diff should be deterministic. -// This is only used for testing. -var Deterministic bool diff --git a/vendor/github.com/google/go-cmp/cmp/internal/function/func.go b/vendor/github.com/google/go-cmp/cmp/internal/function/func.go deleted file mode 100644 index d127d4362..000000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/function/func.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 function provides functionality for identifying function types. -package function - -import ( - "reflect" - "regexp" - "runtime" - "strings" -) - -type funcType int - -const ( - _ funcType = iota - - tbFunc // func(T) bool - ttbFunc // func(T, T) bool - trbFunc // func(T, R) bool - tibFunc // func(T, I) bool - trFunc // func(T) R - - Equal = ttbFunc // func(T, T) bool - EqualAssignable = tibFunc // func(T, I) bool; encapsulates func(T, T) bool - Transformer = trFunc // func(T) R - ValueFilter = ttbFunc // func(T, T) bool - Less = ttbFunc // func(T, T) bool - ValuePredicate = tbFunc // func(T) bool - KeyValuePredicate = trbFunc // func(T, R) bool -) - -var boolType = reflect.TypeOf(true) - -// IsType reports whether the reflect.Type is of the specified function type. -func IsType(t reflect.Type, ft funcType) bool { - if t == nil || t.Kind() != reflect.Func || t.IsVariadic() { - return false - } - ni, no := t.NumIn(), t.NumOut() - switch ft { - case tbFunc: // func(T) bool - if ni == 1 && no == 1 && t.Out(0) == boolType { - return true - } - case ttbFunc: // func(T, T) bool - if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType { - return true - } - case trbFunc: // func(T, R) bool - if ni == 2 && no == 1 && t.Out(0) == boolType { - return true - } - case tibFunc: // func(T, I) bool - if ni == 2 && no == 1 && t.In(0).AssignableTo(t.In(1)) && t.Out(0) == boolType { - return true - } - case trFunc: // func(T) R - if ni == 1 && no == 1 { - return true - } - } - return false -} - -var lastIdentRx = regexp.MustCompile(`[_\p{L}][_\p{L}\p{N}]*$`) - -// NameOf returns the name of the function value. -func NameOf(v reflect.Value) string { - fnc := runtime.FuncForPC(v.Pointer()) - if fnc == nil { - return "" - } - fullName := fnc.Name() // e.g., "long/path/name/mypkg.(*MyType).(long/path/name/mypkg.myMethod)-fm" - - // Method closures have a "-fm" suffix. - fullName = strings.TrimSuffix(fullName, "-fm") - - var name string - for len(fullName) > 0 { - inParen := strings.HasSuffix(fullName, ")") - fullName = strings.TrimSuffix(fullName, ")") - - s := lastIdentRx.FindString(fullName) - if s == "" { - break - } - name = s + "." + name - fullName = strings.TrimSuffix(fullName, s) - - if i := strings.LastIndexByte(fullName, '('); inParen && i >= 0 { - fullName = fullName[:i] - } - fullName = strings.TrimSuffix(fullName, ".") - } - return strings.TrimSuffix(name, ".") -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/name.go b/vendor/github.com/google/go-cmp/cmp/internal/value/name.go deleted file mode 100644 index 7b498bb2c..000000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/name.go +++ /dev/null @@ -1,164 +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 value - -import ( - "reflect" - "strconv" -) - -var anyType = reflect.TypeOf((*interface{})(nil)).Elem() - -// TypeString is nearly identical to reflect.Type.String, -// but has an additional option to specify that full type names be used. -func TypeString(t reflect.Type, qualified bool) string { - return string(appendTypeName(nil, t, qualified, false)) -} - -func appendTypeName(b []byte, t reflect.Type, qualified, elideFunc bool) []byte { - // BUG: Go reflection provides no way to disambiguate two named types - // of the same name and within the same package, - // but declared within the namespace of different functions. - - // Use the "any" alias instead of "interface{}" for better readability. - if t == anyType { - return append(b, "any"...) - } - - // Named type. - if t.Name() != "" { - if qualified && t.PkgPath() != "" { - b = append(b, '"') - b = append(b, t.PkgPath()...) - b = append(b, '"') - b = append(b, '.') - b = append(b, t.Name()...) - } else { - b = append(b, t.String()...) - } - return b - } - - // Unnamed type. - switch k := t.Kind(); k { - case reflect.Bool, reflect.String, reflect.UnsafePointer, - reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, - reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: - b = append(b, k.String()...) - case reflect.Chan: - if t.ChanDir() == reflect.RecvDir { - b = append(b, "<-"...) - } - b = append(b, "chan"...) - if t.ChanDir() == reflect.SendDir { - b = append(b, "<-"...) - } - b = append(b, ' ') - b = appendTypeName(b, t.Elem(), qualified, false) - case reflect.Func: - if !elideFunc { - b = append(b, "func"...) - } - b = append(b, '(') - for i := 0; i < t.NumIn(); i++ { - if i > 0 { - b = append(b, ", "...) - } - if i == t.NumIn()-1 && t.IsVariadic() { - b = append(b, "..."...) - b = appendTypeName(b, t.In(i).Elem(), qualified, false) - } else { - b = appendTypeName(b, t.In(i), qualified, false) - } - } - b = append(b, ')') - switch t.NumOut() { - case 0: - // Do nothing - case 1: - b = append(b, ' ') - b = appendTypeName(b, t.Out(0), qualified, false) - default: - b = append(b, " ("...) - for i := 0; i < t.NumOut(); i++ { - if i > 0 { - b = append(b, ", "...) - } - b = appendTypeName(b, t.Out(i), qualified, false) - } - b = append(b, ')') - } - case reflect.Struct: - b = append(b, "struct{ "...) - for i := 0; i < t.NumField(); i++ { - if i > 0 { - b = append(b, "; "...) - } - sf := t.Field(i) - if !sf.Anonymous { - if qualified && sf.PkgPath != "" { - b = append(b, '"') - b = append(b, sf.PkgPath...) - b = append(b, '"') - b = append(b, '.') - } - b = append(b, sf.Name...) - b = append(b, ' ') - } - b = appendTypeName(b, sf.Type, qualified, false) - if sf.Tag != "" { - b = append(b, ' ') - b = strconv.AppendQuote(b, string(sf.Tag)) - } - } - if b[len(b)-1] == ' ' { - b = b[:len(b)-1] - } else { - b = append(b, ' ') - } - b = append(b, '}') - case reflect.Slice, reflect.Array: - b = append(b, '[') - if k == reflect.Array { - b = strconv.AppendUint(b, uint64(t.Len()), 10) - } - b = append(b, ']') - b = appendTypeName(b, t.Elem(), qualified, false) - case reflect.Map: - b = append(b, "map["...) - b = appendTypeName(b, t.Key(), qualified, false) - b = append(b, ']') - b = appendTypeName(b, t.Elem(), qualified, false) - case reflect.Ptr: - b = append(b, '*') - b = appendTypeName(b, t.Elem(), qualified, false) - case reflect.Interface: - b = append(b, "interface{ "...) - for i := 0; i < t.NumMethod(); i++ { - if i > 0 { - b = append(b, "; "...) - } - m := t.Method(i) - if qualified && m.PkgPath != "" { - b = append(b, '"') - b = append(b, m.PkgPath...) - b = append(b, '"') - b = append(b, '.') - } - b = append(b, m.Name...) - b = appendTypeName(b, m.Type, qualified, true) - } - if b[len(b)-1] == ' ' { - b = b[:len(b)-1] - } else { - b = append(b, ' ') - } - b = append(b, '}') - default: - panic("invalid kind: " + k.String()) - } - return b -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer.go deleted file mode 100644 index e5dfff69a..000000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer.go +++ /dev/null @@ -1,34 +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 value - -import ( - "reflect" - "unsafe" -) - -// Pointer is an opaque typed pointer and is guaranteed to be comparable. -type Pointer struct { - p unsafe.Pointer - t reflect.Type -} - -// PointerOf returns a Pointer from v, which must be a -// reflect.Ptr, reflect.Slice, or reflect.Map. -func PointerOf(v reflect.Value) Pointer { - // The proper representation of a pointer is unsafe.Pointer, - // which is necessary if the GC ever uses a moving collector. - return Pointer{unsafe.Pointer(v.Pointer()), v.Type()} -} - -// IsNil reports whether the pointer is nil. -func (p Pointer) IsNil() bool { - return p.p == nil -} - -// Uintptr returns the pointer as a uintptr. -func (p Pointer) Uintptr() uintptr { - return uintptr(p.p) -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go b/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go deleted file mode 100644 index 98533b036..000000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go +++ /dev/null @@ -1,106 +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 value - -import ( - "fmt" - "math" - "reflect" - "sort" -) - -// SortKeys sorts a list of map keys, deduplicating keys if necessary. -// The type of each value must be comparable. -func SortKeys(vs []reflect.Value) []reflect.Value { - if len(vs) == 0 { - return vs - } - - // Sort the map keys. - sort.SliceStable(vs, func(i, j int) bool { return isLess(vs[i], vs[j]) }) - - // Deduplicate keys (fails for NaNs). - vs2 := vs[:1] - for _, v := range vs[1:] { - if isLess(vs2[len(vs2)-1], v) { - vs2 = append(vs2, v) - } - } - return vs2 -} - -// isLess is a generic function for sorting arbitrary map keys. -// The inputs must be of the same type and must be comparable. -func isLess(x, y reflect.Value) bool { - switch x.Type().Kind() { - case reflect.Bool: - return !x.Bool() && y.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return x.Int() < y.Int() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return x.Uint() < y.Uint() - case reflect.Float32, reflect.Float64: - // NOTE: This does not sort -0 as less than +0 - // since Go maps treat -0 and +0 as equal keys. - fx, fy := x.Float(), y.Float() - return fx < fy || math.IsNaN(fx) && !math.IsNaN(fy) - case reflect.Complex64, reflect.Complex128: - cx, cy := x.Complex(), y.Complex() - rx, ix, ry, iy := real(cx), imag(cx), real(cy), imag(cy) - if rx == ry || (math.IsNaN(rx) && math.IsNaN(ry)) { - return ix < iy || math.IsNaN(ix) && !math.IsNaN(iy) - } - return rx < ry || math.IsNaN(rx) && !math.IsNaN(ry) - case reflect.Ptr, reflect.UnsafePointer, reflect.Chan: - return x.Pointer() < y.Pointer() - case reflect.String: - return x.String() < y.String() - case reflect.Array: - for i := 0; i < x.Len(); i++ { - if isLess(x.Index(i), y.Index(i)) { - return true - } - if isLess(y.Index(i), x.Index(i)) { - return false - } - } - return false - case reflect.Struct: - for i := 0; i < x.NumField(); i++ { - if isLess(x.Field(i), y.Field(i)) { - return true - } - if isLess(y.Field(i), x.Field(i)) { - return false - } - } - return false - case reflect.Interface: - vx, vy := x.Elem(), y.Elem() - if !vx.IsValid() || !vy.IsValid() { - return !vx.IsValid() && vy.IsValid() - } - tx, ty := vx.Type(), vy.Type() - if tx == ty { - return isLess(x.Elem(), y.Elem()) - } - if tx.Kind() != ty.Kind() { - return vx.Kind() < vy.Kind() - } - if tx.String() != ty.String() { - return tx.String() < ty.String() - } - if tx.PkgPath() != ty.PkgPath() { - return tx.PkgPath() < ty.PkgPath() - } - // This can happen in rare situations, so we fallback to just comparing - // the unique pointer for a reflect.Type. This guarantees deterministic - // ordering within a program, but it is obviously not stable. - return reflect.ValueOf(vx.Type()).Pointer() < reflect.ValueOf(vy.Type()).Pointer() - default: - // Must be Func, Map, or Slice; which are not comparable. - panic(fmt.Sprintf("%T is not comparable", x.Type())) - } -} diff --git a/vendor/github.com/google/go-cmp/cmp/options.go b/vendor/github.com/google/go-cmp/cmp/options.go deleted file mode 100644 index 754496f3b..000000000 --- a/vendor/github.com/google/go-cmp/cmp/options.go +++ /dev/null @@ -1,554 +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 cmp - -import ( - "fmt" - "reflect" - "regexp" - "strings" - - "github.com/google/go-cmp/cmp/internal/function" -) - -// Option configures for specific behavior of [Equal] and [Diff]. In particular, -// the fundamental Option functions ([Ignore], [Transformer], and [Comparer]), -// configure how equality is determined. -// -// The fundamental options may be composed with filters ([FilterPath] and -// [FilterValues]) to control the scope over which they are applied. -// -// The [github.com/google/go-cmp/cmp/cmpopts] package provides helper functions -// for creating options that may be used with [Equal] and [Diff]. -type Option interface { - // filter applies all filters and returns the option that remains. - // Each option may only read s.curPath and call s.callTTBFunc. - // - // An Options is returned only if multiple comparers or transformers - // can apply simultaneously and will only contain values of those types - // or sub-Options containing values of those types. - filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption -} - -// applicableOption represents the following types: -// -// Fundamental: ignore | validator | *comparer | *transformer -// Grouping: Options -type applicableOption interface { - Option - - // apply executes the option, which may mutate s or panic. - apply(s *state, vx, vy reflect.Value) -} - -// coreOption represents the following types: -// -// Fundamental: ignore | validator | *comparer | *transformer -// Filters: *pathFilter | *valuesFilter -type coreOption interface { - Option - isCore() -} - -type core struct{} - -func (core) isCore() {} - -// Options is a list of [Option] values that also satisfies the [Option] interface. -// Helper comparison packages may return an Options value when packing multiple -// [Option] values into a single [Option]. When this package processes an Options, -// it will be implicitly expanded into a flat list. -// -// Applying a filter on an Options is equivalent to applying that same filter -// on all individual options held within. -type Options []Option - -func (opts Options) filter(s *state, t reflect.Type, vx, vy reflect.Value) (out applicableOption) { - for _, opt := range opts { - switch opt := opt.filter(s, t, vx, vy); opt.(type) { - case ignore: - return ignore{} // Only ignore can short-circuit evaluation - case validator: - out = validator{} // Takes precedence over comparer or transformer - case *comparer, *transformer, Options: - switch out.(type) { - case nil: - out = opt - case validator: - // Keep validator - case *comparer, *transformer, Options: - out = Options{out, opt} // Conflicting comparers or transformers - } - } - } - return out -} - -func (opts Options) apply(s *state, _, _ reflect.Value) { - const warning = "ambiguous set of applicable options" - const help = "consider using filters to ensure at most one Comparer or Transformer may apply" - var ss []string - for _, opt := range flattenOptions(nil, opts) { - ss = append(ss, fmt.Sprint(opt)) - } - set := strings.Join(ss, "\n\t") - panic(fmt.Sprintf("%s at %#v:\n\t%s\n%s", warning, s.curPath, set, help)) -} - -func (opts Options) String() string { - var ss []string - for _, opt := range opts { - ss = append(ss, fmt.Sprint(opt)) - } - return fmt.Sprintf("Options{%s}", strings.Join(ss, ", ")) -} - -// FilterPath returns a new [Option] where opt is only evaluated if filter f -// returns true for the current [Path] in the value tree. -// -// This filter is called even if a slice element or map entry is missing and -// provides an opportunity to ignore such cases. The filter function must be -// symmetric such that the filter result is identical regardless of whether the -// missing value is from x or y. -// -// The option passed in may be an [Ignore], [Transformer], [Comparer], [Options], or -// a previously filtered [Option]. -func FilterPath(f func(Path) bool, opt Option) Option { - if f == nil { - panic("invalid path filter function") - } - if opt := normalizeOption(opt); opt != nil { - return &pathFilter{fnc: f, opt: opt} - } - return nil -} - -type pathFilter struct { - core - fnc func(Path) bool - opt Option -} - -func (f pathFilter) filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption { - if f.fnc(s.curPath) { - return f.opt.filter(s, t, vx, vy) - } - return nil -} - -func (f pathFilter) String() string { - return fmt.Sprintf("FilterPath(%s, %v)", function.NameOf(reflect.ValueOf(f.fnc)), f.opt) -} - -// FilterValues returns a new [Option] where opt is only evaluated if filter f, -// which is a function of the form "func(T, T) bool", returns true for the -// current pair of values being compared. If either value is invalid or -// the type of the values is not assignable to T, then this filter implicitly -// returns false. -// -// The filter function must be -// symmetric (i.e., agnostic to the order of the inputs) and -// deterministic (i.e., produces the same result when given the same inputs). -// If T is an interface, it is possible that f is called with two values with -// different concrete types that both implement T. -// -// The option passed in may be an [Ignore], [Transformer], [Comparer], [Options], or -// a previously filtered [Option]. -func FilterValues(f interface{}, opt Option) Option { - v := reflect.ValueOf(f) - if !function.IsType(v.Type(), function.ValueFilter) || v.IsNil() { - panic(fmt.Sprintf("invalid values filter function: %T", f)) - } - if opt := normalizeOption(opt); opt != nil { - vf := &valuesFilter{fnc: v, opt: opt} - if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 { - vf.typ = ti - } - return vf - } - return nil -} - -type valuesFilter struct { - core - typ reflect.Type // T - fnc reflect.Value // func(T, T) bool - opt Option -} - -func (f valuesFilter) filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption { - if !vx.IsValid() || !vx.CanInterface() || !vy.IsValid() || !vy.CanInterface() { - return nil - } - if (f.typ == nil || t.AssignableTo(f.typ)) && s.callTTBFunc(f.fnc, vx, vy) { - return f.opt.filter(s, t, vx, vy) - } - return nil -} - -func (f valuesFilter) String() string { - return fmt.Sprintf("FilterValues(%s, %v)", function.NameOf(f.fnc), f.opt) -} - -// Ignore is an [Option] that causes all comparisons to be ignored. -// This value is intended to be combined with [FilterPath] or [FilterValues]. -// It is an error to pass an unfiltered Ignore option to [Equal]. -func Ignore() Option { return ignore{} } - -type ignore struct{ core } - -func (ignore) isFiltered() bool { return false } -func (ignore) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption { return ignore{} } -func (ignore) apply(s *state, _, _ reflect.Value) { s.report(true, reportByIgnore) } -func (ignore) String() string { return "Ignore()" } - -// validator is a sentinel Option type to indicate that some options could not -// be evaluated due to unexported fields, missing slice elements, or -// missing map entries. Both values are validator only for unexported fields. -type validator struct{ core } - -func (validator) filter(_ *state, _ reflect.Type, vx, vy reflect.Value) applicableOption { - if !vx.IsValid() || !vy.IsValid() { - return validator{} - } - if !vx.CanInterface() || !vy.CanInterface() { - return validator{} - } - return nil -} -func (validator) apply(s *state, vx, vy reflect.Value) { - // Implies missing slice element or map entry. - if !vx.IsValid() || !vy.IsValid() { - s.report(vx.IsValid() == vy.IsValid(), 0) - return - } - - // Unable to Interface implies unexported field without visibility access. - if !vx.CanInterface() || !vy.CanInterface() { - help := "consider using a custom Comparer; if you control the implementation of type, you can also consider using an Exporter, AllowUnexported, or cmpopts.IgnoreUnexported" - var name string - if t := s.curPath.Index(-2).Type(); t.Name() != "" { - // Named type with unexported fields. - name = fmt.Sprintf("%q.%v", t.PkgPath(), t.Name()) // e.g., "path/to/package".MyType - if _, ok := reflect.New(t).Interface().(error); ok { - help = "consider using cmpopts.EquateErrors to compare error values" - } else if t.Comparable() { - help = "consider using cmpopts.EquateComparable to compare comparable Go types" - } - } else { - // Unnamed type with unexported fields. Derive PkgPath from field. - var pkgPath string - for i := 0; i < t.NumField() && pkgPath == ""; i++ { - pkgPath = t.Field(i).PkgPath - } - name = fmt.Sprintf("%q.(%v)", pkgPath, t.String()) // e.g., "path/to/package".(struct { a int }) - } - panic(fmt.Sprintf("cannot handle unexported field at %#v:\n\t%v\n%s", s.curPath, name, help)) - } - - panic("not reachable") -} - -// identRx represents a valid identifier according to the Go specification. -const identRx = `[_\p{L}][_\p{L}\p{N}]*` - -var identsRx = regexp.MustCompile(`^` + identRx + `(\.` + identRx + `)*$`) - -// Transformer returns an [Option] that applies a transformation function that -// converts values of a certain type into that of another. -// -// The transformer f must be a function "func(T) R" that converts values of -// type T to those of type R and is implicitly filtered to input values -// assignable to T. The transformer must not mutate T in any way. -// -// To help prevent some cases of infinite recursive cycles applying the -// same transform to the output of itself (e.g., in the case where the -// input and output types are the same), an implicit filter is added such that -// a transformer is applicable only if that exact transformer is not already -// in the tail of the [Path] since the last non-[Transform] step. -// For situations where the implicit filter is still insufficient, -// consider using [github.com/google/go-cmp/cmp/cmpopts.AcyclicTransformer], -// which adds a filter to prevent the transformer from -// being recursively applied upon itself. -// -// The name is a user provided label that is used as the [Transform.Name] in the -// transformation [PathStep] (and eventually shown in the [Diff] output). -// The name must be a valid identifier or qualified identifier in Go syntax. -// If empty, an arbitrary name is used. -func Transformer(name string, f interface{}) Option { - v := reflect.ValueOf(f) - if !function.IsType(v.Type(), function.Transformer) || v.IsNil() { - panic(fmt.Sprintf("invalid transformer function: %T", f)) - } - if name == "" { - name = function.NameOf(v) - if !identsRx.MatchString(name) { - name = "λ" // Lambda-symbol as placeholder name - } - } else if !identsRx.MatchString(name) { - panic(fmt.Sprintf("invalid name: %q", name)) - } - tr := &transformer{name: name, fnc: reflect.ValueOf(f)} - if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 { - tr.typ = ti - } - return tr -} - -type transformer struct { - core - name string - typ reflect.Type // T - fnc reflect.Value // func(T) R -} - -func (tr *transformer) isFiltered() bool { return tr.typ != nil } - -func (tr *transformer) filter(s *state, t reflect.Type, _, _ reflect.Value) applicableOption { - for i := len(s.curPath) - 1; i >= 0; i-- { - if t, ok := s.curPath[i].(Transform); !ok { - break // Hit most recent non-Transform step - } else if tr == t.trans { - return nil // Cannot directly use same Transform - } - } - if tr.typ == nil || t.AssignableTo(tr.typ) { - return tr - } - return nil -} - -func (tr *transformer) apply(s *state, vx, vy reflect.Value) { - step := Transform{&transform{pathStep{typ: tr.fnc.Type().Out(0)}, tr}} - vvx := s.callTRFunc(tr.fnc, vx, step) - vvy := s.callTRFunc(tr.fnc, vy, step) - step.vx, step.vy = vvx, vvy - s.compareAny(step) -} - -func (tr transformer) String() string { - return fmt.Sprintf("Transformer(%s, %s)", tr.name, function.NameOf(tr.fnc)) -} - -// Comparer returns an [Option] that determines whether two values are equal -// to each other. -// -// The comparer f must be a function "func(T, T) bool" and is implicitly -// filtered to input values assignable to T. If T is an interface, it is -// possible that f is called with two values of different concrete types that -// both implement T. -// -// The equality function must be: -// - Symmetric: equal(x, y) == equal(y, x) -// - Deterministic: equal(x, y) == equal(x, y) -// - Pure: equal(x, y) does not modify x or y -func Comparer(f interface{}) Option { - v := reflect.ValueOf(f) - if !function.IsType(v.Type(), function.Equal) || v.IsNil() { - panic(fmt.Sprintf("invalid comparer function: %T", f)) - } - cm := &comparer{fnc: v} - if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 { - cm.typ = ti - } - return cm -} - -type comparer struct { - core - typ reflect.Type // T - fnc reflect.Value // func(T, T) bool -} - -func (cm *comparer) isFiltered() bool { return cm.typ != nil } - -func (cm *comparer) filter(_ *state, t reflect.Type, _, _ reflect.Value) applicableOption { - if cm.typ == nil || t.AssignableTo(cm.typ) { - return cm - } - return nil -} - -func (cm *comparer) apply(s *state, vx, vy reflect.Value) { - eq := s.callTTBFunc(cm.fnc, vx, vy) - s.report(eq, reportByFunc) -} - -func (cm comparer) String() string { - return fmt.Sprintf("Comparer(%s)", function.NameOf(cm.fnc)) -} - -// Exporter returns an [Option] that specifies whether [Equal] is allowed to -// introspect into the unexported fields of certain struct types. -// -// Users of this option must understand that comparing on unexported fields -// from external packages is not safe since changes in the internal -// implementation of some external package may cause the result of [Equal] -// to unexpectedly change. However, it may be valid to use this option on types -// defined in an internal package where the semantic meaning of an unexported -// field is in the control of the user. -// -// In many cases, a custom [Comparer] should be used instead that defines -// equality as a function of the public API of a type rather than the underlying -// unexported implementation. -// -// For example, the [reflect.Type] documentation defines equality to be determined -// by the == operator on the interface (essentially performing a shallow pointer -// comparison) and most attempts to compare *[regexp.Regexp] types are interested -// in only checking that the regular expression strings are equal. -// Both of these are accomplished using [Comparer] options: -// -// Comparer(func(x, y reflect.Type) bool { return x == y }) -// Comparer(func(x, y *regexp.Regexp) bool { return x.String() == y.String() }) -// -// In other cases, the [github.com/google/go-cmp/cmp/cmpopts.IgnoreUnexported] -// option can be used to ignore all unexported fields on specified struct types. -func Exporter(f func(reflect.Type) bool) Option { - return exporter(f) -} - -type exporter func(reflect.Type) bool - -func (exporter) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption { - panic("not implemented") -} - -// AllowUnexported returns an [Option] that allows [Equal] to forcibly introspect -// unexported fields of the specified struct types. -// -// See [Exporter] for the proper use of this option. -func AllowUnexported(types ...interface{}) Option { - m := make(map[reflect.Type]bool) - for _, typ := range types { - t := reflect.TypeOf(typ) - if t.Kind() != reflect.Struct { - panic(fmt.Sprintf("invalid struct type: %T", typ)) - } - m[t] = true - } - return exporter(func(t reflect.Type) bool { return m[t] }) -} - -// Result represents the comparison result for a single node and -// is provided by cmp when calling Report (see [Reporter]). -type Result struct { - _ [0]func() // Make Result incomparable - flags resultFlags -} - -// Equal reports whether the node was determined to be equal or not. -// As a special case, ignored nodes are considered equal. -func (r Result) Equal() bool { - return r.flags&(reportEqual|reportByIgnore) != 0 -} - -// ByIgnore reports whether the node is equal because it was ignored. -// This never reports true if [Result.Equal] reports false. -func (r Result) ByIgnore() bool { - return r.flags&reportByIgnore != 0 -} - -// ByMethod reports whether the Equal method determined equality. -func (r Result) ByMethod() bool { - return r.flags&reportByMethod != 0 -} - -// ByFunc reports whether a [Comparer] function determined equality. -func (r Result) ByFunc() bool { - return r.flags&reportByFunc != 0 -} - -// ByCycle reports whether a reference cycle was detected. -func (r Result) ByCycle() bool { - return r.flags&reportByCycle != 0 -} - -type resultFlags uint - -const ( - _ resultFlags = (1 << iota) / 2 - - reportEqual - reportUnequal - reportByIgnore - reportByMethod - reportByFunc - reportByCycle -) - -// Reporter is an [Option] that can be passed to [Equal]. When [Equal] traverses -// the value trees, it calls PushStep as it descends into each node in the -// tree and PopStep as it ascend out of the node. The leaves of the tree are -// either compared (determined to be equal or not equal) or ignored and reported -// as such by calling the Report method. -func Reporter(r interface { - // PushStep is called when a tree-traversal operation is performed. - // The PathStep itself is only valid until the step is popped. - // The PathStep.Values are valid for the duration of the entire traversal - // and must not be mutated. - // - // Equal always calls PushStep at the start to provide an operation-less - // PathStep used to report the root values. - // - // Within a slice, the exact set of inserted, removed, or modified elements - // is unspecified and may change in future implementations. - // The entries of a map are iterated through in an unspecified order. - PushStep(PathStep) - - // Report is called exactly once on leaf nodes to report whether the - // comparison identified the node as equal, unequal, or ignored. - // A leaf node is one that is immediately preceded by and followed by - // a pair of PushStep and PopStep calls. - Report(Result) - - // PopStep ascends back up the value tree. - // There is always a matching pop call for every push call. - PopStep() -}) Option { - return reporter{r} -} - -type reporter struct{ reporterIface } -type reporterIface interface { - PushStep(PathStep) - Report(Result) - PopStep() -} - -func (reporter) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption { - panic("not implemented") -} - -// normalizeOption normalizes the input options such that all Options groups -// are flattened and groups with a single element are reduced to that element. -// Only coreOptions and Options containing coreOptions are allowed. -func normalizeOption(src Option) Option { - switch opts := flattenOptions(nil, Options{src}); len(opts) { - case 0: - return nil - case 1: - return opts[0] - default: - return opts - } -} - -// flattenOptions copies all options in src to dst as a flat list. -// Only coreOptions and Options containing coreOptions are allowed. -func flattenOptions(dst, src Options) Options { - for _, opt := range src { - switch opt := opt.(type) { - case nil: - continue - case Options: - dst = flattenOptions(dst, opt) - case coreOption: - dst = append(dst, opt) - default: - panic(fmt.Sprintf("invalid option type: %T", opt)) - } - } - return dst -} diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go deleted file mode 100644 index c3c145642..000000000 --- a/vendor/github.com/google/go-cmp/cmp/path.go +++ /dev/null @@ -1,390 +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 cmp - -import ( - "fmt" - "reflect" - "strings" - "unicode" - "unicode/utf8" - - "github.com/google/go-cmp/cmp/internal/value" -) - -// Path is a list of [PathStep] describing the sequence of operations to get -// from some root type to the current position in the value tree. -// The first Path element is always an operation-less [PathStep] that exists -// simply to identify the initial type. -// -// When traversing structs with embedded structs, the embedded struct will -// always be accessed as a field before traversing the fields of the -// embedded struct themselves. That is, an exported field from the -// embedded struct will never be accessed directly from the parent struct. -type Path []PathStep - -// PathStep is a union-type for specific operations to traverse -// a value's tree structure. Users of this package never need to implement -// these types as values of this type will be returned by this package. -// -// Implementations of this interface: -// - [StructField] -// - [SliceIndex] -// - [MapIndex] -// - [Indirect] -// - [TypeAssertion] -// - [Transform] -type PathStep interface { - String() string - - // Type is the resulting type after performing the path step. - Type() reflect.Type - - // Values is the resulting values after performing the path step. - // The type of each valid value is guaranteed to be identical to Type. - // - // In some cases, one or both may be invalid or have restrictions: - // - For StructField, both are not interface-able if the current field - // is unexported and the struct type is not explicitly permitted by - // an Exporter to traverse unexported fields. - // - For SliceIndex, one may be invalid if an element is missing from - // either the x or y slice. - // - For MapIndex, one may be invalid if an entry is missing from - // either the x or y map. - // - // The provided values must not be mutated. - Values() (vx, vy reflect.Value) -} - -var ( - _ PathStep = StructField{} - _ PathStep = SliceIndex{} - _ PathStep = MapIndex{} - _ PathStep = Indirect{} - _ PathStep = TypeAssertion{} - _ PathStep = Transform{} -) - -func (pa *Path) push(s PathStep) { - *pa = append(*pa, s) -} - -func (pa *Path) pop() { - *pa = (*pa)[:len(*pa)-1] -} - -// Last returns the last [PathStep] in the Path. -// If the path is empty, this returns a non-nil [PathStep] -// that reports a nil [PathStep.Type]. -func (pa Path) Last() PathStep { - return pa.Index(-1) -} - -// Index returns the ith step in the Path and supports negative indexing. -// A negative index starts counting from the tail of the Path such that -1 -// refers to the last step, -2 refers to the second-to-last step, and so on. -// If index is invalid, this returns a non-nil [PathStep] -// that reports a nil [PathStep.Type]. -func (pa Path) Index(i int) PathStep { - if i < 0 { - i = len(pa) + i - } - if i < 0 || i >= len(pa) { - return pathStep{} - } - return pa[i] -} - -// String returns the simplified path to a node. -// The simplified path only contains struct field accesses. -// -// For example: -// -// MyMap.MySlices.MyField -func (pa Path) String() string { - var ss []string - for _, s := range pa { - if _, ok := s.(StructField); ok { - ss = append(ss, s.String()) - } - } - return strings.TrimPrefix(strings.Join(ss, ""), ".") -} - -// GoString returns the path to a specific node using Go syntax. -// -// For example: -// -// (*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField -func (pa Path) GoString() string { - var ssPre, ssPost []string - var numIndirect int - for i, s := range pa { - var nextStep PathStep - if i+1 < len(pa) { - nextStep = pa[i+1] - } - switch s := s.(type) { - case Indirect: - numIndirect++ - pPre, pPost := "(", ")" - switch nextStep.(type) { - case Indirect: - continue // Next step is indirection, so let them batch up - case StructField: - numIndirect-- // Automatic indirection on struct fields - case nil: - pPre, pPost = "", "" // Last step; no need for parenthesis - } - if numIndirect > 0 { - ssPre = append(ssPre, pPre+strings.Repeat("*", numIndirect)) - ssPost = append(ssPost, pPost) - } - numIndirect = 0 - continue - case Transform: - ssPre = append(ssPre, s.trans.name+"(") - ssPost = append(ssPost, ")") - continue - } - ssPost = append(ssPost, s.String()) - } - for i, j := 0, len(ssPre)-1; i < j; i, j = i+1, j-1 { - ssPre[i], ssPre[j] = ssPre[j], ssPre[i] - } - return strings.Join(ssPre, "") + strings.Join(ssPost, "") -} - -type pathStep struct { - typ reflect.Type - vx, vy reflect.Value -} - -func (ps pathStep) Type() reflect.Type { return ps.typ } -func (ps pathStep) Values() (vx, vy reflect.Value) { return ps.vx, ps.vy } -func (ps pathStep) String() string { - if ps.typ == nil { - return "" - } - s := value.TypeString(ps.typ, false) - if s == "" || strings.ContainsAny(s, "{}\n") { - return "root" // Type too simple or complex to print - } - return fmt.Sprintf("{%s}", s) -} - -// StructField is a [PathStep] that represents a struct field access -// on a field called [StructField.Name]. -type StructField struct{ *structField } -type structField struct { - pathStep - name string - idx int - - // These fields are used for forcibly accessing an unexported field. - // pvx, pvy, and field are only valid if unexported is true. - unexported bool - mayForce bool // Forcibly allow visibility - paddr bool // Was parent addressable? - pvx, pvy reflect.Value // Parent values (always addressable) - field reflect.StructField // Field information -} - -func (sf StructField) Type() reflect.Type { return sf.typ } -func (sf StructField) Values() (vx, vy reflect.Value) { - if !sf.unexported { - return sf.vx, sf.vy // CanInterface reports true - } - - // Forcibly obtain read-write access to an unexported struct field. - if sf.mayForce { - vx = retrieveUnexportedField(sf.pvx, sf.field, sf.paddr) - vy = retrieveUnexportedField(sf.pvy, sf.field, sf.paddr) - return vx, vy // CanInterface reports true - } - return sf.vx, sf.vy // CanInterface reports false -} -func (sf StructField) String() string { return fmt.Sprintf(".%s", sf.name) } - -// Name is the field name. -func (sf StructField) Name() string { return sf.name } - -// Index is the index of the field in the parent struct type. -// See [reflect.Type.Field]. -func (sf StructField) Index() int { return sf.idx } - -// SliceIndex is a [PathStep] that represents an index operation on -// a slice or array at some index [SliceIndex.Key]. -type SliceIndex struct{ *sliceIndex } -type sliceIndex struct { - pathStep - xkey, ykey int - isSlice bool // False for reflect.Array -} - -func (si SliceIndex) Type() reflect.Type { return si.typ } -func (si SliceIndex) Values() (vx, vy reflect.Value) { return si.vx, si.vy } -func (si SliceIndex) String() string { - switch { - case si.xkey == si.ykey: - return fmt.Sprintf("[%d]", si.xkey) - case si.ykey == -1: - // [5->?] means "I don't know where X[5] went" - return fmt.Sprintf("[%d->?]", si.xkey) - case si.xkey == -1: - // [?->3] means "I don't know where Y[3] came from" - return fmt.Sprintf("[?->%d]", si.ykey) - default: - // [5->3] means "X[5] moved to Y[3]" - return fmt.Sprintf("[%d->%d]", si.xkey, si.ykey) - } -} - -// Key is the index key; it may return -1 if in a split state -func (si SliceIndex) Key() int { - if si.xkey != si.ykey { - return -1 - } - return si.xkey -} - -// SplitKeys are the indexes for indexing into slices in the -// x and y values, respectively. These indexes may differ due to the -// insertion or removal of an element in one of the slices, causing -// all of the indexes to be shifted. If an index is -1, then that -// indicates that the element does not exist in the associated slice. -// -// [SliceIndex.Key] is guaranteed to return -1 if and only if the indexes -// returned by SplitKeys are not the same. SplitKeys will never return -1 for -// both indexes. -func (si SliceIndex) SplitKeys() (ix, iy int) { return si.xkey, si.ykey } - -// MapIndex is a [PathStep] that represents an index operation on a map at some index Key. -type MapIndex struct{ *mapIndex } -type mapIndex struct { - pathStep - key reflect.Value -} - -func (mi MapIndex) Type() reflect.Type { return mi.typ } -func (mi MapIndex) Values() (vx, vy reflect.Value) { return mi.vx, mi.vy } -func (mi MapIndex) String() string { return fmt.Sprintf("[%#v]", mi.key) } - -// Key is the value of the map key. -func (mi MapIndex) Key() reflect.Value { return mi.key } - -// Indirect is a [PathStep] that represents pointer indirection on the parent type. -type Indirect struct{ *indirect } -type indirect struct { - pathStep -} - -func (in Indirect) Type() reflect.Type { return in.typ } -func (in Indirect) Values() (vx, vy reflect.Value) { return in.vx, in.vy } -func (in Indirect) String() string { return "*" } - -// TypeAssertion is a [PathStep] that represents a type assertion on an interface. -type TypeAssertion struct{ *typeAssertion } -type typeAssertion struct { - pathStep -} - -func (ta TypeAssertion) Type() reflect.Type { return ta.typ } -func (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy } -func (ta TypeAssertion) String() string { return fmt.Sprintf(".(%v)", value.TypeString(ta.typ, false)) } - -// Transform is a [PathStep] that represents a transformation -// from the parent type to the current type. -type Transform struct{ *transform } -type transform struct { - pathStep - trans *transformer -} - -func (tf Transform) Type() reflect.Type { return tf.typ } -func (tf Transform) Values() (vx, vy reflect.Value) { return tf.vx, tf.vy } -func (tf Transform) String() string { return fmt.Sprintf("%s()", tf.trans.name) } - -// Name is the name of the [Transformer]. -func (tf Transform) Name() string { return tf.trans.name } - -// Func is the function pointer to the transformer function. -func (tf Transform) Func() reflect.Value { return tf.trans.fnc } - -// Option returns the originally constructed [Transformer] option. -// The == operator can be used to detect the exact option used. -func (tf Transform) Option() Option { return tf.trans } - -// pointerPath represents a dual-stack of pointers encountered when -// recursively traversing the x and y values. This data structure supports -// detection of cycles and determining whether the cycles are equal. -// In Go, cycles can occur via pointers, slices, and maps. -// -// The pointerPath uses a map to represent a stack; where descension into a -// pointer pushes the address onto the stack, and ascension from a pointer -// pops the address from the stack. Thus, when traversing into a pointer from -// reflect.Ptr, reflect.Slice element, or reflect.Map, we can detect cycles -// by checking whether the pointer has already been visited. The cycle detection -// uses a separate stack for the x and y values. -// -// If a cycle is detected we need to determine whether the two pointers -// should be considered equal. The definition of equality chosen by Equal -// requires two graphs to have the same structure. To determine this, both the -// x and y values must have a cycle where the previous pointers were also -// encountered together as a pair. -// -// Semantically, this is equivalent to augmenting Indirect, SliceIndex, and -// MapIndex with pointer information for the x and y values. -// Suppose px and py are two pointers to compare, we then search the -// Path for whether px was ever encountered in the Path history of x, and -// similarly so with py. If either side has a cycle, the comparison is only -// equal if both px and py have a cycle resulting from the same PathStep. -// -// Using a map as a stack is more performant as we can perform cycle detection -// in O(1) instead of O(N) where N is len(Path). -type pointerPath struct { - // mx is keyed by x pointers, where the value is the associated y pointer. - mx map[value.Pointer]value.Pointer - // my is keyed by y pointers, where the value is the associated x pointer. - my map[value.Pointer]value.Pointer -} - -func (p *pointerPath) Init() { - p.mx = make(map[value.Pointer]value.Pointer) - p.my = make(map[value.Pointer]value.Pointer) -} - -// Push indicates intent to descend into pointers vx and vy where -// visited reports whether either has been seen before. If visited before, -// equal reports whether both pointers were encountered together. -// Pop must be called if and only if the pointers were never visited. -// -// The pointers vx and vy must be a reflect.Ptr, reflect.Slice, or reflect.Map -// and be non-nil. -func (p pointerPath) Push(vx, vy reflect.Value) (equal, visited bool) { - px := value.PointerOf(vx) - py := value.PointerOf(vy) - _, ok1 := p.mx[px] - _, ok2 := p.my[py] - if ok1 || ok2 { - equal = p.mx[px] == py && p.my[py] == px // Pointers paired together - return equal, true - } - p.mx[px] = py - p.my[py] = px - return false, false -} - -// Pop ascends from pointers vx and vy. -func (p pointerPath) Pop(vx, vy reflect.Value) { - delete(p.mx, value.PointerOf(vx)) - delete(p.my, value.PointerOf(vy)) -} - -// isExported reports whether the identifier is exported. -func isExported(id string) bool { - r, _ := utf8.DecodeRuneInString(id) - return unicode.IsUpper(r) -} diff --git a/vendor/github.com/google/go-cmp/cmp/report.go b/vendor/github.com/google/go-cmp/cmp/report.go deleted file mode 100644 index f43cd12eb..000000000 --- a/vendor/github.com/google/go-cmp/cmp/report.go +++ /dev/null @@ -1,54 +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 cmp - -// defaultReporter implements the reporter interface. -// -// As Equal serially calls the PushStep, Report, and PopStep methods, the -// defaultReporter constructs a tree-based representation of the compared value -// and the result of each comparison (see valueNode). -// -// When the String method is called, the FormatDiff method transforms the -// valueNode tree into a textNode tree, which is a tree-based representation -// of the textual output (see textNode). -// -// Lastly, the textNode.String method produces the final report as a string. -type defaultReporter struct { - root *valueNode - curr *valueNode -} - -func (r *defaultReporter) PushStep(ps PathStep) { - r.curr = r.curr.PushStep(ps) - if r.root == nil { - r.root = r.curr - } -} -func (r *defaultReporter) Report(rs Result) { - r.curr.Report(rs) -} -func (r *defaultReporter) PopStep() { - r.curr = r.curr.PopStep() -} - -// String provides a full report of the differences detected as a structured -// literal in pseudo-Go syntax. String may only be called after the entire tree -// has been traversed. -func (r *defaultReporter) String() string { - assert(r.root != nil && r.curr == nil) - if r.root.NumDiff == 0 { - return "" - } - ptrs := new(pointerReferences) - text := formatOptions{}.FormatDiff(r.root, ptrs) - resolveReferences(text) - return text.String() -} - -func assert(ok bool) { - if !ok { - panic("assertion failure") - } -} diff --git a/vendor/github.com/google/go-cmp/cmp/report_compare.go b/vendor/github.com/google/go-cmp/cmp/report_compare.go deleted file mode 100644 index 2050bf6b4..000000000 --- a/vendor/github.com/google/go-cmp/cmp/report_compare.go +++ /dev/null @@ -1,433 +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 cmp - -import ( - "fmt" - "reflect" -) - -// numContextRecords is the number of surrounding equal records to print. -const numContextRecords = 2 - -type diffMode byte - -const ( - diffUnknown diffMode = 0 - diffIdentical diffMode = ' ' - diffRemoved diffMode = '-' - diffInserted diffMode = '+' -) - -type typeMode int - -const ( - // emitType always prints the type. - emitType typeMode = iota - // elideType never prints the type. - elideType - // autoType prints the type only for composite kinds - // (i.e., structs, slices, arrays, and maps). - autoType -) - -type formatOptions struct { - // DiffMode controls the output mode of FormatDiff. - // - // If diffUnknown, then produce a diff of the x and y values. - // If diffIdentical, then emit values as if they were equal. - // If diffRemoved, then only emit x values (ignoring y values). - // If diffInserted, then only emit y values (ignoring x values). - DiffMode diffMode - - // TypeMode controls whether to print the type for the current node. - // - // As a general rule of thumb, we always print the type of the next node - // after an interface, and always elide the type of the next node after - // a slice or map node. - TypeMode typeMode - - // formatValueOptions are options specific to printing reflect.Values. - formatValueOptions -} - -func (opts formatOptions) WithDiffMode(d diffMode) formatOptions { - opts.DiffMode = d - return opts -} -func (opts formatOptions) WithTypeMode(t typeMode) formatOptions { - opts.TypeMode = t - return opts -} -func (opts formatOptions) WithVerbosity(level int) formatOptions { - opts.VerbosityLevel = level - opts.LimitVerbosity = true - return opts -} -func (opts formatOptions) verbosity() uint { - switch { - case opts.VerbosityLevel < 0: - return 0 - case opts.VerbosityLevel > 16: - return 16 // some reasonable maximum to avoid shift overflow - default: - return uint(opts.VerbosityLevel) - } -} - -const maxVerbosityPreset = 6 - -// verbosityPreset modifies the verbosity settings given an index -// between 0 and maxVerbosityPreset, inclusive. -func verbosityPreset(opts formatOptions, i int) formatOptions { - opts.VerbosityLevel = int(opts.verbosity()) + 2*i - if i > 0 { - opts.AvoidStringer = true - } - if i >= maxVerbosityPreset { - opts.PrintAddresses = true - opts.QualifiedNames = true - } - return opts -} - -// FormatDiff converts a valueNode tree into a textNode tree, where the later -// is a textual representation of the differences detected in the former. -func (opts formatOptions) FormatDiff(v *valueNode, ptrs *pointerReferences) (out textNode) { - if opts.DiffMode == diffIdentical { - opts = opts.WithVerbosity(1) - } else if opts.verbosity() < 3 { - opts = opts.WithVerbosity(3) - } - - // Check whether we have specialized formatting for this node. - // This is not necessary, but helpful for producing more readable outputs. - if opts.CanFormatDiffSlice(v) { - return opts.FormatDiffSlice(v) - } - - var parentKind reflect.Kind - if v.parent != nil && v.parent.TransformerName == "" { - parentKind = v.parent.Type.Kind() - } - - // For leaf nodes, format the value based on the reflect.Values alone. - // As a special case, treat equal []byte as a leaf nodes. - isBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == byteType - isEqualBytes := isBytes && v.NumDiff+v.NumIgnored+v.NumTransformed == 0 - if v.MaxDepth == 0 || isEqualBytes { - switch opts.DiffMode { - case diffUnknown, diffIdentical: - // Format Equal. - if v.NumDiff == 0 { - outx := opts.FormatValue(v.ValueX, parentKind, ptrs) - outy := opts.FormatValue(v.ValueY, parentKind, ptrs) - if v.NumIgnored > 0 && v.NumSame == 0 { - return textEllipsis - } else if outx.Len() < outy.Len() { - return outx - } else { - return outy - } - } - - // Format unequal. - assert(opts.DiffMode == diffUnknown) - var list textList - outx := opts.WithTypeMode(elideType).FormatValue(v.ValueX, parentKind, ptrs) - outy := opts.WithTypeMode(elideType).FormatValue(v.ValueY, parentKind, ptrs) - for i := 0; i <= maxVerbosityPreset && outx != nil && outy != nil && outx.Equal(outy); i++ { - opts2 := verbosityPreset(opts, i).WithTypeMode(elideType) - outx = opts2.FormatValue(v.ValueX, parentKind, ptrs) - outy = opts2.FormatValue(v.ValueY, parentKind, ptrs) - } - if outx != nil { - list = append(list, textRecord{Diff: '-', Value: outx}) - } - if outy != nil { - list = append(list, textRecord{Diff: '+', Value: outy}) - } - return opts.WithTypeMode(emitType).FormatType(v.Type, list) - case diffRemoved: - return opts.FormatValue(v.ValueX, parentKind, ptrs) - case diffInserted: - return opts.FormatValue(v.ValueY, parentKind, ptrs) - default: - panic("invalid diff mode") - } - } - - // Register slice element to support cycle detection. - if parentKind == reflect.Slice { - ptrRefs := ptrs.PushPair(v.ValueX, v.ValueY, opts.DiffMode, true) - defer ptrs.Pop() - defer func() { out = wrapTrunkReferences(ptrRefs, out) }() - } - - // Descend into the child value node. - if v.TransformerName != "" { - out := opts.WithTypeMode(emitType).FormatDiff(v.Value, ptrs) - out = &textWrap{Prefix: "Inverse(" + v.TransformerName + ", ", Value: out, Suffix: ")"} - return opts.FormatType(v.Type, out) - } else { - switch k := v.Type.Kind(); k { - case reflect.Struct, reflect.Array, reflect.Slice: - out = opts.formatDiffList(v.Records, k, ptrs) - out = opts.FormatType(v.Type, out) - case reflect.Map: - // Register map to support cycle detection. - ptrRefs := ptrs.PushPair(v.ValueX, v.ValueY, opts.DiffMode, false) - defer ptrs.Pop() - - out = opts.formatDiffList(v.Records, k, ptrs) - out = wrapTrunkReferences(ptrRefs, out) - out = opts.FormatType(v.Type, out) - case reflect.Ptr: - // Register pointer to support cycle detection. - ptrRefs := ptrs.PushPair(v.ValueX, v.ValueY, opts.DiffMode, false) - defer ptrs.Pop() - - out = opts.FormatDiff(v.Value, ptrs) - out = wrapTrunkReferences(ptrRefs, out) - out = &textWrap{Prefix: "&", Value: out} - case reflect.Interface: - out = opts.WithTypeMode(emitType).FormatDiff(v.Value, ptrs) - default: - panic(fmt.Sprintf("%v cannot have children", k)) - } - return out - } -} - -func (opts formatOptions) formatDiffList(recs []reportRecord, k reflect.Kind, ptrs *pointerReferences) textNode { - // Derive record name based on the data structure kind. - var name string - var formatKey func(reflect.Value) string - switch k { - case reflect.Struct: - name = "field" - opts = opts.WithTypeMode(autoType) - formatKey = func(v reflect.Value) string { return v.String() } - case reflect.Slice, reflect.Array: - name = "element" - opts = opts.WithTypeMode(elideType) - formatKey = func(reflect.Value) string { return "" } - case reflect.Map: - name = "entry" - opts = opts.WithTypeMode(elideType) - formatKey = func(v reflect.Value) string { return formatMapKey(v, false, ptrs) } - } - - maxLen := -1 - if opts.LimitVerbosity { - if opts.DiffMode == diffIdentical { - maxLen = ((1 << opts.verbosity()) >> 1) << 2 // 0, 4, 8, 16, 32, etc... - } else { - maxLen = (1 << opts.verbosity()) << 1 // 2, 4, 8, 16, 32, 64, etc... - } - opts.VerbosityLevel-- - } - - // Handle unification. - switch opts.DiffMode { - case diffIdentical, diffRemoved, diffInserted: - var list textList - var deferredEllipsis bool // Add final "..." to indicate records were dropped - for _, r := range recs { - if len(list) == maxLen { - deferredEllipsis = true - break - } - - // Elide struct fields that are zero value. - if k == reflect.Struct { - var isZero bool - switch opts.DiffMode { - case diffIdentical: - isZero = r.Value.ValueX.IsZero() || r.Value.ValueY.IsZero() - case diffRemoved: - isZero = r.Value.ValueX.IsZero() - case diffInserted: - isZero = r.Value.ValueY.IsZero() - } - if isZero { - continue - } - } - // Elide ignored nodes. - if r.Value.NumIgnored > 0 && r.Value.NumSame+r.Value.NumDiff == 0 { - deferredEllipsis = !(k == reflect.Slice || k == reflect.Array) - if !deferredEllipsis { - list.AppendEllipsis(diffStats{}) - } - continue - } - if out := opts.FormatDiff(r.Value, ptrs); out != nil { - list = append(list, textRecord{Key: formatKey(r.Key), Value: out}) - } - } - if deferredEllipsis { - list.AppendEllipsis(diffStats{}) - } - return &textWrap{Prefix: "{", Value: list, Suffix: "}"} - case diffUnknown: - default: - panic("invalid diff mode") - } - - // Handle differencing. - var numDiffs int - var list textList - var keys []reflect.Value // invariant: len(list) == len(keys) - groups := coalesceAdjacentRecords(name, recs) - maxGroup := diffStats{Name: name} - for i, ds := range groups { - if maxLen >= 0 && numDiffs >= maxLen { - maxGroup = maxGroup.Append(ds) - continue - } - - // Handle equal records. - if ds.NumDiff() == 0 { - // Compute the number of leading and trailing records to print. - var numLo, numHi int - numEqual := ds.NumIgnored + ds.NumIdentical - for numLo < numContextRecords && numLo+numHi < numEqual && i != 0 { - if r := recs[numLo].Value; r.NumIgnored > 0 && r.NumSame+r.NumDiff == 0 { - break - } - numLo++ - } - for numHi < numContextRecords && numLo+numHi < numEqual && i != len(groups)-1 { - if r := recs[numEqual-numHi-1].Value; r.NumIgnored > 0 && r.NumSame+r.NumDiff == 0 { - break - } - numHi++ - } - if numEqual-(numLo+numHi) == 1 && ds.NumIgnored == 0 { - numHi++ // Avoid pointless coalescing of a single equal record - } - - // Format the equal values. - for _, r := range recs[:numLo] { - out := opts.WithDiffMode(diffIdentical).FormatDiff(r.Value, ptrs) - list = append(list, textRecord{Key: formatKey(r.Key), Value: out}) - keys = append(keys, r.Key) - } - if numEqual > numLo+numHi { - ds.NumIdentical -= numLo + numHi - list.AppendEllipsis(ds) - for len(keys) < len(list) { - keys = append(keys, reflect.Value{}) - } - } - for _, r := range recs[numEqual-numHi : numEqual] { - out := opts.WithDiffMode(diffIdentical).FormatDiff(r.Value, ptrs) - list = append(list, textRecord{Key: formatKey(r.Key), Value: out}) - keys = append(keys, r.Key) - } - recs = recs[numEqual:] - continue - } - - // Handle unequal records. - for _, r := range recs[:ds.NumDiff()] { - switch { - case opts.CanFormatDiffSlice(r.Value): - out := opts.FormatDiffSlice(r.Value) - list = append(list, textRecord{Key: formatKey(r.Key), Value: out}) - keys = append(keys, r.Key) - case r.Value.NumChildren == r.Value.MaxDepth: - outx := opts.WithDiffMode(diffRemoved).FormatDiff(r.Value, ptrs) - outy := opts.WithDiffMode(diffInserted).FormatDiff(r.Value, ptrs) - for i := 0; i <= maxVerbosityPreset && outx != nil && outy != nil && outx.Equal(outy); i++ { - opts2 := verbosityPreset(opts, i) - outx = opts2.WithDiffMode(diffRemoved).FormatDiff(r.Value, ptrs) - outy = opts2.WithDiffMode(diffInserted).FormatDiff(r.Value, ptrs) - } - if outx != nil { - list = append(list, textRecord{Diff: diffRemoved, Key: formatKey(r.Key), Value: outx}) - keys = append(keys, r.Key) - } - if outy != nil { - list = append(list, textRecord{Diff: diffInserted, Key: formatKey(r.Key), Value: outy}) - keys = append(keys, r.Key) - } - default: - out := opts.FormatDiff(r.Value, ptrs) - list = append(list, textRecord{Key: formatKey(r.Key), Value: out}) - keys = append(keys, r.Key) - } - } - recs = recs[ds.NumDiff():] - numDiffs += ds.NumDiff() - } - if maxGroup.IsZero() { - assert(len(recs) == 0) - } else { - list.AppendEllipsis(maxGroup) - for len(keys) < len(list) { - keys = append(keys, reflect.Value{}) - } - } - assert(len(list) == len(keys)) - - // For maps, the default formatting logic uses fmt.Stringer which may - // produce ambiguous output. Avoid calling String to disambiguate. - if k == reflect.Map { - var ambiguous bool - seenKeys := map[string]reflect.Value{} - for i, currKey := range keys { - if currKey.IsValid() { - strKey := list[i].Key - prevKey, seen := seenKeys[strKey] - if seen && prevKey.CanInterface() && currKey.CanInterface() { - ambiguous = prevKey.Interface() != currKey.Interface() - if ambiguous { - break - } - } - seenKeys[strKey] = currKey - } - } - if ambiguous { - for i, k := range keys { - if k.IsValid() { - list[i].Key = formatMapKey(k, true, ptrs) - } - } - } - } - - return &textWrap{Prefix: "{", Value: list, Suffix: "}"} -} - -// coalesceAdjacentRecords coalesces the list of records into groups of -// adjacent equal, or unequal counts. -func coalesceAdjacentRecords(name string, recs []reportRecord) (groups []diffStats) { - var prevCase int // Arbitrary index into which case last occurred - lastStats := func(i int) *diffStats { - if prevCase != i { - groups = append(groups, diffStats{Name: name}) - prevCase = i - } - return &groups[len(groups)-1] - } - for _, r := range recs { - switch rv := r.Value; { - case rv.NumIgnored > 0 && rv.NumSame+rv.NumDiff == 0: - lastStats(1).NumIgnored++ - case rv.NumDiff == 0: - lastStats(1).NumIdentical++ - case rv.NumDiff > 0 && !rv.ValueY.IsValid(): - lastStats(2).NumRemoved++ - case rv.NumDiff > 0 && !rv.ValueX.IsValid(): - lastStats(2).NumInserted++ - default: - lastStats(2).NumModified++ - } - } - return groups -} diff --git a/vendor/github.com/google/go-cmp/cmp/report_references.go b/vendor/github.com/google/go-cmp/cmp/report_references.go deleted file mode 100644 index be31b33a9..000000000 --- a/vendor/github.com/google/go-cmp/cmp/report_references.go +++ /dev/null @@ -1,264 +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 cmp - -import ( - "fmt" - "reflect" - "strings" - - "github.com/google/go-cmp/cmp/internal/flags" - "github.com/google/go-cmp/cmp/internal/value" -) - -const ( - pointerDelimPrefix = "⟪" - pointerDelimSuffix = "⟫" -) - -// formatPointer prints the address of the pointer. -func formatPointer(p value.Pointer, withDelims bool) string { - v := p.Uintptr() - if flags.Deterministic { - v = 0xdeadf00f // Only used for stable testing purposes - } - if withDelims { - return pointerDelimPrefix + formatHex(uint64(v)) + pointerDelimSuffix - } - return formatHex(uint64(v)) -} - -// pointerReferences is a stack of pointers visited so far. -type pointerReferences [][2]value.Pointer - -func (ps *pointerReferences) PushPair(vx, vy reflect.Value, d diffMode, deref bool) (pp [2]value.Pointer) { - if deref && vx.IsValid() { - vx = vx.Addr() - } - if deref && vy.IsValid() { - vy = vy.Addr() - } - switch d { - case diffUnknown, diffIdentical: - pp = [2]value.Pointer{value.PointerOf(vx), value.PointerOf(vy)} - case diffRemoved: - pp = [2]value.Pointer{value.PointerOf(vx), value.Pointer{}} - case diffInserted: - pp = [2]value.Pointer{value.Pointer{}, value.PointerOf(vy)} - } - *ps = append(*ps, pp) - return pp -} - -func (ps *pointerReferences) Push(v reflect.Value) (p value.Pointer, seen bool) { - p = value.PointerOf(v) - for _, pp := range *ps { - if p == pp[0] || p == pp[1] { - return p, true - } - } - *ps = append(*ps, [2]value.Pointer{p, p}) - return p, false -} - -func (ps *pointerReferences) Pop() { - *ps = (*ps)[:len(*ps)-1] -} - -// trunkReferences is metadata for a textNode indicating that the sub-tree -// represents the value for either pointer in a pair of references. -type trunkReferences struct{ pp [2]value.Pointer } - -// trunkReference is metadata for a textNode indicating that the sub-tree -// represents the value for the given pointer reference. -type trunkReference struct{ p value.Pointer } - -// leafReference is metadata for a textNode indicating that the value is -// truncated as it refers to another part of the tree (i.e., a trunk). -type leafReference struct{ p value.Pointer } - -func wrapTrunkReferences(pp [2]value.Pointer, s textNode) textNode { - switch { - case pp[0].IsNil(): - return &textWrap{Value: s, Metadata: trunkReference{pp[1]}} - case pp[1].IsNil(): - return &textWrap{Value: s, Metadata: trunkReference{pp[0]}} - case pp[0] == pp[1]: - return &textWrap{Value: s, Metadata: trunkReference{pp[0]}} - default: - return &textWrap{Value: s, Metadata: trunkReferences{pp}} - } -} -func wrapTrunkReference(p value.Pointer, printAddress bool, s textNode) textNode { - var prefix string - if printAddress { - prefix = formatPointer(p, true) - } - return &textWrap{Prefix: prefix, Value: s, Metadata: trunkReference{p}} -} -func makeLeafReference(p value.Pointer, printAddress bool) textNode { - out := &textWrap{Prefix: "(", Value: textEllipsis, Suffix: ")"} - var prefix string - if printAddress { - prefix = formatPointer(p, true) - } - return &textWrap{Prefix: prefix, Value: out, Metadata: leafReference{p}} -} - -// resolveReferences walks the textNode tree searching for any leaf reference -// metadata and resolves each against the corresponding trunk references. -// Since pointer addresses in memory are not particularly readable to the user, -// it replaces each pointer value with an arbitrary and unique reference ID. -func resolveReferences(s textNode) { - var walkNodes func(textNode, func(textNode)) - walkNodes = func(s textNode, f func(textNode)) { - f(s) - switch s := s.(type) { - case *textWrap: - walkNodes(s.Value, f) - case textList: - for _, r := range s { - walkNodes(r.Value, f) - } - } - } - - // Collect all trunks and leaves with reference metadata. - var trunks, leaves []*textWrap - walkNodes(s, func(s textNode) { - if s, ok := s.(*textWrap); ok { - switch s.Metadata.(type) { - case leafReference: - leaves = append(leaves, s) - case trunkReference, trunkReferences: - trunks = append(trunks, s) - } - } - }) - - // No leaf references to resolve. - if len(leaves) == 0 { - return - } - - // Collect the set of all leaf references to resolve. - leafPtrs := make(map[value.Pointer]bool) - for _, leaf := range leaves { - leafPtrs[leaf.Metadata.(leafReference).p] = true - } - - // Collect the set of trunk pointers that are always paired together. - // This allows us to assign a single ID to both pointers for brevity. - // If a pointer in a pair ever occurs by itself or as a different pair, - // then the pair is broken. - pairedTrunkPtrs := make(map[value.Pointer]value.Pointer) - unpair := func(p value.Pointer) { - if !pairedTrunkPtrs[p].IsNil() { - pairedTrunkPtrs[pairedTrunkPtrs[p]] = value.Pointer{} // invalidate other half - } - pairedTrunkPtrs[p] = value.Pointer{} // invalidate this half - } - for _, trunk := range trunks { - switch p := trunk.Metadata.(type) { - case trunkReference: - unpair(p.p) // standalone pointer cannot be part of a pair - case trunkReferences: - p0, ok0 := pairedTrunkPtrs[p.pp[0]] - p1, ok1 := pairedTrunkPtrs[p.pp[1]] - switch { - case !ok0 && !ok1: - // Register the newly seen pair. - pairedTrunkPtrs[p.pp[0]] = p.pp[1] - pairedTrunkPtrs[p.pp[1]] = p.pp[0] - case ok0 && ok1 && p0 == p.pp[1] && p1 == p.pp[0]: - // Exact pair already seen; do nothing. - default: - // Pair conflicts with some other pair; break all pairs. - unpair(p.pp[0]) - unpair(p.pp[1]) - } - } - } - - // Correlate each pointer referenced by leaves to a unique identifier, - // and print the IDs for each trunk that matches those pointers. - var nextID uint - ptrIDs := make(map[value.Pointer]uint) - newID := func() uint { - id := nextID - nextID++ - return id - } - for _, trunk := range trunks { - switch p := trunk.Metadata.(type) { - case trunkReference: - if print := leafPtrs[p.p]; print { - id, ok := ptrIDs[p.p] - if !ok { - id = newID() - ptrIDs[p.p] = id - } - trunk.Prefix = updateReferencePrefix(trunk.Prefix, formatReference(id)) - } - case trunkReferences: - print0 := leafPtrs[p.pp[0]] - print1 := leafPtrs[p.pp[1]] - if print0 || print1 { - id0, ok0 := ptrIDs[p.pp[0]] - id1, ok1 := ptrIDs[p.pp[1]] - isPair := pairedTrunkPtrs[p.pp[0]] == p.pp[1] && pairedTrunkPtrs[p.pp[1]] == p.pp[0] - if isPair { - var id uint - assert(ok0 == ok1) // must be seen together or not at all - if ok0 { - assert(id0 == id1) // must have the same ID - id = id0 - } else { - id = newID() - ptrIDs[p.pp[0]] = id - ptrIDs[p.pp[1]] = id - } - trunk.Prefix = updateReferencePrefix(trunk.Prefix, formatReference(id)) - } else { - if print0 && !ok0 { - id0 = newID() - ptrIDs[p.pp[0]] = id0 - } - if print1 && !ok1 { - id1 = newID() - ptrIDs[p.pp[1]] = id1 - } - switch { - case print0 && print1: - trunk.Prefix = updateReferencePrefix(trunk.Prefix, formatReference(id0)+","+formatReference(id1)) - case print0: - trunk.Prefix = updateReferencePrefix(trunk.Prefix, formatReference(id0)) - case print1: - trunk.Prefix = updateReferencePrefix(trunk.Prefix, formatReference(id1)) - } - } - } - } - } - - // Update all leaf references with the unique identifier. - for _, leaf := range leaves { - if id, ok := ptrIDs[leaf.Metadata.(leafReference).p]; ok { - leaf.Prefix = updateReferencePrefix(leaf.Prefix, formatReference(id)) - } - } -} - -func formatReference(id uint) string { - return fmt.Sprintf("ref#%d", id) -} - -func updateReferencePrefix(prefix, ref string) string { - if prefix == "" { - return pointerDelimPrefix + ref + pointerDelimSuffix - } - suffix := strings.TrimPrefix(prefix, pointerDelimPrefix) - return pointerDelimPrefix + ref + ": " + suffix -} diff --git a/vendor/github.com/google/go-cmp/cmp/report_reflect.go b/vendor/github.com/google/go-cmp/cmp/report_reflect.go deleted file mode 100644 index e39f42284..000000000 --- a/vendor/github.com/google/go-cmp/cmp/report_reflect.go +++ /dev/null @@ -1,414 +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 cmp - -import ( - "bytes" - "fmt" - "reflect" - "strconv" - "strings" - "unicode" - "unicode/utf8" - - "github.com/google/go-cmp/cmp/internal/value" -) - -var ( - anyType = reflect.TypeOf((*interface{})(nil)).Elem() - stringType = reflect.TypeOf((*string)(nil)).Elem() - bytesType = reflect.TypeOf((*[]byte)(nil)).Elem() - byteType = reflect.TypeOf((*byte)(nil)).Elem() -) - -type formatValueOptions struct { - // AvoidStringer controls whether to avoid calling custom stringer - // methods like error.Error or fmt.Stringer.String. - AvoidStringer bool - - // PrintAddresses controls whether to print the address of all pointers, - // slice elements, and maps. - PrintAddresses bool - - // QualifiedNames controls whether FormatType uses the fully qualified name - // (including the full package path as opposed to just the package name). - QualifiedNames bool - - // VerbosityLevel controls the amount of output to produce. - // A higher value produces more output. A value of zero or lower produces - // no output (represented using an ellipsis). - // If LimitVerbosity is false, then the level is treated as infinite. - VerbosityLevel int - - // LimitVerbosity specifies that formatting should respect VerbosityLevel. - LimitVerbosity bool -} - -// FormatType prints the type as if it were wrapping s. -// This may return s as-is depending on the current type and TypeMode mode. -func (opts formatOptions) FormatType(t reflect.Type, s textNode) textNode { - // Check whether to emit the type or not. - switch opts.TypeMode { - case autoType: - switch t.Kind() { - case reflect.Struct, reflect.Slice, reflect.Array, reflect.Map: - if s.Equal(textNil) { - return s - } - default: - return s - } - if opts.DiffMode == diffIdentical { - return s // elide type for identical nodes - } - case elideType: - return s - } - - // Determine the type label, applying special handling for unnamed types. - typeName := value.TypeString(t, opts.QualifiedNames) - if t.Name() == "" { - // According to Go grammar, certain type literals contain symbols that - // do not strongly bind to the next lexicographical token (e.g., *T). - switch t.Kind() { - case reflect.Chan, reflect.Func, reflect.Ptr: - typeName = "(" + typeName + ")" - } - } - return &textWrap{Prefix: typeName, Value: wrapParens(s)} -} - -// wrapParens wraps s with a set of parenthesis, but avoids it if the -// wrapped node itself is already surrounded by a pair of parenthesis or braces. -// It handles unwrapping one level of pointer-reference nodes. -func wrapParens(s textNode) textNode { - var refNode *textWrap - if s2, ok := s.(*textWrap); ok { - // Unwrap a single pointer reference node. - switch s2.Metadata.(type) { - case leafReference, trunkReference, trunkReferences: - refNode = s2 - if s3, ok := refNode.Value.(*textWrap); ok { - s2 = s3 - } - } - - // Already has delimiters that make parenthesis unnecessary. - hasParens := strings.HasPrefix(s2.Prefix, "(") && strings.HasSuffix(s2.Suffix, ")") - hasBraces := strings.HasPrefix(s2.Prefix, "{") && strings.HasSuffix(s2.Suffix, "}") - if hasParens || hasBraces { - return s - } - } - if refNode != nil { - refNode.Value = &textWrap{Prefix: "(", Value: refNode.Value, Suffix: ")"} - return s - } - return &textWrap{Prefix: "(", Value: s, Suffix: ")"} -} - -// FormatValue prints the reflect.Value, taking extra care to avoid descending -// into pointers already in ptrs. As pointers are visited, ptrs is also updated. -func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, ptrs *pointerReferences) (out textNode) { - if !v.IsValid() { - return nil - } - t := v.Type() - - // Check slice element for cycles. - if parentKind == reflect.Slice { - ptrRef, visited := ptrs.Push(v.Addr()) - if visited { - return makeLeafReference(ptrRef, false) - } - defer ptrs.Pop() - defer func() { out = wrapTrunkReference(ptrRef, false, out) }() - } - - // Check whether there is an Error or String method to call. - if !opts.AvoidStringer && v.CanInterface() { - // Avoid calling Error or String methods on nil receivers since many - // implementations crash when doing so. - if (t.Kind() != reflect.Ptr && t.Kind() != reflect.Interface) || !v.IsNil() { - var prefix, strVal string - func() { - // Swallow and ignore any panics from String or Error. - defer func() { recover() }() - switch v := v.Interface().(type) { - case error: - strVal = v.Error() - prefix = "e" - case fmt.Stringer: - strVal = v.String() - prefix = "s" - } - }() - if prefix != "" { - return opts.formatString(prefix, strVal) - } - } - } - - // Check whether to explicitly wrap the result with the type. - var skipType bool - defer func() { - if !skipType { - out = opts.FormatType(t, out) - } - }() - - switch t.Kind() { - case reflect.Bool: - return textLine(fmt.Sprint(v.Bool())) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return textLine(fmt.Sprint(v.Int())) - case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return textLine(fmt.Sprint(v.Uint())) - case reflect.Uint8: - if parentKind == reflect.Slice || parentKind == reflect.Array { - return textLine(formatHex(v.Uint())) - } - return textLine(fmt.Sprint(v.Uint())) - case reflect.Uintptr: - return textLine(formatHex(v.Uint())) - case reflect.Float32, reflect.Float64: - return textLine(fmt.Sprint(v.Float())) - case reflect.Complex64, reflect.Complex128: - return textLine(fmt.Sprint(v.Complex())) - case reflect.String: - return opts.formatString("", v.String()) - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - return textLine(formatPointer(value.PointerOf(v), true)) - case reflect.Struct: - var list textList - v := makeAddressable(v) // needed for retrieveUnexportedField - maxLen := v.NumField() - if opts.LimitVerbosity { - maxLen = ((1 << opts.verbosity()) >> 1) << 2 // 0, 4, 8, 16, 32, etc... - opts.VerbosityLevel-- - } - for i := 0; i < v.NumField(); i++ { - vv := v.Field(i) - if vv.IsZero() { - continue // Elide fields with zero values - } - if len(list) == maxLen { - list.AppendEllipsis(diffStats{}) - break - } - sf := t.Field(i) - if !isExported(sf.Name) { - vv = retrieveUnexportedField(v, sf, true) - } - s := opts.WithTypeMode(autoType).FormatValue(vv, t.Kind(), ptrs) - list = append(list, textRecord{Key: sf.Name, Value: s}) - } - return &textWrap{Prefix: "{", Value: list, Suffix: "}"} - case reflect.Slice: - if v.IsNil() { - return textNil - } - - // Check whether this is a []byte of text data. - if t.Elem() == byteType { - b := v.Bytes() - isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) || unicode.IsSpace(r) } - if len(b) > 0 && utf8.Valid(b) && len(bytes.TrimFunc(b, isPrintSpace)) == 0 { - out = opts.formatString("", string(b)) - skipType = true - return opts.FormatType(t, out) - } - } - - fallthrough - case reflect.Array: - maxLen := v.Len() - if opts.LimitVerbosity { - maxLen = ((1 << opts.verbosity()) >> 1) << 2 // 0, 4, 8, 16, 32, etc... - opts.VerbosityLevel-- - } - var list textList - for i := 0; i < v.Len(); i++ { - if len(list) == maxLen { - list.AppendEllipsis(diffStats{}) - break - } - s := opts.WithTypeMode(elideType).FormatValue(v.Index(i), t.Kind(), ptrs) - list = append(list, textRecord{Value: s}) - } - - out = &textWrap{Prefix: "{", Value: list, Suffix: "}"} - if t.Kind() == reflect.Slice && opts.PrintAddresses { - header := fmt.Sprintf("ptr:%v, len:%d, cap:%d", formatPointer(value.PointerOf(v), false), v.Len(), v.Cap()) - out = &textWrap{Prefix: pointerDelimPrefix + header + pointerDelimSuffix, Value: out} - } - return out - case reflect.Map: - if v.IsNil() { - return textNil - } - - // Check pointer for cycles. - ptrRef, visited := ptrs.Push(v) - if visited { - return makeLeafReference(ptrRef, opts.PrintAddresses) - } - defer ptrs.Pop() - - maxLen := v.Len() - if opts.LimitVerbosity { - maxLen = ((1 << opts.verbosity()) >> 1) << 2 // 0, 4, 8, 16, 32, etc... - opts.VerbosityLevel-- - } - var list textList - for _, k := range value.SortKeys(v.MapKeys()) { - if len(list) == maxLen { - list.AppendEllipsis(diffStats{}) - break - } - sk := formatMapKey(k, false, ptrs) - sv := opts.WithTypeMode(elideType).FormatValue(v.MapIndex(k), t.Kind(), ptrs) - list = append(list, textRecord{Key: sk, Value: sv}) - } - - out = &textWrap{Prefix: "{", Value: list, Suffix: "}"} - out = wrapTrunkReference(ptrRef, opts.PrintAddresses, out) - return out - case reflect.Ptr: - if v.IsNil() { - return textNil - } - - // Check pointer for cycles. - ptrRef, visited := ptrs.Push(v) - if visited { - out = makeLeafReference(ptrRef, opts.PrintAddresses) - return &textWrap{Prefix: "&", Value: out} - } - defer ptrs.Pop() - - // Skip the name only if this is an unnamed pointer type. - // Otherwise taking the address of a value does not reproduce - // the named pointer type. - if v.Type().Name() == "" { - skipType = true // Let the underlying value print the type instead - } - out = opts.FormatValue(v.Elem(), t.Kind(), ptrs) - out = wrapTrunkReference(ptrRef, opts.PrintAddresses, out) - out = &textWrap{Prefix: "&", Value: out} - return out - case reflect.Interface: - if v.IsNil() { - return textNil - } - // Interfaces accept different concrete types, - // so configure the underlying value to explicitly print the type. - return opts.WithTypeMode(emitType).FormatValue(v.Elem(), t.Kind(), ptrs) - default: - panic(fmt.Sprintf("%v kind not handled", v.Kind())) - } -} - -func (opts formatOptions) formatString(prefix, s string) textNode { - maxLen := len(s) - maxLines := strings.Count(s, "\n") + 1 - if opts.LimitVerbosity { - maxLen = (1 << opts.verbosity()) << 5 // 32, 64, 128, 256, etc... - maxLines = (1 << opts.verbosity()) << 2 // 4, 8, 16, 32, 64, etc... - } - - // For multiline strings, use the triple-quote syntax, - // but only use it when printing removed or inserted nodes since - // we only want the extra verbosity for those cases. - lines := strings.Split(strings.TrimSuffix(s, "\n"), "\n") - isTripleQuoted := len(lines) >= 4 && (opts.DiffMode == '-' || opts.DiffMode == '+') - for i := 0; i < len(lines) && isTripleQuoted; i++ { - lines[i] = strings.TrimPrefix(strings.TrimSuffix(lines[i], "\r"), "\r") // trim leading/trailing carriage returns for legacy Windows endline support - isPrintable := func(r rune) bool { - return unicode.IsPrint(r) || r == '\t' // specially treat tab as printable - } - line := lines[i] - isTripleQuoted = !strings.HasPrefix(strings.TrimPrefix(line, prefix), `"""`) && !strings.HasPrefix(line, "...") && strings.TrimFunc(line, isPrintable) == "" && len(line) <= maxLen - } - if isTripleQuoted { - var list textList - list = append(list, textRecord{Diff: opts.DiffMode, Value: textLine(prefix + `"""`), ElideComma: true}) - for i, line := range lines { - if numElided := len(lines) - i; i == maxLines-1 && numElided > 1 { - comment := commentString(fmt.Sprintf("%d elided lines", numElided)) - list = append(list, textRecord{Diff: opts.DiffMode, Value: textEllipsis, ElideComma: true, Comment: comment}) - break - } - list = append(list, textRecord{Diff: opts.DiffMode, Value: textLine(line), ElideComma: true}) - } - list = append(list, textRecord{Diff: opts.DiffMode, Value: textLine(prefix + `"""`), ElideComma: true}) - return &textWrap{Prefix: "(", Value: list, Suffix: ")"} - } - - // Format the string as a single-line quoted string. - if len(s) > maxLen+len(textEllipsis) { - return textLine(prefix + formatString(s[:maxLen]) + string(textEllipsis)) - } - return textLine(prefix + formatString(s)) -} - -// formatMapKey formats v as if it were a map key. -// The result is guaranteed to be a single line. -func formatMapKey(v reflect.Value, disambiguate bool, ptrs *pointerReferences) string { - var opts formatOptions - opts.DiffMode = diffIdentical - opts.TypeMode = elideType - opts.PrintAddresses = disambiguate - opts.AvoidStringer = disambiguate - opts.QualifiedNames = disambiguate - opts.VerbosityLevel = maxVerbosityPreset - opts.LimitVerbosity = true - s := opts.FormatValue(v, reflect.Map, ptrs).String() - return strings.TrimSpace(s) -} - -// formatString prints s as a double-quoted or backtick-quoted string. -func formatString(s string) string { - // Use quoted string if it the same length as a raw string literal. - // Otherwise, attempt to use the raw string form. - qs := strconv.Quote(s) - if len(qs) == 1+len(s)+1 { - return qs - } - - // Disallow newlines to ensure output is a single line. - // Only allow printable runes for readability purposes. - rawInvalid := func(r rune) bool { - return r == '`' || r == '\n' || !(unicode.IsPrint(r) || r == '\t') - } - if utf8.ValidString(s) && strings.IndexFunc(s, rawInvalid) < 0 { - return "`" + s + "`" - } - return qs -} - -// formatHex prints u as a hexadecimal integer in Go notation. -func formatHex(u uint64) string { - var f string - switch { - case u <= 0xff: - f = "0x%02x" - case u <= 0xffff: - f = "0x%04x" - case u <= 0xffffff: - f = "0x%06x" - case u <= 0xffffffff: - f = "0x%08x" - case u <= 0xffffffffff: - f = "0x%010x" - case u <= 0xffffffffffff: - f = "0x%012x" - case u <= 0xffffffffffffff: - f = "0x%014x" - case u <= 0xffffffffffffffff: - f = "0x%016x" - } - return fmt.Sprintf(f, u) -} diff --git a/vendor/github.com/google/go-cmp/cmp/report_slices.go b/vendor/github.com/google/go-cmp/cmp/report_slices.go deleted file mode 100644 index 23e444f62..000000000 --- a/vendor/github.com/google/go-cmp/cmp/report_slices.go +++ /dev/null @@ -1,614 +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 cmp - -import ( - "bytes" - "fmt" - "math" - "reflect" - "strconv" - "strings" - "unicode" - "unicode/utf8" - - "github.com/google/go-cmp/cmp/internal/diff" -) - -// CanFormatDiffSlice reports whether we support custom formatting for nodes -// that are slices of primitive kinds or strings. -func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool { - switch { - case opts.DiffMode != diffUnknown: - return false // Must be formatting in diff mode - case v.NumDiff == 0: - return false // No differences detected - case !v.ValueX.IsValid() || !v.ValueY.IsValid(): - return false // Both values must be valid - case v.NumIgnored > 0: - return false // Some ignore option was used - case v.NumTransformed > 0: - return false // Some transform option was used - case v.NumCompared > 1: - return false // More than one comparison was used - case v.NumCompared == 1 && v.Type.Name() != "": - // The need for cmp to check applicability of options on every element - // in a slice is a significant performance detriment for large []byte. - // The workaround is to specify Comparer(bytes.Equal), - // which enables cmp to compare []byte more efficiently. - // If they differ, we still want to provide batched diffing. - // The logic disallows named types since they tend to have their own - // String method, with nicer formatting than what this provides. - return false - } - - // Check whether this is an interface with the same concrete types. - t := v.Type - vx, vy := v.ValueX, v.ValueY - if t.Kind() == reflect.Interface && !vx.IsNil() && !vy.IsNil() && vx.Elem().Type() == vy.Elem().Type() { - vx, vy = vx.Elem(), vy.Elem() - t = vx.Type() - } - - // Check whether we provide specialized diffing for this type. - switch t.Kind() { - case reflect.String: - case reflect.Array, reflect.Slice: - // Only slices of primitive types have specialized handling. - switch t.Elem().Kind() { - 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: - default: - return false - } - - // Both slice values have to be non-empty. - if t.Kind() == reflect.Slice && (vx.Len() == 0 || vy.Len() == 0) { - return false - } - - // If a sufficient number of elements already differ, - // use specialized formatting even if length requirement is not met. - if v.NumDiff > v.NumSame { - return true - } - default: - return false - } - - // Use specialized string diffing for longer slices or strings. - const minLength = 32 - return vx.Len() >= minLength && vy.Len() >= minLength -} - -// FormatDiffSlice prints a diff for the slices (or strings) represented by v. -// This provides custom-tailored logic to make printing of differences in -// textual strings and slices of primitive kinds more readable. -func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode { - assert(opts.DiffMode == diffUnknown) - t, vx, vy := v.Type, v.ValueX, v.ValueY - if t.Kind() == reflect.Interface { - vx, vy = vx.Elem(), vy.Elem() - t = vx.Type() - opts = opts.WithTypeMode(emitType) - } - - // Auto-detect the type of the data. - var sx, sy string - var ssx, ssy []string - var isString, isMostlyText, isPureLinedText, isBinary bool - switch { - case t.Kind() == reflect.String: - sx, sy = vx.String(), vy.String() - isString = true - case t.Kind() == reflect.Slice && t.Elem() == byteType: - sx, sy = string(vx.Bytes()), string(vy.Bytes()) - isString = true - case t.Kind() == reflect.Array: - // Arrays need to be addressable for slice operations to work. - vx2, vy2 := reflect.New(t).Elem(), reflect.New(t).Elem() - vx2.Set(vx) - vy2.Set(vy) - vx, vy = vx2, vy2 - } - if isString { - var numTotalRunes, numValidRunes, numLines, lastLineIdx, maxLineLen int - for i, r := range sx + sy { - numTotalRunes++ - if (unicode.IsPrint(r) || unicode.IsSpace(r)) && r != utf8.RuneError { - numValidRunes++ - } - if r == '\n' { - if maxLineLen < i-lastLineIdx { - maxLineLen = i - lastLineIdx - } - lastLineIdx = i + 1 - numLines++ - } - } - isPureText := numValidRunes == numTotalRunes - isMostlyText = float64(numValidRunes) > math.Floor(0.90*float64(numTotalRunes)) - isPureLinedText = isPureText && numLines >= 4 && maxLineLen <= 1024 - isBinary = !isMostlyText - - // Avoid diffing by lines if it produces a significantly more complex - // edit script than diffing by bytes. - if isPureLinedText { - ssx = strings.Split(sx, "\n") - ssy = strings.Split(sy, "\n") - esLines := diff.Difference(len(ssx), len(ssy), func(ix, iy int) diff.Result { - return diff.BoolResult(ssx[ix] == ssy[iy]) - }) - esBytes := diff.Difference(len(sx), len(sy), func(ix, iy int) diff.Result { - return diff.BoolResult(sx[ix] == sy[iy]) - }) - efficiencyLines := float64(esLines.Dist()) / float64(len(esLines)) - efficiencyBytes := float64(esBytes.Dist()) / float64(len(esBytes)) - quotedLength := len(strconv.Quote(sx + sy)) - unquotedLength := len(sx) + len(sy) - escapeExpansionRatio := float64(quotedLength) / float64(unquotedLength) - isPureLinedText = efficiencyLines < 4*efficiencyBytes || escapeExpansionRatio > 1.1 - } - } - - // Format the string into printable records. - var list textList - var delim string - switch { - // If the text appears to be multi-lined text, - // then perform differencing across individual lines. - case isPureLinedText: - list = opts.formatDiffSlice( - reflect.ValueOf(ssx), reflect.ValueOf(ssy), 1, "line", - func(v reflect.Value, d diffMode) textRecord { - s := formatString(v.Index(0).String()) - return textRecord{Diff: d, Value: textLine(s)} - }, - ) - delim = "\n" - - // If possible, use a custom triple-quote (""") syntax for printing - // differences in a string literal. This format is more readable, - // but has edge-cases where differences are visually indistinguishable. - // This format is avoided under the following conditions: - // - A line starts with `"""` - // - A line starts with "..." - // - A line contains non-printable characters - // - Adjacent different lines differ only by whitespace - // - // For example: - // - // """ - // ... // 3 identical lines - // foo - // bar - // - baz - // + BAZ - // """ - isTripleQuoted := true - prevRemoveLines := map[string]bool{} - prevInsertLines := map[string]bool{} - var list2 textList - list2 = append(list2, textRecord{Value: textLine(`"""`), ElideComma: true}) - for _, r := range list { - if !r.Value.Equal(textEllipsis) { - line, _ := strconv.Unquote(string(r.Value.(textLine))) - line = strings.TrimPrefix(strings.TrimSuffix(line, "\r"), "\r") // trim leading/trailing carriage returns for legacy Windows endline support - normLine := strings.Map(func(r rune) rune { - if unicode.IsSpace(r) { - return -1 // drop whitespace to avoid visually indistinguishable output - } - return r - }, line) - isPrintable := func(r rune) bool { - return unicode.IsPrint(r) || r == '\t' // specially treat tab as printable - } - isTripleQuoted = !strings.HasPrefix(line, `"""`) && !strings.HasPrefix(line, "...") && strings.TrimFunc(line, isPrintable) == "" - switch r.Diff { - case diffRemoved: - isTripleQuoted = isTripleQuoted && !prevInsertLines[normLine] - prevRemoveLines[normLine] = true - case diffInserted: - isTripleQuoted = isTripleQuoted && !prevRemoveLines[normLine] - prevInsertLines[normLine] = true - } - if !isTripleQuoted { - break - } - r.Value = textLine(line) - r.ElideComma = true - } - if !(r.Diff == diffRemoved || r.Diff == diffInserted) { // start a new non-adjacent difference group - prevRemoveLines = map[string]bool{} - prevInsertLines = map[string]bool{} - } - list2 = append(list2, r) - } - if r := list2[len(list2)-1]; r.Diff == diffIdentical && len(r.Value.(textLine)) == 0 { - list2 = list2[:len(list2)-1] // elide single empty line at the end - } - list2 = append(list2, textRecord{Value: textLine(`"""`), ElideComma: true}) - if isTripleQuoted { - var out textNode = &textWrap{Prefix: "(", Value: list2, Suffix: ")"} - switch t.Kind() { - case reflect.String: - if t != stringType { - out = opts.FormatType(t, out) - } - case reflect.Slice: - // Always emit type for slices since the triple-quote syntax - // looks like a string (not a slice). - opts = opts.WithTypeMode(emitType) - out = opts.FormatType(t, out) - } - return out - } - - // If the text appears to be single-lined text, - // then perform differencing in approximately fixed-sized chunks. - // The output is printed as quoted strings. - case isMostlyText: - list = opts.formatDiffSlice( - reflect.ValueOf(sx), reflect.ValueOf(sy), 64, "byte", - func(v reflect.Value, d diffMode) textRecord { - s := formatString(v.String()) - return textRecord{Diff: d, Value: textLine(s)} - }, - ) - - // If the text appears to be binary data, - // then perform differencing in approximately fixed-sized chunks. - // The output is inspired by hexdump. - case isBinary: - list = opts.formatDiffSlice( - reflect.ValueOf(sx), reflect.ValueOf(sy), 16, "byte", - func(v reflect.Value, d diffMode) textRecord { - var ss []string - for i := 0; i < v.Len(); i++ { - ss = append(ss, formatHex(v.Index(i).Uint())) - } - s := strings.Join(ss, ", ") - comment := commentString(fmt.Sprintf("%c|%v|", d, formatASCII(v.String()))) - return textRecord{Diff: d, Value: textLine(s), Comment: comment} - }, - ) - - // For all other slices of primitive types, - // then perform differencing in approximately fixed-sized chunks. - // The size of each chunk depends on the width of the element kind. - default: - var chunkSize int - if t.Elem().Kind() == reflect.Bool { - chunkSize = 16 - } else { - switch t.Elem().Bits() { - case 8: - chunkSize = 16 - case 16: - chunkSize = 12 - case 32: - chunkSize = 8 - default: - chunkSize = 8 - } - } - list = opts.formatDiffSlice( - vx, vy, chunkSize, t.Elem().Kind().String(), - func(v reflect.Value, d diffMode) textRecord { - var ss []string - for i := 0; i < v.Len(); i++ { - switch t.Elem().Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - ss = append(ss, fmt.Sprint(v.Index(i).Int())) - case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: - ss = append(ss, fmt.Sprint(v.Index(i).Uint())) - case reflect.Uint8, reflect.Uintptr: - ss = append(ss, formatHex(v.Index(i).Uint())) - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: - ss = append(ss, fmt.Sprint(v.Index(i).Interface())) - } - } - s := strings.Join(ss, ", ") - return textRecord{Diff: d, Value: textLine(s)} - }, - ) - } - - // Wrap the output with appropriate type information. - var out textNode = &textWrap{Prefix: "{", Value: list, Suffix: "}"} - if !isMostlyText { - // The "{...}" byte-sequence literal is not valid Go syntax for strings. - // Emit the type for extra clarity (e.g. "string{...}"). - if t.Kind() == reflect.String { - opts = opts.WithTypeMode(emitType) - } - return opts.FormatType(t, out) - } - switch t.Kind() { - case reflect.String: - out = &textWrap{Prefix: "strings.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} - if t != stringType { - out = opts.FormatType(t, out) - } - case reflect.Slice: - out = &textWrap{Prefix: "bytes.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)} - if t != bytesType { - out = opts.FormatType(t, out) - } - } - return out -} - -// formatASCII formats s as an ASCII string. -// This is useful for printing binary strings in a semi-legible way. -func formatASCII(s string) string { - b := bytes.Repeat([]byte{'.'}, len(s)) - for i := 0; i < len(s); i++ { - if ' ' <= s[i] && s[i] <= '~' { - b[i] = s[i] - } - } - return string(b) -} - -func (opts formatOptions) formatDiffSlice( - vx, vy reflect.Value, chunkSize int, name string, - makeRec func(reflect.Value, diffMode) textRecord, -) (list textList) { - eq := func(ix, iy int) bool { - return vx.Index(ix).Interface() == vy.Index(iy).Interface() - } - es := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result { - return diff.BoolResult(eq(ix, iy)) - }) - - appendChunks := func(v reflect.Value, d diffMode) int { - n0 := v.Len() - for v.Len() > 0 { - n := chunkSize - if n > v.Len() { - n = v.Len() - } - list = append(list, makeRec(v.Slice(0, n), d)) - v = v.Slice(n, v.Len()) - } - return n0 - v.Len() - } - - var numDiffs int - maxLen := -1 - if opts.LimitVerbosity { - maxLen = (1 << opts.verbosity()) << 2 // 4, 8, 16, 32, 64, etc... - opts.VerbosityLevel-- - } - - groups := coalesceAdjacentEdits(name, es) - groups = coalesceInterveningIdentical(groups, chunkSize/4) - groups = cleanupSurroundingIdentical(groups, eq) - maxGroup := diffStats{Name: name} - for i, ds := range groups { - if maxLen >= 0 && numDiffs >= maxLen { - maxGroup = maxGroup.Append(ds) - continue - } - - // Print equal. - if ds.NumDiff() == 0 { - // Compute the number of leading and trailing equal bytes to print. - var numLo, numHi int - numEqual := ds.NumIgnored + ds.NumIdentical - for numLo < chunkSize*numContextRecords && numLo+numHi < numEqual && i != 0 { - numLo++ - } - for numHi < chunkSize*numContextRecords && numLo+numHi < numEqual && i != len(groups)-1 { - numHi++ - } - if numEqual-(numLo+numHi) <= chunkSize && ds.NumIgnored == 0 { - numHi = numEqual - numLo // Avoid pointless coalescing of single equal row - } - - // Print the equal bytes. - appendChunks(vx.Slice(0, numLo), diffIdentical) - if numEqual > numLo+numHi { - ds.NumIdentical -= numLo + numHi - list.AppendEllipsis(ds) - } - appendChunks(vx.Slice(numEqual-numHi, numEqual), diffIdentical) - vx = vx.Slice(numEqual, vx.Len()) - vy = vy.Slice(numEqual, vy.Len()) - continue - } - - // Print unequal. - len0 := len(list) - nx := appendChunks(vx.Slice(0, ds.NumIdentical+ds.NumRemoved+ds.NumModified), diffRemoved) - vx = vx.Slice(nx, vx.Len()) - ny := appendChunks(vy.Slice(0, ds.NumIdentical+ds.NumInserted+ds.NumModified), diffInserted) - vy = vy.Slice(ny, vy.Len()) - numDiffs += len(list) - len0 - } - if maxGroup.IsZero() { - assert(vx.Len() == 0 && vy.Len() == 0) - } else { - list.AppendEllipsis(maxGroup) - } - return list -} - -// coalesceAdjacentEdits coalesces the list of edits into groups of adjacent -// equal or unequal counts. -// -// Example: -// -// Input: "..XXY...Y" -// Output: [ -// {NumIdentical: 2}, -// {NumRemoved: 2, NumInserted 1}, -// {NumIdentical: 3}, -// {NumInserted: 1}, -// ] -func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) { - var prevMode byte - lastStats := func(mode byte) *diffStats { - if prevMode != mode { - groups = append(groups, diffStats{Name: name}) - prevMode = mode - } - return &groups[len(groups)-1] - } - for _, e := range es { - switch e { - case diff.Identity: - lastStats('=').NumIdentical++ - case diff.UniqueX: - lastStats('!').NumRemoved++ - case diff.UniqueY: - lastStats('!').NumInserted++ - case diff.Modified: - lastStats('!').NumModified++ - } - } - return groups -} - -// coalesceInterveningIdentical coalesces sufficiently short (<= windowSize) -// equal groups into adjacent unequal groups that currently result in a -// dual inserted/removed printout. This acts as a high-pass filter to smooth -// out high-frequency changes within the windowSize. -// -// Example: -// -// WindowSize: 16, -// Input: [ -// {NumIdentical: 61}, // group 0 -// {NumRemoved: 3, NumInserted: 1}, // group 1 -// {NumIdentical: 6}, // ├── coalesce -// {NumInserted: 2}, // ├── coalesce -// {NumIdentical: 1}, // ├── coalesce -// {NumRemoved: 9}, // └── coalesce -// {NumIdentical: 64}, // group 2 -// {NumRemoved: 3, NumInserted: 1}, // group 3 -// {NumIdentical: 6}, // ├── coalesce -// {NumInserted: 2}, // ├── coalesce -// {NumIdentical: 1}, // ├── coalesce -// {NumRemoved: 7}, // ├── coalesce -// {NumIdentical: 1}, // ├── coalesce -// {NumRemoved: 2}, // └── coalesce -// {NumIdentical: 63}, // group 4 -// ] -// Output: [ -// {NumIdentical: 61}, -// {NumIdentical: 7, NumRemoved: 12, NumInserted: 3}, -// {NumIdentical: 64}, -// {NumIdentical: 8, NumRemoved: 12, NumInserted: 3}, -// {NumIdentical: 63}, -// ] -func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats { - groups, groupsOrig := groups[:0], groups - for i, ds := range groupsOrig { - if len(groups) >= 2 && ds.NumDiff() > 0 { - prev := &groups[len(groups)-2] // Unequal group - curr := &groups[len(groups)-1] // Equal group - next := &groupsOrig[i] // Unequal group - hadX, hadY := prev.NumRemoved > 0, prev.NumInserted > 0 - hasX, hasY := next.NumRemoved > 0, next.NumInserted > 0 - if ((hadX || hasX) && (hadY || hasY)) && curr.NumIdentical <= windowSize { - *prev = prev.Append(*curr).Append(*next) - groups = groups[:len(groups)-1] // Truncate off equal group - continue - } - } - groups = append(groups, ds) - } - return groups -} - -// cleanupSurroundingIdentical scans through all unequal groups, and -// moves any leading sequence of equal elements to the preceding equal group and -// moves and trailing sequence of equal elements to the succeeding equal group. -// -// This is necessary since coalesceInterveningIdentical may coalesce edit groups -// together such that leading/trailing spans of equal elements becomes possible. -// Note that this can occur even with an optimal diffing algorithm. -// -// Example: -// -// Input: [ -// {NumIdentical: 61}, -// {NumIdentical: 1 , NumRemoved: 11, NumInserted: 2}, // assume 3 leading identical elements -// {NumIdentical: 67}, -// {NumIdentical: 7, NumRemoved: 12, NumInserted: 3}, // assume 10 trailing identical elements -// {NumIdentical: 54}, -// ] -// Output: [ -// {NumIdentical: 64}, // incremented by 3 -// {NumRemoved: 9}, -// {NumIdentical: 67}, -// {NumRemoved: 9}, -// {NumIdentical: 64}, // incremented by 10 -// ] -func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []diffStats { - var ix, iy int // indexes into sequence x and y - for i, ds := range groups { - // Handle equal group. - if ds.NumDiff() == 0 { - ix += ds.NumIdentical - iy += ds.NumIdentical - continue - } - - // Handle unequal group. - nx := ds.NumIdentical + ds.NumRemoved + ds.NumModified - ny := ds.NumIdentical + ds.NumInserted + ds.NumModified - var numLeadingIdentical, numTrailingIdentical int - for j := 0; j < nx && j < ny && eq(ix+j, iy+j); j++ { - numLeadingIdentical++ - } - for j := 0; j < nx && j < ny && eq(ix+nx-1-j, iy+ny-1-j); j++ { - numTrailingIdentical++ - } - if numIdentical := numLeadingIdentical + numTrailingIdentical; numIdentical > 0 { - if numLeadingIdentical > 0 { - // Remove leading identical span from this group and - // insert it into the preceding group. - if i-1 >= 0 { - groups[i-1].NumIdentical += numLeadingIdentical - } else { - // No preceding group exists, so prepend a new group, - // but do so after we finish iterating over all groups. - defer func() { - groups = append([]diffStats{{Name: groups[0].Name, NumIdentical: numLeadingIdentical}}, groups...) - }() - } - // Increment indexes since the preceding group would have handled this. - ix += numLeadingIdentical - iy += numLeadingIdentical - } - if numTrailingIdentical > 0 { - // Remove trailing identical span from this group and - // insert it into the succeeding group. - if i+1 < len(groups) { - groups[i+1].NumIdentical += numTrailingIdentical - } else { - // No succeeding group exists, so append a new group, - // but do so after we finish iterating over all groups. - defer func() { - groups = append(groups, diffStats{Name: groups[len(groups)-1].Name, NumIdentical: numTrailingIdentical}) - }() - } - // Do not increment indexes since the succeeding group will handle this. - } - - // Update this group since some identical elements were removed. - nx -= numIdentical - ny -= numIdentical - groups[i] = diffStats{Name: ds.Name, NumRemoved: nx, NumInserted: ny} - } - ix += nx - iy += ny - } - return groups -} diff --git a/vendor/github.com/google/go-cmp/cmp/report_text.go b/vendor/github.com/google/go-cmp/cmp/report_text.go deleted file mode 100644 index 388fcf571..000000000 --- a/vendor/github.com/google/go-cmp/cmp/report_text.go +++ /dev/null @@ -1,432 +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 cmp - -import ( - "bytes" - "fmt" - "math/rand" - "strings" - "time" - "unicode/utf8" - - "github.com/google/go-cmp/cmp/internal/flags" -) - -var randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0 - -const maxColumnLength = 80 - -type indentMode int - -func (n indentMode) appendIndent(b []byte, d diffMode) []byte { - // The output of Diff is documented as being unstable to provide future - // flexibility in changing the output for more humanly readable reports. - // This logic intentionally introduces instability to the exact output - // so that users can detect accidental reliance on stability early on, - // rather than much later when an actual change to the format occurs. - if flags.Deterministic || randBool { - // Use regular spaces (U+0020). - switch d { - case diffUnknown, diffIdentical: - b = append(b, " "...) - case diffRemoved: - b = append(b, "- "...) - case diffInserted: - b = append(b, "+ "...) - } - } else { - // Use non-breaking spaces (U+00a0). - switch d { - case diffUnknown, diffIdentical: - b = append(b, "  "...) - case diffRemoved: - b = append(b, "- "...) - case diffInserted: - b = append(b, "+ "...) - } - } - return repeatCount(n).appendChar(b, '\t') -} - -type repeatCount int - -func (n repeatCount) appendChar(b []byte, c byte) []byte { - for ; n > 0; n-- { - b = append(b, c) - } - return b -} - -// textNode is a simplified tree-based representation of structured text. -// Possible node types are textWrap, textList, or textLine. -type textNode interface { - // Len reports the length in bytes of a single-line version of the tree. - // Nested textRecord.Diff and textRecord.Comment fields are ignored. - Len() int - // Equal reports whether the two trees are structurally identical. - // Nested textRecord.Diff and textRecord.Comment fields are compared. - Equal(textNode) bool - // String returns the string representation of the text tree. - // It is not guaranteed that len(x.String()) == x.Len(), - // nor that x.String() == y.String() implies that x.Equal(y). - String() string - - // formatCompactTo formats the contents of the tree as a single-line string - // to the provided buffer. Any nested textRecord.Diff and textRecord.Comment - // fields are ignored. - // - // However, not all nodes in the tree should be collapsed as a single-line. - // If a node can be collapsed as a single-line, it is replaced by a textLine - // node. Since the top-level node cannot replace itself, this also returns - // the current node itself. - // - // This does not mutate the receiver. - formatCompactTo([]byte, diffMode) ([]byte, textNode) - // formatExpandedTo formats the contents of the tree as a multi-line string - // to the provided buffer. In order for column alignment to operate well, - // formatCompactTo must be called before calling formatExpandedTo. - formatExpandedTo([]byte, diffMode, indentMode) []byte -} - -// textWrap is a wrapper that concatenates a prefix and/or a suffix -// to the underlying node. -type textWrap struct { - Prefix string // e.g., "bytes.Buffer{" - Value textNode // textWrap | textList | textLine - Suffix string // e.g., "}" - Metadata interface{} // arbitrary metadata; has no effect on formatting -} - -func (s *textWrap) Len() int { - return len(s.Prefix) + s.Value.Len() + len(s.Suffix) -} -func (s1 *textWrap) Equal(s2 textNode) bool { - if s2, ok := s2.(*textWrap); ok { - return s1.Prefix == s2.Prefix && s1.Value.Equal(s2.Value) && s1.Suffix == s2.Suffix - } - return false -} -func (s *textWrap) String() string { - var d diffMode - var n indentMode - _, s2 := s.formatCompactTo(nil, d) - b := n.appendIndent(nil, d) // Leading indent - b = s2.formatExpandedTo(b, d, n) // Main body - b = append(b, '\n') // Trailing newline - return string(b) -} -func (s *textWrap) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) { - n0 := len(b) // Original buffer length - b = append(b, s.Prefix...) - b, s.Value = s.Value.formatCompactTo(b, d) - b = append(b, s.Suffix...) - if _, ok := s.Value.(textLine); ok { - return b, textLine(b[n0:]) - } - return b, s -} -func (s *textWrap) formatExpandedTo(b []byte, d diffMode, n indentMode) []byte { - b = append(b, s.Prefix...) - b = s.Value.formatExpandedTo(b, d, n) - b = append(b, s.Suffix...) - return b -} - -// textList is a comma-separated list of textWrap or textLine nodes. -// The list may be formatted as multi-lines or single-line at the discretion -// of the textList.formatCompactTo method. -type textList []textRecord -type textRecord struct { - Diff diffMode // e.g., 0 or '-' or '+' - Key string // e.g., "MyField" - Value textNode // textWrap | textLine - ElideComma bool // avoid trailing comma - Comment fmt.Stringer // e.g., "6 identical fields" -} - -// AppendEllipsis appends a new ellipsis node to the list if none already -// exists at the end. If cs is non-zero it coalesces the statistics with the -// previous diffStats. -func (s *textList) AppendEllipsis(ds diffStats) { - hasStats := !ds.IsZero() - if len(*s) == 0 || !(*s)[len(*s)-1].Value.Equal(textEllipsis) { - if hasStats { - *s = append(*s, textRecord{Value: textEllipsis, ElideComma: true, Comment: ds}) - } else { - *s = append(*s, textRecord{Value: textEllipsis, ElideComma: true}) - } - return - } - if hasStats { - (*s)[len(*s)-1].Comment = (*s)[len(*s)-1].Comment.(diffStats).Append(ds) - } -} - -func (s textList) Len() (n int) { - for i, r := range s { - n += len(r.Key) - if r.Key != "" { - n += len(": ") - } - n += r.Value.Len() - if i < len(s)-1 { - n += len(", ") - } - } - return n -} - -func (s1 textList) Equal(s2 textNode) bool { - if s2, ok := s2.(textList); ok { - if len(s1) != len(s2) { - return false - } - for i := range s1 { - r1, r2 := s1[i], s2[i] - if !(r1.Diff == r2.Diff && r1.Key == r2.Key && r1.Value.Equal(r2.Value) && r1.Comment == r2.Comment) { - return false - } - } - return true - } - return false -} - -func (s textList) String() string { - return (&textWrap{Prefix: "{", Value: s, Suffix: "}"}).String() -} - -func (s textList) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) { - s = append(textList(nil), s...) // Avoid mutating original - - // Determine whether we can collapse this list as a single line. - n0 := len(b) // Original buffer length - var multiLine bool - for i, r := range s { - if r.Diff == diffInserted || r.Diff == diffRemoved { - multiLine = true - } - b = append(b, r.Key...) - if r.Key != "" { - b = append(b, ": "...) - } - b, s[i].Value = r.Value.formatCompactTo(b, d|r.Diff) - if _, ok := s[i].Value.(textLine); !ok { - multiLine = true - } - if r.Comment != nil { - multiLine = true - } - if i < len(s)-1 { - b = append(b, ", "...) - } - } - // Force multi-lined output when printing a removed/inserted node that - // is sufficiently long. - if (d == diffInserted || d == diffRemoved) && len(b[n0:]) > maxColumnLength { - multiLine = true - } - if !multiLine { - return b, textLine(b[n0:]) - } - return b, s -} - -func (s textList) formatExpandedTo(b []byte, d diffMode, n indentMode) []byte { - alignKeyLens := s.alignLens( - func(r textRecord) bool { - _, isLine := r.Value.(textLine) - return r.Key == "" || !isLine - }, - func(r textRecord) int { return utf8.RuneCountInString(r.Key) }, - ) - alignValueLens := s.alignLens( - func(r textRecord) bool { - _, isLine := r.Value.(textLine) - return !isLine || r.Value.Equal(textEllipsis) || r.Comment == nil - }, - func(r textRecord) int { return utf8.RuneCount(r.Value.(textLine)) }, - ) - - // Format lists of simple lists in a batched form. - // If the list is sequence of only textLine values, - // then batch multiple values on a single line. - var isSimple bool - for _, r := range s { - _, isLine := r.Value.(textLine) - isSimple = r.Diff == 0 && r.Key == "" && isLine && r.Comment == nil - if !isSimple { - break - } - } - if isSimple { - n++ - var batch []byte - emitBatch := func() { - if len(batch) > 0 { - b = n.appendIndent(append(b, '\n'), d) - b = append(b, bytes.TrimRight(batch, " ")...) - batch = batch[:0] - } - } - for _, r := range s { - line := r.Value.(textLine) - if len(batch)+len(line)+len(", ") > maxColumnLength { - emitBatch() - } - batch = append(batch, line...) - batch = append(batch, ", "...) - } - emitBatch() - n-- - return n.appendIndent(append(b, '\n'), d) - } - - // Format the list as a multi-lined output. - n++ - for i, r := range s { - b = n.appendIndent(append(b, '\n'), d|r.Diff) - if r.Key != "" { - b = append(b, r.Key+": "...) - } - b = alignKeyLens[i].appendChar(b, ' ') - - b = r.Value.formatExpandedTo(b, d|r.Diff, n) - if !r.ElideComma { - b = append(b, ',') - } - b = alignValueLens[i].appendChar(b, ' ') - - if r.Comment != nil { - b = append(b, " // "+r.Comment.String()...) - } - } - n-- - - return n.appendIndent(append(b, '\n'), d) -} - -func (s textList) alignLens( - skipFunc func(textRecord) bool, - lenFunc func(textRecord) int, -) []repeatCount { - var startIdx, endIdx, maxLen int - lens := make([]repeatCount, len(s)) - for i, r := range s { - if skipFunc(r) { - for j := startIdx; j < endIdx && j < len(s); j++ { - lens[j] = repeatCount(maxLen - lenFunc(s[j])) - } - startIdx, endIdx, maxLen = i+1, i+1, 0 - } else { - if maxLen < lenFunc(r) { - maxLen = lenFunc(r) - } - endIdx = i + 1 - } - } - for j := startIdx; j < endIdx && j < len(s); j++ { - lens[j] = repeatCount(maxLen - lenFunc(s[j])) - } - return lens -} - -// textLine is a single-line segment of text and is always a leaf node -// in the textNode tree. -type textLine []byte - -var ( - textNil = textLine("nil") - textEllipsis = textLine("...") -) - -func (s textLine) Len() int { - return len(s) -} -func (s1 textLine) Equal(s2 textNode) bool { - if s2, ok := s2.(textLine); ok { - return bytes.Equal([]byte(s1), []byte(s2)) - } - return false -} -func (s textLine) String() string { - return string(s) -} -func (s textLine) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) { - return append(b, s...), s -} -func (s textLine) formatExpandedTo(b []byte, _ diffMode, _ indentMode) []byte { - return append(b, s...) -} - -type diffStats struct { - Name string - NumIgnored int - NumIdentical int - NumRemoved int - NumInserted int - NumModified int -} - -func (s diffStats) IsZero() bool { - s.Name = "" - return s == diffStats{} -} - -func (s diffStats) NumDiff() int { - return s.NumRemoved + s.NumInserted + s.NumModified -} - -func (s diffStats) Append(ds diffStats) diffStats { - assert(s.Name == ds.Name) - s.NumIgnored += ds.NumIgnored - s.NumIdentical += ds.NumIdentical - s.NumRemoved += ds.NumRemoved - s.NumInserted += ds.NumInserted - s.NumModified += ds.NumModified - return s -} - -// String prints a humanly-readable summary of coalesced records. -// -// Example: -// -// diffStats{Name: "Field", NumIgnored: 5}.String() => "5 ignored fields" -func (s diffStats) String() string { - var ss []string - var sum int - labels := [...]string{"ignored", "identical", "removed", "inserted", "modified"} - counts := [...]int{s.NumIgnored, s.NumIdentical, s.NumRemoved, s.NumInserted, s.NumModified} - for i, n := range counts { - if n > 0 { - ss = append(ss, fmt.Sprintf("%d %v", n, labels[i])) - } - sum += n - } - - // Pluralize the name (adjusting for some obscure English grammar rules). - name := s.Name - if sum > 1 { - name += "s" - if strings.HasSuffix(name, "ys") { - name = name[:len(name)-2] + "ies" // e.g., "entrys" => "entries" - } - } - - // Format the list according to English grammar (with Oxford comma). - switch n := len(ss); n { - case 0: - return "" - case 1, 2: - return strings.Join(ss, " and ") + " " + name - default: - return strings.Join(ss[:n-1], ", ") + ", and " + ss[n-1] + " " + name - } -} - -type commentString string - -func (s commentString) String() string { return string(s) } diff --git a/vendor/github.com/google/go-cmp/cmp/report_value.go b/vendor/github.com/google/go-cmp/cmp/report_value.go deleted file mode 100644 index 668d470fd..000000000 --- a/vendor/github.com/google/go-cmp/cmp/report_value.go +++ /dev/null @@ -1,121 +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 cmp - -import "reflect" - -// valueNode represents a single node within a report, which is a -// structured representation of the value tree, containing information -// regarding which nodes are equal or not. -type valueNode struct { - parent *valueNode - - Type reflect.Type - ValueX reflect.Value - ValueY reflect.Value - - // NumSame is the number of leaf nodes that are equal. - // All descendants are equal only if NumDiff is 0. - NumSame int - // NumDiff is the number of leaf nodes that are not equal. - NumDiff int - // NumIgnored is the number of leaf nodes that are ignored. - NumIgnored int - // NumCompared is the number of leaf nodes that were compared - // using an Equal method or Comparer function. - NumCompared int - // NumTransformed is the number of non-leaf nodes that were transformed. - NumTransformed int - // NumChildren is the number of transitive descendants of this node. - // This counts from zero; thus, leaf nodes have no descendants. - NumChildren int - // MaxDepth is the maximum depth of the tree. This counts from zero; - // thus, leaf nodes have a depth of zero. - MaxDepth int - - // Records is a list of struct fields, slice elements, or map entries. - Records []reportRecord // If populated, implies Value is not populated - - // Value is the result of a transformation, pointer indirect, of - // type assertion. - Value *valueNode // If populated, implies Records is not populated - - // TransformerName is the name of the transformer. - TransformerName string // If non-empty, implies Value is populated -} -type reportRecord struct { - Key reflect.Value // Invalid for slice element - Value *valueNode -} - -func (parent *valueNode) PushStep(ps PathStep) (child *valueNode) { - vx, vy := ps.Values() - child = &valueNode{parent: parent, Type: ps.Type(), ValueX: vx, ValueY: vy} - switch s := ps.(type) { - case StructField: - assert(parent.Value == nil) - parent.Records = append(parent.Records, reportRecord{Key: reflect.ValueOf(s.Name()), Value: child}) - case SliceIndex: - assert(parent.Value == nil) - parent.Records = append(parent.Records, reportRecord{Value: child}) - case MapIndex: - assert(parent.Value == nil) - parent.Records = append(parent.Records, reportRecord{Key: s.Key(), Value: child}) - case Indirect: - assert(parent.Value == nil && parent.Records == nil) - parent.Value = child - case TypeAssertion: - assert(parent.Value == nil && parent.Records == nil) - parent.Value = child - case Transform: - assert(parent.Value == nil && parent.Records == nil) - parent.Value = child - parent.TransformerName = s.Name() - parent.NumTransformed++ - default: - assert(parent == nil) // Must be the root step - } - return child -} - -func (r *valueNode) Report(rs Result) { - assert(r.MaxDepth == 0) // May only be called on leaf nodes - - if rs.ByIgnore() { - r.NumIgnored++ - } else { - if rs.Equal() { - r.NumSame++ - } else { - r.NumDiff++ - } - } - assert(r.NumSame+r.NumDiff+r.NumIgnored == 1) - - if rs.ByMethod() { - r.NumCompared++ - } - if rs.ByFunc() { - r.NumCompared++ - } - assert(r.NumCompared <= 1) -} - -func (child *valueNode) PopStep() (parent *valueNode) { - if child.parent == nil { - return nil - } - parent = child.parent - parent.NumSame += child.NumSame - parent.NumDiff += child.NumDiff - parent.NumIgnored += child.NumIgnored - parent.NumCompared += child.NumCompared - parent.NumTransformed += child.NumTransformed - parent.NumChildren += child.NumChildren + 1 - if parent.MaxDepth < child.MaxDepth+1 { - parent.MaxDepth = child.MaxDepth + 1 - } - return parent -} diff --git a/vendor/github.com/google/uuid/CHANGELOG.md b/vendor/github.com/google/uuid/CHANGELOG.md deleted file mode 100644 index 7ec5ac7ea..000000000 --- a/vendor/github.com/google/uuid/CHANGELOG.md +++ /dev/null @@ -1,41 +0,0 @@ -# Changelog - -## [1.6.0](https://github.com/google/uuid/compare/v1.5.0...v1.6.0) (2024-01-16) - - -### Features - -* add Max UUID constant ([#149](https://github.com/google/uuid/issues/149)) ([c58770e](https://github.com/google/uuid/commit/c58770eb495f55fe2ced6284f93c5158a62e53e3)) - - -### Bug Fixes - -* fix typo in version 7 uuid documentation ([#153](https://github.com/google/uuid/issues/153)) ([016b199](https://github.com/google/uuid/commit/016b199544692f745ffc8867b914129ecb47ef06)) -* Monotonicity in UUIDv7 ([#150](https://github.com/google/uuid/issues/150)) ([a2b2b32](https://github.com/google/uuid/commit/a2b2b32373ff0b1a312b7fdf6d38a977099698a6)) - -## [1.5.0](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) (2023-12-12) - - -### Features - -* Validate UUID without creating new UUID ([#141](https://github.com/google/uuid/issues/141)) ([9ee7366](https://github.com/google/uuid/commit/9ee7366e66c9ad96bab89139418a713dc584ae29)) - -## [1.4.0](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) (2023-10-26) - - -### Features - -* UUIDs slice type with Strings() convenience method ([#133](https://github.com/google/uuid/issues/133)) ([cd5fbbd](https://github.com/google/uuid/commit/cd5fbbdd02f3e3467ac18940e07e062be1f864b4)) - -### Fixes - -* Clarify that Parse's job is to parse but not necessarily validate strings. (Documents current behavior) - -## [1.3.1](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) (2023-08-18) - - -### Bug Fixes - -* Use .EqualFold() to parse urn prefixed UUIDs ([#118](https://github.com/google/uuid/issues/118)) ([574e687](https://github.com/google/uuid/commit/574e6874943741fb99d41764c705173ada5293f0)) - -## Changelog diff --git a/vendor/github.com/google/uuid/CONTRIBUTING.md b/vendor/github.com/google/uuid/CONTRIBUTING.md deleted file mode 100644 index a502fdc51..000000000 --- a/vendor/github.com/google/uuid/CONTRIBUTING.md +++ /dev/null @@ -1,26 +0,0 @@ -# How to contribute - -We definitely welcome patches and contribution to this project! - -### Tips - -Commits must be formatted according to the [Conventional Commits Specification](https://www.conventionalcommits.org). - -Always try to include a test case! If it is not possible or not necessary, -please explain why in the pull request description. - -### Releasing - -Commits that would precipitate a SemVer change, as described in the Conventional -Commits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action) -to create a release candidate pull request. Once submitted, `release-please` -will create a release. - -For tips on how to work with `release-please`, see its documentation. - -### Legal requirements - -In order to protect both you and ourselves, you will need to sign the -[Contributor License Agreement](https://cla.developers.google.com/clas). - -You may have already signed it for other Google projects. diff --git a/vendor/github.com/google/uuid/CONTRIBUTORS b/vendor/github.com/google/uuid/CONTRIBUTORS deleted file mode 100644 index b4bb97f6b..000000000 --- a/vendor/github.com/google/uuid/CONTRIBUTORS +++ /dev/null @@ -1,9 +0,0 @@ -Paul Borman -bmatsuo -shawnps -theory -jboverfelt -dsymonds -cd1 -wallclockbuilder -dansouza diff --git a/vendor/github.com/google/uuid/LICENSE b/vendor/github.com/google/uuid/LICENSE deleted file mode 100644 index 5dc68268d..000000000 --- a/vendor/github.com/google/uuid/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009,2014 Google Inc. 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/google/uuid/README.md b/vendor/github.com/google/uuid/README.md deleted file mode 100644 index 3e9a61889..000000000 --- a/vendor/github.com/google/uuid/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# uuid -The uuid package generates and inspects UUIDs based on -[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) -and DCE 1.1: Authentication and Security Services. - -This package is based on the github.com/pborman/uuid package (previously named -code.google.com/p/go-uuid). It differs from these earlier packages in that -a UUID is a 16 byte array rather than a byte slice. One loss due to this -change is the ability to represent an invalid UUID (vs a NIL UUID). - -###### Install -```sh -go get github.com/google/uuid -``` - -###### Documentation -[![Go Reference](https://pkg.go.dev/badge/github.com/google/uuid.svg)](https://pkg.go.dev/github.com/google/uuid) - -Full `go doc` style documentation for the package can be viewed online without -installing this package by using the GoDoc site here: -http://pkg.go.dev/github.com/google/uuid diff --git a/vendor/github.com/google/uuid/dce.go b/vendor/github.com/google/uuid/dce.go deleted file mode 100644 index fa820b9d3..000000000 --- a/vendor/github.com/google/uuid/dce.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "encoding/binary" - "fmt" - "os" -) - -// A Domain represents a Version 2 domain -type Domain byte - -// Domain constants for DCE Security (Version 2) UUIDs. -const ( - Person = Domain(0) - Group = Domain(1) - Org = Domain(2) -) - -// NewDCESecurity returns a DCE Security (Version 2) UUID. -// -// The domain should be one of Person, Group or Org. -// On a POSIX system the id should be the users UID for the Person -// domain and the users GID for the Group. The meaning of id for -// the domain Org or on non-POSIX systems is site defined. -// -// For a given domain/id pair the same token may be returned for up to -// 7 minutes and 10 seconds. -func NewDCESecurity(domain Domain, id uint32) (UUID, error) { - uuid, err := NewUUID() - if err == nil { - uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2 - uuid[9] = byte(domain) - binary.BigEndian.PutUint32(uuid[0:], id) - } - return uuid, err -} - -// NewDCEPerson returns a DCE Security (Version 2) UUID in the person -// domain with the id returned by os.Getuid. -// -// NewDCESecurity(Person, uint32(os.Getuid())) -func NewDCEPerson() (UUID, error) { - return NewDCESecurity(Person, uint32(os.Getuid())) -} - -// NewDCEGroup returns a DCE Security (Version 2) UUID in the group -// domain with the id returned by os.Getgid. -// -// NewDCESecurity(Group, uint32(os.Getgid())) -func NewDCEGroup() (UUID, error) { - return NewDCESecurity(Group, uint32(os.Getgid())) -} - -// Domain returns the domain for a Version 2 UUID. Domains are only defined -// for Version 2 UUIDs. -func (uuid UUID) Domain() Domain { - return Domain(uuid[9]) -} - -// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2 -// UUIDs. -func (uuid UUID) ID() uint32 { - return binary.BigEndian.Uint32(uuid[0:4]) -} - -func (d Domain) String() string { - switch d { - case Person: - return "Person" - case Group: - return "Group" - case Org: - return "Org" - } - return fmt.Sprintf("Domain%d", int(d)) -} diff --git a/vendor/github.com/google/uuid/doc.go b/vendor/github.com/google/uuid/doc.go deleted file mode 100644 index 5b8a4b9af..000000000 --- a/vendor/github.com/google/uuid/doc.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package uuid generates and inspects UUIDs. -// -// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security -// Services. -// -// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to -// maps or compared directly. -package uuid diff --git a/vendor/github.com/google/uuid/hash.go b/vendor/github.com/google/uuid/hash.go deleted file mode 100644 index dc60082d3..000000000 --- a/vendor/github.com/google/uuid/hash.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "crypto/md5" - "crypto/sha1" - "hash" -) - -// Well known namespace IDs and UUIDs -var ( - NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) - NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) - NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) - NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) - Nil UUID // empty UUID, all zeros - - // The Max UUID is special form of UUID that is specified to have all 128 bits set to 1. - Max = UUID{ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - } -) - -// NewHash returns a new UUID derived from the hash of space concatenated with -// data generated by h. The hash should be at least 16 byte in length. The -// first 16 bytes of the hash are used to form the UUID. The version of the -// UUID will be the lower 4 bits of version. NewHash is used to implement -// NewMD5 and NewSHA1. -func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { - h.Reset() - h.Write(space[:]) //nolint:errcheck - h.Write(data) //nolint:errcheck - s := h.Sum(nil) - var uuid UUID - copy(uuid[:], s) - uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) - uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant - return uuid -} - -// NewMD5 returns a new MD5 (Version 3) UUID based on the -// supplied name space and data. It is the same as calling: -// -// NewHash(md5.New(), space, data, 3) -func NewMD5(space UUID, data []byte) UUID { - return NewHash(md5.New(), space, data, 3) -} - -// NewSHA1 returns a new SHA1 (Version 5) UUID based on the -// supplied name space and data. It is the same as calling: -// -// NewHash(sha1.New(), space, data, 5) -func NewSHA1(space UUID, data []byte) UUID { - return NewHash(sha1.New(), space, data, 5) -} diff --git a/vendor/github.com/google/uuid/marshal.go b/vendor/github.com/google/uuid/marshal.go deleted file mode 100644 index 14bd34072..000000000 --- a/vendor/github.com/google/uuid/marshal.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import "fmt" - -// MarshalText implements encoding.TextMarshaler. -func (uuid UUID) MarshalText() ([]byte, error) { - var js [36]byte - encodeHex(js[:], uuid) - return js[:], nil -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (uuid *UUID) UnmarshalText(data []byte) error { - id, err := ParseBytes(data) - if err != nil { - return err - } - *uuid = id - return nil -} - -// MarshalBinary implements encoding.BinaryMarshaler. -func (uuid UUID) MarshalBinary() ([]byte, error) { - return uuid[:], nil -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler. -func (uuid *UUID) UnmarshalBinary(data []byte) error { - if len(data) != 16 { - return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) - } - copy(uuid[:], data) - return nil -} diff --git a/vendor/github.com/google/uuid/node.go b/vendor/github.com/google/uuid/node.go deleted file mode 100644 index d651a2b06..000000000 --- a/vendor/github.com/google/uuid/node.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "sync" -) - -var ( - nodeMu sync.Mutex - ifname string // name of interface being used - nodeID [6]byte // hardware for version 1 UUIDs - zeroID [6]byte // nodeID with only 0's -) - -// NodeInterface returns the name of the interface from which the NodeID was -// derived. The interface "user" is returned if the NodeID was set by -// SetNodeID. -func NodeInterface() string { - defer nodeMu.Unlock() - nodeMu.Lock() - return ifname -} - -// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. -// If name is "" then the first usable interface found will be used or a random -// Node ID will be generated. If a named interface cannot be found then false -// is returned. -// -// SetNodeInterface never fails when name is "". -func SetNodeInterface(name string) bool { - defer nodeMu.Unlock() - nodeMu.Lock() - return setNodeInterface(name) -} - -func setNodeInterface(name string) bool { - iname, addr := getHardwareInterface(name) // null implementation for js - if iname != "" && addr != nil { - ifname = iname - copy(nodeID[:], addr) - return true - } - - // We found no interfaces with a valid hardware address. If name - // does not specify a specific interface generate a random Node ID - // (section 4.1.6) - if name == "" { - ifname = "random" - randomBits(nodeID[:]) - return true - } - return false -} - -// NodeID returns a slice of a copy of the current Node ID, setting the Node ID -// if not already set. -func NodeID() []byte { - defer nodeMu.Unlock() - nodeMu.Lock() - if nodeID == zeroID { - setNodeInterface("") - } - nid := nodeID - return nid[:] -} - -// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes -// of id are used. If id is less than 6 bytes then false is returned and the -// Node ID is not set. -func SetNodeID(id []byte) bool { - if len(id) < 6 { - return false - } - defer nodeMu.Unlock() - nodeMu.Lock() - copy(nodeID[:], id) - ifname = "user" - return true -} - -// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is -// not valid. The NodeID is only well defined for version 1 and 2 UUIDs. -func (uuid UUID) NodeID() []byte { - var node [6]byte - copy(node[:], uuid[10:]) - return node[:] -} diff --git a/vendor/github.com/google/uuid/node_js.go b/vendor/github.com/google/uuid/node_js.go deleted file mode 100644 index b2a0bc871..000000000 --- a/vendor/github.com/google/uuid/node_js.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2017 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build js - -package uuid - -// getHardwareInterface returns nil values for the JS version of the code. -// This removes the "net" dependency, because it is not used in the browser. -// Using the "net" library inflates the size of the transpiled JS code by 673k bytes. -func getHardwareInterface(name string) (string, []byte) { return "", nil } diff --git a/vendor/github.com/google/uuid/node_net.go b/vendor/github.com/google/uuid/node_net.go deleted file mode 100644 index 0cbbcddbd..000000000 --- a/vendor/github.com/google/uuid/node_net.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2017 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !js - -package uuid - -import "net" - -var interfaces []net.Interface // cached list of interfaces - -// getHardwareInterface returns the name and hardware address of interface name. -// If name is "" then the name and hardware address of one of the system's -// interfaces is returned. If no interfaces are found (name does not exist or -// there are no interfaces) then "", nil is returned. -// -// Only addresses of at least 6 bytes are returned. -func getHardwareInterface(name string) (string, []byte) { - if interfaces == nil { - var err error - interfaces, err = net.Interfaces() - if err != nil { - return "", nil - } - } - for _, ifs := range interfaces { - if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { - return ifs.Name, ifs.HardwareAddr - } - } - return "", nil -} diff --git a/vendor/github.com/google/uuid/null.go b/vendor/github.com/google/uuid/null.go deleted file mode 100644 index d7fcbf286..000000000 --- a/vendor/github.com/google/uuid/null.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2021 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "bytes" - "database/sql/driver" - "encoding/json" - "fmt" -) - -var jsonNull = []byte("null") - -// NullUUID represents a UUID that may be null. -// NullUUID implements the SQL driver.Scanner interface so -// it can be used as a scan destination: -// -// var u uuid.NullUUID -// err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&u) -// ... -// if u.Valid { -// // use u.UUID -// } else { -// // NULL value -// } -// -type NullUUID struct { - UUID UUID - Valid bool // Valid is true if UUID is not NULL -} - -// Scan implements the SQL driver.Scanner interface. -func (nu *NullUUID) Scan(value interface{}) error { - if value == nil { - nu.UUID, nu.Valid = Nil, false - return nil - } - - err := nu.UUID.Scan(value) - if err != nil { - nu.Valid = false - return err - } - - nu.Valid = true - return nil -} - -// Value implements the driver Valuer interface. -func (nu NullUUID) Value() (driver.Value, error) { - if !nu.Valid { - return nil, nil - } - // Delegate to UUID Value function - return nu.UUID.Value() -} - -// MarshalBinary implements encoding.BinaryMarshaler. -func (nu NullUUID) MarshalBinary() ([]byte, error) { - if nu.Valid { - return nu.UUID[:], nil - } - - return []byte(nil), nil -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler. -func (nu *NullUUID) UnmarshalBinary(data []byte) error { - if len(data) != 16 { - return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) - } - copy(nu.UUID[:], data) - nu.Valid = true - return nil -} - -// MarshalText implements encoding.TextMarshaler. -func (nu NullUUID) MarshalText() ([]byte, error) { - if nu.Valid { - return nu.UUID.MarshalText() - } - - return jsonNull, nil -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (nu *NullUUID) UnmarshalText(data []byte) error { - id, err := ParseBytes(data) - if err != nil { - nu.Valid = false - return err - } - nu.UUID = id - nu.Valid = true - return nil -} - -// MarshalJSON implements json.Marshaler. -func (nu NullUUID) MarshalJSON() ([]byte, error) { - if nu.Valid { - return json.Marshal(nu.UUID) - } - - return jsonNull, nil -} - -// UnmarshalJSON implements json.Unmarshaler. -func (nu *NullUUID) UnmarshalJSON(data []byte) error { - if bytes.Equal(data, jsonNull) { - *nu = NullUUID{} - return nil // valid null UUID - } - err := json.Unmarshal(data, &nu.UUID) - nu.Valid = err == nil - return err -} diff --git a/vendor/github.com/google/uuid/sql.go b/vendor/github.com/google/uuid/sql.go deleted file mode 100644 index 2e02ec06c..000000000 --- a/vendor/github.com/google/uuid/sql.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "database/sql/driver" - "fmt" -) - -// Scan implements sql.Scanner so UUIDs can be read from databases transparently. -// Currently, database types that map to string and []byte are supported. Please -// consult database-specific driver documentation for matching types. -func (uuid *UUID) Scan(src interface{}) error { - switch src := src.(type) { - case nil: - return nil - - case string: - // if an empty UUID comes from a table, we return a null UUID - if src == "" { - return nil - } - - // see Parse for required string format - u, err := Parse(src) - if err != nil { - return fmt.Errorf("Scan: %v", err) - } - - *uuid = u - - case []byte: - // if an empty UUID comes from a table, we return a null UUID - if len(src) == 0 { - return nil - } - - // assumes a simple slice of bytes if 16 bytes - // otherwise attempts to parse - if len(src) != 16 { - return uuid.Scan(string(src)) - } - copy((*uuid)[:], src) - - default: - return fmt.Errorf("Scan: unable to scan type %T into UUID", src) - } - - return nil -} - -// Value implements sql.Valuer so that UUIDs can be written to databases -// transparently. Currently, UUIDs map to strings. Please consult -// database-specific driver documentation for matching types. -func (uuid UUID) Value() (driver.Value, error) { - return uuid.String(), nil -} diff --git a/vendor/github.com/google/uuid/time.go b/vendor/github.com/google/uuid/time.go deleted file mode 100644 index c35112927..000000000 --- a/vendor/github.com/google/uuid/time.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "encoding/binary" - "sync" - "time" -) - -// A Time represents a time as the number of 100's of nanoseconds since 15 Oct -// 1582. -type Time int64 - -const ( - lillian = 2299160 // Julian day of 15 Oct 1582 - unix = 2440587 // Julian day of 1 Jan 1970 - epoch = unix - lillian // Days between epochs - g1582 = epoch * 86400 // seconds between epochs - g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs -) - -var ( - timeMu sync.Mutex - lasttime uint64 // last time we returned - clockSeq uint16 // clock sequence for this run - - timeNow = time.Now // for testing -) - -// UnixTime converts t the number of seconds and nanoseconds using the Unix -// epoch of 1 Jan 1970. -func (t Time) UnixTime() (sec, nsec int64) { - sec = int64(t - g1582ns100) - nsec = (sec % 10000000) * 100 - sec /= 10000000 - return sec, nsec -} - -// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and -// clock sequence as well as adjusting the clock sequence as needed. An error -// is returned if the current time cannot be determined. -func GetTime() (Time, uint16, error) { - defer timeMu.Unlock() - timeMu.Lock() - return getTime() -} - -func getTime() (Time, uint16, error) { - t := timeNow() - - // If we don't have a clock sequence already, set one. - if clockSeq == 0 { - setClockSequence(-1) - } - now := uint64(t.UnixNano()/100) + g1582ns100 - - // If time has gone backwards with this clock sequence then we - // increment the clock sequence - if now <= lasttime { - clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000 - } - lasttime = now - return Time(now), clockSeq, nil -} - -// ClockSequence returns the current clock sequence, generating one if not -// already set. The clock sequence is only used for Version 1 UUIDs. -// -// The uuid package does not use global static storage for the clock sequence or -// the last time a UUID was generated. Unless SetClockSequence is used, a new -// random clock sequence is generated the first time a clock sequence is -// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) -func ClockSequence() int { - defer timeMu.Unlock() - timeMu.Lock() - return clockSequence() -} - -func clockSequence() int { - if clockSeq == 0 { - setClockSequence(-1) - } - return int(clockSeq & 0x3fff) -} - -// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to -// -1 causes a new sequence to be generated. -func SetClockSequence(seq int) { - defer timeMu.Unlock() - timeMu.Lock() - setClockSequence(seq) -} - -func setClockSequence(seq int) { - if seq == -1 { - var b [2]byte - randomBits(b[:]) // clock sequence - seq = int(b[0])<<8 | int(b[1]) - } - oldSeq := clockSeq - clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant - if oldSeq != clockSeq { - lasttime = 0 - } -} - -// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in -// uuid. The time is only defined for version 1, 2, 6 and 7 UUIDs. -func (uuid UUID) Time() Time { - var t Time - switch uuid.Version() { - case 6: - time := binary.BigEndian.Uint64(uuid[:8]) // Ignore uuid[6] version b0110 - t = Time(time) - case 7: - time := binary.BigEndian.Uint64(uuid[:8]) - t = Time((time>>16)*10000 + g1582ns100) - default: // forward compatible - time := int64(binary.BigEndian.Uint32(uuid[0:4])) - time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 - time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 - t = Time(time) - } - return t -} - -// ClockSequence returns the clock sequence encoded in uuid. -// The clock sequence is only well defined for version 1 and 2 UUIDs. -func (uuid UUID) ClockSequence() int { - return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff -} diff --git a/vendor/github.com/google/uuid/util.go b/vendor/github.com/google/uuid/util.go deleted file mode 100644 index 5ea6c7378..000000000 --- a/vendor/github.com/google/uuid/util.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "io" -) - -// randomBits completely fills slice b with random data. -func randomBits(b []byte) { - if _, err := io.ReadFull(rander, b); err != nil { - panic(err.Error()) // rand should never fail - } -} - -// xvalues returns the value of a byte as a hexadecimal digit or 255. -var xvalues = [256]byte{ - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -} - -// xtob converts hex characters x1 and x2 into a byte. -func xtob(x1, x2 byte) (byte, bool) { - b1 := xvalues[x1] - b2 := xvalues[x2] - return (b1 << 4) | b2, b1 != 255 && b2 != 255 -} diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go deleted file mode 100644 index 5232b4867..000000000 --- a/vendor/github.com/google/uuid/uuid.go +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright 2018 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "bytes" - "crypto/rand" - "encoding/hex" - "errors" - "fmt" - "io" - "strings" - "sync" -) - -// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC -// 4122. -type UUID [16]byte - -// A Version represents a UUID's version. -type Version byte - -// A Variant represents a UUID's variant. -type Variant byte - -// Constants returned by Variant. -const ( - Invalid = Variant(iota) // Invalid UUID - RFC4122 // The variant specified in RFC4122 - Reserved // Reserved, NCS backward compatibility. - Microsoft // Reserved, Microsoft Corporation backward compatibility. - Future // Reserved for future definition. -) - -const randPoolSize = 16 * 16 - -var ( - rander = rand.Reader // random function - poolEnabled = false - poolMu sync.Mutex - poolPos = randPoolSize // protected with poolMu - pool [randPoolSize]byte // protected with poolMu -) - -type invalidLengthError struct{ len int } - -func (err invalidLengthError) Error() string { - return fmt.Sprintf("invalid UUID length: %d", err.len) -} - -// IsInvalidLengthError is matcher function for custom error invalidLengthError -func IsInvalidLengthError(err error) bool { - _, ok := err.(invalidLengthError) - return ok -} - -// Parse decodes s into a UUID or returns an error if it cannot be parsed. Both -// the standard UUID forms defined in RFC 4122 -// (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) are decoded. In addition, -// Parse accepts non-standard strings such as the raw hex encoding -// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx and 38 byte "Microsoft style" encodings, -// e.g. {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. Only the middle 36 bytes are -// examined in the latter case. Parse should not be used to validate strings as -// it parses non-standard encodings as indicated above. -func Parse(s string) (UUID, error) { - var uuid UUID - switch len(s) { - // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - case 36: - - // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - case 36 + 9: - if !strings.EqualFold(s[:9], "urn:uuid:") { - return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) - } - s = s[9:] - - // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} - case 36 + 2: - s = s[1:] - - // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - case 32: - var ok bool - for i := range uuid { - uuid[i], ok = xtob(s[i*2], s[i*2+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - } - return uuid, nil - default: - return uuid, invalidLengthError{len(s)} - } - // s is now at least 36 bytes long - // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { - return uuid, errors.New("invalid UUID format") - } - for i, x := range [16]int{ - 0, 2, 4, 6, - 9, 11, - 14, 16, - 19, 21, - 24, 26, 28, 30, 32, 34, - } { - v, ok := xtob(s[x], s[x+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - uuid[i] = v - } - return uuid, nil -} - -// ParseBytes is like Parse, except it parses a byte slice instead of a string. -func ParseBytes(b []byte) (UUID, error) { - var uuid UUID - switch len(b) { - case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if !bytes.EqualFold(b[:9], []byte("urn:uuid:")) { - return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) - } - b = b[9:] - case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} - b = b[1:] - case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - var ok bool - for i := 0; i < 32; i += 2 { - uuid[i/2], ok = xtob(b[i], b[i+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - } - return uuid, nil - default: - return uuid, invalidLengthError{len(b)} - } - // s is now at least 36 bytes long - // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' { - return uuid, errors.New("invalid UUID format") - } - for i, x := range [16]int{ - 0, 2, 4, 6, - 9, 11, - 14, 16, - 19, 21, - 24, 26, 28, 30, 32, 34, - } { - v, ok := xtob(b[x], b[x+1]) - if !ok { - return uuid, errors.New("invalid UUID format") - } - uuid[i] = v - } - return uuid, nil -} - -// MustParse is like Parse but panics if the string cannot be parsed. -// It simplifies safe initialization of global variables holding compiled UUIDs. -func MustParse(s string) UUID { - uuid, err := Parse(s) - if err != nil { - panic(`uuid: Parse(` + s + `): ` + err.Error()) - } - return uuid -} - -// FromBytes creates a new UUID from a byte slice. Returns an error if the slice -// does not have a length of 16. The bytes are copied from the slice. -func FromBytes(b []byte) (uuid UUID, err error) { - err = uuid.UnmarshalBinary(b) - return uuid, err -} - -// Must returns uuid if err is nil and panics otherwise. -func Must(uuid UUID, err error) UUID { - if err != nil { - panic(err) - } - return uuid -} - -// Validate returns an error if s is not a properly formatted UUID in one of the following formats: -// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} -// It returns an error if the format is invalid, otherwise nil. -func Validate(s string) error { - switch len(s) { - // Standard UUID format - case 36: - - // UUID with "urn:uuid:" prefix - case 36 + 9: - if !strings.EqualFold(s[:9], "urn:uuid:") { - return fmt.Errorf("invalid urn prefix: %q", s[:9]) - } - s = s[9:] - - // UUID enclosed in braces - case 36 + 2: - if s[0] != '{' || s[len(s)-1] != '}' { - return fmt.Errorf("invalid bracketed UUID format") - } - s = s[1 : len(s)-1] - - // UUID without hyphens - case 32: - for i := 0; i < len(s); i += 2 { - _, ok := xtob(s[i], s[i+1]) - if !ok { - return errors.New("invalid UUID format") - } - } - - default: - return invalidLengthError{len(s)} - } - - // Check for standard UUID format - if len(s) == 36 { - if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { - return errors.New("invalid UUID format") - } - for _, x := range []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} { - if _, ok := xtob(s[x], s[x+1]); !ok { - return errors.New("invalid UUID format") - } - } - } - - return nil -} - -// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -// , or "" if uuid is invalid. -func (uuid UUID) String() string { - var buf [36]byte - encodeHex(buf[:], uuid) - return string(buf[:]) -} - -// URN returns the RFC 2141 URN form of uuid, -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. -func (uuid UUID) URN() string { - var buf [36 + 9]byte - copy(buf[:], "urn:uuid:") - encodeHex(buf[9:], uuid) - return string(buf[:]) -} - -func encodeHex(dst []byte, uuid UUID) { - hex.Encode(dst, uuid[:4]) - dst[8] = '-' - hex.Encode(dst[9:13], uuid[4:6]) - dst[13] = '-' - hex.Encode(dst[14:18], uuid[6:8]) - dst[18] = '-' - hex.Encode(dst[19:23], uuid[8:10]) - dst[23] = '-' - hex.Encode(dst[24:], uuid[10:]) -} - -// Variant returns the variant encoded in uuid. -func (uuid UUID) Variant() Variant { - switch { - case (uuid[8] & 0xc0) == 0x80: - return RFC4122 - case (uuid[8] & 0xe0) == 0xc0: - return Microsoft - case (uuid[8] & 0xe0) == 0xe0: - return Future - default: - return Reserved - } -} - -// Version returns the version of uuid. -func (uuid UUID) Version() Version { - return Version(uuid[6] >> 4) -} - -func (v Version) String() string { - if v > 15 { - return fmt.Sprintf("BAD_VERSION_%d", v) - } - return fmt.Sprintf("VERSION_%d", v) -} - -func (v Variant) String() string { - switch v { - case RFC4122: - return "RFC4122" - case Reserved: - return "Reserved" - case Microsoft: - return "Microsoft" - case Future: - return "Future" - case Invalid: - return "Invalid" - } - return fmt.Sprintf("BadVariant%d", int(v)) -} - -// SetRand sets the random number generator to r, which implements io.Reader. -// If r.Read returns an error when the package requests random data then -// a panic will be issued. -// -// Calling SetRand with nil sets the random number generator to the default -// generator. -func SetRand(r io.Reader) { - if r == nil { - rander = rand.Reader - return - } - rander = r -} - -// EnableRandPool enables internal randomness pool used for Random -// (Version 4) UUID generation. The pool contains random bytes read from -// the random number generator on demand in batches. Enabling the pool -// may improve the UUID generation throughput significantly. -// -// Since the pool is stored on the Go heap, this feature may be a bad fit -// for security sensitive applications. -// -// Both EnableRandPool and DisableRandPool are not thread-safe and should -// only be called when there is no possibility that New or any other -// UUID Version 4 generation function will be called concurrently. -func EnableRandPool() { - poolEnabled = true -} - -// DisableRandPool disables the randomness pool if it was previously -// enabled with EnableRandPool. -// -// Both EnableRandPool and DisableRandPool are not thread-safe and should -// only be called when there is no possibility that New or any other -// UUID Version 4 generation function will be called concurrently. -func DisableRandPool() { - poolEnabled = false - defer poolMu.Unlock() - poolMu.Lock() - poolPos = randPoolSize -} - -// UUIDs is a slice of UUID types. -type UUIDs []UUID - -// Strings returns a string slice containing the string form of each UUID in uuids. -func (uuids UUIDs) Strings() []string { - var uuidStrs = make([]string, len(uuids)) - for i, uuid := range uuids { - uuidStrs[i] = uuid.String() - } - return uuidStrs -} diff --git a/vendor/github.com/google/uuid/version1.go b/vendor/github.com/google/uuid/version1.go deleted file mode 100644 index 463109629..000000000 --- a/vendor/github.com/google/uuid/version1.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "encoding/binary" -) - -// NewUUID returns a Version 1 UUID based on the current NodeID and clock -// sequence, and the current time. If the NodeID has not been set by SetNodeID -// or SetNodeInterface then it will be set automatically. If the NodeID cannot -// be set NewUUID returns nil. If clock sequence has not been set by -// SetClockSequence then it will be set automatically. If GetTime fails to -// return the current NewUUID returns nil and an error. -// -// In most cases, New should be used. -func NewUUID() (UUID, error) { - var uuid UUID - now, seq, err := GetTime() - if err != nil { - return uuid, err - } - - timeLow := uint32(now & 0xffffffff) - timeMid := uint16((now >> 32) & 0xffff) - timeHi := uint16((now >> 48) & 0x0fff) - timeHi |= 0x1000 // Version 1 - - binary.BigEndian.PutUint32(uuid[0:], timeLow) - binary.BigEndian.PutUint16(uuid[4:], timeMid) - binary.BigEndian.PutUint16(uuid[6:], timeHi) - binary.BigEndian.PutUint16(uuid[8:], seq) - - nodeMu.Lock() - if nodeID == zeroID { - setNodeInterface("") - } - copy(uuid[10:], nodeID[:]) - nodeMu.Unlock() - - return uuid, nil -} diff --git a/vendor/github.com/google/uuid/version4.go b/vendor/github.com/google/uuid/version4.go deleted file mode 100644 index 7697802e4..000000000 --- a/vendor/github.com/google/uuid/version4.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import "io" - -// New creates a new random UUID or panics. New is equivalent to -// the expression -// -// uuid.Must(uuid.NewRandom()) -func New() UUID { - return Must(NewRandom()) -} - -// NewString creates a new random UUID and returns it as a string or panics. -// NewString is equivalent to the expression -// -// uuid.New().String() -func NewString() string { - return Must(NewRandom()).String() -} - -// NewRandom returns a Random (Version 4) UUID. -// -// The strength of the UUIDs is based on the strength of the crypto/rand -// package. -// -// Uses the randomness pool if it was enabled with EnableRandPool. -// -// A note about uniqueness derived from the UUID Wikipedia entry: -// -// Randomly generated UUIDs have 122 random bits. One's annual risk of being -// hit by a meteorite is estimated to be one chance in 17 billion, that -// means the probability is about 0.00000000006 (6 × 10−11), -// equivalent to the odds of creating a few tens of trillions of UUIDs in a -// year and having one duplicate. -func NewRandom() (UUID, error) { - if !poolEnabled { - return NewRandomFromReader(rander) - } - return newRandomFromPool() -} - -// NewRandomFromReader returns a UUID based on bytes read from a given io.Reader. -func NewRandomFromReader(r io.Reader) (UUID, error) { - var uuid UUID - _, err := io.ReadFull(r, uuid[:]) - if err != nil { - return Nil, err - } - uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 - uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 - return uuid, nil -} - -func newRandomFromPool() (UUID, error) { - var uuid UUID - poolMu.Lock() - if poolPos == randPoolSize { - _, err := io.ReadFull(rander, pool[:]) - if err != nil { - poolMu.Unlock() - return Nil, err - } - poolPos = 0 - } - copy(uuid[:], pool[poolPos:(poolPos+16)]) - poolPos += 16 - poolMu.Unlock() - - uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 - uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 - return uuid, nil -} diff --git a/vendor/github.com/google/uuid/version6.go b/vendor/github.com/google/uuid/version6.go deleted file mode 100644 index 339a959a7..000000000 --- a/vendor/github.com/google/uuid/version6.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2023 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import "encoding/binary" - -// UUID version 6 is a field-compatible version of UUIDv1, reordered for improved DB locality. -// It is expected that UUIDv6 will primarily be used in contexts where there are existing v1 UUIDs. -// Systems that do not involve legacy UUIDv1 SHOULD consider using UUIDv7 instead. -// -// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#uuidv6 -// -// NewV6 returns a Version 6 UUID based on the current NodeID and clock -// sequence, and the current time. If the NodeID has not been set by SetNodeID -// or SetNodeInterface then it will be set automatically. If the NodeID cannot -// be set NewV6 set NodeID is random bits automatically . If clock sequence has not been set by -// SetClockSequence then it will be set automatically. If GetTime fails to -// return the current NewV6 returns Nil and an error. -func NewV6() (UUID, error) { - var uuid UUID - now, seq, err := GetTime() - if err != nil { - return uuid, err - } - - /* - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | time_high | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | time_mid | time_low_and_version | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |clk_seq_hi_res | clk_seq_low | node (0-1) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | node (2-5) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - - binary.BigEndian.PutUint64(uuid[0:], uint64(now)) - binary.BigEndian.PutUint16(uuid[8:], seq) - - uuid[6] = 0x60 | (uuid[6] & 0x0F) - uuid[8] = 0x80 | (uuid[8] & 0x3F) - - nodeMu.Lock() - if nodeID == zeroID { - setNodeInterface("") - } - copy(uuid[10:], nodeID[:]) - nodeMu.Unlock() - - return uuid, nil -} diff --git a/vendor/github.com/google/uuid/version7.go b/vendor/github.com/google/uuid/version7.go deleted file mode 100644 index 3167b643d..000000000 --- a/vendor/github.com/google/uuid/version7.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2023 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "io" -) - -// UUID version 7 features a time-ordered value field derived from the widely -// implemented and well known Unix Epoch timestamp source, -// the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded. -// As well as improved entropy characteristics over versions 1 or 6. -// -// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#name-uuid-version-7 -// -// Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible. -// -// NewV7 returns a Version 7 UUID based on the current time(Unix Epoch). -// Uses the randomness pool if it was enabled with EnableRandPool. -// On error, NewV7 returns Nil and an error -func NewV7() (UUID, error) { - uuid, err := NewRandom() - if err != nil { - return uuid, err - } - makeV7(uuid[:]) - return uuid, nil -} - -// NewV7FromReader returns a Version 7 UUID based on the current time(Unix Epoch). -// it use NewRandomFromReader fill random bits. -// On error, NewV7FromReader returns Nil and an error. -func NewV7FromReader(r io.Reader) (UUID, error) { - uuid, err := NewRandomFromReader(r) - if err != nil { - return uuid, err - } - - makeV7(uuid[:]) - return uuid, nil -} - -// makeV7 fill 48 bits time (uuid[0] - uuid[5]), set version b0111 (uuid[6]) -// uuid[8] already has the right version number (Variant is 10) -// see function NewV7 and NewV7FromReader -func makeV7(uuid []byte) { - /* - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | unix_ts_ms | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | unix_ts_ms | ver | rand_a (12 bit seq) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |var| rand_b | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | rand_b | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - _ = uuid[15] // bounds check - - t, s := getV7Time() - - uuid[0] = byte(t >> 40) - uuid[1] = byte(t >> 32) - uuid[2] = byte(t >> 24) - uuid[3] = byte(t >> 16) - uuid[4] = byte(t >> 8) - uuid[5] = byte(t) - - uuid[6] = 0x70 | (0x0F & byte(s>>8)) - uuid[7] = byte(s) -} - -// lastV7time is the last time we returned stored as: -// -// 52 bits of time in milliseconds since epoch -// 12 bits of (fractional nanoseconds) >> 8 -var lastV7time int64 - -const nanoPerMilli = 1000000 - -// getV7Time returns the time in milliseconds and nanoseconds / 256. -// The returned (milli << 12 + seq) is guarenteed to be greater than -// (milli << 12 + seq) returned by any previous call to getV7Time. -func getV7Time() (milli, seq int64) { - timeMu.Lock() - defer timeMu.Unlock() - - nano := timeNow().UnixNano() - milli = nano / nanoPerMilli - // Sequence number is between 0 and 3906 (nanoPerMilli>>8) - seq = (nano - milli*nanoPerMilli) >> 8 - now := milli<<12 + seq - if now <= lastV7time { - now = lastV7time + 1 - milli = now >> 12 - seq = now & 0xfff - } - lastV7time = now - return milli, seq -} diff --git a/vendor/github.com/gordonklaus/ineffassign/LICENSE b/vendor/github.com/gordonklaus/ineffassign/LICENSE deleted file mode 100644 index 9e3d9bcc0..000000000 --- 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 f9dece8f2..000000000 --- a/vendor/github.com/gordonklaus/ineffassign/pkg/ineffassign/ineffassign.go +++ /dev/null @@ -1,610 +0,0 @@ -package ineffassign - -import ( - "fmt" - "go/ast" - "go/token" - "sort" - "strings" - - "golang.org/x/tools/go/analysis" -) - -// Analyzer is the ineffassign analysis.Analyzer instance. -var Analyzer = &analysis.Analyzer{ - Name: "ineffassign", - Doc: "detect ineffectual assignments in Go code", - Run: checkPath, -} - -func checkPath(pass *analysis.Pass) (interface{}, error) { - for _, file := range pass.Files { - if 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(), - Message: fmt.Sprintf("ineffectual assignment to %s", id.Name), - }) - } - } - - return nil, nil -} - -func isGenerated(file *ast.File) bool { - for _, cg := range file.Comments { - for _, c := range cg.List { - if strings.HasPrefix(c.Text, "// Code generated ") && strings.HasSuffix(c.Text, " DO NOT EDIT.") { - return true - } - } - } - - return false -} - -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.Type, n.Body) - } - case *ast.FuncLit: - bld.fun(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 { - if v, ok := bld.vars[id.Obj]; ok { - v.escapes = true - } - } - 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 { - if v, ok := bld.vars[id.Obj]; ok { - v.escapes = true - } - } - 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 { - if v, ok := bld.vars[id.Obj]; ok { - v.escapes = true - } - } - return bld - case *ast.StarExpr: - bld.maybePanic() - return bld - case *ast.TypeAssertExpr: - bld.maybePanic() - return bld - - default: - return bld - } - return nil -} - -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(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) - 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/gorilla/mux/.editorconfig b/vendor/github.com/gorilla/mux/.editorconfig deleted file mode 100644 index c6b74c3e0..000000000 --- a/vendor/github.com/gorilla/mux/.editorconfig +++ /dev/null @@ -1,20 +0,0 @@ -; https://editorconfig.org/ - -root = true - -[*] -insert_final_newline = true -charset = utf-8 -trim_trailing_whitespace = true -indent_style = space -indent_size = 2 - -[{Makefile,go.mod,go.sum,*.go,.gitmodules}] -indent_style = tab -indent_size = 4 - -[*.md] -indent_size = 4 -trim_trailing_whitespace = false - -eclint_indent_style = unset \ No newline at end of file diff --git a/vendor/github.com/gorilla/mux/.gitignore b/vendor/github.com/gorilla/mux/.gitignore deleted file mode 100644 index 84039fec6..000000000 --- a/vendor/github.com/gorilla/mux/.gitignore +++ /dev/null @@ -1 +0,0 @@ -coverage.coverprofile diff --git a/vendor/github.com/gorilla/mux/LICENSE b/vendor/github.com/gorilla/mux/LICENSE deleted file mode 100644 index bb9d80bc9..000000000 --- a/vendor/github.com/gorilla/mux/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2023 The Gorilla 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/gorilla/mux/Makefile b/vendor/github.com/gorilla/mux/Makefile deleted file mode 100644 index 98f5ab75f..000000000 --- a/vendor/github.com/gorilla/mux/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '') -GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest - -GO_SEC=$(shell which gosec 2> /dev/null || echo '') -GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest - -GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '') -GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest - -.PHONY: golangci-lint -golangci-lint: - $(if $(GO_LINT), ,go install $(GO_LINT_URI)) - @echo "##### Running golangci-lint" - golangci-lint run -v - -.PHONY: gosec -gosec: - $(if $(GO_SEC), ,go install $(GO_SEC_URI)) - @echo "##### Running gosec" - gosec ./... - -.PHONY: govulncheck -govulncheck: - $(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI)) - @echo "##### Running govulncheck" - govulncheck ./... - -.PHONY: verify -verify: golangci-lint gosec govulncheck - -.PHONY: test -test: - @echo "##### Running tests" - go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./... \ No newline at end of file diff --git a/vendor/github.com/gorilla/mux/README.md b/vendor/github.com/gorilla/mux/README.md deleted file mode 100644 index 382513d57..000000000 --- a/vendor/github.com/gorilla/mux/README.md +++ /dev/null @@ -1,812 +0,0 @@ -# gorilla/mux - -![testing](https://github.com/gorilla/mux/actions/workflows/test.yml/badge.svg) -[![codecov](https://codecov.io/github/gorilla/mux/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/mux) -[![godoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux) -[![sourcegraph](https://sourcegraph.com/github.com/gorilla/mux/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/mux?badge) - - -![Gorilla Logo](https://github.com/gorilla/.github/assets/53367916/d92caabf-98e0-473e-bfbf-ab554ba435e5) - -Package `gorilla/mux` implements a request router and dispatcher for matching incoming requests to -their respective handler. - -The name mux stands for "HTTP request multiplexer". Like the standard `http.ServeMux`, `mux.Router` matches incoming requests against a list of registered routes and calls a handler for the route that matches the URL or other conditions. The main features are: - -* It implements the `http.Handler` interface so it is compatible with the standard `http.ServeMux`. -* Requests can be matched based on URL host, path, path prefix, schemes, header and query values, HTTP methods or using custom matchers. -* URL hosts, paths and query values can have variables with an optional regular expression. -* Registered URLs can be built, or "reversed", which helps maintaining references to resources. -* Routes can be used as subrouters: nested routes are only tested if the parent route matches. This is useful to define groups of routes that share common conditions like a host, a path prefix or other repeated attributes. As a bonus, this optimizes request matching. - ---- - -* [Install](#install) -* [Examples](#examples) -* [Matching Routes](#matching-routes) -* [Static Files](#static-files) -* [Serving Single Page Applications](#serving-single-page-applications) (e.g. React, Vue, Ember.js, etc.) -* [Registered URLs](#registered-urls) -* [Walking Routes](#walking-routes) -* [Graceful Shutdown](#graceful-shutdown) -* [Middleware](#middleware) -* [Handling CORS Requests](#handling-cors-requests) -* [Testing Handlers](#testing-handlers) -* [Full Example](#full-example) - ---- - -## Install - -With a [correctly configured](https://golang.org/doc/install#testing) Go toolchain: - -```sh -go get -u github.com/gorilla/mux -``` - -## Examples - -Let's start registering a couple of URL paths and handlers: - -```go -func main() { - r := mux.NewRouter() - r.HandleFunc("/", HomeHandler) - r.HandleFunc("/products", ProductsHandler) - r.HandleFunc("/articles", ArticlesHandler) - http.Handle("/", r) -} -``` - -Here we register three routes mapping URL paths to handlers. This is equivalent to how `http.HandleFunc()` works: if an incoming request URL matches one of the paths, the corresponding handler is called passing (`http.ResponseWriter`, `*http.Request`) as parameters. - -Paths can have variables. They are defined using the format `{name}` or `{name:pattern}`. If a regular expression pattern is not defined, the matched variable will be anything until the next slash. For example: - -```go -r := mux.NewRouter() -r.HandleFunc("/products/{key}", ProductHandler) -r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) -r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) -``` - -The names are used to create a map of route variables which can be retrieved calling `mux.Vars()`: - -```go -func ArticlesCategoryHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, "Category: %v\n", vars["category"]) -} -``` - -And this is all you need to know about the basic usage. More advanced options are explained below. - -### Matching Routes - -Routes can also be restricted to a domain or subdomain. Just define a host pattern to be matched. They can also have variables: - -```go -r := mux.NewRouter() -// Only matches if domain is "www.example.com". -r.Host("www.example.com") -// Matches a dynamic subdomain. -r.Host("{subdomain:[a-z]+}.example.com") -``` - -There are several other matchers that can be added. To match path prefixes: - -```go -r.PathPrefix("/products/") -``` - -...or HTTP methods: - -```go -r.Methods("GET", "POST") -``` - -...or URL schemes: - -```go -r.Schemes("https") -``` - -...or header values: - -```go -r.Headers("X-Requested-With", "XMLHttpRequest") -``` - -...or query values: - -```go -r.Queries("key", "value") -``` - -...or to use a custom matcher function: - -```go -r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool { - return r.ProtoMajor == 0 -}) -``` - -...and finally, it is possible to combine several matchers in a single route: - -```go -r.HandleFunc("/products", ProductsHandler). - Host("www.example.com"). - Methods("GET"). - Schemes("http") -``` - -Routes are tested in the order they were added to the router. If two routes match, the first one wins: - -```go -r := mux.NewRouter() -r.HandleFunc("/specific", specificHandler) -r.PathPrefix("/").Handler(catchAllHandler) -``` - -Setting the same matching conditions again and again can be boring, so we have a way to group several routes that share the same requirements. We call it "subrouting". - -For example, let's say we have several URLs that should only match when the host is `www.example.com`. Create a route for that host and get a "subrouter" from it: - -```go -r := mux.NewRouter() -s := r.Host("www.example.com").Subrouter() -``` - -Then register routes in the subrouter: - -```go -s.HandleFunc("/products/", ProductsHandler) -s.HandleFunc("/products/{key}", ProductHandler) -s.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) -``` - -The three URL paths we registered above will only be tested if the domain is `www.example.com`, because the subrouter is tested first. This is not only convenient, but also optimizes request matching. You can create subrouters combining any attribute matchers accepted by a route. - -Subrouters can be used to create domain or path "namespaces": you define subrouters in a central place and then parts of the app can register its paths relatively to a given subrouter. - -There's one more thing about subroutes. When a subrouter has a path prefix, the inner routes use it as base for their paths: - -```go -r := mux.NewRouter() -s := r.PathPrefix("/products").Subrouter() -// "/products/" -s.HandleFunc("/", ProductsHandler) -// "/products/{key}/" -s.HandleFunc("/{key}/", ProductHandler) -// "/products/{key}/details" -s.HandleFunc("/{key}/details", ProductDetailsHandler) -``` - - -### Static Files - -Note that the path provided to `PathPrefix()` represents a "wildcard": calling -`PathPrefix("/static/").Handler(...)` means that the handler will be passed any -request that matches "/static/\*". This makes it easy to serve static files with mux: - -```go -func main() { - var dir string - - flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir") - flag.Parse() - r := mux.NewRouter() - - // This will serve files under http://localhost:8000/static/ - r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir)))) - - srv := &http.Server{ - Handler: r, - Addr: "127.0.0.1:8000", - // Good practice: enforce timeouts for servers you create! - WriteTimeout: 15 * time.Second, - ReadTimeout: 15 * time.Second, - } - - log.Fatal(srv.ListenAndServe()) -} -``` - -### Serving Single Page Applications - -Most of the time it makes sense to serve your SPA on a separate web server from your API, -but sometimes it's desirable to serve them both from one place. It's possible to write a simple -handler for serving your SPA (for use with React Router's [BrowserRouter](https://reacttraining.com/react-router/web/api/BrowserRouter) for example), and leverage -mux's powerful routing for your API endpoints. - -```go -package main - -import ( - "encoding/json" - "log" - "net/http" - "os" - "path/filepath" - "time" - - "github.com/gorilla/mux" -) - -// spaHandler implements the http.Handler interface, so we can use it -// to respond to HTTP requests. The path to the static directory and -// path to the index file within that static directory are used to -// serve the SPA in the given static directory. -type spaHandler struct { - staticPath string - indexPath string -} - -// ServeHTTP inspects the URL path to locate a file within the static dir -// on the SPA handler. If a file is found, it will be served. If not, the -// file located at the index path on the SPA handler will be served. This -// is suitable behavior for serving an SPA (single page application). -func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // Join internally call path.Clean to prevent directory traversal - path := filepath.Join(h.staticPath, r.URL.Path) - - // check whether a file exists or is a directory at the given path - fi, err := os.Stat(path) - if os.IsNotExist(err) || fi.IsDir() { - // file does not exist or path is a directory, serve index.html - http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath)) - return - } - - if err != nil { - // if we got an error (that wasn't that the file doesn't exist) stating the - // file, return a 500 internal server error and stop - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // otherwise, use http.FileServer to serve the static file - http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r) -} - -func main() { - router := mux.NewRouter() - - router.HandleFunc("/api/health", func(w http.ResponseWriter, r *http.Request) { - // an example API handler - json.NewEncoder(w).Encode(map[string]bool{"ok": true}) - }) - - spa := spaHandler{staticPath: "build", indexPath: "index.html"} - router.PathPrefix("/").Handler(spa) - - srv := &http.Server{ - Handler: router, - Addr: "127.0.0.1:8000", - // Good practice: enforce timeouts for servers you create! - WriteTimeout: 15 * time.Second, - ReadTimeout: 15 * time.Second, - } - - log.Fatal(srv.ListenAndServe()) -} -``` - -### Registered URLs - -Now let's see how to build registered URLs. - -Routes can be named. All routes that define a name can have their URLs built, or "reversed". We define a name calling `Name()` on a route. For example: - -```go -r := mux.NewRouter() -r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). - Name("article") -``` - -To build a URL, get the route and call the `URL()` method, passing a sequence of key/value pairs for the route variables. For the previous route, we would do: - -```go -url, err := r.Get("article").URL("category", "technology", "id", "42") -``` - -...and the result will be a `url.URL` with the following path: - -``` -"/articles/technology/42" -``` - -This also works for host and query value variables: - -```go -r := mux.NewRouter() -r.Host("{subdomain}.example.com"). - Path("/articles/{category}/{id:[0-9]+}"). - Queries("filter", "{filter}"). - HandlerFunc(ArticleHandler). - Name("article") - -// url.String() will be "http://news.example.com/articles/technology/42?filter=gorilla" -url, err := r.Get("article").URL("subdomain", "news", - "category", "technology", - "id", "42", - "filter", "gorilla") -``` - -All variables defined in the route are required, and their values must conform to the corresponding patterns. These requirements guarantee that a generated URL will always match a registered route -- the only exception is for explicitly defined "build-only" routes which never match. - -Regex support also exists for matching Headers within a route. For example, we could do: - -```go -r.HeadersRegexp("Content-Type", "application/(text|json)") -``` - -...and the route will match both requests with a Content-Type of `application/json` as well as `application/text` - -There's also a way to build only the URL host or path for a route: use the methods `URLHost()` or `URLPath()` instead. For the previous route, we would do: - -```go -// "http://news.example.com/" -host, err := r.Get("article").URLHost("subdomain", "news") - -// "/articles/technology/42" -path, err := r.Get("article").URLPath("category", "technology", "id", "42") -``` - -And if you use subrouters, host and path defined separately can be built as well: - -```go -r := mux.NewRouter() -s := r.Host("{subdomain}.example.com").Subrouter() -s.Path("/articles/{category}/{id:[0-9]+}"). - HandlerFunc(ArticleHandler). - Name("article") - -// "http://news.example.com/articles/technology/42" -url, err := r.Get("article").URL("subdomain", "news", - "category", "technology", - "id", "42") -``` - -To find all the required variables for a given route when calling `URL()`, the method `GetVarNames()` is available: -```go -r := mux.NewRouter() -r.Host("{domain}"). - Path("/{group}/{item_id}"). - Queries("some_data1", "{some_data1}"). - Queries("some_data2", "{some_data2}"). - Name("article") - -// Will print [domain group item_id some_data1 some_data2] -fmt.Println(r.Get("article").GetVarNames()) - -``` -### Walking Routes - -The `Walk` function on `mux.Router` can be used to visit all of the routes that are registered on a router. For example, -the following prints all of the registered routes: - -```go -package main - -import ( - "fmt" - "net/http" - "strings" - - "github.com/gorilla/mux" -) - -func handler(w http.ResponseWriter, r *http.Request) { - return -} - -func main() { - r := mux.NewRouter() - r.HandleFunc("/", handler) - r.HandleFunc("/products", handler).Methods("POST") - r.HandleFunc("/articles", handler).Methods("GET") - r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT") - r.HandleFunc("/authors", handler).Queries("surname", "{surname}") - err := r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error { - pathTemplate, err := route.GetPathTemplate() - if err == nil { - fmt.Println("ROUTE:", pathTemplate) - } - pathRegexp, err := route.GetPathRegexp() - if err == nil { - fmt.Println("Path regexp:", pathRegexp) - } - queriesTemplates, err := route.GetQueriesTemplates() - if err == nil { - fmt.Println("Queries templates:", strings.Join(queriesTemplates, ",")) - } - queriesRegexps, err := route.GetQueriesRegexp() - if err == nil { - fmt.Println("Queries regexps:", strings.Join(queriesRegexps, ",")) - } - methods, err := route.GetMethods() - if err == nil { - fmt.Println("Methods:", strings.Join(methods, ",")) - } - fmt.Println() - return nil - }) - - if err != nil { - fmt.Println(err) - } - - http.Handle("/", r) -} -``` - -### Graceful Shutdown - -Go 1.8 introduced the ability to [gracefully shutdown](https://golang.org/doc/go1.8#http_shutdown) a `*http.Server`. Here's how to do that alongside `mux`: - -```go -package main - -import ( - "context" - "flag" - "log" - "net/http" - "os" - "os/signal" - "time" - - "github.com/gorilla/mux" -) - -func main() { - var wait time.Duration - flag.DurationVar(&wait, "graceful-timeout", time.Second * 15, "the duration for which the server gracefully wait for existing connections to finish - e.g. 15s or 1m") - flag.Parse() - - r := mux.NewRouter() - // Add your routes as needed - - srv := &http.Server{ - Addr: "0.0.0.0:8080", - // Good practice to set timeouts to avoid Slowloris attacks. - WriteTimeout: time.Second * 15, - ReadTimeout: time.Second * 15, - IdleTimeout: time.Second * 60, - Handler: r, // Pass our instance of gorilla/mux in. - } - - // Run our server in a goroutine so that it doesn't block. - go func() { - if err := srv.ListenAndServe(); err != nil { - log.Println(err) - } - }() - - c := make(chan os.Signal, 1) - // We'll accept graceful shutdowns when quit via SIGINT (Ctrl+C) - // SIGKILL, SIGQUIT or SIGTERM (Ctrl+/) will not be caught. - signal.Notify(c, os.Interrupt) - - // Block until we receive our signal. - <-c - - // Create a deadline to wait for. - ctx, cancel := context.WithTimeout(context.Background(), wait) - defer cancel() - // Doesn't block if no connections, but will otherwise wait - // until the timeout deadline. - srv.Shutdown(ctx) - // Optionally, you could run srv.Shutdown in a goroutine and block on - // <-ctx.Done() if your application should wait for other services - // to finalize based on context cancellation. - log.Println("shutting down") - os.Exit(0) -} -``` - -### Middleware - -Mux supports the addition of middlewares to a [Router](https://godoc.org/github.com/gorilla/mux#Router), which are executed in the order they are added if a match is found, including its subrouters. -Middlewares are (typically) small pieces of code which take one request, do something with it, and pass it down to another middleware or the final handler. Some common use cases for middleware are request logging, header manipulation, or `ResponseWriter` hijacking. - -Mux middlewares are defined using the de facto standard type: - -```go -type MiddlewareFunc func(http.Handler) http.Handler -``` - -Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed to it, and then calls the handler passed as parameter to the MiddlewareFunc. This takes advantage of closures being able access variables from the context where they are created, while retaining the signature enforced by the receivers. - -A very basic middleware which logs the URI of the request being handled could be written as: - -```go -func loggingMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Do stuff here - log.Println(r.RequestURI) - // Call the next handler, which can be another middleware in the chain, or the final handler. - next.ServeHTTP(w, r) - }) -} -``` - -Middlewares can be added to a router using `Router.Use()`: - -```go -r := mux.NewRouter() -r.HandleFunc("/", handler) -r.Use(loggingMiddleware) -``` - -A more complex authentication middleware, which maps session token to users, could be written as: - -```go -// Define our struct -type authenticationMiddleware struct { - tokenUsers map[string]string -} - -// Initialize it somewhere -func (amw *authenticationMiddleware) Populate() { - amw.tokenUsers["00000000"] = "user0" - amw.tokenUsers["aaaaaaaa"] = "userA" - amw.tokenUsers["05f717e5"] = "randomUser" - amw.tokenUsers["deadbeef"] = "user0" -} - -// Middleware function, which will be called for each request -func (amw *authenticationMiddleware) Middleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - token := r.Header.Get("X-Session-Token") - - if user, found := amw.tokenUsers[token]; found { - // We found the token in our map - log.Printf("Authenticated user %s\n", user) - // Pass down the request to the next middleware (or final handler) - next.ServeHTTP(w, r) - } else { - // Write an error and stop the handler chain - http.Error(w, "Forbidden", http.StatusForbidden) - } - }) -} -``` - -```go -r := mux.NewRouter() -r.HandleFunc("/", handler) - -amw := authenticationMiddleware{tokenUsers: make(map[string]string)} -amw.Populate() - -r.Use(amw.Middleware) -``` - -Note: The handler chain will be stopped if your middleware doesn't call `next.ServeHTTP()` with the corresponding parameters. This can be used to abort a request if the middleware writer wants to. Middlewares _should_ write to `ResponseWriter` if they _are_ going to terminate the request, and they _should not_ write to `ResponseWriter` if they _are not_ going to terminate it. - -### Handling CORS Requests - -[CORSMethodMiddleware](https://godoc.org/github.com/gorilla/mux#CORSMethodMiddleware) intends to make it easier to strictly set the `Access-Control-Allow-Methods` response header. - -* You will still need to use your own CORS handler to set the other CORS headers such as `Access-Control-Allow-Origin` -* The middleware will set the `Access-Control-Allow-Methods` header to all the method matchers (e.g. `r.Methods(http.MethodGet, http.MethodPut, http.MethodOptions)` -> `Access-Control-Allow-Methods: GET,PUT,OPTIONS`) on a route -* If you do not specify any methods, then: -> _Important_: there must be an `OPTIONS` method matcher for the middleware to set the headers. - -Here is an example of using `CORSMethodMiddleware` along with a custom `OPTIONS` handler to set all the required CORS headers: - -```go -package main - -import ( - "net/http" - "github.com/gorilla/mux" -) - -func main() { - r := mux.NewRouter() - - // IMPORTANT: you must specify an OPTIONS method matcher for the middleware to set CORS headers - r.HandleFunc("/foo", fooHandler).Methods(http.MethodGet, http.MethodPut, http.MethodPatch, http.MethodOptions) - r.Use(mux.CORSMethodMiddleware(r)) - - http.ListenAndServe(":8080", r) -} - -func fooHandler(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Access-Control-Allow-Origin", "*") - if r.Method == http.MethodOptions { - return - } - - w.Write([]byte("foo")) -} -``` - -And an request to `/foo` using something like: - -```bash -curl localhost:8080/foo -v -``` - -Would look like: - -```bash -* Trying ::1... -* TCP_NODELAY set -* Connected to localhost (::1) port 8080 (#0) -> GET /foo HTTP/1.1 -> Host: localhost:8080 -> User-Agent: curl/7.59.0 -> Accept: */* -> -< HTTP/1.1 200 OK -< Access-Control-Allow-Methods: GET,PUT,PATCH,OPTIONS -< Access-Control-Allow-Origin: * -< Date: Fri, 28 Jun 2019 20:13:30 GMT -< Content-Length: 3 -< Content-Type: text/plain; charset=utf-8 -< -* Connection #0 to host localhost left intact -foo -``` - -### Testing Handlers - -Testing handlers in a Go web application is straightforward, and _mux_ doesn't complicate this any further. Given two files: `endpoints.go` and `endpoints_test.go`, here's how we'd test an application using _mux_. - -First, our simple HTTP handler: - -```go -// endpoints.go -package main - -func HealthCheckHandler(w http.ResponseWriter, r *http.Request) { - // A very simple health check. - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - - // In the future we could report back on the status of our DB, or our cache - // (e.g. Redis) by performing a simple PING, and include them in the response. - io.WriteString(w, `{"alive": true}`) -} - -func main() { - r := mux.NewRouter() - r.HandleFunc("/health", HealthCheckHandler) - - log.Fatal(http.ListenAndServe("localhost:8080", r)) -} -``` - -Our test code: - -```go -// endpoints_test.go -package main - -import ( - "net/http" - "net/http/httptest" - "testing" -) - -func TestHealthCheckHandler(t *testing.T) { - // Create a request to pass to our handler. We don't have any query parameters for now, so we'll - // pass 'nil' as the third parameter. - req, err := http.NewRequest("GET", "/health", nil) - if err != nil { - t.Fatal(err) - } - - // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response. - rr := httptest.NewRecorder() - handler := http.HandlerFunc(HealthCheckHandler) - - // Our handlers satisfy http.Handler, so we can call their ServeHTTP method - // directly and pass in our Request and ResponseRecorder. - handler.ServeHTTP(rr, req) - - // Check the status code is what we expect. - if status := rr.Code; status != http.StatusOK { - t.Errorf("handler returned wrong status code: got %v want %v", - status, http.StatusOK) - } - - // Check the response body is what we expect. - expected := `{"alive": true}` - if rr.Body.String() != expected { - t.Errorf("handler returned unexpected body: got %v want %v", - rr.Body.String(), expected) - } -} -``` - -In the case that our routes have [variables](#examples), we can pass those in the request. We could write -[table-driven tests](https://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go) to test multiple -possible route variables as needed. - -```go -// endpoints.go -func main() { - r := mux.NewRouter() - // A route with a route variable: - r.HandleFunc("/metrics/{type}", MetricsHandler) - - log.Fatal(http.ListenAndServe("localhost:8080", r)) -} -``` - -Our test file, with a table-driven test of `routeVariables`: - -```go -// endpoints_test.go -func TestMetricsHandler(t *testing.T) { - tt := []struct{ - routeVariable string - shouldPass bool - }{ - {"goroutines", true}, - {"heap", true}, - {"counters", true}, - {"queries", true}, - {"adhadaeqm3k", false}, - } - - for _, tc := range tt { - path := fmt.Sprintf("/metrics/%s", tc.routeVariable) - req, err := http.NewRequest("GET", path, nil) - if err != nil { - t.Fatal(err) - } - - rr := httptest.NewRecorder() - - // To add the vars to the context, - // we need to create a router through which we can pass the request. - router := mux.NewRouter() - router.HandleFunc("/metrics/{type}", MetricsHandler) - router.ServeHTTP(rr, req) - - // In this case, our MetricsHandler returns a non-200 response - // for a route variable it doesn't know about. - if rr.Code == http.StatusOK && !tc.shouldPass { - t.Errorf("handler should have failed on routeVariable %s: got %v want %v", - tc.routeVariable, rr.Code, http.StatusOK) - } - } -} -``` - -## Full Example - -Here's a complete, runnable example of a small `mux` based server: - -```go -package main - -import ( - "net/http" - "log" - "github.com/gorilla/mux" -) - -func YourHandler(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("Gorilla!\n")) -} - -func main() { - r := mux.NewRouter() - // Routes consist of a path and a handler function. - r.HandleFunc("/", YourHandler) - - // Bind to a port and pass our router in - log.Fatal(http.ListenAndServe(":8000", r)) -} -``` - -## License - -BSD licensed. See the LICENSE file for details. diff --git a/vendor/github.com/gorilla/mux/doc.go b/vendor/github.com/gorilla/mux/doc.go deleted file mode 100644 index 80601351f..000000000 --- a/vendor/github.com/gorilla/mux/doc.go +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright 2012 The Gorilla 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 mux implements a request router and dispatcher. - -The name mux stands for "HTTP request multiplexer". Like the standard -http.ServeMux, mux.Router matches incoming requests against a list of -registered routes and calls a handler for the route that matches the URL -or other conditions. The main features are: - - - Requests can be matched based on URL host, path, path prefix, schemes, - header and query values, HTTP methods or using custom matchers. - - URL hosts, paths and query values can have variables with an optional - regular expression. - - Registered URLs can be built, or "reversed", which helps maintaining - references to resources. - - Routes can be used as subrouters: nested routes are only tested if the - parent route matches. This is useful to define groups of routes that - share common conditions like a host, a path prefix or other repeated - attributes. As a bonus, this optimizes request matching. - - It implements the http.Handler interface so it is compatible with the - standard http.ServeMux. - -Let's start registering a couple of URL paths and handlers: - - func main() { - r := mux.NewRouter() - r.HandleFunc("/", HomeHandler) - r.HandleFunc("/products", ProductsHandler) - r.HandleFunc("/articles", ArticlesHandler) - http.Handle("/", r) - } - -Here we register three routes mapping URL paths to handlers. This is -equivalent to how http.HandleFunc() works: if an incoming request URL matches -one of the paths, the corresponding handler is called passing -(http.ResponseWriter, *http.Request) as parameters. - -Paths can have variables. They are defined using the format {name} or -{name:pattern}. If a regular expression pattern is not defined, the matched -variable will be anything until the next slash. For example: - - r := mux.NewRouter() - r.HandleFunc("/products/{key}", ProductHandler) - r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) - r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) - -Groups can be used inside patterns, as long as they are non-capturing (?:re). For example: - - r.HandleFunc("/articles/{category}/{sort:(?:asc|desc|new)}", ArticlesCategoryHandler) - -The names are used to create a map of route variables which can be retrieved -calling mux.Vars(): - - vars := mux.Vars(request) - category := vars["category"] - -Note that if any capturing groups are present, mux will panic() during parsing. To prevent -this, convert any capturing groups to non-capturing, e.g. change "/{sort:(asc|desc)}" to -"/{sort:(?:asc|desc)}". This is a change from prior versions which behaved unpredictably -when capturing groups were present. - -And this is all you need to know about the basic usage. More advanced options -are explained below. - -Routes can also be restricted to a domain or subdomain. Just define a host -pattern to be matched. They can also have variables: - - r := mux.NewRouter() - // Only matches if domain is "www.example.com". - r.Host("www.example.com") - // Matches a dynamic subdomain. - r.Host("{subdomain:[a-z]+}.domain.com") - -There are several other matchers that can be added. To match path prefixes: - - r.PathPrefix("/products/") - -...or HTTP methods: - - r.Methods("GET", "POST") - -...or URL schemes: - - r.Schemes("https") - -...or header values: - - r.Headers("X-Requested-With", "XMLHttpRequest") - -...or query values: - - r.Queries("key", "value") - -...or to use a custom matcher function: - - r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool { - return r.ProtoMajor == 0 - }) - -...and finally, it is possible to combine several matchers in a single route: - - r.HandleFunc("/products", ProductsHandler). - Host("www.example.com"). - Methods("GET"). - Schemes("http") - -Setting the same matching conditions again and again can be boring, so we have -a way to group several routes that share the same requirements. -We call it "subrouting". - -For example, let's say we have several URLs that should only match when the -host is "www.example.com". Create a route for that host and get a "subrouter" -from it: - - r := mux.NewRouter() - s := r.Host("www.example.com").Subrouter() - -Then register routes in the subrouter: - - s.HandleFunc("/products/", ProductsHandler) - s.HandleFunc("/products/{key}", ProductHandler) - s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) - -The three URL paths we registered above will only be tested if the domain is -"www.example.com", because the subrouter is tested first. This is not -only convenient, but also optimizes request matching. You can create -subrouters combining any attribute matchers accepted by a route. - -Subrouters can be used to create domain or path "namespaces": you define -subrouters in a central place and then parts of the app can register its -paths relatively to a given subrouter. - -There's one more thing about subroutes. When a subrouter has a path prefix, -the inner routes use it as base for their paths: - - r := mux.NewRouter() - s := r.PathPrefix("/products").Subrouter() - // "/products/" - s.HandleFunc("/", ProductsHandler) - // "/products/{key}/" - s.HandleFunc("/{key}/", ProductHandler) - // "/products/{key}/details" - s.HandleFunc("/{key}/details", ProductDetailsHandler) - -Note that the path provided to PathPrefix() represents a "wildcard": calling -PathPrefix("/static/").Handler(...) means that the handler will be passed any -request that matches "/static/*". This makes it easy to serve static files with mux: - - func main() { - var dir string - - flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir") - flag.Parse() - r := mux.NewRouter() - - // This will serve files under http://localhost:8000/static/ - r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir)))) - - srv := &http.Server{ - Handler: r, - Addr: "127.0.0.1:8000", - // Good practice: enforce timeouts for servers you create! - WriteTimeout: 15 * time.Second, - ReadTimeout: 15 * time.Second, - } - - log.Fatal(srv.ListenAndServe()) - } - -Now let's see how to build registered URLs. - -Routes can be named. All routes that define a name can have their URLs built, -or "reversed". We define a name calling Name() on a route. For example: - - r := mux.NewRouter() - r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). - Name("article") - -To build a URL, get the route and call the URL() method, passing a sequence of -key/value pairs for the route variables. For the previous route, we would do: - - url, err := r.Get("article").URL("category", "technology", "id", "42") - -...and the result will be a url.URL with the following path: - - "/articles/technology/42" - -This also works for host and query value variables: - - r := mux.NewRouter() - r.Host("{subdomain}.domain.com"). - Path("/articles/{category}/{id:[0-9]+}"). - Queries("filter", "{filter}"). - HandlerFunc(ArticleHandler). - Name("article") - - // url.String() will be "http://news.domain.com/articles/technology/42?filter=gorilla" - url, err := r.Get("article").URL("subdomain", "news", - "category", "technology", - "id", "42", - "filter", "gorilla") - -All variables defined in the route are required, and their values must -conform to the corresponding patterns. These requirements guarantee that a -generated URL will always match a registered route -- the only exception is -for explicitly defined "build-only" routes which never match. - -Regex support also exists for matching Headers within a route. For example, we could do: - - r.HeadersRegexp("Content-Type", "application/(text|json)") - -...and the route will match both requests with a Content-Type of `application/json` as well as -`application/text` - -There's also a way to build only the URL host or path for a route: -use the methods URLHost() or URLPath() instead. For the previous route, -we would do: - - // "http://news.domain.com/" - host, err := r.Get("article").URLHost("subdomain", "news") - - // "/articles/technology/42" - path, err := r.Get("article").URLPath("category", "technology", "id", "42") - -And if you use subrouters, host and path defined separately can be built -as well: - - r := mux.NewRouter() - s := r.Host("{subdomain}.domain.com").Subrouter() - s.Path("/articles/{category}/{id:[0-9]+}"). - HandlerFunc(ArticleHandler). - Name("article") - - // "http://news.domain.com/articles/technology/42" - url, err := r.Get("article").URL("subdomain", "news", - "category", "technology", - "id", "42") - -Mux supports the addition of middlewares to a Router, which are executed in the order they are added if a match is found, including its subrouters. Middlewares are (typically) small pieces of code which take one request, do something with it, and pass it down to another middleware or the final handler. Some common use cases for middleware are request logging, header manipulation, or ResponseWriter hijacking. - - type MiddlewareFunc func(http.Handler) http.Handler - -Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed to it, and then calls the handler passed as parameter to the MiddlewareFunc (closures can access variables from the context where they are created). - -A very basic middleware which logs the URI of the request being handled could be written as: - - func simpleMw(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Do stuff here - log.Println(r.RequestURI) - // Call the next handler, which can be another middleware in the chain, or the final handler. - next.ServeHTTP(w, r) - }) - } - -Middlewares can be added to a router using `Router.Use()`: - - r := mux.NewRouter() - r.HandleFunc("/", handler) - r.Use(simpleMw) - -A more complex authentication middleware, which maps session token to users, could be written as: - - // Define our struct - type authenticationMiddleware struct { - tokenUsers map[string]string - } - - // Initialize it somewhere - func (amw *authenticationMiddleware) Populate() { - amw.tokenUsers["00000000"] = "user0" - amw.tokenUsers["aaaaaaaa"] = "userA" - amw.tokenUsers["05f717e5"] = "randomUser" - amw.tokenUsers["deadbeef"] = "user0" - } - - // Middleware function, which will be called for each request - func (amw *authenticationMiddleware) Middleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - token := r.Header.Get("X-Session-Token") - - if user, found := amw.tokenUsers[token]; found { - // We found the token in our map - log.Printf("Authenticated user %s\n", user) - next.ServeHTTP(w, r) - } else { - http.Error(w, "Forbidden", http.StatusForbidden) - } - }) - } - - r := mux.NewRouter() - r.HandleFunc("/", handler) - - amw := authenticationMiddleware{tokenUsers: make(map[string]string)} - amw.Populate() - - r.Use(amw.Middleware) - -Note: The handler chain will be stopped if your middleware doesn't call `next.ServeHTTP()` with the corresponding parameters. This can be used to abort a request if the middleware writer wants to. -*/ -package mux diff --git a/vendor/github.com/gorilla/mux/middleware.go b/vendor/github.com/gorilla/mux/middleware.go deleted file mode 100644 index cb51c565e..000000000 --- a/vendor/github.com/gorilla/mux/middleware.go +++ /dev/null @@ -1,74 +0,0 @@ -package mux - -import ( - "net/http" - "strings" -) - -// MiddlewareFunc is a function which receives an http.Handler and returns another http.Handler. -// Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed -// to it, and then calls the handler passed as parameter to the MiddlewareFunc. -type MiddlewareFunc func(http.Handler) http.Handler - -// middleware interface is anything which implements a MiddlewareFunc named Middleware. -type middleware interface { - Middleware(handler http.Handler) http.Handler -} - -// Middleware allows MiddlewareFunc to implement the middleware interface. -func (mw MiddlewareFunc) Middleware(handler http.Handler) http.Handler { - return mw(handler) -} - -// Use appends a MiddlewareFunc to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router. -func (r *Router) Use(mwf ...MiddlewareFunc) { - for _, fn := range mwf { - r.middlewares = append(r.middlewares, fn) - } -} - -// useInterface appends a middleware to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router. -func (r *Router) useInterface(mw middleware) { - r.middlewares = append(r.middlewares, mw) -} - -// CORSMethodMiddleware automatically sets the Access-Control-Allow-Methods response header -// on requests for routes that have an OPTIONS method matcher to all the method matchers on -// the route. Routes that do not explicitly handle OPTIONS requests will not be processed -// by the middleware. See examples for usage. -func CORSMethodMiddleware(r *Router) MiddlewareFunc { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - allMethods, err := getAllMethodsForRoute(r, req) - if err == nil { - for _, v := range allMethods { - if v == http.MethodOptions { - w.Header().Set("Access-Control-Allow-Methods", strings.Join(allMethods, ",")) - } - } - } - - next.ServeHTTP(w, req) - }) - } -} - -// getAllMethodsForRoute returns all the methods from method matchers matching a given -// request. -func getAllMethodsForRoute(r *Router, req *http.Request) ([]string, error) { - var allMethods []string - - for _, route := range r.routes { - var match RouteMatch - if route.Match(req, &match) || match.MatchErr == ErrMethodMismatch { - methods, err := route.GetMethods() - if err != nil { - return nil, err - } - - allMethods = append(allMethods, methods...) - } - } - - return allMethods, nil -} diff --git a/vendor/github.com/gorilla/mux/mux.go b/vendor/github.com/gorilla/mux/mux.go deleted file mode 100644 index 1e089906f..000000000 --- a/vendor/github.com/gorilla/mux/mux.go +++ /dev/null @@ -1,608 +0,0 @@ -// Copyright 2012 The Gorilla 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 mux - -import ( - "context" - "errors" - "fmt" - "net/http" - "path" - "regexp" -) - -var ( - // ErrMethodMismatch is returned when the method in the request does not match - // the method defined against the route. - ErrMethodMismatch = errors.New("method is not allowed") - // ErrNotFound is returned when no route match is found. - ErrNotFound = errors.New("no matching route was found") -) - -// NewRouter returns a new router instance. -func NewRouter() *Router { - return &Router{namedRoutes: make(map[string]*Route)} -} - -// Router registers routes to be matched and dispatches a handler. -// -// It implements the http.Handler interface, so it can be registered to serve -// requests: -// -// var router = mux.NewRouter() -// -// func main() { -// http.Handle("/", router) -// } -// -// Or, for Google App Engine, register it in a init() function: -// -// func init() { -// http.Handle("/", router) -// } -// -// This will send all incoming requests to the router. -type Router struct { - // Configurable Handler to be used when no route matches. - // This can be used to render your own 404 Not Found errors. - NotFoundHandler http.Handler - - // Configurable Handler to be used when the request method does not match the route. - // This can be used to render your own 405 Method Not Allowed errors. - MethodNotAllowedHandler http.Handler - - // Routes to be matched, in order. - routes []*Route - - // Routes by name for URL building. - namedRoutes map[string]*Route - - // If true, do not clear the request context after handling the request. - // - // Deprecated: No effect, since the context is stored on the request itself. - KeepContext bool - - // Slice of middlewares to be called after a match is found - middlewares []middleware - - // configuration shared with `Route` - routeConf -} - -// common route configuration shared between `Router` and `Route` -type routeConf struct { - // If true, "/path/foo%2Fbar/to" will match the path "/path/{var}/to" - useEncodedPath bool - - // If true, when the path pattern is "/path/", accessing "/path" will - // redirect to the former and vice versa. - strictSlash bool - - // If true, when the path pattern is "/path//to", accessing "/path//to" - // will not redirect - skipClean bool - - // Manager for the variables from host and path. - regexp routeRegexpGroup - - // List of matchers. - matchers []matcher - - // The scheme used when building URLs. - buildScheme string - - buildVarsFunc BuildVarsFunc -} - -// returns an effective deep copy of `routeConf` -func copyRouteConf(r routeConf) routeConf { - c := r - - if r.regexp.path != nil { - c.regexp.path = copyRouteRegexp(r.regexp.path) - } - - if r.regexp.host != nil { - c.regexp.host = copyRouteRegexp(r.regexp.host) - } - - c.regexp.queries = make([]*routeRegexp, 0, len(r.regexp.queries)) - for _, q := range r.regexp.queries { - c.regexp.queries = append(c.regexp.queries, copyRouteRegexp(q)) - } - - c.matchers = make([]matcher, len(r.matchers)) - copy(c.matchers, r.matchers) - - return c -} - -func copyRouteRegexp(r *routeRegexp) *routeRegexp { - c := *r - return &c -} - -// Match attempts to match the given request against the router's registered routes. -// -// If the request matches a route of this router or one of its subrouters the Route, -// Handler, and Vars fields of the the match argument are filled and this function -// returns true. -// -// If the request does not match any of this router's or its subrouters' routes -// then this function returns false. If available, a reason for the match failure -// will be filled in the match argument's MatchErr field. If the match failure type -// (eg: not found) has a registered handler, the handler is assigned to the Handler -// field of the match argument. -func (r *Router) Match(req *http.Request, match *RouteMatch) bool { - for _, route := range r.routes { - if route.Match(req, match) { - // Build middleware chain if no error was found - if match.MatchErr == nil { - for i := len(r.middlewares) - 1; i >= 0; i-- { - match.Handler = r.middlewares[i].Middleware(match.Handler) - } - } - return true - } - } - - if match.MatchErr == ErrMethodMismatch { - if r.MethodNotAllowedHandler != nil { - match.Handler = r.MethodNotAllowedHandler - return true - } - - return false - } - - // Closest match for a router (includes sub-routers) - if r.NotFoundHandler != nil { - match.Handler = r.NotFoundHandler - match.MatchErr = ErrNotFound - return true - } - - match.MatchErr = ErrNotFound - return false -} - -// ServeHTTP dispatches the handler registered in the matched route. -// -// When there is a match, the route variables can be retrieved calling -// mux.Vars(request). -func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { - if !r.skipClean { - path := req.URL.Path - if r.useEncodedPath { - path = req.URL.EscapedPath() - } - // Clean path to canonical form and redirect. - if p := cleanPath(path); p != path { - - // Added 3 lines (Philip Schlump) - It was dropping the query string and #whatever from query. - // This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue: - // http://code.google.com/p/go/issues/detail?id=5252 - url := *req.URL - url.Path = p - p = url.String() - - w.Header().Set("Location", p) - w.WriteHeader(http.StatusMovedPermanently) - return - } - } - var match RouteMatch - var handler http.Handler - if r.Match(req, &match) { - handler = match.Handler - req = requestWithVars(req, match.Vars) - req = requestWithRoute(req, match.Route) - } - - if handler == nil && match.MatchErr == ErrMethodMismatch { - handler = methodNotAllowedHandler() - } - - if handler == nil { - handler = http.NotFoundHandler() - } - - handler.ServeHTTP(w, req) -} - -// Get returns a route registered with the given name. -func (r *Router) Get(name string) *Route { - return r.namedRoutes[name] -} - -// GetRoute returns a route registered with the given name. This method -// was renamed to Get() and remains here for backwards compatibility. -func (r *Router) GetRoute(name string) *Route { - return r.namedRoutes[name] -} - -// StrictSlash defines the trailing slash behavior for new routes. The initial -// value is false. -// -// When true, if the route path is "/path/", accessing "/path" will perform a redirect -// to the former and vice versa. In other words, your application will always -// see the path as specified in the route. -// -// When false, if the route path is "/path", accessing "/path/" will not match -// this route and vice versa. -// -// The re-direct is a HTTP 301 (Moved Permanently). Note that when this is set for -// routes with a non-idempotent method (e.g. POST, PUT), the subsequent re-directed -// request will be made as a GET by most clients. Use middleware or client settings -// to modify this behaviour as needed. -// -// Special case: when a route sets a path prefix using the PathPrefix() method, -// strict slash is ignored for that route because the redirect behavior can't -// be determined from a prefix alone. However, any subrouters created from that -// route inherit the original StrictSlash setting. -func (r *Router) StrictSlash(value bool) *Router { - r.strictSlash = value - return r -} - -// SkipClean defines the path cleaning behaviour for new routes. The initial -// value is false. Users should be careful about which routes are not cleaned -// -// When true, if the route path is "/path//to", it will remain with the double -// slash. This is helpful if you have a route like: /fetch/http://xkcd.com/534/ -// -// When false, the path will be cleaned, so /fetch/http://xkcd.com/534/ will -// become /fetch/http/xkcd.com/534 -func (r *Router) SkipClean(value bool) *Router { - r.skipClean = value - return r -} - -// UseEncodedPath tells the router to match the encoded original path -// to the routes. -// For eg. "/path/foo%2Fbar/to" will match the path "/path/{var}/to". -// -// If not called, the router will match the unencoded path to the routes. -// For eg. "/path/foo%2Fbar/to" will match the path "/path/foo/bar/to" -func (r *Router) UseEncodedPath() *Router { - r.useEncodedPath = true - return r -} - -// ---------------------------------------------------------------------------- -// Route factories -// ---------------------------------------------------------------------------- - -// NewRoute registers an empty route. -func (r *Router) NewRoute() *Route { - // initialize a route with a copy of the parent router's configuration - route := &Route{routeConf: copyRouteConf(r.routeConf), namedRoutes: r.namedRoutes} - r.routes = append(r.routes, route) - return route -} - -// Name registers a new route with a name. -// See Route.Name(). -func (r *Router) Name(name string) *Route { - return r.NewRoute().Name(name) -} - -// Handle registers a new route with a matcher for the URL path. -// See Route.Path() and Route.Handler(). -func (r *Router) Handle(path string, handler http.Handler) *Route { - return r.NewRoute().Path(path).Handler(handler) -} - -// HandleFunc registers a new route with a matcher for the URL path. -// See Route.Path() and Route.HandlerFunc(). -func (r *Router) HandleFunc(path string, f func(http.ResponseWriter, - *http.Request)) *Route { - return r.NewRoute().Path(path).HandlerFunc(f) -} - -// Headers registers a new route with a matcher for request header values. -// See Route.Headers(). -func (r *Router) Headers(pairs ...string) *Route { - return r.NewRoute().Headers(pairs...) -} - -// Host registers a new route with a matcher for the URL host. -// See Route.Host(). -func (r *Router) Host(tpl string) *Route { - return r.NewRoute().Host(tpl) -} - -// MatcherFunc registers a new route with a custom matcher function. -// See Route.MatcherFunc(). -func (r *Router) MatcherFunc(f MatcherFunc) *Route { - return r.NewRoute().MatcherFunc(f) -} - -// Methods registers a new route with a matcher for HTTP methods. -// See Route.Methods(). -func (r *Router) Methods(methods ...string) *Route { - return r.NewRoute().Methods(methods...) -} - -// Path registers a new route with a matcher for the URL path. -// See Route.Path(). -func (r *Router) Path(tpl string) *Route { - return r.NewRoute().Path(tpl) -} - -// PathPrefix registers a new route with a matcher for the URL path prefix. -// See Route.PathPrefix(). -func (r *Router) PathPrefix(tpl string) *Route { - return r.NewRoute().PathPrefix(tpl) -} - -// Queries registers a new route with a matcher for URL query values. -// See Route.Queries(). -func (r *Router) Queries(pairs ...string) *Route { - return r.NewRoute().Queries(pairs...) -} - -// Schemes registers a new route with a matcher for URL schemes. -// See Route.Schemes(). -func (r *Router) Schemes(schemes ...string) *Route { - return r.NewRoute().Schemes(schemes...) -} - -// BuildVarsFunc registers a new route with a custom function for modifying -// route variables before building a URL. -func (r *Router) BuildVarsFunc(f BuildVarsFunc) *Route { - return r.NewRoute().BuildVarsFunc(f) -} - -// Walk walks the router and all its sub-routers, calling walkFn for each route -// in the tree. The routes are walked in the order they were added. Sub-routers -// are explored depth-first. -func (r *Router) Walk(walkFn WalkFunc) error { - return r.walk(walkFn, []*Route{}) -} - -// SkipRouter is used as a return value from WalkFuncs to indicate that the -// router that walk is about to descend down to should be skipped. -var SkipRouter = errors.New("skip this router") - -// WalkFunc is the type of the function called for each route visited by Walk. -// At every invocation, it is given the current route, and the current router, -// and a list of ancestor routes that lead to the current route. -type WalkFunc func(route *Route, router *Router, ancestors []*Route) error - -func (r *Router) walk(walkFn WalkFunc, ancestors []*Route) error { - for _, t := range r.routes { - err := walkFn(t, r, ancestors) - if err == SkipRouter { - continue - } - if err != nil { - return err - } - for _, sr := range t.matchers { - if h, ok := sr.(*Router); ok { - ancestors = append(ancestors, t) - err := h.walk(walkFn, ancestors) - if err != nil { - return err - } - ancestors = ancestors[:len(ancestors)-1] - } - } - if h, ok := t.handler.(*Router); ok { - ancestors = append(ancestors, t) - err := h.walk(walkFn, ancestors) - if err != nil { - return err - } - ancestors = ancestors[:len(ancestors)-1] - } - } - return nil -} - -// ---------------------------------------------------------------------------- -// Context -// ---------------------------------------------------------------------------- - -// RouteMatch stores information about a matched route. -type RouteMatch struct { - Route *Route - Handler http.Handler - Vars map[string]string - - // MatchErr is set to appropriate matching error - // It is set to ErrMethodMismatch if there is a mismatch in - // the request method and route method - MatchErr error -} - -type contextKey int - -const ( - varsKey contextKey = iota - routeKey -) - -// Vars returns the route variables for the current request, if any. -func Vars(r *http.Request) map[string]string { - if rv := r.Context().Value(varsKey); rv != nil { - return rv.(map[string]string) - } - return nil -} - -// CurrentRoute returns the matched route for the current request, if any. -// This only works when called inside the handler of the matched route -// because the matched route is stored in the request context which is cleared -// after the handler returns. -func CurrentRoute(r *http.Request) *Route { - if rv := r.Context().Value(routeKey); rv != nil { - return rv.(*Route) - } - return nil -} - -func requestWithVars(r *http.Request, vars map[string]string) *http.Request { - ctx := context.WithValue(r.Context(), varsKey, vars) - return r.WithContext(ctx) -} - -func requestWithRoute(r *http.Request, route *Route) *http.Request { - ctx := context.WithValue(r.Context(), routeKey, route) - return r.WithContext(ctx) -} - -// ---------------------------------------------------------------------------- -// Helpers -// ---------------------------------------------------------------------------- - -// cleanPath returns the canonical path for p, eliminating . and .. elements. -// Borrowed from the net/http package. -func cleanPath(p string) string { - if p == "" { - return "/" - } - if p[0] != '/' { - p = "/" + p - } - np := path.Clean(p) - // path.Clean removes trailing slash except for root; - // put the trailing slash back if necessary. - if p[len(p)-1] == '/' && np != "/" { - np += "/" - } - - return np -} - -// uniqueVars returns an error if two slices contain duplicated strings. -func uniqueVars(s1, s2 []string) error { - for _, v1 := range s1 { - for _, v2 := range s2 { - if v1 == v2 { - return fmt.Errorf("mux: duplicated route variable %q", v2) - } - } - } - return nil -} - -// checkPairs returns the count of strings passed in, and an error if -// the count is not an even number. -func checkPairs(pairs ...string) (int, error) { - length := len(pairs) - if length%2 != 0 { - return length, fmt.Errorf( - "mux: number of parameters must be multiple of 2, got %v", pairs) - } - return length, nil -} - -// mapFromPairsToString converts variadic string parameters to a -// string to string map. -func mapFromPairsToString(pairs ...string) (map[string]string, error) { - length, err := checkPairs(pairs...) - if err != nil { - return nil, err - } - m := make(map[string]string, length/2) - for i := 0; i < length; i += 2 { - m[pairs[i]] = pairs[i+1] - } - return m, nil -} - -// mapFromPairsToRegex converts variadic string parameters to a -// string to regex map. -func mapFromPairsToRegex(pairs ...string) (map[string]*regexp.Regexp, error) { - length, err := checkPairs(pairs...) - if err != nil { - return nil, err - } - m := make(map[string]*regexp.Regexp, length/2) - for i := 0; i < length; i += 2 { - regex, err := regexp.Compile(pairs[i+1]) - if err != nil { - return nil, err - } - m[pairs[i]] = regex - } - return m, nil -} - -// matchInArray returns true if the given string value is in the array. -func matchInArray(arr []string, value string) bool { - for _, v := range arr { - if v == value { - return true - } - } - return false -} - -// matchMapWithString returns true if the given key/value pairs exist in a given map. -func matchMapWithString(toCheck map[string]string, toMatch map[string][]string, canonicalKey bool) bool { - for k, v := range toCheck { - // Check if key exists. - if canonicalKey { - k = http.CanonicalHeaderKey(k) - } - if values := toMatch[k]; values == nil { - return false - } else if v != "" { - // If value was defined as an empty string we only check that the - // key exists. Otherwise we also check for equality. - valueExists := false - for _, value := range values { - if v == value { - valueExists = true - break - } - } - if !valueExists { - return false - } - } - } - return true -} - -// matchMapWithRegex returns true if the given key/value pairs exist in a given map compiled against -// the given regex -func matchMapWithRegex(toCheck map[string]*regexp.Regexp, toMatch map[string][]string, canonicalKey bool) bool { - for k, v := range toCheck { - // Check if key exists. - if canonicalKey { - k = http.CanonicalHeaderKey(k) - } - if values := toMatch[k]; values == nil { - return false - } else if v != nil { - // If value was defined as an empty string we only check that the - // key exists. Otherwise we also check for equality. - valueExists := false - for _, value := range values { - if v.MatchString(value) { - valueExists = true - break - } - } - if !valueExists { - return false - } - } - } - return true -} - -// methodNotAllowed replies to the request with an HTTP status code 405. -func methodNotAllowed(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusMethodNotAllowed) -} - -// methodNotAllowedHandler returns a simple request handler -// that replies to each request with a status code 405. -func methodNotAllowedHandler() http.Handler { return http.HandlerFunc(methodNotAllowed) } diff --git a/vendor/github.com/gorilla/mux/regexp.go b/vendor/github.com/gorilla/mux/regexp.go deleted file mode 100644 index 5d05cfa0e..000000000 --- a/vendor/github.com/gorilla/mux/regexp.go +++ /dev/null @@ -1,388 +0,0 @@ -// Copyright 2012 The Gorilla 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 mux - -import ( - "bytes" - "fmt" - "net/http" - "net/url" - "regexp" - "strconv" - "strings" -) - -type routeRegexpOptions struct { - strictSlash bool - useEncodedPath bool -} - -type regexpType int - -const ( - regexpTypePath regexpType = iota - regexpTypeHost - regexpTypePrefix - regexpTypeQuery -) - -// newRouteRegexp parses a route template and returns a routeRegexp, -// used to match a host, a path or a query string. -// -// It will extract named variables, assemble a regexp to be matched, create -// a "reverse" template to build URLs and compile regexps to validate variable -// values used in URL building. -// -// Previously we accepted only Python-like identifiers for variable -// names ([a-zA-Z_][a-zA-Z0-9_]*), but currently the only restriction is that -// name and pattern can't be empty, and names can't contain a colon. -func newRouteRegexp(tpl string, typ regexpType, options routeRegexpOptions) (*routeRegexp, error) { - // Check if it is well-formed. - idxs, errBraces := braceIndices(tpl) - if errBraces != nil { - return nil, errBraces - } - // Backup the original. - template := tpl - // Now let's parse it. - defaultPattern := "[^/]+" - if typ == regexpTypeQuery { - defaultPattern = ".*" - } else if typ == regexpTypeHost { - defaultPattern = "[^.]+" - } - // Only match strict slash if not matching - if typ != regexpTypePath { - options.strictSlash = false - } - // Set a flag for strictSlash. - endSlash := false - if options.strictSlash && strings.HasSuffix(tpl, "/") { - tpl = tpl[:len(tpl)-1] - endSlash = true - } - varsN := make([]string, len(idxs)/2) - varsR := make([]*regexp.Regexp, len(idxs)/2) - pattern := bytes.NewBufferString("") - pattern.WriteByte('^') - reverse := bytes.NewBufferString("") - var end int - var err error - for i := 0; i < len(idxs); i += 2 { - // Set all values we are interested in. - raw := tpl[end:idxs[i]] - end = idxs[i+1] - parts := strings.SplitN(tpl[idxs[i]+1:end-1], ":", 2) - name := parts[0] - patt := defaultPattern - if len(parts) == 2 { - patt = parts[1] - } - // Name or pattern can't be empty. - if name == "" || patt == "" { - return nil, fmt.Errorf("mux: missing name or pattern in %q", - tpl[idxs[i]:end]) - } - // Build the regexp pattern. - fmt.Fprintf(pattern, "%s(?P<%s>%s)", regexp.QuoteMeta(raw), varGroupName(i/2), patt) - - // Build the reverse template. - fmt.Fprintf(reverse, "%s%%s", raw) - - // Append variable name and compiled pattern. - varsN[i/2] = name - varsR[i/2], err = regexp.Compile(fmt.Sprintf("^%s$", patt)) - if err != nil { - return nil, err - } - } - // Add the remaining. - raw := tpl[end:] - pattern.WriteString(regexp.QuoteMeta(raw)) - if options.strictSlash { - pattern.WriteString("[/]?") - } - if typ == regexpTypeQuery { - // Add the default pattern if the query value is empty - if queryVal := strings.SplitN(template, "=", 2)[1]; queryVal == "" { - pattern.WriteString(defaultPattern) - } - } - if typ != regexpTypePrefix { - pattern.WriteByte('$') - } - - var wildcardHostPort bool - if typ == regexpTypeHost { - if !strings.Contains(pattern.String(), ":") { - wildcardHostPort = true - } - } - reverse.WriteString(raw) - if endSlash { - reverse.WriteByte('/') - } - // Compile full regexp. - reg, errCompile := regexp.Compile(pattern.String()) - if errCompile != nil { - return nil, errCompile - } - - // Check for capturing groups which used to work in older versions - if reg.NumSubexp() != len(idxs)/2 { - panic(fmt.Sprintf("route %s contains capture groups in its regexp. ", template) + - "Only non-capturing groups are accepted: e.g. (?:pattern) instead of (pattern)") - } - - // Done! - return &routeRegexp{ - template: template, - regexpType: typ, - options: options, - regexp: reg, - reverse: reverse.String(), - varsN: varsN, - varsR: varsR, - wildcardHostPort: wildcardHostPort, - }, nil -} - -// routeRegexp stores a regexp to match a host or path and information to -// collect and validate route variables. -type routeRegexp struct { - // The unmodified template. - template string - // The type of match - regexpType regexpType - // Options for matching - options routeRegexpOptions - // Expanded regexp. - regexp *regexp.Regexp - // Reverse template. - reverse string - // Variable names. - varsN []string - // Variable regexps (validators). - varsR []*regexp.Regexp - // Wildcard host-port (no strict port match in hostname) - wildcardHostPort bool -} - -// Match matches the regexp against the URL host or path. -func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool { - if r.regexpType == regexpTypeHost { - host := getHost(req) - if r.wildcardHostPort { - // Don't be strict on the port match - if i := strings.Index(host, ":"); i != -1 { - host = host[:i] - } - } - return r.regexp.MatchString(host) - } - - if r.regexpType == regexpTypeQuery { - return r.matchQueryString(req) - } - path := req.URL.Path - if r.options.useEncodedPath { - path = req.URL.EscapedPath() - } - return r.regexp.MatchString(path) -} - -// url builds a URL part using the given values. -func (r *routeRegexp) url(values map[string]string) (string, error) { - urlValues := make([]interface{}, len(r.varsN)) - for k, v := range r.varsN { - value, ok := values[v] - if !ok { - return "", fmt.Errorf("mux: missing route variable %q", v) - } - if r.regexpType == regexpTypeQuery { - value = url.QueryEscape(value) - } - urlValues[k] = value - } - rv := fmt.Sprintf(r.reverse, urlValues...) - if !r.regexp.MatchString(rv) { - // The URL is checked against the full regexp, instead of checking - // individual variables. This is faster but to provide a good error - // message, we check individual regexps if the URL doesn't match. - for k, v := range r.varsN { - if !r.varsR[k].MatchString(values[v]) { - return "", fmt.Errorf( - "mux: variable %q doesn't match, expected %q", values[v], - r.varsR[k].String()) - } - } - } - return rv, nil -} - -// getURLQuery returns a single query parameter from a request URL. -// For a URL with foo=bar&baz=ding, we return only the relevant key -// value pair for the routeRegexp. -func (r *routeRegexp) getURLQuery(req *http.Request) string { - if r.regexpType != regexpTypeQuery { - return "" - } - templateKey := strings.SplitN(r.template, "=", 2)[0] - val, ok := findFirstQueryKey(req.URL.RawQuery, templateKey) - if ok { - return templateKey + "=" + val - } - return "" -} - -// findFirstQueryKey returns the same result as (*url.URL).Query()[key][0]. -// If key was not found, empty string and false is returned. -func findFirstQueryKey(rawQuery, key string) (value string, ok bool) { - query := []byte(rawQuery) - for len(query) > 0 { - foundKey := query - if i := bytes.IndexAny(foundKey, "&;"); i >= 0 { - foundKey, query = foundKey[:i], foundKey[i+1:] - } else { - query = query[:0] - } - if len(foundKey) == 0 { - continue - } - var value []byte - if i := bytes.IndexByte(foundKey, '='); i >= 0 { - foundKey, value = foundKey[:i], foundKey[i+1:] - } - if len(foundKey) < len(key) { - // Cannot possibly be key. - continue - } - keyString, err := url.QueryUnescape(string(foundKey)) - if err != nil { - continue - } - if keyString != key { - continue - } - valueString, err := url.QueryUnescape(string(value)) - if err != nil { - continue - } - return valueString, true - } - return "", false -} - -func (r *routeRegexp) matchQueryString(req *http.Request) bool { - return r.regexp.MatchString(r.getURLQuery(req)) -} - -// braceIndices returns the first level curly brace indices from a string. -// It returns an error in case of unbalanced braces. -func braceIndices(s string) ([]int, error) { - var level, idx int - var idxs []int - for i := 0; i < len(s); i++ { - switch s[i] { - case '{': - if level++; level == 1 { - idx = i - } - case '}': - if level--; level == 0 { - idxs = append(idxs, idx, i+1) - } else if level < 0 { - return nil, fmt.Errorf("mux: unbalanced braces in %q", s) - } - } - } - if level != 0 { - return nil, fmt.Errorf("mux: unbalanced braces in %q", s) - } - return idxs, nil -} - -// varGroupName builds a capturing group name for the indexed variable. -func varGroupName(idx int) string { - return "v" + strconv.Itoa(idx) -} - -// ---------------------------------------------------------------------------- -// routeRegexpGroup -// ---------------------------------------------------------------------------- - -// routeRegexpGroup groups the route matchers that carry variables. -type routeRegexpGroup struct { - host *routeRegexp - path *routeRegexp - queries []*routeRegexp -} - -// setMatch extracts the variables from the URL once a route matches. -func (v routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) { - // Store host variables. - if v.host != nil { - host := getHost(req) - if v.host.wildcardHostPort { - // Don't be strict on the port match - if i := strings.Index(host, ":"); i != -1 { - host = host[:i] - } - } - matches := v.host.regexp.FindStringSubmatchIndex(host) - if len(matches) > 0 { - extractVars(host, matches, v.host.varsN, m.Vars) - } - } - path := req.URL.Path - if r.useEncodedPath { - path = req.URL.EscapedPath() - } - // Store path variables. - if v.path != nil { - matches := v.path.regexp.FindStringSubmatchIndex(path) - if len(matches) > 0 { - extractVars(path, matches, v.path.varsN, m.Vars) - // Check if we should redirect. - if v.path.options.strictSlash { - p1 := strings.HasSuffix(path, "/") - p2 := strings.HasSuffix(v.path.template, "/") - if p1 != p2 { - u, _ := url.Parse(req.URL.String()) - if p1 { - u.Path = u.Path[:len(u.Path)-1] - } else { - u.Path += "/" - } - m.Handler = http.RedirectHandler(u.String(), http.StatusMovedPermanently) - } - } - } - } - // Store query string variables. - for _, q := range v.queries { - queryURL := q.getURLQuery(req) - matches := q.regexp.FindStringSubmatchIndex(queryURL) - if len(matches) > 0 { - extractVars(queryURL, matches, q.varsN, m.Vars) - } - } -} - -// getHost tries its best to return the request host. -// According to section 14.23 of RFC 2616 the Host header -// can include the port number if the default value of 80 is not used. -func getHost(r *http.Request) string { - if r.URL.IsAbs() { - return r.URL.Host - } - return r.Host -} - -func extractVars(input string, matches []int, names []string, output map[string]string) { - for i, name := range names { - output[name] = input[matches[2*i+2]:matches[2*i+3]] - } -} diff --git a/vendor/github.com/gorilla/mux/route.go b/vendor/github.com/gorilla/mux/route.go deleted file mode 100644 index e8f11df22..000000000 --- a/vendor/github.com/gorilla/mux/route.go +++ /dev/null @@ -1,765 +0,0 @@ -// Copyright 2012 The Gorilla 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 mux - -import ( - "errors" - "fmt" - "net/http" - "net/url" - "regexp" - "strings" -) - -// Route stores information to match a request and build URLs. -type Route struct { - // Request handler for the route. - handler http.Handler - // If true, this route never matches: it is only used to build URLs. - buildOnly bool - // The name used to build URLs. - name string - // Error resulted from building a route. - err error - - // "global" reference to all named routes - namedRoutes map[string]*Route - - // config possibly passed in from `Router` - routeConf -} - -// SkipClean reports whether path cleaning is enabled for this route via -// Router.SkipClean. -func (r *Route) SkipClean() bool { - return r.skipClean -} - -// Match matches the route against the request. -func (r *Route) Match(req *http.Request, match *RouteMatch) bool { - if r.buildOnly || r.err != nil { - return false - } - - var matchErr error - - // Match everything. - for _, m := range r.matchers { - if matched := m.Match(req, match); !matched { - if _, ok := m.(methodMatcher); ok { - matchErr = ErrMethodMismatch - continue - } - - // Ignore ErrNotFound errors. These errors arise from match call - // to Subrouters. - // - // This prevents subsequent matching subrouters from failing to - // run middleware. If not ignored, the middleware would see a - // non-nil MatchErr and be skipped, even when there was a - // matching route. - if match.MatchErr == ErrNotFound { - match.MatchErr = nil - } - - matchErr = nil // nolint:ineffassign - return false - } else { - // Multiple routes may share the same path but use different HTTP methods. For instance: - // Route 1: POST "/users/{id}". - // Route 2: GET "/users/{id}", parameters: "id": "[0-9]+". - // - // The router must handle these cases correctly. For a GET request to "/users/abc" with "id" as "-2", - // The router should return a "Not Found" error as no route fully matches this request. - if match.MatchErr == ErrMethodMismatch { - match.MatchErr = nil - } - } - } - - if matchErr != nil { - match.MatchErr = matchErr - return false - } - - if match.MatchErr == ErrMethodMismatch && r.handler != nil { - // We found a route which matches request method, clear MatchErr - match.MatchErr = nil - // Then override the mis-matched handler - match.Handler = r.handler - } - - // Yay, we have a match. Let's collect some info about it. - if match.Route == nil { - match.Route = r - } - if match.Handler == nil { - match.Handler = r.handler - } - if match.Vars == nil { - match.Vars = make(map[string]string) - } - - // Set variables. - r.regexp.setMatch(req, match, r) - return true -} - -// ---------------------------------------------------------------------------- -// Route attributes -// ---------------------------------------------------------------------------- - -// GetError returns an error resulted from building the route, if any. -func (r *Route) GetError() error { - return r.err -} - -// BuildOnly sets the route to never match: it is only used to build URLs. -func (r *Route) BuildOnly() *Route { - r.buildOnly = true - return r -} - -// Handler -------------------------------------------------------------------- - -// Handler sets a handler for the route. -func (r *Route) Handler(handler http.Handler) *Route { - if r.err == nil { - r.handler = handler - } - return r -} - -// HandlerFunc sets a handler function for the route. -func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)) *Route { - return r.Handler(http.HandlerFunc(f)) -} - -// GetHandler returns the handler for the route, if any. -func (r *Route) GetHandler() http.Handler { - return r.handler -} - -// Name ----------------------------------------------------------------------- - -// Name sets the name for the route, used to build URLs. -// It is an error to call Name more than once on a route. -func (r *Route) Name(name string) *Route { - if r.name != "" { - r.err = fmt.Errorf("mux: route already has name %q, can't set %q", - r.name, name) - } - if r.err == nil { - r.name = name - r.namedRoutes[name] = r - } - return r -} - -// GetName returns the name for the route, if any. -func (r *Route) GetName() string { - return r.name -} - -// ---------------------------------------------------------------------------- -// Matchers -// ---------------------------------------------------------------------------- - -// matcher types try to match a request. -type matcher interface { - Match(*http.Request, *RouteMatch) bool -} - -// addMatcher adds a matcher to the route. -func (r *Route) addMatcher(m matcher) *Route { - if r.err == nil { - r.matchers = append(r.matchers, m) - } - return r -} - -// addRegexpMatcher adds a host or path matcher and builder to a route. -func (r *Route) addRegexpMatcher(tpl string, typ regexpType) error { - if r.err != nil { - return r.err - } - if typ == regexpTypePath || typ == regexpTypePrefix { - if len(tpl) > 0 && tpl[0] != '/' { - return fmt.Errorf("mux: path must start with a slash, got %q", tpl) - } - if r.regexp.path != nil { - tpl = strings.TrimRight(r.regexp.path.template, "/") + tpl - } - } - rr, err := newRouteRegexp(tpl, typ, routeRegexpOptions{ - strictSlash: r.strictSlash, - useEncodedPath: r.useEncodedPath, - }) - if err != nil { - return err - } - for _, q := range r.regexp.queries { - if err = uniqueVars(rr.varsN, q.varsN); err != nil { - return err - } - } - if typ == regexpTypeHost { - if r.regexp.path != nil { - if err = uniqueVars(rr.varsN, r.regexp.path.varsN); err != nil { - return err - } - } - r.regexp.host = rr - } else { - if r.regexp.host != nil { - if err = uniqueVars(rr.varsN, r.regexp.host.varsN); err != nil { - return err - } - } - if typ == regexpTypeQuery { - r.regexp.queries = append(r.regexp.queries, rr) - } else { - r.regexp.path = rr - } - } - r.addMatcher(rr) - return nil -} - -// Headers -------------------------------------------------------------------- - -// headerMatcher matches the request against header values. -type headerMatcher map[string]string - -func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool { - return matchMapWithString(m, r.Header, true) -} - -// Headers adds a matcher for request header values. -// It accepts a sequence of key/value pairs to be matched. For example: -// -// r := mux.NewRouter().NewRoute() -// r.Headers("Content-Type", "application/json", -// "X-Requested-With", "XMLHttpRequest") -// -// The above route will only match if both request header values match. -// If the value is an empty string, it will match any value if the key is set. -func (r *Route) Headers(pairs ...string) *Route { - if r.err == nil { - var headers map[string]string - headers, r.err = mapFromPairsToString(pairs...) - return r.addMatcher(headerMatcher(headers)) - } - return r -} - -// headerRegexMatcher matches the request against the route given a regex for the header -type headerRegexMatcher map[string]*regexp.Regexp - -func (m headerRegexMatcher) Match(r *http.Request, match *RouteMatch) bool { - return matchMapWithRegex(m, r.Header, true) -} - -// HeadersRegexp accepts a sequence of key/value pairs, where the value has regex -// support. For example: -// -// r := mux.NewRouter().NewRoute() -// r.HeadersRegexp("Content-Type", "application/(text|json)", -// "X-Requested-With", "XMLHttpRequest") -// -// The above route will only match if both the request header matches both regular expressions. -// If the value is an empty string, it will match any value if the key is set. -// Use the start and end of string anchors (^ and $) to match an exact value. -func (r *Route) HeadersRegexp(pairs ...string) *Route { - if r.err == nil { - var headers map[string]*regexp.Regexp - headers, r.err = mapFromPairsToRegex(pairs...) - return r.addMatcher(headerRegexMatcher(headers)) - } - return r -} - -// Host ----------------------------------------------------------------------- - -// Host adds a matcher for the URL host. -// It accepts a template with zero or more URL variables enclosed by {}. -// Variables can define an optional regexp pattern to be matched: -// -// - {name} matches anything until the next dot. -// -// - {name:pattern} matches the given regexp pattern. -// -// For example: -// -// r := mux.NewRouter().NewRoute() -// r.Host("www.example.com") -// r.Host("{subdomain}.domain.com") -// r.Host("{subdomain:[a-z]+}.domain.com") -// -// Variable names must be unique in a given route. They can be retrieved -// calling mux.Vars(request). -func (r *Route) Host(tpl string) *Route { - r.err = r.addRegexpMatcher(tpl, regexpTypeHost) - return r -} - -// MatcherFunc ---------------------------------------------------------------- - -// MatcherFunc is the function signature used by custom matchers. -type MatcherFunc func(*http.Request, *RouteMatch) bool - -// Match returns the match for a given request. -func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool { - return m(r, match) -} - -// MatcherFunc adds a custom function to be used as request matcher. -func (r *Route) MatcherFunc(f MatcherFunc) *Route { - return r.addMatcher(f) -} - -// Methods -------------------------------------------------------------------- - -// methodMatcher matches the request against HTTP methods. -type methodMatcher []string - -func (m methodMatcher) Match(r *http.Request, match *RouteMatch) bool { - return matchInArray(m, r.Method) -} - -// Methods adds a matcher for HTTP methods. -// It accepts a sequence of one or more methods to be matched, e.g.: -// "GET", "POST", "PUT". -func (r *Route) Methods(methods ...string) *Route { - for k, v := range methods { - methods[k] = strings.ToUpper(v) - } - return r.addMatcher(methodMatcher(methods)) -} - -// Path ----------------------------------------------------------------------- - -// Path adds a matcher for the URL path. -// It accepts a template with zero or more URL variables enclosed by {}. The -// template must start with a "/". -// Variables can define an optional regexp pattern to be matched: -// -// - {name} matches anything until the next slash. -// -// - {name:pattern} matches the given regexp pattern. -// -// For example: -// -// r := mux.NewRouter().NewRoute() -// r.Path("/products/").Handler(ProductsHandler) -// r.Path("/products/{key}").Handler(ProductsHandler) -// r.Path("/articles/{category}/{id:[0-9]+}"). -// Handler(ArticleHandler) -// -// Variable names must be unique in a given route. They can be retrieved -// calling mux.Vars(request). -func (r *Route) Path(tpl string) *Route { - r.err = r.addRegexpMatcher(tpl, regexpTypePath) - return r -} - -// PathPrefix ----------------------------------------------------------------- - -// PathPrefix adds a matcher for the URL path prefix. This matches if the given -// template is a prefix of the full URL path. See Route.Path() for details on -// the tpl argument. -// -// Note that it does not treat slashes specially ("/foobar/" will be matched by -// the prefix "/foo") so you may want to use a trailing slash here. -// -// Also note that the setting of Router.StrictSlash() has no effect on routes -// with a PathPrefix matcher. -func (r *Route) PathPrefix(tpl string) *Route { - r.err = r.addRegexpMatcher(tpl, regexpTypePrefix) - return r -} - -// Query ---------------------------------------------------------------------- - -// Queries adds a matcher for URL query values. -// It accepts a sequence of key/value pairs. Values may define variables. -// For example: -// -// r := mux.NewRouter().NewRoute() -// r.Queries("foo", "bar", "id", "{id:[0-9]+}") -// -// The above route will only match if the URL contains the defined queries -// values, e.g.: ?foo=bar&id=42. -// -// If the value is an empty string, it will match any value if the key is set. -// -// Variables can define an optional regexp pattern to be matched: -// -// - {name} matches anything until the next slash. -// -// - {name:pattern} matches the given regexp pattern. -func (r *Route) Queries(pairs ...string) *Route { - length := len(pairs) - if length%2 != 0 { - r.err = fmt.Errorf( - "mux: number of parameters must be multiple of 2, got %v", pairs) - return nil - } - for i := 0; i < length; i += 2 { - if r.err = r.addRegexpMatcher(pairs[i]+"="+pairs[i+1], regexpTypeQuery); r.err != nil { - return r - } - } - - return r -} - -// Schemes -------------------------------------------------------------------- - -// schemeMatcher matches the request against URL schemes. -type schemeMatcher []string - -func (m schemeMatcher) Match(r *http.Request, match *RouteMatch) bool { - scheme := r.URL.Scheme - // https://golang.org/pkg/net/http/#Request - // "For [most] server requests, fields other than Path and RawQuery will be - // empty." - // Since we're an http muxer, the scheme is either going to be http or https - // though, so we can just set it based on the tls termination state. - if scheme == "" { - if r.TLS == nil { - scheme = "http" - } else { - scheme = "https" - } - } - return matchInArray(m, scheme) -} - -// Schemes adds a matcher for URL schemes. -// It accepts a sequence of schemes to be matched, e.g.: "http", "https". -// If the request's URL has a scheme set, it will be matched against. -// Generally, the URL scheme will only be set if a previous handler set it, -// such as the ProxyHeaders handler from gorilla/handlers. -// If unset, the scheme will be determined based on the request's TLS -// termination state. -// The first argument to Schemes will be used when constructing a route URL. -func (r *Route) Schemes(schemes ...string) *Route { - for k, v := range schemes { - schemes[k] = strings.ToLower(v) - } - if len(schemes) > 0 { - r.buildScheme = schemes[0] - } - return r.addMatcher(schemeMatcher(schemes)) -} - -// BuildVarsFunc -------------------------------------------------------------- - -// BuildVarsFunc is the function signature used by custom build variable -// functions (which can modify route variables before a route's URL is built). -type BuildVarsFunc func(map[string]string) map[string]string - -// BuildVarsFunc adds a custom function to be used to modify build variables -// before a route's URL is built. -func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route { - if r.buildVarsFunc != nil { - // compose the old and new functions - old := r.buildVarsFunc - r.buildVarsFunc = func(m map[string]string) map[string]string { - return f(old(m)) - } - } else { - r.buildVarsFunc = f - } - return r -} - -// Subrouter ------------------------------------------------------------------ - -// Subrouter creates a subrouter for the route. -// -// It will test the inner routes only if the parent route matched. For example: -// -// r := mux.NewRouter().NewRoute() -// s := r.Host("www.example.com").Subrouter() -// s.HandleFunc("/products/", ProductsHandler) -// s.HandleFunc("/products/{key}", ProductHandler) -// s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) -// -// Here, the routes registered in the subrouter won't be tested if the host -// doesn't match. -func (r *Route) Subrouter() *Router { - // initialize a subrouter with a copy of the parent route's configuration - router := &Router{routeConf: copyRouteConf(r.routeConf), namedRoutes: r.namedRoutes} - r.addMatcher(router) - return router -} - -// ---------------------------------------------------------------------------- -// URL building -// ---------------------------------------------------------------------------- - -// URL builds a URL for the route. -// -// It accepts a sequence of key/value pairs for the route variables. For -// example, given this route: -// -// r := mux.NewRouter() -// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). -// Name("article") -// -// ...a URL for it can be built using: -// -// url, err := r.Get("article").URL("category", "technology", "id", "42") -// -// ...which will return an url.URL with the following path: -// -// "/articles/technology/42" -// -// This also works for host variables: -// -// r := mux.NewRouter() -// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). -// Host("{subdomain}.domain.com"). -// Name("article") -// -// // url.String() will be "http://news.domain.com/articles/technology/42" -// url, err := r.Get("article").URL("subdomain", "news", -// "category", "technology", -// "id", "42") -// -// The scheme of the resulting url will be the first argument that was passed to Schemes: -// -// // url.String() will be "https://example.com" -// r := mux.NewRouter().NewRoute() -// url, err := r.Host("example.com") -// .Schemes("https", "http").URL() -// -// All variables defined in the route are required, and their values must -// conform to the corresponding patterns. -func (r *Route) URL(pairs ...string) (*url.URL, error) { - if r.err != nil { - return nil, r.err - } - values, err := r.prepareVars(pairs...) - if err != nil { - return nil, err - } - var scheme, host, path string - queries := make([]string, 0, len(r.regexp.queries)) - if r.regexp.host != nil { - if host, err = r.regexp.host.url(values); err != nil { - return nil, err - } - scheme = "http" - if r.buildScheme != "" { - scheme = r.buildScheme - } - } - if r.regexp.path != nil { - if path, err = r.regexp.path.url(values); err != nil { - return nil, err - } - } - for _, q := range r.regexp.queries { - var query string - if query, err = q.url(values); err != nil { - return nil, err - } - queries = append(queries, query) - } - return &url.URL{ - Scheme: scheme, - Host: host, - Path: path, - RawQuery: strings.Join(queries, "&"), - }, nil -} - -// URLHost builds the host part of the URL for a route. See Route.URL(). -// -// The route must have a host defined. -func (r *Route) URLHost(pairs ...string) (*url.URL, error) { - if r.err != nil { - return nil, r.err - } - if r.regexp.host == nil { - return nil, errors.New("mux: route doesn't have a host") - } - values, err := r.prepareVars(pairs...) - if err != nil { - return nil, err - } - host, err := r.regexp.host.url(values) - if err != nil { - return nil, err - } - u := &url.URL{ - Scheme: "http", - Host: host, - } - if r.buildScheme != "" { - u.Scheme = r.buildScheme - } - return u, nil -} - -// URLPath builds the path part of the URL for a route. See Route.URL(). -// -// The route must have a path defined. -func (r *Route) URLPath(pairs ...string) (*url.URL, error) { - if r.err != nil { - return nil, r.err - } - if r.regexp.path == nil { - return nil, errors.New("mux: route doesn't have a path") - } - values, err := r.prepareVars(pairs...) - if err != nil { - return nil, err - } - path, err := r.regexp.path.url(values) - if err != nil { - return nil, err - } - return &url.URL{ - Path: path, - }, nil -} - -// GetPathTemplate returns the template used to build the -// route match. -// This is useful for building simple REST API documentation and for instrumentation -// against third-party services. -// An error will be returned if the route does not define a path. -func (r *Route) GetPathTemplate() (string, error) { - if r.err != nil { - return "", r.err - } - if r.regexp.path == nil { - return "", errors.New("mux: route doesn't have a path") - } - return r.regexp.path.template, nil -} - -// GetPathRegexp returns the expanded regular expression used to match route path. -// This is useful for building simple REST API documentation and for instrumentation -// against third-party services. -// An error will be returned if the route does not define a path. -func (r *Route) GetPathRegexp() (string, error) { - if r.err != nil { - return "", r.err - } - if r.regexp.path == nil { - return "", errors.New("mux: route does not have a path") - } - return r.regexp.path.regexp.String(), nil -} - -// GetQueriesRegexp returns the expanded regular expressions used to match the -// route queries. -// This is useful for building simple REST API documentation and for instrumentation -// against third-party services. -// An error will be returned if the route does not have queries. -func (r *Route) GetQueriesRegexp() ([]string, error) { - if r.err != nil { - return nil, r.err - } - if r.regexp.queries == nil { - return nil, errors.New("mux: route doesn't have queries") - } - queries := make([]string, 0, len(r.regexp.queries)) - for _, query := range r.regexp.queries { - queries = append(queries, query.regexp.String()) - } - return queries, nil -} - -// GetQueriesTemplates returns the templates used to build the -// query matching. -// This is useful for building simple REST API documentation and for instrumentation -// against third-party services. -// An error will be returned if the route does not define queries. -func (r *Route) GetQueriesTemplates() ([]string, error) { - if r.err != nil { - return nil, r.err - } - if r.regexp.queries == nil { - return nil, errors.New("mux: route doesn't have queries") - } - queries := make([]string, 0, len(r.regexp.queries)) - for _, query := range r.regexp.queries { - queries = append(queries, query.template) - } - return queries, nil -} - -// GetMethods returns the methods the route matches against -// This is useful for building simple REST API documentation and for instrumentation -// against third-party services. -// An error will be returned if route does not have methods. -func (r *Route) GetMethods() ([]string, error) { - if r.err != nil { - return nil, r.err - } - for _, m := range r.matchers { - if methods, ok := m.(methodMatcher); ok { - return []string(methods), nil - } - } - return nil, errors.New("mux: route doesn't have methods") -} - -// GetHostTemplate returns the template used to build the -// route match. -// This is useful for building simple REST API documentation and for instrumentation -// against third-party services. -// An error will be returned if the route does not define a host. -func (r *Route) GetHostTemplate() (string, error) { - if r.err != nil { - return "", r.err - } - if r.regexp.host == nil { - return "", errors.New("mux: route doesn't have a host") - } - return r.regexp.host.template, nil -} - -// GetVarNames returns the names of all variables added by regexp matchers -// These can be used to know which route variables should be passed into r.URL() -func (r *Route) GetVarNames() ([]string, error) { - if r.err != nil { - return nil, r.err - } - var varNames []string - if r.regexp.host != nil { - varNames = append(varNames, r.regexp.host.varsN...) - } - if r.regexp.path != nil { - varNames = append(varNames, r.regexp.path.varsN...) - } - for _, regx := range r.regexp.queries { - varNames = append(varNames, regx.varsN...) - } - return varNames, nil -} - -// prepareVars converts the route variable pairs into a map. If the route has a -// BuildVarsFunc, it is invoked. -func (r *Route) prepareVars(pairs ...string) (map[string]string, error) { - m, err := mapFromPairsToString(pairs...) - if err != nil { - return nil, err - } - return r.buildVars(m), nil -} - -func (r *Route) buildVars(m map[string]string) map[string]string { - if r.buildVarsFunc != nil { - m = r.buildVarsFunc(m) - } - return m -} diff --git a/vendor/github.com/gorilla/mux/test_helpers.go b/vendor/github.com/gorilla/mux/test_helpers.go deleted file mode 100644 index 5f5c496de..000000000 --- a/vendor/github.com/gorilla/mux/test_helpers.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2012 The Gorilla 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 mux - -import "net/http" - -// SetURLVars sets the URL variables for the given request, to be accessed via -// mux.Vars for testing route behaviour. Arguments are not modified, a shallow -// copy is returned. -// -// This API should only be used for testing purposes; it provides a way to -// inject variables into the request context. Alternatively, URL variables -// can be set by making a route that captures the required variables, -// starting a server and sending the request to that server. -func SetURLVars(r *http.Request, val map[string]string) *http.Request { - return requestWithVars(r, val) -} diff --git a/vendor/github.com/gostaticanalysis/analysisutil/LICENSE b/vendor/github.com/gostaticanalysis/analysisutil/LICENSE deleted file mode 100644 index bf7e33db8..000000000 --- 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 d8fd3d2a4..000000000 --- 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 e3d98d1dc..000000000 --- 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 a911db6f1..000000000 --- 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 b9b295530..000000000 --- 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 b64150d81..000000000 --- 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 2e22bbe79..000000000 --- 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 b2ae75f24..000000000 --- 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 8265efc8e..000000000 --- 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/LICENSE b/vendor/github.com/gostaticanalysis/comment/LICENSE deleted file mode 100644 index 4f7eeff5b..000000000 --- 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 533555313..000000000 --- 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 79cb09382..000000000 --- a/vendor/github.com/gostaticanalysis/comment/comment.go +++ /dev/null @@ -1,152 +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 -} - -// 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 -} - -// 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 1b60a160c..000000000 --- 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/forcetypeassert/.reviewdog.yml b/vendor/github.com/gostaticanalysis/forcetypeassert/.reviewdog.yml deleted file mode 100644 index 2e243ff73..000000000 --- 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/LICENSE b/vendor/github.com/gostaticanalysis/forcetypeassert/LICENSE deleted file mode 100644 index bf7e33db8..000000000 --- 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 36a47594e..000000000 --- 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 bb48485d9..000000000 --- a/vendor/github.com/gostaticanalysis/forcetypeassert/forcetypeassert.go +++ /dev/null @@ -1,143 +0,0 @@ -package forcetypeassert - -import ( - "go/ast" - "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" - -func run(pass *analysis.Pass) (interface{}, 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 { - 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 checkAssignStmt(pass *analysis.Pass, result *Panicable, n *ast.AssignStmt) bool { - tae := findTypeAssertion(n.Rhs) - if tae == nil { - return true - } - - switch { - // 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: - 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 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: - 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 -} diff --git a/vendor/github.com/gostaticanalysis/nilerr/LICENSE b/vendor/github.com/gostaticanalysis/nilerr/LICENSE deleted file mode 100644 index bf7e33db8..000000000 --- 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 d6b4acf8b..000000000 --- a/vendor/github.com/gostaticanalysis/nilerr/README.md +++ /dev/null @@ -1,41 +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 - } -} -``` - - -[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 787a9e1e9..000000000 --- a/vendor/github.com/gostaticanalysis/nilerr/nilerr.go +++ /dev/null @@ -1,291 +0,0 @@ -package nilerr - -import ( - "fmt" - "go/token" - "go/types" - - "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() - line := getNodeLineNumber(pass, ret) - errLines := getValueLineNumbers(pass, v) - if !cmaps.IgnoreLine(pass.Fset, line, "nilerr") { - 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 -} - -func getValueLineNumbers(pass *analysis.Pass, v ssa.Value) []int { - if phi, ok := v.(*ssa.Phi); ok { - result := make([]int, 0, len(phi.Edges)) - for _, edge := range phi.Edges { - result = append(result, getValueLineNumbers(pass, edge)...) - } - return result - } - - value := v - if extract, ok := value.(*ssa.Extract); ok { - value = extract.Tuple - } - - pos := value.Pos() - return []int{pass.Fset.File(pos).Line(pos)} -} - -func getNodeLineNumber(pass *analysis.Pass, node ssa.Node) int { - pos := node.Pos() - return 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/grpc-ecosystem/go-grpc-middleware/.gitignore b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.gitignore deleted file mode 100644 index 826caa390..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.gitignore +++ /dev/null @@ -1,204 +0,0 @@ -# Created by .ignore support plugin (hsz.mobi) -### Go template -# 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 -### Windows template -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# Windows shortcuts -*.lnk -### Kate template -# Swap Files # -.*.kate-swp -.swp.* -### SublimeText template -# cache files for sublime text -*.tmlanguage.cache -*.tmPreferences.cache -*.stTheme.cache - -# workspace files are user-specific -*.sublime-workspace - -# project files should be checked into the repository, unless a significant -# proportion of contributors will probably not be using SublimeText -# *.sublime-project - -# sftp configuration file -sftp-config.json -### Linux template -*~ - -# 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-* -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff: -.idea -.idea/tasks.xml -.idea/dictionaries -.idea/vcs.xml -.idea/jsLibraryMappings.xml - -# Sensitive or high-churn files: -.idea/dataSources.ids -.idea/dataSources.xml -.idea/dataSources.local.xml -.idea/sqlDataSources.xml -.idea/dynamic.xml -.idea/uiDesigner.xml - -# Gradle: -.idea/gradle.xml -.idea/libraries - -# Mongo Explorer plugin: -.idea/mongoSettings.xml - -## File-based project format: -*.iws - -## Plugin-specific files: - -# IntelliJ -/out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties -### Xcode template -# Xcode -# -# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - -## Build generated -build/ -DerivedData/ - -## Various settings -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata/ - -## Other -*.moved-aside -*.xccheckout -*.xcscmblueprint -### Eclipse template - -.metadata -bin/ -tmp/ -*.tmp -*.bak -*.swp -*~.nib -local.properties -.settings/ -.loadpath -.recommenders - -# Eclipse Core -.project - -# External tool builders -.externalToolBuilders/ - -# Locally stored "Eclipse launch configurations" -*.launch - -# PyDev specific (Python IDE for Eclipse) -*.pydevproject - -# CDT-specific (C/C++ Development Tooling) -.cproject - -# JDT-specific (Eclipse Java Development Tools) -.classpath - -# Java annotation processor (APT) -.factorypath - -# PDT-specific (PHP Development Tools) -.buildpath - -# sbteclipse plugin -.target - -# Tern plugin -.tern-project - -# TeXlipse plugin -.texlipse - -# STS (Spring Tool Suite) -.springBeans - -# Code Recommenders -.recommenders/ - - -coverage.txt - -#vendor -vendor/ - -.envrc \ No newline at end of file diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CONTRIBUTING.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CONTRIBUTING.md deleted file mode 100644 index dd52ab893..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CONTRIBUTING.md +++ /dev/null @@ -1,20 +0,0 @@ -# Contributing - -We would love to have people submit pull requests and help make `grpc-ecosystem/go-grpc-middleware` even better 👍. - -Fork, then clone the repo: - -```bash -git clone git@github.com:your-username/go-grpc-middleware.git -``` - -Before checking in please run the following: - -```bash -make all -``` - -This will `vet`, `fmt`, regenerate documentation and run all tests. - - -Push to your fork and open a pull request. \ No newline at end of file diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE deleted file mode 100644 index b2b065037..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/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. \ No newline at end of file diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md deleted file mode 100644 index a12b40904..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# Go gRPC Middleware - -[![Travis Build](https://travis-ci.org/grpc-ecosystem/go-grpc-middleware.svg?branch=master)](https://travis-ci.org/grpc-ecosystem/go-grpc-middleware) -[![Go Report Card](https://goreportcard.com/badge/github.com/grpc-ecosystem/go-grpc-middleware)](https://goreportcard.com/report/github.com/grpc-ecosystem/go-grpc-middleware) -[![GoDoc](http://img.shields.io/badge/GoDoc-Reference-blue.svg)](https://godoc.org/github.com/grpc-ecosystem/go-grpc-middleware) -[![SourceGraph](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-middleware/-/badge.svg)](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-middleware/?badge) -[![codecov](https://codecov.io/gh/grpc-ecosystem/go-grpc-middleware/branch/master/graph/badge.svg)](https://codecov.io/gh/grpc-ecosystem/go-grpc-middleware) -[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) -[![quality: production](https://img.shields.io/badge/quality-production-orange.svg)](#status) -[![Slack](https://img.shields.io/badge/slack-%23grpc--middleware-brightgreen)](https://gophers.slack.com/archives/CNJL30P4P) - -[gRPC Go](https://github.com/grpc/grpc-go) Middleware: interceptors, helpers, utilities. - -## ⚠️ Status - -Version [v2](https://github.com/grpc-ecosystem/go-grpc-middleware/tree/v2) is about to be released, with migration guide, which will replace v1. Try v2 and give us feedback! - -Version v1 is currently in deprecation mode, which means only critical and safety bug fixes will be merged. - - -## Middleware - -[gRPC Go](https://github.com/grpc/grpc-go) recently acquired support for -Interceptors, i.e. [middleware](https://medium.com/@matryer/writing-middleware-in-golang-and-how-go-makes-it-so-much-fun-4375c1246e81#.gv7tdlghs) -that is executed either on the gRPC Server before the request is passed onto the user's application logic, or on the gRPC client around the user call. It is a perfect way to implement -common patterns: auth, logging, message, validation, retries, or monitoring. - -These are generic building blocks that make it easy to build multiple microservices easily. -The purpose of this repository is to act as a go-to point for such reusable functionality. It contains -some of them itself, but also will link to useful external repos. - -`grpc_middleware` itself provides support for chaining interceptors, here's an example: - -```go -import "github.com/grpc-ecosystem/go-grpc-middleware" - -myServer := grpc.NewServer( - grpc.StreamInterceptor(grpc_middleware.ChainStreamServer( - grpc_ctxtags.StreamServerInterceptor(), - grpc_opentracing.StreamServerInterceptor(), - grpc_prometheus.StreamServerInterceptor, - grpc_zap.StreamServerInterceptor(zapLogger), - grpc_auth.StreamServerInterceptor(myAuthFunction), - grpc_recovery.StreamServerInterceptor(), - )), - grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( - grpc_ctxtags.UnaryServerInterceptor(), - grpc_opentracing.UnaryServerInterceptor(), - grpc_prometheus.UnaryServerInterceptor, - grpc_zap.UnaryServerInterceptor(zapLogger), - grpc_auth.UnaryServerInterceptor(myAuthFunction), - grpc_recovery.UnaryServerInterceptor(), - )), -) -``` - -## Interceptors - -_Please send a PR to add new interceptors or middleware to this list_ - -#### Auth - -- [`grpc_auth`](auth) - a customizable (via `AuthFunc`) piece of auth middleware - -#### Logging - -- [`grpc_ctxtags`](tags/) - a library that adds a `Tag` map to context, with data populated from request body -- [`grpc_zap`](logging/zap/) - integration of [zap](https://github.com/uber-go/zap) logging library into gRPC handlers. -- [`grpc_logrus`](logging/logrus/) - integration of [logrus](https://github.com/sirupsen/logrus) logging library into gRPC handlers. -- [`grpc_kit`](logging/kit/) - integration of [go-kit/log](https://github.com/go-kit/log) logging library into gRPC handlers. -- [`grpc_grpc_logsettable`](logging/settable/) - a wrapper around `grpclog.LoggerV2` that allows to replace loggers in runtime (thread-safe). - -#### Monitoring - -- [`grpc_prometheus`⚡](https://github.com/grpc-ecosystem/go-grpc-prometheus) - Prometheus client-side and server-side monitoring middleware -- [`otgrpc`⚡](https://github.com/grpc-ecosystem/grpc-opentracing/tree/master/go/otgrpc) - [OpenTracing](http://opentracing.io/) client-side and server-side interceptors -- [`grpc_opentracing`](tracing/opentracing) - [OpenTracing](http://opentracing.io/) client-side and server-side interceptors with support for streaming and handler-returned tags -- [`otelgrpc`](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/instrumentation/google.golang.org/grpc/otelgrpc) - [OpenTelemetry](https://opentelemetry.io/) client-side and server-side interceptors - -#### Client - -- [`grpc_retry`](retry/) - a generic gRPC response code retry mechanism, client-side middleware - -#### Server - -- [`grpc_validator`](validator/) - codegen inbound message validation from `.proto` options -- [`grpc_recovery`](recovery/) - turn panics into gRPC errors -- [`ratelimit`](ratelimit/) - grpc rate limiting by your own limiter - - -## License - -`go-grpc-middleware` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details. diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/auth.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/auth.go deleted file mode 100644 index a7e2890ee..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/auth.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_auth - -import ( - "context" - - "github.com/grpc-ecosystem/go-grpc-middleware" - "google.golang.org/grpc" -) - -// AuthFunc is the pluggable function that performs authentication. -// -// The passed in `Context` will contain the gRPC metadata.MD object (for header-based authentication) and -// the peer.Peer information that can contain transport-based credentials (e.g. `credentials.AuthInfo`). -// -// The returned context will be propagated to handlers, allowing user changes to `Context`. However, -// please make sure that the `Context` returned is a child `Context` of the one passed in. -// -// If error is returned, its `grpc.Code()` will be returned to the user as well as the verbatim message. -// Please make sure you use `codes.Unauthenticated` (lacking auth) and `codes.PermissionDenied` -// (authed, but lacking perms) appropriately. -type AuthFunc func(ctx context.Context) (context.Context, error) - -// ServiceAuthFuncOverride allows a given gRPC service implementation to override the global `AuthFunc`. -// -// If a service implements the AuthFuncOverride method, it takes precedence over the `AuthFunc` method, -// and will be called instead of AuthFunc for all method invocations within that service. -type ServiceAuthFuncOverride interface { - AuthFuncOverride(ctx context.Context, fullMethodName string) (context.Context, error) -} - -// UnaryServerInterceptor returns a new unary server interceptors that performs per-request auth. -func UnaryServerInterceptor(authFunc AuthFunc) grpc.UnaryServerInterceptor { - return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - var newCtx context.Context - var err error - if overrideSrv, ok := info.Server.(ServiceAuthFuncOverride); ok { - newCtx, err = overrideSrv.AuthFuncOverride(ctx, info.FullMethod) - } else { - newCtx, err = authFunc(ctx) - } - if err != nil { - return nil, err - } - return handler(newCtx, req) - } -} - -// StreamServerInterceptor returns a new unary server interceptors that performs per-request auth. -func StreamServerInterceptor(authFunc AuthFunc) grpc.StreamServerInterceptor { - return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - var newCtx context.Context - var err error - if overrideSrv, ok := srv.(ServiceAuthFuncOverride); ok { - newCtx, err = overrideSrv.AuthFuncOverride(stream.Context(), info.FullMethod) - } else { - newCtx, err = authFunc(stream.Context()) - } - if err != nil { - return err - } - wrapped := grpc_middleware.WrapServerStream(stream) - wrapped.WrappedContext = newCtx - return handler(srv, wrapped) - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/doc.go deleted file mode 100644 index 0550f023e..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -/* -`grpc_auth` a generic server-side auth middleware for gRPC. - -Server Side Auth Middleware - -It allows for easy assertion of `:authorization` headers in gRPC calls, be it HTTP Basic auth, or -OAuth2 Bearer tokens. - -The middleware takes a user-customizable `AuthFunc`, which can be customized to verify and extract -auth information from the request. The extracted information can be put in the `context.Context` of -handlers downstream for retrieval. - -It also allows for per-service implementation overrides of `AuthFunc`. See `ServiceAuthFuncOverride`. - -Please see examples for simple examples of use. -*/ -package grpc_auth diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/metadata.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/metadata.go deleted file mode 100644 index d386fcaf5..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/metadata.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_auth - -import ( - "context" - "strings" - - "github.com/grpc-ecosystem/go-grpc-middleware/util/metautils" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -var ( - headerAuthorize = "authorization" -) - -// AuthFromMD is a helper function for extracting the :authorization header from the gRPC metadata of the request. -// -// It expects the `:authorization` header to be of a certain scheme (e.g. `basic`, `bearer`), in a -// case-insensitive format (see rfc2617, sec 1.2). If no such authorization is found, or the token -// is of wrong scheme, an error with gRPC status `Unauthenticated` is returned. -func AuthFromMD(ctx context.Context, expectedScheme string) (string, error) { - val := metautils.ExtractIncoming(ctx).Get(headerAuthorize) - if val == "" { - return "", status.Errorf(codes.Unauthenticated, "Request unauthenticated with "+expectedScheme) - } - splits := strings.SplitN(val, " ", 2) - if len(splits) < 2 { - return "", status.Errorf(codes.Unauthenticated, "Bad authorization string") - } - if !strings.EqualFold(splits[0], expectedScheme) { - return "", status.Errorf(codes.Unauthenticated, "Request unauthenticated with "+expectedScheme) - } - return splits[1], nil -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go deleted file mode 100644 index 407d9332c..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -// gRPC Server Interceptor chaining middleware. - -package grpc_middleware - -import ( - "context" - - "google.golang.org/grpc" -) - -// ChainUnaryServer creates a single interceptor out of a chain of many interceptors. -// -// Execution is done in left-to-right order, including passing of context. -// For example ChainUnaryServer(one, two, three) will execute one before two before three, and three -// will see context changes of one and two. -// -// While this can be useful in some scenarios, it is generally advisable to use google.golang.org/grpc.ChainUnaryInterceptor directly. -func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor { - n := len(interceptors) - - // Dummy interceptor maintained for backward compatibility to avoid returning nil. - if n == 0 { - return func(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - return handler(ctx, req) - } - } - - // The degenerate case, just return the single wrapped interceptor directly. - if n == 1 { - return interceptors[0] - } - - // Return a function which satisfies the interceptor interface, and which is - // a closure over the given list of interceptors to be chained. - return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - currHandler := handler - // Iterate backwards through all interceptors except the first (outermost). - // Wrap each one in a function which satisfies the handler interface, but - // is also a closure over the `info` and `handler` parameters. Then pass - // each pseudo-handler to the next outer interceptor as the handler to be called. - for i := n - 1; i > 0; i-- { - // Rebind to loop-local vars so they can be closed over. - innerHandler, i := currHandler, i - currHandler = func(currentCtx context.Context, currentReq interface{}) (interface{}, error) { - return interceptors[i](currentCtx, currentReq, info, innerHandler) - } - } - // Finally return the result of calling the outermost interceptor with the - // outermost pseudo-handler created above as its handler. - return interceptors[0](ctx, req, info, currHandler) - } -} - -// ChainStreamServer creates a single interceptor out of a chain of many interceptors. -// -// Execution is done in left-to-right order, including passing of context. -// For example ChainUnaryServer(one, two, three) will execute one before two before three. -// If you want to pass context between interceptors, use WrapServerStream. -// -// While this can be useful in some scenarios, it is generally advisable to use google.golang.org/grpc.ChainStreamInterceptor directly. -func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor { - n := len(interceptors) - - // Dummy interceptor maintained for backward compatibility to avoid returning nil. - if n == 0 { - return func(srv interface{}, stream grpc.ServerStream, _ *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - return handler(srv, stream) - } - } - - if n == 1 { - return interceptors[0] - } - - return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - currHandler := handler - for i := n - 1; i > 0; i-- { - innerHandler, i := currHandler, i - currHandler = func(currentSrv interface{}, currentStream grpc.ServerStream) error { - return interceptors[i](currentSrv, currentStream, info, innerHandler) - } - } - return interceptors[0](srv, stream, info, currHandler) - } -} - -// ChainUnaryClient creates a single interceptor out of a chain of many interceptors. -// -// Execution is done in left-to-right order, including passing of context. -// For example ChainUnaryClient(one, two, three) will execute one before two before three. -func ChainUnaryClient(interceptors ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor { - n := len(interceptors) - - // Dummy interceptor maintained for backward compatibility to avoid returning nil. - if n == 0 { - return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - return invoker(ctx, method, req, reply, cc, opts...) - } - } - - if n == 1 { - return interceptors[0] - } - - return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - currInvoker := invoker - for i := n - 1; i > 0; i-- { - innerInvoker, i := currInvoker, i - currInvoker = func(currentCtx context.Context, currentMethod string, currentReq, currentRepl interface{}, currentConn *grpc.ClientConn, currentOpts ...grpc.CallOption) error { - return interceptors[i](currentCtx, currentMethod, currentReq, currentRepl, currentConn, innerInvoker, currentOpts...) - } - } - return interceptors[0](ctx, method, req, reply, cc, currInvoker, opts...) - } -} - -// ChainStreamClient creates a single interceptor out of a chain of many interceptors. -// -// Execution is done in left-to-right order, including passing of context. -// For example ChainStreamClient(one, two, three) will execute one before two before three. -func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor { - n := len(interceptors) - - // Dummy interceptor maintained for backward compatibility to avoid returning nil. - if n == 0 { - return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { - return streamer(ctx, desc, cc, method, opts...) - } - } - - if n == 1 { - return interceptors[0] - } - - return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { - currStreamer := streamer - for i := n - 1; i > 0; i-- { - innerStreamer, i := currStreamer, i - currStreamer = func(currentCtx context.Context, currentDesc *grpc.StreamDesc, currentConn *grpc.ClientConn, currentMethod string, currentOpts ...grpc.CallOption) (grpc.ClientStream, error) { - return interceptors[i](currentCtx, currentDesc, currentConn, currentMethod, innerStreamer, currentOpts...) - } - } - return interceptors[0](ctx, desc, cc, method, currStreamer, opts...) - } -} - -// Chain creates a single interceptor out of a chain of many interceptors. -// -// WithUnaryServerChain is a grpc.Server config option that accepts multiple unary interceptors. -// Basically syntactic sugar. -// -// Deprecated: use google.golang.org/grpc.ChainUnaryInterceptor instead. -func WithUnaryServerChain(interceptors ...grpc.UnaryServerInterceptor) grpc.ServerOption { - return grpc.ChainUnaryInterceptor(interceptors...) -} - -// WithStreamServerChain is a grpc.Server config option that accepts multiple stream interceptors. -// Basically syntactic sugar. -// -// Deprecated: use google.golang.org/grpc.ChainStreamInterceptor instead. -func WithStreamServerChain(interceptors ...grpc.StreamServerInterceptor) grpc.ServerOption { - return grpc.ChainStreamInterceptor(interceptors...) -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go deleted file mode 100644 index 718e10046..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -/* -`grpc_middleware` is a collection of gRPC middleware packages: interceptors, helpers and tools. - -Middleware - -gRPC is a fantastic RPC middleware, which sees a lot of adoption in the Golang world. However, the -upstream gRPC codebase is relatively bare bones. - -This package, and most of its child packages provides commonly needed middleware for gRPC: -client-side interceptors for retires, server-side interceptors for input validation and auth, -functions for chaining said interceptors, metadata convenience methods and more. - -Chaining - -By default, gRPC doesn't allow one to have more than one interceptor either on the client nor on -the server side. `grpc_middleware` provides convenient chaining methods - -Simple way of turning a multiple interceptors into a single interceptor. Here's an example for -server chaining: - - myServer := grpc.NewServer( - grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(loggingStream, monitoringStream, authStream)), - grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(loggingUnary, monitoringUnary, authUnary)), - ) - -These interceptors will be executed from left to right: logging, monitoring and auth. - -Here's an example for client side chaining: - - clientConn, err = grpc.Dial( - address, - grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(monitoringClientUnary, retryUnary)), - grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(monitoringClientStream, retryStream)), - ) - client = pb_testproto.NewTestServiceClient(clientConn) - resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"}) - -These interceptors will be executed from left to right: monitoring and then retry logic. - -The retry interceptor will call every interceptor that follows it whenever when a retry happens. - -Writing Your Own - -Implementing your own interceptor is pretty trivial: there are interfaces for that. But the interesting -bit exposing common data to handlers (and other middleware), similarly to HTTP Middleware design. -For example, you may want to pass the identity of the caller from the auth interceptor all the way -to the handling function. - -For example, a client side interceptor example for auth looks like: - - func FakeAuthUnaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - newCtx := context.WithValue(ctx, "user_id", "john@example.com") - return handler(newCtx, req) - } - -Unfortunately, it's not as easy for streaming RPCs. These have the `context.Context` embedded within -the `grpc.ServerStream` object. To pass values through context, a wrapper (`WrappedServerStream`) is -needed. For example: - - func FakeAuthStreamingInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - newStream := grpc_middleware.WrapServerStream(stream) - newStream.WrappedContext = context.WithValue(ctx, "user_id", "john@example.com") - return handler(srv, newStream) - } -*/ -package grpc_middleware diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile deleted file mode 100644 index b18d2d2bb..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile +++ /dev/null @@ -1,17 +0,0 @@ -SHELL=/bin/bash - -GOFILES_NOVENDOR = $(shell go list ./... | grep -v /vendor/) - -all: vet fmt test - -fmt: - go fmt $(GOFILES_NOVENDOR) - -vet: - # do not check lostcancel, they are intentional. - go vet -lostcancel=false $(GOFILES_NOVENDOR) - -test: vet - ./scripts/test_all.sh - -.PHONY: all test diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/LICENSE b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/LICENSE deleted file mode 100644 index b2b065037..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/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. \ No newline at end of file diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_metrics.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_metrics.go deleted file mode 100644 index 5c8ba2076..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_metrics.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -package prometheus - -import ( - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors" - "github.com/prometheus/client_golang/prometheus" - "google.golang.org/grpc" -) - -// ClientMetrics represents a collection of metrics to be registered on a -// Prometheus metrics registry for a gRPC client. -type ClientMetrics struct { - clientStartedCounter *prometheus.CounterVec - clientHandledCounter *prometheus.CounterVec - clientStreamMsgReceived *prometheus.CounterVec - clientStreamMsgSent *prometheus.CounterVec - - // clientHandledHistogram can be nil - clientHandledHistogram *prometheus.HistogramVec - // clientStreamRecvHistogram can be nil - clientStreamRecvHistogram *prometheus.HistogramVec - // clientStreamSendHistogram can be nil - clientStreamSendHistogram *prometheus.HistogramVec -} - -// NewClientMetrics returns a new ClientMetrics object. -// NOTE: Remember to register ClientMetrics object using prometheus registry -// e.g. prometheus.MustRegister(myClientMetrics). -func NewClientMetrics(opts ...ClientMetricsOption) *ClientMetrics { - var config clientMetricsConfig - config.apply(opts) - return &ClientMetrics{ - clientStartedCounter: prometheus.NewCounterVec( - config.counterOpts.apply(prometheus.CounterOpts{ - Name: "grpc_client_started_total", - Help: "Total number of RPCs started on the client.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - - clientHandledCounter: prometheus.NewCounterVec( - config.counterOpts.apply(prometheus.CounterOpts{ - Name: "grpc_client_handled_total", - Help: "Total number of RPCs completed by the client, regardless of success or failure.", - }), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}), - - clientStreamMsgReceived: prometheus.NewCounterVec( - config.counterOpts.apply(prometheus.CounterOpts{ - Name: "grpc_client_msg_received_total", - Help: "Total number of RPC stream messages received by the client.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - - clientStreamMsgSent: prometheus.NewCounterVec( - config.counterOpts.apply(prometheus.CounterOpts{ - Name: "grpc_client_msg_sent_total", - Help: "Total number of gRPC stream messages sent by the client.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - - clientHandledHistogram: config.clientHandledHistogram, - clientStreamRecvHistogram: config.clientStreamRecvHistogram, - clientStreamSendHistogram: config.clientStreamSendHistogram, - } -} - -// Describe sends the super-set of all possible descriptors of metrics -// collected by this Collector to the provided channel and returns once -// the last descriptor has been sent. -func (m *ClientMetrics) Describe(ch chan<- *prometheus.Desc) { - m.clientStartedCounter.Describe(ch) - m.clientHandledCounter.Describe(ch) - m.clientStreamMsgReceived.Describe(ch) - m.clientStreamMsgSent.Describe(ch) - if m.clientHandledHistogram != nil { - m.clientHandledHistogram.Describe(ch) - } - if m.clientStreamRecvHistogram != nil { - m.clientStreamRecvHistogram.Describe(ch) - } - if m.clientStreamSendHistogram != nil { - m.clientStreamSendHistogram.Describe(ch) - } -} - -// Collect is called by the Prometheus registry when collecting -// metrics. The implementation sends each collected metric via the -// provided channel and returns once the last metric has been sent. -func (m *ClientMetrics) Collect(ch chan<- prometheus.Metric) { - m.clientStartedCounter.Collect(ch) - m.clientHandledCounter.Collect(ch) - m.clientStreamMsgReceived.Collect(ch) - m.clientStreamMsgSent.Collect(ch) - if m.clientHandledHistogram != nil { - m.clientHandledHistogram.Collect(ch) - } - if m.clientStreamRecvHistogram != nil { - m.clientStreamRecvHistogram.Collect(ch) - } - if m.clientStreamSendHistogram != nil { - m.clientStreamSendHistogram.Collect(ch) - } -} - -// UnaryClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Unary RPCs. -func (m *ClientMetrics) UnaryClientInterceptor(opts ...Option) grpc.UnaryClientInterceptor { - return interceptors.UnaryClientInterceptor(&reportable{ - opts: opts, - clientMetrics: m, - }) -} - -// StreamClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs. -func (m *ClientMetrics) StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor { - return interceptors.StreamClientInterceptor(&reportable{ - opts: opts, - clientMetrics: m, - }) -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_options.go deleted file mode 100644 index c2671679c..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/client_options.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -package prometheus - -import ( - "github.com/prometheus/client_golang/prometheus" -) - -type clientMetricsConfig struct { - counterOpts counterOptions - // clientHandledHistogram can be nil. - clientHandledHistogram *prometheus.HistogramVec - // clientStreamRecvHistogram can be nil. - clientStreamRecvHistogram *prometheus.HistogramVec - // clientStreamSendHistogram can be nil. - clientStreamSendHistogram *prometheus.HistogramVec -} - -type ClientMetricsOption func(*clientMetricsConfig) - -func (c *clientMetricsConfig) apply(opts []ClientMetricsOption) { - for _, o := range opts { - o(c) - } -} - -func WithClientCounterOptions(opts ...CounterOption) ClientMetricsOption { - return func(o *clientMetricsConfig) { - o.counterOpts = opts - } -} - -// WithClientHandlingTimeHistogram turns on recording of handling time of RPCs. -// Histogram metrics can be very expensive for Prometheus to retain and query. -func WithClientHandlingTimeHistogram(opts ...HistogramOption) ClientMetricsOption { - return func(o *clientMetricsConfig) { - o.clientHandledHistogram = prometheus.NewHistogramVec( - histogramOptions(opts).apply(prometheus.HistogramOpts{ - Name: "grpc_client_handling_seconds", - Help: "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", - Buckets: prometheus.DefBuckets, - }), - []string{"grpc_type", "grpc_service", "grpc_method"}, - ) - } -} - -// WithClientStreamRecvHistogram turns on recording of single message receive time of streaming RPCs. -// Histogram metrics can be very expensive for Prometheus to retain and query. -func WithClientStreamRecvHistogram(opts ...HistogramOption) ClientMetricsOption { - return func(o *clientMetricsConfig) { - o.clientStreamRecvHistogram = prometheus.NewHistogramVec( - histogramOptions(opts).apply(prometheus.HistogramOpts{ - Name: "grpc_client_msg_recv_handling_seconds", - Help: "Histogram of response latency (seconds) of the gRPC single message receive.", - Buckets: prometheus.DefBuckets, - }), - []string{"grpc_type", "grpc_service", "grpc_method"}, - ) - } -} - -// WithClientStreamSendHistogram turns on recording of single message send time of streaming RPCs. -// Histogram metrics can be very expensive for Prometheus to retain and query. -func WithClientStreamSendHistogram(opts ...HistogramOption) ClientMetricsOption { - return func(o *clientMetricsConfig) { - o.clientStreamSendHistogram = prometheus.NewHistogramVec( - histogramOptions(opts).apply(prometheus.HistogramOpts{ - Name: "grpc_client_msg_send_handling_seconds", - Help: "Histogram of response latency (seconds) of the gRPC single message send.", - Buckets: prometheus.DefBuckets, - }), - []string{"grpc_type", "grpc_service", "grpc_method"}, - ) - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/constants.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/constants.go deleted file mode 100644 index 5c36923f7..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/constants.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -package prometheus - -type grpcType string - -// grpcType describes all types of grpc connection. -const ( - Unary grpcType = "unary" - ClientStream grpcType = "client_stream" - ServerStream grpcType = "server_stream" - BidiStream grpcType = "bidi_stream" -) - -// Kind describes whether interceptor is a client or server type. -type Kind string - -// Enum for Client and Server Kind. -const ( - KindClient Kind = "client" - KindServer Kind = "server" -) diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/doc.go deleted file mode 100644 index b62f17efb..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -/* -Package prometheus provides a standalone interceptor for metrics. It's next iteration of deprecated https://github.com/grpc-ecosystem/go-grpc-prometheus. -See https://github.com/grpc-ecosystem/go-grpc-middleware/tree/main/examples for example. -*/ -package prometheus diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go deleted file mode 100644 index bdd171e29..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -package prometheus - -import ( - "github.com/prometheus/client_golang/prometheus" - "google.golang.org/grpc" - "google.golang.org/grpc/status" -) - -// FromError returns a grpc status. If the error code is neither a valid grpc status nor a context error, codes.Unknown -// will be set. -func FromError(err error) *status.Status { - s, ok := status.FromError(err) - // Mirror what the grpc server itself does, i.e. also convert context errors to status - if !ok { - s = status.FromContextError(err) - } - return s -} - -// A CounterOption lets you add options to Counter metrics using With* funcs. -type CounterOption func(*prometheus.CounterOpts) - -type counterOptions []CounterOption - -func (co counterOptions) apply(o prometheus.CounterOpts) prometheus.CounterOpts { - for _, f := range co { - f(&o) - } - return o -} - -// WithConstLabels allows you to add ConstLabels to Counter metrics. -func WithConstLabels(labels prometheus.Labels) CounterOption { - return func(o *prometheus.CounterOpts) { - o.ConstLabels = labels - } -} - -// WithSubsystem allows you to add a Subsystem to Counter metrics. -func WithSubsystem(subsystem string) CounterOption { - return func(o *prometheus.CounterOpts) { - o.Subsystem = subsystem - } -} - -// A HistogramOption lets you add options to Histogram metrics using With* -// funcs. -type HistogramOption func(*prometheus.HistogramOpts) - -type histogramOptions []HistogramOption - -func (ho histogramOptions) apply(o prometheus.HistogramOpts) prometheus.HistogramOpts { - for _, f := range ho { - f(&o) - } - return o -} - -// WithHistogramBuckets allows you to specify custom bucket ranges for histograms if EnableHandlingTimeHistogram is on. -func WithHistogramBuckets(buckets []float64) HistogramOption { - return func(o *prometheus.HistogramOpts) { o.Buckets = buckets } -} - -// WithHistogramOpts allows you to specify HistogramOpts but makes sure the correct name and label is used. -// This function is helpful when specifying more than just the buckets, like using NativeHistograms. -func WithHistogramOpts(opts *prometheus.HistogramOpts) HistogramOption { - // TODO: This isn't ideal either if new fields are added to prometheus.HistogramOpts. - // Maybe we can change the interface to accept abitrary HistogramOpts and - // only make sure to overwrite the necessary fields (name, labels). - return func(o *prometheus.HistogramOpts) { - o.Buckets = opts.Buckets - o.NativeHistogramBucketFactor = opts.NativeHistogramBucketFactor - o.NativeHistogramZeroThreshold = opts.NativeHistogramZeroThreshold - o.NativeHistogramMaxBucketNumber = opts.NativeHistogramMaxBucketNumber - o.NativeHistogramMinResetDuration = opts.NativeHistogramMinResetDuration - o.NativeHistogramMaxZeroThreshold = opts.NativeHistogramMaxZeroThreshold - } -} - -// WithHistogramConstLabels allows you to add custom ConstLabels to -// histograms metrics. -func WithHistogramConstLabels(labels prometheus.Labels) HistogramOption { - return func(o *prometheus.HistogramOpts) { - o.ConstLabels = labels - } -} - -// WithHistogramSubsystem allows you to add a Subsystem to histograms metrics. -func WithHistogramSubsystem(subsystem string) HistogramOption { - return func(o *prometheus.HistogramOpts) { - o.Subsystem = subsystem - } -} - -func typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType { - if !mInfo.IsClientStream && !mInfo.IsServerStream { - return Unary - } - if mInfo.IsClientStream && !mInfo.IsServerStream { - return ClientStream - } - if !mInfo.IsClientStream && mInfo.IsServerStream { - return ServerStream - } - return BidiStream -} - -// An Option lets you add options to prometheus interceptors using With* funcs. -type Option func(*config) - -type config struct { - exemplarFn exemplarFromCtxFn -} - -func (c *config) apply(opts []Option) { - for _, o := range opts { - o(c) - } -} - -// WithExemplarFromContext sets function that will be used to deduce exemplar for all counter and histogram metrics. -func WithExemplarFromContext(exemplarFn exemplarFromCtxFn) Option { - return func(o *config) { - o.exemplarFn = exemplarFn - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go deleted file mode 100644 index 96c49ad93..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -package prometheus - -import ( - "context" - "time" - - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors" - "github.com/prometheus/client_golang/prometheus" -) - -type reporter struct { - clientMetrics *ClientMetrics - serverMetrics *ServerMetrics - typ interceptors.GRPCType - service, method string - kind Kind - exemplar prometheus.Labels -} - -func (r *reporter) PostCall(err error, rpcDuration time.Duration) { - // get status code from error - status := FromError(err) - code := status.Code() - - // perform handling of metrics from code - switch r.kind { - case KindServer: - r.incrementWithExemplar(r.serverMetrics.serverHandledCounter, string(r.typ), r.service, r.method, code.String()) - if r.serverMetrics.serverHandledHistogram != nil { - r.observeWithExemplar(r.serverMetrics.serverHandledHistogram, rpcDuration.Seconds(), string(r.typ), r.service, r.method) - } - - case KindClient: - r.incrementWithExemplar(r.clientMetrics.clientHandledCounter, string(r.typ), r.service, r.method, code.String()) - if r.clientMetrics.clientHandledHistogram != nil { - r.observeWithExemplar(r.clientMetrics.clientHandledHistogram, rpcDuration.Seconds(), string(r.typ), r.service, r.method) - } - } -} - -func (r *reporter) PostMsgSend(_ any, _ error, sendDuration time.Duration) { - switch r.kind { - case KindServer: - r.incrementWithExemplar(r.serverMetrics.serverStreamMsgSent, string(r.typ), r.service, r.method) - case KindClient: - r.incrementWithExemplar(r.clientMetrics.clientStreamMsgSent, string(r.typ), r.service, r.method) - if r.clientMetrics.clientStreamSendHistogram != nil { - r.observeWithExemplar(r.clientMetrics.clientStreamSendHistogram, sendDuration.Seconds(), string(r.typ), r.service, r.method) - } - } -} - -func (r *reporter) PostMsgReceive(_ any, _ error, recvDuration time.Duration) { - switch r.kind { - case KindServer: - r.incrementWithExemplar(r.serverMetrics.serverStreamMsgReceived, string(r.typ), r.service, r.method) - case KindClient: - r.incrementWithExemplar(r.clientMetrics.clientStreamMsgReceived, string(r.typ), r.service, r.method) - if r.clientMetrics.clientStreamRecvHistogram != nil { - r.observeWithExemplar(r.clientMetrics.clientStreamRecvHistogram, recvDuration.Seconds(), string(r.typ), r.service, r.method) - } - } -} - -type reportable struct { - clientMetrics *ClientMetrics - serverMetrics *ServerMetrics - - opts []Option -} - -func (rep *reportable) ServerReporter(ctx context.Context, meta interceptors.CallMeta) (interceptors.Reporter, context.Context) { - return rep.reporter(ctx, rep.serverMetrics, nil, meta, KindServer) -} - -func (rep *reportable) ClientReporter(ctx context.Context, meta interceptors.CallMeta) (interceptors.Reporter, context.Context) { - return rep.reporter(ctx, nil, rep.clientMetrics, meta, KindClient) -} - -func (rep *reportable) reporter(ctx context.Context, sm *ServerMetrics, cm *ClientMetrics, meta interceptors.CallMeta, kind Kind) (interceptors.Reporter, context.Context) { - var c config - c.apply(rep.opts) - r := &reporter{ - clientMetrics: cm, - serverMetrics: sm, - typ: meta.Typ, - service: meta.Service, - method: meta.Method, - kind: kind, - } - if c.exemplarFn != nil { - r.exemplar = c.exemplarFn(ctx) - } - - switch kind { - case KindClient: - r.incrementWithExemplar(r.clientMetrics.clientStartedCounter, string(r.typ), r.service, r.method) - case KindServer: - r.incrementWithExemplar(r.serverMetrics.serverStartedCounter, string(r.typ), r.service, r.method) - } - return r, ctx -} - -func (r *reporter) incrementWithExemplar(c *prometheus.CounterVec, lvals ...string) { - c.WithLabelValues(lvals...).(prometheus.ExemplarAdder).AddWithExemplar(1, r.exemplar) -} - -func (r *reporter) observeWithExemplar(h *prometheus.HistogramVec, value float64, lvals ...string) { - h.WithLabelValues(lvals...).(prometheus.ExemplarObserver).ObserveWithExemplar(value, r.exemplar) -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go deleted file mode 100644 index 9b2f3e6d8..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -package prometheus - -import ( - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors" - "github.com/prometheus/client_golang/prometheus" - "google.golang.org/grpc" -) - -// ServerMetrics represents a collection of metrics to be registered on a -// Prometheus metrics registry for a gRPC server. -type ServerMetrics struct { - serverStartedCounter *prometheus.CounterVec - serverHandledCounter *prometheus.CounterVec - serverStreamMsgReceived *prometheus.CounterVec - serverStreamMsgSent *prometheus.CounterVec - // serverHandledHistogram can be nil. - serverHandledHistogram *prometheus.HistogramVec -} - -// NewServerMetrics returns a new ServerMetrics object that has server interceptor methods. -// NOTE: Remember to register ServerMetrics object by using prometheus registry -// e.g. prometheus.MustRegister(myServerMetrics). -func NewServerMetrics(opts ...ServerMetricsOption) *ServerMetrics { - var config serverMetricsConfig - config.apply(opts) - return &ServerMetrics{ - serverStartedCounter: prometheus.NewCounterVec( - config.counterOpts.apply(prometheus.CounterOpts{ - Name: "grpc_server_started_total", - Help: "Total number of RPCs started on the server.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - serverHandledCounter: prometheus.NewCounterVec( - config.counterOpts.apply(prometheus.CounterOpts{ - Name: "grpc_server_handled_total", - Help: "Total number of RPCs completed on the server, regardless of success or failure.", - }), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}), - serverStreamMsgReceived: prometheus.NewCounterVec( - config.counterOpts.apply(prometheus.CounterOpts{ - Name: "grpc_server_msg_received_total", - Help: "Total number of RPC stream messages received on the server.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - serverStreamMsgSent: prometheus.NewCounterVec( - config.counterOpts.apply(prometheus.CounterOpts{ - Name: "grpc_server_msg_sent_total", - Help: "Total number of gRPC stream messages sent by the server.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - serverHandledHistogram: config.serverHandledHistogram, - } -} - -// Describe sends the super-set of all possible descriptors of metrics -// collected by this Collector to the provided channel and returns once -// the last descriptor has been sent. -func (m *ServerMetrics) Describe(ch chan<- *prometheus.Desc) { - m.serverStartedCounter.Describe(ch) - m.serverHandledCounter.Describe(ch) - m.serverStreamMsgReceived.Describe(ch) - m.serverStreamMsgSent.Describe(ch) - if m.serverHandledHistogram != nil { - m.serverHandledHistogram.Describe(ch) - } -} - -// Collect is called by the Prometheus registry when collecting -// metrics. The implementation sends each collected metric via the -// provided channel and returns once the last metric has been sent. -func (m *ServerMetrics) Collect(ch chan<- prometheus.Metric) { - m.serverStartedCounter.Collect(ch) - m.serverHandledCounter.Collect(ch) - m.serverStreamMsgReceived.Collect(ch) - m.serverStreamMsgSent.Collect(ch) - if m.serverHandledHistogram != nil { - m.serverHandledHistogram.Collect(ch) - } -} - -// InitializeMetrics initializes all metrics, with their appropriate null -// value, for all gRPC methods registered on a gRPC server. This is useful, to -// ensure that all metrics exist when collecting and querying. -// NOTE: This might add significant cardinality and might not be needed in future version of Prometheus (created timestamp). -func (m *ServerMetrics) InitializeMetrics(server *grpc.Server) { - serviceInfo := server.GetServiceInfo() - for serviceName, info := range serviceInfo { - for _, mInfo := range info.Methods { - m.preRegisterMethod(serviceName, &mInfo) - } - } -} - -// preRegisterMethod is invoked on Register of a Server, allowing all gRPC services labels to be pre-populated. -func (m *ServerMetrics) preRegisterMethod(serviceName string, mInfo *grpc.MethodInfo) { - methodName := mInfo.Name - methodType := string(typeFromMethodInfo(mInfo)) - // These are just references (no increments), as just referencing will create the labels but not set values. - _, _ = m.serverStartedCounter.GetMetricWithLabelValues(methodType, serviceName, methodName) - _, _ = m.serverStreamMsgReceived.GetMetricWithLabelValues(methodType, serviceName, methodName) - _, _ = m.serverStreamMsgSent.GetMetricWithLabelValues(methodType, serviceName, methodName) - if m.serverHandledHistogram != nil { - _, _ = m.serverHandledHistogram.GetMetricWithLabelValues(methodType, serviceName, methodName) - } - for _, code := range interceptors.AllCodes { - _, _ = m.serverHandledCounter.GetMetricWithLabelValues(methodType, serviceName, methodName, code.String()) - } -} - -// UnaryServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Unary RPCs. -func (m *ServerMetrics) UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor { - return interceptors.UnaryServerInterceptor(&reportable{ - opts: opts, - serverMetrics: m, - }) -} - -// StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs. -func (m *ServerMetrics) StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor { - return interceptors.StreamServerInterceptor(&reportable{ - opts: opts, - serverMetrics: m, - }) -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go deleted file mode 100644 index 39d422042..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -package prometheus - -import ( - "context" - - "github.com/prometheus/client_golang/prometheus" -) - -type exemplarFromCtxFn func(ctx context.Context) prometheus.Labels - -type serverMetricsConfig struct { - counterOpts counterOptions - // serverHandledHistogram can be nil. - serverHandledHistogram *prometheus.HistogramVec -} - -type ServerMetricsOption func(*serverMetricsConfig) - -func (c *serverMetricsConfig) apply(opts []ServerMetricsOption) { - for _, o := range opts { - o(c) - } -} - -// WithServerCounterOptions sets counter options. -func WithServerCounterOptions(opts ...CounterOption) ServerMetricsOption { - return func(o *serverMetricsConfig) { - o.counterOpts = opts - } -} - -// WithServerHandlingTimeHistogram turns on recording of handling time of RPCs. -// Histogram metrics can be very expensive for Prometheus to retain and query. -func WithServerHandlingTimeHistogram(opts ...HistogramOption) ServerMetricsOption { - return func(o *serverMetricsConfig) { - o.serverHandledHistogram = prometheus.NewHistogramVec( - histogramOptions(opts).apply(prometheus.HistogramOpts{ - Name: "grpc_server_handling_seconds", - Help: "Histogram of response latency (seconds) of gRPC that had been application-level handled by the server.", - Buckets: prometheus.DefBuckets, - }), - []string{"grpc_type", "grpc_service", "grpc_method"}, - ) - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/backoff.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/backoff.go deleted file mode 100644 index ad35f09a8..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/backoff.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_retry - -import ( - "time" - - "github.com/grpc-ecosystem/go-grpc-middleware/util/backoffutils" -) - -// BackoffLinear is very simple: it waits for a fixed period of time between calls. -func BackoffLinear(waitBetween time.Duration) BackoffFunc { - return func(attempt uint) time.Duration { - return waitBetween - } -} - -// BackoffLinearWithJitter waits a set period of time, allowing for jitter (fractional adjustment). -// -// For example waitBetween=1s and jitter=0.10 can generate waits between 900ms and 1100ms. -func BackoffLinearWithJitter(waitBetween time.Duration, jitterFraction float64) BackoffFunc { - return func(attempt uint) time.Duration { - return backoffutils.JitterUp(waitBetween, jitterFraction) - } -} - -// BackoffExponential produces increasing intervals for each attempt. -// -// The scalar is multiplied times 2 raised to the current attempt. So the first -// retry with a scalar of 100ms is 100ms, while the 5th attempt would be 1.6s. -func BackoffExponential(scalar time.Duration) BackoffFunc { - return func(attempt uint) time.Duration { - return scalar * time.Duration(backoffutils.ExponentBase2(attempt)) - } -} - -// BackoffExponentialWithJitter creates an exponential backoff like -// BackoffExponential does, but adds jitter. -func BackoffExponentialWithJitter(scalar time.Duration, jitterFraction float64) BackoffFunc { - return func(attempt uint) time.Duration { - return backoffutils.JitterUp(scalar*time.Duration(backoffutils.ExponentBase2(attempt)), jitterFraction) - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/doc.go deleted file mode 100644 index f8ba7198a..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/doc.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -/* -`grpc_retry` provides client-side request retry logic for gRPC. - -Client-Side Request Retry Interceptor - -It allows for automatic retry, inside the generated gRPC code of requests based on the gRPC status -of the reply. It supports unary (1:1), and server stream (1:n) requests. - -By default the interceptors *are disabled*, preventing accidental use of retries. You can easily -override the number of retries (setting them to more than 0) with a `grpc.ClientOption`, e.g.: - - myclient.Ping(ctx, goodPing, grpc_retry.WithMax(5)) - -Other default options are: retry on `ResourceExhausted` and `Unavailable` gRPC codes, use a 50ms -linear backoff with 10% jitter. - -For chained interceptors, the retry interceptor will call every interceptor that follows it -whenever a retry happens. - -Please see examples for more advanced use. -*/ -package grpc_retry diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/options.go deleted file mode 100644 index 7a633e293..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/options.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_retry - -import ( - "context" - "time" - - "google.golang.org/grpc" - "google.golang.org/grpc/codes" -) - -var ( - // DefaultRetriableCodes is a set of well known types gRPC codes that should be retri-able. - // - // `ResourceExhausted` means that the user quota, e.g. per-RPC limits, have been reached. - // `Unavailable` means that system is currently unavailable and the client should retry again. - DefaultRetriableCodes = []codes.Code{codes.ResourceExhausted, codes.Unavailable} - - defaultOptions = &options{ - max: 0, // disabled - perCallTimeout: 0, // disabled - includeHeader: true, - codes: DefaultRetriableCodes, - backoffFunc: BackoffFuncContext(func(ctx context.Context, attempt uint) time.Duration { - return BackoffLinearWithJitter(50*time.Millisecond /*jitter*/, 0.10)(attempt) - }), - } -) - -// BackoffFunc denotes a family of functions that control the backoff duration between call retries. -// -// They are called with an identifier of the attempt, and should return a time the system client should -// hold off for. If the time returned is longer than the `context.Context.Deadline` of the request -// the deadline of the request takes precedence and the wait will be interrupted before proceeding -// with the next iteration. -type BackoffFunc func(attempt uint) time.Duration - -// BackoffFuncContext denotes a family of functions that control the backoff duration between call retries. -// -// They are called with an identifier of the attempt, and should return a time the system client should -// hold off for. If the time returned is longer than the `context.Context.Deadline` of the request -// the deadline of the request takes precedence and the wait will be interrupted before proceeding -// with the next iteration. The context can be used to extract request scoped metadata and context values. -type BackoffFuncContext func(ctx context.Context, attempt uint) time.Duration - -// Disable disables the retry behaviour on this call, or this interceptor. -// -// Its semantically the same to `WithMax` -func Disable() CallOption { - return WithMax(0) -} - -// WithMax sets the maximum number of retries on this call, or this interceptor. -func WithMax(maxRetries uint) CallOption { - return CallOption{applyFunc: func(o *options) { - o.max = maxRetries - }} -} - -// WithBackoff sets the `BackoffFunc` used to control time between retries. -func WithBackoff(bf BackoffFunc) CallOption { - return CallOption{applyFunc: func(o *options) { - o.backoffFunc = BackoffFuncContext(func(ctx context.Context, attempt uint) time.Duration { - return bf(attempt) - }) - }} -} - -// WithBackoffContext sets the `BackoffFuncContext` used to control time between retries. -func WithBackoffContext(bf BackoffFuncContext) CallOption { - return CallOption{applyFunc: func(o *options) { - o.backoffFunc = bf - }} -} - -// WithCodes sets which codes should be retried. -// -// Please *use with care*, as you may be retrying non-idempotent calls. -// -// You cannot automatically retry on Cancelled and Deadline, please use `WithPerRetryTimeout` for these. -func WithCodes(retryCodes ...codes.Code) CallOption { - return CallOption{applyFunc: func(o *options) { - o.codes = retryCodes - }} -} - -// WithPerRetryTimeout sets the RPC timeout per call (including initial call) on this call, or this interceptor. -// -// The context.Deadline of the call takes precedence and sets the maximum time the whole invocation -// will take, but WithPerRetryTimeout can be used to limit the RPC time per each call. -// -// For example, with context.Deadline = now + 10s, and WithPerRetryTimeout(3 * time.Seconds), each -// of the retry calls (including the initial one) will have a deadline of now + 3s. -// -// A value of 0 disables the timeout overrides completely and returns to each retry call using the -// parent `context.Deadline`. -// -// Note that when this is enabled, any DeadlineExceeded errors that are propagated up will be retried. -func WithPerRetryTimeout(timeout time.Duration) CallOption { - return CallOption{applyFunc: func(o *options) { - o.perCallTimeout = timeout - }} -} - -type options struct { - max uint - perCallTimeout time.Duration - includeHeader bool - codes []codes.Code - backoffFunc BackoffFuncContext -} - -// CallOption is a grpc.CallOption that is local to grpc_retry. -type CallOption struct { - grpc.EmptyCallOption // make sure we implement private after() and before() fields so we don't panic. - applyFunc func(opt *options) -} - -func reuseOrNewWithCallOptions(opt *options, callOptions []CallOption) *options { - if len(callOptions) == 0 { - return opt - } - optCopy := &options{} - *optCopy = *opt - for _, f := range callOptions { - f.applyFunc(optCopy) - } - return optCopy -} - -func filterCallOptions(callOptions []grpc.CallOption) (grpcOptions []grpc.CallOption, retryOptions []CallOption) { - for _, opt := range callOptions { - if co, ok := opt.(CallOption); ok { - retryOptions = append(retryOptions, co) - } else { - grpcOptions = append(grpcOptions, opt) - } - } - return grpcOptions, retryOptions -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/retry.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/retry.go deleted file mode 100644 index 003bbd906..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/retry.go +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_retry - -import ( - "context" - "io" - "strconv" - "sync" - "time" - - "github.com/grpc-ecosystem/go-grpc-middleware/util/metautils" - "golang.org/x/net/trace" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" -) - -const ( - AttemptMetadataKey = "x-retry-attempty" -) - -// UnaryClientInterceptor returns a new retrying unary client interceptor. -// -// The default configuration of the interceptor is to not retry *at all*. This behaviour can be -// changed through options (e.g. WithMax) on creation of the interceptor or on call (through grpc.CallOptions). -func UnaryClientInterceptor(optFuncs ...CallOption) grpc.UnaryClientInterceptor { - intOpts := reuseOrNewWithCallOptions(defaultOptions, optFuncs) - return func(parentCtx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - grpcOpts, retryOpts := filterCallOptions(opts) - callOpts := reuseOrNewWithCallOptions(intOpts, retryOpts) - // short circuit for simplicity, and avoiding allocations. - if callOpts.max == 0 { - return invoker(parentCtx, method, req, reply, cc, grpcOpts...) - } - var lastErr error - for attempt := uint(0); attempt < callOpts.max; attempt++ { - if err := waitRetryBackoff(attempt, parentCtx, callOpts); err != nil { - return err - } - callCtx := perCallContext(parentCtx, callOpts, attempt) - lastErr = invoker(callCtx, method, req, reply, cc, grpcOpts...) - // TODO(mwitkow): Maybe dial and transport errors should be retriable? - if lastErr == nil { - return nil - } - logTrace(parentCtx, "grpc_retry attempt: %d, got err: %v", attempt, lastErr) - if isContextError(lastErr) { - if parentCtx.Err() != nil { - logTrace(parentCtx, "grpc_retry attempt: %d, parent context error: %v", attempt, parentCtx.Err()) - // its the parent context deadline or cancellation. - return lastErr - } else if callOpts.perCallTimeout != 0 { - // We have set a perCallTimeout in the retry middleware, which would result in a context error if - // the deadline was exceeded, in which case try again. - logTrace(parentCtx, "grpc_retry attempt: %d, context error from retry call", attempt) - continue - } - } - if !isRetriable(lastErr, callOpts) { - return lastErr - } - } - return lastErr - } -} - -// StreamClientInterceptor returns a new retrying stream client interceptor for server side streaming calls. -// -// The default configuration of the interceptor is to not retry *at all*. This behaviour can be -// changed through options (e.g. WithMax) on creation of the interceptor or on call (through grpc.CallOptions). -// -// Retry logic is available *only for ServerStreams*, i.e. 1:n streams, as the internal logic needs -// to buffer the messages sent by the client. If retry is enabled on any other streams (ClientStreams, -// BidiStreams), the retry interceptor will fail the call. -func StreamClientInterceptor(optFuncs ...CallOption) grpc.StreamClientInterceptor { - intOpts := reuseOrNewWithCallOptions(defaultOptions, optFuncs) - return func(parentCtx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { - grpcOpts, retryOpts := filterCallOptions(opts) - callOpts := reuseOrNewWithCallOptions(intOpts, retryOpts) - // short circuit for simplicity, and avoiding allocations. - if callOpts.max == 0 { - return streamer(parentCtx, desc, cc, method, grpcOpts...) - } - if desc.ClientStreams { - return nil, status.Errorf(codes.Unimplemented, "grpc_retry: cannot retry on ClientStreams, set grpc_retry.Disable()") - } - - var lastErr error - for attempt := uint(0); attempt < callOpts.max; attempt++ { - if err := waitRetryBackoff(attempt, parentCtx, callOpts); err != nil { - return nil, err - } - callCtx := perCallContext(parentCtx, callOpts, 0) - - var newStreamer grpc.ClientStream - newStreamer, lastErr = streamer(callCtx, desc, cc, method, grpcOpts...) - if lastErr == nil { - retryingStreamer := &serverStreamingRetryingStream{ - ClientStream: newStreamer, - callOpts: callOpts, - parentCtx: parentCtx, - streamerCall: func(ctx context.Context) (grpc.ClientStream, error) { - return streamer(ctx, desc, cc, method, grpcOpts...) - }, - } - return retryingStreamer, nil - } - - logTrace(parentCtx, "grpc_retry attempt: %d, got err: %v", attempt, lastErr) - if isContextError(lastErr) { - if parentCtx.Err() != nil { - logTrace(parentCtx, "grpc_retry attempt: %d, parent context error: %v", attempt, parentCtx.Err()) - // its the parent context deadline or cancellation. - return nil, lastErr - } else if callOpts.perCallTimeout != 0 { - // We have set a perCallTimeout in the retry middleware, which would result in a context error if - // the deadline was exceeded, in which case try again. - logTrace(parentCtx, "grpc_retry attempt: %d, context error from retry call", attempt) - continue - } - } - if !isRetriable(lastErr, callOpts) { - return nil, lastErr - } - } - return nil, lastErr - } -} - -// type serverStreamingRetryingStream is the implementation of grpc.ClientStream that acts as a -// proxy to the underlying call. If any of the RecvMsg() calls fail, it will try to reestablish -// a new ClientStream according to the retry policy. -type serverStreamingRetryingStream struct { - grpc.ClientStream - bufferedSends []interface{} // single message that the client can sen - wasClosedSend bool // indicates that CloseSend was closed - parentCtx context.Context - callOpts *options - streamerCall func(ctx context.Context) (grpc.ClientStream, error) - mu sync.RWMutex -} - -func (s *serverStreamingRetryingStream) setStream(clientStream grpc.ClientStream) { - s.mu.Lock() - s.ClientStream = clientStream - s.mu.Unlock() -} - -func (s *serverStreamingRetryingStream) getStream() grpc.ClientStream { - s.mu.RLock() - defer s.mu.RUnlock() - return s.ClientStream -} - -func (s *serverStreamingRetryingStream) SendMsg(m interface{}) error { - s.mu.Lock() - s.bufferedSends = append(s.bufferedSends, m) - s.mu.Unlock() - return s.getStream().SendMsg(m) -} - -func (s *serverStreamingRetryingStream) CloseSend() error { - s.mu.Lock() - s.wasClosedSend = true - s.mu.Unlock() - return s.getStream().CloseSend() -} - -func (s *serverStreamingRetryingStream) Header() (metadata.MD, error) { - return s.getStream().Header() -} - -func (s *serverStreamingRetryingStream) Trailer() metadata.MD { - return s.getStream().Trailer() -} - -func (s *serverStreamingRetryingStream) RecvMsg(m interface{}) error { - attemptRetry, lastErr := s.receiveMsgAndIndicateRetry(m) - if !attemptRetry { - return lastErr // success or hard failure - } - // We start off from attempt 1, because zeroth was already made on normal SendMsg(). - for attempt := uint(1); attempt < s.callOpts.max; attempt++ { - if err := waitRetryBackoff(attempt, s.parentCtx, s.callOpts); err != nil { - return err - } - callCtx := perCallContext(s.parentCtx, s.callOpts, attempt) - newStream, err := s.reestablishStreamAndResendBuffer(callCtx) - if err != nil { - // Retry dial and transport errors of establishing stream as grpc doesn't retry. - if isRetriable(err, s.callOpts) { - continue - } - return err - } - - s.setStream(newStream) - attemptRetry, lastErr = s.receiveMsgAndIndicateRetry(m) - //fmt.Printf("Received message and indicate: %v %v\n", attemptRetry, lastErr) - if !attemptRetry { - return lastErr - } - } - return lastErr -} - -func (s *serverStreamingRetryingStream) receiveMsgAndIndicateRetry(m interface{}) (bool, error) { - err := s.getStream().RecvMsg(m) - if err == nil || err == io.EOF { - return false, err - } - if isContextError(err) { - if s.parentCtx.Err() != nil { - logTrace(s.parentCtx, "grpc_retry parent context error: %v", s.parentCtx.Err()) - return false, err - } else if s.callOpts.perCallTimeout != 0 { - // We have set a perCallTimeout in the retry middleware, which would result in a context error if - // the deadline was exceeded, in which case try again. - logTrace(s.parentCtx, "grpc_retry context error from retry call") - return true, err - } - } - return isRetriable(err, s.callOpts), err -} - -func (s *serverStreamingRetryingStream) reestablishStreamAndResendBuffer( - callCtx context.Context, -) (grpc.ClientStream, error) { - s.mu.RLock() - bufferedSends := s.bufferedSends - s.mu.RUnlock() - newStream, err := s.streamerCall(callCtx) - if err != nil { - logTrace(callCtx, "grpc_retry failed redialing new stream: %v", err) - return nil, err - } - for _, msg := range bufferedSends { - if err := newStream.SendMsg(msg); err != nil { - logTrace(callCtx, "grpc_retry failed resending message: %v", err) - return nil, err - } - } - if err := newStream.CloseSend(); err != nil { - logTrace(callCtx, "grpc_retry failed CloseSend on new stream %v", err) - return nil, err - } - return newStream, nil -} - -func waitRetryBackoff(attempt uint, parentCtx context.Context, callOpts *options) error { - var waitTime time.Duration = 0 - if attempt > 0 { - waitTime = callOpts.backoffFunc(parentCtx, attempt) - } - if waitTime > 0 { - logTrace(parentCtx, "grpc_retry attempt: %d, backoff for %v", attempt, waitTime) - timer := time.NewTimer(waitTime) - select { - case <-parentCtx.Done(): - timer.Stop() - return contextErrToGrpcErr(parentCtx.Err()) - case <-timer.C: - } - } - return nil -} - -func isRetriable(err error, callOpts *options) bool { - errCode := status.Code(err) - if isContextError(err) { - // context errors are not retriable based on user settings. - return false - } - for _, code := range callOpts.codes { - if code == errCode { - return true - } - } - return false -} - -func isContextError(err error) bool { - code := status.Code(err) - return code == codes.DeadlineExceeded || code == codes.Canceled -} - -func perCallContext(parentCtx context.Context, callOpts *options, attempt uint) context.Context { - ctx := parentCtx - if callOpts.perCallTimeout != 0 { - ctx, _ = context.WithTimeout(ctx, callOpts.perCallTimeout) - } - if attempt > 0 && callOpts.includeHeader { - mdClone := metautils.ExtractOutgoing(ctx).Clone().Set(AttemptMetadataKey, strconv.FormatUint(uint64(attempt), 10)) - ctx = mdClone.ToOutgoing(ctx) - } - return ctx -} - -func contextErrToGrpcErr(err error) error { - switch err { - case context.DeadlineExceeded: - return status.Error(codes.DeadlineExceeded, err.Error()) - case context.Canceled: - return status.Error(codes.Canceled, err.Error()) - default: - return status.Error(codes.Unknown, err.Error()) - } -} - -func logTrace(ctx context.Context, format string, a ...interface{}) { - tr, ok := trace.FromContext(ctx) - if !ok { - return - } - tr.LazyPrintf(format, a...) -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/slack.png b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/slack.png deleted file mode 100644 index cc8f9a68a9368ca56dab09e6902ae41ecb8356b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5088 zcmZ|Tc{Ei2`vCAe3x;e-vX2jlNl|9+lk+JWL6qTqDN!GHjk+C(5ghC|Q z89rp+TE@P8@A&Wc$M1E{ooDX7=b1U@eeXQaGxw31i7o>jCmjF)4ElOn=3p!VH&$k9 z@Kt}PY#$78cXeZR0C@NG+>s*{xXd;33>H00c<_z^VfPD82-M zOW4=V*OkE&)J}%FT3`h2YqrFIfflQ09RNm~vkfcI7zMte3Dh^%rkR6tA+FNiG=De_ z04%BcTIx4LCpPTDZn9dAoZbov8v4dCE&J634Y7Qp&X3^i)B1M(ADWDkSV*iN7kd)> zqd4~Y*H}BDdBJ$Wu0|IuL+0RbEjvkFo(wIsbO_aTEJU62)m;xvI%)0jP3x;w2nU<) z@2u*WC30Bt>TuK+>2UK948xvI_!&&wc(kmn$)(p4^0&uYvw!h_KvchE7vw+xNJ63p z3Va*cnVhjFDE_dqa(r-66Cwh$yDuYa9*+6AtDq3Cwa`yfL=H^(#{~0H2xDMeh>qp- z^0}j7#;SeYqT9-`^VAd*dw##F3SPruUt0PBV_h~NfP4F@M5ydvA!>`oqlOxml8Y8r zzfJG|=l*wk%qpd)pteM8&76R;qWwW9TCpcwP@;TaNh#IBX&G4&UHg$vw7J6|@A&?( zsfCrJb_kZ;Db(IIm_invBB-A-P@PNa5ztNMR`CDXx!apYBH{6GbYWa_$-D%2rihp| ziumC^e*@} z5o=w0)5UGOMz$zNTcdDaT%=!s;j^5_|Ht17GT%whqFOCH|R>^DXD zMAt}!?X}qW_^PT`uTGwxI&3RM$cnB1cIFcXO+WPqH??+8`FYhm@jsCz)QXkD-GBF8Qf68r3Zu%CeRqd`Zn=g=d52GkeC(9`Y}Fe(j(-f zIIZf6-pfd_l$3qrk^7gQy|S@j;}~za9XDL8R95EYEh-vYQPI=WXN2p%kf^|&j_&P6 zs)~ui`m@W+6oct&8ffAfV2nJElL&#djZrO?l{L?@_rQ9^QRmL|>*P?_w5tocu)x63 z*$E_QGTTYa&PjQtX+h1>DmTz`cKK#kSm_*o&!q}?e8m02-kDkU;FAs*spv?EP2xh? z8yP_HzSR|dpMmJ@aw0K})!{!4WbUnUoT(Zi1a+<6{YWx1SL@@Fk^-dM^6=o~KPI%( z+~6B&H-LeG)7VG+SsJ;E%XjyYFVTVXHO#B;RyQ&## z@L;7Qc6O3T9k8(m-`{i6?zlq3#Ke`0w}Q48deMR8w10au>Nc*5R%OW{)g;8;Ru>yV zHc3%`ej-l+AtPqGViPJxq=fkKswl4DzQ$wd$zC@yW~v5aR%&DW!a(+hi2)t0bqkwS z4RKmUf#Y+3Rpm6kax2t7c!wMq$lZ9GI&QpTbXUy;yd#Iti1`&2Q@}2sL0_jh?;y!e zPpvrsaqi)ecI$h26^1xR0Ylv5L)`m{%`{36i~jlfIoLtqWoK{)6ya#0RIm`@k(CzZ z!(P@Jt~FtQ7r$o7!J5vX?J0Qq*b+OP{AS?echqR%5)#~uv-8rCjnyc#J2N8|H(>N! zI}_f@ypq8c#Y^{TiKc2QVJTVX^aSU-|Awj@a;Qv<$VxI_5iKuo@q>NyQc=lz1w8uH z72gdr$&LOsyL_GRvg_QZuUX;?>+4Wh>|_HMr-31)exkDw&&Dp>H<{H9`}2qO@m4Er zr1HWe@Z!LsjJj9g&CNzdJ3FKe&I;9Ozl~SsVT<$*zG_~q`a2b$2pZ_m?Pe&u-psIvNqrE7IY+BJO(JCuY8Qd0kALDo~MNUruFUps0kp?Xp@ZQ>(NTrg)<2ilGn-s%qyqC*?ACXe<52jCC{+^x<` zudRfOGkjvmR+(W$qRFl}Vz1`ZPs#!6<4FNwIfMI>Dr}mg%z>bzfI6MQy+4x!Tb!qW zY3Wcv|2>1#c{AuCgZ7}fQsdBmkLny-jej`7zIwDyt9Sl)sIt9jg4Fi()+IKI+KoGH z(Z>hdYbuXg<;V-dmoCK;hc1jY`b{;eL;y52DQN}}-lqi^46Z`#(a$~(;^buiU9hnT zU3g??hg)6k@2{1bO+=NIeIFX%dD2xSQOCiDprN@3EQ`ljFmZ8Z_Whx1pOVW|RPt0% z%w5DT2LU%w%<>9;P3itR0@{#(#m1KIZrHg?t$*mU^}ox9zsK)@y&NxF|4OJJc4df1 zC^at5WK=1i7S2MO%M=)BcGL0_ddp*Q-Z%v}_<2m%6msvG0R$(gT~M5)MDSBbDP)MP zOt&IqFqos02t$R^9}W)E|1fs<_hYC76;t(#-$?WHo**>%Br`qC8lbq*)B@>@?%*0I@&nN;MQ%13cLLdrt8;La^(5zc-hS1AWflLodNPhs z$(YuJZm?fFIhpkLWr7!LsB{=@^|E2N!kXB!MNM60H$Id@np?5nSVd7s(hayoo()&Y zXg`XpHDCw3-4gtc<1M8gKTx4D=VL~|p?PQ3A#*x4jnV*FUn&GF_GL;(^jtLzx^sp& zK=HKFUCKm>q9rGp)E0Aka(p;WpZ?`FM-qV8wy}tu! z9i6+IwXSHl#g!rNQRrxuN+|X}C^ItVmqVz0P0-qS-P*`Drn*3*P(%bOWP}Z3perz4 zo1Pjwu&$e$c6JIsDE(kpC?W>$N)8HUMC9$piyg~E;InKoV%Q~<8$(~S(7FkOC4)eB z@{6>{L-AiblXqfN{P=B8erZ~dKNpA_Enb2bX%ZU3b<`GHTUyYPPH>-rPmj>r+J=UX z|6teB4T6ppCH>zTEpC}^5sY7Za4^XP(LJ!MvYKj$G8K4Lym4{I4Jm4zK^X70n`th* zNos7LxXkL`#K?$=(tDUXG_=_6un;~pzi3=on+N>*{rrp0Q|gZ$Goj91^k^|&xn#j{ z|J5IIGxQ7_`eU7)be+TH#JNs;`*KT|t1CDJQUUrClNaD-HV1ot>X4eycMZF%!{GG_ z_&Z!)@u9M^osSJhr)_KNEP!V2NN8w)IlXIB(}xBu!r@|8MDo~aXt+hofi0svEGUG6 zCgqIS%e@%d^}XNo-A|G3OmWRjR{9jQErB!dJ%@^nv&K63o9rYqdLa>KEUL;W5~mN1 zj451cQx%TJTSB%-goxN43Ilvh5h0F-iB~z4+3LN=V1afbj!Et4R|k_C9FG|X2XZ!i z?&fl@sgaHl+f$@z3h_QIFR!{faVdAEEjOL|!{6lG8Svh{e*MPKLhpJ2p}yK8peZSd zD4hFREjNcT^3NCYN_R3uktaLzHo@jbz$SOzphvxFPR$=5AHh;HAWJq|@x^O;%#?h< zqTCFi%$w0W4>53!XwiT~k_VdtL@lAXV&QCcMWq0F%s7u%y}cTH6!ogEgk||f1kSgW zmhRwiW_-X$^<=LvbC(2@;e1|F_#i5Jy7_|e+PwY~H49>Y@_;)dZJ!%hmqbM6 zFn|oF`;zx)ctf?^y_K!{%LLV^g46P;RAJ>D4am`o=_Qn#3y_&PRK%kQ|GYrX*T0=@ z;2PGrTLCtRK~n!x10K3X2w5L%*@Aj{*13cA{>zu>Xk<)Zj+don`S8L5TKj>`ZL81t z8x|v^=xveNRS{OOni)T{tO8iIFK`8@#GI5@3kgA8T{#(y^Z3teLmoWv-v_4^t@}5d zL$B8O*gDLH%s@Dk21_hp{$V##?HJ|d^$L@dk2z>K2fQp})cdmJd`Ta|j*HE*O^SzB z#x941NOBbE34$Xk+L=ON_H5++DDiICtKOy(ZwDRR&3uw(Z6lreFU;-V0rJdrY@g$W zRBNeY=>)@yxJi(8#LH-Qm1gI>)2<&AHa1?801GWaw`jO$LFfXSnM}Tju)8gu@twfP zoNsXsjyCM=NZ@2ZBa?u^!BnBnE~qbIVUw4K;pk-d+BHAF^k^@iYgw`V{mqK0w0SG= zS?pfqJwS^eiIfPLHB4_`eRFehX>A*4#KvjR=5=!MlEnQ4IXPHq+whseVvzZIEPd>n*c0HEB^=b!T)9QYs_=a=?8XoCa14=Hoi@)!d!C3hU}x zNiI;A+Gos$QPiTNS-ek9czB-jawL&S(&Fj^5-F^7v;|A{0`nQ^>2pqTv6T()`~rVs zfozjPsVqoRQCZJ-Un6d*4R4v<&B1xyn8;6V z_@5+XbLzAR)tTtNkV~=sx!;hur~c>cV>Wyz?6{lDo6_rS*%QgIK@+5n!#;|{wB)KyB4U|;DLJPP1C@@FzM@~ctV z`mHaSe&=SWiri9zfq#_FkUp?_PmRjf*3^_S zLE;YeaZZM+`O42Pr<>#nI#GKOILrA)zKm3Cy!7h;|7BwR5gE*}62^niPug*NjKT`} z3JP|)qN41kp6 zRe5nq8F4AOo02k$G75^43gE7yq@<=ga_s*k`1rbbx`qA!2~ym}E?|NrQ|-94SX#jjnJm)CTa(>D^oW*K(PRrb$m?jo2A=xdv3 JRcScf`yb{=X{rDK diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go deleted file mode 100644 index 0da1658bb..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/context.go +++ /dev/null @@ -1,78 +0,0 @@ -package grpc_ctxtags - -import ( - "context" -) - -type ctxMarker struct{} - -var ( - // ctxMarkerKey is the Context value marker used by *all* logging middleware. - // The logging middleware object must interf - ctxMarkerKey = &ctxMarker{} - // NoopTags is a trivial, minimum overhead implementation of Tags for which all operations are no-ops. - NoopTags = &noopTags{} -) - -// Tags is the interface used for storing request tags between Context calls. -// The default implementation is *not* thread safe, and should be handled only in the context of the request. -type Tags interface { - // Set sets the given key in the metadata tags. - Set(key string, value interface{}) Tags - // Has checks if the given key exists. - Has(key string) bool - // Values returns a map of key to values. - // Do not modify the underlying map, please use Set instead. - Values() map[string]interface{} -} - -type mapTags struct { - values map[string]interface{} -} - -func (t *mapTags) Set(key string, value interface{}) Tags { - t.values[key] = value - return t -} - -func (t *mapTags) Has(key string) bool { - _, ok := t.values[key] - return ok -} - -func (t *mapTags) Values() map[string]interface{} { - return t.values -} - -type noopTags struct{} - -func (t *noopTags) Set(key string, value interface{}) Tags { - return t -} - -func (t *noopTags) Has(key string) bool { - return false -} - -func (t *noopTags) Values() map[string]interface{} { - return nil -} - -// Extracts returns a pre-existing Tags object in the Context. -// If the context wasn't set in a tag interceptor, a no-op Tag storage is returned that will *not* be propagated in context. -func Extract(ctx context.Context) Tags { - t, ok := ctx.Value(ctxMarkerKey).(Tags) - if !ok { - return NoopTags - } - - return t -} - -func SetInContext(ctx context.Context, tags Tags) context.Context { - return context.WithValue(ctx, ctxMarkerKey, tags) -} - -func NewTags() Tags { - return &mapTags{values: make(map[string]interface{})} -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go deleted file mode 100644 index 960638d0f..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -/* -`grpc_ctxtags` adds a Tag object to the context that can be used by other middleware to add context about a request. - -Request Context Tags - -Tags describe information about the request, and can be set and used by other middleware, or handlers. Tags are used -for logging and tracing of requests. Tags are populated both upwards, *and* downwards in the interceptor-handler stack. - -You can automatically extract tags (in `grpc.request.`) from request payloads. - -For unary and server-streaming methods, pass in the `WithFieldExtractor` option. For client-streams and bidirectional-streams, you can -use `WithFieldExtractorForInitialReq` which will extract the tags from the first message passed from client to server. -Note the tags will not be modified for subsequent requests, so this option only makes sense when the initial message -establishes the meta-data for the stream. - -If a user doesn't use the interceptors that initialize the `Tags` object, all operations following from an `Extract(ctx)` -will be no-ops. This is to ensure that code doesn't panic if the interceptors weren't used. - -Tags fields are typed, and shallow and should follow the OpenTracing semantics convention: -https://github.com/opentracing/specification/blob/master/semantic_conventions.md -*/ -package grpc_ctxtags diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go deleted file mode 100644 index a4073ab49..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/fieldextractor.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2017 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_ctxtags - -import ( - "reflect" -) - -// RequestFieldExtractorFunc is a user-provided function that extracts field information from a gRPC request. -// It is called from tags middleware on arrival of unary request or a server-stream request. -// Keys and values will be added to the context tags of the request. If there are no fields, you should return a nil. -type RequestFieldExtractorFunc func(fullMethod string, req interface{}) map[string]interface{} - -type requestFieldsExtractor interface { - // ExtractRequestFields is a method declared on a Protobuf message that extracts fields from the interface. - // The values from the extracted fields should be set in the appendToMap, in order to avoid allocations. - ExtractRequestFields(appendToMap map[string]interface{}) -} - -// CodeGenRequestFieldExtractor is a function that relies on code-generated functions that export log fields from requests. -// These are usually coming from a protoc-plugin that generates additional information based on custom field options. -func CodeGenRequestFieldExtractor(fullMethod string, req interface{}) map[string]interface{} { - if ext, ok := req.(requestFieldsExtractor); ok { - retMap := make(map[string]interface{}) - ext.ExtractRequestFields(retMap) - if len(retMap) == 0 { - return nil - } - return retMap - } - return nil -} - -// TagBasedRequestFieldExtractor is a function that relies on Go struct tags to export log fields from requests. -// These are usually coming from a protoc-plugin, such as Gogo protobuf. -// -// message Metadata { -// repeated string tags = 1 [ (gogoproto.moretags) = "log_field:\"meta_tags\"" ]; -// } -// -// The tagName is configurable using the tagName variable. Here it would be "log_field". -func TagBasedRequestFieldExtractor(tagName string) RequestFieldExtractorFunc { - return func(fullMethod string, req interface{}) map[string]interface{} { - retMap := make(map[string]interface{}) - reflectMessageTags(req, retMap, tagName) - if len(retMap) == 0 { - return nil - } - return retMap - } -} - -func reflectMessageTags(msg interface{}, existingMap map[string]interface{}, tagName string) { - v := reflect.ValueOf(msg) - // Only deal with pointers to structs. - if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { - return - } - // Deref the pointer get to the struct. - v = v.Elem() - t := v.Type() - for i := 0; i < v.NumField(); i++ { - field := v.Field(i) - kind := field.Kind() - // Only recurse down direct pointers, which should only be to nested structs. - if (kind == reflect.Ptr || kind == reflect.Interface) && field.CanInterface() { - reflectMessageTags(field.Interface(), existingMap, tagName) - } - // In case of arrays/slices (repeated fields) go down to the concrete type. - if kind == reflect.Array || kind == reflect.Slice { - if field.Len() == 0 { - continue - } - kind = field.Index(0).Kind() - } - // Only be interested in - if (kind >= reflect.Bool && kind <= reflect.Float64) || kind == reflect.String { - if tag := t.Field(i).Tag.Get(tagName); tag != "" { - existingMap[tag] = field.Interface() - } - } - } - return -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go deleted file mode 100644 index a7ced60f5..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/interceptors.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2017 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_ctxtags - -import ( - "context" - - "google.golang.org/grpc" - "google.golang.org/grpc/peer" - - "github.com/grpc-ecosystem/go-grpc-middleware" -) - -// UnaryServerInterceptor returns a new unary server interceptors that sets the values for request tags. -func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor { - o := evaluateOptions(opts) - return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - newCtx := newTagsForCtx(ctx) - if o.requestFieldsFunc != nil { - setRequestFieldTags(newCtx, o.requestFieldsFunc, info.FullMethod, req) - } - return handler(newCtx, req) - } -} - -// StreamServerInterceptor returns a new streaming server interceptor that sets the values for request tags. -func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor { - o := evaluateOptions(opts) - return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - newCtx := newTagsForCtx(stream.Context()) - if o.requestFieldsFunc == nil { - // Short-circuit, don't do the expensive bit of allocating a wrappedStream. - wrappedStream := grpc_middleware.WrapServerStream(stream) - wrappedStream.WrappedContext = newCtx - return handler(srv, wrappedStream) - } - wrapped := &wrappedStream{stream, info, o, newCtx, true} - err := handler(srv, wrapped) - return err - } -} - -// wrappedStream is a thin wrapper around grpc.ServerStream that allows modifying context and extracts log fields from the initial message. -type wrappedStream struct { - grpc.ServerStream - info *grpc.StreamServerInfo - opts *options - // WrappedContext is the wrapper's own Context. You can assign it. - WrappedContext context.Context - initial bool -} - -// Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context() -func (w *wrappedStream) Context() context.Context { - return w.WrappedContext -} - -func (w *wrappedStream) RecvMsg(m interface{}) error { - err := w.ServerStream.RecvMsg(m) - // We only do log fields extraction on the single-request of a server-side stream. - if !w.info.IsClientStream || w.opts.requestFieldsFromInitial && w.initial { - w.initial = false - - setRequestFieldTags(w.Context(), w.opts.requestFieldsFunc, w.info.FullMethod, m) - } - return err -} - -func newTagsForCtx(ctx context.Context) context.Context { - t := NewTags() - if peer, ok := peer.FromContext(ctx); ok { - t.Set("peer.address", peer.Addr.String()) - } - return SetInContext(ctx, t) -} - -func setRequestFieldTags(ctx context.Context, f RequestFieldExtractorFunc, fullMethodName string, req interface{}) { - if valMap := f(fullMethodName, req); valMap != nil { - t := Extract(ctx) - for k, v := range valMap { - t.Set("grpc.request."+k, v) - } - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go deleted file mode 100644 index 952775f88..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/options.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2017 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_ctxtags - -var ( - defaultOptions = &options{ - requestFieldsFunc: nil, - } -) - -type options struct { - requestFieldsFunc RequestFieldExtractorFunc - requestFieldsFromInitial bool -} - -func evaluateOptions(opts []Option) *options { - optCopy := &options{} - *optCopy = *defaultOptions - for _, o := range opts { - o(optCopy) - } - return optCopy -} - -type Option func(*options) - -// WithFieldExtractor customizes the function for extracting log fields from protobuf messages, for -// unary and server-streamed methods only. -func WithFieldExtractor(f RequestFieldExtractorFunc) Option { - return func(o *options) { - o.requestFieldsFunc = f - } -} - -// WithFieldExtractorForInitialReq customizes the function for extracting log fields from protobuf messages, -// for all unary and streaming methods. For client-streams and bidirectional-streams, the tags will be -// extracted from the first message from the client. -func WithFieldExtractorForInitialReq(f RequestFieldExtractorFunc) Option { - return func(o *options) { - o.requestFieldsFunc = f - o.requestFieldsFromInitial = true - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/client_interceptors.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/client_interceptors.go deleted file mode 100644 index 2e9cafd2b..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/client_interceptors.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2017 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_opentracing - -import ( - "context" - "io" - "sync" - - "github.com/grpc-ecosystem/go-grpc-middleware/util/metautils" - opentracing "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/ext" - "github.com/opentracing/opentracing-go/log" - "google.golang.org/grpc" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/metadata" -) - -// UnaryClientInterceptor returns a new unary client interceptor for OpenTracing. -func UnaryClientInterceptor(opts ...Option) grpc.UnaryClientInterceptor { - o := evaluateOptions(opts) - return func(parentCtx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - if o.filterOutFunc != nil && !o.filterOutFunc(parentCtx, method) { - return invoker(parentCtx, method, req, reply, cc, opts...) - } - newCtx, clientSpan := newClientSpanFromContext(parentCtx, o.tracer, method) - if o.unaryRequestHandlerFunc != nil { - o.unaryRequestHandlerFunc(clientSpan, req) - } - err := invoker(newCtx, method, req, reply, cc, opts...) - finishClientSpan(clientSpan, err) - return err - } -} - -// StreamClientInterceptor returns a new streaming client interceptor for OpenTracing. -func StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor { - o := evaluateOptions(opts) - return func(parentCtx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { - if o.filterOutFunc != nil && !o.filterOutFunc(parentCtx, method) { - return streamer(parentCtx, desc, cc, method, opts...) - } - newCtx, clientSpan := newClientSpanFromContext(parentCtx, o.tracer, method) - clientStream, err := streamer(newCtx, desc, cc, method, opts...) - if err != nil { - finishClientSpan(clientSpan, err) - return nil, err - } - return &tracedClientStream{ClientStream: clientStream, clientSpan: clientSpan}, nil - } -} - -// type serverStreamingRetryingStream is the implementation of grpc.ClientStream that acts as a -// proxy to the underlying call. If any of the RecvMsg() calls fail, it will try to reestablish -// a new ClientStream according to the retry policy. -type tracedClientStream struct { - grpc.ClientStream - mu sync.Mutex - alreadyFinished bool - clientSpan opentracing.Span -} - -func (s *tracedClientStream) Header() (metadata.MD, error) { - h, err := s.ClientStream.Header() - if err != nil { - s.finishClientSpan(err) - } - return h, err -} - -func (s *tracedClientStream) SendMsg(m interface{}) error { - err := s.ClientStream.SendMsg(m) - if err != nil { - s.finishClientSpan(err) - } - return err -} - -func (s *tracedClientStream) CloseSend() error { - err := s.ClientStream.CloseSend() - s.finishClientSpan(err) - return err -} - -func (s *tracedClientStream) RecvMsg(m interface{}) error { - err := s.ClientStream.RecvMsg(m) - if err != nil { - s.finishClientSpan(err) - } - return err -} - -func (s *tracedClientStream) finishClientSpan(err error) { - s.mu.Lock() - defer s.mu.Unlock() - if !s.alreadyFinished { - finishClientSpan(s.clientSpan, err) - s.alreadyFinished = true - } -} - -// ClientAddContextTags returns a context with specified opentracing tags, which -// are used by UnaryClientInterceptor/StreamClientInterceptor when creating a -// new span. -func ClientAddContextTags(ctx context.Context, tags opentracing.Tags) context.Context { - return context.WithValue(ctx, clientSpanTagKey{}, tags) -} - -type clientSpanTagKey struct{} - -func newClientSpanFromContext(ctx context.Context, tracer opentracing.Tracer, fullMethodName string) (context.Context, opentracing.Span) { - var parentSpanCtx opentracing.SpanContext - if parent := opentracing.SpanFromContext(ctx); parent != nil { - parentSpanCtx = parent.Context() - } - opts := []opentracing.StartSpanOption{ - opentracing.ChildOf(parentSpanCtx), - ext.SpanKindRPCClient, - grpcTag, - } - if tagx := ctx.Value(clientSpanTagKey{}); tagx != nil { - if opt, ok := tagx.(opentracing.StartSpanOption); ok { - opts = append(opts, opt) - } - } - clientSpan := tracer.StartSpan(fullMethodName, opts...) - // Make sure we add this to the metadata of the call, so it gets propagated: - md := metautils.ExtractOutgoing(ctx).Clone() - if err := tracer.Inject(clientSpan.Context(), opentracing.HTTPHeaders, metadataTextMap(md)); err != nil { - grpclog.Infof("grpc_opentracing: failed serializing trace information: %v", err) - } - ctxWithMetadata := md.ToOutgoing(ctx) - return opentracing.ContextWithSpan(ctxWithMetadata, clientSpan), clientSpan -} - -func finishClientSpan(clientSpan opentracing.Span, err error) { - if err != nil && err != io.EOF { - ext.Error.Set(clientSpan, true) - clientSpan.LogFields(log.String("event", "error"), log.String("message", err.Error())) - } - clientSpan.Finish() -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/doc.go deleted file mode 100644 index 7a58efc22..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -/* -`grpc_opentracing` adds OpenTracing - -OpenTracing Interceptors - -These are both client-side and server-side interceptors for OpenTracing. They are a provider-agnostic, with backends -such as Zipkin, or Google Stackdriver Trace. - -For a service that sends out requests and receives requests, you *need* to use both, otherwise downstream requests will -not have the appropriate requests propagated. - -All server-side spans are tagged with grpc_ctxtags information. - -For more information see: -http://opentracing.io/documentation/ -https://github.com/opentracing/specification/blob/master/semantic_conventions.md - -*/ -package grpc_opentracing diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/id_extract.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/id_extract.go deleted file mode 100644 index bc7302e3a..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/id_extract.go +++ /dev/null @@ -1,82 +0,0 @@ -package grpc_opentracing - -import ( - "strings" - - grpc_ctxtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" - opentracing "github.com/opentracing/opentracing-go" - "google.golang.org/grpc/grpclog" -) - -const ( - TagTraceId = "trace.traceid" - TagSpanId = "trace.spanid" - TagSampled = "trace.sampled" - jaegerNotSampledFlag = "0" -) - -// injectOpentracingIdsToTags writes trace data to ctxtags. -// This is done in an incredibly hacky way, because the public-facing interface of opentracing doesn't give access to -// the TraceId and SpanId of the SpanContext. Only the Tracer's Inject/Extract methods know what these are. -// Most tracers have them encoded as keys with 'traceid' and 'spanid': -// https://github.com/openzipkin/zipkin-go-opentracing/blob/594640b9ef7e5c994e8d9499359d693c032d738c/propagation_ot.go#L29 -// https://github.com/opentracing/basictracer-go/blob/1b32af207119a14b1b231d451df3ed04a72efebf/propagation_ot.go#L26 -// Jaeger from Uber use one-key schema with next format '{trace-id}:{span-id}:{parent-span-id}:{flags}' -// https://www.jaegertracing.io/docs/client-libraries/#trace-span-identity -// Datadog uses keys ending with 'trace-id' and 'parent-id' (for span) by default: -// https://github.com/DataDog/dd-trace-go/blob/v1/ddtrace/tracer/textmap.go#L77 -func injectOpentracingIdsToTags(traceHeaderName string, span opentracing.Span, tags grpc_ctxtags.Tags) { - if err := span.Tracer().Inject(span.Context(), opentracing.HTTPHeaders, - &tagsCarrier{Tags: tags, traceHeaderName: traceHeaderName}); err != nil { - grpclog.Infof("grpc_opentracing: failed extracting trace info into ctx %v", err) - } -} - -// tagsCarrier is a really hacky way of -type tagsCarrier struct { - grpc_ctxtags.Tags - traceHeaderName string -} - -func (t *tagsCarrier) Set(key, val string) { - key = strings.ToLower(key) - - if key == t.traceHeaderName { - parts := strings.Split(val, ":") - if len(parts) == 4 { - t.Tags.Set(TagTraceId, parts[0]) - t.Tags.Set(TagSpanId, parts[1]) - - if parts[3] != jaegerNotSampledFlag { - t.Tags.Set(TagSampled, "true") - } else { - t.Tags.Set(TagSampled, "false") - } - - return - } - } - - if strings.Contains(key, "traceid") { - t.Tags.Set(TagTraceId, val) // this will most likely be base-16 (hex) encoded - } - - if strings.Contains(key, "spanid") && !strings.Contains(strings.ToLower(key), "parent") { - t.Tags.Set(TagSpanId, val) // this will most likely be base-16 (hex) encoded - } - - if strings.Contains(key, "sampled") { - switch val { - case "true", "false": - t.Tags.Set(TagSampled, val) - } - } - - if strings.HasSuffix(key, "trace-id") { - t.Tags.Set(TagTraceId, val) - } - - if strings.HasSuffix(key, "parent-id") { - t.Tags.Set(TagSpanId, val) - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/metadata.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/metadata.go deleted file mode 100644 index 3649fb5b8..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/metadata.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2017 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_opentracing - -import ( - "encoding/base64" - "strings" - - "google.golang.org/grpc/metadata" -) - -const ( - binHdrSuffix = "-bin" -) - -// metadataTextMap extends a metadata.MD to be an opentracing textmap -type metadataTextMap metadata.MD - -// Set is a opentracing.TextMapReader interface that extracts values. -func (m metadataTextMap) Set(key, val string) { - // gRPC allows for complex binary values to be written. - encodedKey, encodedVal := encodeKeyValue(key, val) - // The metadata object is a multimap, and previous values may exist, but for opentracing headers, we do not append - // we just override. - m[encodedKey] = []string{encodedVal} -} - -// ForeachKey is a opentracing.TextMapReader interface that extracts values. -func (m metadataTextMap) ForeachKey(callback func(key, val string) error) error { - for k, vv := range m { - for _, v := range vv { - if err := callback(k, v); err != nil { - return err - } - } - } - return nil -} - -// encodeKeyValue encodes key and value qualified for transmission via gRPC. -// note: copy pasted from private values of grpc.metadata -func encodeKeyValue(k, v string) (string, string) { - k = strings.ToLower(k) - if strings.HasSuffix(k, binHdrSuffix) { - val := base64.StdEncoding.EncodeToString([]byte(v)) - v = string(val) - } - return k, v -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/options.go deleted file mode 100644 index 430fe56a1..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/options.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2017 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_opentracing - -import ( - "context" - - "github.com/opentracing/opentracing-go" -) - -var ( - defaultOptions = &options{ - filterOutFunc: nil, - tracer: nil, - } -) - -// FilterFunc allows users to provide a function that filters out certain methods from being traced. -// -// If it returns false, the given request will not be traced. -type FilterFunc func(ctx context.Context, fullMethodName string) bool - -// UnaryRequestHandlerFunc is a custom request handler -type UnaryRequestHandlerFunc func(span opentracing.Span, req interface{}) - -// OpNameFunc is a func that allows custom operation names instead of the gRPC method. -type OpNameFunc func(method string) string - -type options struct { - filterOutFunc FilterFunc - tracer opentracing.Tracer - traceHeaderName string - unaryRequestHandlerFunc UnaryRequestHandlerFunc - opNameFunc OpNameFunc -} - -func evaluateOptions(opts []Option) *options { - optCopy := &options{} - *optCopy = *defaultOptions - for _, o := range opts { - o(optCopy) - } - if optCopy.tracer == nil { - optCopy.tracer = opentracing.GlobalTracer() - } - if optCopy.traceHeaderName == "" { - optCopy.traceHeaderName = "uber-trace-id" - } - return optCopy -} - -type Option func(*options) - -// WithFilterFunc customizes the function used for deciding whether a given call is traced or not. -func WithFilterFunc(f FilterFunc) Option { - return func(o *options) { - o.filterOutFunc = f - } -} - -// WithTraceHeaderName customizes the trace header name where trace metadata passed with requests. -// Default one is `uber-trace-id` -func WithTraceHeaderName(name string) Option { - return func(o *options) { - o.traceHeaderName = name - } -} - -// WithTracer sets a custom tracer to be used for this middleware, otherwise the opentracing.GlobalTracer is used. -func WithTracer(tracer opentracing.Tracer) Option { - return func(o *options) { - o.tracer = tracer - } -} - -// WithUnaryRequestHandlerFunc sets a custom handler for the request -func WithUnaryRequestHandlerFunc(f UnaryRequestHandlerFunc) Option { - return func(o *options) { - o.unaryRequestHandlerFunc = f - } -} - -// WithOpName customizes the trace Operation name -func WithOpName(f OpNameFunc) Option { - return func(o *options) { - o.opNameFunc = f - } -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/server_interceptors.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/server_interceptors.go deleted file mode 100644 index 186b1084f..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/server_interceptors.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2017 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_opentracing - -import ( - "context" - - "github.com/grpc-ecosystem/go-grpc-middleware" - "github.com/grpc-ecosystem/go-grpc-middleware/tags" - "github.com/grpc-ecosystem/go-grpc-middleware/util/metautils" - "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/ext" - "github.com/opentracing/opentracing-go/log" - "google.golang.org/grpc" - "google.golang.org/grpc/grpclog" -) - -var ( - grpcTag = opentracing.Tag{Key: string(ext.Component), Value: "gRPC"} -) - -// UnaryServerInterceptor returns a new unary server interceptor for OpenTracing. -func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor { - o := evaluateOptions(opts) - return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - if o.filterOutFunc != nil && !o.filterOutFunc(ctx, info.FullMethod) { - return handler(ctx, req) - } - opName := info.FullMethod - if o.opNameFunc != nil { - opName = o.opNameFunc(info.FullMethod) - } - newCtx, serverSpan := newServerSpanFromInbound(ctx, o.tracer, o.traceHeaderName, opName) - if o.unaryRequestHandlerFunc != nil { - o.unaryRequestHandlerFunc(serverSpan, req) - } - resp, err := handler(newCtx, req) - finishServerSpan(ctx, serverSpan, err) - return resp, err - } -} - -// StreamServerInterceptor returns a new streaming server interceptor for OpenTracing. -func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor { - o := evaluateOptions(opts) - return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - if o.filterOutFunc != nil && !o.filterOutFunc(stream.Context(), info.FullMethod) { - return handler(srv, stream) - } - opName := info.FullMethod - if o.opNameFunc != nil { - opName = o.opNameFunc(info.FullMethod) - } - newCtx, serverSpan := newServerSpanFromInbound(stream.Context(), o.tracer, o.traceHeaderName, opName) - wrappedStream := grpc_middleware.WrapServerStream(stream) - wrappedStream.WrappedContext = newCtx - err := handler(srv, wrappedStream) - finishServerSpan(newCtx, serverSpan, err) - return err - } -} - -func newServerSpanFromInbound(ctx context.Context, tracer opentracing.Tracer, traceHeaderName, opName string) (context.Context, opentracing.Span) { - md := metautils.ExtractIncoming(ctx) - parentSpanContext, err := tracer.Extract(opentracing.HTTPHeaders, metadataTextMap(md)) - if err != nil && err != opentracing.ErrSpanContextNotFound { - grpclog.Infof("grpc_opentracing: failed parsing trace information: %v", err) - } - - serverSpan := tracer.StartSpan( - opName, - // this is magical, it attaches the new span to the parent parentSpanContext, and creates an unparented one if empty. - ext.RPCServerOption(parentSpanContext), - grpcTag, - ) - - injectOpentracingIdsToTags(traceHeaderName, serverSpan, grpc_ctxtags.Extract(ctx)) - return opentracing.ContextWithSpan(ctx, serverSpan), serverSpan -} - -func finishServerSpan(ctx context.Context, serverSpan opentracing.Span, err error) { - // Log context information - tags := grpc_ctxtags.Extract(ctx) - for k, v := range tags.Values() { - // Don't tag errors, log them instead. - if vErr, ok := v.(error); ok { - serverSpan.LogKV(k, vErr.Error()) - } else { - serverSpan.SetTag(k, v) - } - } - if err != nil { - ext.Error.Set(serverSpan, true) - serverSpan.LogFields(log.String("event", "error"), log.String("message", err.Error())) - } - serverSpan.Finish() -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/backoffutils/backoff.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/backoffutils/backoff.go deleted file mode 100644 index 4e69a6305..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/backoffutils/backoff.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -/* -Backoff Helper Utilities - -Implements common backoff features. -*/ -package backoffutils - -import ( - "math/rand" - "time" -) - -// JitterUp adds random jitter to the duration. -// -// This adds or subtracts time from the duration within a given jitter fraction. -// For example for 10s and jitter 0.1, it will return a time within [9s, 11s]) -func JitterUp(duration time.Duration, jitter float64) time.Duration { - multiplier := jitter * (rand.Float64()*2 - 1) - return time.Duration(float64(duration) * (1 + multiplier)) -} - -// ExponentBase2 computes 2^(a-1) where a >= 1. If a is 0, the result is 0. -func ExponentBase2(a uint) uint { - return (1 << a) >> 1 -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go deleted file mode 100644 index 1ed9bb499..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -/* -Package `metautils` provides convenience functions for dealing with gRPC metadata.MD objects inside -Context handlers. - -While the upstream grpc-go package contains decent functionality (see https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md) -they are hard to use. - -The majority of functions center around the NiceMD, which is a convenience wrapper around metadata.MD. For example -the following code allows you to easily extract incoming metadata (server handler) and put it into a new client context -metadata. - - nmd := metautils.ExtractIncoming(serverCtx).Clone(":authorization", ":custom") - clientCtx := nmd.Set("x-client-header", "2").Set("x-another", "3").ToOutgoing(ctx) -*/ - -package metautils diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go deleted file mode 100644 index 15225d710..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package metautils - -import ( - "context" - "strings" - - "google.golang.org/grpc/metadata" -) - -// NiceMD is a convenience wrapper defining extra functions on the metadata. -type NiceMD metadata.MD - -// ExtractIncoming extracts an inbound metadata from the server-side context. -// -// This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns -// a new empty NiceMD. -func ExtractIncoming(ctx context.Context) NiceMD { - md, ok := metadata.FromIncomingContext(ctx) - if !ok { - return NiceMD(metadata.Pairs()) - } - return NiceMD(md) -} - -// ExtractOutgoing extracts an outbound metadata from the client-side context. -// -// This function always returns a NiceMD wrapper of the metadata.MD, in case the context doesn't have metadata it returns -// a new empty NiceMD. -func ExtractOutgoing(ctx context.Context) NiceMD { - md, ok := metadata.FromOutgoingContext(ctx) - if !ok { - return NiceMD(metadata.Pairs()) - } - return NiceMD(md) -} - -// Clone performs a *deep* copy of the metadata.MD. -// -// You can specify the lower-case copiedKeys to only copy certain allow-listed keys. If no keys are explicitly allow-listed -// all keys get copied. -func (m NiceMD) Clone(copiedKeys ...string) NiceMD { - newMd := NiceMD(metadata.Pairs()) - for k, vv := range m { - found := false - if len(copiedKeys) == 0 { - found = true - } else { - for _, allowedKey := range copiedKeys { - if strings.EqualFold(allowedKey, k) { - found = true - break - } - } - } - if !found { - continue - } - newMd[k] = make([]string, len(vv)) - copy(newMd[k], vv) - } - return newMd -} - -// ToOutgoing sets the given NiceMD as a client-side context for dispatching. -func (m NiceMD) ToOutgoing(ctx context.Context) context.Context { - return metadata.NewOutgoingContext(ctx, metadata.MD(m)) -} - -// ToIncoming sets the given NiceMD as a server-side context for dispatching. -// -// This is mostly useful in ServerInterceptors.. -func (m NiceMD) ToIncoming(ctx context.Context) context.Context { - return metadata.NewIncomingContext(ctx, metadata.MD(m)) -} - -// Get retrieves a single value from the metadata. -// -// It works analogously to http.Header.Get, returning the first value if there are many set. If the value is not set, -// an empty string is returned. -// -// The function is binary-key safe. -func (m NiceMD) Get(key string) string { - k := strings.ToLower(key) - vv, ok := m[k] - if !ok { - return "" - } - return vv[0] -} - -// Del retrieves a single value from the metadata. -// -// It works analogously to http.Header.Del, deleting all values if they exist. -// -// The function is binary-key safe. - -func (m NiceMD) Del(key string) NiceMD { - k := strings.ToLower(key) - delete(m, k) - return m -} - -// Set sets the given value in a metadata. -// -// It works analogously to http.Header.Set, overwriting all previous metadata values. -// -// The function is binary-key safe. -func (m NiceMD) Set(key string, value string) NiceMD { - k := strings.ToLower(key) - m[k] = []string{value} - return m -} - -// Add retrieves a single value from the metadata. -// -// It works analogously to http.Header.Add, as it appends to any existing values associated with key. -// -// The function is binary-key safe. -func (m NiceMD) Add(key string, value string) NiceMD { - k := strings.ToLower(key) - m[k] = append(m[k], value) - return m -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/COPYRIGHT b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/COPYRIGHT deleted file mode 100644 index 3b13627cd..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/COPYRIGHT +++ /dev/null @@ -1,2 +0,0 @@ -Copyright (c) The go-grpc-middleware Authors. -Licensed under the Apache License 2.0. diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/LICENSE b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/LICENSE deleted file mode 100644 index b2b065037..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/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. \ No newline at end of file diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/client.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/client.go deleted file mode 100644 index 86c51a079..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/client.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -// Go gRPC Middleware monitoring interceptors for client-side gRPC. - -package interceptors - -import ( - "context" - "io" - "time" - - "google.golang.org/grpc" -) - -// UnaryClientInterceptor is a gRPC client-side interceptor that provides reporting for Unary RPCs. -func UnaryClientInterceptor(reportable ClientReportable) grpc.UnaryClientInterceptor { - return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - r := newReport(Unary, method) - reporter, newCtx := reportable.ClientReporter(ctx, CallMeta{ReqProtoOrNil: req, Typ: r.rpcType, Service: r.service, Method: r.method}) - - reporter.PostMsgSend(req, nil, time.Since(r.startTime)) - err := invoker(newCtx, method, req, reply, cc, opts...) - reporter.PostMsgReceive(reply, err, time.Since(r.startTime)) - reporter.PostCall(err, time.Since(r.startTime)) - return err - } -} - -// StreamClientInterceptor is a gRPC client-side interceptor that provides reporting for Stream RPCs. -func StreamClientInterceptor(reportable ClientReportable) grpc.StreamClientInterceptor { - return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { - r := newReport(clientStreamType(desc), method) - reporter, newCtx := reportable.ClientReporter(ctx, CallMeta{ReqProtoOrNil: nil, Typ: r.rpcType, Service: r.service, Method: r.method}) - - clientStream, err := streamer(newCtx, desc, cc, method, opts...) - if err != nil { - reporter.PostCall(err, time.Since(r.startTime)) - return nil, err - } - return &monitoredClientStream{ClientStream: clientStream, startTime: r.startTime, reporter: reporter}, nil - } -} - -func clientStreamType(desc *grpc.StreamDesc) GRPCType { - if desc.ClientStreams && !desc.ServerStreams { - return ClientStream - } else if !desc.ClientStreams && desc.ServerStreams { - return ServerStream - } - return BidiStream -} - -// monitoredClientStream wraps grpc.ClientStream allowing each Sent/Recv of message to report. -type monitoredClientStream struct { - grpc.ClientStream - - startTime time.Time - reporter Reporter -} - -func (s *monitoredClientStream) SendMsg(m interface{}) error { - start := time.Now() - err := s.ClientStream.SendMsg(m) - s.reporter.PostMsgSend(m, err, time.Since(start)) - return err -} - -func (s *monitoredClientStream) RecvMsg(m interface{}) error { - start := time.Now() - err := s.ClientStream.RecvMsg(m) - s.reporter.PostMsgReceive(m, err, time.Since(start)) - - if err == nil { - return nil - } - var postErr error - if err != io.EOF { - postErr = err - } - s.reporter.PostCall(postErr, time.Since(s.startTime)) - return err -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/doc.go deleted file mode 100644 index 2608b9a4f..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/doc.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -// -/* -interceptor is an internal package used by higher level middlewares. It allows injecting custom code in various -places of the gRPC lifecycle. - -This particular package is intended for use by other middleware, metric, logging or otherwise. -This allows code to be shared between different implementations. -*/ -package interceptors diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/reporter.go deleted file mode 100644 index cc3b4f136..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/reporter.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -package interceptors - -import ( - "context" - "fmt" - "strings" - "time" - - "google.golang.org/grpc/codes" -) - -type GRPCType string - -// Timer is a helper interface to time functions. -// Useful for interceptors to record the total -// time elapsed since completion of a call. -type Timer interface { - ObserveDuration() time.Duration -} - -// zeroTimer. -type zeroTimer struct { -} - -func (zeroTimer) ObserveDuration() time.Duration { - return 0 -} - -var EmptyTimer = &zeroTimer{} - -const ( - Unary GRPCType = "unary" - ClientStream GRPCType = "client_stream" - ServerStream GRPCType = "server_stream" - BidiStream GRPCType = "bidi_stream" -) - -var ( - AllCodes = []codes.Code{ - codes.OK, codes.Canceled, codes.Unknown, codes.InvalidArgument, codes.DeadlineExceeded, codes.NotFound, - codes.AlreadyExists, codes.PermissionDenied, codes.Unauthenticated, codes.ResourceExhausted, - codes.FailedPrecondition, codes.Aborted, codes.OutOfRange, codes.Unimplemented, codes.Internal, - codes.Unavailable, codes.DataLoss, - } -) - -func SplitMethodName(fullMethod string) (string, string) { - fullMethod = strings.TrimPrefix(fullMethod, "/") // remove leading slash - if i := strings.Index(fullMethod, "/"); i >= 0 { - return fullMethod[:i], fullMethod[i+1:] - } - return "unknown", "unknown" -} - -type CallMeta struct { - ReqProtoOrNil interface{} - Typ GRPCType - Service string - Method string -} - -func (c CallMeta) FullMethod() string { - return fmt.Sprintf("/%s/%s", c.Service, c.Method) -} - -type ClientReportable interface { - ClientReporter(context.Context, CallMeta) (Reporter, context.Context) -} - -type ServerReportable interface { - ServerReporter(context.Context, CallMeta) (Reporter, context.Context) -} - -// CommonReportableFunc helper allows an easy way to implement reporter with common client and server logic. -type CommonReportableFunc func(ctx context.Context, c CallMeta, isClient bool) (Reporter, context.Context) - -func (f CommonReportableFunc) ClientReporter(ctx context.Context, c CallMeta) (Reporter, context.Context) { - return f(ctx, c, true) -} - -func (f CommonReportableFunc) ServerReporter(ctx context.Context, c CallMeta) (Reporter, context.Context) { - return f(ctx, c, false) -} - -type Reporter interface { - PostCall(err error, rpcDuration time.Duration) - PostMsgSend(reqProto interface{}, err error, sendDuration time.Duration) - PostMsgReceive(replyProto interface{}, err error, recvDuration time.Duration) -} - -var _ Reporter = NoopReporter{} - -type NoopReporter struct{} - -func (NoopReporter) PostCall(error, time.Duration) {} -func (NoopReporter) PostMsgSend(interface{}, error, time.Duration) {} -func (NoopReporter) PostMsgReceive(interface{}, error, time.Duration) {} - -type report struct { - rpcType GRPCType - service string - method string - startTime time.Time -} - -func newReport(typ GRPCType, fullMethod string) report { - r := report{ - startTime: time.Now(), - rpcType: typ, - } - r.service, r.method = SplitMethodName(fullMethod) - return r -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/server.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/server.go deleted file mode 100644 index 1fcb8e4e9..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/server.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) The go-grpc-middleware Authors. -// Licensed under the Apache License 2.0. - -// Go gRPC Middleware monitoring interceptors for server-side gRPC. - -package interceptors - -import ( - "context" - "time" - - "google.golang.org/grpc" -) - -// UnaryServerInterceptor is a gRPC server-side interceptor that provides reporting for Unary RPCs. -func UnaryServerInterceptor(reportable ServerReportable) grpc.UnaryServerInterceptor { - return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - r := newReport(Unary, info.FullMethod) - reporter, newCtx := reportable.ServerReporter(ctx, CallMeta{ReqProtoOrNil: req, Typ: r.rpcType, Service: r.service, Method: r.method}) - - reporter.PostMsgReceive(req, nil, time.Since(r.startTime)) - resp, err := handler(newCtx, req) - reporter.PostMsgSend(resp, err, time.Since(r.startTime)) - - reporter.PostCall(err, time.Since(r.startTime)) - return resp, err - } -} - -// StreamServerInterceptor is a gRPC server-side interceptor that provides reporting for Streaming RPCs. -func StreamServerInterceptor(reportable ServerReportable) grpc.StreamServerInterceptor { - return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - r := newReport(ServerStream, info.FullMethod) - reporter, newCtx := reportable.ServerReporter(ss.Context(), CallMeta{ReqProtoOrNil: nil, Typ: StreamRPCType(info), Service: r.service, Method: r.method}) - err := handler(srv, &monitoredServerStream{ServerStream: ss, newCtx: newCtx, reporter: reporter}) - reporter.PostCall(err, time.Since(r.startTime)) - return err - } -} - -func StreamRPCType(info *grpc.StreamServerInfo) GRPCType { - if info.IsClientStream && !info.IsServerStream { - return ClientStream - } else if !info.IsClientStream && info.IsServerStream { - return ServerStream - } - return BidiStream -} - -// monitoredStream wraps grpc.ServerStream allowing each Sent/Recv of message to report. -type monitoredServerStream struct { - grpc.ServerStream - - newCtx context.Context - reporter Reporter -} - -func (s *monitoredServerStream) Context() context.Context { - return s.newCtx -} - -func (s *monitoredServerStream) SendMsg(m interface{}) error { - start := time.Now() - err := s.ServerStream.SendMsg(m) - s.reporter.PostMsgSend(m, err, time.Since(start)) - return err -} - -func (s *monitoredServerStream) RecvMsg(m interface{}) error { - start := time.Now() - err := s.ServerStream.RecvMsg(m) - s.reporter.PostMsgReceive(m, err, time.Since(start)) - return err -} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go deleted file mode 100644 index 05ccfb3f2..000000000 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. -// See LICENSE for licensing terms. - -package grpc_middleware - -import ( - "context" - - "google.golang.org/grpc" -) - -// WrappedServerStream is a thin wrapper around grpc.ServerStream that allows modifying context. -type WrappedServerStream struct { - grpc.ServerStream - // WrappedContext is the wrapper's own Context. You can assign it. - WrappedContext context.Context -} - -// Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context() -func (w *WrappedServerStream) Context() context.Context { - return w.WrappedContext -} - -// WrapServerStream returns a ServerStream that has the ability to overwrite context. -func WrapServerStream(stream grpc.ServerStream) *WrappedServerStream { - if existing, ok := stream.(*WrappedServerStream); ok { - return existing - } - return &WrappedServerStream{ServerStream: stream, WrappedContext: stream.Context()} -} diff --git a/vendor/github.com/hashicorp/go-version/CHANGELOG.md b/vendor/github.com/hashicorp/go-version/CHANGELOG.md deleted file mode 100644 index 6d48174bf..000000000 --- a/vendor/github.com/hashicorp/go-version/CHANGELOG.md +++ /dev/null @@ -1,64 +0,0 @@ -# 1.7.0 (May 24, 2024) - -ENHANCEMENTS: - -- Remove `reflect` dependency ([#91](https://github.com/hashicorp/go-version/pull/91)) -- Implement the `database/sql.Scanner` and `database/sql/driver.Value` interfaces for `Version` ([#133](https://github.com/hashicorp/go-version/pull/133)) - -INTERNAL: - -- [COMPLIANCE] Add Copyright and License Headers ([#115](https://github.com/hashicorp/go-version/pull/115)) -- [COMPLIANCE] Update MPL-2.0 LICENSE ([#105](https://github.com/hashicorp/go-version/pull/105)) -- Bump actions/cache from 3.0.11 to 3.2.5 ([#116](https://github.com/hashicorp/go-version/pull/116)) -- Bump actions/checkout from 3.2.0 to 3.3.0 ([#111](https://github.com/hashicorp/go-version/pull/111)) -- Bump actions/upload-artifact from 3.1.1 to 3.1.2 ([#112](https://github.com/hashicorp/go-version/pull/112)) -- GHA Migration ([#103](https://github.com/hashicorp/go-version/pull/103)) -- github: Pin external GitHub Actions to hashes ([#107](https://github.com/hashicorp/go-version/pull/107)) -- SEC-090: Automated trusted workflow pinning (2023-04-05) ([#124](https://github.com/hashicorp/go-version/pull/124)) -- update readme ([#104](https://github.com/hashicorp/go-version/pull/104)) - -# 1.6.0 (June 28, 2022) - -FEATURES: - -- Add `Prerelease` function to `Constraint` to return true if the version includes a prerelease field ([#100](https://github.com/hashicorp/go-version/pull/100)) - -# 1.5.0 (May 18, 2022) - -FEATURES: - -- Use `encoding` `TextMarshaler` & `TextUnmarshaler` instead of JSON equivalents ([#95](https://github.com/hashicorp/go-version/pull/95)) -- Add JSON handlers to allow parsing from/to JSON ([#93](https://github.com/hashicorp/go-version/pull/93)) - -# 1.4.0 (January 5, 2022) - -FEATURES: - - - Introduce `MustConstraints()` ([#87](https://github.com/hashicorp/go-version/pull/87)) - - `Constraints`: Introduce `Equals()` and `sort.Interface` methods ([#88](https://github.com/hashicorp/go-version/pull/88)) - -# 1.3.0 (March 31, 2021) - -Please note that CHANGELOG.md does not exist in the source code prior to this release. - -FEATURES: - - Add `Core` function to return a version without prerelease or metadata ([#85](https://github.com/hashicorp/go-version/pull/85)) - -# 1.2.1 (June 17, 2020) - -BUG FIXES: - - Prevent `Version.Equal` method from panicking on `nil` encounter ([#73](https://github.com/hashicorp/go-version/pull/73)) - -# 1.2.0 (April 23, 2019) - -FEATURES: - - Add `GreaterThanOrEqual` and `LessThanOrEqual` helper methods ([#53](https://github.com/hashicorp/go-version/pull/53)) - -# 1.1.0 (Jan 07, 2019) - -FEATURES: - - Add `NewSemver` constructor ([#45](https://github.com/hashicorp/go-version/pull/45)) - -# 1.0.0 (August 24, 2018) - -Initial release. diff --git a/vendor/github.com/hashicorp/go-version/LICENSE b/vendor/github.com/hashicorp/go-version/LICENSE deleted file mode 100644 index 1409d6ab9..000000000 --- a/vendor/github.com/hashicorp/go-version/LICENSE +++ /dev/null @@ -1,356 +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/go-version/README.md b/vendor/github.com/hashicorp/go-version/README.md deleted file mode 100644 index 4b7806cd9..000000000 --- a/vendor/github.com/hashicorp/go-version/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Versioning Library for Go -![Build Status](https://github.com/hashicorp/go-version/actions/workflows/go-tests.yml/badge.svg) -[![GoDoc](https://godoc.org/github.com/hashicorp/go-version?status.svg)](https://godoc.org/github.com/hashicorp/go-version) - -go-version is a library for parsing versions and version constraints, -and verifying versions against a set of constraints. go-version -can sort a collection of versions properly, handles prerelease/beta -versions, can increment versions, etc. - -Versions used with go-version must follow [SemVer](http://semver.org/). - -## Installation and Usage - -Package documentation can be found on -[GoDoc](http://godoc.org/github.com/hashicorp/go-version). - -Installation can be done with a normal `go get`: - -``` -$ go get github.com/hashicorp/go-version -``` - -#### Version Parsing and Comparison - -```go -v1, err := version.NewVersion("1.2") -v2, err := version.NewVersion("1.5+metadata") - -// Comparison example. There is also GreaterThan, Equal, and just -// a simple Compare that returns an int allowing easy >=, <=, etc. -if v1.LessThan(v2) { - fmt.Printf("%s is less than %s", v1, v2) -} -``` - -#### Version Constraints - -```go -v1, err := version.NewVersion("1.2") - -// Constraints example. -constraints, err := version.NewConstraint(">= 1.0, < 1.4") -if constraints.Check(v1) { - fmt.Printf("%s satisfies constraints %s", v1, constraints) -} -``` - -#### Version Sorting - -```go -versionsRaw := []string{"1.1", "0.7.1", "1.4-beta", "1.4", "2"} -versions := make([]*version.Version, len(versionsRaw)) -for i, raw := range versionsRaw { - v, _ := version.NewVersion(raw) - versions[i] = v -} - -// After this, the versions are properly sorted -sort.Sort(version.Collection(versions)) -``` - -## Issues and Contributing - -If you find an issue with this library, please report an issue. If you'd -like, we welcome any contributions. Fork this library and submit a pull -request. diff --git a/vendor/github.com/hashicorp/go-version/constraint.go b/vendor/github.com/hashicorp/go-version/constraint.go deleted file mode 100644 index 29bdc4d2b..000000000 --- a/vendor/github.com/hashicorp/go-version/constraint.go +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package version - -import ( - "fmt" - "regexp" - "sort" - "strings" -) - -// Constraint represents a single constraint for a version, such as -// ">= 1.0". -type Constraint struct { - f constraintFunc - op operator - check *Version - original string -} - -func (c *Constraint) Equals(con *Constraint) bool { - return c.op == con.op && c.check.Equal(con.check) -} - -// Constraints is a slice of constraints. We make a custom type so that -// we can add methods to it. -type Constraints []*Constraint - -type constraintFunc func(v, c *Version) bool - -var constraintOperators map[string]constraintOperation - -type constraintOperation struct { - op operator - f constraintFunc -} - -var constraintRegexp *regexp.Regexp - -func init() { - constraintOperators = map[string]constraintOperation{ - "": {op: equal, f: constraintEqual}, - "=": {op: equal, f: constraintEqual}, - "!=": {op: notEqual, f: constraintNotEqual}, - ">": {op: greaterThan, f: constraintGreaterThan}, - "<": {op: lessThan, f: constraintLessThan}, - ">=": {op: greaterThanEqual, f: constraintGreaterThanEqual}, - "<=": {op: lessThanEqual, f: constraintLessThanEqual}, - "~>": {op: pessimistic, f: constraintPessimistic}, - } - - ops := make([]string, 0, len(constraintOperators)) - for k := range constraintOperators { - ops = append(ops, regexp.QuoteMeta(k)) - } - - constraintRegexp = regexp.MustCompile(fmt.Sprintf( - `^\s*(%s)\s*(%s)\s*$`, - strings.Join(ops, "|"), - VersionRegexpRaw)) -} - -// NewConstraint will parse one or more constraints from the given -// constraint string. The string must be a comma-separated list of -// constraints. -func NewConstraint(v string) (Constraints, error) { - vs := strings.Split(v, ",") - result := make([]*Constraint, len(vs)) - for i, single := range vs { - c, err := parseSingle(single) - if err != nil { - return nil, err - } - - result[i] = c - } - - return Constraints(result), nil -} - -// MustConstraints is a helper that wraps a call to a function -// returning (Constraints, error) and panics if error is non-nil. -func MustConstraints(c Constraints, err error) Constraints { - if err != nil { - panic(err) - } - - return c -} - -// Check tests if a version satisfies all the constraints. -func (cs Constraints) Check(v *Version) bool { - for _, c := range cs { - if !c.Check(v) { - return false - } - } - - return true -} - -// Equals compares Constraints with other Constraints -// for equality. This may not represent logical equivalence -// of compared constraints. -// e.g. even though '>0.1,>0.2' is logically equivalent -// to '>0.2' it is *NOT* treated as equal. -// -// Missing operator is treated as equal to '=', whitespaces -// are ignored and constraints are sorted before comaparison. -func (cs Constraints) Equals(c Constraints) bool { - if len(cs) != len(c) { - return false - } - - // make copies to retain order of the original slices - left := make(Constraints, len(cs)) - copy(left, cs) - sort.Stable(left) - right := make(Constraints, len(c)) - copy(right, c) - sort.Stable(right) - - // compare sorted slices - for i, con := range left { - if !con.Equals(right[i]) { - return false - } - } - - return true -} - -func (cs Constraints) Len() int { - return len(cs) -} - -func (cs Constraints) Less(i, j int) bool { - if cs[i].op < cs[j].op { - return true - } - if cs[i].op > cs[j].op { - return false - } - - return cs[i].check.LessThan(cs[j].check) -} - -func (cs Constraints) Swap(i, j int) { - cs[i], cs[j] = cs[j], cs[i] -} - -// Returns the string format of the constraints -func (cs Constraints) String() string { - csStr := make([]string, len(cs)) - for i, c := range cs { - csStr[i] = c.String() - } - - return strings.Join(csStr, ",") -} - -// Check tests if a constraint is validated by the given version. -func (c *Constraint) Check(v *Version) bool { - return c.f(v, c.check) -} - -// Prerelease returns true if the version underlying this constraint -// contains a prerelease field. -func (c *Constraint) Prerelease() bool { - return len(c.check.Prerelease()) > 0 -} - -func (c *Constraint) String() string { - return c.original -} - -func parseSingle(v string) (*Constraint, error) { - matches := constraintRegexp.FindStringSubmatch(v) - if matches == nil { - return nil, fmt.Errorf("Malformed constraint: %s", v) - } - - check, err := NewVersion(matches[2]) - if err != nil { - return nil, err - } - - cop := constraintOperators[matches[1]] - - return &Constraint{ - f: cop.f, - op: cop.op, - check: check, - original: v, - }, nil -} - -func prereleaseCheck(v, c *Version) bool { - switch vPre, cPre := v.Prerelease() != "", c.Prerelease() != ""; { - case cPre && vPre: - // A constraint with a pre-release can only match a pre-release version - // with the same base segments. - return v.equalSegments(c) - - case !cPre && vPre: - // A constraint without a pre-release can only match a version without a - // pre-release. - return false - - case cPre && !vPre: - // OK, except with the pessimistic operator - case !cPre && !vPre: - // OK - } - return true -} - -//------------------------------------------------------------------- -// Constraint functions -//------------------------------------------------------------------- - -type operator rune - -const ( - equal operator = '=' - notEqual operator = '≠' - greaterThan operator = '>' - lessThan operator = '<' - greaterThanEqual operator = '≥' - lessThanEqual operator = '≤' - pessimistic operator = '~' -) - -func constraintEqual(v, c *Version) bool { - return v.Equal(c) -} - -func constraintNotEqual(v, c *Version) bool { - return !v.Equal(c) -} - -func constraintGreaterThan(v, c *Version) bool { - return prereleaseCheck(v, c) && v.Compare(c) == 1 -} - -func constraintLessThan(v, c *Version) bool { - return prereleaseCheck(v, c) && v.Compare(c) == -1 -} - -func constraintGreaterThanEqual(v, c *Version) bool { - return prereleaseCheck(v, c) && v.Compare(c) >= 0 -} - -func constraintLessThanEqual(v, c *Version) bool { - return prereleaseCheck(v, c) && v.Compare(c) <= 0 -} - -func constraintPessimistic(v, c *Version) bool { - // Using a pessimistic constraint with a pre-release, restricts versions to pre-releases - if !prereleaseCheck(v, c) || (c.Prerelease() != "" && v.Prerelease() == "") { - return false - } - - // If the version being checked is naturally less than the constraint, then there - // is no way for the version to be valid against the constraint - if v.LessThan(c) { - return false - } - // We'll use this more than once, so grab the length now so it's a little cleaner - // to write the later checks - cs := len(c.segments) - - // If the version being checked has less specificity than the constraint, then there - // is no way for the version to be valid against the constraint - if cs > len(v.segments) { - return false - } - - // Check the segments in the constraint against those in the version. If the version - // being checked, at any point, does not have the same values in each index of the - // constraints segments, then it cannot be valid against the constraint. - for i := 0; i < c.si-1; i++ { - if v.segments[i] != c.segments[i] { - return false - } - } - - // Check the last part of the segment in the constraint. If the version segment at - // this index is less than the constraints segment at this index, then it cannot - // be valid against the constraint - if c.segments[cs-1] > v.segments[cs-1] { - return false - } - - // If nothing has rejected the version by now, it's valid - return true -} diff --git a/vendor/github.com/hashicorp/go-version/version.go b/vendor/github.com/hashicorp/go-version/version.go deleted file mode 100644 index 7c683c281..000000000 --- a/vendor/github.com/hashicorp/go-version/version.go +++ /dev/null @@ -1,441 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package version - -import ( - "bytes" - "database/sql/driver" - "fmt" - "regexp" - "strconv" - "strings" -) - -// The compiled regular expression used to test the validity of a version. -var ( - versionRegexp *regexp.Regexp - semverRegexp *regexp.Regexp -) - -// The raw regular expression string used for testing the validity -// of a version. -const ( - VersionRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` + - `(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-?([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` + - `(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` + - `?` - - // SemverRegexpRaw requires a separator between version and prerelease - SemverRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` + - `(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` + - `(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` + - `?` -) - -// Version represents a single version. -type Version struct { - metadata string - pre string - segments []int64 - si int - original string -} - -func init() { - versionRegexp = regexp.MustCompile("^" + VersionRegexpRaw + "$") - semverRegexp = regexp.MustCompile("^" + SemverRegexpRaw + "$") -} - -// NewVersion parses the given version and returns a new -// Version. -func NewVersion(v string) (*Version, error) { - return newVersion(v, versionRegexp) -} - -// NewSemver parses the given version and returns a new -// Version that adheres strictly to SemVer specs -// https://semver.org/ -func NewSemver(v string) (*Version, error) { - return newVersion(v, semverRegexp) -} - -func newVersion(v string, pattern *regexp.Regexp) (*Version, error) { - matches := pattern.FindStringSubmatch(v) - if matches == nil { - return nil, fmt.Errorf("Malformed version: %s", v) - } - segmentsStr := strings.Split(matches[1], ".") - segments := make([]int64, len(segmentsStr)) - for i, str := range segmentsStr { - val, err := strconv.ParseInt(str, 10, 64) - if err != nil { - return nil, fmt.Errorf( - "Error parsing version: %s", err) - } - - segments[i] = val - } - - // Even though we could support more than three segments, if we - // got less than three, pad it with 0s. This is to cover the basic - // default usecase of semver, which is MAJOR.MINOR.PATCH at the minimum - for i := len(segments); i < 3; i++ { - segments = append(segments, 0) - } - - pre := matches[7] - if pre == "" { - pre = matches[4] - } - - return &Version{ - metadata: matches[10], - pre: pre, - segments: segments, - si: len(segmentsStr), - original: v, - }, nil -} - -// Must is a helper that wraps a call to a function returning (*Version, error) -// and panics if error is non-nil. -func Must(v *Version, err error) *Version { - if err != nil { - panic(err) - } - - return v -} - -// Compare compares this version to another version. This -// returns -1, 0, or 1 if this version is smaller, equal, -// or larger than the other version, respectively. -// -// If you want boolean results, use the LessThan, Equal, -// GreaterThan, GreaterThanOrEqual or LessThanOrEqual methods. -func (v *Version) Compare(other *Version) int { - // A quick, efficient equality check - if v.String() == other.String() { - return 0 - } - - // If the segments are the same, we must compare on prerelease info - if v.equalSegments(other) { - preSelf := v.Prerelease() - preOther := other.Prerelease() - if preSelf == "" && preOther == "" { - return 0 - } - if preSelf == "" { - return 1 - } - if preOther == "" { - return -1 - } - - return comparePrereleases(preSelf, preOther) - } - - segmentsSelf := v.Segments64() - segmentsOther := other.Segments64() - // Get the highest specificity (hS), or if they're equal, just use segmentSelf length - lenSelf := len(segmentsSelf) - lenOther := len(segmentsOther) - hS := lenSelf - if lenSelf < lenOther { - hS = lenOther - } - // Compare the segments - // Because a constraint could have more/less specificity than the version it's - // checking, we need to account for a lopsided or jagged comparison - for i := 0; i < hS; i++ { - if i > lenSelf-1 { - // This means Self had the lower specificity - // Check to see if the remaining segments in Other are all zeros - if !allZero(segmentsOther[i:]) { - // if not, it means that Other has to be greater than Self - return -1 - } - break - } else if i > lenOther-1 { - // this means Other had the lower specificity - // Check to see if the remaining segments in Self are all zeros - - if !allZero(segmentsSelf[i:]) { - // if not, it means that Self has to be greater than Other - return 1 - } - break - } - lhs := segmentsSelf[i] - rhs := segmentsOther[i] - if lhs == rhs { - continue - } else if lhs < rhs { - return -1 - } - // Otherwis, rhs was > lhs, they're not equal - return 1 - } - - // if we got this far, they're equal - return 0 -} - -func (v *Version) equalSegments(other *Version) bool { - segmentsSelf := v.Segments64() - segmentsOther := other.Segments64() - - if len(segmentsSelf) != len(segmentsOther) { - return false - } - for i, v := range segmentsSelf { - if v != segmentsOther[i] { - return false - } - } - return true -} - -func allZero(segs []int64) bool { - for _, s := range segs { - if s != 0 { - return false - } - } - return true -} - -func comparePart(preSelf string, preOther string) int { - if preSelf == preOther { - return 0 - } - - var selfInt int64 - selfNumeric := true - selfInt, err := strconv.ParseInt(preSelf, 10, 64) - if err != nil { - selfNumeric = false - } - - var otherInt int64 - otherNumeric := true - otherInt, err = strconv.ParseInt(preOther, 10, 64) - if err != nil { - otherNumeric = false - } - - // if a part is empty, we use the other to decide - if preSelf == "" { - if otherNumeric { - return -1 - } - return 1 - } - - if preOther == "" { - if selfNumeric { - return 1 - } - return -1 - } - - if selfNumeric && !otherNumeric { - return -1 - } else if !selfNumeric && otherNumeric { - return 1 - } else if !selfNumeric && !otherNumeric && preSelf > preOther { - return 1 - } else if selfInt > otherInt { - return 1 - } - - return -1 -} - -func comparePrereleases(v string, other string) int { - // the same pre release! - if v == other { - return 0 - } - - // split both pre releases for analyse their parts - selfPreReleaseMeta := strings.Split(v, ".") - otherPreReleaseMeta := strings.Split(other, ".") - - selfPreReleaseLen := len(selfPreReleaseMeta) - otherPreReleaseLen := len(otherPreReleaseMeta) - - biggestLen := otherPreReleaseLen - if selfPreReleaseLen > otherPreReleaseLen { - biggestLen = selfPreReleaseLen - } - - // loop for parts to find the first difference - for i := 0; i < biggestLen; i = i + 1 { - partSelfPre := "" - if i < selfPreReleaseLen { - partSelfPre = selfPreReleaseMeta[i] - } - - partOtherPre := "" - if i < otherPreReleaseLen { - partOtherPre = otherPreReleaseMeta[i] - } - - compare := comparePart(partSelfPre, partOtherPre) - // if parts are equals, continue the loop - if compare != 0 { - return compare - } - } - - return 0 -} - -// Core returns a new version constructed from only the MAJOR.MINOR.PATCH -// segments of the version, without prerelease or metadata. -func (v *Version) Core() *Version { - segments := v.Segments64() - segmentsOnly := fmt.Sprintf("%d.%d.%d", segments[0], segments[1], segments[2]) - return Must(NewVersion(segmentsOnly)) -} - -// Equal tests if two versions are equal. -func (v *Version) Equal(o *Version) bool { - if v == nil || o == nil { - return v == o - } - - return v.Compare(o) == 0 -} - -// GreaterThan tests if this version is greater than another version. -func (v *Version) GreaterThan(o *Version) bool { - return v.Compare(o) > 0 -} - -// GreaterThanOrEqual tests if this version is greater than or equal to another version. -func (v *Version) GreaterThanOrEqual(o *Version) bool { - return v.Compare(o) >= 0 -} - -// LessThan tests if this version is less than another version. -func (v *Version) LessThan(o *Version) bool { - return v.Compare(o) < 0 -} - -// LessThanOrEqual tests if this version is less than or equal to another version. -func (v *Version) LessThanOrEqual(o *Version) bool { - return v.Compare(o) <= 0 -} - -// Metadata returns any metadata that was part of the version -// string. -// -// Metadata is anything that comes after the "+" in the version. -// For example, with "1.2.3+beta", the metadata is "beta". -func (v *Version) Metadata() string { - return v.metadata -} - -// Prerelease returns any prerelease data that is part of the version, -// or blank if there is no prerelease data. -// -// Prerelease information is anything that comes after the "-" in the -// version (but before any metadata). For example, with "1.2.3-beta", -// the prerelease information is "beta". -func (v *Version) Prerelease() string { - return v.pre -} - -// Segments returns the numeric segments of the version as a slice of ints. -// -// This excludes any metadata or pre-release information. For example, -// for a version "1.2.3-beta", segments will return a slice of -// 1, 2, 3. -func (v *Version) Segments() []int { - segmentSlice := make([]int, len(v.segments)) - for i, v := range v.segments { - segmentSlice[i] = int(v) - } - return segmentSlice -} - -// Segments64 returns the numeric segments of the version as a slice of int64s. -// -// This excludes any metadata or pre-release information. For example, -// for a version "1.2.3-beta", segments will return a slice of -// 1, 2, 3. -func (v *Version) Segments64() []int64 { - result := make([]int64, len(v.segments)) - copy(result, v.segments) - return result -} - -// String returns the full version string included pre-release -// and metadata information. -// -// This value is rebuilt according to the parsed segments and other -// information. Therefore, ambiguities in the version string such as -// prefixed zeroes (1.04.0 => 1.4.0), `v` prefix (v1.0.0 => 1.0.0), and -// missing parts (1.0 => 1.0.0) will be made into a canonicalized form -// as shown in the parenthesized examples. -func (v *Version) String() string { - var buf bytes.Buffer - fmtParts := make([]string, len(v.segments)) - for i, s := range v.segments { - // We can ignore err here since we've pre-parsed the values in segments - str := strconv.FormatInt(s, 10) - fmtParts[i] = str - } - fmt.Fprintf(&buf, strings.Join(fmtParts, ".")) - 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 parsed version as-is, including any -// potential whitespace, `v` prefix, etc. -func (v *Version) Original() string { - return v.original -} - -// UnmarshalText implements encoding.TextUnmarshaler interface. -func (v *Version) UnmarshalText(b []byte) error { - temp, err := NewVersion(string(b)) - if err != nil { - return err - } - - *v = *temp - - return nil -} - -// MarshalText implements encoding.TextMarshaler interface. -func (v *Version) MarshalText() ([]byte, error) { - return []byte(v.String()), nil -} - -// Scan implements the sql.Scanner interface. -func (v *Version) Scan(src interface{}) error { - switch src := src.(type) { - case string: - return v.UnmarshalText([]byte(src)) - case nil: - return nil - default: - return fmt.Errorf("cannot scan %T as Version", src) - } -} - -// Value implements the driver.Valuer interface. -func (v *Version) Value() (driver.Value, error) { - return v.String(), nil -} diff --git a/vendor/github.com/hashicorp/go-version/version_collection.go b/vendor/github.com/hashicorp/go-version/version_collection.go deleted file mode 100644 index 83547fe13..000000000 --- a/vendor/github.com/hashicorp/go-version/version_collection.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package version - -// Collection is a type that implements the sort.Interface interface -// so that versions can be sorted. -type Collection []*Version - -func (v Collection) Len() int { - return len(v) -} - -func (v Collection) Less(i, j int) bool { - return v[i].LessThan(v[j]) -} - -func (v Collection) Swap(i, j int) { - v[i], v[j] = v[j], v[i] -} diff --git a/vendor/github.com/hashicorp/hcl/.gitignore b/vendor/github.com/hashicorp/hcl/.gitignore deleted file mode 100644 index 15586a2b5..000000000 --- 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 cb63a3216..000000000 --- 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 c33dcc7c9..000000000 --- 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 84fd743f5..000000000 --- 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 c8223326d..000000000 --- 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 bed9ebbe1..000000000 --- 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 575a20b50..000000000 --- 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 6e5ef654b..000000000 --- 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 ba07ad42b..000000000 --- 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 5c99381df..000000000 --- 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 64c83bcfb..000000000 --- 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 7c038d12a..000000000 --- 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 6617ab8e7..000000000 --- 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 624a18fe3..000000000 --- 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 5f981eaa2..000000000 --- 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 59c1bb72d..000000000 --- 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 e37c0664e..000000000 --- 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 125a5f072..000000000 --- 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 fe3f0f095..000000000 --- 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 59c1bb72d..000000000 --- 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 95a0c3eee..000000000 --- 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 d9993c292..000000000 --- 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 1fca53c4c..000000000 --- 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/hexops/gotextdiff/LICENSE b/vendor/github.com/hexops/gotextdiff/LICENSE deleted file mode 100644 index 6a66aea5e..000000000 --- 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 bfd49a0c9..000000000 --- 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 53e499bc0..000000000 --- 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 5e3e92364..000000000 --- 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 aa17c84ec..000000000 --- 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 4d2ad0986..000000000 --- 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 6f8b9b570..000000000 --- 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 bf7a5406b..000000000 --- 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 017aec9c1..000000000 --- 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 250492135..000000000 --- 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 f06a2468b..000000000 --- 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 b7d85cfcc..000000000 --- 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 5f920e973..000000000 --- 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 7a950d177..000000000 --- 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 06a91f086..000000000 --- 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 0c5688021..000000000 --- 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/LICENSE b/vendor/github.com/jgautheron/goconst/LICENSE deleted file mode 100644 index e92649543..000000000 --- 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 c671eb541..000000000 --- a/vendor/github.com/jgautheron/goconst/README.md +++ /dev/null @@ -1,51 +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 get github.com/jgautheron/goconst/cmd/goconst - $ 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 values - -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 - -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 . -``` - -### 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 b838e035f..000000000 --- a/vendor/github.com/jgautheron/goconst/api.go +++ /dev/null @@ -1,76 +0,0 @@ -package goconst - -import ( - "go/ast" - "go/token" - "strings" -) - -type Issue struct { - Pos token.Position - OccurrencesCount int - Str string - MatchingConst string -} - -type Config struct { - IgnoreStrings string - IgnoreTests bool - MatchWithConstants bool - MinStringLength int - MinOccurrences int - ParseNumbers bool - NumberMin int - NumberMax int - ExcludeTypes map[Type]bool -} - -func Run(files []*ast.File, fset *token.FileSet, cfg *Config) ([]Issue, error) { - p := New( - "", - "", - cfg.IgnoreStrings, - cfg.IgnoreTests, - cfg.MatchWithConstants, - cfg.ParseNumbers, - cfg.NumberMin, - cfg.NumberMax, - cfg.MinStringLength, - cfg.MinOccurrences, - cfg.ExcludeTypes, - ) - var issues []Issue - for _, f := range files { - if p.ignoreTests { - if filename := fset.Position(f.Pos()).Filename; strings.HasSuffix(filename, testSuffix) { - continue - } - } - ast.Walk(&treeVisitor{ - fileSet: fset, - packageName: "", - fileName: "", - p: p, - }, f) - } - p.ProcessResults() - - for str, item := range p.strs { - fi := item[0] - i := Issue{ - Pos: fi.Position, - OccurrencesCount: len(item), - Str: str, - } - - if len(p.consts) != 0 { - if cst, ok := p.consts[str]; ok { - // const should be in the same package and exported - i.MatchingConst = cst.Name - } - } - issues = append(issues, i) - } - - return issues, nil -} diff --git a/vendor/github.com/jgautheron/goconst/parser.go b/vendor/github.com/jgautheron/goconst/parser.go deleted file mode 100644 index 2f32740b9..000000000 --- a/vendor/github.com/jgautheron/goconst/parser.go +++ /dev/null @@ -1,187 +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/parser" - "go/token" - "log" - "os" - "path/filepath" - "regexp" - "strconv" - "strings" -) - -const ( - testSuffix = "_test.go" -) - -type Parser struct { - // Meant to be passed via New() - path, ignore, ignoreStrings string - ignoreTests, matchConstant bool - minLength, minOccurrences int - numberMin, numberMax int - excludeTypes map[Type]bool - - supportedTokens []token.Token - - // Internals - strs Strings - consts Constants -} - -// New creates a new instance of the parser. -// This is your entry point if you'd like to use goconst as an API. -func New(path, ignore, ignoreStrings string, ignoreTests, matchConstant, numbers bool, numberMin, numberMax, minLength, minOccurrences int, excludeTypes map[Type]bool) *Parser { - supportedTokens := []token.Token{token.STRING} - if numbers { - supportedTokens = append(supportedTokens, token.INT, token.FLOAT) - } - - return &Parser{ - path: path, - ignore: ignore, - ignoreStrings: ignoreStrings, - ignoreTests: ignoreTests, - matchConstant: matchConstant, - minLength: minLength, - minOccurrences: minOccurrences, - numberMin: numberMin, - numberMax: numberMax, - supportedTokens: supportedTokens, - excludeTypes: excludeTypes, - - // Initialize the maps - strs: Strings{}, - consts: Constants{}, - } -} - -// ParseTree will search the given path for occurrences that could be moved into constants. -// If "..." is appended, the search will be recursive. -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:] == "..." { - filepath.Walk(p.path[:pathLen-3], func(path string, f os.FileInfo, err error) error { - if err != nil { - log.Println(err) - // resume walking - return nil - } - - if f.IsDir() { - p.parseDir(path) - } - return nil - }) - } else { - p.parseDir(p.path) - } - - p.ProcessResults() - - return p.strs, p.consts, nil -} - -// ProcessResults post-processes the raw results. -func (p *Parser) ProcessResults() { - for str, item := range p.strs { - // Filter out items whose occurrences don't match the min value - if len(item) < p.minOccurrences { - delete(p.strs, str) - } - - if p.ignoreStrings != "" { - match, err := regexp.MatchString(p.ignoreStrings, str) - if err != nil { - log.Println(err) - } - if match { - delete(p.strs, str) - } - } - - // If the value is a number - if i, err := strconv.ParseInt(str, 0, 0); err == nil { - if p.numberMin != 0 && i < int64(p.numberMin) { - delete(p.strs, str) - } - if p.numberMax != 0 && i > int64(p.numberMax) { - delete(p.strs, str) - } - } - } -} - -func (p *Parser) parseDir(dir string) error { - fset := token.NewFileSet() - pkgs, err := parser.ParseDir(fset, dir, func(info os.FileInfo) bool { - valid, name := true, info.Name() - - if p.ignoreTests { - if strings.HasSuffix(name, testSuffix) { - valid = false - } - } - - if len(p.ignore) != 0 { - match, err := regexp.MatchString(p.ignore, dir+name) - if err != nil { - log.Fatal(err) - return true - } - if match { - valid = false - } - } - - return valid - }, 0) - if err != nil { - return err - } - - for _, pkg := range pkgs { - for fn, f := range pkg.Files { - ast.Walk(&treeVisitor{ - fileSet: fset, - packageName: pkg.Name, - fileName: fn, - p: p, - }, f) - } - } - - return nil -} - -type Strings map[string][]ExtendedPos -type Constants map[string]ConstType - -type ConstType struct { - token.Position - Name, packageName string -} - -type ExtendedPos struct { - token.Position - packageName string -} - -type Type int - -const ( - Assignment Type = iota - Binary - Case - Return - Call -) diff --git a/vendor/github.com/jgautheron/goconst/visitor.go b/vendor/github.com/jgautheron/goconst/visitor.go deleted file mode 100644 index c0974da8f..000000000 --- a/vendor/github.com/jgautheron/goconst/visitor.go +++ /dev/null @@ -1,160 +0,0 @@ -package goconst - -import ( - "go/ast" - "go/token" - "strconv" - "strings" -) - -// treeVisitor carries the package name and file name -// for passing it to the imports map, and the fileSet for -// retrieving the token.Position. -type treeVisitor struct { - p *Parser - fileSet *token.FileSet - packageName, fileName string -} - -// 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 { - return v - } - if t.Tok != token.CONST { - return v - } - - for _, spec := range t.Specs { - val := spec.(*ast.ValueSpec) - for i, str := range val.Values { - 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) { - ok, excluded := v.p.excludeTypes[typ] - if ok && excluded { - return - } - // Drop quotes if any - if strings.HasPrefix(str, `"`) || strings.HasPrefix(str, "`") { - str, _ = strconv.Unquote(str) - } - - // Ignore empty strings - if len(str) == 0 { - return - } - - if len(str) < v.p.minLength { - return - } - - _, ok = v.p.strs[str] - if !ok { - v.p.strs[str] = make([]ExtendedPos, 0) - } - v.p.strs[str] = append(v.p.strs[str], ExtendedPos{ - packageName: v.packageName, - Position: v.fileSet.Position(pos), - }) -} - -// 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) { - val = strings.Replace(val, `"`, "", 2) - v.p.consts[val] = ConstType{ - Name: name, - packageName: v.packageName, - 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 -} diff --git a/vendor/github.com/jingyugao/rowserrcheck/LICENSE b/vendor/github.com/jingyugao/rowserrcheck/LICENSE deleted file mode 100644 index 6957f1889..000000000 --- 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 a142a6744..000000000 --- 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/jinzhu/inflection/LICENSE b/vendor/github.com/jinzhu/inflection/LICENSE deleted file mode 100644 index a1ca9a0ff..000000000 --- a/vendor/github.com/jinzhu/inflection/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 - Jinzhu - -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/jinzhu/inflection/README.md b/vendor/github.com/jinzhu/inflection/README.md deleted file mode 100644 index a3de33614..000000000 --- a/vendor/github.com/jinzhu/inflection/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Inflection - -Inflection pluralizes and singularizes English nouns - -[![wercker status](https://app.wercker.com/status/f8c7432b097d1f4ce636879670be0930/s/master "wercker status")](https://app.wercker.com/project/byKey/f8c7432b097d1f4ce636879670be0930) - -## Basic Usage - -```go -inflection.Plural("person") => "people" -inflection.Plural("Person") => "People" -inflection.Plural("PERSON") => "PEOPLE" -inflection.Plural("bus") => "buses" -inflection.Plural("BUS") => "BUSES" -inflection.Plural("Bus") => "Buses" - -inflection.Singular("people") => "person" -inflection.Singular("People") => "Person" -inflection.Singular("PEOPLE") => "PERSON" -inflection.Singular("buses") => "bus" -inflection.Singular("BUSES") => "BUS" -inflection.Singular("Buses") => "Bus" - -inflection.Plural("FancyPerson") => "FancyPeople" -inflection.Singular("FancyPeople") => "FancyPerson" -``` - -## Register Rules - -Standard rules are from Rails's ActiveSupport (https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflections.rb) - -If you want to register more rules, follow: - -``` -inflection.AddUncountable("fish") -inflection.AddIrregular("person", "people") -inflection.AddPlural("(bu)s$", "${1}ses") # "bus" => "buses" / "BUS" => "BUSES" / "Bus" => "Buses" -inflection.AddSingular("(bus)(es)?$", "${1}") # "buses" => "bus" / "Buses" => "Bus" / "BUSES" => "BUS" -``` - -## Contributing - -You can help to make the project better, check out [http://gorm.io/contribute.html](http://gorm.io/contribute.html) for things you can do. - -## Author - -**jinzhu** - -* -* -* - -## License - -Released under the [MIT License](http://www.opensource.org/licenses/MIT). diff --git a/vendor/github.com/jinzhu/inflection/inflections.go b/vendor/github.com/jinzhu/inflection/inflections.go deleted file mode 100644 index 606263bb7..000000000 --- a/vendor/github.com/jinzhu/inflection/inflections.go +++ /dev/null @@ -1,273 +0,0 @@ -/* -Package inflection pluralizes and singularizes English nouns. - - inflection.Plural("person") => "people" - inflection.Plural("Person") => "People" - inflection.Plural("PERSON") => "PEOPLE" - - inflection.Singular("people") => "person" - inflection.Singular("People") => "Person" - inflection.Singular("PEOPLE") => "PERSON" - - inflection.Plural("FancyPerson") => "FancydPeople" - inflection.Singular("FancyPeople") => "FancydPerson" - -Standard rules are from Rails's ActiveSupport (https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflections.rb) - -If you want to register more rules, follow: - - inflection.AddUncountable("fish") - inflection.AddIrregular("person", "people") - inflection.AddPlural("(bu)s$", "${1}ses") # "bus" => "buses" / "BUS" => "BUSES" / "Bus" => "Buses" - inflection.AddSingular("(bus)(es)?$", "${1}") # "buses" => "bus" / "Buses" => "Bus" / "BUSES" => "BUS" -*/ -package inflection - -import ( - "regexp" - "strings" -) - -type inflection struct { - regexp *regexp.Regexp - replace string -} - -// Regular is a regexp find replace inflection -type Regular struct { - find string - replace string -} - -// Irregular is a hard replace inflection, -// containing both singular and plural forms -type Irregular struct { - singular string - plural string -} - -// RegularSlice is a slice of Regular inflections -type RegularSlice []Regular - -// IrregularSlice is a slice of Irregular inflections -type IrregularSlice []Irregular - -var pluralInflections = RegularSlice{ - {"([a-z])$", "${1}s"}, - {"s$", "s"}, - {"^(ax|test)is$", "${1}es"}, - {"(octop|vir)us$", "${1}i"}, - {"(octop|vir)i$", "${1}i"}, - {"(alias|status)$", "${1}es"}, - {"(bu)s$", "${1}ses"}, - {"(buffal|tomat)o$", "${1}oes"}, - {"([ti])um$", "${1}a"}, - {"([ti])a$", "${1}a"}, - {"sis$", "ses"}, - {"(?:([^f])fe|([lr])f)$", "${1}${2}ves"}, - {"(hive)$", "${1}s"}, - {"([^aeiouy]|qu)y$", "${1}ies"}, - {"(x|ch|ss|sh)$", "${1}es"}, - {"(matr|vert|ind)(?:ix|ex)$", "${1}ices"}, - {"^(m|l)ouse$", "${1}ice"}, - {"^(m|l)ice$", "${1}ice"}, - {"^(ox)$", "${1}en"}, - {"^(oxen)$", "${1}"}, - {"(quiz)$", "${1}zes"}, -} - -var singularInflections = RegularSlice{ - {"s$", ""}, - {"(ss)$", "${1}"}, - {"(n)ews$", "${1}ews"}, - {"([ti])a$", "${1}um"}, - {"((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$", "${1}sis"}, - {"(^analy)(sis|ses)$", "${1}sis"}, - {"([^f])ves$", "${1}fe"}, - {"(hive)s$", "${1}"}, - {"(tive)s$", "${1}"}, - {"([lr])ves$", "${1}f"}, - {"([^aeiouy]|qu)ies$", "${1}y"}, - {"(s)eries$", "${1}eries"}, - {"(m)ovies$", "${1}ovie"}, - {"(c)ookies$", "${1}ookie"}, - {"(x|ch|ss|sh)es$", "${1}"}, - {"^(m|l)ice$", "${1}ouse"}, - {"(bus)(es)?$", "${1}"}, - {"(o)es$", "${1}"}, - {"(shoe)s$", "${1}"}, - {"(cris|test)(is|es)$", "${1}is"}, - {"^(a)x[ie]s$", "${1}xis"}, - {"(octop|vir)(us|i)$", "${1}us"}, - {"(alias|status)(es)?$", "${1}"}, - {"^(ox)en", "${1}"}, - {"(vert|ind)ices$", "${1}ex"}, - {"(matr)ices$", "${1}ix"}, - {"(quiz)zes$", "${1}"}, - {"(database)s$", "${1}"}, -} - -var irregularInflections = IrregularSlice{ - {"person", "people"}, - {"man", "men"}, - {"child", "children"}, - {"sex", "sexes"}, - {"move", "moves"}, - {"mombie", "mombies"}, -} - -var uncountableInflections = []string{"equipment", "information", "rice", "money", "species", "series", "fish", "sheep", "jeans", "police"} - -var compiledPluralMaps []inflection -var compiledSingularMaps []inflection - -func compile() { - compiledPluralMaps = []inflection{} - compiledSingularMaps = []inflection{} - for _, uncountable := range uncountableInflections { - inf := inflection{ - regexp: regexp.MustCompile("^(?i)(" + uncountable + ")$"), - replace: "${1}", - } - compiledPluralMaps = append(compiledPluralMaps, inf) - compiledSingularMaps = append(compiledSingularMaps, inf) - } - - for _, value := range irregularInflections { - infs := []inflection{ - inflection{regexp: regexp.MustCompile(strings.ToUpper(value.singular) + "$"), replace: strings.ToUpper(value.plural)}, - inflection{regexp: regexp.MustCompile(strings.Title(value.singular) + "$"), replace: strings.Title(value.plural)}, - inflection{regexp: regexp.MustCompile(value.singular + "$"), replace: value.plural}, - } - compiledPluralMaps = append(compiledPluralMaps, infs...) - } - - for _, value := range irregularInflections { - infs := []inflection{ - inflection{regexp: regexp.MustCompile(strings.ToUpper(value.plural) + "$"), replace: strings.ToUpper(value.singular)}, - inflection{regexp: regexp.MustCompile(strings.Title(value.plural) + "$"), replace: strings.Title(value.singular)}, - inflection{regexp: regexp.MustCompile(value.plural + "$"), replace: value.singular}, - } - compiledSingularMaps = append(compiledSingularMaps, infs...) - } - - for i := len(pluralInflections) - 1; i >= 0; i-- { - value := pluralInflections[i] - infs := []inflection{ - inflection{regexp: regexp.MustCompile(strings.ToUpper(value.find)), replace: strings.ToUpper(value.replace)}, - inflection{regexp: regexp.MustCompile(value.find), replace: value.replace}, - inflection{regexp: regexp.MustCompile("(?i)" + value.find), replace: value.replace}, - } - compiledPluralMaps = append(compiledPluralMaps, infs...) - } - - for i := len(singularInflections) - 1; i >= 0; i-- { - value := singularInflections[i] - infs := []inflection{ - inflection{regexp: regexp.MustCompile(strings.ToUpper(value.find)), replace: strings.ToUpper(value.replace)}, - inflection{regexp: regexp.MustCompile(value.find), replace: value.replace}, - inflection{regexp: regexp.MustCompile("(?i)" + value.find), replace: value.replace}, - } - compiledSingularMaps = append(compiledSingularMaps, infs...) - } -} - -func init() { - compile() -} - -// AddPlural adds a plural inflection -func AddPlural(find, replace string) { - pluralInflections = append(pluralInflections, Regular{find, replace}) - compile() -} - -// AddSingular adds a singular inflection -func AddSingular(find, replace string) { - singularInflections = append(singularInflections, Regular{find, replace}) - compile() -} - -// AddIrregular adds an irregular inflection -func AddIrregular(singular, plural string) { - irregularInflections = append(irregularInflections, Irregular{singular, plural}) - compile() -} - -// AddUncountable adds an uncountable inflection -func AddUncountable(values ...string) { - uncountableInflections = append(uncountableInflections, values...) - compile() -} - -// GetPlural retrieves the plural inflection values -func GetPlural() RegularSlice { - plurals := make(RegularSlice, len(pluralInflections)) - copy(plurals, pluralInflections) - return plurals -} - -// GetSingular retrieves the singular inflection values -func GetSingular() RegularSlice { - singulars := make(RegularSlice, len(singularInflections)) - copy(singulars, singularInflections) - return singulars -} - -// GetIrregular retrieves the irregular inflection values -func GetIrregular() IrregularSlice { - irregular := make(IrregularSlice, len(irregularInflections)) - copy(irregular, irregularInflections) - return irregular -} - -// GetUncountable retrieves the uncountable inflection values -func GetUncountable() []string { - uncountables := make([]string, len(uncountableInflections)) - copy(uncountables, uncountableInflections) - return uncountables -} - -// SetPlural sets the plural inflections slice -func SetPlural(inflections RegularSlice) { - pluralInflections = inflections - compile() -} - -// SetSingular sets the singular inflections slice -func SetSingular(inflections RegularSlice) { - singularInflections = inflections - compile() -} - -// SetIrregular sets the irregular inflections slice -func SetIrregular(inflections IrregularSlice) { - irregularInflections = inflections - compile() -} - -// SetUncountable sets the uncountable inflections slice -func SetUncountable(inflections []string) { - uncountableInflections = inflections - compile() -} - -// Plural converts a word to its plural form -func Plural(str string) string { - for _, inflection := range compiledPluralMaps { - if inflection.regexp.MatchString(str) { - return inflection.regexp.ReplaceAllString(str, inflection.replace) - } - } - return str -} - -// Singular converts a word to its singular form -func Singular(str string) string { - for _, inflection := range compiledSingularMaps { - if inflection.regexp.MatchString(str) { - return inflection.regexp.ReplaceAllString(str, inflection.replace) - } - } - return str -} diff --git a/vendor/github.com/jinzhu/inflection/wercker.yml b/vendor/github.com/jinzhu/inflection/wercker.yml deleted file mode 100644 index 5e6ce981d..000000000 --- a/vendor/github.com/jinzhu/inflection/wercker.yml +++ /dev/null @@ -1,23 +0,0 @@ -box: golang - -build: - steps: - - setup-go-workspace - - # Gets the dependencies - - script: - name: go get - code: | - go get - - # Build the project - - script: - name: go build - code: | - go build ./... - - # Test the project - - script: - name: go test - code: | - go test ./... diff --git a/vendor/github.com/jirfag/go-printf-func-name/LICENSE b/vendor/github.com/jirfag/go-printf-func-name/LICENSE deleted file mode 100644 index d06a809c2..000000000 --- a/vendor/github.com/jirfag/go-printf-func-name/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -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/jirfag/go-printf-func-name/pkg/analyzer/analyzer.go b/vendor/github.com/jirfag/go-printf-func-name/pkg/analyzer/analyzer.go deleted file mode 100644 index 7937dd433..000000000 --- a/vendor/github.com/jirfag/go-printf-func-name/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,74 +0,0 @@ -package analyzer - -import ( - "go/ast" - "strings" - - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - - "golang.org/x/tools/go/analysis" -) - -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) (interface{}, error) { - inspector := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - nodeFilter := []ast.Node{ - (*ast.FuncDecl)(nil), - } - - inspector.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 - } - - if formatParamNames := params[len(params)-2].Names; 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 - } - - elementType, ok := argsParamType.Elt.(*ast.InterfaceType) - if !ok { // args are not of interface type, but we need interface{} - return - } - - if elementType.Methods != nil && len(elementType.Methods.List) != 0 { - return // has >= 1 method in interface, but we need an empty interface "interface{}" - } - - 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 -} diff --git a/vendor/github.com/jjti/go-spancheck/.gitignore b/vendor/github.com/jjti/go-spancheck/.gitignore deleted file mode 100644 index 1f83be414..000000000 --- a/vendor/github.com/jjti/go-spancheck/.gitignore +++ /dev/null @@ -1,19 +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/ 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 15d8513d6..000000000 --- a/vendor/github.com/jjti/go-spancheck/.golangci.yml +++ /dev/null @@ -1,103 +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 - - exhaustive # checks exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - gci - - gochecknoinits # checks that no init functions are present in Go code - - gocritic - - gomnd - - 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 - - tenv - - 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) - exhaustive: - # Program elements to check for exhaustiveness. - # Default: [ switch ] - check: - - switch - - map - 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: 4 - 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 32932fae1..000000000 --- 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 552ddf2dc..000000000 --- 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 8e9d07be3..000000000 --- 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 393663ba7..000000000 --- a/vendor/github.com/jjti/go-spancheck/README.md +++ /dev/null @@ -1,268 +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 - -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 - -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) 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 ed02a1ad9..000000000 --- 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 f9dec043f..000000000 --- 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 7d0a87b9e..000000000 --- a/vendor/github.com/jjti/go-spancheck/go.work +++ /dev/null @@ -1,8 +0,0 @@ -go 1.20 - -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 04eadf2c5..000000000 --- a/vendor/github.com/jjti/go-spancheck/go.work.sum +++ /dev/null @@ -1,4 +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/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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 8fc7945c6..000000000 --- a/vendor/github.com/jjti/go-spancheck/spancheck.go +++ /dev/null @@ -1,466 +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 -) - -// 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, "End", 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, "SetStatus", 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, "RecordError", 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 - - // 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) -} - -// 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 one level deep check. - return false - } - - 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 { - cfgs := pass.ResultOf[ctrlflow.Analyzer].(*ctrlflow.CFGs) - 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 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/jpillora/backoff/LICENSE b/vendor/github.com/jpillora/backoff/LICENSE deleted file mode 100644 index 1cc708081..000000000 --- a/vendor/github.com/jpillora/backoff/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 Jaime Pillora - -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/jpillora/backoff/README.md b/vendor/github.com/jpillora/backoff/README.md deleted file mode 100644 index ee4d6230a..000000000 --- a/vendor/github.com/jpillora/backoff/README.md +++ /dev/null @@ -1,119 +0,0 @@ -# Backoff - -A simple exponential backoff counter in Go (Golang) - -[![GoDoc](https://godoc.org/github.com/jpillora/backoff?status.svg)](https://godoc.org/github.com/jpillora/backoff) [![Circle CI](https://circleci.com/gh/jpillora/backoff.svg?style=shield)](https://circleci.com/gh/jpillora/backoff) - -### Install - -``` -$ go get -v github.com/jpillora/backoff -``` - -### Usage - -Backoff is a `time.Duration` counter. It starts at `Min`. After every call to `Duration()` it is multiplied by `Factor`. It is capped at `Max`. It returns to `Min` on every call to `Reset()`. `Jitter` adds randomness ([see below](#example-using-jitter)). Used in conjunction with the `time` package. - ---- - -#### Simple example - -``` go - -b := &backoff.Backoff{ - //These are the defaults - Min: 100 * time.Millisecond, - Max: 10 * time.Second, - Factor: 2, - Jitter: false, -} - -fmt.Printf("%s\n", b.Duration()) -fmt.Printf("%s\n", b.Duration()) -fmt.Printf("%s\n", b.Duration()) - -fmt.Printf("Reset!\n") -b.Reset() - -fmt.Printf("%s\n", b.Duration()) -``` - -``` -100ms -200ms -400ms -Reset! -100ms -``` - ---- - -#### Example using `net` package - -``` go -b := &backoff.Backoff{ - Max: 5 * time.Minute, -} - -for { - conn, err := net.Dial("tcp", "example.com:5309") - if err != nil { - d := b.Duration() - fmt.Printf("%s, reconnecting in %s", err, d) - time.Sleep(d) - continue - } - //connected - b.Reset() - conn.Write([]byte("hello world!")) - // ... Read ... Write ... etc - conn.Close() - //disconnected -} - -``` - ---- - -#### Example using `Jitter` - -Enabling `Jitter` adds some randomization to the backoff durations. [See Amazon's writeup of performance gains using jitter](http://www.awsarchitectureblog.com/2015/03/backoff.html). Seeding is not necessary but doing so gives repeatable results. - -```go -import "math/rand" - -b := &backoff.Backoff{ - Jitter: true, -} - -rand.Seed(42) - -fmt.Printf("%s\n", b.Duration()) -fmt.Printf("%s\n", b.Duration()) -fmt.Printf("%s\n", b.Duration()) - -fmt.Printf("Reset!\n") -b.Reset() - -fmt.Printf("%s\n", b.Duration()) -fmt.Printf("%s\n", b.Duration()) -fmt.Printf("%s\n", b.Duration()) -``` - -``` -100ms -106.600049ms -281.228155ms -Reset! -100ms -104.381845ms -214.957989ms -``` - -#### Documentation - -https://godoc.org/github.com/jpillora/backoff - -#### Credits - -Forked from [some JavaScript](https://github.com/segmentio/backo) written by [@tj](https://github.com/tj) diff --git a/vendor/github.com/jpillora/backoff/backoff.go b/vendor/github.com/jpillora/backoff/backoff.go deleted file mode 100644 index d113e6890..000000000 --- a/vendor/github.com/jpillora/backoff/backoff.go +++ /dev/null @@ -1,100 +0,0 @@ -// Package backoff provides an exponential-backoff implementation. -package backoff - -import ( - "math" - "math/rand" - "sync/atomic" - "time" -) - -// Backoff is a time.Duration counter, starting at Min. After every call to -// the Duration method the current timing is multiplied by Factor, but it -// never exceeds Max. -// -// Backoff is not generally concurrent-safe, but the ForAttempt method can -// be used concurrently. -type Backoff struct { - attempt uint64 - // Factor is the multiplying factor for each increment step - Factor float64 - // Jitter eases contention by randomizing backoff steps - Jitter bool - // Min and Max are the minimum and maximum values of the counter - Min, Max time.Duration -} - -// Duration returns the duration for the current attempt before incrementing -// the attempt counter. See ForAttempt. -func (b *Backoff) Duration() time.Duration { - d := b.ForAttempt(float64(atomic.AddUint64(&b.attempt, 1) - 1)) - return d -} - -const maxInt64 = float64(math.MaxInt64 - 512) - -// ForAttempt returns the duration for a specific attempt. This is useful if -// you have a large number of independent Backoffs, but don't want use -// unnecessary memory storing the Backoff parameters per Backoff. The first -// attempt should be 0. -// -// ForAttempt is concurrent-safe. -func (b *Backoff) ForAttempt(attempt float64) time.Duration { - // Zero-values are nonsensical, so we use - // them to apply defaults - min := b.Min - if min <= 0 { - min = 100 * time.Millisecond - } - max := b.Max - if max <= 0 { - max = 10 * time.Second - } - if min >= max { - // short-circuit - return max - } - factor := b.Factor - if factor <= 0 { - factor = 2 - } - //calculate this duration - minf := float64(min) - durf := minf * math.Pow(factor, attempt) - if b.Jitter { - durf = rand.Float64()*(durf-minf) + minf - } - //ensure float64 wont overflow int64 - if durf > maxInt64 { - return max - } - dur := time.Duration(durf) - //keep within bounds - if dur < min { - return min - } - if dur > max { - return max - } - return dur -} - -// Reset restarts the current attempt counter at zero. -func (b *Backoff) Reset() { - atomic.StoreUint64(&b.attempt, 0) -} - -// Attempt returns the current attempt counter value. -func (b *Backoff) Attempt() float64 { - return float64(atomic.LoadUint64(&b.attempt)) -} - -// Copy returns a backoff with equals constraints as the original -func (b *Backoff) Copy() *Backoff { - return &Backoff{ - Factor: b.Factor, - Jitter: b.Jitter, - Min: b.Min, - Max: b.Max, - } -} diff --git a/vendor/github.com/json-iterator/go/.codecov.yml b/vendor/github.com/json-iterator/go/.codecov.yml deleted file mode 100644 index 955dc0be5..000000000 --- a/vendor/github.com/json-iterator/go/.codecov.yml +++ /dev/null @@ -1,3 +0,0 @@ -ignore: - - "output_tests/.*" - diff --git a/vendor/github.com/json-iterator/go/.gitignore b/vendor/github.com/json-iterator/go/.gitignore deleted file mode 100644 index 15556530a..000000000 --- a/vendor/github.com/json-iterator/go/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/vendor -/bug_test.go -/coverage.txt -/.idea diff --git a/vendor/github.com/json-iterator/go/.travis.yml b/vendor/github.com/json-iterator/go/.travis.yml deleted file mode 100644 index 449e67cd0..000000000 --- a/vendor/github.com/json-iterator/go/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go - -go: - - 1.8.x - - 1.x - -before_install: - - go get -t -v ./... - -script: - - ./test.sh - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/json-iterator/go/Gopkg.lock b/vendor/github.com/json-iterator/go/Gopkg.lock deleted file mode 100644 index c8a9fbb38..000000000 --- a/vendor/github.com/json-iterator/go/Gopkg.lock +++ /dev/null @@ -1,21 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/modern-go/concurrent" - packages = ["."] - revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a" - version = "1.0.0" - -[[projects]] - name = "github.com/modern-go/reflect2" - packages = ["."] - revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd" - version = "1.0.1" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "ea54a775e5a354cb015502d2e7aa4b74230fc77e894f34a838b268c25ec8eeb8" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/json-iterator/go/Gopkg.toml b/vendor/github.com/json-iterator/go/Gopkg.toml deleted file mode 100644 index 313a0f887..000000000 --- a/vendor/github.com/json-iterator/go/Gopkg.toml +++ /dev/null @@ -1,26 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# 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" - -ignored = ["github.com/davecgh/go-spew*","github.com/google/gofuzz*","github.com/stretchr/testify*"] - -[[constraint]] - name = "github.com/modern-go/reflect2" - version = "1.0.1" diff --git a/vendor/github.com/json-iterator/go/LICENSE b/vendor/github.com/json-iterator/go/LICENSE deleted file mode 100644 index 2cf4f5ab2..000000000 --- a/vendor/github.com/json-iterator/go/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 json-iterator - -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/json-iterator/go/README.md b/vendor/github.com/json-iterator/go/README.md deleted file mode 100644 index c589addf9..000000000 --- a/vendor/github.com/json-iterator/go/README.md +++ /dev/null @@ -1,85 +0,0 @@ -[![Sourcegraph](https://sourcegraph.com/github.com/json-iterator/go/-/badge.svg)](https://sourcegraph.com/github.com/json-iterator/go?badge) -[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://pkg.go.dev/github.com/json-iterator/go) -[![Build Status](https://travis-ci.org/json-iterator/go.svg?branch=master)](https://travis-ci.org/json-iterator/go) -[![codecov](https://codecov.io/gh/json-iterator/go/branch/master/graph/badge.svg)](https://codecov.io/gh/json-iterator/go) -[![rcard](https://goreportcard.com/badge/github.com/json-iterator/go)](https://goreportcard.com/report/github.com/json-iterator/go) -[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/json-iterator/go/master/LICENSE) -[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby) - -A high-performance 100% compatible drop-in replacement of "encoding/json" - -# Benchmark - -![benchmark](http://jsoniter.com/benchmarks/go-benchmark.png) - -Source code: https://github.com/json-iterator/go-benchmark/blob/master/src/github.com/json-iterator/go-benchmark/benchmark_medium_payload_test.go - -Raw Result (easyjson requires static code generation) - -| | ns/op | allocation bytes | allocation times | -| --------------- | ----------- | ---------------- | ---------------- | -| std decode | 35510 ns/op | 1960 B/op | 99 allocs/op | -| easyjson decode | 8499 ns/op | 160 B/op | 4 allocs/op | -| jsoniter decode | 5623 ns/op | 160 B/op | 3 allocs/op | -| std encode | 2213 ns/op | 712 B/op | 5 allocs/op | -| easyjson encode | 883 ns/op | 576 B/op | 3 allocs/op | -| jsoniter encode | 837 ns/op | 384 B/op | 4 allocs/op | - -Always benchmark with your own workload. -The result depends heavily on the data input. - -# Usage - -100% compatibility with standard lib - -Replace - -```go -import "encoding/json" -json.Marshal(&data) -``` - -with - -```go -import jsoniter "github.com/json-iterator/go" - -var json = jsoniter.ConfigCompatibleWithStandardLibrary -json.Marshal(&data) -``` - -Replace - -```go -import "encoding/json" -json.Unmarshal(input, &data) -``` - -with - -```go -import jsoniter "github.com/json-iterator/go" - -var json = jsoniter.ConfigCompatibleWithStandardLibrary -json.Unmarshal(input, &data) -``` - -[More documentation](http://jsoniter.com/migrate-from-go-std.html) - -# How to get - -``` -go get github.com/json-iterator/go -``` - -# Contribution Welcomed ! - -Contributors - -- [thockin](https://github.com/thockin) -- [mattn](https://github.com/mattn) -- [cch123](https://github.com/cch123) -- [Oleg Shaldybin](https://github.com/olegshaldybin) -- [Jason Toffaletti](https://github.com/toffaletti) - -Report issue or pull request, or email taowen@gmail.com, or [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby) diff --git a/vendor/github.com/json-iterator/go/adapter.go b/vendor/github.com/json-iterator/go/adapter.go deleted file mode 100644 index 92d2cc4a3..000000000 --- a/vendor/github.com/json-iterator/go/adapter.go +++ /dev/null @@ -1,150 +0,0 @@ -package jsoniter - -import ( - "bytes" - "io" -) - -// RawMessage to make replace json with jsoniter -type RawMessage []byte - -// Unmarshal adapts to json/encoding Unmarshal API -// -// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. -// Refer to https://godoc.org/encoding/json#Unmarshal for more information -func Unmarshal(data []byte, v interface{}) error { - return ConfigDefault.Unmarshal(data, v) -} - -// UnmarshalFromString is a convenient method to read from string instead of []byte -func UnmarshalFromString(str string, v interface{}) error { - return ConfigDefault.UnmarshalFromString(str, v) -} - -// Get quick method to get value from deeply nested JSON structure -func Get(data []byte, path ...interface{}) Any { - return ConfigDefault.Get(data, path...) -} - -// Marshal adapts to json/encoding Marshal API -// -// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API -// Refer to https://godoc.org/encoding/json#Marshal for more information -func Marshal(v interface{}) ([]byte, error) { - return ConfigDefault.Marshal(v) -} - -// MarshalIndent same as json.MarshalIndent. Prefix is not supported. -func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { - return ConfigDefault.MarshalIndent(v, prefix, indent) -} - -// MarshalToString convenient method to write as string instead of []byte -func MarshalToString(v interface{}) (string, error) { - return ConfigDefault.MarshalToString(v) -} - -// NewDecoder adapts to json/stream NewDecoder API. -// -// NewDecoder returns a new decoder that reads from r. -// -// Instead of a json/encoding Decoder, an Decoder is returned -// Refer to https://godoc.org/encoding/json#NewDecoder for more information -func NewDecoder(reader io.Reader) *Decoder { - return ConfigDefault.NewDecoder(reader) -} - -// Decoder reads and decodes JSON values from an input stream. -// Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress) -type Decoder struct { - iter *Iterator -} - -// Decode decode JSON into interface{} -func (adapter *Decoder) Decode(obj interface{}) error { - if adapter.iter.head == adapter.iter.tail && adapter.iter.reader != nil { - if !adapter.iter.loadMore() { - return io.EOF - } - } - adapter.iter.ReadVal(obj) - err := adapter.iter.Error - if err == io.EOF { - return nil - } - return adapter.iter.Error -} - -// More is there more? -func (adapter *Decoder) More() bool { - iter := adapter.iter - if iter.Error != nil { - return false - } - c := iter.nextToken() - if c == 0 { - return false - } - iter.unreadByte() - return c != ']' && c != '}' -} - -// Buffered remaining buffer -func (adapter *Decoder) Buffered() io.Reader { - remaining := adapter.iter.buf[adapter.iter.head:adapter.iter.tail] - return bytes.NewReader(remaining) -} - -// UseNumber causes the Decoder to unmarshal a number into an interface{} as a -// Number instead of as a float64. -func (adapter *Decoder) UseNumber() { - cfg := adapter.iter.cfg.configBeforeFrozen - cfg.UseNumber = true - adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) -} - -// DisallowUnknownFields causes the Decoder to return an error when the destination -// is a struct and the input contains object keys which do not match any -// non-ignored, exported fields in the destination. -func (adapter *Decoder) DisallowUnknownFields() { - cfg := adapter.iter.cfg.configBeforeFrozen - cfg.DisallowUnknownFields = true - adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) -} - -// NewEncoder same as json.NewEncoder -func NewEncoder(writer io.Writer) *Encoder { - return ConfigDefault.NewEncoder(writer) -} - -// Encoder same as json.Encoder -type Encoder struct { - stream *Stream -} - -// Encode encode interface{} as JSON to io.Writer -func (adapter *Encoder) Encode(val interface{}) error { - adapter.stream.WriteVal(val) - adapter.stream.WriteRaw("\n") - adapter.stream.Flush() - return adapter.stream.Error -} - -// SetIndent set the indention. Prefix is not supported -func (adapter *Encoder) SetIndent(prefix, indent string) { - config := adapter.stream.cfg.configBeforeFrozen - config.IndentionStep = len(indent) - adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) -} - -// SetEscapeHTML escape html by default, set to false to disable -func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) { - config := adapter.stream.cfg.configBeforeFrozen - config.EscapeHTML = escapeHTML - adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) -} - -// Valid reports whether data is a valid JSON encoding. -func Valid(data []byte) bool { - return ConfigDefault.Valid(data) -} diff --git a/vendor/github.com/json-iterator/go/any.go b/vendor/github.com/json-iterator/go/any.go deleted file mode 100644 index f6b8aeab0..000000000 --- a/vendor/github.com/json-iterator/go/any.go +++ /dev/null @@ -1,325 +0,0 @@ -package jsoniter - -import ( - "errors" - "fmt" - "github.com/modern-go/reflect2" - "io" - "reflect" - "strconv" - "unsafe" -) - -// Any generic object representation. -// The lazy json implementation holds []byte and parse lazily. -type Any interface { - LastError() error - ValueType() ValueType - MustBeValid() Any - ToBool() bool - ToInt() int - ToInt32() int32 - ToInt64() int64 - ToUint() uint - ToUint32() uint32 - ToUint64() uint64 - ToFloat32() float32 - ToFloat64() float64 - ToString() string - ToVal(val interface{}) - Get(path ...interface{}) Any - Size() int - Keys() []string - GetInterface() interface{} - WriteTo(stream *Stream) -} - -type baseAny struct{} - -func (any *baseAny) Get(path ...interface{}) Any { - return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} -} - -func (any *baseAny) Size() int { - return 0 -} - -func (any *baseAny) Keys() []string { - return []string{} -} - -func (any *baseAny) ToVal(obj interface{}) { - panic("not implemented") -} - -// WrapInt32 turn int32 into Any interface -func WrapInt32(val int32) Any { - return &int32Any{baseAny{}, val} -} - -// WrapInt64 turn int64 into Any interface -func WrapInt64(val int64) Any { - return &int64Any{baseAny{}, val} -} - -// WrapUint32 turn uint32 into Any interface -func WrapUint32(val uint32) Any { - return &uint32Any{baseAny{}, val} -} - -// WrapUint64 turn uint64 into Any interface -func WrapUint64(val uint64) Any { - return &uint64Any{baseAny{}, val} -} - -// WrapFloat64 turn float64 into Any interface -func WrapFloat64(val float64) Any { - return &floatAny{baseAny{}, val} -} - -// WrapString turn string into Any interface -func WrapString(val string) Any { - return &stringAny{baseAny{}, val} -} - -// Wrap turn a go object into Any interface -func Wrap(val interface{}) Any { - if val == nil { - return &nilAny{} - } - asAny, isAny := val.(Any) - if isAny { - return asAny - } - typ := reflect2.TypeOf(val) - switch typ.Kind() { - case reflect.Slice: - return wrapArray(val) - case reflect.Struct: - return wrapStruct(val) - case reflect.Map: - return wrapMap(val) - case reflect.String: - return WrapString(val.(string)) - case reflect.Int: - if strconv.IntSize == 32 { - return WrapInt32(int32(val.(int))) - } - return WrapInt64(int64(val.(int))) - case reflect.Int8: - return WrapInt32(int32(val.(int8))) - case reflect.Int16: - return WrapInt32(int32(val.(int16))) - case reflect.Int32: - return WrapInt32(val.(int32)) - case reflect.Int64: - return WrapInt64(val.(int64)) - case reflect.Uint: - if strconv.IntSize == 32 { - return WrapUint32(uint32(val.(uint))) - } - return WrapUint64(uint64(val.(uint))) - case reflect.Uintptr: - if ptrSize == 32 { - return WrapUint32(uint32(val.(uintptr))) - } - return WrapUint64(uint64(val.(uintptr))) - case reflect.Uint8: - return WrapUint32(uint32(val.(uint8))) - case reflect.Uint16: - return WrapUint32(uint32(val.(uint16))) - case reflect.Uint32: - return WrapUint32(uint32(val.(uint32))) - case reflect.Uint64: - return WrapUint64(val.(uint64)) - case reflect.Float32: - return WrapFloat64(float64(val.(float32))) - case reflect.Float64: - return WrapFloat64(val.(float64)) - case reflect.Bool: - if val.(bool) == true { - return &trueAny{} - } - return &falseAny{} - } - return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)} -} - -// ReadAny read next JSON element as an Any object. It is a better json.RawMessage. -func (iter *Iterator) ReadAny() Any { - return iter.readAny() -} - -func (iter *Iterator) readAny() Any { - c := iter.nextToken() - switch c { - case '"': - iter.unreadByte() - return &stringAny{baseAny{}, iter.ReadString()} - case 'n': - iter.skipThreeBytes('u', 'l', 'l') // null - return &nilAny{} - case 't': - iter.skipThreeBytes('r', 'u', 'e') // true - return &trueAny{} - case 'f': - iter.skipFourBytes('a', 'l', 's', 'e') // false - return &falseAny{} - case '{': - return iter.readObjectAny() - case '[': - return iter.readArrayAny() - case '-': - return iter.readNumberAny(false) - case 0: - return &invalidAny{baseAny{}, errors.New("input is empty")} - default: - return iter.readNumberAny(true) - } -} - -func (iter *Iterator) readNumberAny(positive bool) Any { - iter.startCapture(iter.head - 1) - iter.skipNumber() - lazyBuf := iter.stopCapture() - return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} -} - -func (iter *Iterator) readObjectAny() Any { - iter.startCapture(iter.head - 1) - iter.skipObject() - lazyBuf := iter.stopCapture() - return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} -} - -func (iter *Iterator) readArrayAny() Any { - iter.startCapture(iter.head - 1) - iter.skipArray() - lazyBuf := iter.stopCapture() - return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} -} - -func locateObjectField(iter *Iterator, target string) []byte { - var found []byte - iter.ReadObjectCB(func(iter *Iterator, field string) bool { - if field == target { - found = iter.SkipAndReturnBytes() - return false - } - iter.Skip() - return true - }) - return found -} - -func locateArrayElement(iter *Iterator, target int) []byte { - var found []byte - n := 0 - iter.ReadArrayCB(func(iter *Iterator) bool { - if n == target { - found = iter.SkipAndReturnBytes() - return false - } - iter.Skip() - n++ - return true - }) - return found -} - -func locatePath(iter *Iterator, path []interface{}) Any { - for i, pathKeyObj := range path { - switch pathKey := pathKeyObj.(type) { - case string: - valueBytes := locateObjectField(iter, pathKey) - if valueBytes == nil { - return newInvalidAny(path[i:]) - } - iter.ResetBytes(valueBytes) - case int: - valueBytes := locateArrayElement(iter, pathKey) - if valueBytes == nil { - return newInvalidAny(path[i:]) - } - iter.ResetBytes(valueBytes) - case int32: - if '*' == pathKey { - return iter.readAny().Get(path[i:]...) - } - return newInvalidAny(path[i:]) - default: - return newInvalidAny(path[i:]) - } - } - if iter.Error != nil && iter.Error != io.EOF { - return &invalidAny{baseAny{}, iter.Error} - } - return iter.readAny() -} - -var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem() - -func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder { - if typ == anyType { - return &directAnyCodec{} - } - if typ.Implements(anyType) { - return &anyCodec{ - valType: typ, - } - } - return nil -} - -func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder { - if typ == anyType { - return &directAnyCodec{} - } - if typ.Implements(anyType) { - return &anyCodec{ - valType: typ, - } - } - return nil -} - -type anyCodec struct { - valType reflect2.Type -} - -func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - panic("not implemented") -} - -func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - obj := codec.valType.UnsafeIndirect(ptr) - any := obj.(Any) - any.WriteTo(stream) -} - -func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool { - obj := codec.valType.UnsafeIndirect(ptr) - any := obj.(Any) - return any.Size() == 0 -} - -type directAnyCodec struct { -} - -func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *(*Any)(ptr) = iter.readAny() -} - -func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - any := *(*Any)(ptr) - if any == nil { - stream.WriteNil() - return - } - any.WriteTo(stream) -} - -func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool { - any := *(*Any)(ptr) - return any.Size() == 0 -} diff --git a/vendor/github.com/json-iterator/go/any_array.go b/vendor/github.com/json-iterator/go/any_array.go deleted file mode 100644 index 0449e9aa4..000000000 --- a/vendor/github.com/json-iterator/go/any_array.go +++ /dev/null @@ -1,278 +0,0 @@ -package jsoniter - -import ( - "reflect" - "unsafe" -) - -type arrayLazyAny struct { - baseAny - cfg *frozenConfig - buf []byte - err error -} - -func (any *arrayLazyAny) ValueType() ValueType { - return ArrayValue -} - -func (any *arrayLazyAny) MustBeValid() Any { - return any -} - -func (any *arrayLazyAny) LastError() error { - return any.err -} - -func (any *arrayLazyAny) ToBool() bool { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - return iter.ReadArray() -} - -func (any *arrayLazyAny) ToInt() int { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToInt32() int32 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToInt64() int64 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToUint() uint { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToUint32() uint32 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToUint64() uint64 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToFloat32() float32 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToFloat64() float64 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToString() string { - return *(*string)(unsafe.Pointer(&any.buf)) -} - -func (any *arrayLazyAny) ToVal(val interface{}) { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadVal(val) -} - -func (any *arrayLazyAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - switch firstPath := path[0].(type) { - case int: - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - valueBytes := locateArrayElement(iter, firstPath) - if valueBytes == nil { - return newInvalidAny(path) - } - iter.ResetBytes(valueBytes) - return locatePath(iter, path[1:]) - case int32: - if '*' == firstPath { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - arr := make([]Any, 0) - iter.ReadArrayCB(func(iter *Iterator) bool { - found := iter.readAny().Get(path[1:]...) - if found.ValueType() != InvalidValue { - arr = append(arr, found) - } - return true - }) - return wrapArray(arr) - } - return newInvalidAny(path) - default: - return newInvalidAny(path) - } -} - -func (any *arrayLazyAny) Size() int { - size := 0 - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadArrayCB(func(iter *Iterator) bool { - size++ - iter.Skip() - return true - }) - return size -} - -func (any *arrayLazyAny) WriteTo(stream *Stream) { - stream.Write(any.buf) -} - -func (any *arrayLazyAny) GetInterface() interface{} { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - return iter.Read() -} - -type arrayAny struct { - baseAny - val reflect.Value -} - -func wrapArray(val interface{}) *arrayAny { - return &arrayAny{baseAny{}, reflect.ValueOf(val)} -} - -func (any *arrayAny) ValueType() ValueType { - return ArrayValue -} - -func (any *arrayAny) MustBeValid() Any { - return any -} - -func (any *arrayAny) LastError() error { - return nil -} - -func (any *arrayAny) ToBool() bool { - return any.val.Len() != 0 -} - -func (any *arrayAny) ToInt() int { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToInt32() int32 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToInt64() int64 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToUint() uint { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToUint32() uint32 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToUint64() uint64 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToFloat32() float32 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToFloat64() float64 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToString() string { - str, _ := MarshalToString(any.val.Interface()) - return str -} - -func (any *arrayAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - switch firstPath := path[0].(type) { - case int: - if firstPath < 0 || firstPath >= any.val.Len() { - return newInvalidAny(path) - } - return Wrap(any.val.Index(firstPath).Interface()) - case int32: - if '*' == firstPath { - mappedAll := make([]Any, 0) - for i := 0; i < any.val.Len(); i++ { - mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...) - if mapped.ValueType() != InvalidValue { - mappedAll = append(mappedAll, mapped) - } - } - return wrapArray(mappedAll) - } - return newInvalidAny(path) - default: - return newInvalidAny(path) - } -} - -func (any *arrayAny) Size() int { - return any.val.Len() -} - -func (any *arrayAny) WriteTo(stream *Stream) { - stream.WriteVal(any.val) -} - -func (any *arrayAny) GetInterface() interface{} { - return any.val.Interface() -} diff --git a/vendor/github.com/json-iterator/go/any_bool.go b/vendor/github.com/json-iterator/go/any_bool.go deleted file mode 100644 index 9452324af..000000000 --- a/vendor/github.com/json-iterator/go/any_bool.go +++ /dev/null @@ -1,137 +0,0 @@ -package jsoniter - -type trueAny struct { - baseAny -} - -func (any *trueAny) LastError() error { - return nil -} - -func (any *trueAny) ToBool() bool { - return true -} - -func (any *trueAny) ToInt() int { - return 1 -} - -func (any *trueAny) ToInt32() int32 { - return 1 -} - -func (any *trueAny) ToInt64() int64 { - return 1 -} - -func (any *trueAny) ToUint() uint { - return 1 -} - -func (any *trueAny) ToUint32() uint32 { - return 1 -} - -func (any *trueAny) ToUint64() uint64 { - return 1 -} - -func (any *trueAny) ToFloat32() float32 { - return 1 -} - -func (any *trueAny) ToFloat64() float64 { - return 1 -} - -func (any *trueAny) ToString() string { - return "true" -} - -func (any *trueAny) WriteTo(stream *Stream) { - stream.WriteTrue() -} - -func (any *trueAny) Parse() *Iterator { - return nil -} - -func (any *trueAny) GetInterface() interface{} { - return true -} - -func (any *trueAny) ValueType() ValueType { - return BoolValue -} - -func (any *trueAny) MustBeValid() Any { - return any -} - -type falseAny struct { - baseAny -} - -func (any *falseAny) LastError() error { - return nil -} - -func (any *falseAny) ToBool() bool { - return false -} - -func (any *falseAny) ToInt() int { - return 0 -} - -func (any *falseAny) ToInt32() int32 { - return 0 -} - -func (any *falseAny) ToInt64() int64 { - return 0 -} - -func (any *falseAny) ToUint() uint { - return 0 -} - -func (any *falseAny) ToUint32() uint32 { - return 0 -} - -func (any *falseAny) ToUint64() uint64 { - return 0 -} - -func (any *falseAny) ToFloat32() float32 { - return 0 -} - -func (any *falseAny) ToFloat64() float64 { - return 0 -} - -func (any *falseAny) ToString() string { - return "false" -} - -func (any *falseAny) WriteTo(stream *Stream) { - stream.WriteFalse() -} - -func (any *falseAny) Parse() *Iterator { - return nil -} - -func (any *falseAny) GetInterface() interface{} { - return false -} - -func (any *falseAny) ValueType() ValueType { - return BoolValue -} - -func (any *falseAny) MustBeValid() Any { - return any -} diff --git a/vendor/github.com/json-iterator/go/any_float.go b/vendor/github.com/json-iterator/go/any_float.go deleted file mode 100644 index 35fdb0949..000000000 --- a/vendor/github.com/json-iterator/go/any_float.go +++ /dev/null @@ -1,83 +0,0 @@ -package jsoniter - -import ( - "strconv" -) - -type floatAny struct { - baseAny - val float64 -} - -func (any *floatAny) Parse() *Iterator { - return nil -} - -func (any *floatAny) ValueType() ValueType { - return NumberValue -} - -func (any *floatAny) MustBeValid() Any { - return any -} - -func (any *floatAny) LastError() error { - return nil -} - -func (any *floatAny) ToBool() bool { - return any.ToFloat64() != 0 -} - -func (any *floatAny) ToInt() int { - return int(any.val) -} - -func (any *floatAny) ToInt32() int32 { - return int32(any.val) -} - -func (any *floatAny) ToInt64() int64 { - return int64(any.val) -} - -func (any *floatAny) ToUint() uint { - if any.val > 0 { - return uint(any.val) - } - return 0 -} - -func (any *floatAny) ToUint32() uint32 { - if any.val > 0 { - return uint32(any.val) - } - return 0 -} - -func (any *floatAny) ToUint64() uint64 { - if any.val > 0 { - return uint64(any.val) - } - return 0 -} - -func (any *floatAny) ToFloat32() float32 { - return float32(any.val) -} - -func (any *floatAny) ToFloat64() float64 { - return any.val -} - -func (any *floatAny) ToString() string { - return strconv.FormatFloat(any.val, 'E', -1, 64) -} - -func (any *floatAny) WriteTo(stream *Stream) { - stream.WriteFloat64(any.val) -} - -func (any *floatAny) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/any_int32.go b/vendor/github.com/json-iterator/go/any_int32.go deleted file mode 100644 index 1b56f3991..000000000 --- a/vendor/github.com/json-iterator/go/any_int32.go +++ /dev/null @@ -1,74 +0,0 @@ -package jsoniter - -import ( - "strconv" -) - -type int32Any struct { - baseAny - val int32 -} - -func (any *int32Any) LastError() error { - return nil -} - -func (any *int32Any) ValueType() ValueType { - return NumberValue -} - -func (any *int32Any) MustBeValid() Any { - return any -} - -func (any *int32Any) ToBool() bool { - return any.val != 0 -} - -func (any *int32Any) ToInt() int { - return int(any.val) -} - -func (any *int32Any) ToInt32() int32 { - return any.val -} - -func (any *int32Any) ToInt64() int64 { - return int64(any.val) -} - -func (any *int32Any) ToUint() uint { - return uint(any.val) -} - -func (any *int32Any) ToUint32() uint32 { - return uint32(any.val) -} - -func (any *int32Any) ToUint64() uint64 { - return uint64(any.val) -} - -func (any *int32Any) ToFloat32() float32 { - return float32(any.val) -} - -func (any *int32Any) ToFloat64() float64 { - return float64(any.val) -} - -func (any *int32Any) ToString() string { - return strconv.FormatInt(int64(any.val), 10) -} - -func (any *int32Any) WriteTo(stream *Stream) { - stream.WriteInt32(any.val) -} - -func (any *int32Any) Parse() *Iterator { - return nil -} - -func (any *int32Any) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/any_int64.go b/vendor/github.com/json-iterator/go/any_int64.go deleted file mode 100644 index c440d72b6..000000000 --- a/vendor/github.com/json-iterator/go/any_int64.go +++ /dev/null @@ -1,74 +0,0 @@ -package jsoniter - -import ( - "strconv" -) - -type int64Any struct { - baseAny - val int64 -} - -func (any *int64Any) LastError() error { - return nil -} - -func (any *int64Any) ValueType() ValueType { - return NumberValue -} - -func (any *int64Any) MustBeValid() Any { - return any -} - -func (any *int64Any) ToBool() bool { - return any.val != 0 -} - -func (any *int64Any) ToInt() int { - return int(any.val) -} - -func (any *int64Any) ToInt32() int32 { - return int32(any.val) -} - -func (any *int64Any) ToInt64() int64 { - return any.val -} - -func (any *int64Any) ToUint() uint { - return uint(any.val) -} - -func (any *int64Any) ToUint32() uint32 { - return uint32(any.val) -} - -func (any *int64Any) ToUint64() uint64 { - return uint64(any.val) -} - -func (any *int64Any) ToFloat32() float32 { - return float32(any.val) -} - -func (any *int64Any) ToFloat64() float64 { - return float64(any.val) -} - -func (any *int64Any) ToString() string { - return strconv.FormatInt(any.val, 10) -} - -func (any *int64Any) WriteTo(stream *Stream) { - stream.WriteInt64(any.val) -} - -func (any *int64Any) Parse() *Iterator { - return nil -} - -func (any *int64Any) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/any_invalid.go b/vendor/github.com/json-iterator/go/any_invalid.go deleted file mode 100644 index 1d859eac3..000000000 --- a/vendor/github.com/json-iterator/go/any_invalid.go +++ /dev/null @@ -1,82 +0,0 @@ -package jsoniter - -import "fmt" - -type invalidAny struct { - baseAny - err error -} - -func newInvalidAny(path []interface{}) *invalidAny { - return &invalidAny{baseAny{}, fmt.Errorf("%v not found", path)} -} - -func (any *invalidAny) LastError() error { - return any.err -} - -func (any *invalidAny) ValueType() ValueType { - return InvalidValue -} - -func (any *invalidAny) MustBeValid() Any { - panic(any.err) -} - -func (any *invalidAny) ToBool() bool { - return false -} - -func (any *invalidAny) ToInt() int { - return 0 -} - -func (any *invalidAny) ToInt32() int32 { - return 0 -} - -func (any *invalidAny) ToInt64() int64 { - return 0 -} - -func (any *invalidAny) ToUint() uint { - return 0 -} - -func (any *invalidAny) ToUint32() uint32 { - return 0 -} - -func (any *invalidAny) ToUint64() uint64 { - return 0 -} - -func (any *invalidAny) ToFloat32() float32 { - return 0 -} - -func (any *invalidAny) ToFloat64() float64 { - return 0 -} - -func (any *invalidAny) ToString() string { - return "" -} - -func (any *invalidAny) WriteTo(stream *Stream) { -} - -func (any *invalidAny) Get(path ...interface{}) Any { - if any.err == nil { - return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)} - } - return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)} -} - -func (any *invalidAny) Parse() *Iterator { - return nil -} - -func (any *invalidAny) GetInterface() interface{} { - return nil -} diff --git a/vendor/github.com/json-iterator/go/any_nil.go b/vendor/github.com/json-iterator/go/any_nil.go deleted file mode 100644 index d04cb54c1..000000000 --- a/vendor/github.com/json-iterator/go/any_nil.go +++ /dev/null @@ -1,69 +0,0 @@ -package jsoniter - -type nilAny struct { - baseAny -} - -func (any *nilAny) LastError() error { - return nil -} - -func (any *nilAny) ValueType() ValueType { - return NilValue -} - -func (any *nilAny) MustBeValid() Any { - return any -} - -func (any *nilAny) ToBool() bool { - return false -} - -func (any *nilAny) ToInt() int { - return 0 -} - -func (any *nilAny) ToInt32() int32 { - return 0 -} - -func (any *nilAny) ToInt64() int64 { - return 0 -} - -func (any *nilAny) ToUint() uint { - return 0 -} - -func (any *nilAny) ToUint32() uint32 { - return 0 -} - -func (any *nilAny) ToUint64() uint64 { - return 0 -} - -func (any *nilAny) ToFloat32() float32 { - return 0 -} - -func (any *nilAny) ToFloat64() float64 { - return 0 -} - -func (any *nilAny) ToString() string { - return "" -} - -func (any *nilAny) WriteTo(stream *Stream) { - stream.WriteNil() -} - -func (any *nilAny) Parse() *Iterator { - return nil -} - -func (any *nilAny) GetInterface() interface{} { - return nil -} diff --git a/vendor/github.com/json-iterator/go/any_number.go b/vendor/github.com/json-iterator/go/any_number.go deleted file mode 100644 index 9d1e901a6..000000000 --- a/vendor/github.com/json-iterator/go/any_number.go +++ /dev/null @@ -1,123 +0,0 @@ -package jsoniter - -import ( - "io" - "unsafe" -) - -type numberLazyAny struct { - baseAny - cfg *frozenConfig - buf []byte - err error -} - -func (any *numberLazyAny) ValueType() ValueType { - return NumberValue -} - -func (any *numberLazyAny) MustBeValid() Any { - return any -} - -func (any *numberLazyAny) LastError() error { - return any.err -} - -func (any *numberLazyAny) ToBool() bool { - return any.ToFloat64() != 0 -} - -func (any *numberLazyAny) ToInt() int { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadInt() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToInt32() int32 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadInt32() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToInt64() int64 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadInt64() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToUint() uint { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadUint() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToUint32() uint32 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadUint32() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToUint64() uint64 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadUint64() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToFloat32() float32 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadFloat32() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToFloat64() float64 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadFloat64() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToString() string { - return *(*string)(unsafe.Pointer(&any.buf)) -} - -func (any *numberLazyAny) WriteTo(stream *Stream) { - stream.Write(any.buf) -} - -func (any *numberLazyAny) GetInterface() interface{} { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - return iter.Read() -} diff --git a/vendor/github.com/json-iterator/go/any_object.go b/vendor/github.com/json-iterator/go/any_object.go deleted file mode 100644 index c44ef5c98..000000000 --- a/vendor/github.com/json-iterator/go/any_object.go +++ /dev/null @@ -1,374 +0,0 @@ -package jsoniter - -import ( - "reflect" - "unsafe" -) - -type objectLazyAny struct { - baseAny - cfg *frozenConfig - buf []byte - err error -} - -func (any *objectLazyAny) ValueType() ValueType { - return ObjectValue -} - -func (any *objectLazyAny) MustBeValid() Any { - return any -} - -func (any *objectLazyAny) LastError() error { - return any.err -} - -func (any *objectLazyAny) ToBool() bool { - return true -} - -func (any *objectLazyAny) ToInt() int { - return 0 -} - -func (any *objectLazyAny) ToInt32() int32 { - return 0 -} - -func (any *objectLazyAny) ToInt64() int64 { - return 0 -} - -func (any *objectLazyAny) ToUint() uint { - return 0 -} - -func (any *objectLazyAny) ToUint32() uint32 { - return 0 -} - -func (any *objectLazyAny) ToUint64() uint64 { - return 0 -} - -func (any *objectLazyAny) ToFloat32() float32 { - return 0 -} - -func (any *objectLazyAny) ToFloat64() float64 { - return 0 -} - -func (any *objectLazyAny) ToString() string { - return *(*string)(unsafe.Pointer(&any.buf)) -} - -func (any *objectLazyAny) ToVal(obj interface{}) { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadVal(obj) -} - -func (any *objectLazyAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - switch firstPath := path[0].(type) { - case string: - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - valueBytes := locateObjectField(iter, firstPath) - if valueBytes == nil { - return newInvalidAny(path) - } - iter.ResetBytes(valueBytes) - return locatePath(iter, path[1:]) - case int32: - if '*' == firstPath { - mappedAll := map[string]Any{} - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadMapCB(func(iter *Iterator, field string) bool { - mapped := locatePath(iter, path[1:]) - if mapped.ValueType() != InvalidValue { - mappedAll[field] = mapped - } - return true - }) - return wrapMap(mappedAll) - } - return newInvalidAny(path) - default: - return newInvalidAny(path) - } -} - -func (any *objectLazyAny) Keys() []string { - keys := []string{} - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadMapCB(func(iter *Iterator, field string) bool { - iter.Skip() - keys = append(keys, field) - return true - }) - return keys -} - -func (any *objectLazyAny) Size() int { - size := 0 - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadObjectCB(func(iter *Iterator, field string) bool { - iter.Skip() - size++ - return true - }) - return size -} - -func (any *objectLazyAny) WriteTo(stream *Stream) { - stream.Write(any.buf) -} - -func (any *objectLazyAny) GetInterface() interface{} { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - return iter.Read() -} - -type objectAny struct { - baseAny - err error - val reflect.Value -} - -func wrapStruct(val interface{}) *objectAny { - return &objectAny{baseAny{}, nil, reflect.ValueOf(val)} -} - -func (any *objectAny) ValueType() ValueType { - return ObjectValue -} - -func (any *objectAny) MustBeValid() Any { - return any -} - -func (any *objectAny) Parse() *Iterator { - return nil -} - -func (any *objectAny) LastError() error { - return any.err -} - -func (any *objectAny) ToBool() bool { - return any.val.NumField() != 0 -} - -func (any *objectAny) ToInt() int { - return 0 -} - -func (any *objectAny) ToInt32() int32 { - return 0 -} - -func (any *objectAny) ToInt64() int64 { - return 0 -} - -func (any *objectAny) ToUint() uint { - return 0 -} - -func (any *objectAny) ToUint32() uint32 { - return 0 -} - -func (any *objectAny) ToUint64() uint64 { - return 0 -} - -func (any *objectAny) ToFloat32() float32 { - return 0 -} - -func (any *objectAny) ToFloat64() float64 { - return 0 -} - -func (any *objectAny) ToString() string { - str, err := MarshalToString(any.val.Interface()) - any.err = err - return str -} - -func (any *objectAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - switch firstPath := path[0].(type) { - case string: - field := any.val.FieldByName(firstPath) - if !field.IsValid() { - return newInvalidAny(path) - } - return Wrap(field.Interface()) - case int32: - if '*' == firstPath { - mappedAll := map[string]Any{} - for i := 0; i < any.val.NumField(); i++ { - field := any.val.Field(i) - if field.CanInterface() { - mapped := Wrap(field.Interface()).Get(path[1:]...) - if mapped.ValueType() != InvalidValue { - mappedAll[any.val.Type().Field(i).Name] = mapped - } - } - } - return wrapMap(mappedAll) - } - return newInvalidAny(path) - default: - return newInvalidAny(path) - } -} - -func (any *objectAny) Keys() []string { - keys := make([]string, 0, any.val.NumField()) - for i := 0; i < any.val.NumField(); i++ { - keys = append(keys, any.val.Type().Field(i).Name) - } - return keys -} - -func (any *objectAny) Size() int { - return any.val.NumField() -} - -func (any *objectAny) WriteTo(stream *Stream) { - stream.WriteVal(any.val) -} - -func (any *objectAny) GetInterface() interface{} { - return any.val.Interface() -} - -type mapAny struct { - baseAny - err error - val reflect.Value -} - -func wrapMap(val interface{}) *mapAny { - return &mapAny{baseAny{}, nil, reflect.ValueOf(val)} -} - -func (any *mapAny) ValueType() ValueType { - return ObjectValue -} - -func (any *mapAny) MustBeValid() Any { - return any -} - -func (any *mapAny) Parse() *Iterator { - return nil -} - -func (any *mapAny) LastError() error { - return any.err -} - -func (any *mapAny) ToBool() bool { - return true -} - -func (any *mapAny) ToInt() int { - return 0 -} - -func (any *mapAny) ToInt32() int32 { - return 0 -} - -func (any *mapAny) ToInt64() int64 { - return 0 -} - -func (any *mapAny) ToUint() uint { - return 0 -} - -func (any *mapAny) ToUint32() uint32 { - return 0 -} - -func (any *mapAny) ToUint64() uint64 { - return 0 -} - -func (any *mapAny) ToFloat32() float32 { - return 0 -} - -func (any *mapAny) ToFloat64() float64 { - return 0 -} - -func (any *mapAny) ToString() string { - str, err := MarshalToString(any.val.Interface()) - any.err = err - return str -} - -func (any *mapAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - switch firstPath := path[0].(type) { - case int32: - if '*' == firstPath { - mappedAll := map[string]Any{} - for _, key := range any.val.MapKeys() { - keyAsStr := key.String() - element := Wrap(any.val.MapIndex(key).Interface()) - mapped := element.Get(path[1:]...) - if mapped.ValueType() != InvalidValue { - mappedAll[keyAsStr] = mapped - } - } - return wrapMap(mappedAll) - } - return newInvalidAny(path) - default: - value := any.val.MapIndex(reflect.ValueOf(firstPath)) - if !value.IsValid() { - return newInvalidAny(path) - } - return Wrap(value.Interface()) - } -} - -func (any *mapAny) Keys() []string { - keys := make([]string, 0, any.val.Len()) - for _, key := range any.val.MapKeys() { - keys = append(keys, key.String()) - } - return keys -} - -func (any *mapAny) Size() int { - return any.val.Len() -} - -func (any *mapAny) WriteTo(stream *Stream) { - stream.WriteVal(any.val) -} - -func (any *mapAny) GetInterface() interface{} { - return any.val.Interface() -} diff --git a/vendor/github.com/json-iterator/go/any_str.go b/vendor/github.com/json-iterator/go/any_str.go deleted file mode 100644 index 1f12f6612..000000000 --- a/vendor/github.com/json-iterator/go/any_str.go +++ /dev/null @@ -1,166 +0,0 @@ -package jsoniter - -import ( - "fmt" - "strconv" -) - -type stringAny struct { - baseAny - val string -} - -func (any *stringAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} -} - -func (any *stringAny) Parse() *Iterator { - return nil -} - -func (any *stringAny) ValueType() ValueType { - return StringValue -} - -func (any *stringAny) MustBeValid() Any { - return any -} - -func (any *stringAny) LastError() error { - return nil -} - -func (any *stringAny) ToBool() bool { - str := any.ToString() - if str == "0" { - return false - } - for _, c := range str { - switch c { - case ' ', '\n', '\r', '\t': - default: - return true - } - } - return false -} - -func (any *stringAny) ToInt() int { - return int(any.ToInt64()) - -} - -func (any *stringAny) ToInt32() int32 { - return int32(any.ToInt64()) -} - -func (any *stringAny) ToInt64() int64 { - if any.val == "" { - return 0 - } - - flag := 1 - startPos := 0 - if any.val[0] == '+' || any.val[0] == '-' { - startPos = 1 - } - - if any.val[0] == '-' { - flag = -1 - } - - endPos := startPos - for i := startPos; i < len(any.val); i++ { - if any.val[i] >= '0' && any.val[i] <= '9' { - endPos = i + 1 - } else { - break - } - } - parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64) - return int64(flag) * parsed -} - -func (any *stringAny) ToUint() uint { - return uint(any.ToUint64()) -} - -func (any *stringAny) ToUint32() uint32 { - return uint32(any.ToUint64()) -} - -func (any *stringAny) ToUint64() uint64 { - if any.val == "" { - return 0 - } - - startPos := 0 - - if any.val[0] == '-' { - return 0 - } - if any.val[0] == '+' { - startPos = 1 - } - - endPos := startPos - for i := startPos; i < len(any.val); i++ { - if any.val[i] >= '0' && any.val[i] <= '9' { - endPos = i + 1 - } else { - break - } - } - parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64) - return parsed -} - -func (any *stringAny) ToFloat32() float32 { - return float32(any.ToFloat64()) -} - -func (any *stringAny) ToFloat64() float64 { - if len(any.val) == 0 { - return 0 - } - - // first char invalid - if any.val[0] != '+' && any.val[0] != '-' && (any.val[0] > '9' || any.val[0] < '0') { - return 0 - } - - // extract valid num expression from string - // eg 123true => 123, -12.12xxa => -12.12 - endPos := 1 - for i := 1; i < len(any.val); i++ { - if any.val[i] == '.' || any.val[i] == 'e' || any.val[i] == 'E' || any.val[i] == '+' || any.val[i] == '-' { - endPos = i + 1 - continue - } - - // end position is the first char which is not digit - if any.val[i] >= '0' && any.val[i] <= '9' { - endPos = i + 1 - } else { - endPos = i - break - } - } - parsed, _ := strconv.ParseFloat(any.val[:endPos], 64) - return parsed -} - -func (any *stringAny) ToString() string { - return any.val -} - -func (any *stringAny) WriteTo(stream *Stream) { - stream.WriteString(any.val) -} - -func (any *stringAny) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/any_uint32.go b/vendor/github.com/json-iterator/go/any_uint32.go deleted file mode 100644 index 656bbd33d..000000000 --- a/vendor/github.com/json-iterator/go/any_uint32.go +++ /dev/null @@ -1,74 +0,0 @@ -package jsoniter - -import ( - "strconv" -) - -type uint32Any struct { - baseAny - val uint32 -} - -func (any *uint32Any) LastError() error { - return nil -} - -func (any *uint32Any) ValueType() ValueType { - return NumberValue -} - -func (any *uint32Any) MustBeValid() Any { - return any -} - -func (any *uint32Any) ToBool() bool { - return any.val != 0 -} - -func (any *uint32Any) ToInt() int { - return int(any.val) -} - -func (any *uint32Any) ToInt32() int32 { - return int32(any.val) -} - -func (any *uint32Any) ToInt64() int64 { - return int64(any.val) -} - -func (any *uint32Any) ToUint() uint { - return uint(any.val) -} - -func (any *uint32Any) ToUint32() uint32 { - return any.val -} - -func (any *uint32Any) ToUint64() uint64 { - return uint64(any.val) -} - -func (any *uint32Any) ToFloat32() float32 { - return float32(any.val) -} - -func (any *uint32Any) ToFloat64() float64 { - return float64(any.val) -} - -func (any *uint32Any) ToString() string { - return strconv.FormatInt(int64(any.val), 10) -} - -func (any *uint32Any) WriteTo(stream *Stream) { - stream.WriteUint32(any.val) -} - -func (any *uint32Any) Parse() *Iterator { - return nil -} - -func (any *uint32Any) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/any_uint64.go b/vendor/github.com/json-iterator/go/any_uint64.go deleted file mode 100644 index 7df2fce33..000000000 --- a/vendor/github.com/json-iterator/go/any_uint64.go +++ /dev/null @@ -1,74 +0,0 @@ -package jsoniter - -import ( - "strconv" -) - -type uint64Any struct { - baseAny - val uint64 -} - -func (any *uint64Any) LastError() error { - return nil -} - -func (any *uint64Any) ValueType() ValueType { - return NumberValue -} - -func (any *uint64Any) MustBeValid() Any { - return any -} - -func (any *uint64Any) ToBool() bool { - return any.val != 0 -} - -func (any *uint64Any) ToInt() int { - return int(any.val) -} - -func (any *uint64Any) ToInt32() int32 { - return int32(any.val) -} - -func (any *uint64Any) ToInt64() int64 { - return int64(any.val) -} - -func (any *uint64Any) ToUint() uint { - return uint(any.val) -} - -func (any *uint64Any) ToUint32() uint32 { - return uint32(any.val) -} - -func (any *uint64Any) ToUint64() uint64 { - return any.val -} - -func (any *uint64Any) ToFloat32() float32 { - return float32(any.val) -} - -func (any *uint64Any) ToFloat64() float64 { - return float64(any.val) -} - -func (any *uint64Any) ToString() string { - return strconv.FormatUint(any.val, 10) -} - -func (any *uint64Any) WriteTo(stream *Stream) { - stream.WriteUint64(any.val) -} - -func (any *uint64Any) Parse() *Iterator { - return nil -} - -func (any *uint64Any) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/build.sh b/vendor/github.com/json-iterator/go/build.sh deleted file mode 100644 index b45ef6883..000000000 --- a/vendor/github.com/json-iterator/go/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -set -e -set -x - -if [ ! -d /tmp/build-golang/src/github.com/json-iterator ]; then - mkdir -p /tmp/build-golang/src/github.com/json-iterator - ln -s $PWD /tmp/build-golang/src/github.com/json-iterator/go -fi -export GOPATH=/tmp/build-golang -go get -u github.com/golang/dep/cmd/dep -cd /tmp/build-golang/src/github.com/json-iterator/go -exec $GOPATH/bin/dep ensure -update diff --git a/vendor/github.com/json-iterator/go/config.go b/vendor/github.com/json-iterator/go/config.go deleted file mode 100644 index 2adcdc3b7..000000000 --- a/vendor/github.com/json-iterator/go/config.go +++ /dev/null @@ -1,375 +0,0 @@ -package jsoniter - -import ( - "encoding/json" - "io" - "reflect" - "sync" - "unsafe" - - "github.com/modern-go/concurrent" - "github.com/modern-go/reflect2" -) - -// Config customize how the API should behave. -// The API is created from Config by Froze. -type Config struct { - IndentionStep int - MarshalFloatWith6Digits bool - EscapeHTML bool - SortMapKeys bool - UseNumber bool - DisallowUnknownFields bool - TagKey string - OnlyTaggedField bool - ValidateJsonRawMessage bool - ObjectFieldMustBeSimpleString bool - CaseSensitive bool -} - -// API the public interface of this package. -// Primary Marshal and Unmarshal. -type API interface { - IteratorPool - StreamPool - MarshalToString(v interface{}) (string, error) - Marshal(v interface{}) ([]byte, error) - MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) - UnmarshalFromString(str string, v interface{}) error - Unmarshal(data []byte, v interface{}) error - Get(data []byte, path ...interface{}) Any - NewEncoder(writer io.Writer) *Encoder - NewDecoder(reader io.Reader) *Decoder - Valid(data []byte) bool - RegisterExtension(extension Extension) - DecoderOf(typ reflect2.Type) ValDecoder - EncoderOf(typ reflect2.Type) ValEncoder -} - -// ConfigDefault the default API -var ConfigDefault = Config{ - EscapeHTML: true, -}.Froze() - -// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior -var ConfigCompatibleWithStandardLibrary = Config{ - EscapeHTML: true, - SortMapKeys: true, - ValidateJsonRawMessage: true, -}.Froze() - -// ConfigFastest marshals float with only 6 digits precision -var ConfigFastest = Config{ - EscapeHTML: false, - MarshalFloatWith6Digits: true, // will lose precession - ObjectFieldMustBeSimpleString: true, // do not unescape object field -}.Froze() - -type frozenConfig struct { - configBeforeFrozen Config - sortMapKeys bool - indentionStep int - objectFieldMustBeSimpleString bool - onlyTaggedField bool - disallowUnknownFields bool - decoderCache *concurrent.Map - encoderCache *concurrent.Map - encoderExtension Extension - decoderExtension Extension - extraExtensions []Extension - streamPool *sync.Pool - iteratorPool *sync.Pool - caseSensitive bool -} - -func (cfg *frozenConfig) initCache() { - cfg.decoderCache = concurrent.NewMap() - cfg.encoderCache = concurrent.NewMap() -} - -func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) { - cfg.decoderCache.Store(cacheKey, decoder) -} - -func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) { - cfg.encoderCache.Store(cacheKey, encoder) -} - -func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder { - decoder, found := cfg.decoderCache.Load(cacheKey) - if found { - return decoder.(ValDecoder) - } - return nil -} - -func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder { - encoder, found := cfg.encoderCache.Load(cacheKey) - if found { - return encoder.(ValEncoder) - } - return nil -} - -var cfgCache = concurrent.NewMap() - -func getFrozenConfigFromCache(cfg Config) *frozenConfig { - obj, found := cfgCache.Load(cfg) - if found { - return obj.(*frozenConfig) - } - return nil -} - -func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) { - cfgCache.Store(cfg, frozenConfig) -} - -// Froze forge API from config -func (cfg Config) Froze() API { - api := &frozenConfig{ - sortMapKeys: cfg.SortMapKeys, - indentionStep: cfg.IndentionStep, - objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString, - onlyTaggedField: cfg.OnlyTaggedField, - disallowUnknownFields: cfg.DisallowUnknownFields, - caseSensitive: cfg.CaseSensitive, - } - api.streamPool = &sync.Pool{ - New: func() interface{} { - return NewStream(api, nil, 512) - }, - } - api.iteratorPool = &sync.Pool{ - New: func() interface{} { - return NewIterator(api) - }, - } - api.initCache() - encoderExtension := EncoderExtension{} - decoderExtension := DecoderExtension{} - if cfg.MarshalFloatWith6Digits { - api.marshalFloatWith6Digits(encoderExtension) - } - if cfg.EscapeHTML { - api.escapeHTML(encoderExtension) - } - if cfg.UseNumber { - api.useNumber(decoderExtension) - } - if cfg.ValidateJsonRawMessage { - api.validateJsonRawMessage(encoderExtension) - } - api.encoderExtension = encoderExtension - api.decoderExtension = decoderExtension - api.configBeforeFrozen = cfg - return api -} - -func (cfg Config) frozeWithCacheReuse(extraExtensions []Extension) *frozenConfig { - api := getFrozenConfigFromCache(cfg) - if api != nil { - return api - } - api = cfg.Froze().(*frozenConfig) - for _, extension := range extraExtensions { - api.RegisterExtension(extension) - } - addFrozenConfigToCache(cfg, api) - return api -} - -func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) { - encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) { - rawMessage := *(*json.RawMessage)(ptr) - iter := cfg.BorrowIterator([]byte(rawMessage)) - defer cfg.ReturnIterator(iter) - iter.Read() - if iter.Error != nil && iter.Error != io.EOF { - stream.WriteRaw("null") - } else { - stream.WriteRaw(string(rawMessage)) - } - }, func(ptr unsafe.Pointer) bool { - return len(*((*json.RawMessage)(ptr))) == 0 - }} - extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder - extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder -} - -func (cfg *frozenConfig) useNumber(extension DecoderExtension) { - extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) { - exitingValue := *((*interface{})(ptr)) - if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr { - iter.ReadVal(exitingValue) - return - } - if iter.WhatIsNext() == NumberValue { - *((*interface{})(ptr)) = json.Number(iter.readNumberAsString()) - } else { - *((*interface{})(ptr)) = iter.Read() - } - }} -} -func (cfg *frozenConfig) getTagKey() string { - tagKey := cfg.configBeforeFrozen.TagKey - if tagKey == "" { - return "json" - } - return tagKey -} - -func (cfg *frozenConfig) RegisterExtension(extension Extension) { - cfg.extraExtensions = append(cfg.extraExtensions, extension) - copied := cfg.configBeforeFrozen - cfg.configBeforeFrozen = copied -} - -type lossyFloat32Encoder struct { -} - -func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteFloat32Lossy(*((*float32)(ptr))) -} - -func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool { - return *((*float32)(ptr)) == 0 -} - -type lossyFloat64Encoder struct { -} - -func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteFloat64Lossy(*((*float64)(ptr))) -} - -func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool { - return *((*float64)(ptr)) == 0 -} - -// EnableLossyFloatMarshalling keeps 10**(-6) precision -// for float variables for better performance. -func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) { - // for better performance - extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{} - extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{} -} - -type htmlEscapedStringEncoder struct { -} - -func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - str := *((*string)(ptr)) - stream.WriteStringWithHTMLEscaped(str) -} - -func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return *((*string)(ptr)) == "" -} - -func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) { - encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{} -} - -func (cfg *frozenConfig) cleanDecoders() { - typeDecoders = map[string]ValDecoder{} - fieldDecoders = map[string]ValDecoder{} - *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) -} - -func (cfg *frozenConfig) cleanEncoders() { - typeEncoders = map[string]ValEncoder{} - fieldEncoders = map[string]ValEncoder{} - *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) -} - -func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) { - stream := cfg.BorrowStream(nil) - defer cfg.ReturnStream(stream) - stream.WriteVal(v) - if stream.Error != nil { - return "", stream.Error - } - return string(stream.Buffer()), nil -} - -func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) { - stream := cfg.BorrowStream(nil) - defer cfg.ReturnStream(stream) - stream.WriteVal(v) - if stream.Error != nil { - return nil, stream.Error - } - result := stream.Buffer() - copied := make([]byte, len(result)) - copy(copied, result) - return copied, nil -} - -func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { - if prefix != "" { - panic("prefix is not supported") - } - for _, r := range indent { - if r != ' ' { - panic("indent can only be space") - } - } - newCfg := cfg.configBeforeFrozen - newCfg.IndentionStep = len(indent) - return newCfg.frozeWithCacheReuse(cfg.extraExtensions).Marshal(v) -} - -func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error { - data := []byte(str) - iter := cfg.BorrowIterator(data) - defer cfg.ReturnIterator(iter) - iter.ReadVal(v) - c := iter.nextToken() - if c == 0 { - if iter.Error == io.EOF { - return nil - } - return iter.Error - } - iter.ReportError("Unmarshal", "there are bytes left after unmarshal") - return iter.Error -} - -func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any { - iter := cfg.BorrowIterator(data) - defer cfg.ReturnIterator(iter) - return locatePath(iter, path) -} - -func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error { - iter := cfg.BorrowIterator(data) - defer cfg.ReturnIterator(iter) - iter.ReadVal(v) - c := iter.nextToken() - if c == 0 { - if iter.Error == io.EOF { - return nil - } - return iter.Error - } - iter.ReportError("Unmarshal", "there are bytes left after unmarshal") - return iter.Error -} - -func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder { - stream := NewStream(cfg, writer, 512) - return &Encoder{stream} -} - -func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder { - iter := Parse(cfg, reader, 512) - return &Decoder{iter} -} - -func (cfg *frozenConfig) Valid(data []byte) bool { - iter := cfg.BorrowIterator(data) - defer cfg.ReturnIterator(iter) - iter.Skip() - return iter.Error == nil -} diff --git a/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md b/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md deleted file mode 100644 index 3095662b0..000000000 --- a/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md +++ /dev/null @@ -1,7 +0,0 @@ -| json type \ dest type | bool | int | uint | float |string| -| --- | --- | --- | --- |--|--| -| number | positive => true
negative => true
zero => false| 23.2 => 23
-32.1 => -32| 12.1 => 12
-12.1 => 0|as normal|same as origin| -| string | empty string => false
string "0" => false
other strings => true | "123.32" => 123
"-123.4" => -123
"123.23xxxw" => 123
"abcde12" => 0
"-32.1" => -32| 13.2 => 13
-1.1 => 0 |12.1 => 12.1
-12.3 => -12.3
12.4xxa => 12.4
+1.1e2 =>110 |same as origin| -| bool | true => true
false => false| true => 1
false => 0 | true => 1
false => 0 |true => 1
false => 0|true => "true"
false => "false"| -| object | true | 0 | 0 |0|originnal json| -| array | empty array => false
nonempty array => true| [] => 0
[1,2] => 1 | [] => 0
[1,2] => 1 |[] => 0
[1,2] => 1|original json| \ No newline at end of file diff --git a/vendor/github.com/json-iterator/go/iter.go b/vendor/github.com/json-iterator/go/iter.go deleted file mode 100644 index 29b31cf78..000000000 --- a/vendor/github.com/json-iterator/go/iter.go +++ /dev/null @@ -1,349 +0,0 @@ -package jsoniter - -import ( - "encoding/json" - "fmt" - "io" -) - -// ValueType the type for JSON element -type ValueType int - -const ( - // InvalidValue invalid JSON element - InvalidValue ValueType = iota - // StringValue JSON element "string" - StringValue - // NumberValue JSON element 100 or 0.10 - NumberValue - // NilValue JSON element null - NilValue - // BoolValue JSON element true or false - BoolValue - // ArrayValue JSON element [] - ArrayValue - // ObjectValue JSON element {} - ObjectValue -) - -var hexDigits []byte -var valueTypes []ValueType - -func init() { - hexDigits = make([]byte, 256) - for i := 0; i < len(hexDigits); i++ { - hexDigits[i] = 255 - } - for i := '0'; i <= '9'; i++ { - hexDigits[i] = byte(i - '0') - } - for i := 'a'; i <= 'f'; i++ { - hexDigits[i] = byte((i - 'a') + 10) - } - for i := 'A'; i <= 'F'; i++ { - hexDigits[i] = byte((i - 'A') + 10) - } - valueTypes = make([]ValueType, 256) - for i := 0; i < len(valueTypes); i++ { - valueTypes[i] = InvalidValue - } - valueTypes['"'] = StringValue - valueTypes['-'] = NumberValue - valueTypes['0'] = NumberValue - valueTypes['1'] = NumberValue - valueTypes['2'] = NumberValue - valueTypes['3'] = NumberValue - valueTypes['4'] = NumberValue - valueTypes['5'] = NumberValue - valueTypes['6'] = NumberValue - valueTypes['7'] = NumberValue - valueTypes['8'] = NumberValue - valueTypes['9'] = NumberValue - valueTypes['t'] = BoolValue - valueTypes['f'] = BoolValue - valueTypes['n'] = NilValue - valueTypes['['] = ArrayValue - valueTypes['{'] = ObjectValue -} - -// Iterator is a io.Reader like object, with JSON specific read functions. -// Error is not returned as return value, but stored as Error member on this iterator instance. -type Iterator struct { - cfg *frozenConfig - reader io.Reader - buf []byte - head int - tail int - depth int - captureStartedAt int - captured []byte - Error error - Attachment interface{} // open for customized decoder -} - -// NewIterator creates an empty Iterator instance -func NewIterator(cfg API) *Iterator { - return &Iterator{ - cfg: cfg.(*frozenConfig), - reader: nil, - buf: nil, - head: 0, - tail: 0, - depth: 0, - } -} - -// Parse creates an Iterator instance from io.Reader -func Parse(cfg API, reader io.Reader, bufSize int) *Iterator { - return &Iterator{ - cfg: cfg.(*frozenConfig), - reader: reader, - buf: make([]byte, bufSize), - head: 0, - tail: 0, - depth: 0, - } -} - -// ParseBytes creates an Iterator instance from byte array -func ParseBytes(cfg API, input []byte) *Iterator { - return &Iterator{ - cfg: cfg.(*frozenConfig), - reader: nil, - buf: input, - head: 0, - tail: len(input), - depth: 0, - } -} - -// ParseString creates an Iterator instance from string -func ParseString(cfg API, input string) *Iterator { - return ParseBytes(cfg, []byte(input)) -} - -// Pool returns a pool can provide more iterator with same configuration -func (iter *Iterator) Pool() IteratorPool { - return iter.cfg -} - -// Reset reuse iterator instance by specifying another reader -func (iter *Iterator) Reset(reader io.Reader) *Iterator { - iter.reader = reader - iter.head = 0 - iter.tail = 0 - iter.depth = 0 - return iter -} - -// ResetBytes reuse iterator instance by specifying another byte array as input -func (iter *Iterator) ResetBytes(input []byte) *Iterator { - iter.reader = nil - iter.buf = input - iter.head = 0 - iter.tail = len(input) - iter.depth = 0 - return iter -} - -// WhatIsNext gets ValueType of relatively next json element -func (iter *Iterator) WhatIsNext() ValueType { - valueType := valueTypes[iter.nextToken()] - iter.unreadByte() - return valueType -} - -func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - switch c { - case ' ', '\n', '\t', '\r': - continue - } - iter.head = i - return false - } - return true -} - -func (iter *Iterator) isObjectEnd() bool { - c := iter.nextToken() - if c == ',' { - return false - } - if c == '}' { - return true - } - iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c})) - return true -} - -func (iter *Iterator) nextToken() byte { - // a variation of skip whitespaces, returning the next non-whitespace token - for { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - switch c { - case ' ', '\n', '\t', '\r': - continue - } - iter.head = i + 1 - return c - } - if !iter.loadMore() { - return 0 - } - } -} - -// ReportError record a error in iterator instance with current position. -func (iter *Iterator) ReportError(operation string, msg string) { - if iter.Error != nil { - if iter.Error != io.EOF { - return - } - } - peekStart := iter.head - 10 - if peekStart < 0 { - peekStart = 0 - } - peekEnd := iter.head + 10 - if peekEnd > iter.tail { - peekEnd = iter.tail - } - parsing := string(iter.buf[peekStart:peekEnd]) - contextStart := iter.head - 50 - if contextStart < 0 { - contextStart = 0 - } - contextEnd := iter.head + 50 - if contextEnd > iter.tail { - contextEnd = iter.tail - } - context := string(iter.buf[contextStart:contextEnd]) - iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...", - operation, msg, iter.head-peekStart, parsing, context) -} - -// CurrentBuffer gets current buffer as string for debugging purpose -func (iter *Iterator) CurrentBuffer() string { - peekStart := iter.head - 10 - if peekStart < 0 { - peekStart = 0 - } - return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head, - string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) -} - -func (iter *Iterator) readByte() (ret byte) { - if iter.head == iter.tail { - if iter.loadMore() { - ret = iter.buf[iter.head] - iter.head++ - return ret - } - return 0 - } - ret = iter.buf[iter.head] - iter.head++ - return ret -} - -func (iter *Iterator) loadMore() bool { - if iter.reader == nil { - if iter.Error == nil { - iter.head = iter.tail - iter.Error = io.EOF - } - return false - } - if iter.captured != nil { - iter.captured = append(iter.captured, - iter.buf[iter.captureStartedAt:iter.tail]...) - iter.captureStartedAt = 0 - } - for { - n, err := iter.reader.Read(iter.buf) - if n == 0 { - if err != nil { - if iter.Error == nil { - iter.Error = err - } - return false - } - } else { - iter.head = 0 - iter.tail = n - return true - } - } -} - -func (iter *Iterator) unreadByte() { - if iter.Error != nil { - return - } - iter.head-- - return -} - -// Read read the next JSON element as generic interface{}. -func (iter *Iterator) Read() interface{} { - valueType := iter.WhatIsNext() - switch valueType { - case StringValue: - return iter.ReadString() - case NumberValue: - if iter.cfg.configBeforeFrozen.UseNumber { - return json.Number(iter.readNumberAsString()) - } - return iter.ReadFloat64() - case NilValue: - iter.skipFourBytes('n', 'u', 'l', 'l') - return nil - case BoolValue: - return iter.ReadBool() - case ArrayValue: - arr := []interface{}{} - iter.ReadArrayCB(func(iter *Iterator) bool { - var elem interface{} - iter.ReadVal(&elem) - arr = append(arr, elem) - return true - }) - return arr - case ObjectValue: - obj := map[string]interface{}{} - iter.ReadMapCB(func(Iter *Iterator, field string) bool { - var elem interface{} - iter.ReadVal(&elem) - obj[field] = elem - return true - }) - return obj - default: - iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType)) - return nil - } -} - -// limit maximum depth of nesting, as allowed by https://tools.ietf.org/html/rfc7159#section-9 -const maxDepth = 10000 - -func (iter *Iterator) incrementDepth() (success bool) { - iter.depth++ - if iter.depth <= maxDepth { - return true - } - iter.ReportError("incrementDepth", "exceeded max depth") - return false -} - -func (iter *Iterator) decrementDepth() (success bool) { - iter.depth-- - if iter.depth >= 0 { - return true - } - iter.ReportError("decrementDepth", "unexpected negative nesting") - return false -} diff --git a/vendor/github.com/json-iterator/go/iter_array.go b/vendor/github.com/json-iterator/go/iter_array.go deleted file mode 100644 index 204fe0e09..000000000 --- a/vendor/github.com/json-iterator/go/iter_array.go +++ /dev/null @@ -1,64 +0,0 @@ -package jsoniter - -// ReadArray read array element, tells if the array has more element to read. -func (iter *Iterator) ReadArray() (ret bool) { - c := iter.nextToken() - switch c { - case 'n': - iter.skipThreeBytes('u', 'l', 'l') - return false // null - case '[': - c = iter.nextToken() - if c != ']' { - iter.unreadByte() - return true - } - return false - case ']': - return false - case ',': - return true - default: - iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c})) - return - } -} - -// ReadArrayCB read array with callback -func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { - c := iter.nextToken() - if c == '[' { - if !iter.incrementDepth() { - return false - } - c = iter.nextToken() - if c != ']' { - iter.unreadByte() - if !callback(iter) { - iter.decrementDepth() - return false - } - c = iter.nextToken() - for c == ',' { - if !callback(iter) { - iter.decrementDepth() - return false - } - c = iter.nextToken() - } - if c != ']' { - iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c})) - iter.decrementDepth() - return false - } - return iter.decrementDepth() - } - return iter.decrementDepth() - } - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return true // null - } - iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c})) - return false -} diff --git a/vendor/github.com/json-iterator/go/iter_float.go b/vendor/github.com/json-iterator/go/iter_float.go deleted file mode 100644 index 8a3d8b6fb..000000000 --- a/vendor/github.com/json-iterator/go/iter_float.go +++ /dev/null @@ -1,342 +0,0 @@ -package jsoniter - -import ( - "encoding/json" - "io" - "math/big" - "strconv" - "strings" - "unsafe" -) - -var floatDigits []int8 - -const invalidCharForNumber = int8(-1) -const endOfNumber = int8(-2) -const dotInNumber = int8(-3) - -func init() { - floatDigits = make([]int8, 256) - for i := 0; i < len(floatDigits); i++ { - floatDigits[i] = invalidCharForNumber - } - for i := int8('0'); i <= int8('9'); i++ { - floatDigits[i] = i - int8('0') - } - floatDigits[','] = endOfNumber - floatDigits[']'] = endOfNumber - floatDigits['}'] = endOfNumber - floatDigits[' '] = endOfNumber - floatDigits['\t'] = endOfNumber - floatDigits['\n'] = endOfNumber - floatDigits['.'] = dotInNumber -} - -// ReadBigFloat read big.Float -func (iter *Iterator) ReadBigFloat() (ret *big.Float) { - str := iter.readNumberAsString() - if iter.Error != nil && iter.Error != io.EOF { - return nil - } - prec := 64 - if len(str) > prec { - prec = len(str) - } - val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero) - if err != nil { - iter.Error = err - return nil - } - return val -} - -// ReadBigInt read big.Int -func (iter *Iterator) ReadBigInt() (ret *big.Int) { - str := iter.readNumberAsString() - if iter.Error != nil && iter.Error != io.EOF { - return nil - } - ret = big.NewInt(0) - var success bool - ret, success = ret.SetString(str, 10) - if !success { - iter.ReportError("ReadBigInt", "invalid big int") - return nil - } - return ret -} - -//ReadFloat32 read float32 -func (iter *Iterator) ReadFloat32() (ret float32) { - c := iter.nextToken() - if c == '-' { - return -iter.readPositiveFloat32() - } - iter.unreadByte() - return iter.readPositiveFloat32() -} - -func (iter *Iterator) readPositiveFloat32() (ret float32) { - i := iter.head - // first char - if i == iter.tail { - return iter.readFloat32SlowPath() - } - c := iter.buf[i] - i++ - ind := floatDigits[c] - switch ind { - case invalidCharForNumber: - return iter.readFloat32SlowPath() - case endOfNumber: - iter.ReportError("readFloat32", "empty number") - return - case dotInNumber: - iter.ReportError("readFloat32", "leading dot is invalid") - return - case 0: - if i == iter.tail { - return iter.readFloat32SlowPath() - } - c = iter.buf[i] - switch c { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - iter.ReportError("readFloat32", "leading zero is invalid") - return - } - } - value := uint64(ind) - // chars before dot -non_decimal_loop: - for ; i < iter.tail; i++ { - c = iter.buf[i] - ind := floatDigits[c] - switch ind { - case invalidCharForNumber: - return iter.readFloat32SlowPath() - case endOfNumber: - iter.head = i - return float32(value) - case dotInNumber: - break non_decimal_loop - } - if value > uint64SafeToMultiple10 { - return iter.readFloat32SlowPath() - } - value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; - } - // chars after dot - if c == '.' { - i++ - decimalPlaces := 0 - if i == iter.tail { - return iter.readFloat32SlowPath() - } - for ; i < iter.tail; i++ { - c = iter.buf[i] - ind := floatDigits[c] - switch ind { - case endOfNumber: - if decimalPlaces > 0 && decimalPlaces < len(pow10) { - iter.head = i - return float32(float64(value) / float64(pow10[decimalPlaces])) - } - // too many decimal places - return iter.readFloat32SlowPath() - case invalidCharForNumber, dotInNumber: - return iter.readFloat32SlowPath() - } - decimalPlaces++ - if value > uint64SafeToMultiple10 { - return iter.readFloat32SlowPath() - } - value = (value << 3) + (value << 1) + uint64(ind) - } - } - return iter.readFloat32SlowPath() -} - -func (iter *Iterator) readNumberAsString() (ret string) { - strBuf := [16]byte{} - str := strBuf[0:0] -load_loop: - for { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - switch c { - case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - str = append(str, c) - continue - default: - iter.head = i - break load_loop - } - } - if !iter.loadMore() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - return - } - if len(str) == 0 { - iter.ReportError("readNumberAsString", "invalid number") - } - return *(*string)(unsafe.Pointer(&str)) -} - -func (iter *Iterator) readFloat32SlowPath() (ret float32) { - str := iter.readNumberAsString() - if iter.Error != nil && iter.Error != io.EOF { - return - } - errMsg := validateFloat(str) - if errMsg != "" { - iter.ReportError("readFloat32SlowPath", errMsg) - return - } - val, err := strconv.ParseFloat(str, 32) - if err != nil { - iter.Error = err - return - } - return float32(val) -} - -// ReadFloat64 read float64 -func (iter *Iterator) ReadFloat64() (ret float64) { - c := iter.nextToken() - if c == '-' { - return -iter.readPositiveFloat64() - } - iter.unreadByte() - return iter.readPositiveFloat64() -} - -func (iter *Iterator) readPositiveFloat64() (ret float64) { - i := iter.head - // first char - if i == iter.tail { - return iter.readFloat64SlowPath() - } - c := iter.buf[i] - i++ - ind := floatDigits[c] - switch ind { - case invalidCharForNumber: - return iter.readFloat64SlowPath() - case endOfNumber: - iter.ReportError("readFloat64", "empty number") - return - case dotInNumber: - iter.ReportError("readFloat64", "leading dot is invalid") - return - case 0: - if i == iter.tail { - return iter.readFloat64SlowPath() - } - c = iter.buf[i] - switch c { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - iter.ReportError("readFloat64", "leading zero is invalid") - return - } - } - value := uint64(ind) - // chars before dot -non_decimal_loop: - for ; i < iter.tail; i++ { - c = iter.buf[i] - ind := floatDigits[c] - switch ind { - case invalidCharForNumber: - return iter.readFloat64SlowPath() - case endOfNumber: - iter.head = i - return float64(value) - case dotInNumber: - break non_decimal_loop - } - if value > uint64SafeToMultiple10 { - return iter.readFloat64SlowPath() - } - value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; - } - // chars after dot - if c == '.' { - i++ - decimalPlaces := 0 - if i == iter.tail { - return iter.readFloat64SlowPath() - } - for ; i < iter.tail; i++ { - c = iter.buf[i] - ind := floatDigits[c] - switch ind { - case endOfNumber: - if decimalPlaces > 0 && decimalPlaces < len(pow10) { - iter.head = i - return float64(value) / float64(pow10[decimalPlaces]) - } - // too many decimal places - return iter.readFloat64SlowPath() - case invalidCharForNumber, dotInNumber: - return iter.readFloat64SlowPath() - } - decimalPlaces++ - if value > uint64SafeToMultiple10 { - return iter.readFloat64SlowPath() - } - value = (value << 3) + (value << 1) + uint64(ind) - if value > maxFloat64 { - return iter.readFloat64SlowPath() - } - } - } - return iter.readFloat64SlowPath() -} - -func (iter *Iterator) readFloat64SlowPath() (ret float64) { - str := iter.readNumberAsString() - if iter.Error != nil && iter.Error != io.EOF { - return - } - errMsg := validateFloat(str) - if errMsg != "" { - iter.ReportError("readFloat64SlowPath", errMsg) - return - } - val, err := strconv.ParseFloat(str, 64) - if err != nil { - iter.Error = err - return - } - return val -} - -func validateFloat(str string) string { - // strconv.ParseFloat is not validating `1.` or `1.e1` - if len(str) == 0 { - return "empty number" - } - if str[0] == '-' { - return "-- is not valid" - } - dotPos := strings.IndexByte(str, '.') - if dotPos != -1 { - if dotPos == len(str)-1 { - return "dot can not be last character" - } - switch str[dotPos+1] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - default: - return "missing digit after dot" - } - } - return "" -} - -// ReadNumber read json.Number -func (iter *Iterator) ReadNumber() (ret json.Number) { - return json.Number(iter.readNumberAsString()) -} diff --git a/vendor/github.com/json-iterator/go/iter_int.go b/vendor/github.com/json-iterator/go/iter_int.go deleted file mode 100644 index d786a89fe..000000000 --- a/vendor/github.com/json-iterator/go/iter_int.go +++ /dev/null @@ -1,346 +0,0 @@ -package jsoniter - -import ( - "math" - "strconv" -) - -var intDigits []int8 - -const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1 -const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1 -const maxFloat64 = 1<<53 - 1 - -func init() { - intDigits = make([]int8, 256) - for i := 0; i < len(intDigits); i++ { - intDigits[i] = invalidCharForNumber - } - for i := int8('0'); i <= int8('9'); i++ { - intDigits[i] = i - int8('0') - } -} - -// ReadUint read uint -func (iter *Iterator) ReadUint() uint { - if strconv.IntSize == 32 { - return uint(iter.ReadUint32()) - } - return uint(iter.ReadUint64()) -} - -// ReadInt read int -func (iter *Iterator) ReadInt() int { - if strconv.IntSize == 32 { - return int(iter.ReadInt32()) - } - return int(iter.ReadInt64()) -} - -// ReadInt8 read int8 -func (iter *Iterator) ReadInt8() (ret int8) { - c := iter.nextToken() - if c == '-' { - val := iter.readUint32(iter.readByte()) - if val > math.MaxInt8+1 { - iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return -int8(val) - } - val := iter.readUint32(c) - if val > math.MaxInt8 { - iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return int8(val) -} - -// ReadUint8 read uint8 -func (iter *Iterator) ReadUint8() (ret uint8) { - val := iter.readUint32(iter.nextToken()) - if val > math.MaxUint8 { - iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return uint8(val) -} - -// ReadInt16 read int16 -func (iter *Iterator) ReadInt16() (ret int16) { - c := iter.nextToken() - if c == '-' { - val := iter.readUint32(iter.readByte()) - if val > math.MaxInt16+1 { - iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return -int16(val) - } - val := iter.readUint32(c) - if val > math.MaxInt16 { - iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return int16(val) -} - -// ReadUint16 read uint16 -func (iter *Iterator) ReadUint16() (ret uint16) { - val := iter.readUint32(iter.nextToken()) - if val > math.MaxUint16 { - iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return uint16(val) -} - -// ReadInt32 read int32 -func (iter *Iterator) ReadInt32() (ret int32) { - c := iter.nextToken() - if c == '-' { - val := iter.readUint32(iter.readByte()) - if val > math.MaxInt32+1 { - iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return -int32(val) - } - val := iter.readUint32(c) - if val > math.MaxInt32 { - iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return int32(val) -} - -// ReadUint32 read uint32 -func (iter *Iterator) ReadUint32() (ret uint32) { - return iter.readUint32(iter.nextToken()) -} - -func (iter *Iterator) readUint32(c byte) (ret uint32) { - ind := intDigits[c] - if ind == 0 { - iter.assertInteger() - return 0 // single zero - } - if ind == invalidCharForNumber { - iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)})) - return - } - value := uint32(ind) - if iter.tail-iter.head > 10 { - i := iter.head - ind2 := intDigits[iter.buf[i]] - if ind2 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value - } - i++ - ind3 := intDigits[iter.buf[i]] - if ind3 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*10 + uint32(ind2) - } - //iter.head = i + 1 - //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) - i++ - ind4 := intDigits[iter.buf[i]] - if ind4 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*100 + uint32(ind2)*10 + uint32(ind3) - } - i++ - ind5 := intDigits[iter.buf[i]] - if ind5 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4) - } - i++ - ind6 := intDigits[iter.buf[i]] - if ind6 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5) - } - i++ - ind7 := intDigits[iter.buf[i]] - if ind7 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6) - } - i++ - ind8 := intDigits[iter.buf[i]] - if ind8 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7) - } - i++ - ind9 := intDigits[iter.buf[i]] - value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8) - iter.head = i - if ind9 == invalidCharForNumber { - iter.assertInteger() - return value - } - } - for { - for i := iter.head; i < iter.tail; i++ { - ind = intDigits[iter.buf[i]] - if ind == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value - } - if value > uint32SafeToMultiply10 { - value2 := (value << 3) + (value << 1) + uint32(ind) - if value2 < value { - iter.ReportError("readUint32", "overflow") - return - } - value = value2 - continue - } - value = (value << 3) + (value << 1) + uint32(ind) - } - if !iter.loadMore() { - iter.assertInteger() - return value - } - } -} - -// ReadInt64 read int64 -func (iter *Iterator) ReadInt64() (ret int64) { - c := iter.nextToken() - if c == '-' { - val := iter.readUint64(iter.readByte()) - if val > math.MaxInt64+1 { - iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) - return - } - return -int64(val) - } - val := iter.readUint64(c) - if val > math.MaxInt64 { - iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) - return - } - return int64(val) -} - -// ReadUint64 read uint64 -func (iter *Iterator) ReadUint64() uint64 { - return iter.readUint64(iter.nextToken()) -} - -func (iter *Iterator) readUint64(c byte) (ret uint64) { - ind := intDigits[c] - if ind == 0 { - iter.assertInteger() - return 0 // single zero - } - if ind == invalidCharForNumber { - iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)})) - return - } - value := uint64(ind) - if iter.tail-iter.head > 10 { - i := iter.head - ind2 := intDigits[iter.buf[i]] - if ind2 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value - } - i++ - ind3 := intDigits[iter.buf[i]] - if ind3 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*10 + uint64(ind2) - } - //iter.head = i + 1 - //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) - i++ - ind4 := intDigits[iter.buf[i]] - if ind4 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*100 + uint64(ind2)*10 + uint64(ind3) - } - i++ - ind5 := intDigits[iter.buf[i]] - if ind5 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4) - } - i++ - ind6 := intDigits[iter.buf[i]] - if ind6 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5) - } - i++ - ind7 := intDigits[iter.buf[i]] - if ind7 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6) - } - i++ - ind8 := intDigits[iter.buf[i]] - if ind8 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7) - } - i++ - ind9 := intDigits[iter.buf[i]] - value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8) - iter.head = i - if ind9 == invalidCharForNumber { - iter.assertInteger() - return value - } - } - for { - for i := iter.head; i < iter.tail; i++ { - ind = intDigits[iter.buf[i]] - if ind == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value - } - if value > uint64SafeToMultiple10 { - value2 := (value << 3) + (value << 1) + uint64(ind) - if value2 < value { - iter.ReportError("readUint64", "overflow") - return - } - value = value2 - continue - } - value = (value << 3) + (value << 1) + uint64(ind) - } - if !iter.loadMore() { - iter.assertInteger() - return value - } - } -} - -func (iter *Iterator) assertInteger() { - if iter.head < iter.tail && iter.buf[iter.head] == '.' { - iter.ReportError("assertInteger", "can not decode float as int") - } -} diff --git a/vendor/github.com/json-iterator/go/iter_object.go b/vendor/github.com/json-iterator/go/iter_object.go deleted file mode 100644 index 58ee89c84..000000000 --- a/vendor/github.com/json-iterator/go/iter_object.go +++ /dev/null @@ -1,267 +0,0 @@ -package jsoniter - -import ( - "fmt" - "strings" -) - -// ReadObject read one field from object. -// If object ended, returns empty string. -// Otherwise, returns the field name. -func (iter *Iterator) ReadObject() (ret string) { - c := iter.nextToken() - switch c { - case 'n': - iter.skipThreeBytes('u', 'l', 'l') - return "" // null - case '{': - c = iter.nextToken() - if c == '"' { - iter.unreadByte() - field := iter.ReadString() - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - return field - } - if c == '}' { - return "" // end of object - } - iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) - return - case ',': - field := iter.ReadString() - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - return field - case '}': - return "" // end of object - default: - iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c}))) - return - } -} - -// CaseInsensitive -func (iter *Iterator) readFieldHash() int64 { - hash := int64(0x811c9dc5) - c := iter.nextToken() - if c != '"' { - iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) - return 0 - } - for { - for i := iter.head; i < iter.tail; i++ { - // require ascii string and no escape - b := iter.buf[i] - if b == '\\' { - iter.head = i - for _, b := range iter.readStringSlowPath() { - if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { - b += 'a' - 'A' - } - hash ^= int64(b) - hash *= 0x1000193 - } - c = iter.nextToken() - if c != ':' { - iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) - return 0 - } - return hash - } - if b == '"' { - iter.head = i + 1 - c = iter.nextToken() - if c != ':' { - iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) - return 0 - } - return hash - } - if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { - b += 'a' - 'A' - } - hash ^= int64(b) - hash *= 0x1000193 - } - if !iter.loadMore() { - iter.ReportError("readFieldHash", `incomplete field name`) - return 0 - } - } -} - -func calcHash(str string, caseSensitive bool) int64 { - if !caseSensitive { - str = strings.ToLower(str) - } - hash := int64(0x811c9dc5) - for _, b := range []byte(str) { - hash ^= int64(b) - hash *= 0x1000193 - } - return int64(hash) -} - -// ReadObjectCB read object with callback, the key is ascii only and field name not copied -func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { - c := iter.nextToken() - var field string - if c == '{' { - if !iter.incrementDepth() { - return false - } - c = iter.nextToken() - if c == '"' { - iter.unreadByte() - field = iter.ReadString() - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - if !callback(iter, field) { - iter.decrementDepth() - return false - } - c = iter.nextToken() - for c == ',' { - field = iter.ReadString() - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - if !callback(iter, field) { - iter.decrementDepth() - return false - } - c = iter.nextToken() - } - if c != '}' { - iter.ReportError("ReadObjectCB", `object not ended with }`) - iter.decrementDepth() - return false - } - return iter.decrementDepth() - } - if c == '}' { - return iter.decrementDepth() - } - iter.ReportError("ReadObjectCB", `expect " after {, but found `+string([]byte{c})) - iter.decrementDepth() - return false - } - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return true // null - } - iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) - return false -} - -// ReadMapCB read map with callback, the key can be any string -func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { - c := iter.nextToken() - if c == '{' { - if !iter.incrementDepth() { - return false - } - c = iter.nextToken() - if c == '"' { - iter.unreadByte() - field := iter.ReadString() - if iter.nextToken() != ':' { - iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) - iter.decrementDepth() - return false - } - if !callback(iter, field) { - iter.decrementDepth() - return false - } - c = iter.nextToken() - for c == ',' { - field = iter.ReadString() - if iter.nextToken() != ':' { - iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) - iter.decrementDepth() - return false - } - if !callback(iter, field) { - iter.decrementDepth() - return false - } - c = iter.nextToken() - } - if c != '}' { - iter.ReportError("ReadMapCB", `object not ended with }`) - iter.decrementDepth() - return false - } - return iter.decrementDepth() - } - if c == '}' { - return iter.decrementDepth() - } - iter.ReportError("ReadMapCB", `expect " after {, but found `+string([]byte{c})) - iter.decrementDepth() - return false - } - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return true // null - } - iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) - return false -} - -func (iter *Iterator) readObjectStart() bool { - c := iter.nextToken() - if c == '{' { - c = iter.nextToken() - if c == '}' { - return false - } - iter.unreadByte() - return true - } else if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return false - } - iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) - return false -} - -func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { - str := iter.ReadStringAsSlice() - if iter.skipWhitespacesWithoutLoadMore() { - if ret == nil { - ret = make([]byte, len(str)) - copy(ret, str) - } - if !iter.loadMore() { - return - } - } - if iter.buf[iter.head] != ':' { - iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) - return - } - iter.head++ - if iter.skipWhitespacesWithoutLoadMore() { - if ret == nil { - ret = make([]byte, len(str)) - copy(ret, str) - } - if !iter.loadMore() { - return - } - } - if ret == nil { - return str - } - return ret -} diff --git a/vendor/github.com/json-iterator/go/iter_skip.go b/vendor/github.com/json-iterator/go/iter_skip.go deleted file mode 100644 index e91eefb15..000000000 --- a/vendor/github.com/json-iterator/go/iter_skip.go +++ /dev/null @@ -1,130 +0,0 @@ -package jsoniter - -import "fmt" - -// ReadNil reads a json object as nil and -// returns whether it's a nil or not -func (iter *Iterator) ReadNil() (ret bool) { - c := iter.nextToken() - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') // null - return true - } - iter.unreadByte() - return false -} - -// ReadBool reads a json object as BoolValue -func (iter *Iterator) ReadBool() (ret bool) { - c := iter.nextToken() - if c == 't' { - iter.skipThreeBytes('r', 'u', 'e') - return true - } - if c == 'f' { - iter.skipFourBytes('a', 'l', 's', 'e') - return false - } - iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c})) - return -} - -// SkipAndReturnBytes skip next JSON element, and return its content as []byte. -// The []byte can be kept, it is a copy of data. -func (iter *Iterator) SkipAndReturnBytes() []byte { - iter.startCapture(iter.head) - iter.Skip() - return iter.stopCapture() -} - -// SkipAndAppendBytes skips next JSON element and appends its content to -// buffer, returning the result. -func (iter *Iterator) SkipAndAppendBytes(buf []byte) []byte { - iter.startCaptureTo(buf, iter.head) - iter.Skip() - return iter.stopCapture() -} - -func (iter *Iterator) startCaptureTo(buf []byte, captureStartedAt int) { - if iter.captured != nil { - panic("already in capture mode") - } - iter.captureStartedAt = captureStartedAt - iter.captured = buf -} - -func (iter *Iterator) startCapture(captureStartedAt int) { - iter.startCaptureTo(make([]byte, 0, 32), captureStartedAt) -} - -func (iter *Iterator) stopCapture() []byte { - if iter.captured == nil { - panic("not in capture mode") - } - captured := iter.captured - remaining := iter.buf[iter.captureStartedAt:iter.head] - iter.captureStartedAt = -1 - iter.captured = nil - return append(captured, remaining...) -} - -// Skip skips a json object and positions to relatively the next json object -func (iter *Iterator) Skip() { - c := iter.nextToken() - switch c { - case '"': - iter.skipString() - case 'n': - iter.skipThreeBytes('u', 'l', 'l') // null - case 't': - iter.skipThreeBytes('r', 'u', 'e') // true - case 'f': - iter.skipFourBytes('a', 'l', 's', 'e') // false - case '0': - iter.unreadByte() - iter.ReadFloat32() - case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': - iter.skipNumber() - case '[': - iter.skipArray() - case '{': - iter.skipObject() - default: - iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c)) - return - } -} - -func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) { - if iter.readByte() != b1 { - iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) - return - } - if iter.readByte() != b2 { - iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) - return - } - if iter.readByte() != b3 { - iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) - return - } - if iter.readByte() != b4 { - iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) - return - } -} - -func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) { - if iter.readByte() != b1 { - iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) - return - } - if iter.readByte() != b2 { - iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) - return - } - if iter.readByte() != b3 { - iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) - return - } -} diff --git a/vendor/github.com/json-iterator/go/iter_skip_sloppy.go b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go deleted file mode 100644 index 9303de41e..000000000 --- a/vendor/github.com/json-iterator/go/iter_skip_sloppy.go +++ /dev/null @@ -1,163 +0,0 @@ -//+build jsoniter_sloppy - -package jsoniter - -// sloppy but faster implementation, do not validate the input json - -func (iter *Iterator) skipNumber() { - for { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - switch c { - case ' ', '\n', '\r', '\t', ',', '}', ']': - iter.head = i - return - } - } - if !iter.loadMore() { - return - } - } -} - -func (iter *Iterator) skipArray() { - level := 1 - if !iter.incrementDepth() { - return - } - for { - for i := iter.head; i < iter.tail; i++ { - switch iter.buf[i] { - case '"': // If inside string, skip it - iter.head = i + 1 - iter.skipString() - i = iter.head - 1 // it will be i++ soon - case '[': // If open symbol, increase level - level++ - if !iter.incrementDepth() { - return - } - case ']': // If close symbol, increase level - level-- - if !iter.decrementDepth() { - return - } - - // If we have returned to the original level, we're done - if level == 0 { - iter.head = i + 1 - return - } - } - } - if !iter.loadMore() { - iter.ReportError("skipObject", "incomplete array") - return - } - } -} - -func (iter *Iterator) skipObject() { - level := 1 - if !iter.incrementDepth() { - return - } - - for { - for i := iter.head; i < iter.tail; i++ { - switch iter.buf[i] { - case '"': // If inside string, skip it - iter.head = i + 1 - iter.skipString() - i = iter.head - 1 // it will be i++ soon - case '{': // If open symbol, increase level - level++ - if !iter.incrementDepth() { - return - } - case '}': // If close symbol, increase level - level-- - if !iter.decrementDepth() { - return - } - - // If we have returned to the original level, we're done - if level == 0 { - iter.head = i + 1 - return - } - } - } - if !iter.loadMore() { - iter.ReportError("skipObject", "incomplete object") - return - } - } -} - -func (iter *Iterator) skipString() { - for { - end, escaped := iter.findStringEnd() - if end == -1 { - if !iter.loadMore() { - iter.ReportError("skipString", "incomplete string") - return - } - if escaped { - iter.head = 1 // skip the first char as last char read is \ - } - } else { - iter.head = end - return - } - } -} - -// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go -// Tries to find the end of string -// Support if string contains escaped quote symbols. -func (iter *Iterator) findStringEnd() (int, bool) { - escaped := false - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - if c == '"' { - if !escaped { - return i + 1, false - } - j := i - 1 - for { - if j < iter.head || iter.buf[j] != '\\' { - // even number of backslashes - // either end of buffer, or " found - return i + 1, true - } - j-- - if j < iter.head || iter.buf[j] != '\\' { - // odd number of backslashes - // it is \" or \\\" - break - } - j-- - } - } else if c == '\\' { - escaped = true - } - } - j := iter.tail - 1 - for { - if j < iter.head || iter.buf[j] != '\\' { - // even number of backslashes - // either end of buffer, or " found - return -1, false // do not end with \ - } - j-- - if j < iter.head || iter.buf[j] != '\\' { - // odd number of backslashes - // it is \" or \\\" - break - } - j-- - - } - return -1, true // end with \ -} diff --git a/vendor/github.com/json-iterator/go/iter_skip_strict.go b/vendor/github.com/json-iterator/go/iter_skip_strict.go deleted file mode 100644 index 6cf66d043..000000000 --- a/vendor/github.com/json-iterator/go/iter_skip_strict.go +++ /dev/null @@ -1,99 +0,0 @@ -//+build !jsoniter_sloppy - -package jsoniter - -import ( - "fmt" - "io" -) - -func (iter *Iterator) skipNumber() { - if !iter.trySkipNumber() { - iter.unreadByte() - if iter.Error != nil && iter.Error != io.EOF { - return - } - iter.ReadFloat64() - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = nil - iter.ReadBigFloat() - } - } -} - -func (iter *Iterator) trySkipNumber() bool { - dotFound := false - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - switch c { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - case '.': - if dotFound { - iter.ReportError("validateNumber", `more than one dot found in number`) - return true // already failed - } - if i+1 == iter.tail { - return false - } - c = iter.buf[i+1] - switch c { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - default: - iter.ReportError("validateNumber", `missing digit after dot`) - return true // already failed - } - dotFound = true - default: - switch c { - case ',', ']', '}', ' ', '\t', '\n', '\r': - if iter.head == i { - return false // if - without following digits - } - iter.head = i - return true // must be valid - } - return false // may be invalid - } - } - return false -} - -func (iter *Iterator) skipString() { - if !iter.trySkipString() { - iter.unreadByte() - iter.ReadString() - } -} - -func (iter *Iterator) trySkipString() bool { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - if c == '"' { - iter.head = i + 1 - return true // valid - } else if c == '\\' { - return false - } else if c < ' ' { - iter.ReportError("trySkipString", - fmt.Sprintf(`invalid control character found: %d`, c)) - return true // already failed - } - } - return false -} - -func (iter *Iterator) skipObject() { - iter.unreadByte() - iter.ReadObjectCB(func(iter *Iterator, field string) bool { - iter.Skip() - return true - }) -} - -func (iter *Iterator) skipArray() { - iter.unreadByte() - iter.ReadArrayCB(func(iter *Iterator) bool { - iter.Skip() - return true - }) -} diff --git a/vendor/github.com/json-iterator/go/iter_str.go b/vendor/github.com/json-iterator/go/iter_str.go deleted file mode 100644 index adc487ea8..000000000 --- a/vendor/github.com/json-iterator/go/iter_str.go +++ /dev/null @@ -1,215 +0,0 @@ -package jsoniter - -import ( - "fmt" - "unicode/utf16" -) - -// ReadString read string from iterator -func (iter *Iterator) ReadString() (ret string) { - c := iter.nextToken() - if c == '"' { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - if c == '"' { - ret = string(iter.buf[iter.head:i]) - iter.head = i + 1 - return ret - } else if c == '\\' { - break - } else if c < ' ' { - iter.ReportError("ReadString", - fmt.Sprintf(`invalid control character found: %d`, c)) - return - } - } - return iter.readStringSlowPath() - } else if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return "" - } - iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c})) - return -} - -func (iter *Iterator) readStringSlowPath() (ret string) { - var str []byte - var c byte - for iter.Error == nil { - c = iter.readByte() - if c == '"' { - return string(str) - } - if c == '\\' { - c = iter.readByte() - str = iter.readEscapedChar(c, str) - } else { - str = append(str, c) - } - } - iter.ReportError("readStringSlowPath", "unexpected end of input") - return -} - -func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte { - switch c { - case 'u': - r := iter.readU4() - if utf16.IsSurrogate(r) { - c = iter.readByte() - if iter.Error != nil { - return nil - } - if c != '\\' { - iter.unreadByte() - str = appendRune(str, r) - return str - } - c = iter.readByte() - if iter.Error != nil { - return nil - } - if c != 'u' { - str = appendRune(str, r) - return iter.readEscapedChar(c, str) - } - r2 := iter.readU4() - if iter.Error != nil { - return nil - } - combined := utf16.DecodeRune(r, r2) - if combined == '\uFFFD' { - str = appendRune(str, r) - str = appendRune(str, r2) - } else { - str = appendRune(str, combined) - } - } else { - str = appendRune(str, r) - } - case '"': - str = append(str, '"') - case '\\': - str = append(str, '\\') - case '/': - str = append(str, '/') - case 'b': - str = append(str, '\b') - case 'f': - str = append(str, '\f') - case 'n': - str = append(str, '\n') - case 'r': - str = append(str, '\r') - case 't': - str = append(str, '\t') - default: - iter.ReportError("readEscapedChar", - `invalid escape char after \`) - return nil - } - return str -} - -// ReadStringAsSlice read string from iterator without copying into string form. -// The []byte can not be kept, as it will change after next iterator call. -func (iter *Iterator) ReadStringAsSlice() (ret []byte) { - c := iter.nextToken() - if c == '"' { - for i := iter.head; i < iter.tail; i++ { - // require ascii string and no escape - // for: field name, base64, number - if iter.buf[i] == '"' { - // fast path: reuse the underlying buffer - ret = iter.buf[iter.head:i] - iter.head = i + 1 - return ret - } - } - readLen := iter.tail - iter.head - copied := make([]byte, readLen, readLen*2) - copy(copied, iter.buf[iter.head:iter.tail]) - iter.head = iter.tail - for iter.Error == nil { - c := iter.readByte() - if c == '"' { - return copied - } - copied = append(copied, c) - } - return copied - } - iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c})) - return -} - -func (iter *Iterator) readU4() (ret rune) { - for i := 0; i < 4; i++ { - c := iter.readByte() - if iter.Error != nil { - return - } - if c >= '0' && c <= '9' { - ret = ret*16 + rune(c-'0') - } else if c >= 'a' && c <= 'f' { - ret = ret*16 + rune(c-'a'+10) - } else if c >= 'A' && c <= 'F' { - ret = ret*16 + rune(c-'A'+10) - } else { - iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c})) - return - } - } - return ret -} - -const ( - t1 = 0x00 // 0000 0000 - tx = 0x80 // 1000 0000 - t2 = 0xC0 // 1100 0000 - t3 = 0xE0 // 1110 0000 - t4 = 0xF0 // 1111 0000 - t5 = 0xF8 // 1111 1000 - - maskx = 0x3F // 0011 1111 - mask2 = 0x1F // 0001 1111 - mask3 = 0x0F // 0000 1111 - mask4 = 0x07 // 0000 0111 - - rune1Max = 1<<7 - 1 - rune2Max = 1<<11 - 1 - rune3Max = 1<<16 - 1 - - surrogateMin = 0xD800 - surrogateMax = 0xDFFF - - maxRune = '\U0010FFFF' // Maximum valid Unicode code point. - runeError = '\uFFFD' // the "error" Rune or "Unicode replacement character" -) - -func appendRune(p []byte, r rune) []byte { - // Negative values are erroneous. Making it unsigned addresses the problem. - switch i := uint32(r); { - case i <= rune1Max: - p = append(p, byte(r)) - return p - case i <= rune2Max: - p = append(p, t2|byte(r>>6)) - p = append(p, tx|byte(r)&maskx) - return p - case i > maxRune, surrogateMin <= i && i <= surrogateMax: - r = runeError - fallthrough - case i <= rune3Max: - p = append(p, t3|byte(r>>12)) - p = append(p, tx|byte(r>>6)&maskx) - p = append(p, tx|byte(r)&maskx) - return p - default: - p = append(p, t4|byte(r>>18)) - p = append(p, tx|byte(r>>12)&maskx) - p = append(p, tx|byte(r>>6)&maskx) - p = append(p, tx|byte(r)&maskx) - return p - } -} diff --git a/vendor/github.com/json-iterator/go/jsoniter.go b/vendor/github.com/json-iterator/go/jsoniter.go deleted file mode 100644 index c2934f916..000000000 --- a/vendor/github.com/json-iterator/go/jsoniter.go +++ /dev/null @@ -1,18 +0,0 @@ -// Package jsoniter implements encoding and decoding of JSON as defined in -// RFC 4627 and provides interfaces with identical syntax of standard lib encoding/json. -// Converting from encoding/json to jsoniter is no more than replacing the package with jsoniter -// and variable type declarations (if any). -// jsoniter interfaces gives 100% compatibility with code using standard lib. -// -// "JSON and Go" -// (https://golang.org/doc/articles/json_and_go.html) -// gives a description of how Marshal/Unmarshal operate -// between arbitrary or predefined json objects and bytes, -// and it applies to jsoniter.Marshal/Unmarshal as well. -// -// Besides, jsoniter.Iterator provides a different set of interfaces -// iterating given bytes/string/reader -// and yielding parsed elements one by one. -// This set of interfaces reads input as required and gives -// better performance. -package jsoniter diff --git a/vendor/github.com/json-iterator/go/pool.go b/vendor/github.com/json-iterator/go/pool.go deleted file mode 100644 index e2389b56c..000000000 --- a/vendor/github.com/json-iterator/go/pool.go +++ /dev/null @@ -1,42 +0,0 @@ -package jsoniter - -import ( - "io" -) - -// IteratorPool a thread safe pool of iterators with same configuration -type IteratorPool interface { - BorrowIterator(data []byte) *Iterator - ReturnIterator(iter *Iterator) -} - -// StreamPool a thread safe pool of streams with same configuration -type StreamPool interface { - BorrowStream(writer io.Writer) *Stream - ReturnStream(stream *Stream) -} - -func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream { - stream := cfg.streamPool.Get().(*Stream) - stream.Reset(writer) - return stream -} - -func (cfg *frozenConfig) ReturnStream(stream *Stream) { - stream.out = nil - stream.Error = nil - stream.Attachment = nil - cfg.streamPool.Put(stream) -} - -func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator { - iter := cfg.iteratorPool.Get().(*Iterator) - iter.ResetBytes(data) - return iter -} - -func (cfg *frozenConfig) ReturnIterator(iter *Iterator) { - iter.Error = nil - iter.Attachment = nil - cfg.iteratorPool.Put(iter) -} diff --git a/vendor/github.com/json-iterator/go/reflect.go b/vendor/github.com/json-iterator/go/reflect.go deleted file mode 100644 index 39acb320a..000000000 --- a/vendor/github.com/json-iterator/go/reflect.go +++ /dev/null @@ -1,337 +0,0 @@ -package jsoniter - -import ( - "fmt" - "reflect" - "unsafe" - - "github.com/modern-go/reflect2" -) - -// ValDecoder is an internal type registered to cache as needed. -// Don't confuse jsoniter.ValDecoder with json.Decoder. -// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link). -// -// Reflection on type to create decoders, which is then cached -// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions -// 1. create instance of new value, for example *int will need a int to be allocated -// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New -// 3. assignment to map, both key and value will be reflect.Value -// For a simple struct binding, it will be reflect.Value free and allocation free -type ValDecoder interface { - Decode(ptr unsafe.Pointer, iter *Iterator) -} - -// ValEncoder is an internal type registered to cache as needed. -// Don't confuse jsoniter.ValEncoder with json.Encoder. -// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link). -type ValEncoder interface { - IsEmpty(ptr unsafe.Pointer) bool - Encode(ptr unsafe.Pointer, stream *Stream) -} - -type checkIsEmpty interface { - IsEmpty(ptr unsafe.Pointer) bool -} - -type ctx struct { - *frozenConfig - prefix string - encoders map[reflect2.Type]ValEncoder - decoders map[reflect2.Type]ValDecoder -} - -func (b *ctx) caseSensitive() bool { - if b.frozenConfig == nil { - // default is case-insensitive - return false - } - return b.frozenConfig.caseSensitive -} - -func (b *ctx) append(prefix string) *ctx { - return &ctx{ - frozenConfig: b.frozenConfig, - prefix: b.prefix + " " + prefix, - encoders: b.encoders, - decoders: b.decoders, - } -} - -// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal -func (iter *Iterator) ReadVal(obj interface{}) { - depth := iter.depth - cacheKey := reflect2.RTypeOf(obj) - decoder := iter.cfg.getDecoderFromCache(cacheKey) - if decoder == nil { - typ := reflect2.TypeOf(obj) - if typ == nil || typ.Kind() != reflect.Ptr { - iter.ReportError("ReadVal", "can only unmarshal into pointer") - return - } - decoder = iter.cfg.DecoderOf(typ) - } - ptr := reflect2.PtrOf(obj) - if ptr == nil { - iter.ReportError("ReadVal", "can not read into nil pointer") - return - } - decoder.Decode(ptr, iter) - if iter.depth != depth { - iter.ReportError("ReadVal", "unexpected mismatched nesting") - return - } -} - -// WriteVal copy the go interface into underlying JSON, same as json.Marshal -func (stream *Stream) WriteVal(val interface{}) { - if nil == val { - stream.WriteNil() - return - } - cacheKey := reflect2.RTypeOf(val) - encoder := stream.cfg.getEncoderFromCache(cacheKey) - if encoder == nil { - typ := reflect2.TypeOf(val) - encoder = stream.cfg.EncoderOf(typ) - } - encoder.Encode(reflect2.PtrOf(val), stream) -} - -func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder { - cacheKey := typ.RType() - decoder := cfg.getDecoderFromCache(cacheKey) - if decoder != nil { - return decoder - } - ctx := &ctx{ - frozenConfig: cfg, - prefix: "", - decoders: map[reflect2.Type]ValDecoder{}, - encoders: map[reflect2.Type]ValEncoder{}, - } - ptrType := typ.(*reflect2.UnsafePtrType) - decoder = decoderOfType(ctx, ptrType.Elem()) - cfg.addDecoderToCache(cacheKey, decoder) - return decoder -} - -func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { - decoder := getTypeDecoderFromExtension(ctx, typ) - if decoder != nil { - return decoder - } - decoder = createDecoderOfType(ctx, typ) - for _, extension := range extensions { - decoder = extension.DecorateDecoder(typ, decoder) - } - decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) - for _, extension := range ctx.extraExtensions { - decoder = extension.DecorateDecoder(typ, decoder) - } - return decoder -} - -func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { - decoder := ctx.decoders[typ] - if decoder != nil { - return decoder - } - placeholder := &placeholderDecoder{} - ctx.decoders[typ] = placeholder - decoder = _createDecoderOfType(ctx, typ) - placeholder.decoder = decoder - return decoder -} - -func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { - decoder := createDecoderOfJsonRawMessage(ctx, typ) - if decoder != nil { - return decoder - } - decoder = createDecoderOfJsonNumber(ctx, typ) - if decoder != nil { - return decoder - } - decoder = createDecoderOfMarshaler(ctx, typ) - if decoder != nil { - return decoder - } - decoder = createDecoderOfAny(ctx, typ) - if decoder != nil { - return decoder - } - decoder = createDecoderOfNative(ctx, typ) - if decoder != nil { - return decoder - } - switch typ.Kind() { - case reflect.Interface: - ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType) - if isIFace { - return &ifaceDecoder{valType: ifaceType} - } - return &efaceDecoder{} - case reflect.Struct: - return decoderOfStruct(ctx, typ) - case reflect.Array: - return decoderOfArray(ctx, typ) - case reflect.Slice: - return decoderOfSlice(ctx, typ) - case reflect.Map: - return decoderOfMap(ctx, typ) - case reflect.Ptr: - return decoderOfOptional(ctx, typ) - default: - return &lazyErrorDecoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} - } -} - -func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder { - cacheKey := typ.RType() - encoder := cfg.getEncoderFromCache(cacheKey) - if encoder != nil { - return encoder - } - ctx := &ctx{ - frozenConfig: cfg, - prefix: "", - decoders: map[reflect2.Type]ValDecoder{}, - encoders: map[reflect2.Type]ValEncoder{}, - } - encoder = encoderOfType(ctx, typ) - if typ.LikePtr() { - encoder = &onePtrEncoder{encoder} - } - cfg.addEncoderToCache(cacheKey, encoder) - return encoder -} - -type onePtrEncoder struct { - encoder ValEncoder -} - -func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) -} - -func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) -} - -func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { - encoder := getTypeEncoderFromExtension(ctx, typ) - if encoder != nil { - return encoder - } - encoder = createEncoderOfType(ctx, typ) - for _, extension := range extensions { - encoder = extension.DecorateEncoder(typ, encoder) - } - encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) - for _, extension := range ctx.extraExtensions { - encoder = extension.DecorateEncoder(typ, encoder) - } - return encoder -} - -func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { - encoder := ctx.encoders[typ] - if encoder != nil { - return encoder - } - placeholder := &placeholderEncoder{} - ctx.encoders[typ] = placeholder - encoder = _createEncoderOfType(ctx, typ) - placeholder.encoder = encoder - return encoder -} -func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { - encoder := createEncoderOfJsonRawMessage(ctx, typ) - if encoder != nil { - return encoder - } - encoder = createEncoderOfJsonNumber(ctx, typ) - if encoder != nil { - return encoder - } - encoder = createEncoderOfMarshaler(ctx, typ) - if encoder != nil { - return encoder - } - encoder = createEncoderOfAny(ctx, typ) - if encoder != nil { - return encoder - } - encoder = createEncoderOfNative(ctx, typ) - if encoder != nil { - return encoder - } - kind := typ.Kind() - switch kind { - case reflect.Interface: - return &dynamicEncoder{typ} - case reflect.Struct: - return encoderOfStruct(ctx, typ) - case reflect.Array: - return encoderOfArray(ctx, typ) - case reflect.Slice: - return encoderOfSlice(ctx, typ) - case reflect.Map: - return encoderOfMap(ctx, typ) - case reflect.Ptr: - return encoderOfOptional(ctx, typ) - default: - return &lazyErrorEncoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} - } -} - -type lazyErrorDecoder struct { - err error -} - -func (decoder *lazyErrorDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.WhatIsNext() != NilValue { - if iter.Error == nil { - iter.Error = decoder.err - } - } else { - iter.Skip() - } -} - -type lazyErrorEncoder struct { - err error -} - -func (encoder *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if ptr == nil { - stream.WriteNil() - } else if stream.Error == nil { - stream.Error = encoder.err - } -} - -func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return false -} - -type placeholderDecoder struct { - decoder ValDecoder -} - -func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.decoder.Decode(ptr, iter) -} - -type placeholderEncoder struct { - encoder ValEncoder -} - -func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - encoder.encoder.Encode(ptr, stream) -} - -func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.encoder.IsEmpty(ptr) -} diff --git a/vendor/github.com/json-iterator/go/reflect_array.go b/vendor/github.com/json-iterator/go/reflect_array.go deleted file mode 100644 index 13a0b7b08..000000000 --- a/vendor/github.com/json-iterator/go/reflect_array.go +++ /dev/null @@ -1,104 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "io" - "unsafe" -) - -func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder { - arrayType := typ.(*reflect2.UnsafeArrayType) - decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) - return &arrayDecoder{arrayType, decoder} -} - -func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder { - arrayType := typ.(*reflect2.UnsafeArrayType) - if arrayType.Len() == 0 { - return emptyArrayEncoder{} - } - encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) - return &arrayEncoder{arrayType, encoder} -} - -type emptyArrayEncoder struct{} - -func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteEmptyArray() -} - -func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return true -} - -type arrayEncoder struct { - arrayType *reflect2.UnsafeArrayType - elemEncoder ValEncoder -} - -func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteArrayStart() - elemPtr := unsafe.Pointer(ptr) - encoder.elemEncoder.Encode(elemPtr, stream) - for i := 1; i < encoder.arrayType.Len(); i++ { - stream.WriteMore() - elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i) - encoder.elemEncoder.Encode(elemPtr, stream) - } - stream.WriteArrayEnd() - if stream.Error != nil && stream.Error != io.EOF { - stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error()) - } -} - -func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return false -} - -type arrayDecoder struct { - arrayType *reflect2.UnsafeArrayType - elemDecoder ValDecoder -} - -func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.doDecode(ptr, iter) - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error()) - } -} - -func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { - c := iter.nextToken() - arrayType := decoder.arrayType - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return - } - if c != '[' { - iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c})) - return - } - c = iter.nextToken() - if c == ']' { - return - } - iter.unreadByte() - elemPtr := arrayType.UnsafeGetIndex(ptr, 0) - decoder.elemDecoder.Decode(elemPtr, iter) - length := 1 - for c = iter.nextToken(); c == ','; c = iter.nextToken() { - if length >= arrayType.Len() { - iter.Skip() - continue - } - idx := length - length += 1 - elemPtr = arrayType.UnsafeGetIndex(ptr, idx) - decoder.elemDecoder.Decode(elemPtr, iter) - } - if c != ']' { - iter.ReportError("decode array", "expect ], but found "+string([]byte{c})) - return - } -} diff --git a/vendor/github.com/json-iterator/go/reflect_dynamic.go b/vendor/github.com/json-iterator/go/reflect_dynamic.go deleted file mode 100644 index 8b6bc8b43..000000000 --- a/vendor/github.com/json-iterator/go/reflect_dynamic.go +++ /dev/null @@ -1,70 +0,0 @@ -package jsoniter - -import ( - "github.com/modern-go/reflect2" - "reflect" - "unsafe" -) - -type dynamicEncoder struct { - valType reflect2.Type -} - -func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - obj := encoder.valType.UnsafeIndirect(ptr) - stream.WriteVal(obj) -} - -func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.valType.UnsafeIndirect(ptr) == nil -} - -type efaceDecoder struct { -} - -func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - pObj := (*interface{})(ptr) - obj := *pObj - if obj == nil { - *pObj = iter.Read() - return - } - typ := reflect2.TypeOf(obj) - if typ.Kind() != reflect.Ptr { - *pObj = iter.Read() - return - } - ptrType := typ.(*reflect2.UnsafePtrType) - ptrElemType := ptrType.Elem() - if iter.WhatIsNext() == NilValue { - if ptrElemType.Kind() != reflect.Ptr { - iter.skipFourBytes('n', 'u', 'l', 'l') - *pObj = nil - return - } - } - if reflect2.IsNil(obj) { - obj := ptrElemType.New() - iter.ReadVal(obj) - *pObj = obj - return - } - iter.ReadVal(obj) -} - -type ifaceDecoder struct { - valType *reflect2.UnsafeIFaceType -} - -func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.ReadNil() { - decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew()) - return - } - obj := decoder.valType.UnsafeIndirect(ptr) - if reflect2.IsNil(obj) { - iter.ReportError("decode non empty interface", "can not unmarshal into nil") - return - } - iter.ReadVal(obj) -} diff --git a/vendor/github.com/json-iterator/go/reflect_extension.go b/vendor/github.com/json-iterator/go/reflect_extension.go deleted file mode 100644 index 74a97bfe5..000000000 --- a/vendor/github.com/json-iterator/go/reflect_extension.go +++ /dev/null @@ -1,483 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "reflect" - "sort" - "strings" - "unicode" - "unsafe" -) - -var typeDecoders = map[string]ValDecoder{} -var fieldDecoders = map[string]ValDecoder{} -var typeEncoders = map[string]ValEncoder{} -var fieldEncoders = map[string]ValEncoder{} -var extensions = []Extension{} - -// StructDescriptor describe how should we encode/decode the struct -type StructDescriptor struct { - Type reflect2.Type - Fields []*Binding -} - -// GetField get one field from the descriptor by its name. -// Can not use map here to keep field orders. -func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding { - for _, binding := range structDescriptor.Fields { - if binding.Field.Name() == fieldName { - return binding - } - } - return nil -} - -// Binding describe how should we encode/decode the struct field -type Binding struct { - levels []int - Field reflect2.StructField - FromNames []string - ToNames []string - Encoder ValEncoder - Decoder ValDecoder -} - -// Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder. -// Can also rename fields by UpdateStructDescriptor. -type Extension interface { - UpdateStructDescriptor(structDescriptor *StructDescriptor) - CreateMapKeyDecoder(typ reflect2.Type) ValDecoder - CreateMapKeyEncoder(typ reflect2.Type) ValEncoder - CreateDecoder(typ reflect2.Type) ValDecoder - CreateEncoder(typ reflect2.Type) ValEncoder - DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder - DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder -} - -// DummyExtension embed this type get dummy implementation for all methods of Extension -type DummyExtension struct { -} - -// UpdateStructDescriptor No-op -func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { -} - -// CreateMapKeyDecoder No-op -func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { - return nil -} - -// CreateMapKeyEncoder No-op -func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { - return nil -} - -// CreateDecoder No-op -func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder { - return nil -} - -// CreateEncoder No-op -func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder { - return nil -} - -// DecorateDecoder No-op -func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { - return decoder -} - -// DecorateEncoder No-op -func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { - return encoder -} - -type EncoderExtension map[reflect2.Type]ValEncoder - -// UpdateStructDescriptor No-op -func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { -} - -// CreateDecoder No-op -func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { - return nil -} - -// CreateEncoder get encoder from map -func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { - return extension[typ] -} - -// CreateMapKeyDecoder No-op -func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { - return nil -} - -// CreateMapKeyEncoder No-op -func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { - return nil -} - -// DecorateDecoder No-op -func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { - return decoder -} - -// DecorateEncoder No-op -func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { - return encoder -} - -type DecoderExtension map[reflect2.Type]ValDecoder - -// UpdateStructDescriptor No-op -func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { -} - -// CreateMapKeyDecoder No-op -func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { - return nil -} - -// CreateMapKeyEncoder No-op -func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { - return nil -} - -// CreateDecoder get decoder from map -func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { - return extension[typ] -} - -// CreateEncoder No-op -func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { - return nil -} - -// DecorateDecoder No-op -func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { - return decoder -} - -// DecorateEncoder No-op -func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { - return encoder -} - -type funcDecoder struct { - fun DecoderFunc -} - -func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.fun(ptr, iter) -} - -type funcEncoder struct { - fun EncoderFunc - isEmptyFunc func(ptr unsafe.Pointer) bool -} - -func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - encoder.fun(ptr, stream) -} - -func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { - if encoder.isEmptyFunc == nil { - return false - } - return encoder.isEmptyFunc(ptr) -} - -// DecoderFunc the function form of TypeDecoder -type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) - -// EncoderFunc the function form of TypeEncoder -type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) - -// RegisterTypeDecoderFunc register TypeDecoder for a type with function -func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) { - typeDecoders[typ] = &funcDecoder{fun} -} - -// RegisterTypeDecoder register TypeDecoder for a typ -func RegisterTypeDecoder(typ string, decoder ValDecoder) { - typeDecoders[typ] = decoder -} - -// RegisterFieldDecoderFunc register TypeDecoder for a struct field with function -func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) { - RegisterFieldDecoder(typ, field, &funcDecoder{fun}) -} - -// RegisterFieldDecoder register TypeDecoder for a struct field -func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) { - fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder -} - -// RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function -func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { - typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc} -} - -// RegisterTypeEncoder register TypeEncoder for a type -func RegisterTypeEncoder(typ string, encoder ValEncoder) { - typeEncoders[typ] = encoder -} - -// RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function -func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { - RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc}) -} - -// RegisterFieldEncoder register TypeEncoder for a struct field -func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) { - fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder -} - -// RegisterExtension register extension -func RegisterExtension(extension Extension) { - extensions = append(extensions, extension) -} - -func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { - decoder := _getTypeDecoderFromExtension(ctx, typ) - if decoder != nil { - for _, extension := range extensions { - decoder = extension.DecorateDecoder(typ, decoder) - } - decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) - for _, extension := range ctx.extraExtensions { - decoder = extension.DecorateDecoder(typ, decoder) - } - } - return decoder -} -func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { - for _, extension := range extensions { - decoder := extension.CreateDecoder(typ) - if decoder != nil { - return decoder - } - } - decoder := ctx.decoderExtension.CreateDecoder(typ) - if decoder != nil { - return decoder - } - for _, extension := range ctx.extraExtensions { - decoder := extension.CreateDecoder(typ) - if decoder != nil { - return decoder - } - } - typeName := typ.String() - decoder = typeDecoders[typeName] - if decoder != nil { - return decoder - } - if typ.Kind() == reflect.Ptr { - ptrType := typ.(*reflect2.UnsafePtrType) - decoder := typeDecoders[ptrType.Elem().String()] - if decoder != nil { - return &OptionalDecoder{ptrType.Elem(), decoder} - } - } - return nil -} - -func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { - encoder := _getTypeEncoderFromExtension(ctx, typ) - if encoder != nil { - for _, extension := range extensions { - encoder = extension.DecorateEncoder(typ, encoder) - } - encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) - for _, extension := range ctx.extraExtensions { - encoder = extension.DecorateEncoder(typ, encoder) - } - } - return encoder -} - -func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { - for _, extension := range extensions { - encoder := extension.CreateEncoder(typ) - if encoder != nil { - return encoder - } - } - encoder := ctx.encoderExtension.CreateEncoder(typ) - if encoder != nil { - return encoder - } - for _, extension := range ctx.extraExtensions { - encoder := extension.CreateEncoder(typ) - if encoder != nil { - return encoder - } - } - typeName := typ.String() - encoder = typeEncoders[typeName] - if encoder != nil { - return encoder - } - if typ.Kind() == reflect.Ptr { - typePtr := typ.(*reflect2.UnsafePtrType) - encoder := typeEncoders[typePtr.Elem().String()] - if encoder != nil { - return &OptionalEncoder{encoder} - } - } - return nil -} - -func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor { - structType := typ.(*reflect2.UnsafeStructType) - embeddedBindings := []*Binding{} - bindings := []*Binding{} - for i := 0; i < structType.NumField(); i++ { - field := structType.Field(i) - tag, hastag := field.Tag().Lookup(ctx.getTagKey()) - if ctx.onlyTaggedField && !hastag && !field.Anonymous() { - continue - } - if tag == "-" || field.Name() == "_" { - continue - } - tagParts := strings.Split(tag, ",") - if field.Anonymous() && (tag == "" || tagParts[0] == "") { - if field.Type().Kind() == reflect.Struct { - structDescriptor := describeStruct(ctx, field.Type()) - for _, binding := range structDescriptor.Fields { - binding.levels = append([]int{i}, binding.levels...) - omitempty := binding.Encoder.(*structFieldEncoder).omitempty - binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} - binding.Decoder = &structFieldDecoder{field, binding.Decoder} - embeddedBindings = append(embeddedBindings, binding) - } - continue - } else if field.Type().Kind() == reflect.Ptr { - ptrType := field.Type().(*reflect2.UnsafePtrType) - if ptrType.Elem().Kind() == reflect.Struct { - structDescriptor := describeStruct(ctx, ptrType.Elem()) - for _, binding := range structDescriptor.Fields { - binding.levels = append([]int{i}, binding.levels...) - omitempty := binding.Encoder.(*structFieldEncoder).omitempty - binding.Encoder = &dereferenceEncoder{binding.Encoder} - binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} - binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder} - binding.Decoder = &structFieldDecoder{field, binding.Decoder} - embeddedBindings = append(embeddedBindings, binding) - } - continue - } - } - } - fieldNames := calcFieldNames(field.Name(), tagParts[0], tag) - fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name()) - decoder := fieldDecoders[fieldCacheKey] - if decoder == nil { - decoder = decoderOfType(ctx.append(field.Name()), field.Type()) - } - encoder := fieldEncoders[fieldCacheKey] - if encoder == nil { - encoder = encoderOfType(ctx.append(field.Name()), field.Type()) - } - binding := &Binding{ - Field: field, - FromNames: fieldNames, - ToNames: fieldNames, - Decoder: decoder, - Encoder: encoder, - } - binding.levels = []int{i} - bindings = append(bindings, binding) - } - return createStructDescriptor(ctx, typ, bindings, embeddedBindings) -} -func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor { - structDescriptor := &StructDescriptor{ - Type: typ, - Fields: bindings, - } - for _, extension := range extensions { - extension.UpdateStructDescriptor(structDescriptor) - } - ctx.encoderExtension.UpdateStructDescriptor(structDescriptor) - ctx.decoderExtension.UpdateStructDescriptor(structDescriptor) - for _, extension := range ctx.extraExtensions { - extension.UpdateStructDescriptor(structDescriptor) - } - processTags(structDescriptor, ctx.frozenConfig) - // merge normal & embedded bindings & sort with original order - allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...)) - sort.Sort(allBindings) - structDescriptor.Fields = allBindings - return structDescriptor -} - -type sortableBindings []*Binding - -func (bindings sortableBindings) Len() int { - return len(bindings) -} - -func (bindings sortableBindings) Less(i, j int) bool { - left := bindings[i].levels - right := bindings[j].levels - k := 0 - for { - if left[k] < right[k] { - return true - } else if left[k] > right[k] { - return false - } - k++ - } -} - -func (bindings sortableBindings) Swap(i, j int) { - bindings[i], bindings[j] = bindings[j], bindings[i] -} - -func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) { - for _, binding := range structDescriptor.Fields { - shouldOmitEmpty := false - tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",") - for _, tagPart := range tagParts[1:] { - if tagPart == "omitempty" { - shouldOmitEmpty = true - } else if tagPart == "string" { - if binding.Field.Type().Kind() == reflect.String { - binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg} - binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg} - } else { - binding.Decoder = &stringModeNumberDecoder{binding.Decoder} - binding.Encoder = &stringModeNumberEncoder{binding.Encoder} - } - } - } - binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder} - binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty} - } -} - -func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string { - // ignore? - if wholeTag == "-" { - return []string{} - } - // rename? - var fieldNames []string - if tagProvidedFieldName == "" { - fieldNames = []string{originalFieldName} - } else { - fieldNames = []string{tagProvidedFieldName} - } - // private? - isNotExported := unicode.IsLower(rune(originalFieldName[0])) || originalFieldName[0] == '_' - if isNotExported { - fieldNames = []string{} - } - return fieldNames -} diff --git a/vendor/github.com/json-iterator/go/reflect_json_number.go b/vendor/github.com/json-iterator/go/reflect_json_number.go deleted file mode 100644 index 98d45c1ec..000000000 --- a/vendor/github.com/json-iterator/go/reflect_json_number.go +++ /dev/null @@ -1,112 +0,0 @@ -package jsoniter - -import ( - "encoding/json" - "github.com/modern-go/reflect2" - "strconv" - "unsafe" -) - -type Number string - -// String returns the literal text of the number. -func (n Number) String() string { return string(n) } - -// Float64 returns the number as a float64. -func (n Number) Float64() (float64, error) { - return strconv.ParseFloat(string(n), 64) -} - -// Int64 returns the number as an int64. -func (n Number) Int64() (int64, error) { - return strconv.ParseInt(string(n), 10, 64) -} - -func CastJsonNumber(val interface{}) (string, bool) { - switch typedVal := val.(type) { - case json.Number: - return string(typedVal), true - case Number: - return string(typedVal), true - } - return "", false -} - -var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem() -var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem() - -func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder { - if typ.AssignableTo(jsonNumberType) { - return &jsonNumberCodec{} - } - if typ.AssignableTo(jsoniterNumberType) { - return &jsoniterNumberCodec{} - } - return nil -} - -func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder { - if typ.AssignableTo(jsonNumberType) { - return &jsonNumberCodec{} - } - if typ.AssignableTo(jsoniterNumberType) { - return &jsoniterNumberCodec{} - } - return nil -} - -type jsonNumberCodec struct { -} - -func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - switch iter.WhatIsNext() { - case StringValue: - *((*json.Number)(ptr)) = json.Number(iter.ReadString()) - case NilValue: - iter.skipFourBytes('n', 'u', 'l', 'l') - *((*json.Number)(ptr)) = "" - default: - *((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString())) - } -} - -func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - number := *((*json.Number)(ptr)) - if len(number) == 0 { - stream.writeByte('0') - } else { - stream.WriteRaw(string(number)) - } -} - -func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*json.Number)(ptr))) == 0 -} - -type jsoniterNumberCodec struct { -} - -func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - switch iter.WhatIsNext() { - case StringValue: - *((*Number)(ptr)) = Number(iter.ReadString()) - case NilValue: - iter.skipFourBytes('n', 'u', 'l', 'l') - *((*Number)(ptr)) = "" - default: - *((*Number)(ptr)) = Number([]byte(iter.readNumberAsString())) - } -} - -func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - number := *((*Number)(ptr)) - if len(number) == 0 { - stream.writeByte('0') - } else { - stream.WriteRaw(string(number)) - } -} - -func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*Number)(ptr))) == 0 -} diff --git a/vendor/github.com/json-iterator/go/reflect_json_raw_message.go b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go deleted file mode 100644 index eba434f2f..000000000 --- a/vendor/github.com/json-iterator/go/reflect_json_raw_message.go +++ /dev/null @@ -1,76 +0,0 @@ -package jsoniter - -import ( - "encoding/json" - "github.com/modern-go/reflect2" - "unsafe" -) - -var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem() -var jsoniterRawMessageType = reflect2.TypeOfPtr((*RawMessage)(nil)).Elem() - -func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValEncoder { - if typ == jsonRawMessageType { - return &jsonRawMessageCodec{} - } - if typ == jsoniterRawMessageType { - return &jsoniterRawMessageCodec{} - } - return nil -} - -func createDecoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValDecoder { - if typ == jsonRawMessageType { - return &jsonRawMessageCodec{} - } - if typ == jsoniterRawMessageType { - return &jsoniterRawMessageCodec{} - } - return nil -} - -type jsonRawMessageCodec struct { -} - -func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.ReadNil() { - *((*json.RawMessage)(ptr)) = nil - } else { - *((*json.RawMessage)(ptr)) = iter.SkipAndReturnBytes() - } -} - -func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - if *((*json.RawMessage)(ptr)) == nil { - stream.WriteNil() - } else { - stream.WriteRaw(string(*((*json.RawMessage)(ptr)))) - } -} - -func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*json.RawMessage)(ptr))) == 0 -} - -type jsoniterRawMessageCodec struct { -} - -func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.ReadNil() { - *((*RawMessage)(ptr)) = nil - } else { - *((*RawMessage)(ptr)) = iter.SkipAndReturnBytes() - } -} - -func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - if *((*RawMessage)(ptr)) == nil { - stream.WriteNil() - } else { - stream.WriteRaw(string(*((*RawMessage)(ptr)))) - } -} - -func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*RawMessage)(ptr))) == 0 -} diff --git a/vendor/github.com/json-iterator/go/reflect_map.go b/vendor/github.com/json-iterator/go/reflect_map.go deleted file mode 100644 index 582967130..000000000 --- a/vendor/github.com/json-iterator/go/reflect_map.go +++ /dev/null @@ -1,346 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "io" - "reflect" - "sort" - "unsafe" -) - -func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder { - mapType := typ.(*reflect2.UnsafeMapType) - keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()) - elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem()) - return &mapDecoder{ - mapType: mapType, - keyType: mapType.Key(), - elemType: mapType.Elem(), - keyDecoder: keyDecoder, - elemDecoder: elemDecoder, - } -} - -func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder { - mapType := typ.(*reflect2.UnsafeMapType) - if ctx.sortMapKeys { - return &sortKeysMapEncoder{ - mapType: mapType, - keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), - elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), - } - } - return &mapEncoder{ - mapType: mapType, - keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), - elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), - } -} - -func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder { - decoder := ctx.decoderExtension.CreateMapKeyDecoder(typ) - if decoder != nil { - return decoder - } - for _, extension := range ctx.extraExtensions { - decoder := extension.CreateMapKeyDecoder(typ) - if decoder != nil { - return decoder - } - } - - ptrType := reflect2.PtrTo(typ) - if ptrType.Implements(unmarshalerType) { - return &referenceDecoder{ - &unmarshalerDecoder{ - valType: ptrType, - }, - } - } - if typ.Implements(unmarshalerType) { - return &unmarshalerDecoder{ - valType: typ, - } - } - if ptrType.Implements(textUnmarshalerType) { - return &referenceDecoder{ - &textUnmarshalerDecoder{ - valType: ptrType, - }, - } - } - if typ.Implements(textUnmarshalerType) { - return &textUnmarshalerDecoder{ - valType: typ, - } - } - - switch typ.Kind() { - case reflect.String: - return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) - case reflect.Bool, - reflect.Uint8, reflect.Int8, - reflect.Uint16, reflect.Int16, - reflect.Uint32, reflect.Int32, - reflect.Uint64, reflect.Int64, - reflect.Uint, reflect.Int, - reflect.Float32, reflect.Float64, - reflect.Uintptr: - typ = reflect2.DefaultTypeOfKind(typ.Kind()) - return &numericMapKeyDecoder{decoderOfType(ctx, typ)} - default: - return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)} - } -} - -func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder { - encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ) - if encoder != nil { - return encoder - } - for _, extension := range ctx.extraExtensions { - encoder := extension.CreateMapKeyEncoder(typ) - if encoder != nil { - return encoder - } - } - - if typ == textMarshalerType { - return &directTextMarshalerEncoder{ - stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), - } - } - if typ.Implements(textMarshalerType) { - return &textMarshalerEncoder{ - valType: typ, - stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), - } - } - - switch typ.Kind() { - case reflect.String: - return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) - case reflect.Bool, - reflect.Uint8, reflect.Int8, - reflect.Uint16, reflect.Int16, - reflect.Uint32, reflect.Int32, - reflect.Uint64, reflect.Int64, - reflect.Uint, reflect.Int, - reflect.Float32, reflect.Float64, - reflect.Uintptr: - typ = reflect2.DefaultTypeOfKind(typ.Kind()) - return &numericMapKeyEncoder{encoderOfType(ctx, typ)} - default: - if typ.Kind() == reflect.Interface { - return &dynamicMapKeyEncoder{ctx, typ} - } - return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)} - } -} - -type mapDecoder struct { - mapType *reflect2.UnsafeMapType - keyType reflect2.Type - elemType reflect2.Type - keyDecoder ValDecoder - elemDecoder ValDecoder -} - -func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - mapType := decoder.mapType - c := iter.nextToken() - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - *(*unsafe.Pointer)(ptr) = nil - mapType.UnsafeSet(ptr, mapType.UnsafeNew()) - return - } - if mapType.UnsafeIsNil(ptr) { - mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0)) - } - if c != '{' { - iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) - return - } - c = iter.nextToken() - if c == '}' { - return - } - iter.unreadByte() - key := decoder.keyType.UnsafeNew() - decoder.keyDecoder.Decode(key, iter) - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) - return - } - elem := decoder.elemType.UnsafeNew() - decoder.elemDecoder.Decode(elem, iter) - decoder.mapType.UnsafeSetIndex(ptr, key, elem) - for c = iter.nextToken(); c == ','; c = iter.nextToken() { - key := decoder.keyType.UnsafeNew() - decoder.keyDecoder.Decode(key, iter) - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) - return - } - elem := decoder.elemType.UnsafeNew() - decoder.elemDecoder.Decode(elem, iter) - decoder.mapType.UnsafeSetIndex(ptr, key, elem) - } - if c != '}' { - iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c})) - } -} - -type numericMapKeyDecoder struct { - decoder ValDecoder -} - -func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - c := iter.nextToken() - if c != '"' { - iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) - return - } - decoder.decoder.Decode(ptr, iter) - c = iter.nextToken() - if c != '"' { - iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) - return - } -} - -type numericMapKeyEncoder struct { - encoder ValEncoder -} - -func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.writeByte('"') - encoder.encoder.Encode(ptr, stream) - stream.writeByte('"') -} - -func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return false -} - -type dynamicMapKeyEncoder struct { - ctx *ctx - valType reflect2.Type -} - -func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - obj := encoder.valType.UnsafeIndirect(ptr) - encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream) -} - -func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { - obj := encoder.valType.UnsafeIndirect(ptr) - return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj)) -} - -type mapEncoder struct { - mapType *reflect2.UnsafeMapType - keyEncoder ValEncoder - elemEncoder ValEncoder -} - -func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if *(*unsafe.Pointer)(ptr) == nil { - stream.WriteNil() - return - } - stream.WriteObjectStart() - iter := encoder.mapType.UnsafeIterate(ptr) - for i := 0; iter.HasNext(); i++ { - if i != 0 { - stream.WriteMore() - } - key, elem := iter.UnsafeNext() - encoder.keyEncoder.Encode(key, stream) - if stream.indention > 0 { - stream.writeTwoBytes(byte(':'), byte(' ')) - } else { - stream.writeByte(':') - } - encoder.elemEncoder.Encode(elem, stream) - } - stream.WriteObjectEnd() -} - -func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool { - iter := encoder.mapType.UnsafeIterate(ptr) - return !iter.HasNext() -} - -type sortKeysMapEncoder struct { - mapType *reflect2.UnsafeMapType - keyEncoder ValEncoder - elemEncoder ValEncoder -} - -func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if *(*unsafe.Pointer)(ptr) == nil { - stream.WriteNil() - return - } - stream.WriteObjectStart() - mapIter := encoder.mapType.UnsafeIterate(ptr) - subStream := stream.cfg.BorrowStream(nil) - subStream.Attachment = stream.Attachment - subIter := stream.cfg.BorrowIterator(nil) - keyValues := encodedKeyValues{} - for mapIter.HasNext() { - key, elem := mapIter.UnsafeNext() - subStreamIndex := subStream.Buffered() - encoder.keyEncoder.Encode(key, subStream) - if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil { - stream.Error = subStream.Error - } - encodedKey := subStream.Buffer()[subStreamIndex:] - subIter.ResetBytes(encodedKey) - decodedKey := subIter.ReadString() - if stream.indention > 0 { - subStream.writeTwoBytes(byte(':'), byte(' ')) - } else { - subStream.writeByte(':') - } - encoder.elemEncoder.Encode(elem, subStream) - keyValues = append(keyValues, encodedKV{ - key: decodedKey, - keyValue: subStream.Buffer()[subStreamIndex:], - }) - } - sort.Sort(keyValues) - for i, keyValue := range keyValues { - if i != 0 { - stream.WriteMore() - } - stream.Write(keyValue.keyValue) - } - if subStream.Error != nil && stream.Error == nil { - stream.Error = subStream.Error - } - stream.WriteObjectEnd() - stream.cfg.ReturnStream(subStream) - stream.cfg.ReturnIterator(subIter) -} - -func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool { - iter := encoder.mapType.UnsafeIterate(ptr) - return !iter.HasNext() -} - -type encodedKeyValues []encodedKV - -type encodedKV struct { - key string - keyValue []byte -} - -func (sv encodedKeyValues) Len() int { return len(sv) } -func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } -func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key } diff --git a/vendor/github.com/json-iterator/go/reflect_marshaler.go b/vendor/github.com/json-iterator/go/reflect_marshaler.go deleted file mode 100644 index 3e21f3756..000000000 --- a/vendor/github.com/json-iterator/go/reflect_marshaler.go +++ /dev/null @@ -1,225 +0,0 @@ -package jsoniter - -import ( - "encoding" - "encoding/json" - "unsafe" - - "github.com/modern-go/reflect2" -) - -var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem() -var unmarshalerType = reflect2.TypeOfPtr((*json.Unmarshaler)(nil)).Elem() -var textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem() -var textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem() - -func createDecoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValDecoder { - ptrType := reflect2.PtrTo(typ) - if ptrType.Implements(unmarshalerType) { - return &referenceDecoder{ - &unmarshalerDecoder{ptrType}, - } - } - if ptrType.Implements(textUnmarshalerType) { - return &referenceDecoder{ - &textUnmarshalerDecoder{ptrType}, - } - } - return nil -} - -func createEncoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValEncoder { - if typ == marshalerType { - checkIsEmpty := createCheckIsEmpty(ctx, typ) - var encoder ValEncoder = &directMarshalerEncoder{ - checkIsEmpty: checkIsEmpty, - } - return encoder - } - if typ.Implements(marshalerType) { - checkIsEmpty := createCheckIsEmpty(ctx, typ) - var encoder ValEncoder = &marshalerEncoder{ - valType: typ, - checkIsEmpty: checkIsEmpty, - } - return encoder - } - ptrType := reflect2.PtrTo(typ) - if ctx.prefix != "" && ptrType.Implements(marshalerType) { - checkIsEmpty := createCheckIsEmpty(ctx, ptrType) - var encoder ValEncoder = &marshalerEncoder{ - valType: ptrType, - checkIsEmpty: checkIsEmpty, - } - return &referenceEncoder{encoder} - } - if typ == textMarshalerType { - checkIsEmpty := createCheckIsEmpty(ctx, typ) - var encoder ValEncoder = &directTextMarshalerEncoder{ - checkIsEmpty: checkIsEmpty, - stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), - } - return encoder - } - if typ.Implements(textMarshalerType) { - checkIsEmpty := createCheckIsEmpty(ctx, typ) - var encoder ValEncoder = &textMarshalerEncoder{ - valType: typ, - stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), - checkIsEmpty: checkIsEmpty, - } - return encoder - } - // if prefix is empty, the type is the root type - if ctx.prefix != "" && ptrType.Implements(textMarshalerType) { - checkIsEmpty := createCheckIsEmpty(ctx, ptrType) - var encoder ValEncoder = &textMarshalerEncoder{ - valType: ptrType, - stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), - checkIsEmpty: checkIsEmpty, - } - return &referenceEncoder{encoder} - } - return nil -} - -type marshalerEncoder struct { - checkIsEmpty checkIsEmpty - valType reflect2.Type -} - -func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - obj := encoder.valType.UnsafeIndirect(ptr) - if encoder.valType.IsNullable() && reflect2.IsNil(obj) { - stream.WriteNil() - return - } - marshaler := obj.(json.Marshaler) - bytes, err := marshaler.MarshalJSON() - if err != nil { - stream.Error = err - } else { - // html escape was already done by jsoniter - // but the extra '\n' should be trimed - l := len(bytes) - if l > 0 && bytes[l-1] == '\n' { - bytes = bytes[:l-1] - } - stream.Write(bytes) - } -} - -func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.checkIsEmpty.IsEmpty(ptr) -} - -type directMarshalerEncoder struct { - checkIsEmpty checkIsEmpty -} - -func (encoder *directMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - marshaler := *(*json.Marshaler)(ptr) - if marshaler == nil { - stream.WriteNil() - return - } - bytes, err := marshaler.MarshalJSON() - if err != nil { - stream.Error = err - } else { - stream.Write(bytes) - } -} - -func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.checkIsEmpty.IsEmpty(ptr) -} - -type textMarshalerEncoder struct { - valType reflect2.Type - stringEncoder ValEncoder - checkIsEmpty checkIsEmpty -} - -func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - obj := encoder.valType.UnsafeIndirect(ptr) - if encoder.valType.IsNullable() && reflect2.IsNil(obj) { - stream.WriteNil() - return - } - marshaler := (obj).(encoding.TextMarshaler) - bytes, err := marshaler.MarshalText() - if err != nil { - stream.Error = err - } else { - str := string(bytes) - encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) - } -} - -func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.checkIsEmpty.IsEmpty(ptr) -} - -type directTextMarshalerEncoder struct { - stringEncoder ValEncoder - checkIsEmpty checkIsEmpty -} - -func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - marshaler := *(*encoding.TextMarshaler)(ptr) - if marshaler == nil { - stream.WriteNil() - return - } - bytes, err := marshaler.MarshalText() - if err != nil { - stream.Error = err - } else { - str := string(bytes) - encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) - } -} - -func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.checkIsEmpty.IsEmpty(ptr) -} - -type unmarshalerDecoder struct { - valType reflect2.Type -} - -func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - valType := decoder.valType - obj := valType.UnsafeIndirect(ptr) - unmarshaler := obj.(json.Unmarshaler) - iter.nextToken() - iter.unreadByte() // skip spaces - bytes := iter.SkipAndReturnBytes() - err := unmarshaler.UnmarshalJSON(bytes) - if err != nil { - iter.ReportError("unmarshalerDecoder", err.Error()) - } -} - -type textUnmarshalerDecoder struct { - valType reflect2.Type -} - -func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - valType := decoder.valType - obj := valType.UnsafeIndirect(ptr) - if reflect2.IsNil(obj) { - ptrType := valType.(*reflect2.UnsafePtrType) - elemType := ptrType.Elem() - elem := elemType.UnsafeNew() - ptrType.UnsafeSet(ptr, unsafe.Pointer(&elem)) - obj = valType.UnsafeIndirect(ptr) - } - unmarshaler := (obj).(encoding.TextUnmarshaler) - str := iter.ReadString() - err := unmarshaler.UnmarshalText([]byte(str)) - if err != nil { - iter.ReportError("textUnmarshalerDecoder", err.Error()) - } -} diff --git a/vendor/github.com/json-iterator/go/reflect_native.go b/vendor/github.com/json-iterator/go/reflect_native.go deleted file mode 100644 index f88722d14..000000000 --- a/vendor/github.com/json-iterator/go/reflect_native.go +++ /dev/null @@ -1,453 +0,0 @@ -package jsoniter - -import ( - "encoding/base64" - "reflect" - "strconv" - "unsafe" - - "github.com/modern-go/reflect2" -) - -const ptrSize = 32 << uintptr(^uintptr(0)>>63) - -func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder { - if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { - sliceDecoder := decoderOfSlice(ctx, typ) - return &base64Codec{sliceDecoder: sliceDecoder} - } - typeName := typ.String() - kind := typ.Kind() - switch kind { - case reflect.String: - if typeName != "string" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) - } - return &stringCodec{} - case reflect.Int: - if typeName != "int" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) - } - if strconv.IntSize == 32 { - return &int32Codec{} - } - return &int64Codec{} - case reflect.Int8: - if typeName != "int8" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) - } - return &int8Codec{} - case reflect.Int16: - if typeName != "int16" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) - } - return &int16Codec{} - case reflect.Int32: - if typeName != "int32" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) - } - return &int32Codec{} - case reflect.Int64: - if typeName != "int64" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) - } - return &int64Codec{} - case reflect.Uint: - if typeName != "uint" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) - } - if strconv.IntSize == 32 { - return &uint32Codec{} - } - return &uint64Codec{} - case reflect.Uint8: - if typeName != "uint8" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) - } - return &uint8Codec{} - case reflect.Uint16: - if typeName != "uint16" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) - } - return &uint16Codec{} - case reflect.Uint32: - if typeName != "uint32" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) - } - return &uint32Codec{} - case reflect.Uintptr: - if typeName != "uintptr" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) - } - if ptrSize == 32 { - return &uint32Codec{} - } - return &uint64Codec{} - case reflect.Uint64: - if typeName != "uint64" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) - } - return &uint64Codec{} - case reflect.Float32: - if typeName != "float32" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) - } - return &float32Codec{} - case reflect.Float64: - if typeName != "float64" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) - } - return &float64Codec{} - case reflect.Bool: - if typeName != "bool" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) - } - return &boolCodec{} - } - return nil -} - -func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder { - if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { - sliceDecoder := decoderOfSlice(ctx, typ) - return &base64Codec{sliceDecoder: sliceDecoder} - } - typeName := typ.String() - switch typ.Kind() { - case reflect.String: - if typeName != "string" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) - } - return &stringCodec{} - case reflect.Int: - if typeName != "int" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) - } - if strconv.IntSize == 32 { - return &int32Codec{} - } - return &int64Codec{} - case reflect.Int8: - if typeName != "int8" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) - } - return &int8Codec{} - case reflect.Int16: - if typeName != "int16" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) - } - return &int16Codec{} - case reflect.Int32: - if typeName != "int32" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) - } - return &int32Codec{} - case reflect.Int64: - if typeName != "int64" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) - } - return &int64Codec{} - case reflect.Uint: - if typeName != "uint" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) - } - if strconv.IntSize == 32 { - return &uint32Codec{} - } - return &uint64Codec{} - case reflect.Uint8: - if typeName != "uint8" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) - } - return &uint8Codec{} - case reflect.Uint16: - if typeName != "uint16" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) - } - return &uint16Codec{} - case reflect.Uint32: - if typeName != "uint32" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) - } - return &uint32Codec{} - case reflect.Uintptr: - if typeName != "uintptr" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) - } - if ptrSize == 32 { - return &uint32Codec{} - } - return &uint64Codec{} - case reflect.Uint64: - if typeName != "uint64" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) - } - return &uint64Codec{} - case reflect.Float32: - if typeName != "float32" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) - } - return &float32Codec{} - case reflect.Float64: - if typeName != "float64" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) - } - return &float64Codec{} - case reflect.Bool: - if typeName != "bool" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) - } - return &boolCodec{} - } - return nil -} - -type stringCodec struct { -} - -func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*string)(ptr)) = iter.ReadString() -} - -func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - str := *((*string)(ptr)) - stream.WriteString(str) -} - -func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*string)(ptr)) == "" -} - -type int8Codec struct { -} - -func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*int8)(ptr)) = iter.ReadInt8() - } -} - -func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt8(*((*int8)(ptr))) -} - -func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int8)(ptr)) == 0 -} - -type int16Codec struct { -} - -func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*int16)(ptr)) = iter.ReadInt16() - } -} - -func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt16(*((*int16)(ptr))) -} - -func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int16)(ptr)) == 0 -} - -type int32Codec struct { -} - -func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*int32)(ptr)) = iter.ReadInt32() - } -} - -func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt32(*((*int32)(ptr))) -} - -func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int32)(ptr)) == 0 -} - -type int64Codec struct { -} - -func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*int64)(ptr)) = iter.ReadInt64() - } -} - -func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt64(*((*int64)(ptr))) -} - -func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int64)(ptr)) == 0 -} - -type uint8Codec struct { -} - -func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*uint8)(ptr)) = iter.ReadUint8() - } -} - -func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint8(*((*uint8)(ptr))) -} - -func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint8)(ptr)) == 0 -} - -type uint16Codec struct { -} - -func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*uint16)(ptr)) = iter.ReadUint16() - } -} - -func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint16(*((*uint16)(ptr))) -} - -func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint16)(ptr)) == 0 -} - -type uint32Codec struct { -} - -func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*uint32)(ptr)) = iter.ReadUint32() - } -} - -func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint32(*((*uint32)(ptr))) -} - -func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint32)(ptr)) == 0 -} - -type uint64Codec struct { -} - -func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*uint64)(ptr)) = iter.ReadUint64() - } -} - -func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint64(*((*uint64)(ptr))) -} - -func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint64)(ptr)) == 0 -} - -type float32Codec struct { -} - -func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*float32)(ptr)) = iter.ReadFloat32() - } -} - -func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteFloat32(*((*float32)(ptr))) -} - -func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*float32)(ptr)) == 0 -} - -type float64Codec struct { -} - -func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*float64)(ptr)) = iter.ReadFloat64() - } -} - -func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteFloat64(*((*float64)(ptr))) -} - -func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*float64)(ptr)) == 0 -} - -type boolCodec struct { -} - -func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*bool)(ptr)) = iter.ReadBool() - } -} - -func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteBool(*((*bool)(ptr))) -} - -func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool { - return !(*((*bool)(ptr))) -} - -type base64Codec struct { - sliceType *reflect2.UnsafeSliceType - sliceDecoder ValDecoder -} - -func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.ReadNil() { - codec.sliceType.UnsafeSetNil(ptr) - return - } - switch iter.WhatIsNext() { - case StringValue: - src := iter.ReadString() - dst, err := base64.StdEncoding.DecodeString(src) - if err != nil { - iter.ReportError("decode base64", err.Error()) - } else { - codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst)) - } - case ArrayValue: - codec.sliceDecoder.Decode(ptr, iter) - default: - iter.ReportError("base64Codec", "invalid input") - } -} - -func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - if codec.sliceType.UnsafeIsNil(ptr) { - stream.WriteNil() - return - } - src := *((*[]byte)(ptr)) - encoding := base64.StdEncoding - stream.writeByte('"') - if len(src) != 0 { - size := encoding.EncodedLen(len(src)) - buf := make([]byte, size) - encoding.Encode(buf, src) - stream.buf = append(stream.buf, buf...) - } - stream.writeByte('"') -} - -func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*[]byte)(ptr))) == 0 -} diff --git a/vendor/github.com/json-iterator/go/reflect_optional.go b/vendor/github.com/json-iterator/go/reflect_optional.go deleted file mode 100644 index fa71f4748..000000000 --- a/vendor/github.com/json-iterator/go/reflect_optional.go +++ /dev/null @@ -1,129 +0,0 @@ -package jsoniter - -import ( - "github.com/modern-go/reflect2" - "unsafe" -) - -func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder { - ptrType := typ.(*reflect2.UnsafePtrType) - elemType := ptrType.Elem() - decoder := decoderOfType(ctx, elemType) - return &OptionalDecoder{elemType, decoder} -} - -func encoderOfOptional(ctx *ctx, typ reflect2.Type) ValEncoder { - ptrType := typ.(*reflect2.UnsafePtrType) - elemType := ptrType.Elem() - elemEncoder := encoderOfType(ctx, elemType) - encoder := &OptionalEncoder{elemEncoder} - return encoder -} - -type OptionalDecoder struct { - ValueType reflect2.Type - ValueDecoder ValDecoder -} - -func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.ReadNil() { - *((*unsafe.Pointer)(ptr)) = nil - } else { - if *((*unsafe.Pointer)(ptr)) == nil { - //pointer to null, we have to allocate memory to hold the value - newPtr := decoder.ValueType.UnsafeNew() - decoder.ValueDecoder.Decode(newPtr, iter) - *((*unsafe.Pointer)(ptr)) = newPtr - } else { - //reuse existing instance - decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) - } - } -} - -type dereferenceDecoder struct { - // only to deference a pointer - valueType reflect2.Type - valueDecoder ValDecoder -} - -func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if *((*unsafe.Pointer)(ptr)) == nil { - //pointer to null, we have to allocate memory to hold the value - newPtr := decoder.valueType.UnsafeNew() - decoder.valueDecoder.Decode(newPtr, iter) - *((*unsafe.Pointer)(ptr)) = newPtr - } else { - //reuse existing instance - decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) - } -} - -type OptionalEncoder struct { - ValueEncoder ValEncoder -} - -func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if *((*unsafe.Pointer)(ptr)) == nil { - stream.WriteNil() - } else { - encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) - } -} - -func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return *((*unsafe.Pointer)(ptr)) == nil -} - -type dereferenceEncoder struct { - ValueEncoder ValEncoder -} - -func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if *((*unsafe.Pointer)(ptr)) == nil { - stream.WriteNil() - } else { - encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) - } -} - -func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { - dePtr := *((*unsafe.Pointer)(ptr)) - if dePtr == nil { - return true - } - return encoder.ValueEncoder.IsEmpty(dePtr) -} - -func (encoder *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { - deReferenced := *((*unsafe.Pointer)(ptr)) - if deReferenced == nil { - return true - } - isEmbeddedPtrNil, converted := encoder.ValueEncoder.(IsEmbeddedPtrNil) - if !converted { - return false - } - fieldPtr := unsafe.Pointer(deReferenced) - return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) -} - -type referenceEncoder struct { - encoder ValEncoder -} - -func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) -} - -func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) -} - -type referenceDecoder struct { - decoder ValDecoder -} - -func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.decoder.Decode(unsafe.Pointer(&ptr), iter) -} diff --git a/vendor/github.com/json-iterator/go/reflect_slice.go b/vendor/github.com/json-iterator/go/reflect_slice.go deleted file mode 100644 index 9441d79df..000000000 --- a/vendor/github.com/json-iterator/go/reflect_slice.go +++ /dev/null @@ -1,99 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "io" - "unsafe" -) - -func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder { - sliceType := typ.(*reflect2.UnsafeSliceType) - decoder := decoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) - return &sliceDecoder{sliceType, decoder} -} - -func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder { - sliceType := typ.(*reflect2.UnsafeSliceType) - encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) - return &sliceEncoder{sliceType, encoder} -} - -type sliceEncoder struct { - sliceType *reflect2.UnsafeSliceType - elemEncoder ValEncoder -} - -func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if encoder.sliceType.UnsafeIsNil(ptr) { - stream.WriteNil() - return - } - length := encoder.sliceType.UnsafeLengthOf(ptr) - if length == 0 { - stream.WriteEmptyArray() - return - } - stream.WriteArrayStart() - encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream) - for i := 1; i < length; i++ { - stream.WriteMore() - elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i) - encoder.elemEncoder.Encode(elemPtr, stream) - } - stream.WriteArrayEnd() - if stream.Error != nil && stream.Error != io.EOF { - stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error()) - } -} - -func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.sliceType.UnsafeLengthOf(ptr) == 0 -} - -type sliceDecoder struct { - sliceType *reflect2.UnsafeSliceType - elemDecoder ValDecoder -} - -func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.doDecode(ptr, iter) - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error()) - } -} - -func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { - c := iter.nextToken() - sliceType := decoder.sliceType - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - sliceType.UnsafeSetNil(ptr) - return - } - if c != '[' { - iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c})) - return - } - c = iter.nextToken() - if c == ']' { - sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0)) - return - } - iter.unreadByte() - sliceType.UnsafeGrow(ptr, 1) - elemPtr := sliceType.UnsafeGetIndex(ptr, 0) - decoder.elemDecoder.Decode(elemPtr, iter) - length := 1 - for c = iter.nextToken(); c == ','; c = iter.nextToken() { - idx := length - length += 1 - sliceType.UnsafeGrow(ptr, length) - elemPtr = sliceType.UnsafeGetIndex(ptr, idx) - decoder.elemDecoder.Decode(elemPtr, iter) - } - if c != ']' { - iter.ReportError("decode slice", "expect ], but found "+string([]byte{c})) - return - } -} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_decoder.go b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go deleted file mode 100644 index 92ae912dc..000000000 --- a/vendor/github.com/json-iterator/go/reflect_struct_decoder.go +++ /dev/null @@ -1,1097 +0,0 @@ -package jsoniter - -import ( - "fmt" - "io" - "strings" - "unsafe" - - "github.com/modern-go/reflect2" -) - -func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder { - bindings := map[string]*Binding{} - structDescriptor := describeStruct(ctx, typ) - for _, binding := range structDescriptor.Fields { - for _, fromName := range binding.FromNames { - old := bindings[fromName] - if old == nil { - bindings[fromName] = binding - continue - } - ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding) - if ignoreOld { - delete(bindings, fromName) - } - if !ignoreNew { - bindings[fromName] = binding - } - } - } - fields := map[string]*structFieldDecoder{} - for k, binding := range bindings { - fields[k] = binding.Decoder.(*structFieldDecoder) - } - - if !ctx.caseSensitive() { - for k, binding := range bindings { - if _, found := fields[strings.ToLower(k)]; !found { - fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder) - } - } - } - - return createStructDecoder(ctx, typ, fields) -} - -func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder { - if ctx.disallowUnknownFields { - return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true} - } - knownHash := map[int64]struct{}{ - 0: {}, - } - - switch len(fields) { - case 0: - return &skipObjectDecoder{typ} - case 1: - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName, ctx.caseSensitive()) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder} - } - case 2: - var fieldHash1 int64 - var fieldHash2 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName, ctx.caseSensitive()) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldHash1 == 0 { - fieldHash1 = fieldHash - fieldDecoder1 = fieldDecoder - } else { - fieldHash2 = fieldHash - fieldDecoder2 = fieldDecoder - } - } - return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2} - case 3: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName, ctx.caseSensitive()) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } - } - return &threeFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3} - case 4: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName, ctx.caseSensitive()) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } - } - return &fourFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4} - case 5: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName, ctx.caseSensitive()) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } - } - return &fiveFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5} - case 6: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldName6 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - var fieldDecoder6 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName, ctx.caseSensitive()) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else if fieldName5 == 0 { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } else { - fieldName6 = fieldHash - fieldDecoder6 = fieldDecoder - } - } - return &sixFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5, - fieldName6, fieldDecoder6} - case 7: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldName6 int64 - var fieldName7 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - var fieldDecoder6 *structFieldDecoder - var fieldDecoder7 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName, ctx.caseSensitive()) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else if fieldName5 == 0 { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } else if fieldName6 == 0 { - fieldName6 = fieldHash - fieldDecoder6 = fieldDecoder - } else { - fieldName7 = fieldHash - fieldDecoder7 = fieldDecoder - } - } - return &sevenFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5, - fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7} - case 8: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldName6 int64 - var fieldName7 int64 - var fieldName8 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - var fieldDecoder6 *structFieldDecoder - var fieldDecoder7 *structFieldDecoder - var fieldDecoder8 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName, ctx.caseSensitive()) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else if fieldName5 == 0 { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } else if fieldName6 == 0 { - fieldName6 = fieldHash - fieldDecoder6 = fieldDecoder - } else if fieldName7 == 0 { - fieldName7 = fieldHash - fieldDecoder7 = fieldDecoder - } else { - fieldName8 = fieldHash - fieldDecoder8 = fieldDecoder - } - } - return &eightFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5, - fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, - fieldName8, fieldDecoder8} - case 9: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldName6 int64 - var fieldName7 int64 - var fieldName8 int64 - var fieldName9 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - var fieldDecoder6 *structFieldDecoder - var fieldDecoder7 *structFieldDecoder - var fieldDecoder8 *structFieldDecoder - var fieldDecoder9 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName, ctx.caseSensitive()) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else if fieldName5 == 0 { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } else if fieldName6 == 0 { - fieldName6 = fieldHash - fieldDecoder6 = fieldDecoder - } else if fieldName7 == 0 { - fieldName7 = fieldHash - fieldDecoder7 = fieldDecoder - } else if fieldName8 == 0 { - fieldName8 = fieldHash - fieldDecoder8 = fieldDecoder - } else { - fieldName9 = fieldHash - fieldDecoder9 = fieldDecoder - } - } - return &nineFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5, - fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, - fieldName8, fieldDecoder8, - fieldName9, fieldDecoder9} - case 10: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldName6 int64 - var fieldName7 int64 - var fieldName8 int64 - var fieldName9 int64 - var fieldName10 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - var fieldDecoder6 *structFieldDecoder - var fieldDecoder7 *structFieldDecoder - var fieldDecoder8 *structFieldDecoder - var fieldDecoder9 *structFieldDecoder - var fieldDecoder10 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName, ctx.caseSensitive()) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else if fieldName5 == 0 { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } else if fieldName6 == 0 { - fieldName6 = fieldHash - fieldDecoder6 = fieldDecoder - } else if fieldName7 == 0 { - fieldName7 = fieldHash - fieldDecoder7 = fieldDecoder - } else if fieldName8 == 0 { - fieldName8 = fieldHash - fieldDecoder8 = fieldDecoder - } else if fieldName9 == 0 { - fieldName9 = fieldHash - fieldDecoder9 = fieldDecoder - } else { - fieldName10 = fieldHash - fieldDecoder10 = fieldDecoder - } - } - return &tenFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5, - fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, - fieldName8, fieldDecoder8, - fieldName9, fieldDecoder9, - fieldName10, fieldDecoder10} - } - return &generalStructDecoder{typ, fields, false} -} - -type generalStructDecoder struct { - typ reflect2.Type - fields map[string]*structFieldDecoder - disallowUnknownFields bool -} - -func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - if !iter.incrementDepth() { - return - } - var c byte - for c = ','; c == ','; c = iter.nextToken() { - decoder.decodeOneField(ptr, iter) - } - if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } - if c != '}' { - iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c})) - } - iter.decrementDepth() -} - -func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) { - var field string - var fieldDecoder *structFieldDecoder - if iter.cfg.objectFieldMustBeSimpleString { - fieldBytes := iter.ReadStringAsSlice() - field = *(*string)(unsafe.Pointer(&fieldBytes)) - fieldDecoder = decoder.fields[field] - if fieldDecoder == nil && !iter.cfg.caseSensitive { - fieldDecoder = decoder.fields[strings.ToLower(field)] - } - } else { - field = iter.ReadString() - fieldDecoder = decoder.fields[field] - if fieldDecoder == nil && !iter.cfg.caseSensitive { - fieldDecoder = decoder.fields[strings.ToLower(field)] - } - } - if fieldDecoder == nil { - if decoder.disallowUnknownFields { - msg := "found unknown field: " + field - iter.ReportError("ReadObject", msg) - } - c := iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - iter.Skip() - return - } - c := iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - fieldDecoder.Decode(ptr, iter) -} - -type skipObjectDecoder struct { - typ reflect2.Type -} - -func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - valueType := iter.WhatIsNext() - if valueType != ObjectValue && valueType != NilValue { - iter.ReportError("skipObjectDecoder", "expect object or null") - return - } - iter.Skip() -} - -type oneFieldStructDecoder struct { - typ reflect2.Type - fieldHash int64 - fieldDecoder *structFieldDecoder -} - -func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - if !iter.incrementDepth() { - return - } - for { - if iter.readFieldHash() == decoder.fieldHash { - decoder.fieldDecoder.Decode(ptr, iter) - } else { - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } - iter.decrementDepth() -} - -type twoFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder -} - -func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - if !iter.incrementDepth() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } - iter.decrementDepth() -} - -type threeFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder -} - -func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - if !iter.incrementDepth() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } - iter.decrementDepth() -} - -type fourFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder -} - -func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - if !iter.incrementDepth() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } - iter.decrementDepth() -} - -type fiveFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder -} - -func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - if !iter.incrementDepth() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } - iter.decrementDepth() -} - -type sixFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder - fieldHash6 int64 - fieldDecoder6 *structFieldDecoder -} - -func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - if !iter.incrementDepth() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - case decoder.fieldHash6: - decoder.fieldDecoder6.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } - iter.decrementDepth() -} - -type sevenFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder - fieldHash6 int64 - fieldDecoder6 *structFieldDecoder - fieldHash7 int64 - fieldDecoder7 *structFieldDecoder -} - -func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - if !iter.incrementDepth() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - case decoder.fieldHash6: - decoder.fieldDecoder6.Decode(ptr, iter) - case decoder.fieldHash7: - decoder.fieldDecoder7.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } - iter.decrementDepth() -} - -type eightFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder - fieldHash6 int64 - fieldDecoder6 *structFieldDecoder - fieldHash7 int64 - fieldDecoder7 *structFieldDecoder - fieldHash8 int64 - fieldDecoder8 *structFieldDecoder -} - -func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - if !iter.incrementDepth() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - case decoder.fieldHash6: - decoder.fieldDecoder6.Decode(ptr, iter) - case decoder.fieldHash7: - decoder.fieldDecoder7.Decode(ptr, iter) - case decoder.fieldHash8: - decoder.fieldDecoder8.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } - iter.decrementDepth() -} - -type nineFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder - fieldHash6 int64 - fieldDecoder6 *structFieldDecoder - fieldHash7 int64 - fieldDecoder7 *structFieldDecoder - fieldHash8 int64 - fieldDecoder8 *structFieldDecoder - fieldHash9 int64 - fieldDecoder9 *structFieldDecoder -} - -func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - if !iter.incrementDepth() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - case decoder.fieldHash6: - decoder.fieldDecoder6.Decode(ptr, iter) - case decoder.fieldHash7: - decoder.fieldDecoder7.Decode(ptr, iter) - case decoder.fieldHash8: - decoder.fieldDecoder8.Decode(ptr, iter) - case decoder.fieldHash9: - decoder.fieldDecoder9.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } - iter.decrementDepth() -} - -type tenFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder - fieldHash6 int64 - fieldDecoder6 *structFieldDecoder - fieldHash7 int64 - fieldDecoder7 *structFieldDecoder - fieldHash8 int64 - fieldDecoder8 *structFieldDecoder - fieldHash9 int64 - fieldDecoder9 *structFieldDecoder - fieldHash10 int64 - fieldDecoder10 *structFieldDecoder -} - -func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - if !iter.incrementDepth() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - case decoder.fieldHash6: - decoder.fieldDecoder6.Decode(ptr, iter) - case decoder.fieldHash7: - decoder.fieldDecoder7.Decode(ptr, iter) - case decoder.fieldHash8: - decoder.fieldDecoder8.Decode(ptr, iter) - case decoder.fieldHash9: - decoder.fieldDecoder9.Decode(ptr, iter) - case decoder.fieldHash10: - decoder.fieldDecoder10.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } - iter.decrementDepth() -} - -type structFieldDecoder struct { - field reflect2.StructField - fieldDecoder ValDecoder -} - -func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - fieldPtr := decoder.field.UnsafeGet(ptr) - decoder.fieldDecoder.Decode(fieldPtr, iter) - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error()) - } -} - -type stringModeStringDecoder struct { - elemDecoder ValDecoder - cfg *frozenConfig -} - -func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.elemDecoder.Decode(ptr, iter) - str := *((*string)(ptr)) - tempIter := decoder.cfg.BorrowIterator([]byte(str)) - defer decoder.cfg.ReturnIterator(tempIter) - *((*string)(ptr)) = tempIter.ReadString() -} - -type stringModeNumberDecoder struct { - elemDecoder ValDecoder -} - -func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.WhatIsNext() == NilValue { - decoder.elemDecoder.Decode(ptr, iter) - return - } - - c := iter.nextToken() - if c != '"' { - iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) - return - } - decoder.elemDecoder.Decode(ptr, iter) - if iter.Error != nil { - return - } - c = iter.readByte() - if c != '"' { - iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) - return - } -} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_encoder.go b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go deleted file mode 100644 index 152e3ef5a..000000000 --- a/vendor/github.com/json-iterator/go/reflect_struct_encoder.go +++ /dev/null @@ -1,211 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "io" - "reflect" - "unsafe" -) - -func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder { - type bindingTo struct { - binding *Binding - toName string - ignored bool - } - orderedBindings := []*bindingTo{} - structDescriptor := describeStruct(ctx, typ) - for _, binding := range structDescriptor.Fields { - for _, toName := range binding.ToNames { - new := &bindingTo{ - binding: binding, - toName: toName, - } - for _, old := range orderedBindings { - if old.toName != toName { - continue - } - old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding) - } - orderedBindings = append(orderedBindings, new) - } - } - if len(orderedBindings) == 0 { - return &emptyStructEncoder{} - } - finalOrderedFields := []structFieldTo{} - for _, bindingTo := range orderedBindings { - if !bindingTo.ignored { - finalOrderedFields = append(finalOrderedFields, structFieldTo{ - encoder: bindingTo.binding.Encoder.(*structFieldEncoder), - toName: bindingTo.toName, - }) - } - } - return &structEncoder{typ, finalOrderedFields} -} - -func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty { - encoder := createEncoderOfNative(ctx, typ) - if encoder != nil { - return encoder - } - kind := typ.Kind() - switch kind { - case reflect.Interface: - return &dynamicEncoder{typ} - case reflect.Struct: - return &structEncoder{typ: typ} - case reflect.Array: - return &arrayEncoder{} - case reflect.Slice: - return &sliceEncoder{} - case reflect.Map: - return encoderOfMap(ctx, typ) - case reflect.Ptr: - return &OptionalEncoder{} - default: - return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)} - } -} - -func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) { - newTagged := new.Field.Tag().Get(cfg.getTagKey()) != "" - oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != "" - if newTagged { - if oldTagged { - if len(old.levels) > len(new.levels) { - return true, false - } else if len(new.levels) > len(old.levels) { - return false, true - } else { - return true, true - } - } else { - return true, false - } - } else { - if oldTagged { - return true, false - } - if len(old.levels) > len(new.levels) { - return true, false - } else if len(new.levels) > len(old.levels) { - return false, true - } else { - return true, true - } - } -} - -type structFieldEncoder struct { - field reflect2.StructField - fieldEncoder ValEncoder - omitempty bool -} - -func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - fieldPtr := encoder.field.UnsafeGet(ptr) - encoder.fieldEncoder.Encode(fieldPtr, stream) - if stream.Error != nil && stream.Error != io.EOF { - stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error()) - } -} - -func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool { - fieldPtr := encoder.field.UnsafeGet(ptr) - return encoder.fieldEncoder.IsEmpty(fieldPtr) -} - -func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { - isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil) - if !converted { - return false - } - fieldPtr := encoder.field.UnsafeGet(ptr) - return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) -} - -type IsEmbeddedPtrNil interface { - IsEmbeddedPtrNil(ptr unsafe.Pointer) bool -} - -type structEncoder struct { - typ reflect2.Type - fields []structFieldTo -} - -type structFieldTo struct { - encoder *structFieldEncoder - toName string -} - -func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteObjectStart() - isNotFirst := false - for _, field := range encoder.fields { - if field.encoder.omitempty && field.encoder.IsEmpty(ptr) { - continue - } - if field.encoder.IsEmbeddedPtrNil(ptr) { - continue - } - if isNotFirst { - stream.WriteMore() - } - stream.WriteObjectField(field.toName) - field.encoder.Encode(ptr, stream) - isNotFirst = true - } - stream.WriteObjectEnd() - if stream.Error != nil && stream.Error != io.EOF { - stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error()) - } -} - -func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return false -} - -type emptyStructEncoder struct { -} - -func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteEmptyObject() -} - -func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return false -} - -type stringModeNumberEncoder struct { - elemEncoder ValEncoder -} - -func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.writeByte('"') - encoder.elemEncoder.Encode(ptr, stream) - stream.writeByte('"') -} - -func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.elemEncoder.IsEmpty(ptr) -} - -type stringModeStringEncoder struct { - elemEncoder ValEncoder - cfg *frozenConfig -} - -func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - tempStream := encoder.cfg.BorrowStream(nil) - tempStream.Attachment = stream.Attachment - defer encoder.cfg.ReturnStream(tempStream) - encoder.elemEncoder.Encode(ptr, tempStream) - stream.WriteString(string(tempStream.Buffer())) -} - -func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.elemEncoder.IsEmpty(ptr) -} diff --git a/vendor/github.com/json-iterator/go/stream.go b/vendor/github.com/json-iterator/go/stream.go deleted file mode 100644 index 23d8a3ad6..000000000 --- a/vendor/github.com/json-iterator/go/stream.go +++ /dev/null @@ -1,210 +0,0 @@ -package jsoniter - -import ( - "io" -) - -// stream is a io.Writer like object, with JSON specific write functions. -// Error is not returned as return value, but stored as Error member on this stream instance. -type Stream struct { - cfg *frozenConfig - out io.Writer - buf []byte - Error error - indention int - Attachment interface{} // open for customized encoder -} - -// NewStream create new stream instance. -// cfg can be jsoniter.ConfigDefault. -// out can be nil if write to internal buffer. -// bufSize is the initial size for the internal buffer in bytes. -func NewStream(cfg API, out io.Writer, bufSize int) *Stream { - return &Stream{ - cfg: cfg.(*frozenConfig), - out: out, - buf: make([]byte, 0, bufSize), - Error: nil, - indention: 0, - } -} - -// Pool returns a pool can provide more stream with same configuration -func (stream *Stream) Pool() StreamPool { - return stream.cfg -} - -// Reset reuse this stream instance by assign a new writer -func (stream *Stream) Reset(out io.Writer) { - stream.out = out - stream.buf = stream.buf[:0] -} - -// Available returns how many bytes are unused in the buffer. -func (stream *Stream) Available() int { - return cap(stream.buf) - len(stream.buf) -} - -// Buffered returns the number of bytes that have been written into the current buffer. -func (stream *Stream) Buffered() int { - return len(stream.buf) -} - -// Buffer if writer is nil, use this method to take the result -func (stream *Stream) Buffer() []byte { - return stream.buf -} - -// SetBuffer allows to append to the internal buffer directly -func (stream *Stream) SetBuffer(buf []byte) { - stream.buf = buf -} - -// Write writes the contents of p into the buffer. -// It returns the number of bytes written. -// If nn < len(p), it also returns an error explaining -// why the write is short. -func (stream *Stream) Write(p []byte) (nn int, err error) { - stream.buf = append(stream.buf, p...) - if stream.out != nil { - nn, err = stream.out.Write(stream.buf) - stream.buf = stream.buf[nn:] - return - } - return len(p), nil -} - -// WriteByte writes a single byte. -func (stream *Stream) writeByte(c byte) { - stream.buf = append(stream.buf, c) -} - -func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) { - stream.buf = append(stream.buf, c1, c2) -} - -func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) { - stream.buf = append(stream.buf, c1, c2, c3) -} - -func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) { - stream.buf = append(stream.buf, c1, c2, c3, c4) -} - -func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) { - stream.buf = append(stream.buf, c1, c2, c3, c4, c5) -} - -// Flush writes any buffered data to the underlying io.Writer. -func (stream *Stream) Flush() error { - if stream.out == nil { - return nil - } - if stream.Error != nil { - return stream.Error - } - _, err := stream.out.Write(stream.buf) - if err != nil { - if stream.Error == nil { - stream.Error = err - } - return err - } - stream.buf = stream.buf[:0] - return nil -} - -// WriteRaw write string out without quotes, just like []byte -func (stream *Stream) WriteRaw(s string) { - stream.buf = append(stream.buf, s...) -} - -// WriteNil write null to stream -func (stream *Stream) WriteNil() { - stream.writeFourBytes('n', 'u', 'l', 'l') -} - -// WriteTrue write true to stream -func (stream *Stream) WriteTrue() { - stream.writeFourBytes('t', 'r', 'u', 'e') -} - -// WriteFalse write false to stream -func (stream *Stream) WriteFalse() { - stream.writeFiveBytes('f', 'a', 'l', 's', 'e') -} - -// WriteBool write true or false into stream -func (stream *Stream) WriteBool(val bool) { - if val { - stream.WriteTrue() - } else { - stream.WriteFalse() - } -} - -// WriteObjectStart write { with possible indention -func (stream *Stream) WriteObjectStart() { - stream.indention += stream.cfg.indentionStep - stream.writeByte('{') - stream.writeIndention(0) -} - -// WriteObjectField write "field": with possible indention -func (stream *Stream) WriteObjectField(field string) { - stream.WriteString(field) - if stream.indention > 0 { - stream.writeTwoBytes(':', ' ') - } else { - stream.writeByte(':') - } -} - -// WriteObjectEnd write } with possible indention -func (stream *Stream) WriteObjectEnd() { - stream.writeIndention(stream.cfg.indentionStep) - stream.indention -= stream.cfg.indentionStep - stream.writeByte('}') -} - -// WriteEmptyObject write {} -func (stream *Stream) WriteEmptyObject() { - stream.writeByte('{') - stream.writeByte('}') -} - -// WriteMore write , with possible indention -func (stream *Stream) WriteMore() { - stream.writeByte(',') - stream.writeIndention(0) -} - -// WriteArrayStart write [ with possible indention -func (stream *Stream) WriteArrayStart() { - stream.indention += stream.cfg.indentionStep - stream.writeByte('[') - stream.writeIndention(0) -} - -// WriteEmptyArray write [] -func (stream *Stream) WriteEmptyArray() { - stream.writeTwoBytes('[', ']') -} - -// WriteArrayEnd write ] with possible indention -func (stream *Stream) WriteArrayEnd() { - stream.writeIndention(stream.cfg.indentionStep) - stream.indention -= stream.cfg.indentionStep - stream.writeByte(']') -} - -func (stream *Stream) writeIndention(delta int) { - if stream.indention == 0 { - return - } - stream.writeByte('\n') - toWrite := stream.indention - delta - for i := 0; i < toWrite; i++ { - stream.buf = append(stream.buf, ' ') - } -} diff --git a/vendor/github.com/json-iterator/go/stream_float.go b/vendor/github.com/json-iterator/go/stream_float.go deleted file mode 100644 index 826aa594a..000000000 --- a/vendor/github.com/json-iterator/go/stream_float.go +++ /dev/null @@ -1,111 +0,0 @@ -package jsoniter - -import ( - "fmt" - "math" - "strconv" -) - -var pow10 []uint64 - -func init() { - pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000} -} - -// WriteFloat32 write float32 to stream -func (stream *Stream) WriteFloat32(val float32) { - if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) { - stream.Error = fmt.Errorf("unsupported value: %f", val) - return - } - abs := math.Abs(float64(val)) - fmt := byte('f') - // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. - if abs != 0 { - if float32(abs) < 1e-6 || float32(abs) >= 1e21 { - fmt = 'e' - } - } - stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32) -} - -// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster -func (stream *Stream) WriteFloat32Lossy(val float32) { - if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) { - stream.Error = fmt.Errorf("unsupported value: %f", val) - return - } - if val < 0 { - stream.writeByte('-') - val = -val - } - if val > 0x4ffffff { - stream.WriteFloat32(val) - return - } - precision := 6 - exp := uint64(1000000) // 6 - lval := uint64(float64(val)*float64(exp) + 0.5) - stream.WriteUint64(lval / exp) - fval := lval % exp - if fval == 0 { - return - } - stream.writeByte('.') - for p := precision - 1; p > 0 && fval < pow10[p]; p-- { - stream.writeByte('0') - } - stream.WriteUint64(fval) - for stream.buf[len(stream.buf)-1] == '0' { - stream.buf = stream.buf[:len(stream.buf)-1] - } -} - -// WriteFloat64 write float64 to stream -func (stream *Stream) WriteFloat64(val float64) { - if math.IsInf(val, 0) || math.IsNaN(val) { - stream.Error = fmt.Errorf("unsupported value: %f", val) - return - } - abs := math.Abs(val) - fmt := byte('f') - // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. - if abs != 0 { - if abs < 1e-6 || abs >= 1e21 { - fmt = 'e' - } - } - stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64) -} - -// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster -func (stream *Stream) WriteFloat64Lossy(val float64) { - if math.IsInf(val, 0) || math.IsNaN(val) { - stream.Error = fmt.Errorf("unsupported value: %f", val) - return - } - if val < 0 { - stream.writeByte('-') - val = -val - } - if val > 0x4ffffff { - stream.WriteFloat64(val) - return - } - precision := 6 - exp := uint64(1000000) // 6 - lval := uint64(val*float64(exp) + 0.5) - stream.WriteUint64(lval / exp) - fval := lval % exp - if fval == 0 { - return - } - stream.writeByte('.') - for p := precision - 1; p > 0 && fval < pow10[p]; p-- { - stream.writeByte('0') - } - stream.WriteUint64(fval) - for stream.buf[len(stream.buf)-1] == '0' { - stream.buf = stream.buf[:len(stream.buf)-1] - } -} diff --git a/vendor/github.com/json-iterator/go/stream_int.go b/vendor/github.com/json-iterator/go/stream_int.go deleted file mode 100644 index d1059ee4c..000000000 --- a/vendor/github.com/json-iterator/go/stream_int.go +++ /dev/null @@ -1,190 +0,0 @@ -package jsoniter - -var digits []uint32 - -func init() { - digits = make([]uint32, 1000) - for i := uint32(0); i < 1000; i++ { - digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0' - if i < 10 { - digits[i] += 2 << 24 - } else if i < 100 { - digits[i] += 1 << 24 - } - } -} - -func writeFirstBuf(space []byte, v uint32) []byte { - start := v >> 24 - if start == 0 { - space = append(space, byte(v>>16), byte(v>>8)) - } else if start == 1 { - space = append(space, byte(v>>8)) - } - space = append(space, byte(v)) - return space -} - -func writeBuf(buf []byte, v uint32) []byte { - return append(buf, byte(v>>16), byte(v>>8), byte(v)) -} - -// WriteUint8 write uint8 to stream -func (stream *Stream) WriteUint8(val uint8) { - stream.buf = writeFirstBuf(stream.buf, digits[val]) -} - -// WriteInt8 write int8 to stream -func (stream *Stream) WriteInt8(nval int8) { - var val uint8 - if nval < 0 { - val = uint8(-nval) - stream.buf = append(stream.buf, '-') - } else { - val = uint8(nval) - } - stream.buf = writeFirstBuf(stream.buf, digits[val]) -} - -// WriteUint16 write uint16 to stream -func (stream *Stream) WriteUint16(val uint16) { - q1 := val / 1000 - if q1 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[val]) - return - } - r1 := val - q1*1000 - stream.buf = writeFirstBuf(stream.buf, digits[q1]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return -} - -// WriteInt16 write int16 to stream -func (stream *Stream) WriteInt16(nval int16) { - var val uint16 - if nval < 0 { - val = uint16(-nval) - stream.buf = append(stream.buf, '-') - } else { - val = uint16(nval) - } - stream.WriteUint16(val) -} - -// WriteUint32 write uint32 to stream -func (stream *Stream) WriteUint32(val uint32) { - q1 := val / 1000 - if q1 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[val]) - return - } - r1 := val - q1*1000 - q2 := q1 / 1000 - if q2 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q1]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return - } - r2 := q1 - q2*1000 - q3 := q2 / 1000 - if q3 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q2]) - } else { - r3 := q2 - q3*1000 - stream.buf = append(stream.buf, byte(q3+'0')) - stream.buf = writeBuf(stream.buf, digits[r3]) - } - stream.buf = writeBuf(stream.buf, digits[r2]) - stream.buf = writeBuf(stream.buf, digits[r1]) -} - -// WriteInt32 write int32 to stream -func (stream *Stream) WriteInt32(nval int32) { - var val uint32 - if nval < 0 { - val = uint32(-nval) - stream.buf = append(stream.buf, '-') - } else { - val = uint32(nval) - } - stream.WriteUint32(val) -} - -// WriteUint64 write uint64 to stream -func (stream *Stream) WriteUint64(val uint64) { - q1 := val / 1000 - if q1 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[val]) - return - } - r1 := val - q1*1000 - q2 := q1 / 1000 - if q2 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q1]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return - } - r2 := q1 - q2*1000 - q3 := q2 / 1000 - if q3 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q2]) - stream.buf = writeBuf(stream.buf, digits[r2]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return - } - r3 := q2 - q3*1000 - q4 := q3 / 1000 - if q4 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q3]) - stream.buf = writeBuf(stream.buf, digits[r3]) - stream.buf = writeBuf(stream.buf, digits[r2]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return - } - r4 := q3 - q4*1000 - q5 := q4 / 1000 - if q5 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q4]) - stream.buf = writeBuf(stream.buf, digits[r4]) - stream.buf = writeBuf(stream.buf, digits[r3]) - stream.buf = writeBuf(stream.buf, digits[r2]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return - } - r5 := q4 - q5*1000 - q6 := q5 / 1000 - if q6 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q5]) - } else { - stream.buf = writeFirstBuf(stream.buf, digits[q6]) - r6 := q5 - q6*1000 - stream.buf = writeBuf(stream.buf, digits[r6]) - } - stream.buf = writeBuf(stream.buf, digits[r5]) - stream.buf = writeBuf(stream.buf, digits[r4]) - stream.buf = writeBuf(stream.buf, digits[r3]) - stream.buf = writeBuf(stream.buf, digits[r2]) - stream.buf = writeBuf(stream.buf, digits[r1]) -} - -// WriteInt64 write int64 to stream -func (stream *Stream) WriteInt64(nval int64) { - var val uint64 - if nval < 0 { - val = uint64(-nval) - stream.buf = append(stream.buf, '-') - } else { - val = uint64(nval) - } - stream.WriteUint64(val) -} - -// WriteInt write int to stream -func (stream *Stream) WriteInt(val int) { - stream.WriteInt64(int64(val)) -} - -// WriteUint write uint to stream -func (stream *Stream) WriteUint(val uint) { - stream.WriteUint64(uint64(val)) -} diff --git a/vendor/github.com/json-iterator/go/stream_str.go b/vendor/github.com/json-iterator/go/stream_str.go deleted file mode 100644 index 54c2ba0b3..000000000 --- a/vendor/github.com/json-iterator/go/stream_str.go +++ /dev/null @@ -1,372 +0,0 @@ -package jsoniter - -import ( - "unicode/utf8" -) - -// htmlSafeSet holds the value true if the ASCII character with the given -// array position can be safely represented inside a JSON string, embedded -// inside of HTML - -`) - w.WriteString("") - w.WriteString("

") - w.WriteString(html.EscapeString(name)) - w.WriteString("

") - w.WriteString(` -help -
- -

-Click on a value or block to toggle highlighting of that value/block -and its uses. (Values and blocks are highlighted by ID, and IDs of -dead items may be reused, so not all highlights necessarily correspond -to the clicked item.) -

- -

-Faded out values and blocks are dead code that has not been eliminated. -

- -

-Values printed in italics have a dependency cycle. -

- -

-CFG: Dashed edge is for unlikely branches. Blue color is for backward edges. -Edge with a dot means that this edge follows the order in which blocks were laid out. -

- -
-`) - w.WriteString("") - w.WriteString("") -} - -func (w *HTMLWriter) Close() { - if w == nil { - return - } - io.WriteString(w.w, "") - io.WriteString(w.w, "
") - io.WriteString(w.w, "") - io.WriteString(w.w, "") - w.w.Close() - fmt.Printf("dumped IR to %v\n", w.path) -} - -// WriteFunc writes f in a column headed by title. -// phase is used for collapsing columns and should be unique across the table. -func (w *HTMLWriter) WriteFunc(phase, title string, f *Function) { - if w == nil { - return - } - w.WriteColumn(phase, title, "", funcHTML(f, phase, w.dot)) -} - -// WriteColumn writes raw HTML in a column headed by title. -// It is intended for pre- and post-compilation log output. -func (w *HTMLWriter) WriteColumn(phase, title, class, html string) { - if w == nil { - return - } - id := strings.Replace(phase, " ", "-", -1) - // collapsed column - w.Printf("
%v
", id, phase) - - if class == "" { - w.Printf("", id) - } else { - w.Printf("", id, class) - } - w.WriteString("

" + title + "

") - w.WriteString(html) - w.WriteString("") -} - -func (w *HTMLWriter) Printf(msg string, v ...interface{}) { - if _, err := fmt.Fprintf(w.w, msg, v...); err != nil { - log.Fatalf("%v", err) - } -} - -func (w *HTMLWriter) WriteString(s string) { - if _, err := io.WriteString(w.w, s); err != nil { - log.Fatalf("%v", err) - } -} - -func valueHTML(v Node) string { - if v == nil { - return "<nil>" - } - // TODO: Using the value ID as the class ignores the fact - // that value IDs get recycled and that some values - // are transmuted into other values. - class := fmt.Sprintf("t%d", v.ID()) - var label string - switch v := v.(type) { - case *Function: - label = v.RelString(nil) - case *Builtin: - label = v.Name() - default: - label = class - } - return fmt.Sprintf("%s", class, label) -} - -func valueLongHTML(v Node) string { - // TODO: Any intra-value formatting? - // I'm wary of adding too much visual noise, - // but a little bit might be valuable. - // We already have visual noise in the form of punctuation - // maybe we could replace some of that with formatting. - s := fmt.Sprintf("", v.ID()) - - linenumber := "(?)" - if v.Pos().IsValid() { - line := v.Parent().Prog.Fset.Position(v.Pos()).Line - linenumber = fmt.Sprintf("(%d)", line, line) - } - - s += fmt.Sprintf("%s %s = %s", valueHTML(v), linenumber, opName(v)) - - if v, ok := v.(Value); ok { - s += " <" + html.EscapeString(v.Type().String()) + ">" - } - - switch v := v.(type) { - case *Parameter: - s += fmt.Sprintf(" {%s}", html.EscapeString(v.name)) - case *BinOp: - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Op.String())) - case *UnOp: - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Op.String())) - case *Extract: - name := v.Tuple.Type().(*types.Tuple).At(v.Index).Name() - s += fmt.Sprintf(" [%d] (%s)", v.Index, name) - case *Field: - st := v.X.Type().Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - s += fmt.Sprintf(" [%d] (%s)", v.Field, name) - case *FieldAddr: - st := deref(v.X.Type()).Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - - s += fmt.Sprintf(" [%d] (%s)", v.Field, name) - case *Recv: - s += fmt.Sprintf(" {%t}", v.CommaOk) - case *Call: - if v.Common().IsInvoke() { - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Common().Method.FullName())) - } - case *Const: - if v.Value == nil { - s += " {<nil>}" - } else { - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Value.String())) - } - case *Sigma: - s += fmt.Sprintf(" [#%s]", v.From) - } - for _, a := range v.Operands(nil) { - s += fmt.Sprintf(" %s", valueHTML(*a)) - } - if v, ok := v.(Instruction); ok { - s += fmt.Sprintf(" (%s)", v.Comment()) - } - - // OPT(dh): we're calling namedValues many times on the same function. - allNames := namedValues(v.Parent()) - var names []string - for name, values := range allNames { - for _, value := range values { - if v == value { - names = append(names, name.Name()) - break - } - } - } - if len(names) != 0 { - s += " (" + strings.Join(names, ", ") + ")" - } - - s += "" - return s -} - -func blockHTML(b *BasicBlock) string { - // TODO: Using the value ID as the class ignores the fact - // that value IDs get recycled and that some values - // are transmuted into other values. - s := html.EscapeString(b.String()) - return fmt.Sprintf("%s", s, s) -} - -func blockLongHTML(b *BasicBlock) string { - var kind string - var term Instruction - if len(b.Instrs) > 0 { - term = b.Control() - kind = opName(term) - } - // TODO: improve this for HTML? - s := fmt.Sprintf("%s", b.Index, kind) - - if term != nil { - ops := term.Operands(nil) - if len(ops) > 0 { - var ss []string - for _, op := range ops { - ss = append(ss, valueHTML(*op)) - } - s += " " + strings.Join(ss, ", ") - } - } - if len(b.Succs) > 0 { - s += " →" // right arrow - for _, c := range b.Succs { - s += " " + blockHTML(c) - } - } - return s -} - -func funcHTML(f *Function, phase string, dot *dotWriter) string { - buf := new(bytes.Buffer) - if dot != nil { - dot.writeFuncSVG(buf, phase, f) - } - fmt.Fprint(buf, "") - p := htmlFuncPrinter{w: buf} - fprintFunc(p, f) - - // fprintFunc(&buf, f) // TODO: HTML, not text,
for line breaks, etc. - fmt.Fprint(buf, "
") - return buf.String() -} - -type htmlFuncPrinter struct { - w io.Writer -} - -func (p htmlFuncPrinter) startBlock(b *BasicBlock, reachable bool) { - var dead string - if !reachable { - dead = "dead-block" - } - fmt.Fprintf(p.w, "
    ", b, dead) - fmt.Fprintf(p.w, "
  • %s:", blockHTML(b)) - if len(b.Preds) > 0 { - io.WriteString(p.w, " ←") // left arrow - for _, pred := range b.Preds { - fmt.Fprintf(p.w, " %s", blockHTML(pred)) - } - } - if len(b.Instrs) > 0 { - io.WriteString(p.w, ``) - } - io.WriteString(p.w, "
  • ") - if len(b.Instrs) > 0 { // start list of values - io.WriteString(p.w, "
  • ") - io.WriteString(p.w, "
      ") - } -} - -func (p htmlFuncPrinter) endBlock(b *BasicBlock) { - if len(b.Instrs) > 0 { // end list of values - io.WriteString(p.w, "
    ") - io.WriteString(p.w, "
  • ") - } - io.WriteString(p.w, "
  • ") - fmt.Fprint(p.w, blockLongHTML(b)) - io.WriteString(p.w, "
  • ") - io.WriteString(p.w, "
") -} - -func (p htmlFuncPrinter) value(v Node, live bool) { - var dead string - if !live { - dead = "dead-value" - } - fmt.Fprintf(p.w, "
  • ", dead) - fmt.Fprint(p.w, valueLongHTML(v)) - io.WriteString(p.w, "
  • ") -} - -func (p htmlFuncPrinter) startDepCycle() { - fmt.Fprintln(p.w, "") -} - -func (p htmlFuncPrinter) endDepCycle() { - fmt.Fprintln(p.w, "") -} - -func (p htmlFuncPrinter) named(n string, vals []Value) { - fmt.Fprintf(p.w, "
  • name %s: ", n) - for _, val := range vals { - fmt.Fprintf(p.w, "%s ", valueHTML(val)) - } - fmt.Fprintf(p.w, "
  • ") -} - -type dotWriter struct { - path string - broken bool -} - -// newDotWriter returns non-nil value when mask is valid. -// dotWriter will generate SVGs only for the phases specified in the mask. -// mask can contain following patterns and combinations of them: -// * - all of them; -// x-y - x through y, inclusive; -// x,y - x and y, but not the passes between. -func newDotWriter() *dotWriter { - path, err := exec.LookPath("dot") - if err != nil { - fmt.Println(err) - return nil - } - return &dotWriter{path: path} -} - -func (d *dotWriter) writeFuncSVG(w io.Writer, phase string, f *Function) { - if d.broken { - return - } - cmd := exec.Command(d.path, "-Tsvg") - pipe, err := cmd.StdinPipe() - if err != nil { - d.broken = true - fmt.Println(err) - return - } - buf := new(bytes.Buffer) - cmd.Stdout = buf - bufErr := new(bytes.Buffer) - cmd.Stderr = bufErr - err = cmd.Start() - if err != nil { - d.broken = true - fmt.Println(err) - return - } - fmt.Fprint(pipe, `digraph "" { margin=0; size="4,40"; ranksep=.2; `) - id := strings.Replace(phase, " ", "-", -1) - fmt.Fprintf(pipe, `id="g_graph_%s";`, id) - fmt.Fprintf(pipe, `node [style=filled,fillcolor=white,fontsize=16,fontname="Menlo,Times,serif",margin="0.01,0.03"];`) - fmt.Fprintf(pipe, `edge [fontsize=16,fontname="Menlo,Times,serif"];`) - for _, b := range f.Blocks { - layout := "" - fmt.Fprintf(pipe, `%v [label="%v%s\n%v",id="graph_node_%v_%v"];`, b, b, layout, b.Control().String(), id, b) - } - indexOf := make([]int, len(f.Blocks)) - for i, b := range f.Blocks { - indexOf[b.Index] = i - } - - // XXX - /* - ponums := make([]int32, len(f.Blocks)) - _ = postorderWithNumbering(f, ponums) - isBackEdge := func(from, to int) bool { - return ponums[from] <= ponums[to] - } - */ - isBackEdge := func(from, to int) bool { return false } - - for _, b := range f.Blocks { - for i, s := range b.Succs { - style := "solid" - color := "black" - arrow := "vee" - if isBackEdge(b.Index, s.Index) { - color = "blue" - } - fmt.Fprintf(pipe, `%v -> %v [label=" %d ",style="%s",color="%s",arrowhead="%s"];`, b, s, i, style, color, arrow) - } - } - fmt.Fprint(pipe, "}") - pipe.Close() - err = cmd.Wait() - if err != nil { - d.broken = true - fmt.Printf("dot: %v\n%v\n", err, bufErr.String()) - return - } - - svgID := "svg_graph_" + id - fmt.Fprintf(w, `
    `, svgID, svgID) - // For now, an awful hack: edit the html as it passes through - // our fingers, finding ' 0 { - fset = initial[0].Fset - } - - prog := ir.NewProgram(fset, mode) - if opts != nil { - prog.PrintFunc = opts.PrintFunc - } - - isInitial := make(map[*packages.Package]bool, len(initial)) - for _, p := range initial { - isInitial[p] = true - } - - irmap := make(map[*packages.Package]*ir.Package) - packages.Visit(initial, nil, func(p *packages.Package) { - if p.Types != nil && !p.IllTyped { - var files []*ast.File - if deps || isInitial[p] { - files = p.Syntax - } - irmap[p] = prog.CreatePackage(p.Types, files, p.TypesInfo, true) - } - }) - - var irpkgs []*ir.Package - for _, p := range initial { - irpkgs = append(irpkgs, irmap[p]) // may be nil - } - return prog, irpkgs -} - -// CreateProgram returns a new program in IR form, given a program -// loaded from source. An IR package is created for each transitively -// error-free package of lprog. -// -// Code for bodies of functions is not built until Build is called -// on the result. -// -// The mode parameter controls diagnostics and checking during IR construction. -// -// Deprecated: use golang.org/x/tools/go/packages and the Packages -// function instead; see ir.ExampleLoadPackages. -func CreateProgram(lprog *loader.Program, mode ir.BuilderMode) *ir.Program { - prog := ir.NewProgram(lprog.Fset, mode) - - for _, info := range lprog.AllPackages { - if info.TransitivelyErrorFree { - prog.CreatePackage(info.Pkg, info.Files, &info.Info, info.Importable) - } - } - - return prog -} - -// BuildPackage builds an IR program with IR for a single package. -// -// It populates pkg by type-checking the specified file ASTs. All -// dependencies are loaded using the importer specified by tc, which -// typically loads compiler export data; IR code cannot be built for -// those packages. BuildPackage then constructs an ir.Program with all -// dependency packages created, and builds and returns the IR package -// corresponding to pkg. -// -// The caller must have set pkg.Path() to the import path. -// -// The operation fails if there were any type-checking or import errors. -// -// See ../ir/example_test.go for an example. -func BuildPackage(tc *types.Config, fset *token.FileSet, pkg *types.Package, files []*ast.File, mode ir.BuilderMode) (*ir.Package, *types.Info, error) { - if fset == nil { - panic("no token.FileSet") - } - if pkg.Path() == "" { - panic("package has no import path") - } - - info := &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - Instances: make(map[*ast.Ident]types.Instance), - FileVersions: make(map[*ast.File]string), - } - if err := types.NewChecker(tc, fset, pkg, info).Files(files); err != nil { - return nil, nil, err - } - - prog := ir.NewProgram(fset, mode) - - // Create IR packages for all imports. - // Order is not significant. - created := make(map[*types.Package]bool) - var createAll func(pkgs []*types.Package) - createAll = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !created[p] { - created[p] = true - prog.CreatePackage(p, nil, nil, true) - createAll(p.Imports()) - } - } - } - createAll(pkg.Imports()) - - // Create and build the primary package. - irpkg := prog.CreatePackage(pkg, files, info, false) - irpkg.Build() - return irpkg, info, nil -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/loops.go b/vendor/honnef.co/go/tools/go/ir/irutil/loops.go deleted file mode 100644 index 751cc680b..000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/loops.go +++ /dev/null @@ -1,54 +0,0 @@ -package irutil - -import "honnef.co/go/tools/go/ir" - -type Loop struct{ *ir.BlockSet } - -func FindLoops(fn *ir.Function) []Loop { - if fn.Blocks == nil { - return nil - } - tree := fn.DomPreorder() - var sets []Loop - for _, h := range tree { - for _, n := range h.Preds { - if !h.Dominates(n) { - continue - } - // n is a back-edge to h - // h is the loop header - if n == h { - set := Loop{ir.NewBlockSet(len(fn.Blocks))} - set.Add(n) - sets = append(sets, set) - continue - } - set := Loop{ir.NewBlockSet(len(fn.Blocks))} - set.Add(h) - set.Add(n) - for _, b := range allPredsBut(n, h, nil) { - set.Add(b) - } - sets = append(sets, set) - } - } - return sets -} - -func allPredsBut(b, but *ir.BasicBlock, list []*ir.BasicBlock) []*ir.BasicBlock { -outer: - for _, pred := range b.Preds { - if pred == but { - continue - } - for _, p := range list { - // TODO improve big-o complexity of this function - if pred == p { - continue outer - } - } - list = append(list, pred) - list = allPredsBut(pred, but, list) - } - return list -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/stub.go b/vendor/honnef.co/go/tools/go/ir/irutil/stub.go deleted file mode 100644 index 4311c7dbe..000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/stub.go +++ /dev/null @@ -1,32 +0,0 @@ -package irutil - -import ( - "honnef.co/go/tools/go/ir" -) - -// IsStub reports whether a function is a stub. A function is -// considered a stub if it has no instructions or if all it does is -// return a constant value. -func IsStub(fn *ir.Function) bool { - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - switch instr.(type) { - case *ir.Const: - // const naturally has no side-effects - case *ir.Panic: - // panic is a stub if it only uses constants - case *ir.Return: - // return is a stub if it only uses constants - case *ir.DebugRef: - case *ir.Jump: - // if there are no disallowed instructions, then we're - // only jumping to the exit block (or possibly - // somewhere else that's stubby?) - default: - // all other instructions are assumed to do actual work - return false - } - } - } - return true -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/switch.go b/vendor/honnef.co/go/tools/go/ir/irutil/switch.go deleted file mode 100644 index afe899d86..000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/switch.go +++ /dev/null @@ -1,260 +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. - -package irutil - -// This file implements discovery of switch and type-switch constructs -// from low-level control flow. -// -// Many techniques exist for compiling a high-level switch with -// constant cases to efficient machine code. The optimal choice will -// depend on the data type, the specific case values, the code in the -// body of each case, and the hardware. -// Some examples: -// - a lookup table (for a switch that maps constants to constants) -// - a computed goto -// - a binary tree -// - a perfect hash -// - a two-level switch (to partition constant strings by their first byte). - -import ( - "bytes" - "fmt" - "go/token" - "go/types" - - "honnef.co/go/tools/go/ir" -) - -// A ConstCase represents a single constant comparison. -// It is part of a Switch. -type ConstCase struct { - Block *ir.BasicBlock // block performing the comparison - Body *ir.BasicBlock // body of the case - Value *ir.Const // case comparand -} - -// A TypeCase represents a single type assertion. -// It is part of a Switch. -type TypeCase struct { - Block *ir.BasicBlock // block performing the type assert - Body *ir.BasicBlock // body of the case - Type types.Type // case type - Binding ir.Value // value bound by this case -} - -// A Switch is a logical high-level control flow operation -// (a multiway branch) discovered by analysis of a CFG containing -// only if/else chains. It is not part of the ir.Instruction set. -// -// One of ConstCases and TypeCases has length >= 2; -// the other is nil. -// -// In a value switch, the list of cases may contain duplicate constants. -// A type switch may contain duplicate types, or types assignable -// to an interface type also in the list. -// TODO(adonovan): eliminate such duplicates. -type Switch struct { - Start *ir.BasicBlock // block containing start of if/else chain - X ir.Value // the switch operand - ConstCases []ConstCase // ordered list of constant comparisons - TypeCases []TypeCase // ordered list of type assertions - Default *ir.BasicBlock // successor if all comparisons fail -} - -func (sw *Switch) String() string { - // We represent each block by the String() of its - // first Instruction, e.g. "print(42:int)". - var buf bytes.Buffer - if sw.ConstCases != nil { - fmt.Fprintf(&buf, "switch %s {\n", sw.X.Name()) - for _, c := range sw.ConstCases { - fmt.Fprintf(&buf, "case %s: %s\n", c.Value.Name(), c.Body.Instrs[0]) - } - } else { - fmt.Fprintf(&buf, "switch %s.(type) {\n", sw.X.Name()) - for _, c := range sw.TypeCases { - fmt.Fprintf(&buf, "case %s %s: %s\n", - c.Binding.Name(), c.Type, c.Body.Instrs[0]) - } - } - if sw.Default != nil { - fmt.Fprintf(&buf, "default: %s\n", sw.Default.Instrs[0]) - } - fmt.Fprintf(&buf, "}") - return buf.String() -} - -// Switches examines the control-flow graph of fn and returns the -// set of inferred value and type switches. A value switch tests an -// ir.Value for equality against two or more compile-time constant -// values. Switches involving link-time constants (addresses) are -// ignored. A type switch type-asserts an ir.Value against two or -// more types. -// -// The switches are returned in dominance order. -// -// The resulting switches do not necessarily correspond to uses of the -// 'switch' keyword in the source: for example, a single source-level -// switch statement with non-constant cases may result in zero, one or -// many Switches, one per plural sequence of constant cases. -// Switches may even be inferred from if/else- or goto-based control flow. -// (In general, the control flow constructs of the source program -// cannot be faithfully reproduced from the IR.) -func Switches(fn *ir.Function) []Switch { - // Traverse the CFG in dominance order, so we don't - // enter an if/else-chain in the middle. - var switches []Switch - seen := make(map[*ir.BasicBlock]bool) // TODO(adonovan): opt: use ir.blockSet - for _, b := range fn.DomPreorder() { - if x, k := isComparisonBlock(b); x != nil { - // Block b starts a switch. - sw := Switch{Start: b, X: x} - valueSwitch(&sw, k, seen) - if len(sw.ConstCases) > 1 { - switches = append(switches, sw) - } - } - - if y, x, T := isTypeAssertBlock(b); y != nil { - // Block b starts a type switch. - sw := Switch{Start: b, X: x} - typeSwitch(&sw, y, T, seen) - if len(sw.TypeCases) > 1 { - switches = append(switches, sw) - } - } - } - return switches -} - -func isSameX(x1 ir.Value, x2 ir.Value) bool { - if x1 == x2 { - return true - } - if x2, ok := x2.(*ir.Sigma); ok { - return isSameX(x1, x2.X) - } - return false -} - -func valueSwitch(sw *Switch, k *ir.Const, seen map[*ir.BasicBlock]bool) { - b := sw.Start - x := sw.X - for isSameX(sw.X, x) { - if seen[b] { - break - } - seen[b] = true - - sw.ConstCases = append(sw.ConstCases, ConstCase{ - Block: b, - Body: b.Succs[0], - Value: k, - }) - b = b.Succs[1] - n := 0 - for _, instr := range b.Instrs { - switch instr.(type) { - case *ir.If, *ir.BinOp: - n++ - case *ir.Sigma, *ir.Phi, *ir.DebugRef: - default: - n += 1000 - } - } - if n != 2 { - // Block b contains not just 'if x == k' and σ/ϕ nodes, - // so it may have side effects that - // make it unsafe to elide. - break - } - if len(b.Preds) != 1 { - // Block b has multiple predecessors, - // so it cannot be treated as a case. - break - } - x, k = isComparisonBlock(b) - } - sw.Default = b -} - -func typeSwitch(sw *Switch, y ir.Value, T types.Type, seen map[*ir.BasicBlock]bool) { - b := sw.Start - x := sw.X - for isSameX(sw.X, x) { - if seen[b] { - break - } - seen[b] = true - - sw.TypeCases = append(sw.TypeCases, TypeCase{ - Block: b, - Body: b.Succs[0], - Type: T, - Binding: y, - }) - b = b.Succs[1] - n := 0 - for _, instr := range b.Instrs { - switch instr.(type) { - case *ir.TypeAssert, *ir.Extract, *ir.If: - n++ - case *ir.Sigma, *ir.Phi: - default: - n += 1000 - } - } - if n != 4 { - // Block b contains not just - // {TypeAssert; Extract #0; Extract #1; If} - // so it may have side effects that - // make it unsafe to elide. - break - } - if len(b.Preds) != 1 { - // Block b has multiple predecessors, - // so it cannot be treated as a case. - break - } - y, x, T = isTypeAssertBlock(b) - } - sw.Default = b -} - -// isComparisonBlock returns the operands (v, k) if a block ends with -// a comparison v==k, where k is a compile-time constant. -func isComparisonBlock(b *ir.BasicBlock) (v ir.Value, k *ir.Const) { - if n := len(b.Instrs); n >= 2 { - if i, ok := b.Instrs[n-1].(*ir.If); ok { - if binop, ok := i.Cond.(*ir.BinOp); ok && binop.Block() == b && binop.Op == token.EQL { - if k, ok := binop.Y.(*ir.Const); ok { - return binop.X, k - } - if k, ok := binop.X.(*ir.Const); ok { - return binop.Y, k - } - } - } - } - return -} - -// isTypeAssertBlock returns the operands (y, x, T) if a block ends with -// a type assertion "if y, ok := x.(T); ok {". -func isTypeAssertBlock(b *ir.BasicBlock) (y, x ir.Value, T types.Type) { - if n := len(b.Instrs); n >= 4 { - if i, ok := b.Instrs[n-1].(*ir.If); ok { - if ext1, ok := i.Cond.(*ir.Extract); ok && ext1.Block() == b && ext1.Index == 1 { - if ta, ok := ext1.Tuple.(*ir.TypeAssert); ok && ta.Block() == b { - // hack: relies upon instruction ordering. - if ext0, ok := b.Instrs[n-3].(*ir.Extract); ok { - return ext0, ta.X, ta.AssertedType - } - } - } - } - } - return -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/terminates.go b/vendor/honnef.co/go/tools/go/ir/irutil/terminates.go deleted file mode 100644 index 84e7503bb..000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/terminates.go +++ /dev/null @@ -1,70 +0,0 @@ -package irutil - -import ( - "go/types" - - "honnef.co/go/tools/go/ir" -) - -// Terminates reports whether fn is supposed to return, that is if it -// has at least one theoretic path that returns from the function. -// Explicit panics do not count as terminating. -func Terminates(fn *ir.Function) bool { - if fn.Blocks == nil { - // assuming that a function terminates is the conservative - // choice - return true - } - - for _, block := range fn.Blocks { - if _, ok := block.Control().(*ir.Return); ok { - if len(block.Preds) == 0 { - return true - } - for _, pred := range block.Preds { - switch ctrl := pred.Control().(type) { - case *ir.Panic: - // explicit panics do not count as terminating - case *ir.If: - // Check if we got here by receiving from a closed - // time.Tick channel – this cannot happen at - // runtime and thus doesn't constitute termination - iff := ctrl - if !ok { - return true - } - ex, ok := iff.Cond.(*ir.Extract) - if !ok { - return true - } - if ex.Index != 1 { - return true - } - recv, ok := ex.Tuple.(*ir.Recv) - if !ok { - return true - } - call, ok := recv.Chan.(*ir.Call) - if !ok { - return true - } - fn, ok := call.Common().Value.(*ir.Function) - if !ok { - return true - } - fn2, ok := fn.Object().(*types.Func) - if !ok { - return true - } - if fn2.FullName() != "time.Tick" { - return true - } - default: - // we've reached the exit block - return true - } - } - } - } - return false -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/util.go b/vendor/honnef.co/go/tools/go/ir/irutil/util.go deleted file mode 100644 index d2f10948d..000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/util.go +++ /dev/null @@ -1,178 +0,0 @@ -package irutil - -import ( - "go/types" - "strings" - - "honnef.co/go/tools/go/ir" - "honnef.co/go/tools/go/types/typeutil" -) - -func Reachable(from, to *ir.BasicBlock) bool { - if from == to { - return true - } - if from.Dominates(to) { - return true - } - - found := false - Walk(from, func(b *ir.BasicBlock) bool { - if b == to { - found = true - return false - } - return true - }) - return found -} - -func Walk(b *ir.BasicBlock, fn func(*ir.BasicBlock) bool) { - seen := map[*ir.BasicBlock]bool{} - wl := []*ir.BasicBlock{b} - for len(wl) > 0 { - b := wl[len(wl)-1] - wl = wl[:len(wl)-1] - if seen[b] { - continue - } - seen[b] = true - if !fn(b) { - continue - } - wl = append(wl, b.Succs...) - } -} - -func Vararg(x *ir.Slice) ([]ir.Value, bool) { - var out []ir.Value - alloc, ok := ir.Unwrap(x.X).(*ir.Alloc) - if !ok { - return nil, false - } - var checkAlloc func(alloc ir.Value) bool - checkAlloc = func(alloc ir.Value) bool { - for _, ref := range *alloc.Referrers() { - if ref == x { - continue - } - if ref.Block() != x.Block() { - return false - } - switch ref := ref.(type) { - case *ir.IndexAddr: - idx := ref - if len(*idx.Referrers()) != 1 { - return false - } - store, ok := (*idx.Referrers())[0].(*ir.Store) - if !ok { - return false - } - out = append(out, store.Val) - case *ir.Copy: - if !checkAlloc(ref) { - return false - } - default: - return false - } - } - return true - } - if !checkAlloc(alloc) { - return nil, false - } - return out, true -} - -func CallName(call *ir.CallCommon) string { - if call.IsInvoke() { - return "" - } - switch v := call.Value.(type) { - case *ir.Function: - fn, ok := v.Object().(*types.Func) - if !ok { - return "" - } - return typeutil.FuncName(fn) - case *ir.Builtin: - return v.Name() - } - return "" -} - -func IsCallTo(call *ir.CallCommon, name string) bool { return CallName(call) == name } - -func IsCallToAny(call *ir.CallCommon, names ...string) bool { - q := CallName(call) - for _, name := range names { - if q == name { - return true - } - } - return false -} - -func FilterDebug(instr []ir.Instruction) []ir.Instruction { - var out []ir.Instruction - for _, ins := range instr { - if _, ok := ins.(*ir.DebugRef); !ok { - out = append(out, ins) - } - } - return out -} - -func IsExample(fn *ir.Function) bool { - if !strings.HasPrefix(fn.Name(), "Example") { - return false - } - f := fn.Prog.Fset.File(fn.Pos()) - if f == nil { - return false - } - return strings.HasSuffix(f.Name(), "_test.go") -} - -// Flatten recursively returns the underlying value of an ir.Sigma or -// ir.Phi node. If all edges in an ir.Phi node are the same (after -// flattening), the flattened edge will get returned. If flattening is -// not possible, nil is returned. -func Flatten(v ir.Value) ir.Value { - failed := false - seen := map[ir.Value]struct{}{} - var out ir.Value - var dfs func(v ir.Value) - dfs = func(v ir.Value) { - if failed { - return - } - if _, ok := seen[v]; ok { - return - } - seen[v] = struct{}{} - - switch v := v.(type) { - case *ir.Sigma: - dfs(v.X) - case *ir.Phi: - for _, e := range v.Edges { - dfs(e) - } - default: - if out == nil { - out = v - } else if out != v { - failed = true - } - } - } - dfs(v) - - if failed { - return nil - } - return out -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/visit.go b/vendor/honnef.co/go/tools/go/ir/irutil/visit.go deleted file mode 100644 index f2135dca4..000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/visit.go +++ /dev/null @@ -1,78 +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. - -package irutil - -import "honnef.co/go/tools/go/ir" - -// This file defines utilities for visiting the IR of -// a Program. -// -// TODO(adonovan): test coverage. - -// AllFunctions finds and returns the set of functions potentially -// needed by program prog, as determined by a simple linker-style -// reachability algorithm starting from the members and method-sets of -// each package. The result may include anonymous functions and -// synthetic wrappers. -// -// Precondition: all packages are built. -func AllFunctions(prog *ir.Program) map[*ir.Function]bool { - visit := visitor{ - prog: prog, - seen: make(map[*ir.Function]bool), - } - visit.program() - return visit.seen -} - -type visitor struct { - prog *ir.Program - seen map[*ir.Function]bool -} - -func (visit *visitor) program() { - for _, pkg := range visit.prog.AllPackages() { - for _, mem := range pkg.Members { - if fn, ok := mem.(*ir.Function); ok { - visit.function(fn) - } - } - } - for _, T := range visit.prog.RuntimeTypes() { - mset := visit.prog.MethodSets.MethodSet(T) - for i, n := 0, mset.Len(); i < n; i++ { - visit.function(visit.prog.MethodValue(mset.At(i))) - } - } -} - -func (visit *visitor) function(fn *ir.Function) { - if !visit.seen[fn] { - visit.seen[fn] = true - var buf [10]*ir.Value // avoid alloc in common case - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - for _, op := range instr.Operands(buf[:0]) { - if fn, ok := (*op).(*ir.Function); ok { - visit.function(fn) - } - } - } - } - } -} - -// MainPackages returns the subset of the specified packages -// named "main" that define a main function. -// The result may include synthetic "testmain" packages. -func MainPackages(pkgs []*ir.Package) []*ir.Package { - var mains []*ir.Package - for _, pkg := range pkgs { - if pkg.Pkg.Name() == "main" && pkg.Func("main") != nil { - mains = append(mains, pkg) - } - } - return mains -} diff --git a/vendor/honnef.co/go/tools/go/ir/lift.go b/vendor/honnef.co/go/tools/go/ir/lift.go deleted file mode 100644 index 08be0d371..000000000 --- a/vendor/honnef.co/go/tools/go/ir/lift.go +++ /dev/null @@ -1,1819 +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. - -package ir - -// This file defines the lifting pass which tries to "lift" Alloc -// cells (new/local variables) into SSA registers, replacing loads -// with the dominating stored value, eliminating loads and stores, and -// inserting φ- and σ-nodes as needed. - -// Cited papers and resources: -// -// Ron Cytron et al. 1991. Efficiently computing SSA form... -// https://doi.acm.org/10.1145/115372.115320 -// -// Cooper, Harvey, Kennedy. 2001. A Simple, Fast Dominance Algorithm. -// Software Practice and Experience 2001, 4:1-10. -// https://www.hipersoft.rice.edu/grads/publications/dom14.pdf -// -// Daniel Berlin, llvmdev mailing list, 2012. -// https://lists.cs.uiuc.edu/pipermail/llvmdev/2012-January/046638.html -// (Be sure to expand the whole thread.) -// -// C. Scott Ananian. 1997. The static single information form. -// -// Jeremy Singer. 2006. Static program analysis based on virtual register renaming. - -// TODO(adonovan): opt: there are many optimizations worth evaluating, and -// the conventional wisdom for SSA construction is that a simple -// algorithm well engineered often beats those of better asymptotic -// complexity on all but the most egregious inputs. -// -// Danny Berlin suggests that the Cooper et al. algorithm for -// computing the dominance frontier is superior to Cytron et al. -// Furthermore he recommends that rather than computing the DF for the -// whole function then renaming all alloc cells, it may be cheaper to -// compute the DF for each alloc cell separately and throw it away. -// -// Consider exploiting liveness information to avoid creating dead -// φ-nodes which we then immediately remove. -// -// Also see many other "TODO: opt" suggestions in the code. - -import ( - "encoding/binary" - "fmt" - "os" - "slices" -) - -// If true, show diagnostic information at each step of lifting. -// Very verbose. -const debugLifting = false - -// domFrontier maps each block to the set of blocks in its dominance -// frontier. The outer slice is conceptually a map keyed by -// Block.Index. The inner slice is conceptually a set, possibly -// containing duplicates. -// -// TODO(adonovan): opt: measure impact of dups; consider a packed bit -// representation, e.g. big.Int, and bitwise parallel operations for -// the union step in the Children loop. -// -// domFrontier's methods mutate the slice's elements but not its -// length, so their receivers needn't be pointers. -type domFrontier BlockMap[[]*BasicBlock] - -func (df domFrontier) add(u, v *BasicBlock) { - df[u.Index] = append(df[u.Index], v) -} - -// build builds the dominance frontier df for the dominator tree of -// fn, using the algorithm found in A Simple, Fast Dominance -// Algorithm, Figure 5. -// -// TODO(adonovan): opt: consider Berlin approach, computing pruned SSA -// by pruning the entire IDF computation, rather than merely pruning -// the DF -> IDF step. -func (df domFrontier) build(fn *Function) { - for _, b := range fn.Blocks { - preds := b.Preds[0:len(b.Preds):len(b.Preds)] - if b == fn.Exit { - for i, v := range fn.fakeExits.values { - if v { - preds = append(preds, fn.Blocks[i]) - } - } - } - if len(preds) >= 2 { - for _, p := range preds { - runner := p - for runner != b.dom.idom { - df.add(runner, b) - runner = runner.dom.idom - } - } - } - } -} - -func buildDomFrontier(fn *Function) domFrontier { - df := make(domFrontier, len(fn.Blocks)) - df.build(fn) - return df -} - -type postDomFrontier BlockMap[[]*BasicBlock] - -func (rdf postDomFrontier) add(u, v *BasicBlock) { - rdf[u.Index] = append(rdf[u.Index], v) -} - -func (rdf postDomFrontier) build(fn *Function) { - for _, b := range fn.Blocks { - succs := b.Succs[0:len(b.Succs):len(b.Succs)] - if fn.fakeExits.Has(b) { - succs = append(succs, fn.Exit) - } - if len(succs) >= 2 { - for _, s := range succs { - runner := s - for runner != b.pdom.idom { - rdf.add(runner, b) - runner = runner.pdom.idom - } - } - } - } -} - -func buildPostDomFrontier(fn *Function) postDomFrontier { - rdf := make(postDomFrontier, len(fn.Blocks)) - rdf.build(fn) - return rdf -} - -func removeInstr(refs []Instruction, instr Instruction) []Instruction { - return removeInstrsIf(refs, func(i Instruction) bool { return i == instr }) -} - -func removeInstrsIf(refs []Instruction, p func(Instruction) bool) []Instruction { - return slices.DeleteFunc(refs, p) -} - -func clearInstrs(instrs []Instruction) { - for i := range instrs { - instrs[i] = nil - } -} - -func numberNodesPerBlock(f *Function) { - for _, b := range f.Blocks { - var base ID - for _, instr := range b.Instrs { - if instr == nil { - continue - } - instr.setID(base) - base++ - } - } -} - -// lift replaces local and new Allocs accessed only with -// load/store by IR registers, inserting φ- and σ-nodes where necessary. -// The result is a program in pruned SSI form. -// -// Preconditions: -// - fn has no dead blocks (blockopt has run). -// - Def/use info (Operands and Referrers) is up-to-date. -// - The dominator tree is up-to-date. -func lift(fn *Function) bool { - // TODO(adonovan): opt: lots of little optimizations may be - // worthwhile here, especially if they cause us to avoid - // buildDomFrontier. For example: - // - // - Alloc never loaded? Eliminate. - // - Alloc never stored? Replace all loads with a zero constant. - // - Alloc stored once? Replace loads with dominating store; - // don't forget that an Alloc is itself an effective store - // of zero. - // - Alloc used only within a single block? - // Use degenerate algorithm avoiding φ-nodes. - // - Consider synergy with scalar replacement of aggregates (SRA). - // e.g. *(&x.f) where x is an Alloc. - // Perhaps we'd get better results if we generated this as x.f - // i.e. Field(x, .f) instead of Load(FieldIndex(x, .f)). - // Unclear. - // - // But we will start with the simplest correct code. - var df domFrontier - var rdf postDomFrontier - var closure *closure - var newPhis BlockMap[[]newPhi] - var newSigmas BlockMap[[]newSigma] - - // During this pass we will replace some BasicBlock.Instrs - // (allocs, loads and stores) with nil, keeping a count in - // BasicBlock.gaps. At the end we will reset Instrs to the - // concatenation of all non-dead newPhis and non-nil Instrs - // for the block, reusing the original array if space permits. - - // While we're here, we also eliminate 'rundefers' - // instructions and ssa:deferstack() in functions that contain no - // 'defer' instructions. Eliminate ssa:deferstack() if it does not - // escape. - usesDefer := false - deferstackAlloc, deferstackCall := deferstackPreamble(fn) - eliminateDeferStack := deferstackAlloc != nil && !deferstackAlloc.Heap - - // Determine which allocs we can lift and number them densely. - // The renaming phase uses this numbering for compact maps. - numAllocs := 0 - - instructions := make(BlockMap[liftInstructions], len(fn.Blocks)) - for i := range instructions { - instructions[i].insertInstructions = map[Instruction][]Instruction{} - } - - // Number nodes, for liftable - numberNodesPerBlock(fn) - - for _, b := range fn.Blocks { - b.gaps = 0 - b.rundefers = 0 - - for _, instr := range b.Instrs { - switch instr := instr.(type) { - case *Alloc: - if !liftable(instr, instructions) { - instr.index = -1 - continue - } - - if numAllocs == 0 { - df = buildDomFrontier(fn) - rdf = buildPostDomFrontier(fn) - if len(fn.Blocks) > 2 { - closure = transitiveClosure(fn) - } - newPhis = make(BlockMap[[]newPhi], len(fn.Blocks)) - newSigmas = make(BlockMap[[]newSigma], len(fn.Blocks)) - - if debugLifting { - title := false - for i, blocks := range df { - if blocks != nil { - if !title { - fmt.Fprintf(os.Stderr, "Dominance frontier of %s:\n", fn) - title = true - } - fmt.Fprintf(os.Stderr, "\t%s: %s\n", fn.Blocks[i], blocks) - } - } - } - } - instr.index = numAllocs - numAllocs++ - case *Defer: - usesDefer = true - if eliminateDeferStack { - // Clear _DeferStack and remove references to loads - if instr._DeferStack != nil { - if refs := instr._DeferStack.Referrers(); refs != nil { - *refs = removeInstr(*refs, instr) - } - instr._DeferStack = nil - } - } - case *RunDefers: - b.rundefers++ - } - } - } - - if numAllocs > 0 { - for _, b := range fn.Blocks { - work := instructions[b.Index] - for _, rename := range work.renameAllocs { - for _, instr_ := range b.Instrs[rename.startingAt:] { - replace(instr_, rename.from, rename.to) - } - } - } - - for _, b := range fn.Blocks { - work := instructions[b.Index] - if len(work.insertInstructions) != 0 { - newInstrs := make([]Instruction, 0, len(fn.Blocks)+len(work.insertInstructions)*3) - for _, instr := range b.Instrs { - if add, ok := work.insertInstructions[instr]; ok { - newInstrs = append(newInstrs, add...) - } - newInstrs = append(newInstrs, instr) - } - b.Instrs = newInstrs - } - } - - // TODO(dh): remove inserted allocs that end up unused after lifting. - - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - if instr, ok := instr.(*Alloc); ok && instr.index >= 0 { - liftAlloc(closure, df, rdf, instr, newPhis, newSigmas) - } - } - } - - // renaming maps an alloc (keyed by index) to its replacement - // value. Initially the renaming contains nil, signifying the - // zero constant of the appropriate type; we construct the - // Const lazily at most once on each path through the domtree. - // TODO(adonovan): opt: cache per-function not per subtree. - renaming := make([]Value, numAllocs) - - // Renaming. - rename(fn.Blocks[0], renaming, newPhis, newSigmas) - - simplifyPhisAndSigmas(newPhis, newSigmas) - - // Eliminate dead φ- and σ-nodes. - markLiveNodes(fn.Blocks, newPhis, newSigmas) - - // Eliminate ssa:deferstack() call. - if eliminateDeferStack { - b := deferstackCall.block - for i, instr := range b.Instrs { - if instr == deferstackCall { - b.Instrs[i] = nil - b.gaps++ - break - } - } - } - } - - // Prepend remaining live φ-nodes to each block and possibly kill rundefers. - for _, b := range fn.Blocks { - var head []Instruction - if numAllocs > 0 { - nps := newPhis[b.Index] - head = make([]Instruction, 0, len(nps)) - for _, pred := range b.Preds { - nss := newSigmas[pred.Index] - idx := pred.succIndex(b) - for _, newSigma := range nss { - if sigma := newSigma.sigmas[idx]; sigma != nil && sigma.live { - head = append(head, sigma) - - // we didn't populate referrers before, as most - // sigma nodes will be killed - if refs := sigma.X.Referrers(); refs != nil { - *refs = append(*refs, sigma) - } - } else if sigma != nil { - sigma.block = nil - } - } - } - for _, np := range nps { - if np.phi.live { - head = append(head, np.phi) - } else { - for _, edge := range np.phi.Edges { - if refs := edge.Referrers(); refs != nil { - *refs = removeInstr(*refs, np.phi) - } - } - np.phi.block = nil - } - } - } - - rundefersToKill := b.rundefers - if usesDefer { - rundefersToKill = 0 - } - - j := len(head) - if j+b.gaps+rundefersToKill == 0 { - continue // fast path: no new phis or gaps - } - - // We could do straight copies instead of element-wise copies - // when both b.gaps and rundefersToKill are zero. However, - // that seems to only be the case ~1% of the time, which - // doesn't seem worth the extra branch. - - // Remove dead instructions, add phis and sigmas - ns := len(b.Instrs) + j - b.gaps - rundefersToKill - if ns <= cap(b.Instrs) { - // b.Instrs has enough capacity to store all instructions - - // OPT(dh): check cap vs the actually required space; if - // there is a big enough difference, it may be worth - // allocating a new slice, to avoid pinning memory. - dst := b.Instrs[:cap(b.Instrs)] - i := len(dst) - 1 - for n := len(b.Instrs) - 1; n >= 0; n-- { - instr := dst[n] - if instr == nil { - continue - } - if !usesDefer { - if _, ok := instr.(*RunDefers); ok { - continue - } - } - dst[i] = instr - i-- - } - off := i + 1 - len(head) - // aid GC - clearInstrs(dst[:off]) - dst = dst[off:] - copy(dst, head) - b.Instrs = dst - } else { - // not enough space, so allocate a new slice and copy - // over. - dst := make([]Instruction, ns) - copy(dst, head) - - for _, instr := range b.Instrs { - if instr == nil { - continue - } - if !usesDefer { - if _, ok := instr.(*RunDefers); ok { - continue - } - } - dst[j] = instr - j++ - } - b.Instrs = dst - } - } - - // Remove any fn.Locals that were lifted. - j := 0 - for _, l := range fn.Locals { - if l.index < 0 { - fn.Locals[j] = l - j++ - } - } - // Nil out fn.Locals[j:] to aid GC. - for i := j; i < len(fn.Locals); i++ { - fn.Locals[i] = nil - } - fn.Locals = fn.Locals[:j] - - return numAllocs > 0 -} - -func hasDirectReferrer(instr Instruction) bool { - for _, instr := range *instr.Referrers() { - switch instr.(type) { - case *Phi, *Sigma: - // ignore - default: - return true - } - } - return false -} - -func markLiveNodes(blocks []*BasicBlock, newPhis BlockMap[[]newPhi], newSigmas BlockMap[[]newSigma]) { - // Phis and sigmas may become dead due to optimization passes. We may also insert more nodes than strictly - // necessary, e.g. sigma nodes for constants, which will never be used. - - // Phi and sigma nodes are considered live if a non-phi, non-sigma - // node uses them. Once we find a node that is live, we mark all - // of its operands as used, too. - for _, npList := range newPhis { - for _, np := range npList { - phi := np.phi - if !phi.live && hasDirectReferrer(phi) { - markLivePhi(phi) - } - } - } - for _, npList := range newSigmas { - for _, np := range npList { - for _, sigma := range np.sigmas { - if sigma != nil && !sigma.live && hasDirectReferrer(sigma) { - markLiveSigma(sigma) - } - } - } - } - // Existing φ-nodes due to && and || operators - // are all considered live (see Go issue 19622). - for _, b := range blocks { - for _, phi := range b.phis() { - markLivePhi(phi.(*Phi)) - } - } -} - -func markLivePhi(phi *Phi) { - phi.live = true - for _, rand := range phi.Edges { - switch rand := rand.(type) { - case *Phi: - if !rand.live { - markLivePhi(rand) - } - case *Sigma: - if !rand.live { - markLiveSigma(rand) - } - } - } -} - -func markLiveSigma(sigma *Sigma) { - sigma.live = true - switch rand := sigma.X.(type) { - case *Phi: - if !rand.live { - markLivePhi(rand) - } - case *Sigma: - if !rand.live { - markLiveSigma(rand) - } - } -} - -// simplifyPhisAndSigmas removes duplicate phi and sigma nodes, -// and replaces trivial phis with non-phi alternatives. Phi -// nodes where all edges are identical, or consist of only the phi -// itself and one other value, may be replaced with the value. -func simplifyPhisAndSigmas(newPhis BlockMap[[]newPhi], newSigmas BlockMap[[]newSigma]) { - // temporary numbering of values used in phis so that we can build map keys - var id ID - for _, npList := range newPhis { - for _, np := range npList { - for _, edge := range np.phi.Edges { - edge.setID(id) - id++ - } - } - } - // find all phis that are trivial and can be replaced with a - // non-phi value. run until we reach a fixpoint, because replacing - // a phi may make other phis trivial. - for changed := true; changed; { - changed = false - for _, npList := range newPhis { - for _, np := range npList { - if np.phi.live { - // we're reusing 'live' to mean 'dead' in the context of simplifyPhisAndSigmas - continue - } - if r, ok := isUselessPhi(np.phi); ok { - // useless phi, replace its uses with the - // replacement value. the dead phi pass will clean - // up the phi afterwards. - replaceAll(np.phi, r) - np.phi.live = true - changed = true - } - } - } - - // Replace duplicate sigma nodes with a single node. These nodes exist when multiple allocs get replaced with the - // same dominating store. - for _, sigmaList := range newSigmas { - primarySigmas := map[struct { - succ int - v Value - }]*Sigma{} - for _, sigmas := range sigmaList { - for succ, sigma := range sigmas.sigmas { - if sigma == nil { - continue - } - if sigma.live { - // we're reusing 'live' to mean 'dead' in the context of simplifyPhisAndSigmas - continue - } - key := struct { - succ int - v Value - }{succ, sigma.X} - if alt, ok := primarySigmas[key]; ok { - replaceAll(sigma, alt) - sigma.live = true - changed = true - } else { - primarySigmas[key] = sigma - } - } - } - } - - // Replace duplicate phi nodes with a single node. As far as we know, these duplicate nodes only ever exist - // because of the previous sigma deduplication. - keyb := make([]byte, 0, 4*8) - for _, npList := range newPhis { - primaryPhis := map[string]*Phi{} - for _, np := range npList { - if np.phi.live { - continue - } - if n := len(np.phi.Edges) * 8; cap(keyb) >= n { - keyb = keyb[:n] - } else { - keyb = make([]byte, n, n*2) - } - for i, e := range np.phi.Edges { - binary.LittleEndian.PutUint64(keyb[i*8:i*8+8], uint64(e.ID())) - } - if alt, ok := primaryPhis[string(keyb)]; ok { - replaceAll(np.phi, alt) - np.phi.live = true - changed = true - } else { - primaryPhis[string(keyb)] = np.phi - } - } - } - - } - - for _, npList := range newPhis { - for _, np := range npList { - np.phi.live = false - for _, edge := range np.phi.Edges { - edge.setID(0) - } - } - } - - for _, sigmaList := range newSigmas { - for _, sigmas := range sigmaList { - for _, sigma := range sigmas.sigmas { - if sigma != nil { - sigma.live = false - } - } - } - } -} - -type BlockSet struct { - idx int - values []bool - count int -} - -func NewBlockSet(size int) *BlockSet { - return &BlockSet{values: make([]bool, size)} -} - -func (s *BlockSet) Set(s2 *BlockSet) { - copy(s.values, s2.values) - s.count = 0 - for _, v := range s.values { - if v { - s.count++ - } - } -} - -func (s *BlockSet) Num() int { - return s.count -} - -func (s *BlockSet) Has(b *BasicBlock) bool { - if b.Index >= len(s.values) { - return false - } - return s.values[b.Index] -} - -// add adds b to the set and returns true if the set changed. -func (s *BlockSet) Add(b *BasicBlock) bool { - if s.values[b.Index] { - return false - } - s.count++ - s.values[b.Index] = true - s.idx = b.Index - - return true -} - -func (s *BlockSet) Clear() { - for j := range s.values { - s.values[j] = false - } - s.count = 0 -} - -// take removes an arbitrary element from a set s and -// returns its index, or returns -1 if empty. -func (s *BlockSet) Take() int { - // [i, end] - for i := s.idx; i < len(s.values); i++ { - if s.values[i] { - s.values[i] = false - s.idx = i - s.count-- - return i - } - } - - // [start, i) - for i := 0; i < s.idx; i++ { - if s.values[i] { - s.values[i] = false - s.idx = i - s.count-- - return i - } - } - - return -1 -} - -type closure struct { - span []uint32 - reachables BlockMap[interval] -} - -type interval uint32 - -const ( - flagMask = 1 << 31 - numBits = 20 - lengthBits = 32 - numBits - 1 - lengthMask = (1<>numBits - } else { - // large interval - i++ - start = uint32(inv & numMask) - end = uint32(r[i]) - } - if idx >= start && idx <= end { - return true - } - } - return false -} - -func (c closure) reachable(id int) []interval { - return c.reachables[c.span[id]:c.span[id+1]] -} - -func (c closure) walk(current *BasicBlock, b *BasicBlock, visited []bool) { - // TODO(dh): the 'current' argument seems to be unused - // TODO(dh): there's no reason for this to be a method - visited[b.Index] = true - for _, succ := range b.Succs { - if visited[succ.Index] { - continue - } - visited[succ.Index] = true - c.walk(current, succ, visited) - } -} - -func transitiveClosure(fn *Function) *closure { - reachable := make(BlockMap[bool], len(fn.Blocks)) - c := &closure{} - c.span = make([]uint32, len(fn.Blocks)+1) - - addInterval := func(start, end uint32) { - if l := end - start; l <= 1<= desc.firstUnliftable { - continue - } - hasLiftable := false - switch instr := instr.(type) { - case *Store: - if instr.Val != alloc { - desc.hasLiftableOther = true - hasLiftable = true - } - case *Load: - desc.hasLiftableLoad = true - hasLiftable = true - case *DebugRef: - desc.hasLiftableOther = true - } - if hasLiftable { - if int(instr.ID()) > desc.lastLiftable { - desc.lastLiftable = int(instr.ID()) - } - } - } - - for i := range blocks { - // Update firstUnliftable to be one after lastLiftable. We do this to include the unliftable's preceding - // DebugRefs in the renaming. - if blocks[i].lastLiftable == -1 && !blocks[i].storeInPreds { - // There are no liftable instructions (for this alloc) in this block. Set firstUnliftable to the - // first non-head instruction to avoid inserting the store before phi instructions, which would - // fail validation. - first := -1 - instrLoop: - for i, instr := range fn.Blocks[i].Instrs { - switch instr.(type) { - case *Phi, *Sigma: - default: - first = i - break instrLoop - } - } - blocks[i].firstUnliftable = first - } else { - blocks[i].firstUnliftable = blocks[i].lastLiftable + 1 - } - } - - // If a block is reachable by a (partially) unliftable block, then the entirety of the block is unliftable. In that - // case, stores have to be inserted in the predecessors. - // - // TODO(dh): this isn't always necessary. If the block is reachable by itself, i.e. part of a loop, then if the - // Alloc instruction is itself part of that loop, then there is a subset of instructions in the loop that can be - // lifted. For example: - // - // for { - // x := 42 - // println(x) - // escape(&x) - // } - // - // The x that escapes in one iteration of the loop isn't the same x that we read from on the next iteration. - seen := make(BlockMap[bool], len(fn.Blocks)) - var dfs func(b *BasicBlock) - dfs = func(b *BasicBlock) { - if seen[b.Index] { - return - } - seen[b.Index] = true - desc := &blocks[b.Index] - desc.hasLiftableLoad = false - desc.hasLiftableOther = false - desc.isUnliftable = true - desc.firstUnliftable = 0 - desc.storeInPreds = true - for _, succ := range b.Succs { - dfs(succ) - } - } - for _, b := range fn.Blocks { - if blocks[b.Index].isUnliftable { - for _, succ := range b.Succs { - dfs(succ) - } - } - } - - hasLiftableLoad := false - hasLiftableOther := false - hasUnliftable := false - for _, b := range fn.Blocks { - desc := blocks[b.Index] - hasLiftableLoad = hasLiftableLoad || desc.hasLiftableLoad - hasLiftableOther = hasLiftableOther || desc.hasLiftableOther - if desc.isUnliftable { - hasUnliftable = true - } - } - if !hasLiftableLoad && !hasLiftableOther { - // There are no liftable uses - return false - } else if !hasUnliftable { - // The alloc is entirely liftable without splitting - return true - } else if !hasLiftableLoad { - // The alloc is not entirely liftable, and the only liftable uses are stores. While some of those stores could - // get lifted away, it would also lead to an infinite loop when lifting to a fixpoint, because the newly created - // allocs also get stored into repeatable and that's their only liftable uses. - return false - } - - // We need to insert stores for the new alloc. If a (partially) unliftable block has no unliftable - // predecessors and the use isn't in a phi node, then the store can be inserted right before the unliftable use. - // Otherwise, stores have to be inserted at the end of all liftable predecessors. - - newAlloc := &Alloc{Heap: true} - newAlloc.setBlock(alloc.block) - newAlloc.setType(alloc.typ) - newAlloc.setSource(alloc.source) - newAlloc.index = -1 - newAlloc.comment = "split alloc" - - { - work := instructions[alloc.block.Index] - work.insertInstructions[alloc] = append(work.insertInstructions[alloc], newAlloc) - } - - predHasStore := make(BlockMap[bool], len(fn.Blocks)) - for _, b := range fn.Blocks { - desc := &blocks[b.Index] - bWork := &instructions[b.Index] - - if desc.isUnliftable { - bWork.renameAllocs = append(bWork.renameAllocs, struct { - from *Alloc - to *Alloc - startingAt int - }{ - alloc, newAlloc, int(desc.firstUnliftable), - }) - } - - if !desc.isUnliftable { - continue - } - - propagate := func(in *BasicBlock, before Instruction) { - load := &Load{ - X: alloc, - } - store := &Store{ - Addr: newAlloc, - Val: load, - } - load.setType(deref(alloc.typ)) - load.setBlock(in) - load.comment = "split alloc" - store.setBlock(in) - updateOperandReferrers(load) - updateOperandReferrers(store) - store.comment = "split alloc" - - entry := &instructions[in.Index] - entry.insertInstructions[before] = append(entry.insertInstructions[before], load, store) - } - - if desc.storeInPreds { - // emit stores at the end of liftable preds - for _, pred := range b.Preds { - if blocks[pred.Index].isUnliftable { - continue - } - - if !alloc.block.Dominates(pred) { - // Consider this cfg: - // - // 1 - // /| - // / | - // ↙ ↓ - // 2--→3 - // - // with an Alloc in block 2. It doesn't make sense to insert a store in block 1 for the jump to - // block 3, because 1 can never see the Alloc in the first place. - // - // Ignoring phi nodes, an Alloc always dominates all of its uses, and phi nodes don't matter here, - // because for the incoming edges that do matter, we do emit the stores. - - continue - } - - if predHasStore[pred.Index] { - // Don't generate redundant propagations. Not only is it unnecessary, it can lead to infinite loops - // when trying to lift to a fix point, because redundant stores are liftable. - continue - } - - predHasStore[pred.Index] = true - - before := pred.Instrs[len(pred.Instrs)-1] - propagate(pred, before) - } - } else { - // emit store before the first unliftable use - before := b.Instrs[desc.firstUnliftable] - propagate(b, before) - } - } - - return true -} - -// liftAlloc lifts alloc into registers and populates newPhis and newSigmas with all the φ- and σ-nodes it may require. -func liftAlloc(closure *closure, df domFrontier, rdf postDomFrontier, alloc *Alloc, newPhis BlockMap[[]newPhi], newSigmas BlockMap[[]newSigma]) { - fn := alloc.Parent() - - defblocks := fn.blockset(0) - useblocks := fn.blockset(1) - Aphi := fn.blockset(2) - Asigma := fn.blockset(3) - W := fn.blockset(4) - - // Compute defblocks, the set of blocks containing a - // definition of the alloc cell. - for _, instr := range *alloc.Referrers() { - switch instr := instr.(type) { - case *Store: - defblocks.Add(instr.Block()) - case *Load: - useblocks.Add(instr.Block()) - for _, ref := range *instr.Referrers() { - useblocks.Add(ref.Block()) - } - } - } - // The Alloc itself counts as a (zero) definition of the cell. - defblocks.Add(alloc.Block()) - - if debugLifting { - fmt.Fprintln(os.Stderr, "\tlifting ", alloc, alloc.Name()) - } - - // Φ-insertion. - // - // What follows is the body of the main loop of the insert-φ - // function described by Cytron et al, but instead of using - // counter tricks, we just reset the 'hasAlready' and 'work' - // sets each iteration. These are bitmaps so it's pretty cheap. - - // Initialize W and work to defblocks. - - for change := true; change; { - change = false - { - // Traverse iterated dominance frontier, inserting φ-nodes. - W.Set(defblocks) - - for i := W.Take(); i != -1; i = W.Take() { - n := fn.Blocks[i] - for _, y := range df[n.Index] { - if Aphi.Add(y) { - if len(*alloc.Referrers()) == 0 { - continue - } - live := false - if closure == nil { - live = true - } else { - for _, ref := range *alloc.Referrers() { - if _, ok := ref.(*Load); ok { - if closure.has(y, ref.Block()) { - live = true - break - } - } - } - } - if !live { - continue - } - - // Create φ-node. - // It will be prepended to v.Instrs later, if needed. - if len(y.Preds) == 0 { - // The exit block may be unreachable if the function doesn't - // return, e.g. due to an infinite loop. In that case we - // should not replace loads in the exit block with ϕ node that - // have no edges. Such loads exist when the function has named - // return parameters, as the exit block loads them to turn - // them into a Return instruction. By not replacing the loads - // with ϕ nodes, they will later be replaced by zero - // constants. This is arguably more correct, and more - // importantly, it doesn't break code that assumes that phis - // have at least one edge. - // - // For one instance of breakage see - // https://staticcheck.dev/issues/1533 - continue - } - phi := &Phi{ - Edges: make([]Value, len(y.Preds)), - } - phi.comment = alloc.comment - phi.source = alloc.source - phi.setType(deref(alloc.Type())) - phi.block = y - if debugLifting { - fmt.Fprintf(os.Stderr, "\tplace %s = %s at block %s\n", phi.Name(), phi, y) - } - newPhis[y.Index] = append(newPhis[y.Index], newPhi{phi, alloc}) - - for _, p := range y.Preds { - useblocks.Add(p) - } - change = true - if defblocks.Add(y) { - W.Add(y) - } - } - } - } - } - - { - W.Set(useblocks) - for i := W.Take(); i != -1; i = W.Take() { - n := fn.Blocks[i] - for _, y := range rdf[n.Index] { - if Asigma.Add(y) { - sigmas := make([]*Sigma, 0, len(y.Succs)) - anyLive := false - for _, succ := range y.Succs { - live := false - for _, ref := range *alloc.Referrers() { - if closure == nil || closure.has(succ, ref.Block()) { - live = true - anyLive = true - break - } - } - if live { - sigma := &Sigma{ - From: y, - X: alloc, - } - sigma.comment = alloc.comment - sigma.source = alloc.source - sigma.setType(deref(alloc.Type())) - sigma.block = succ - sigmas = append(sigmas, sigma) - } else { - sigmas = append(sigmas, nil) - } - } - - if anyLive { - newSigmas[y.Index] = append(newSigmas[y.Index], newSigma{alloc, sigmas}) - for _, s := range y.Succs { - defblocks.Add(s) - } - change = true - if useblocks.Add(y) { - W.Add(y) - } - } - } - } - } - } - } -} - -// replaceAll replaces all intraprocedural uses of x with y, -// updating x.Referrers and y.Referrers. -// Precondition: x.Referrers() != nil, i.e. x must be local to some function. -func replaceAll(x, y Value) { - var rands []*Value - pxrefs := x.Referrers() - pyrefs := y.Referrers() - for _, instr := range *pxrefs { - switch instr := instr.(type) { - case *CompositeValue: - // Special case CompositeValue because it might have very large lists of operands - // - // OPT(dh): this loop is still expensive for large composite values - for i, rand := range instr.Values { - if rand == x { - instr.Values[i] = y - } - } - default: - rands = instr.Operands(rands[:0]) // recycle storage - for _, rand := range rands { - if *rand != nil { - if *rand == x { - *rand = y - } - } - } - } - if pyrefs != nil { - *pyrefs = append(*pyrefs, instr) // dups ok - } - } - *pxrefs = nil // x is now unreferenced -} - -func replace(instr Instruction, x, y Value) { - args := instr.Operands(nil) - matched := false - for _, arg := range args { - if *arg == x { - *arg = y - matched = true - } - } - if matched { - yrefs := y.Referrers() - if yrefs != nil { - *yrefs = append(*yrefs, instr) - } - - xrefs := x.Referrers() - if xrefs != nil { - *xrefs = removeInstr(*xrefs, instr) - } - } -} - -// renamed returns the value to which alloc is being renamed, -// constructing it lazily if it's the implicit zero initialization. -func renamed(fn *Function, renaming []Value, alloc *Alloc) Value { - v := renaming[alloc.index] - if v == nil { - v = emitConst(fn, zeroConst(deref(alloc.Type()), alloc.source)) - renaming[alloc.index] = v - } - return v -} - -func copyValue(v Value, why Instruction, info CopyInfo) *Copy { - c := &Copy{ - X: v, - Why: why, - Info: info, - } - if refs := v.Referrers(); refs != nil { - *refs = append(*refs, c) - } - c.setType(v.Type()) - c.setSource(v.Source()) - return c -} - -func splitOnNewInformation(u *BasicBlock, renaming *StackMap) { - renaming.Push() - defer renaming.Pop() - - rename := func(v Value, why Instruction, info CopyInfo, i int) { - c := copyValue(v, why, info) - c.setBlock(u) - renaming.Set(v, c) - u.Instrs = append(u.Instrs, nil) - copy(u.Instrs[i+2:], u.Instrs[i+1:]) - u.Instrs[i+1] = c - } - - replacement := func(v Value) (Value, bool) { - r, ok := renaming.Get(v) - if !ok { - return nil, false - } - for { - rr, ok := renaming.Get(r) - if !ok { - // Store replacement in the map so that future calls to replacement(v) don't have to go through the - // iterative process again. - renaming.Set(v, r) - return r, true - } - r = rr - } - } - - var hasInfo func(v Value, info CopyInfo) bool - hasInfo = func(v Value, info CopyInfo) bool { - switch v := v.(type) { - case *Copy: - return (v.Info&info) == info || hasInfo(v.X, info) - case *FieldAddr, *IndexAddr, *TypeAssert, *MakeChan, *MakeMap, *MakeSlice, *Alloc: - return info == CopyInfoNotNil - case Member, *Builtin: - return info == CopyInfoNotNil - case *Sigma: - return hasInfo(v.X, info) - default: - return false - } - } - - var args []*Value - for i := 0; i < len(u.Instrs); i++ { - instr := u.Instrs[i] - if instr == nil { - continue - } - args = instr.Operands(args[:0]) - for _, arg := range args { - if *arg == nil { - continue - } - if r, ok := replacement(*arg); ok { - *arg = r - replace(instr, *arg, r) - } - } - - // TODO write some bits on why we copy values instead of encoding the actual control flow and panics - - switch instr := instr.(type) { - case *IndexAddr: - // Note that we rename instr.Index and instr.X even if they're already copies, because unique combinations - // of X and Index may lead to unique information. - - // OPT we should rename both variables at once and avoid one memmove - rename(instr.Index, instr, CopyInfoNotNegative, i) - rename(instr.X, instr, CopyInfoNotNil, i) - i += 2 // skip over instructions we just inserted - case *FieldAddr: - if !hasInfo(instr.X, CopyInfoNotNil) { - rename(instr.X, instr, CopyInfoNotNil, i) - i++ - } - case *TypeAssert: - // If we've already type asserted instr.X without comma-ok before, then it can only contain a single type, - // and successive type assertions, no matter the type, don't tell us anything new. - if !hasInfo(instr.X, CopyInfoNotNil|CopyInfoSingleConcreteType) { - rename(instr.X, instr, CopyInfoNotNil|CopyInfoSingleConcreteType, i) - i++ // skip over instruction we just inserted - } - case *Load: - if !hasInfo(instr.X, CopyInfoNotNil) { - rename(instr.X, instr, CopyInfoNotNil, i) - i++ - } - case *Store: - if !hasInfo(instr.Addr, CopyInfoNotNil) { - rename(instr.Addr, instr, CopyInfoNotNil, i) - i++ - } - case *MapUpdate: - if !hasInfo(instr.Map, CopyInfoNotNil) { - rename(instr.Map, instr, CopyInfoNotNil, i) - i++ - } - case CallInstruction: - off := 0 - if !instr.Common().IsInvoke() && !hasInfo(instr.Common().Value, CopyInfoNotNil) { - rename(instr.Common().Value, instr, CopyInfoNotNil, i) - off++ - } - if f, ok := instr.Common().Value.(*Builtin); ok { - switch f.name { - case "close": - arg := instr.Common().Args[0] - if !hasInfo(arg, CopyInfoNotNil|CopyInfoClosed) { - rename(arg, instr, CopyInfoNotNil|CopyInfoClosed, i) - off++ - } - } - } - i += off - case *SliceToArrayPointer: - // A slice to array pointer conversion tells us the minimum length of the slice - rename(instr.X, instr, CopyInfoUnspecified, i) - i++ - case *SliceToArray: - // A slice to array conversion tells us the minimum length of the slice - rename(instr.X, instr, CopyInfoUnspecified, i) - i++ - case *Slice: - // Slicing tells us about some of the bounds - off := 0 - if instr.Low == nil && instr.High == nil && instr.Max == nil { - // If all indices are unspecified, then we can only learn something about instr.X if it might've been - // nil. - if !hasInfo(instr.X, CopyInfoNotNil) { - rename(instr.X, instr, CopyInfoUnspecified, i) - off++ - } - } else { - rename(instr.X, instr, CopyInfoUnspecified, i) - off++ - } - // We copy the indices even if we already know they are not negative, because we can associate numeric - // ranges with them. - if instr.Low != nil { - rename(instr.Low, instr, CopyInfoNotNegative, i) - off++ - } - if instr.High != nil { - rename(instr.High, instr, CopyInfoNotNegative, i) - off++ - } - if instr.Max != nil { - rename(instr.Max, instr, CopyInfoNotNegative, i) - off++ - } - i += off - case *StringLookup: - rename(instr.X, instr, CopyInfoUnspecified, i) - rename(instr.Index, instr, CopyInfoNotNegative, i) - i += 2 - case *Recv: - if !hasInfo(instr.Chan, CopyInfoNotNil) { - // Receiving from a nil channel never completes - rename(instr.Chan, instr, CopyInfoNotNil, i) - i++ - } - case *Send: - if !hasInfo(instr.Chan, CopyInfoNotNil) { - // Sending to a nil channel never completes. Sending to a closed channel panics, but whether a channel - // is closed isn't local to this function, so we didn't learn anything. - rename(instr.Chan, instr, CopyInfoNotNil, i) - i++ - } - } - } - - for _, v := range u.dom.children { - splitOnNewInformation(v, renaming) - } -} - -// rename implements the Cytron et al-based SSI renaming algorithm, a -// preorder traversal of the dominator tree replacing all loads of -// Alloc cells with the value stored to that cell by the dominating -// store instruction. -// -// renaming is a map from *Alloc (keyed by index number) to its -// dominating stored value; newPhis[x] is the set of new φ-nodes to be -// prepended to block x. -func rename(u *BasicBlock, renaming []Value, newPhis BlockMap[[]newPhi], newSigmas BlockMap[[]newSigma]) { - // Each φ-node becomes the new name for its associated Alloc. - for _, np := range newPhis[u.Index] { - phi := np.phi - alloc := np.alloc - renaming[alloc.index] = phi - } - - // Rename loads and stores of allocs. - for i, instr := range u.Instrs { - switch instr := instr.(type) { - case *Alloc: - if instr.index >= 0 { // store of zero to Alloc cell - // Replace dominated loads by the zero value. - renaming[instr.index] = nil - if debugLifting { - fmt.Fprintf(os.Stderr, "\tkill alloc %s\n", instr) - } - // Delete the Alloc. - u.Instrs[i] = nil - u.gaps++ - } - - case *Store: - if alloc, ok := instr.Addr.(*Alloc); ok && alloc.index >= 0 { // store to Alloc cell - // Replace dominated loads by the stored value. - renaming[alloc.index] = instr.Val - if debugLifting { - fmt.Fprintf(os.Stderr, "\tkill store %s; new value: %s\n", - instr, instr.Val.Name()) - } - if refs := instr.Addr.Referrers(); refs != nil { - *refs = removeInstr(*refs, instr) - } - if refs := instr.Val.Referrers(); refs != nil { - *refs = removeInstr(*refs, instr) - } - // Delete the Store. - u.Instrs[i] = nil - u.gaps++ - } - - case *Load: - if alloc, ok := instr.X.(*Alloc); ok && alloc.index >= 0 { // load of Alloc cell - // In theory, we wouldn't be able to replace loads directly, because a loaded value could be used in - // different branches, in which case it should be replaced with different sigma nodes. But we can't - // simply defer replacement, either, because then later stores might incorrectly affect this load. - // - // To avoid doing renaming on _all_ values (instead of just loads and stores like we're doing), we make - // sure during code generation that each load is only used in one block. For example, in constant switch - // statements, where the tag is only evaluated once, we store it in a temporary and load it for each - // comparison, so that we have individual loads to replace. - // - // Because we only rename stores and loads, the end result will not contain sigma nodes for all - // constants. Some constants may be used directly, e.g. in comparisons such as 'x == 5'. We may still - // end up inserting dead sigma nodes in branches, but these will never get used in renaming and will be - // cleaned up when we remove dead phis and sigmas. - newval := renamed(u.Parent(), renaming, alloc) - if debugLifting { - fmt.Fprintf(os.Stderr, "\tupdate load %s = %s with %s\n", - instr.Name(), instr, newval) - } - replaceAll(instr, newval) - u.Instrs[i] = nil - u.gaps++ - } - - case *DebugRef: - if x, ok := instr.X.(*Alloc); ok && x.index >= 0 { - if instr.IsAddr { - instr.X = renamed(u.Parent(), renaming, x) - instr.IsAddr = false - - // Add DebugRef to instr.X's referrers. - if refs := instr.X.Referrers(); refs != nil { - *refs = append(*refs, instr) - } - } else { - // A source expression denotes the address - // of an Alloc that was optimized away. - instr.X = nil - - // Delete the DebugRef. - u.Instrs[i] = nil - u.gaps++ - } - } - } - } - - // update all outgoing sigma nodes with the dominating store - for _, sigmas := range newSigmas[u.Index] { - for _, sigma := range sigmas.sigmas { - if sigma == nil { - continue - } - sigma.X = renamed(u.Parent(), renaming, sigmas.alloc) - } - } - - // For each φ-node in a CFG successor, rename the edge. - for succi, v := range u.Succs { - phis := newPhis[v.Index] - if len(phis) == 0 { - continue - } - i := v.predIndex(u) - for _, np := range phis { - phi := np.phi - alloc := np.alloc - // if there's a sigma node, use it, else use the dominating value - var newval Value - for _, sigmas := range newSigmas[u.Index] { - if sigmas.alloc == alloc && sigmas.sigmas[succi] != nil { - newval = sigmas.sigmas[succi] - break - } - } - if newval == nil { - newval = renamed(u.Parent(), renaming, alloc) - } - if debugLifting { - fmt.Fprintf(os.Stderr, "\tsetphi %s edge %s -> %s (#%d) (alloc=%s) := %s\n", - phi.Name(), u, v, i, alloc.Name(), newval.Name()) - } - phi.Edges[i] = newval - if prefs := newval.Referrers(); prefs != nil { - *prefs = append(*prefs, phi) - } - } - } - - // Continue depth-first recursion over domtree, pushing a - // fresh copy of the renaming map for each subtree. - r := make([]Value, len(renaming)) - for _, v := range u.dom.children { - copy(r, renaming) - - // on entry to a block, the incoming sigma nodes become the new values for their alloc - if idx := u.succIndex(v); idx != -1 { - for _, sigma := range newSigmas[u.Index] { - if sigma.sigmas[idx] != nil { - r[sigma.alloc.index] = sigma.sigmas[idx] - } - } - } - rename(v, r, newPhis, newSigmas) - } - -} - -func simplifyConstantCompositeValues(fn *Function) bool { - changed := false - - for _, b := range fn.Blocks { - n := 0 - for _, instr := range b.Instrs { - replaced := false - - if cv, ok := instr.(*CompositeValue); ok { - ac := &AggregateConst{} - ac.typ = cv.typ - replaced = true - for _, v := range cv.Values { - if c, ok := v.(Constant); ok { - ac.Values = append(ac.Values, c) - } else { - replaced = false - break - } - } - if replaced { - replaceAll(cv, emitConst(fn, ac)) - killInstruction(cv) - } - - } - - if replaced { - changed = true - } else { - b.Instrs[n] = instr - n++ - } - } - - clearInstrs(b.Instrs[n:]) - b.Instrs = b.Instrs[:n] - } - - return changed -} - -func updateOperandReferrers(instr Instruction) { - for _, op := range instr.Operands(nil) { - refs := (*op).Referrers() - if refs != nil { - *refs = append(*refs, instr) - } - } -} - -// deferstackPreamble returns the *Alloc and ssa:deferstack() call for fn.deferstack. -func deferstackPreamble(fn *Function) (*Alloc, *Call) { - if alloc, _ := fn.vars[fn.deferstack].(*Alloc); alloc != nil { - for _, ref := range *alloc.Referrers() { - if ref, _ := ref.(*Store); ref != nil && ref.Addr == alloc { - if call, _ := ref.Val.(*Call); call != nil { - return alloc, call - } - } - } - } - return nil, nil -} diff --git a/vendor/honnef.co/go/tools/go/ir/lvalue.go b/vendor/honnef.co/go/tools/go/ir/lvalue.go deleted file mode 100644 index 86eb4a5d1..000000000 --- a/vendor/honnef.co/go/tools/go/ir/lvalue.go +++ /dev/null @@ -1,175 +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. - -package ir - -// lvalues are the union of addressable expressions and map-index -// expressions. - -import ( - "go/ast" - "go/types" -) - -// An lvalue represents an assignable location that may appear on the -// left-hand side of an assignment. This is a generalization of a -// pointer to permit updates to elements of maps. -type lvalue interface { - store(fn *Function, v Value, source ast.Node) // stores v into the location - load(fn *Function, source ast.Node) Value // loads the contents of the location - address(fn *Function) Value // address of the location - typ() types.Type // returns the type of the location -} - -// An address is an lvalue represented by a true pointer. -type address struct { - addr Value - expr ast.Expr // source syntax of the value (not address) [debug mode] -} - -func (a *address) load(fn *Function, source ast.Node) Value { - return emitLoad(fn, a.addr, source) -} - -func (a *address) store(fn *Function, v Value, source ast.Node) { - store := emitStore(fn, a.addr, v, source) - if a.expr != nil { - // store.Val is v, converted for assignability. - emitDebugRef(fn, a.expr, store.Val, false) - } -} - -func (a *address) address(fn *Function) Value { - if a.expr != nil { - emitDebugRef(fn, a.expr, a.addr, true) - } - return a.addr -} - -func (a *address) typ() types.Type { - return deref(a.addr.Type()) -} - -type compositeElement struct { - cv *CompositeValue - idx int - t types.Type - expr ast.Expr -} - -func (ce *compositeElement) load(fn *Function, source ast.Node) Value { - panic("not implemented") -} - -func (ce *compositeElement) store(fn *Function, v Value, source ast.Node) { - v = emitConv(fn, v, ce.t, source) - ce.cv.Values[ce.idx] = v - if ce.expr != nil { - // store.Val is v, converted for assignability. - emitDebugRef(fn, ce.expr, v, false) - } -} - -func (ce *compositeElement) address(fn *Function) Value { - panic("not implemented") -} - -func (ce *compositeElement) typ() types.Type { - return ce.t -} - -// An element is an lvalue represented by m[k], the location of an -// element of a map. These locations are not addressable -// since pointers cannot be formed from them, but they do support -// load() and store(). -type element struct { - m, k Value // map - t types.Type // map element type -} - -func (e *element) load(fn *Function, source ast.Node) Value { - l := &MapLookup{ - X: e.m, - Index: e.k, - } - l.setType(e.t) - return fn.emit(l, source) -} - -func (e *element) store(fn *Function, v Value, source ast.Node) { - up := &MapUpdate{ - Map: e.m, - Key: e.k, - Value: emitConv(fn, v, e.t, source), - } - fn.emit(up, source) -} - -func (e *element) address(fn *Function) Value { - panic("map elements are not addressable") -} - -func (e *element) typ() types.Type { - return e.t -} - -// A lazyAddress is an lvalue whose address is the result of an instruction. -// These work like an *address except a new address.address() Value -// is created on each load, store and address call. -// A lazyAddress can be used to control when a side effect (nil pointer -// dereference, index out of bounds) of using a location happens. -type lazyAddress struct { - addr func(fn *Function) Value // emit to fn the computation of the address - t types.Type // type of the location - expr ast.Expr // source syntax of the value (not address) [debug mode] -} - -func (l *lazyAddress) load(fn *Function, source ast.Node) Value { - load := emitLoad(fn, l.addr(fn), source) - return load -} - -func (l *lazyAddress) store(fn *Function, v Value, source ast.Node) { - store := emitStore(fn, l.addr(fn), v, source) - if l.expr != nil { - // store.Val is v, converted for assignability. - emitDebugRef(fn, l.expr, store.Val, false) - } -} - -func (l *lazyAddress) address(fn *Function) Value { - addr := l.addr(fn) - if l.expr != nil { - emitDebugRef(fn, l.expr, addr, true) - } - return addr -} - -func (l *lazyAddress) typ() types.Type { return l.t } - -// A blank is a dummy variable whose name is "_". -// It is not reified: loads are illegal and stores are ignored. -type blank struct{} - -func (bl blank) load(fn *Function, source ast.Node) Value { - panic("blank.load is illegal") -} - -func (bl blank) store(fn *Function, v Value, source ast.Node) { - s := &BlankStore{ - Val: v, - } - fn.emit(s, source) -} - -func (bl blank) address(fn *Function) Value { - panic("blank var is not addressable") -} - -func (bl blank) typ() types.Type { - // This should be the type of the blank Ident; the typechecker - // doesn't provide this yet, but fortunately, we don't need it - // yet either. - panic("blank.typ is unimplemented") -} diff --git a/vendor/honnef.co/go/tools/go/ir/methods.go b/vendor/honnef.co/go/tools/go/ir/methods.go deleted file mode 100644 index f8607b03d..000000000 --- a/vendor/honnef.co/go/tools/go/ir/methods.go +++ /dev/null @@ -1,244 +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. - -package ir - -// This file defines utilities for population of method sets. - -import ( - "fmt" - "go/types" - - "honnef.co/go/tools/analysis/lint" -) - -// MethodValue returns the Function implementing method sel, building -// wrapper methods on demand. It returns nil if sel denotes an -// abstract (interface) method. -// -// Precondition: sel.Kind() == MethodVal. -// -// Thread-safe. -// -// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu) -func (prog *Program) MethodValue(sel *types.Selection) *Function { - if sel.Kind() != types.MethodVal { - panic(fmt.Sprintf("MethodValue(%s) kind != MethodVal", sel)) - } - T := sel.Recv() - if types.IsInterface(T) { - return nil // abstract method - } - if prog.mode&LogSource != 0 { - defer logStack("MethodValue %s %v", T, sel)() - } - - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - - return prog.addMethod(prog.createMethodSet(T), sel) -} - -// LookupMethod returns the implementation of the method of type T -// identified by (pkg, name). It returns nil if the method exists but -// is abstract, and panics if T has no such method. -func (prog *Program) LookupMethod(T types.Type, pkg *types.Package, name string) *Function { - sel := prog.MethodSets.MethodSet(T).Lookup(pkg, name) - if sel == nil { - panic(fmt.Sprintf("%s has no method %s", T, types.Id(pkg, name))) - } - return prog.MethodValue(sel) -} - -// methodSet contains the (concrete) methods of a non-interface type. -type methodSet struct { - mapping map[string]*Function // populated lazily - complete bool // mapping contains all methods -} - -// Precondition: !isInterface(T). -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -func (prog *Program) createMethodSet(T types.Type) *methodSet { - mset, ok := prog.methodSets.At(T) - if !ok { - mset = &methodSet{mapping: make(map[string]*Function)} - prog.methodSets.Set(T, mset) - } - return mset -} - -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -func (prog *Program) addMethod(mset *methodSet, sel *types.Selection) *Function { - if sel.Kind() == types.MethodExpr { - panic(sel) - } - id := sel.Obj().Id() - fn := mset.mapping[id] - if fn == nil { - obj := sel.Obj().(*types.Func) - - needsPromotion := len(sel.Index()) > 1 - needsIndirection := !isPointer(recvType(obj)) && isPointer(sel.Recv()) - if needsPromotion || needsIndirection { - fn = makeWrapper(prog, sel) - } else { - fn = prog.declaredFunc(obj) - } - if fn.Signature.Recv() == nil { - panic(fn) // missing receiver - } - mset.mapping[id] = fn - } - return fn -} - -// RuntimeTypes returns a new unordered slice containing all -// concrete types in the program for which a complete (non-empty) -// method set is required at run-time. -// -// Thread-safe. -// -// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu) -func (prog *Program) RuntimeTypes() []types.Type { - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - - var res []types.Type - prog.methodSets.Iterate(func(T types.Type, v *methodSet) { - if v.complete { - res = append(res, T) - } - }) - return res -} - -// declaredFunc returns the concrete function/method denoted by obj. -// Panic ensues if there is none. -func (prog *Program) declaredFunc(obj *types.Func) *Function { - if origin := obj.Origin(); origin != obj { - // Calling method on instantiated type, create a wrapper that calls the generic type's method - base := prog.packageLevelValue(origin) - return makeInstance(prog, base.(*Function), obj.Type().(*types.Signature), nil) - } else { - if v := prog.packageLevelValue(obj); v != nil { - return v.(*Function) - } - } - panic("no concrete method: " + obj.String()) -} - -// needMethodsOf ensures that runtime type information (including the -// complete method set) is available for the specified type T and all -// its subcomponents. -// -// needMethodsOf must be called for at least every type that is an -// operand of some MakeInterface instruction, and for the type of -// every exported package member. -// -// Precondition: T is not a method signature (*Signature with Recv()!=nil). -// -// Thread-safe. (Called via emitConv from multiple builder goroutines.) -// -// TODO(adonovan): make this faster. It accounts for 20% of SSA build time. -// -// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu) -func (prog *Program) needMethodsOf(T types.Type) { - prog.methodsMu.Lock() - prog.needMethods(T, false) - prog.methodsMu.Unlock() -} - -// Precondition: T is not a method signature (*Signature with Recv()!=nil). -// Recursive case: skip => don't create methods for T. -// -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -func (prog *Program) needMethods(T types.Type, skip bool) { - // Each package maintains its own set of types it has visited. - if prevSkip, ok := prog.runtimeTypes.At(T); ok { - // needMethods(T) was previously called - if !prevSkip || skip { - return // already seen, with same or false 'skip' value - } - } - prog.runtimeTypes.Set(T, skip) - - tmset := prog.MethodSets.MethodSet(T) - - if !skip && !types.IsInterface(T) && tmset.Len() > 0 { - // Create methods of T. - mset := prog.createMethodSet(T) - if !mset.complete { - mset.complete = true - n := tmset.Len() - for i := 0; i < n; i++ { - prog.addMethod(mset, tmset.At(i)) - } - } - } - - // Recursion over signatures of each method. - for i := 0; i < tmset.Len(); i++ { - sig := tmset.At(i).Type().(*types.Signature) - prog.needMethods(sig.Params(), false) - prog.needMethods(sig.Results(), false) - } - - switch t := T.(type) { - case *types.Basic: - // nop - - case *types.Interface, *types.TypeParam: - // nop---handled by recursion over method set. - - case *types.Pointer: - prog.needMethods(t.Elem(), false) - - case *types.Slice: - prog.needMethods(t.Elem(), false) - - case *types.Chan: - prog.needMethods(t.Elem(), false) - - case *types.Map: - prog.needMethods(t.Key(), false) - prog.needMethods(t.Elem(), false) - - case *types.Signature: - if t.Recv() != nil { - panic(fmt.Sprintf("Signature %s has Recv %s", t, t.Recv())) - } - prog.needMethods(t.Params(), false) - prog.needMethods(t.Results(), false) - - case *types.Named: - // A pointer-to-named type can be derived from a named - // type via reflection. It may have methods too. - prog.needMethods(types.NewPointer(t), false) - - // Consider 'type T struct{S}' where S has methods. - // Reflection provides no way to get from T to struct{S}, - // only to S, so the method set of struct{S} is unwanted, - // so set 'skip' flag during recursion. - prog.needMethods(t.Underlying(), true) - - case *types.Array: - prog.needMethods(t.Elem(), false) - - case *types.Struct: - for i, n := 0, t.NumFields(); i < n; i++ { - prog.needMethods(t.Field(i).Type(), false) - } - - case *types.Tuple: - for i, n := 0, t.Len(); i < n; i++ { - prog.needMethods(t.At(i).Type(), false) - } - - case *types.Alias: - prog.needMethods(types.Unalias(t), false) - - default: - lint.ExhaustiveTypeSwitch(T) - } -} diff --git a/vendor/honnef.co/go/tools/go/ir/mode.go b/vendor/honnef.co/go/tools/go/ir/mode.go deleted file mode 100644 index 15b5a33f7..000000000 --- a/vendor/honnef.co/go/tools/go/ir/mode.go +++ /dev/null @@ -1,104 +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 ir - -// This file defines the BuilderMode type and its command-line flag. - -import ( - "bytes" - "fmt" -) - -// BuilderMode is a bitmask of options for diagnostics and checking. -// -// *BuilderMode satisfies the flag.Value interface. Example: -// -// var mode = ir.BuilderMode(0) -// func init() { flag.Var(&mode, "build", ir.BuilderModeDoc) } -type BuilderMode uint - -const ( - PrintPackages BuilderMode = 1 << iota // Print package inventory to stdout - PrintFunctions // Print function IR code to stdout - PrintSource // Print source code when printing function IR - LogSource // Log source locations as IR builder progresses - SanityCheckFunctions // Perform sanity checking of function bodies - NaiveForm // Build naïve IR form: don't replace local loads/stores with registers - GlobalDebug // Enable debug info for all packages - SplitAfterNewInformation // Split live range after we learn something new about a value -) - -const BuilderModeDoc = `Options controlling the IR builder. -The value is a sequence of zero or more of these symbols: -C perform sanity [C]hecking of the IR form. -D include [D]ebug info for every function. -P print [P]ackage inventory. -F print [F]unction IR code. -A print [A]ST nodes responsible for IR instructions -S log [S]ource locations as IR builder progresses. -N build [N]aive IR form: don't replace local loads/stores with registers. -I Split live range after a value is used as slice or array index -` - -func (m BuilderMode) String() string { - var buf bytes.Buffer - if m&GlobalDebug != 0 { - buf.WriteByte('D') - } - if m&PrintPackages != 0 { - buf.WriteByte('P') - } - if m&PrintFunctions != 0 { - buf.WriteByte('F') - } - if m&PrintSource != 0 { - buf.WriteByte('A') - } - if m&LogSource != 0 { - buf.WriteByte('S') - } - if m&SanityCheckFunctions != 0 { - buf.WriteByte('C') - } - if m&NaiveForm != 0 { - buf.WriteByte('N') - } - if m&SplitAfterNewInformation != 0 { - buf.WriteByte('I') - } - return buf.String() -} - -// Set parses the flag characters in s and updates *m. -func (m *BuilderMode) Set(s string) error { - var mode BuilderMode - for _, c := range s { - switch c { - case 'D': - mode |= GlobalDebug - case 'P': - mode |= PrintPackages - case 'F': - mode |= PrintFunctions - case 'A': - mode |= PrintSource - case 'S': - mode |= LogSource - case 'C': - mode |= SanityCheckFunctions - case 'N': - mode |= NaiveForm - case 'I': - mode |= SplitAfterNewInformation - default: - return fmt.Errorf("unknown BuilderMode option: %q", c) - } - } - *m = mode - return nil -} - -// Get returns m. -func (m BuilderMode) Get() interface{} { return m } diff --git a/vendor/honnef.co/go/tools/go/ir/print.go b/vendor/honnef.co/go/tools/go/ir/print.go deleted file mode 100644 index b30753dff..000000000 --- a/vendor/honnef.co/go/tools/go/ir/print.go +++ /dev/null @@ -1,539 +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. - -package ir - -// This file implements the String() methods for all Value and -// Instruction types. - -import ( - "bytes" - "fmt" - "go/types" - "io" - "reflect" - "sort" - "strings" - - "honnef.co/go/tools/go/types/typeutil" -) - -// relName returns the name of v relative to i. -// In most cases, this is identical to v.Name(), but references to -// Functions (including methods) and Globals use RelString and -// all types are displayed with relType, so that only cross-package -// references are package-qualified. -func relName(v Value, i Instruction) string { - if v == nil { - return "" - } - var from *types.Package - if i != nil { - from = i.Parent().pkg() - } - switch v := v.(type) { - case Member: // *Function or *Global - return v.RelString(from) - } - return v.Name() -} - -func relType(t types.Type, from *types.Package) string { - return types.TypeString(t, types.RelativeTo(from)) -} - -func relTerm(term *types.Term, from *types.Package) string { - s := relType(term.Type(), from) - if term.Tilde() { - return "~" + s - } - return s -} - -func relString(m Member, from *types.Package) string { - // NB: not all globals have an Object (e.g. init$guard), - // so use Package().Object not Object.Package(). - if pkg := m.Package().Pkg; pkg != nil && pkg != from { - return fmt.Sprintf("%s.%s", pkg.Path(), m.Name()) - } - return m.Name() -} - -// Value.String() -// -// This method is provided only for debugging. -// It never appears in disassembly, which uses Value.Name(). - -func (v *Parameter) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Parameter <%s> {%s}", relType(v.Type(), from), v.name) -} - -func (v *FreeVar) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("FreeVar <%s> %s", relType(v.Type(), from), v.Name()) -} - -func (v *Builtin) String() string { - return fmt.Sprintf("Builtin %s", v.Name()) -} - -// Instruction.String() - -func (v *Alloc) String() string { - from := v.Parent().pkg() - storage := "Stack" - if v.Heap { - storage = "Heap" - } - return fmt.Sprintf("%sAlloc <%s>", storage, relType(v.Type(), from)) -} - -func (v *Sigma) String() string { - from := v.Parent().pkg() - s := fmt.Sprintf("Sigma <%s> [b%d] %s", relType(v.Type(), from), v.From.Index, v.X.Name()) - return s -} - -func (v *Phi) String() string { - var b bytes.Buffer - fmt.Fprintf(&b, "Phi <%s>", v.Type()) - for i, edge := range v.Edges { - b.WriteString(" ") - // Be robust against malformed CFG. - if v.block == nil { - b.WriteString("??") - continue - } - block := -1 - if i < len(v.block.Preds) { - block = v.block.Preds[i].Index - } - fmt.Fprintf(&b, "%d:", block) - edgeVal := "" // be robust - if edge != nil { - edgeVal = relName(edge, v) - } - b.WriteString(edgeVal) - } - return b.String() -} - -func printCall(v *CallCommon, prefix string, instr Instruction) string { - var b bytes.Buffer - if !v.IsInvoke() { - if value, ok := instr.(Value); ok { - fmt.Fprintf(&b, "%s <%s> %s", prefix, relType(value.Type(), instr.Parent().pkg()), relName(v.Value, instr)) - } else { - fmt.Fprintf(&b, "%s %s", prefix, relName(v.Value, instr)) - } - } else { - if value, ok := instr.(Value); ok { - fmt.Fprintf(&b, "%sInvoke <%s> %s.%s", prefix, relType(value.Type(), instr.Parent().pkg()), relName(v.Value, instr), v.Method.Name()) - } else { - fmt.Fprintf(&b, "%sInvoke %s.%s", prefix, relName(v.Value, instr), v.Method.Name()) - } - } - for _, arg := range v.TypeArgs { - b.WriteString(" ") - b.WriteString(relType(arg, instr.Parent().pkg())) - } - for _, arg := range v.Args { - b.WriteString(" ") - b.WriteString(relName(arg, instr)) - } - return b.String() -} - -func (c *CallCommon) String() string { - return printCall(c, "", nil) -} - -func (v *Call) String() string { - return printCall(&v.Call, "Call", v) -} - -func (v *BinOp) String() string { - return fmt.Sprintf("BinOp <%s> {%s} %s %s", relType(v.Type(), v.Parent().pkg()), v.Op.String(), relName(v.X, v), relName(v.Y, v)) -} - -func (v *UnOp) String() string { - return fmt.Sprintf("UnOp <%s> {%s} %s", relType(v.Type(), v.Parent().pkg()), v.Op.String(), relName(v.X, v)) -} - -func (v *Load) String() string { - return fmt.Sprintf("Load <%s> %s", relType(v.Type(), v.Parent().pkg()), relName(v.X, v)) -} - -func (v *Copy) String() string { - return fmt.Sprintf("Copy <%s> %s", relType(v.Type(), v.Parent().pkg()), relName(v.X, v)) -} - -func printConv(prefix string, v, x Value) string { - from := v.Parent().pkg() - return fmt.Sprintf("%s <%s> %s", - prefix, - relType(v.Type(), from), - relName(x, v.(Instruction))) -} - -func (v *ChangeType) String() string { return printConv("ChangeType", v, v.X) } -func (v *Convert) String() string { return printConv("Convert", v, v.X) } -func (v *ChangeInterface) String() string { return printConv("ChangeInterface", v, v.X) } -func (v *SliceToArrayPointer) String() string { return printConv("SliceToArrayPointer", v, v.X) } -func (v *SliceToArray) String() string { return printConv("SliceToArray", v, v.X) } -func (v *MakeInterface) String() string { return printConv("MakeInterface", v, v.X) } - -func (v *MakeClosure) String() string { - from := v.Parent().pkg() - var b bytes.Buffer - fmt.Fprintf(&b, "MakeClosure <%s> %s", relType(v.Type(), from), relName(v.Fn, v)) - if v.Bindings != nil { - for _, c := range v.Bindings { - b.WriteString(" ") - b.WriteString(relName(c, v)) - } - } - return b.String() -} - -func (v *MakeSlice) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("MakeSlice <%s> %s %s", - relType(v.Type(), from), - relName(v.Len, v), - relName(v.Cap, v)) -} - -func (v *Slice) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Slice <%s> %s %s %s %s", - relType(v.Type(), from), relName(v.X, v), relName(v.Low, v), relName(v.High, v), relName(v.Max, v)) -} - -func (v *MakeMap) String() string { - res := "" - if v.Reserve != nil { - res = relName(v.Reserve, v) - } - from := v.Parent().pkg() - return fmt.Sprintf("MakeMap <%s> %s", relType(v.Type(), from), res) -} - -func (v *MakeChan) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("MakeChan <%s> %s", relType(v.Type(), from), relName(v.Size, v)) -} - -func (v *FieldAddr) String() string { - from := v.Parent().pkg() - // v.X.Type() might be a pointer to a type parameter whose core type is a pointer to a struct - st := deref(typeutil.CoreType(deref(v.X.Type()))).Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - return fmt.Sprintf("FieldAddr <%s> [%d] (%s) %s", relType(v.Type(), from), v.Field, name, relName(v.X, v)) -} - -func (v *Field) String() string { - st := typeutil.CoreType(v.X.Type()).Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - from := v.Parent().pkg() - return fmt.Sprintf("Field <%s> [%d] (%s) %s", relType(v.Type(), from), v.Field, name, relName(v.X, v)) -} - -func (v *IndexAddr) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("IndexAddr <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *Index) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Index <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *MapLookup) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("MapLookup <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *StringLookup) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("StringLookup <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *Range) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Range <%s> %s", relType(v.Type(), from), relName(v.X, v)) -} - -func (v *Next) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Next <%s> %s", relType(v.Type(), from), relName(v.Iter, v)) -} - -func (v *TypeAssert) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("TypeAssert <%s> %s", relType(v.Type(), from), relName(v.X, v)) -} - -func (v *Extract) String() string { - from := v.Parent().pkg() - name := v.Tuple.Type().(*types.Tuple).At(v.Index).Name() - return fmt.Sprintf("Extract <%s> [%d] (%s) %s", relType(v.Type(), from), v.Index, name, relName(v.Tuple, v)) -} - -func (s *Jump) String() string { - // Be robust against malformed CFG. - block := -1 - if s.block != nil && len(s.block.Succs) == 1 { - block = s.block.Succs[0].Index - } - str := fmt.Sprintf("Jump → b%d", block) - if s.Comment() != "" { - str = fmt.Sprintf("%s # %s", str, s.Comment()) - } - return str -} - -func (s *Unreachable) String() string { - // Be robust against malformed CFG. - block := -1 - if s.block != nil && len(s.block.Succs) == 1 { - block = s.block.Succs[0].Index - } - return fmt.Sprintf("Unreachable → b%d", block) -} - -func (s *If) String() string { - // Be robust against malformed CFG. - tblock, fblock := -1, -1 - if s.block != nil && len(s.block.Succs) == 2 { - tblock = s.block.Succs[0].Index - fblock = s.block.Succs[1].Index - } - return fmt.Sprintf("If %s → b%d b%d", relName(s.Cond, s), tblock, fblock) -} - -func (s *ConstantSwitch) String() string { - var b bytes.Buffer - fmt.Fprintf(&b, "ConstantSwitch %s", relName(s.Tag, s)) - for _, cond := range s.Conds { - fmt.Fprintf(&b, " %s", relName(cond, s)) - } - fmt.Fprint(&b, " →") - for _, succ := range s.block.Succs { - fmt.Fprintf(&b, " b%d", succ.Index) - } - return b.String() -} - -func (v *CompositeValue) String() string { - var b bytes.Buffer - from := v.Parent().pkg() - fmt.Fprintf(&b, "CompositeValue <%s>", relType(v.Type(), from)) - if v.NumSet >= len(v.Values) { - // All values provided - fmt.Fprint(&b, " [all]") - } else if v.Bitmap.BitLen() == 0 { - // No values provided - fmt.Fprint(&b, " [none]") - } else { - // Some values provided - bits := []byte(fmt.Sprintf("%0*b", len(v.Values), &v.Bitmap)) - for i := 0; i < len(bits)/2; i++ { - o := len(bits) - 1 - i - bits[i], bits[o] = bits[o], bits[i] - } - fmt.Fprintf(&b, " [%s]", bits) - } - for _, vv := range v.Values { - fmt.Fprintf(&b, " %s", relName(vv, v)) - } - return b.String() -} - -func (s *TypeSwitch) String() string { - from := s.Parent().pkg() - var b bytes.Buffer - fmt.Fprintf(&b, "TypeSwitch <%s> %s", relType(s.typ, from), relName(s.Tag, s)) - for _, cond := range s.Conds { - fmt.Fprintf(&b, " %q", relType(cond, s.block.parent.pkg())) - } - return b.String() -} - -func (s *Go) String() string { - return printCall(&s.Call, "Go", s) -} - -func (s *Panic) String() string { - // Be robust against malformed CFG. - block := -1 - if s.block != nil && len(s.block.Succs) == 1 { - block = s.block.Succs[0].Index - } - return fmt.Sprintf("Panic %s → b%d", relName(s.X, s), block) -} - -func (s *Return) String() string { - var b bytes.Buffer - b.WriteString("Return") - for _, r := range s.Results { - b.WriteString(" ") - b.WriteString(relName(r, s)) - } - return b.String() -} - -func (*RunDefers) String() string { - return "RunDefers" -} - -func (s *Send) String() string { - return fmt.Sprintf("Send %s %s", relName(s.Chan, s), relName(s.X, s)) -} - -func (recv *Recv) String() string { - from := recv.Parent().pkg() - return fmt.Sprintf("Recv <%s> %s", relType(recv.Type(), from), relName(recv.Chan, recv)) -} - -func (s *Defer) String() string { - prefix := "Defer " - if s._DeferStack != nil { - prefix += "[" + relName(s._DeferStack, s) + "] " - } - c := printCall(&s.Call, prefix, s) - return c -} - -func (s *Select) String() string { - var b bytes.Buffer - for i, st := range s.States { - if i > 0 { - b.WriteString(", ") - } - if st.Dir == types.RecvOnly { - b.WriteString("<-") - b.WriteString(relName(st.Chan, s)) - } else { - b.WriteString(relName(st.Chan, s)) - b.WriteString("<-") - b.WriteString(relName(st.Send, s)) - } - } - non := "" - if !s.Blocking { - non = "Non" - } - from := s.Parent().pkg() - return fmt.Sprintf("Select%sBlocking <%s> [%s]", non, relType(s.Type(), from), b.String()) -} - -func (s *Store) String() string { - return fmt.Sprintf("Store {%s} %s %s", - s.Val.Type(), relName(s.Addr, s), relName(s.Val, s)) -} - -func (s *BlankStore) String() string { - return fmt.Sprintf("BlankStore %s", relName(s.Val, s)) -} - -func (s *MapUpdate) String() string { - return fmt.Sprintf("MapUpdate %s %s %s", relName(s.Map, s), relName(s.Key, s), relName(s.Value, s)) -} - -func (s *DebugRef) String() string { - p := s.Parent().Prog.Fset.Position(s.Pos()) - var descr interface{} - if s.object != nil { - descr = s.object // e.g. "var x int" - } else { - descr = reflect.TypeOf(s.Expr) // e.g. "*ast.CallExpr" - } - var addr string - if s.IsAddr { - addr = "address of " - } - return fmt.Sprintf("; %s%s @ %d:%d is %s", addr, descr, p.Line, p.Column, s.X.Name()) -} - -func (p *Package) String() string { - return "package " + p.Pkg.Path() -} - -var _ io.WriterTo = (*Package)(nil) // *Package implements io.Writer - -func (p *Package) WriteTo(w io.Writer) (int64, error) { - var buf bytes.Buffer - WritePackage(&buf, p) - n, err := w.Write(buf.Bytes()) - return int64(n), err -} - -// WritePackage writes to buf a human-readable summary of p. -func WritePackage(buf *bytes.Buffer, p *Package) { - fmt.Fprintf(buf, "%s:\n", p) - - var names []string - maxname := 0 - for name := range p.Members { - if l := len(name); l > maxname { - maxname = l - } - names = append(names, name) - } - - from := p.Pkg - sort.Strings(names) - for _, name := range names { - switch mem := p.Members[name].(type) { - case *NamedConst: - fmt.Fprintf(buf, " const %-*s %s = %s\n", - maxname, name, mem.Name(), mem.Value.RelString(from)) - - case *Function: - fmt.Fprintf(buf, " func %-*s %s\n", - maxname, name, relType(mem.Type(), from)) - - case *Type: - fmt.Fprintf(buf, " type %-*s %s\n", - maxname, name, relType(mem.Type().Underlying(), from)) - for _, meth := range typeutil.IntuitiveMethodSet(mem.Type(), &p.Prog.MethodSets) { - fmt.Fprintf(buf, " %s\n", types.SelectionString(meth, types.RelativeTo(from))) - } - - case *Global: - fmt.Fprintf(buf, " var %-*s %s\n", - maxname, name, relType(mem.Type().(*types.Pointer).Elem(), from)) - } - } - - fmt.Fprintf(buf, "\n") -} - -func (v *MultiConvert) String() string { - from := v.Parent().Pkg.Pkg - - var b strings.Builder - b.WriteString(printConv("MultiConvert", v, v.X)) - b.WriteString(" [") - for i, s := range v.from.Terms { - for j, d := range v.to.Terms { - if i != 0 || j != 0 { - b.WriteString(" | ") - } - fmt.Fprintf(&b, "%s -> %s", relTerm(s, from), relTerm(d, from)) - } - } - b.WriteString("]") - return b.String() -} diff --git a/vendor/honnef.co/go/tools/go/ir/sanity.go b/vendor/honnef.co/go/tools/go/ir/sanity.go deleted file mode 100644 index 4bbd711fa..000000000 --- a/vendor/honnef.co/go/tools/go/ir/sanity.go +++ /dev/null @@ -1,568 +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. - -package ir - -// An optional pass for sanity-checking invariants of the IR representation. -// Currently it checks CFG invariants but little at the instruction level. - -import ( - "bytes" - "fmt" - "go/ast" - "go/types" - "io" - "os" - "strings" - - "honnef.co/go/tools/go/types/typeutil" -) - -type sanity struct { - reporter io.Writer - fn *Function - block *BasicBlock - instrs map[Instruction]struct{} - insane bool -} - -// sanityCheck performs integrity checking of the IR representation -// of the function fn and returns true if it was valid. Diagnostics -// are written to reporter if non-nil, os.Stderr otherwise. Some -// diagnostics are only warnings and do not imply a negative result. -// -// Sanity-checking is intended to facilitate the debugging of code -// transformation passes. -func sanityCheck(fn *Function, reporter io.Writer) bool { - if reporter == nil { - reporter = os.Stderr - } - return (&sanity{reporter: reporter}).checkFunction(fn) -} - -// mustSanityCheck is like sanityCheck but panics instead of returning -// a negative result. -func mustSanityCheck(fn *Function, reporter io.Writer) { - if !sanityCheck(fn, reporter) { - fn.WriteTo(os.Stderr) - panic("SanityCheck failed") - } -} - -func (s *sanity) diagnostic(prefix, format string, args ...interface{}) { - fmt.Fprintf(s.reporter, "%s: function %s", prefix, s.fn) - if s.block != nil { - fmt.Fprintf(s.reporter, ", block %s", s.block) - } - io.WriteString(s.reporter, ": ") - fmt.Fprintf(s.reporter, format, args...) - io.WriteString(s.reporter, "\n") -} - -func (s *sanity) errorf(format string, args ...interface{}) { - s.insane = true - s.diagnostic("Error", format, args...) -} - -func (s *sanity) warnf(format string, args ...interface{}) { - s.diagnostic("Warning", format, args...) -} - -// findDuplicate returns an arbitrary basic block that appeared more -// than once in blocks, or nil if all were unique. -func findDuplicate(blocks []*BasicBlock) *BasicBlock { - if len(blocks) < 2 { - return nil - } - if blocks[0] == blocks[1] { - return blocks[0] - } - // Slow path: - m := make(map[*BasicBlock]bool) - for _, b := range blocks { - if m[b] { - return b - } - m[b] = true - } - return nil -} - -func (s *sanity) checkInstr(idx int, instr Instruction) { - switch instr := instr.(type) { - case *If, *Jump, *Return, *Panic, *Unreachable, *ConstantSwitch: - s.errorf("control flow instruction not at end of block") - case *Sigma: - if idx > 0 { - prev := s.block.Instrs[idx-1] - if _, ok := prev.(*Sigma); !ok { - s.errorf("Sigma instruction follows a non-Sigma: %T", prev) - } - } - case *Phi: - if idx == 0 { - // It suffices to apply this check to just the first phi node. - if dup := findDuplicate(s.block.Preds); dup != nil { - s.errorf("phi node in block with duplicate predecessor %s", dup) - } - } else { - prev := s.block.Instrs[idx-1] - switch prev.(type) { - case *Phi, *Sigma: - default: - s.errorf("Phi instruction follows a non-Phi, non-Sigma: %T", prev) - } - } - if ne, np := len(instr.Edges), len(s.block.Preds); ne != np { - s.errorf("phi node has %d edges but %d predecessors", ne, np) - - } else { - for i, e := range instr.Edges { - if e == nil { - s.errorf("phi node '%s' has no value for edge #%d from %s", instr.Comment(), i, s.block.Preds[i]) - } - } - } - - case *Alloc: - if !instr.Heap { - found := false - for _, l := range s.fn.Locals { - if l == instr { - found = true - break - } - } - if !found { - s.errorf("local alloc %s = %s does not appear in Function.Locals", instr.Name(), instr) - } - } - - case *BinOp: - case *Call: - case *ChangeInterface: - case *ChangeType: - case *SliceToArrayPointer: - case *SliceToArray: - case *Convert: - tsetInstrX := typeutil.NewTypeSet(instr.X.Type().Underlying()) - tsetInstr := typeutil.NewTypeSet(instr.Type().Underlying()) - ok1 := tsetInstr.Any(func(term *types.Term) bool { _, ok := term.Type().Underlying().(*types.Basic); return ok }) - ok2 := tsetInstrX.Any(func(term *types.Term) bool { _, ok := term.Type().Underlying().(*types.Basic); return ok }) - if !ok1 && !ok2 { - s.errorf("convert %s -> %s: at least one type set must contain basic type", instr.X.Type(), instr.Type()) - } - - case *MultiConvert: - case *Defer: - case *Extract: - case *Field: - case *FieldAddr: - case *Go: - case *Index: - case *IndexAddr: - case *MapLookup: - case *StringLookup: - case *MakeChan: - case *MakeClosure: - numFree := len(instr.Fn.(*Function).FreeVars) - numBind := len(instr.Bindings) - if numFree != numBind { - s.errorf("MakeClosure has %d Bindings for function %s with %d free vars", - numBind, instr.Fn, numFree) - - } - if recv := instr.Type().(*types.Signature).Recv(); recv != nil { - s.errorf("MakeClosure's type includes receiver %s", recv.Type()) - } - - case *MakeInterface: - case *MakeMap: - case *MakeSlice: - case *MapUpdate: - case *Next: - case *Range: - case *RunDefers: - case *Select: - case *Send: - case *Slice: - case *Store: - case *TypeAssert: - case *UnOp: - case *DebugRef: - case *BlankStore: - case *Load: - case *Parameter: - case *Const: - case *AggregateConst: - case *ArrayConst: - case *GenericConst: - case *Recv: - case *TypeSwitch: - case *CompositeValue: - default: - panic(fmt.Sprintf("Unknown instruction type: %T", instr)) - } - - if call, ok := instr.(CallInstruction); ok { - if call.Common().Signature() == nil { - s.errorf("nil signature: %s", call) - } - } - - // Check that value-defining instructions have valid types - // and a valid referrer list. - if v, ok := instr.(Value); ok { - t := v.Type() - if t == nil { - s.errorf("no type: %s = %s", v.Name(), v) - } else if b, ok := t.Underlying().(*types.Basic); ok && b.Info()&types.IsUntyped != 0 { - if _, ok := v.(*Const); !ok { - s.errorf("instruction has 'untyped' result: %s = %s : %s", v.Name(), v, t) - } - } - s.checkReferrerList(v) - } - - // Untyped constants are legal as instruction Operands(), - // for example: - // _ = "foo"[0] - // or: - // if wordsize==64 {...} - - // All other non-Instruction Values can be found via their - // enclosing Function or Package. -} - -func (s *sanity) checkFinalInstr(instr Instruction) { - switch instr := instr.(type) { - case *If: - if nsuccs := len(s.block.Succs); nsuccs != 2 { - s.errorf("If-terminated block has %d successors; expected 2", nsuccs) - return - } - if s.block.Succs[0] == s.block.Succs[1] { - s.errorf("If-instruction has same True, False target blocks: %s", s.block.Succs[0]) - return - } - - case *Jump: - if nsuccs := len(s.block.Succs); nsuccs != 1 { - s.errorf("Jump-terminated block has %d successors; expected 1", nsuccs) - return - } - - case *Return: - if nsuccs := len(s.block.Succs); nsuccs != 0 { - s.errorf("Return-terminated block has %d successors; expected none", nsuccs) - return - } - if na, nf := len(instr.Results), s.fn.Signature.Results().Len(); nf != na { - s.errorf("%d-ary return in %d-ary function", na, nf) - } - - case *Panic: - if nsuccs := len(s.block.Succs); nsuccs != 1 { - s.errorf("Panic-terminated block has %d successors; expected one", nsuccs) - return - } - - case *Unreachable: - if nsuccs := len(s.block.Succs); nsuccs != 1 { - s.errorf("Unreachable-terminated block has %d successors; expected one", nsuccs) - return - } - - case *ConstantSwitch: - - default: - s.errorf("non-control flow instruction at end of block") - } -} - -func (s *sanity) checkBlock(b *BasicBlock, index int) { - s.block = b - - if b.Index != index { - s.errorf("block has incorrect Index %d", b.Index) - } - if b.parent != s.fn { - s.errorf("block has incorrect parent %s", b.parent) - } - - // Check all blocks are reachable. - // (The entry block is always implicitly reachable, the exit block may be unreachable.) - if index > 1 && len(b.Preds) == 0 { - s.warnf("unreachable block") - if b.Instrs == nil { - // Since this block is about to be pruned, - // tolerating transient problems in it - // simplifies other optimizations. - return - } - } - - // Check predecessor and successor relations are dual, - // and that all blocks in CFG belong to same function. - for _, a := range b.Preds { - found := false - for _, bb := range a.Succs { - if bb == b { - found = true - break - } - } - if !found { - s.errorf("expected successor edge in predecessor %s; found only: %s", a, a.Succs) - } - if a.parent != s.fn { - s.errorf("predecessor %s belongs to different function %s", a, a.parent) - } - } - for _, c := range b.Succs { - found := false - for _, bb := range c.Preds { - if bb == b { - found = true - break - } - } - if !found { - s.errorf("expected predecessor edge in successor %s; found only: %s", c, c.Preds) - } - if c.parent != s.fn { - s.errorf("successor %s belongs to different function %s", c, c.parent) - } - } - - // Check each instruction is sane. - n := len(b.Instrs) - if n == 0 { - s.errorf("basic block contains no instructions") - } - var rands [10]*Value // reuse storage - for j, instr := range b.Instrs { - if instr == nil { - s.errorf("nil instruction at index %d", j) - continue - } - if b2 := instr.Block(); b2 == nil { - s.errorf("nil Block() for instruction at index %d", j) - continue - } else if b2 != b { - s.errorf("wrong Block() (%s) for instruction at index %d ", b2, j) - continue - } - if j < n-1 { - s.checkInstr(j, instr) - } else { - s.checkFinalInstr(instr) - } - - // Check Instruction.Operands. - operands: - for i, op := range instr.Operands(rands[:0]) { - if op == nil { - s.errorf("nil operand pointer %d of %s", i, instr) - continue - } - val := *op - if val == nil { - continue // a nil operand is ok - } - - // Check that "untyped" types only appear on constant operands. - if _, ok := (*op).(*Const); !ok { - if basic, ok := types.Unalias((*op).Type()).(*types.Basic); ok { - if basic.Info()&types.IsUntyped != 0 { - s.errorf("operand #%d of %s is untyped: %s", i, instr, basic) - } - } - } - - // Check that Operands that are also Instructions belong to same function. - // TODO(adonovan): also check their block dominates block b. - if val, ok := val.(Instruction); ok { - if val.Block() == nil { - s.errorf("operand %d of %s is an instruction (%s) that belongs to no block", i, instr, val) - } else if val.Parent() != s.fn { - s.errorf("operand %d of %s is an instruction (%s) from function %s", i, instr, val, val.Parent()) - } - } - - // Check that each function-local operand of - // instr refers back to instr. (NB: quadratic) - switch val := val.(type) { - case *Const, *Global, *Builtin: - continue // not local - case *Function: - if val.parent == nil { - continue // only anon functions are local - } - } - - // TODO(adonovan): check val.Parent() != nil <=> val.Referrers() is defined. - - if refs := val.Referrers(); refs != nil { - for _, ref := range *refs { - if ref == instr { - continue operands - } - } - s.errorf("operand %d of %s (%s) does not refer to us", i, instr, val) - } else { - s.errorf("operand %d of %s (%s) has no referrers", i, instr, val) - } - } - } -} - -func (s *sanity) checkReferrerList(v Value) { - refs := v.Referrers() - if refs == nil { - s.errorf("%s has missing referrer list", v.Name()) - return - } - for i, ref := range *refs { - if _, ok := s.instrs[ref]; !ok { - if val, ok := ref.(Value); ok { - s.errorf("%s.Referrers()[%d] = %s = %s is not an instruction belonging to this function", v.Name(), i, val.Name(), val) - } else { - s.errorf("%s.Referrers()[%d] = %s is not an instruction belonging to this function", v.Name(), i, ref) - } - } - } -} - -func (s *sanity) checkFunction(fn *Function) bool { - // TODO(adonovan): check Function invariants: - // - check params match signature - // - check transient fields are nil - // - warn if any fn.Locals do not appear among block instructions. - s.fn = fn - if fn.Prog == nil { - s.errorf("nil Prog") - } - - var buf bytes.Buffer - _ = fn.String() // must not crash - _ = fn.RelString(fn.pkg()) // must not crash - WriteFunction(&buf, fn) // must not crash - - // All functions have a package, except delegates (which are - // shared across packages, or duplicated as weak symbols in a - // separate-compilation model), and error.Error. - if fn.Pkg == nil { - switch fn.Synthetic { - case SyntheticWrapper, SyntheticBound, SyntheticThunk, SyntheticGeneric: - default: - if !strings.HasSuffix(fn.name, "Error") { - s.errorf("nil Pkg") - } - } - } - if syn, src := fn.Synthetic == 0, fn.source != nil; src != syn { - if _, ok := fn.source.(*ast.RangeStmt); !ok || fn.Synthetic != SyntheticRangeOverFuncYield { - // Only range-over-func yield functions are synthetic and have syntax - s.errorf("got fromSource=%t, hasSyntax=%t; want same values", src, syn) - } - } - for i, l := range fn.Locals { - if l.Parent() != fn { - s.errorf("Local %s at index %d has wrong parent", l.Name(), i) - } - if l.Heap { - s.errorf("Local %s at index %d has Heap flag set", l.Name(), i) - } - } - // Build the set of valid referrers. - s.instrs = make(map[Instruction]struct{}) - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - s.instrs[instr] = struct{}{} - } - } - for i, p := range fn.Params { - if p.Parent() != fn { - s.errorf("Param %s at index %d has wrong parent", p.Name(), i) - } - // Check common suffix of Signature and Params match type. - if sig := fn.Signature; sig != nil { - j := i - len(fn.Params) + sig.Params().Len() // index within sig.Params - if j < 0 { - continue - } - if !types.Identical(p.Type(), sig.Params().At(j).Type()) { - s.errorf("Param %s at index %d has wrong type (%s, versus %s in Signature)", p.Name(), i, p.Type(), sig.Params().At(j).Type()) - - } - } - - s.checkReferrerList(p) - } - for i, fv := range fn.FreeVars { - if fv.Parent() != fn { - s.errorf("FreeVar %s at index %d has wrong parent", fv.Name(), i) - } - s.checkReferrerList(fv) - } - - if fn.Blocks != nil && len(fn.Blocks) == 0 { - // Function _had_ blocks (so it's not external) but - // they were "optimized" away, even the entry block. - s.errorf("Blocks slice is non-nil but empty") - } - for i, b := range fn.Blocks { - if b == nil { - s.warnf("nil *BasicBlock at f.Blocks[%d]", i) - continue - } - s.checkBlock(b, i) - } - - s.block = nil - for i, anon := range fn.AnonFuncs { - if anon.Parent() != fn { - s.errorf("AnonFuncs[%d]=%s but %s.Parent()=%s", i, anon, anon, anon.Parent()) - } - } - s.fn = nil - return !s.insane -} - -// sanityCheckPackage checks invariants of packages upon creation. -// It does not require that the package is built. -// Unlike sanityCheck (for functions), it just panics at the first error. -func sanityCheckPackage(pkg *Package) { - if pkg.Pkg == nil { - panic(fmt.Sprintf("Package %s has no Object", pkg)) - } - _ = pkg.String() // must not crash - - for name, mem := range pkg.Members { - if name != mem.Name() { - panic(fmt.Sprintf("%s: %T.Name() = %s, want %s", - pkg.Pkg.Path(), mem, mem.Name(), name)) - } - obj := mem.Object() - if obj == nil { - // This check is sound because fields - // {Global,Function}.object have type - // types.Object. (If they were declared as - // *types.{Var,Func}, we'd have a non-empty - // interface containing a nil pointer.) - - continue // not all members have typechecker objects - } - if obj.Name() != name { - if obj.Name() == "init" && strings.HasPrefix(mem.Name(), "init#") { - // Ok. The name of a declared init function varies between - // its types.Func ("init") and its ir.Function ("init#%d"). - } else { - panic(fmt.Sprintf("%s: %T.Object().Name() = %s, want %s", - pkg.Pkg.Path(), mem, obj.Name(), name)) - } - } - } -} diff --git a/vendor/honnef.co/go/tools/go/ir/source.go b/vendor/honnef.co/go/tools/go/ir/source.go deleted file mode 100644 index 5e3ac28b8..000000000 --- a/vendor/honnef.co/go/tools/go/ir/source.go +++ /dev/null @@ -1,263 +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. - -package ir - -// This file defines utilities for working with source positions -// or source-level named entities ("objects"). - -// TODO(adonovan): test that {Value,Instruction}.Pos() positions match -// the originating syntax, as specified. - -import ( - "go/ast" - "go/token" - "go/types" -) - -// EnclosingFunction returns the function that contains the syntax -// node denoted by path. -// -// Syntax associated with package-level variable specifications is -// enclosed by the package's init() function. -// -// Returns nil if not found; reasons might include: -// - the node is not enclosed by any function. -// - the node is within an anonymous function (FuncLit) and -// its IR function has not been created yet -// (pkg.Build() has not yet been called). -func EnclosingFunction(pkg *Package, path []ast.Node) *Function { - // Start with package-level function... - fn := findEnclosingPackageLevelFunction(pkg, path) - if fn == nil { - return nil // not in any function - } - - // ...then walk down the nested anonymous functions. - n := len(path) -outer: - for i := range path { - if lit, ok := path[n-1-i].(*ast.FuncLit); ok { - for _, anon := range fn.AnonFuncs { - if anon.Pos() == lit.Type.Func { - fn = anon - continue outer - } - } - // IR function not found: - // - package not yet built, or maybe - // - builder skipped FuncLit in dead block - // (in principle; but currently the Builder - // generates even dead FuncLits). - return nil - } - } - return fn -} - -// HasEnclosingFunction returns true if the AST node denoted by path -// is contained within the declaration of some function or -// package-level variable. -// -// Unlike EnclosingFunction, the behaviour of this function does not -// depend on whether IR code for pkg has been built, so it can be -// used to quickly reject check inputs that will cause -// EnclosingFunction to fail, prior to IR building. -func HasEnclosingFunction(pkg *Package, path []ast.Node) bool { - return findEnclosingPackageLevelFunction(pkg, path) != nil -} - -// findEnclosingPackageLevelFunction returns the Function -// corresponding to the package-level function enclosing path. -func findEnclosingPackageLevelFunction(pkg *Package, path []ast.Node) *Function { - if n := len(path); n >= 2 { // [... {Gen,Func}Decl File] - switch decl := path[n-2].(type) { - case *ast.GenDecl: - if decl.Tok == token.VAR && n >= 3 { - // Package-level 'var' initializer. - return pkg.init - } - - case *ast.FuncDecl: - // Declared function/method. - fn := findNamedFunc(pkg, decl.Pos()) - if fn == nil && decl.Recv == nil && decl.Name.Name == "init" { - // Hack: return non-nil when IR is not yet - // built so that HasEnclosingFunction works. - return pkg.init - } - return fn - } - } - return nil // not in any function -} - -// findNamedFunc returns the named function whose FuncDecl.Ident is at -// position pos. -func findNamedFunc(pkg *Package, pos token.Pos) *Function { - for _, fn := range pkg.Functions { - if fn.Pos() == pos { - return fn - } - } - return nil -} - -// ValueForExpr returns the IR Value that corresponds to non-constant -// expression e. -// -// It returns nil if no value was found, e.g. -// - the expression is not lexically contained within f; -// - f was not built with debug information; or -// - e is a constant expression. (For efficiency, no debug -// information is stored for constants. Use -// go/types.Info.Types[e].Value instead.) -// - e is a reference to nil or a built-in function. -// - the value was optimised away. -// -// If e is an addressable expression used in an lvalue context, -// value is the address denoted by e, and isAddr is true. -// -// The types of e (or &e, if isAddr) and the result are equal -// (modulo "untyped" bools resulting from comparisons). -// -// (Tip: to find the ir.Value given a source position, use -// astutil.PathEnclosingInterval to locate the ast.Node, then -// EnclosingFunction to locate the Function, then ValueForExpr to find -// the ir.Value.) -func (f *Function) ValueForExpr(e ast.Expr) (value Value, isAddr bool) { - if f.debugInfo() { // (opt) - e = unparen(e) - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - if ref, ok := instr.(*DebugRef); ok { - if ref.Expr == e { - return ref.X, ref.IsAddr - } - } - } - } - } - return -} - -// --- Lookup functions for source-level named entities (types.Objects) --- - -// Package returns the IR Package corresponding to the specified -// type-checker package object. -// It returns nil if no such IR package has been created. -func (prog *Program) Package(obj *types.Package) *Package { - return prog.packages[obj] -} - -// packageLevelValue returns the package-level value corresponding to -// the specified named object, which may be a package-level const -// (*Const), var (*Global) or func (*Function) of some package in -// prog. It returns nil if the object is not found. -func (prog *Program) packageLevelValue(obj types.Object) Value { - if pkg, ok := prog.packages[obj.Pkg()]; ok { - return pkg.values[obj] - } - return nil -} - -// FuncValue returns the concrete Function denoted by the source-level -// named function obj, or nil if obj denotes an interface method. -// -// TODO(adonovan): check the invariant that obj.Type() matches the -// result's Signature, both in the params/results and in the receiver. -func (prog *Program) FuncValue(obj *types.Func) *Function { - obj = obj.Origin() - fn, _ := prog.packageLevelValue(obj).(*Function) - return fn -} - -// ConstValue returns the IR Value denoted by the source-level named -// constant obj. -func (prog *Program) ConstValue(obj *types.Const) *Const { - // TODO(adonovan): opt: share (don't reallocate) - // Consts for const objects and constant ast.Exprs. - - // Universal constant? {true,false,nil} - if obj.Parent() == types.Universe { - return NewConst(obj.Val(), obj.Type(), nil) - } - // Package-level named constant? - if v := prog.packageLevelValue(obj); v != nil { - return v.(*Const) - } - return NewConst(obj.Val(), obj.Type(), nil) -} - -// VarValue returns the IR Value that corresponds to a specific -// identifier denoting the source-level named variable obj. -// -// VarValue returns nil if a local variable was not found, perhaps -// because its package was not built, the debug information was not -// requested during IR construction, or the value was optimized away. -// -// ref is the path to an ast.Ident (e.g. from PathEnclosingInterval), -// and that ident must resolve to obj. -// -// pkg is the package enclosing the reference. (A reference to a var -// always occurs within a function, so we need to know where to find it.) -// -// If the identifier is a field selector and its base expression is -// non-addressable, then VarValue returns the value of that field. -// For example: -// -// func f() struct {x int} -// f().x // VarValue(x) returns a *Field instruction of type int -// -// All other identifiers denote addressable locations (variables). -// For them, VarValue may return either the variable's address or its -// value, even when the expression is evaluated only for its value; the -// situation is reported by isAddr, the second component of the result. -// -// If !isAddr, the returned value is the one associated with the -// specific identifier. For example, -// -// var x int // VarValue(x) returns Const 0 here -// x = 1 // VarValue(x) returns Const 1 here -// -// It is not specified whether the value or the address is returned in -// any particular case, as it may depend upon optimizations performed -// during IR code generation, such as registerization, constant -// folding, avoidance of materialization of subexpressions, etc. -func (prog *Program) VarValue(obj *types.Var, pkg *Package, ref []ast.Node) (value Value, isAddr bool) { - // All references to a var are local to some function, possibly init. - fn := EnclosingFunction(pkg, ref) - if fn == nil { - return // e.g. def of struct field; IR not built? - } - - id := ref[0].(*ast.Ident) - - // Defining ident of a parameter? - if id.Pos() == obj.Pos() { - for _, param := range fn.Params { - if param.Object() == obj { - return param, false - } - } - } - - // Other ident? - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - if dr, ok := instr.(*DebugRef); ok { - if dr.Pos() == id.Pos() { - return dr.X, dr.IsAddr - } - } - } - } - - // Defining ident of package-level var? - if v := prog.packageLevelValue(obj); v != nil { - return v.(*Global), true - } - - return // e.g. debug info not requested, or var optimized away -} diff --git a/vendor/honnef.co/go/tools/go/ir/ssa.go b/vendor/honnef.co/go/tools/go/ir/ssa.go deleted file mode 100644 index 6061b6085..000000000 --- a/vendor/honnef.co/go/tools/go/ir/ssa.go +++ /dev/null @@ -1,2160 +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. - -package ir - -// This package defines a high-level intermediate representation for -// Go programs using static single-information (SSI) form. - -import ( - "fmt" - "go/ast" - "go/constant" - "go/token" - "go/types" - "math/big" - "sync" - - "honnef.co/go/tools/go/types/typeutil" -) - -const ( - // Replace CompositeValue with only constant values with AggregateConst. Currently disabled because it breaks field - // tracking in U1000. - doSimplifyConstantCompositeValues = false -) - -type ID int - -// A Program is a partial or complete Go program converted to IR form. -type Program struct { - Fset *token.FileSet // position information for the files of this Program - PrintFunc string // create ir.html for function specified in PrintFunc - imported map[string]*Package // all importable Packages, keyed by import path - packages map[*types.Package]*Package // all loaded Packages, keyed by object - mode BuilderMode // set of mode bits for IR construction - MethodSets typeutil.MethodSetCache // cache of type-checker's method-sets - - methodsMu sync.Mutex // guards the following maps: - methodSets typeutil.Map[*methodSet] // maps type to its concrete methodSet - runtimeTypes typeutil.Map[bool] // types for which rtypes are needed - canon typeutil.Map[types.Type] // type canonicalization map -} - -// A Package is a single analyzed Go package containing Members for -// all package-level functions, variables, constants and types it -// declares. These may be accessed directly via Members, or via the -// type-specific accessor methods Func, Type, Var and Const. -// -// Members also contains entries for "init" (the synthetic package -// initializer) and "init#%d", the nth declared init function, -// and unspecified other things too. -type Package struct { - Prog *Program // the owning program - Pkg *types.Package // the corresponding go/types.Package - Members map[string]Member // all package members keyed by name (incl. init and init#%d) - Functions []*Function // all functions, excluding anonymous ones - values map[types.Object]Value // package members (incl. types and methods), keyed by object - init *Function // Func("init"); the package's init function - debug bool // include full debug info in this package - printFunc string // which function to print in HTML form - - // The following fields are set transiently, then cleared - // after building. - buildOnce sync.Once // ensures package building occurs once - ninit int32 // number of init functions - info *types.Info // package type information - files []*ast.File // package ASTs - initVersion map[ast.Expr]string // goversion to use for each global var init expr -} - -// A Member is a member of a Go package, implemented by *NamedConst, -// *Global, *Function, or *Type; they are created by package-level -// const, var, func and type declarations respectively. -type Member interface { - Name() string // declared name of the package member - String() string // package-qualified name of the package member - RelString(*types.Package) string // like String, but relative refs are unqualified - Object() types.Object // typechecker's object for this member, if any - Type() types.Type // type of the package member - Token() token.Token // token.{VAR,FUNC,CONST,TYPE} - Package() *Package // the containing package -} - -// A Type is a Member of a Package representing a package-level named type. -type Type struct { - object *types.TypeName - pkg *Package -} - -// A NamedConst is a Member of a Package representing a package-level -// named constant. -// -// Pos() returns the position of the declaring ast.ValueSpec.Names[*] -// identifier. -// -// NB: a NamedConst is not a Value; it contains a constant Value, which -// it augments with the name and position of its 'const' declaration. -type NamedConst struct { - object *types.Const - Value *Const - pkg *Package -} - -// A Value is an IR value that can be referenced by an instruction. -type Value interface { - setID(ID) - - // Name returns the name of this value, and determines how - // this Value appears when used as an operand of an - // Instruction. - // - // This is the same as the source name for Parameters, - // Builtins, Functions, FreeVars, Globals. - // For constants, it is a representation of the constant's value - // and type. For all other Values this is the name of the - // virtual register defined by the instruction. - // - // The name of an IR Value is not semantically significant, - // and may not even be unique within a function. - Name() string - - // ID returns the ID of this value. IDs are unique within a single - // function and are densely numbered, but may contain gaps. - // Values and other Instructions share the same ID space. - // Globally, values are identified by their addresses. However, - // IDs exist to facilitate efficient storage of mappings between - // values and data when analysing functions. - // - // NB: IDs are allocated late in the IR construction process and - // are not available to early stages of said process. - ID() ID - - // If this value is an Instruction, String returns its - // disassembled form; otherwise it returns unspecified - // human-readable information about the Value, such as its - // kind, name and type. - String() string - - // Type returns the type of this value. Many instructions - // (e.g. IndexAddr) change their behaviour depending on the - // types of their operands. - Type() types.Type - - // Parent returns the function to which this Value belongs. - // It returns nil for named Functions, Builtin and Global. - Parent() *Function - - // Referrers returns the list of instructions that have this - // value as one of their operands; it may contain duplicates - // if an instruction has a repeated operand. - // - // Referrers actually returns a pointer through which the - // caller may perform mutations to the object's state. - // - // Referrers is currently only defined if Parent()!=nil, - // i.e. for the function-local values FreeVar, Parameter, - // Functions (iff anonymous) and all value-defining instructions. - // It returns nil for named Functions, Builtin and Global. - // - // Instruction.Operands contains the inverse of this relation. - Referrers() *[]Instruction - - Operands(rands []*Value) []*Value // nil for non-Instructions - - // Source returns the AST node responsible for creating this - // value. A single AST node may be responsible for more than one - // value, and not all values have an associated AST node. - // - // Do not use this method to find a Value given an ast.Expr; use - // ValueForExpr instead. - Source() ast.Node - - // Pos returns Source().Pos() if Source is not nil, else it - // returns token.NoPos. - Pos() token.Pos -} - -// An Instruction is an IR instruction that computes a new Value or -// has some effect. -// -// An Instruction that defines a value (e.g. BinOp) also implements -// the Value interface; an Instruction that only has an effect (e.g. Store) -// does not. -type Instruction interface { - setSource(ast.Node) - setID(ID) - - Comment() string - - // String returns the disassembled form of this value. - // - // Examples of Instructions that are Values: - // "BinOp {+} t1 t2" (BinOp) - // "Call len t1" (Call) - // Note that the name of the Value is not printed. - // - // Examples of Instructions that are not Values: - // "Return t1" (Return) - // "Store {int} t2 t1" (Store) - // - // (The separation of Value.Name() from Value.String() is useful - // for some analyses which distinguish the operation from the - // value it defines, e.g., 'y = local int' is both an allocation - // of memory 'local int' and a definition of a pointer y.) - String() string - - // ID returns the ID of this instruction. IDs are unique within a single - // function and are densely numbered, but may contain gaps. - // Globally, instructions are identified by their addresses. However, - // IDs exist to facilitate efficient storage of mappings between - // instructions and data when analysing functions. - // - // NB: IDs are allocated late in the IR construction process and - // are not available to early stages of said process. - ID() ID - - // Parent returns the function to which this instruction - // belongs. - Parent() *Function - - // Block returns the basic block to which this instruction - // belongs. - Block() *BasicBlock - - // setBlock sets the basic block to which this instruction belongs. - setBlock(*BasicBlock) - - // Operands returns the operands of this instruction: the - // set of Values it references. - // - // Specifically, it appends their addresses to rands, a - // user-provided slice, and returns the resulting slice, - // permitting avoidance of memory allocation. - // - // The operands are appended in undefined order, but the order - // is consistent for a given Instruction; the addresses are - // always non-nil but may point to a nil Value. Clients may - // store through the pointers, e.g. to effect a value - // renaming. - // - // Value.Referrers is a subset of the inverse of this - // relation. (Referrers are not tracked for all types of - // Values.) - Operands(rands []*Value) []*Value - - Referrers() *[]Instruction // nil for non-Values - - // Source returns the AST node responsible for creating this - // instruction. A single AST node may be responsible for more than - // one instruction, and not all instructions have an associated - // AST node. - Source() ast.Node - - // Pos returns Source().Pos() if Source is not nil, else it - // returns token.NoPos. - Pos() token.Pos -} - -// A Node is a node in the IR value graph. Every concrete type that -// implements Node is also either a Value, an Instruction, or both. -// -// Node contains the methods common to Value and Instruction, plus the -// Operands and Referrers methods generalized to return nil for -// non-Instructions and non-Values, respectively. -// -// Node is provided to simplify IR graph algorithms. Clients should -// use the more specific and informative Value or Instruction -// interfaces where appropriate. -type Node interface { - setID(ID) - - // Common methods: - ID() ID - String() string - Source() ast.Node - Pos() token.Pos - Parent() *Function - - // Partial methods: - Operands(rands []*Value) []*Value // nil for non-Instructions - Referrers() *[]Instruction // nil for non-Values -} - -type Synthetic int - -const ( - SyntheticLoadedFromExportData Synthetic = iota + 1 - SyntheticPackageInitializer - SyntheticThunk - SyntheticWrapper - SyntheticBound - SyntheticGeneric - SyntheticRangeOverFuncYield -) - -func (syn Synthetic) String() string { - switch syn { - case SyntheticLoadedFromExportData: - return "loaded from export data" - case SyntheticPackageInitializer: - return "package initializer" - case SyntheticThunk: - return "thunk" - case SyntheticWrapper: - return "wrapper" - case SyntheticBound: - return "bound" - case SyntheticGeneric: - return "generic" - case SyntheticRangeOverFuncYield: - return "range-over-func yield" - default: - return fmt.Sprintf("Synthetic(%d)", syn) - } -} - -// Function represents the parameters, results, and code of a function -// or method. -// -// If Blocks is nil, this indicates an external function for which no -// Go source code is available. In this case, FreeVars, Locals, and -// Params are nil too. Clients performing whole-program analysis must -// handle external functions specially. -// -// Blocks contains the function's control-flow graph (CFG). -// Blocks[0] is the function entry point; block order is not otherwise -// semantically significant, though it may affect the readability of -// the disassembly. -// To iterate over the blocks in dominance order, use DomPreorder(). -// -// A nested function (Parent()!=nil) that refers to one or more -// lexically enclosing local variables ("free variables") has FreeVars. -// Such functions cannot be called directly but require a -// value created by MakeClosure which, via its Bindings, supplies -// values for these parameters. -// -// If the function is a method (Signature.Recv() != nil) then the first -// element of Params is the receiver parameter. -// -// A Go package may declare many functions called "init". -// For each one, Object().Name() returns "init" but Name() returns -// "init#1", etc, in declaration order. -// -// Pos() returns the declaring ast.FuncLit.Type.Func or the position -// of the ast.FuncDecl.Name, if the function was explicit in the -// source. Synthetic wrappers, for which Synthetic != "", may share -// the same position as the function they wrap. -// Syntax.Pos() always returns the position of the declaring "func" token. -// -// When the operand of a range statement is an iterator function, -// the loop body is transformed into a synthetic anonymous function -// that is passed as the yield argument in a call to the iterator. -// In that case, Function.Source() is the ast.RangeStmt. -// -// Synthetic functions, for which Synthetic != "", are functions -// that do not appear in the source AST. These include: -// - method wrappers, -// - thunks, -// - bound functions, -// - empty functions built from loaded type information, -// - yield functions created from range-over-func loops, and -// - package init functions. -// -// Type() returns the function's Signature. -type Function struct { - node - - name string - object *types.Func // symbol for declared function (nil for FuncLit or synthetic init) - method *types.Selection // info about provenance of synthetic methods - Signature *types.Signature - generics instanceWrapperMap - - Synthetic Synthetic // provenance of synthetic function; 0 for true source functions - parent *Function // enclosing function if anon; nil if global - Pkg *Package // enclosing package; nil for shared funcs (wrappers and error.Error) - Prog *Program // enclosing program - - // These fields are populated only when the function body is built: - - Params []*Parameter // function parameters; for methods, includes receiver - FreeVars []*FreeVar // free variables whose values must be supplied by closure - Locals []*Alloc // frame-allocated variables of this function - Blocks []*BasicBlock // basic blocks of the function; nil => external - Exit *BasicBlock // The function's exit block - AnonFuncs []*Function // anonymous functions (from FuncLit, RangeStmt) directly beneath this one - referrers []Instruction // referring instructions (iff Parent() != nil) - NoReturn NoReturn // Calling this function will always terminate control flow. - - goversion string // Go version of syntax (NB: init is special) - - // uniq is not stored in functionBody because we need it after function building finishes - uniq int64 // source of unique ints within the source tree while building - - *functionBody -} - -type instanceWrapperMap struct { - h typeutil.Hasher - entries map[uint32][]struct { - key *types.TypeList - val *Function - } - len int -} - -func typeListIdentical(l1, l2 *types.TypeList) bool { - if l1.Len() != l2.Len() { - return false - } - for i := 0; i < l1.Len(); i++ { - t1 := l1.At(i) - t2 := l2.At(i) - if !types.Identical(t1, t2) { - return false - } - } - return true -} - -func (m *instanceWrapperMap) At(key *types.TypeList) *Function { - if m.entries == nil { - m.entries = make(map[uint32][]struct { - key *types.TypeList - val *Function - }) - m.h = typeutil.MakeHasher() - } - - var hash uint32 - for i := 0; i < key.Len(); i++ { - t := key.At(i) - hash += m.h.Hash(t) - } - - for _, e := range m.entries[hash] { - if typeListIdentical(e.key, key) { - return e.val - } - } - return nil -} - -func (m *instanceWrapperMap) Set(key *types.TypeList, val *Function) { - if m.entries == nil { - m.entries = make(map[uint32][]struct { - key *types.TypeList - val *Function - }) - m.h = typeutil.MakeHasher() - } - - var hash uint32 - for i := 0; i < key.Len(); i++ { - t := key.At(i) - hash += m.h.Hash(t) - } - for i, e := range m.entries[hash] { - if typeListIdentical(e.key, key) { - m.entries[hash][i].val = val - return - } - } - m.entries[hash] = append(m.entries[hash], struct { - key *types.TypeList - val *Function - }{key, val}) - m.len++ -} - -func (m *instanceWrapperMap) Len() int { - return m.len -} - -type NoReturn uint8 - -const ( - Returns NoReturn = iota - AlwaysExits - AlwaysUnwinds - NeverReturns -) - -type constValue struct { - c Constant - idx int -} - -type functionBody struct { - // The following fields are set transiently during building, - // then cleared. - currentBlock *BasicBlock // where to emit code - vars map[*types.Var]Value // addresses of local variables - results []*Alloc // result allocations of the current function - returnVars []*types.Var // variables for a return statement. Either results or for range-over-func a parent's results - targets *targets // linked stack of branch targets - lblocks map[*types.Label]*lblock // labelled blocks - jump *types.Var // synthetic variable for the yield state (non-nil => range-over-func) - deferstack *types.Var // synthetic variable holding enclosing ssa:deferstack() - sourceFn *Function // nearest enclosing source function - exits []*exit // exits of the function that need to be resolved - - consts map[constKey]constValue - aggregateConsts typeutil.Map[[]*AggregateConst] - - wr *HTMLWriter - fakeExits BlockSet - blocksets [5]BlockSet - hasDefer bool - - // a contiguous block of instructions that will be used by blocks, - // to avoid making multiple allocations. - scratchInstructions []Instruction -} - -// BasicBlock represents an IR basic block. -// -// The final element of Instrs is always an explicit transfer of -// control (If, Jump, Return, Panic, or Unreachable). -// -// A block may contain no Instructions only if it is unreachable, -// i.e., Preds is nil. Empty blocks are typically pruned. -// -// BasicBlocks and their Preds/Succs relation form a (possibly cyclic) -// graph independent of the IR Value graph: the control-flow graph or -// CFG. It is illegal for multiple edges to exist between the same -// pair of blocks. -// -// Each BasicBlock is also a node in the dominator tree of the CFG. -// The tree may be navigated using Idom()/Dominees() and queried using -// Dominates(). -// -// The order of Preds and Succs is significant (to Phi and If -// instructions, respectively). -type BasicBlock struct { - Index int // index of this block within Parent().Blocks - Comment string // optional label; no semantic significance - parent *Function // parent function - Instrs []Instruction // instructions in order - Preds, Succs []*BasicBlock // predecessors and successors - succs2 [2]*BasicBlock // initial space for Succs - dom domInfo // dominator tree info - pdom domInfo // post-dominator tree info - post int - gaps int // number of nil Instrs (transient) - rundefers int // number of rundefers (transient) -} - -// Pure values ---------------------------------------- - -// A FreeVar represents a free variable of the function to which it -// belongs. -// -// FreeVars are used to implement anonymous functions, whose free -// variables are lexically captured in a closure formed by -// MakeClosure. The value of such a free var is an Alloc or another -// FreeVar and is considered a potentially escaping heap address, with -// pointer type. -// -// FreeVars are also used to implement bound method closures. Such a -// free var represents the receiver value and may be of any type that -// has concrete methods. -// -// Pos() returns the position of the value that was captured, which -// belongs to an enclosing function. -type FreeVar struct { - node - - name string - typ types.Type - parent *Function - referrers []Instruction - - // Transiently needed during building. - outer Value // the Value captured from the enclosing context. -} - -// A Parameter represents an input parameter of a function. -type Parameter struct { - register - - name string - object *types.Var // non-nil -} - -// A Const represents the value of a constant expression. -// -// The underlying type of a constant may be any boolean, numeric, or -// string type. In addition, a Const may represent the nil value of -// any reference type---interface, map, channel, pointer, slice, or -// function---but not "untyped nil". -// -// All source-level constant expressions are represented by a Const -// of the same type and value. -// -// Value holds the exact value of the constant, independent of its -// Type(), using the same representation as package go/constant uses for -// constants, or nil for a typed nil value. -// -// Pos() returns token.NoPos. -// -// Example printed form: -// -// Const {42} -// Const {"test"} -// Const {(3 + 4i)} -type Const struct { - register - - Value constant.Value -} - -type AggregateConst struct { - register - - Values []Value -} - -type CompositeValue struct { - register - - // Bitmap records which elements were explicitly provided. For example, [4]byte{2: x} would have a bitmap of 0010. - Bitmap big.Int - // The number of bits set in Bitmap - NumSet int - // Dense list of values in the composite literal. Omitted elements are filled in with zero values. - Values []Value -} - -// TODO add the element's zero constant to ArrayConst -type ArrayConst struct { - register -} - -type GenericConst struct { - register -} - -type Constant interface { - Instruction - Value - aConstant() - RelString(*types.Package) string - equal(Constant) bool - setType(types.Type) -} - -func (*Const) aConstant() {} -func (*AggregateConst) aConstant() {} -func (*ArrayConst) aConstant() {} -func (*GenericConst) aConstant() {} - -// A Global is a named Value holding the address of a package-level -// variable. -// -// Pos() returns the position of the ast.ValueSpec.Names[*] -// identifier. -type Global struct { - node - - name string - object types.Object // a *types.Var; may be nil for synthetics e.g. init$guard - typ types.Type - - Pkg *Package -} - -// A Builtin represents a specific use of a built-in function, e.g. len. -// -// Builtins are immutable values. Builtins do not have addresses. -// Builtins can only appear in CallCommon.Func. -// -// Name() indicates the function: one of the built-in functions from the -// Go spec (excluding "make" and "new") or one of these ir-defined -// intrinsics: -// -// // wrapnilchk returns ptr if non-nil, panics otherwise. -// // (For use in indirection wrappers.) -// func ir:wrapnilchk(ptr *T, recvType, methodName string) *T -// -// // noreturnWasPanic returns true if the previously called -// // function panicked, false if it exited the process. -// func ir:noreturnWasPanic() bool -// -// Object() returns a *types.Builtin for built-ins defined by the spec, -// nil for others. -// -// Type() returns a *types.Signature representing the effective -// signature of the built-in for this call. -type Builtin struct { - node - - name string - sig *types.Signature -} - -// Value-defining instructions ---------------------------------------- - -// The Alloc instruction reserves space for a variable of the given type, -// zero-initializes it, and yields its address. -// -// Alloc values are always addresses, and have pointer types, so the -// type of the allocated variable is actually -// Type().Underlying().(*types.Pointer).Elem(). -// -// If Heap is false, Alloc zero-initializes the same local variable in -// the call frame and returns its address; in this case the Alloc must -// be present in Function.Locals. We call this a "local" alloc. -// -// If Heap is true, Alloc allocates a new zero-initialized variable -// each time the instruction is executed. We call this a "new" alloc. -// -// When Alloc is applied to a channel, map or slice type, it returns -// the address of an uninitialized (nil) reference of that kind; store -// the result of MakeSlice, MakeMap or MakeChan in that location to -// instantiate these types. -// -// Pos() returns the ast.CompositeLit.Lbrace for a composite literal, -// or the ast.CallExpr.Rparen for a call to new() or for a call that -// allocates a varargs slice. -// -// Example printed form: -// -// t1 = StackAlloc <*int> -// t2 = HeapAlloc <*int> (new) -type Alloc struct { - register - Heap bool - index int // dense numbering; for lifting -} - -var _ Instruction = (*Sigma)(nil) -var _ Value = (*Sigma)(nil) - -// The Sigma instruction represents an SSI σ-node, which splits values -// at branches in the control flow. -// -// Conceptually, σ-nodes exist at the end of blocks that branch and -// constitute parallel assignments to one value per destination block. -// However, such a representation would be awkward to work with, so -// instead we place σ-nodes at the beginning of branch targets. The -// From field denotes to which incoming edge the node applies. -// -// Within a block, all σ-nodes must appear before all non-σ nodes. -// -// Example printed form: -// -// t2 = Sigma [#0] t1 (x) -type Sigma struct { - register - From *BasicBlock - X Value - - live bool // used during lifting -} - -type CopyInfo uint64 - -const ( - CopyInfoUnspecified CopyInfo = 0 - CopyInfoNotNil CopyInfo = 1 << iota - CopyInfoNotZeroLength - CopyInfoNotNegative - CopyInfoSingleConcreteType - CopyInfoClosed -) - -type Copy struct { - register - X Value - Why Instruction - Info CopyInfo -} - -// The Phi instruction represents an SSA φ-node, which combines values -// that differ across incoming control-flow edges and yields a new -// value. Within a block, all φ-nodes must appear before all non-φ, non-σ -// nodes. -// -// Pos() returns the position of the && or || for short-circuit -// control-flow joins, or that of the *Alloc for φ-nodes inserted -// during SSA renaming. -// -// Example printed form: -// -// t3 = Phi 2:t1 4:t2 (x) -type Phi struct { - register - Edges []Value // Edges[i] is value for Block().Preds[i] - - live bool // used during lifting -} - -// The Call instruction represents a function or method call. -// -// The Call instruction yields the function result if there is exactly -// one. Otherwise it returns a tuple, the components of which are -// accessed via Extract. -// -// See CallCommon for generic function call documentation. -// -// Pos() returns the ast.CallExpr.Lparen, if explicit in the source. -// -// Example printed form: -// -// t3 = Call <()> println t1 t2 -// t4 = Call <()> foo$1 -// t6 = Invoke t5.String -type Call struct { - register - Call CallCommon -} - -// The BinOp instruction yields the result of binary operation X Op Y. -// -// Pos() returns the ast.BinaryExpr.OpPos, if explicit in the source. -// -// Example printed form: -// -// t3 = BinOp {+} t2 t1 -type BinOp struct { - register - // One of: - // ADD SUB MUL QUO REM + - * / % - // AND OR XOR SHL SHR AND_NOT & | ^ << >> &^ - // EQL NEQ LSS LEQ GTR GEQ == != < <= < >= - Op token.Token - X, Y Value -} - -// The UnOp instruction yields the result of Op X. -// XOR is bitwise complement. -// SUB is negation. -// NOT is logical negation. -// -// Example printed form: -// -// t2 = UnOp {^} t1 -type UnOp struct { - register - Op token.Token // One of: NOT SUB XOR ! - ^ - X Value -} - -// The Load instruction loads a value from a memory address. -// -// For implicit memory loads, Pos() returns the position of the -// most closely associated source-level construct; the details are not -// specified. -// -// Example printed form: -// -// t2 = Load t1 -type Load struct { - register - X Value -} - -// The ChangeType instruction applies to X a value-preserving type -// change to Type(). -// -// Type changes are permitted: -// - between a named type and its underlying type. -// - between two named types of the same underlying type. -// - between (possibly named) pointers to identical base types. -// - from a bidirectional channel to a read- or write-channel, -// optionally adding/removing a name. -// -// This operation cannot fail dynamically. -// -// Pos() returns the ast.CallExpr.Lparen, if the instruction arose -// from an explicit conversion in the source. -// -// Example printed form: -// -// t2 = ChangeType <*T> t1 -type ChangeType struct { - register - X Value -} - -// The Convert instruction yields the conversion of value X to type -// Type(). One or both of those types is basic (but possibly named). -// -// A conversion may change the value and representation of its operand. -// Conversions are permitted: -// - between real numeric types. -// - between complex numeric types. -// - between string and []byte or []rune. -// - between pointers and unsafe.Pointer. -// - between unsafe.Pointer and uintptr. -// - from (Unicode) integer to (UTF-8) string. -// -// A conversion may imply a type name change also. -// -// This operation cannot fail dynamically. -// -// Conversions of untyped string/number/bool constants to a specific -// representation are eliminated during IR construction. -// -// Pos() returns the ast.CallExpr.Lparen, if the instruction arose -// from an explicit conversion in the source. -// -// Example printed form: -// -// t2 = Convert <[]byte> t1 -type Convert struct { - register - X Value -} - -// The MultiConvert instruction yields the conversion of value X to type -// Type(). Either X.Type() or Type() must be a type parameter. Each -// type in the type set of X.Type() can be converted to each type in the -// type set of Type(). -// -// See the documentation for Convert, ChangeType, SliceToArray, and SliceToArrayPointer -// for the conversions that are permitted. -// -// This operation can fail dynamically (see SliceToArrayPointer). -// -// Example printed form: -// -// t1 = multiconvert D <- S (t0) [*[2]rune <- []rune | string <- []rune] -type MultiConvert struct { - register - X Value - from typeutil.TypeSet - to typeutil.TypeSet -} - -// ChangeInterface constructs a value of one interface type from a -// value of another interface type known to be assignable to it. -// This operation cannot fail. -// -// Pos() returns the ast.CallExpr.Lparen if the instruction arose from -// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the -// instruction arose from an explicit e.(T) operation; or token.NoPos -// otherwise. -// -// Example printed form: -// -// t2 = ChangeInterface t1 -type ChangeInterface struct { - register - X Value -} - -// The SliceToArrayPointer instruction yields the conversion of slice X to -// array pointer. -// -// Pos() returns the ast.CallExpr.Lparen, if the instruction arose -// from an explicit conversion in the source. -// -// Example printed form: -// -// t2 = SliceToArrayPointer <*[4]byte> t1 -type SliceToArrayPointer struct { - register - X Value -} - -// The SliceToArray instruction yields the conversion of slice X to -// array. -// -// Pos() returns the ast.CallExpr.Lparen, if the instruction arose -// from an explicit conversion in the source. -// -// Example printed form: -// -// t2 = SliceToArray <[4]byte> t1 -type SliceToArray struct { - register - X Value -} - -// MakeInterface constructs an instance of an interface type from a -// value of a concrete type. -// -// Use Program.MethodSets.MethodSet(X.Type()) to find the method-set -// of X, and Program.MethodValue(m) to find the implementation of a method. -// -// To construct the zero value of an interface type T, use: -// -// NewConst(constant.MakeNil(), T, pos) -// -// Pos() returns the ast.CallExpr.Lparen, if the instruction arose -// from an explicit conversion in the source. -// -// Example printed form: -// -// t2 = MakeInterface t1 -type MakeInterface struct { - register - X Value -} - -// The MakeClosure instruction yields a closure value whose code is -// Fn and whose free variables' values are supplied by Bindings. -// -// Type() returns a (possibly named) *types.Signature. -// -// Pos() returns the ast.FuncLit.Type.Func for a function literal -// closure or the ast.SelectorExpr.Sel for a bound method closure. -// -// Example printed form: -// -// t1 = MakeClosure foo$1 t1 t2 -// t5 = MakeClosure (T).foo$bound t4 -type MakeClosure struct { - register - Fn Value // always a *Function - Bindings []Value // values for each free variable in Fn.FreeVars -} - -// The MakeMap instruction creates a new hash-table-based map object -// and yields a value of kind map. -// -// Type() returns a (possibly named) *types.Map. -// -// Pos() returns the ast.CallExpr.Lparen, if created by make(map), or -// the ast.CompositeLit.Lbrack if created by a literal. -// -// Example printed form: -// -// t1 = MakeMap -// t2 = MakeMap t1 -type MakeMap struct { - register - Reserve Value // initial space reservation; nil => default -} - -// The MakeChan instruction creates a new channel object and yields a -// value of kind chan. -// -// Type() returns a (possibly named) *types.Chan. -// -// Pos() returns the ast.CallExpr.Lparen for the make(chan) that -// created it. -// -// Example printed form: -// -// t3 = MakeChan t1 -// t4 = MakeChan t2 -type MakeChan struct { - register - Size Value // int; size of buffer; zero => synchronous. -} - -// The MakeSlice instruction yields a slice of length Len backed by a -// newly allocated array of length Cap. -// -// Both Len and Cap must be non-nil Values of integer type. -// -// (Alloc(types.Array) followed by Slice will not suffice because -// Alloc can only create arrays of constant length.) -// -// Type() returns a (possibly named) *types.Slice. -// -// Pos() returns the ast.CallExpr.Lparen for the make([]T) that -// created it. -// -// Example printed form: -// -// t3 = MakeSlice <[]string> t1 t2 -// t4 = MakeSlice t1 t2 -type MakeSlice struct { - register - Len Value - Cap Value -} - -// The Slice instruction yields a slice of an existing string, slice -// or *array X between optional integer bounds Low and High. -// -// Dynamically, this instruction panics if X evaluates to a nil *array -// pointer. -// -// Type() returns string if the type of X was string, otherwise a -// *types.Slice with the same element type as X. -// -// Pos() returns the ast.SliceExpr.Lbrack if created by a x[:] slice -// operation, the ast.CompositeLit.Lbrace if created by a literal, or -// NoPos if not explicit in the source (e.g. a variadic argument slice). -// -// Example printed form: -// -// t4 = Slice <[]int> t3 t2 t1 -type Slice struct { - register - X Value // slice, string, or *array - Low, High, Max Value // each may be nil -} - -// The FieldAddr instruction yields the address of Field of *struct X. -// -// The field is identified by its index within the field list of the -// struct type of X. -// -// Dynamically, this instruction panics if X evaluates to a nil -// pointer. -// -// Type() returns a (possibly named) *types.Pointer. -// -// Pos() returns the position of the ast.SelectorExpr.Sel for the -// field, if explicit in the source. -// -// Example printed form: -// -// t2 = FieldAddr <*int> [0] (X) t1 -type FieldAddr struct { - register - X Value // *struct - Field int // field is X.Type().Underlying().(*types.Pointer).Elem().Underlying().(*types.Struct).Field(Field) -} - -// The Field instruction yields the Field of struct X. -// -// The field is identified by its index within the field list of the -// struct type of X; by using numeric indices we avoid ambiguity of -// package-local identifiers and permit compact representations. -// -// Pos() returns the position of the ast.SelectorExpr.Sel for the -// field, if explicit in the source. -// -// Example printed form: -// -// t2 = FieldAddr [0] (X) t1 -type Field struct { - register - X Value // struct - Field int // index into X.Type().(*types.Struct).Fields -} - -// The IndexAddr instruction yields the address of the element at -// index Index of collection X. Index is an integer expression. -// -// The elements of maps and strings are not addressable; use StringLookup, MapLookup or -// MapUpdate instead. -// -// Dynamically, this instruction panics if X evaluates to a nil *array -// pointer. -// -// Type() returns a (possibly named) *types.Pointer. -// -// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if -// explicit in the source. -// -// Example printed form: -// -// t3 = IndexAddr <*int> t2 t1 -type IndexAddr struct { - register - X Value // slice or *array, - Index Value // numeric index -} - -// The Index instruction yields element Index of array X. -// -// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if -// explicit in the source. -// -// Example printed form: -// -// t3 = Index t2 t1 -type Index struct { - register - X Value // array - Index Value // integer index -} - -// The MapLookup instruction yields element Index of collection X, a map. -// -// If CommaOk, the result is a 2-tuple of the value above and a -// boolean indicating the result of a map membership test for the key. -// The components of the tuple are accessed using Extract. -// -// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source. -// -// Example printed form: -// -// t4 = MapLookup t3 t1 -// t6 = MapLookup <(string, bool)> t3 t2 -type MapLookup struct { - register - X Value // map - Index Value // key-typed index - CommaOk bool // return a value,ok pair -} - -// The StringLookup instruction yields element Index of collection X, a string. -// Index is an integer expression. -// -// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source. -// -// Example printed form: -// -// t3 = StringLookup t2 t1 -type StringLookup struct { - register - X Value // string - Index Value // numeric index -} - -// SelectState is a helper for Select. -// It represents one goal state and its corresponding communication. -type SelectState struct { - Dir types.ChanDir // direction of case (SendOnly or RecvOnly) - Chan Value // channel to use (for send or receive) - Send Value // value to send (for send) - Pos token.Pos // position of token.ARROW - DebugNode ast.Node // ast.SendStmt or ast.UnaryExpr(<-) [debug mode] -} - -// The Select instruction tests whether (or blocks until) one -// of the specified sent or received states is entered. -// -// Let n be the number of States for which Dir==RECV and Tᵢ (0 ≤ i < n) -// be the element type of each such state's Chan. -// Select returns an n+2-tuple -// -// (index int, recvOk bool, r₀ T₀, ... rₙ-1 Tₙ-1) -// -// The tuple's components, described below, must be accessed via the -// Extract instruction. -// -// If Blocking, select waits until exactly one state holds, i.e. a -// channel becomes ready for the designated operation of sending or -// receiving; select chooses one among the ready states -// pseudorandomly, performs the send or receive operation, and sets -// 'index' to the index of the chosen channel. -// -// If !Blocking, select doesn't block if no states hold; instead it -// returns immediately with index equal to -1. -// -// If the chosen channel was used for a receive, the rᵢ component is -// set to the received value, where i is the index of that state among -// all n receive states; otherwise rᵢ has the zero value of type Tᵢ. -// Note that the receive index i is not the same as the state -// index index. -// -// The second component of the triple, recvOk, is a boolean whose value -// is true iff the selected operation was a receive and the receive -// successfully yielded a value. -// -// Pos() returns the ast.SelectStmt.Select. -// -// Example printed form: -// -// t6 = SelectNonBlocking <(index int, ok bool, int)> [<-t4, t5<-t1] -// t11 = SelectBlocking <(index int, ok bool)> [] -type Select struct { - register - States []*SelectState - Blocking bool -} - -// The Range instruction yields an iterator over the domain and range -// of X, which must be a string or map. -// -// Elements are accessed via Next. -// -// Type() returns an opaque and degenerate "rangeIter" type. -// -// Pos() returns the ast.RangeStmt.For. -// -// Example printed form: -// -// t2 = Range t1 -type Range struct { - register - X Value // string or map -} - -// The Next instruction reads and advances the (map or string) -// iterator Iter and returns a 3-tuple value (ok, k, v). If the -// iterator is not exhausted, ok is true and k and v are the next -// elements of the domain and range, respectively. Otherwise ok is -// false and k and v are undefined. -// -// Components of the tuple are accessed using Extract. -// -// The IsString field distinguishes iterators over strings from those -// over maps, as the Type() alone is insufficient: consider -// map[int]rune. -// -// Type() returns a *types.Tuple for the triple (ok, k, v). -// The types of k and/or v may be types.Invalid. -// -// Example printed form: -// -// t5 = Next <(ok bool, k int, v rune)> t2 -// t5 = Next <(ok bool, k invalid type, v invalid type)> t2 -type Next struct { - register - Iter Value - IsString bool // true => string iterator; false => map iterator. -} - -// The TypeAssert instruction tests whether interface value X has type -// AssertedType. -// -// If !CommaOk, on success it returns v, the result of the conversion -// (defined below); on failure it panics. -// -// If CommaOk: on success it returns a pair (v, true) where v is the -// result of the conversion; on failure it returns (z, false) where z -// is AssertedType's zero value. The components of the pair must be -// accessed using the Extract instruction. -// -// If AssertedType is a concrete type, TypeAssert checks whether the -// dynamic type in interface X is equal to it, and if so, the result -// of the conversion is a copy of the value in the interface. -// -// If AssertedType is an interface, TypeAssert checks whether the -// dynamic type of the interface is assignable to it, and if so, the -// result of the conversion is a copy of the interface value X. -// If AssertedType is a superinterface of X.Type(), the operation will -// fail iff the operand is nil. (Contrast with ChangeInterface, which -// performs no nil-check.) -// -// Type() reflects the actual type of the result, possibly a -// 2-types.Tuple; AssertedType is the asserted type. -// -// Pos() returns the ast.CallExpr.Lparen if the instruction arose from -// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the -// instruction arose from an explicit e.(T) operation; or the -// ast.CaseClause.Case if the instruction arose from a case of a -// type-switch statement. -// -// Example printed form: -// -// t2 = TypeAssert t1 -// t4 = TypeAssert <(value fmt.Stringer, ok bool)> t1 -type TypeAssert struct { - register - X Value - AssertedType types.Type - CommaOk bool -} - -// The Extract instruction yields component Index of Tuple. -// -// This is used to access the results of instructions with multiple -// return values, such as Call, TypeAssert, Next, Recv, -// MapLookup and others. -// -// Example printed form: -// -// t7 = Extract [1] (ok) t4 -type Extract struct { - register - Tuple Value - Index int -} - -// Instructions executed for effect. They do not yield a value. -------------------- - -// The Jump instruction transfers control to the sole successor of its -// owning block. -// -// A Jump must be the last instruction of its containing BasicBlock. -// -// Pos() returns NoPos. -// -// Example printed form: -// -// Jump → b1 -type Jump struct { - anInstruction -} - -// The Unreachable pseudo-instruction signals that execution cannot -// continue after the preceding function call because it terminates -// the process. -// -// The instruction acts as a control instruction, jumping to the exit -// block. However, this jump will never execute. -// -// An Unreachable instruction must be the last instruction of its -// containing BasicBlock. -// -// Example printed form: -// -// Unreachable → b1 -type Unreachable struct { - anInstruction -} - -// The If instruction transfers control to one of the two successors -// of its owning block, depending on the boolean Cond: the first if -// true, the second if false. -// -// An If instruction must be the last instruction of its containing -// BasicBlock. -// -// Pos() returns the *ast.IfStmt, if explicit in the source. -// -// Example printed form: -// -// If t2 → b1 b2 -type If struct { - anInstruction - Cond Value -} - -type ConstantSwitch struct { - anInstruction - Tag Value - // Constant branch conditions. A nil Value denotes the (implicit - // or explicit) default branch. - Conds []Value -} - -type TypeSwitch struct { - register - Tag Value - Conds []types.Type -} - -// The Return instruction returns values and control back to the calling -// function. -// -// len(Results) is always equal to the number of results in the -// function's signature. -// -// If len(Results) > 1, Return returns a tuple value with the specified -// components which the caller must access using Extract instructions. -// -// There is no instruction to return a ready-made tuple like those -// returned by a "value,ok"-mode TypeAssert, MapLookup or Recv or -// a tail-call to a function with multiple result parameters. -// -// Return must be the last instruction of its containing BasicBlock. -// Such a block has no successors. -// -// Pos() returns the ast.ReturnStmt.Return, if explicit in the source. -// -// Example printed form: -// -// Return -// Return t1 t2 -type Return struct { - anInstruction - Results []Value -} - -// The RunDefers instruction pops and invokes the entire stack of -// procedure calls pushed by Defer instructions in this function. -// -// It is legal to encounter multiple 'rundefers' instructions in a -// single control-flow path through a function; this is useful in -// the combined init() function, for example. -// -// Pos() returns NoPos. -// -// Example printed form: -// -// RunDefers -type RunDefers struct { - anInstruction -} - -// The Panic instruction initiates a panic with value X. -// -// A Panic instruction must be the last instruction of its containing -// BasicBlock, which must have one successor, the exit block. -// -// NB: 'go panic(x)' and 'defer panic(x)' do not use this instruction; -// they are treated as calls to a built-in function. -// -// Pos() returns the ast.CallExpr.Lparen if this panic was explicit -// in the source. -// -// Example printed form: -// -// Panic t1 -type Panic struct { - anInstruction - X Value // an interface{} -} - -// The Go instruction creates a new goroutine and calls the specified -// function within it. -// -// See CallCommon for generic function call documentation. -// -// Pos() returns the ast.GoStmt.Go. -// -// Example printed form: -// -// Go println t1 -// Go t3 -// GoInvoke t4.Bar t2 -type Go struct { - anInstruction - Call CallCommon -} - -// The Defer instruction pushes the specified call onto a stack of -// functions to be called by a RunDefers instruction or by a panic. -// -// If _DeferStack != nil, it indicates the defer list that the defer is -// added to. Defer list values come from the Builtin function -// ssa:deferstack. Calls to ssa:deferstack() produces the defer stack -// of the current function frame. _DeferStack allows for deferring into an -// alternative function stack than the current function. -// -// See CallCommon for generic function call documentation. -// -// Pos() returns the ast.DeferStmt.Defer. -// -// Example printed form: -// -// Defer println t1 -// Defer t3 -// DeferInvoke t4.Bar t2 -type Defer struct { - anInstruction - Call CallCommon - _DeferStack Value // stack (from ssa:deferstack() intrinsic) onto which this function is pushed - - // TODO: Exporting _DeferStack and possibly making _DeferStack != nil awaits proposal https://github.com/golang/go/issues/66601. -} - -// The Send instruction sends X on channel Chan. -// -// Pos() returns the ast.SendStmt.Arrow, if explicit in the source. -// -// Example printed form: -// -// Send t2 t1 -type Send struct { - anInstruction - Chan, X Value -} - -// The Recv instruction receives from channel Chan. -// -// If CommaOk, the result is a 2-tuple of the value above -// and a boolean indicating the success of the receive. The -// components of the tuple are accessed using Extract. -// -// Pos() returns the ast.UnaryExpr.OpPos, if explicit in the source. -// For receive operations implicit in ranging over a channel, -// Pos() returns the ast.RangeStmt.For. -// -// Example printed form: -// -// t2 = Recv t1 -// t3 = Recv <(int, bool)> t1 -type Recv struct { - register - Chan Value - CommaOk bool -} - -// The Store instruction stores Val at address Addr. -// Stores can be of arbitrary types. -// -// Pos() returns the position of the source-level construct most closely -// associated with the memory store operation. -// Since implicit memory stores are numerous and varied and depend upon -// implementation choices, the details are not specified. -// -// Example printed form: -// -// Store {int} t2 t1 -type Store struct { - anInstruction - Addr Value - Val Value -} - -// The BlankStore instruction is emitted for assignments to the blank -// identifier. -// -// BlankStore is a pseudo-instruction: it has no dynamic effect. -// -// Pos() returns NoPos. -// -// Example printed form: -// -// BlankStore t1 -type BlankStore struct { - anInstruction - Val Value -} - -// The MapUpdate instruction updates the association of Map[Key] to -// Value. -// -// Pos() returns the ast.KeyValueExpr.Colon or ast.IndexExpr.Lbrack, -// if explicit in the source. -// -// Example printed form: -// -// MapUpdate t3 t1 t2 -type MapUpdate struct { - anInstruction - Map Value - Key Value - Value Value -} - -// A DebugRef instruction maps a source-level expression Expr to the -// IR value X that represents the value (!IsAddr) or address (IsAddr) -// of that expression. -// -// DebugRef is a pseudo-instruction: it has no dynamic effect. -// -// Pos() returns Expr.Pos(), the start position of the source-level -// expression. This is not the same as the "designated" token as -// documented at Value.Pos(). e.g. CallExpr.Pos() does not return the -// position of the ("designated") Lparen token. -// -// DebugRefs are generated only for functions built with debugging -// enabled; see Package.SetDebugMode() and the GlobalDebug builder -// mode flag. -// -// DebugRefs are not emitted for ast.Idents referring to constants or -// predeclared identifiers, since they are trivial and numerous. -// Nor are they emitted for ast.ParenExprs. -// -// (By representing these as instructions, rather than out-of-band, -// consistency is maintained during transformation passes by the -// ordinary SSA renaming machinery.) -// -// Example printed form: -// -// ; *ast.CallExpr @ 102:9 is t5 -// ; var x float64 @ 109:72 is x -// ; address of *ast.CompositeLit @ 216:10 is t0 -type DebugRef struct { - anInstruction - Expr ast.Expr // the referring expression (never *ast.ParenExpr) - object types.Object // the identity of the source var/func - IsAddr bool // Expr is addressable and X is the address it denotes - X Value // the value or address of Expr -} - -// Embeddable mix-ins and helpers for common parts of other structs. ----------- - -// register is a mix-in embedded by all IR values that are also -// instructions, i.e. virtual registers, and provides a uniform -// implementation of most of the Value interface: Value.Name() is a -// numbered register (e.g. "t0"); the other methods are field accessors. -// -// Temporary names are automatically assigned to each register on -// completion of building a function in IR form. -type register struct { - anInstruction - typ types.Type // type of virtual register - referrers []Instruction -} - -type node struct { - source ast.Node - id ID -} - -func (n *node) setID(id ID) { n.id = id } -func (n node) ID() ID { return n.id } - -func (n *node) setSource(source ast.Node) { n.source = source } -func (n *node) Source() ast.Node { return n.source } - -func (n *node) Pos() token.Pos { - if n.source != nil { - return n.source.Pos() - } - return token.NoPos -} - -// anInstruction is a mix-in embedded by all Instructions. -// It provides the implementations of the Block and setBlock methods. -type anInstruction struct { - node - block *BasicBlock // the basic block of this instruction - comment string -} - -func (instr anInstruction) Comment() string { - return instr.comment -} - -// CallCommon is contained by Go, Defer and Call to hold the -// common parts of a function or method call. -// -// Each CallCommon exists in one of two modes, function call and -// interface method invocation, or "call" and "invoke" for short. -// -// 1. "call" mode: when Method is nil (!IsInvoke), a CallCommon -// represents an ordinary function call of the value in Value, -// which may be a *Builtin, a *Function or any other value of kind -// 'func'. -// -// Value may be one of: -// -// (a) a *Function, indicating a statically dispatched call -// to a package-level function, an anonymous function, or -// a method of a named type. -// (b) a *MakeClosure, indicating an immediately applied -// function literal with free variables. -// (c) a *Builtin, indicating a statically dispatched call -// to a built-in function. -// (d) any other value, indicating a dynamically dispatched -// function call. -// -// StaticCallee returns the identity of the callee in cases -// (a) and (b), nil otherwise. -// -// Args contains the arguments to the call. If Value is a method, -// Args[0] contains the receiver parameter. -// -// Example printed form: -// -// t3 = Call <()> println t1 t2 -// Go t3 -// Defer t3 -// -// 2. "invoke" mode: when Method is non-nil (IsInvoke), a CallCommon -// represents a dynamically dispatched call to an interface method. -// In this mode, Value is the interface value and Method is the -// interface's abstract method. Note: an abstract method may be -// shared by multiple interfaces due to embedding; Value.Type() -// provides the specific interface used for this call. -// -// Value is implicitly supplied to the concrete method implementation -// as the receiver parameter; in other words, Args[0] holds not the -// receiver but the first true argument. -// -// Example printed form: -// -// t6 = Invoke t5.String -// GoInvoke t4.Bar t2 -// DeferInvoke t4.Bar t2 -// -// For all calls to variadic functions (Signature().Variadic()), -// the last element of Args is a slice. -type CallCommon struct { - Value Value // receiver (invoke mode) or func value (call mode) - Method *types.Func // abstract method (invoke mode) - Args []Value // actual parameters (in static method call, includes receiver) - TypeArgs []types.Type - Results Value -} - -// IsInvoke returns true if this call has "invoke" (not "call") mode. -func (c *CallCommon) IsInvoke() bool { - return c.Method != nil -} - -// Signature returns the signature of the called function. -// -// For an "invoke"-mode call, the signature of the interface method is -// returned. -// -// In either "call" or "invoke" mode, if the callee is a method, its -// receiver is represented by sig.Recv, not sig.Params().At(0). -func (c *CallCommon) Signature() *types.Signature { - if c.Method != nil { - return c.Method.Type().(*types.Signature) - } - return typeutil.CoreType(c.Value.Type()).(*types.Signature) -} - -// StaticCallee returns the callee if this is a trivially static -// "call"-mode call to a function. -func (c *CallCommon) StaticCallee() *Function { - switch fn := c.Value.(type) { - case *Function: - return fn - case *MakeClosure: - return fn.Fn.(*Function) - } - return nil -} - -// Description returns a description of the mode of this call suitable -// for a user interface, e.g., "static method call". -func (c *CallCommon) Description() string { - switch fn := c.Value.(type) { - case *Builtin: - return "built-in function call" - case *MakeClosure: - return "static function closure call" - case *Function: - if fn.Signature.Recv() != nil { - return "static method call" - } - return "static function call" - } - if c.IsInvoke() { - return "dynamic method call" // ("invoke" mode) - } - return "dynamic function call" -} - -// The CallInstruction interface, implemented by *Go, *Defer and *Call, -// exposes the common parts of function-calling instructions, -// yet provides a way back to the Value defined by *Call alone. -type CallInstruction interface { - Instruction - Common() *CallCommon // returns the common parts of the call - Value() *Call -} - -func (s *Call) Common() *CallCommon { return &s.Call } -func (s *Defer) Common() *CallCommon { return &s.Call } -func (s *Go) Common() *CallCommon { return &s.Call } - -func (s *Call) Value() *Call { return s } -func (s *Defer) Value() *Call { return nil } -func (s *Go) Value() *Call { return nil } - -func (v *Builtin) Type() types.Type { return v.sig } -func (v *Builtin) Name() string { return v.name } -func (*Builtin) Referrers() *[]Instruction { return nil } -func (v *Builtin) Pos() token.Pos { return token.NoPos } -func (v *Builtin) Object() types.Object { return types.Universe.Lookup(v.name) } -func (v *Builtin) Parent() *Function { return nil } - -func (v *FreeVar) Type() types.Type { return v.typ } -func (v *FreeVar) Name() string { return v.name } -func (v *FreeVar) Referrers() *[]Instruction { return &v.referrers } -func (v *FreeVar) Parent() *Function { return v.parent } - -func (v *Global) Type() types.Type { return v.typ } -func (v *Global) Name() string { return v.name } -func (v *Global) Parent() *Function { return nil } -func (v *Global) Referrers() *[]Instruction { return nil } -func (v *Global) Token() token.Token { return token.VAR } -func (v *Global) Object() types.Object { return v.object } -func (v *Global) String() string { return v.RelString(nil) } -func (v *Global) Package() *Package { return v.Pkg } -func (v *Global) RelString(from *types.Package) string { return relString(v, from) } - -func (v *Function) Name() string { return v.name } -func (v *Function) Type() types.Type { return v.Signature } -func (v *Function) Token() token.Token { return token.FUNC } -func (v *Function) Object() types.Object { - if v.object != nil { - return types.Object(v.object) - } - return nil -} -func (v *Function) String() string { return v.RelString(nil) } -func (v *Function) Package() *Package { return v.Pkg } -func (v *Function) Parent() *Function { return v.parent } -func (v *Function) Referrers() *[]Instruction { - if v.parent != nil { - return &v.referrers - } - return nil -} - -func (v *Parameter) Object() types.Object { return v.object } - -func (v *Alloc) Type() types.Type { return v.typ } -func (v *Alloc) Referrers() *[]Instruction { return &v.referrers } - -func (v *register) Type() types.Type { return v.typ } -func (v *register) setType(typ types.Type) { v.typ = typ } -func (v *register) Name() string { return fmt.Sprintf("t%d", v.id) } -func (v *register) Referrers() *[]Instruction { return &v.referrers } - -func (v *anInstruction) Parent() *Function { return v.block.parent } -func (v *anInstruction) Block() *BasicBlock { return v.block } -func (v *anInstruction) setBlock(block *BasicBlock) { v.block = block } -func (v *anInstruction) Referrers() *[]Instruction { return nil } - -func (t *Type) Name() string { return t.object.Name() } -func (t *Type) Pos() token.Pos { return t.object.Pos() } -func (t *Type) Type() types.Type { return t.object.Type() } -func (t *Type) Token() token.Token { return token.TYPE } -func (t *Type) Object() types.Object { return t.object } -func (t *Type) String() string { return t.RelString(nil) } -func (t *Type) Package() *Package { return t.pkg } -func (t *Type) RelString(from *types.Package) string { return relString(t, from) } - -func (c *NamedConst) Name() string { return c.object.Name() } -func (c *NamedConst) Pos() token.Pos { return c.object.Pos() } -func (c *NamedConst) String() string { return c.RelString(nil) } -func (c *NamedConst) Type() types.Type { return c.object.Type() } -func (c *NamedConst) Token() token.Token { return token.CONST } -func (c *NamedConst) Object() types.Object { return c.object } -func (c *NamedConst) Package() *Package { return c.pkg } -func (c *NamedConst) RelString(from *types.Package) string { return relString(c, from) } - -// Func returns the package-level function of the specified name, -// or nil if not found. -func (p *Package) Func(name string) (f *Function) { - f, _ = p.Members[name].(*Function) - return -} - -// Var returns the package-level variable of the specified name, -// or nil if not found. -func (p *Package) Var(name string) (g *Global) { - g, _ = p.Members[name].(*Global) - return -} - -// Const returns the package-level constant of the specified name, -// or nil if not found. -func (p *Package) Const(name string) (c *NamedConst) { - c, _ = p.Members[name].(*NamedConst) - return -} - -// Type returns the package-level type of the specified name, -// or nil if not found. -func (p *Package) Type(name string) (t *Type) { - t, _ = p.Members[name].(*Type) - return -} - -func (s *DebugRef) Pos() token.Pos { return s.Expr.Pos() } - -// Operands. - -func (v *Alloc) Operands(rands []*Value) []*Value { - return rands -} - -func (v *BinOp) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Y) -} - -func (c *CallCommon) Operands(rands []*Value) []*Value { - rands = append(rands, &c.Value) - for i := range c.Args { - rands = append(rands, &c.Args[i]) - } - return rands -} - -func (s *Go) Operands(rands []*Value) []*Value { - return s.Call.Operands(rands) -} - -func (s *Call) Operands(rands []*Value) []*Value { - return s.Call.Operands(rands) -} - -func (s *Defer) Operands(rands []*Value) []*Value { - return append(s.Call.Operands(rands), &s._DeferStack) -} - -func (v *ChangeInterface) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *ChangeType) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *Convert) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *MultiConvert) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *SliceToArrayPointer) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *SliceToArray) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (s *DebugRef) Operands(rands []*Value) []*Value { - return append(rands, &s.X) -} - -func (s *Copy) Operands(rands []*Value) []*Value { - return append(rands, &s.X) -} - -func (v *Extract) Operands(rands []*Value) []*Value { - return append(rands, &v.Tuple) -} - -func (v *Field) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *FieldAddr) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (s *If) Operands(rands []*Value) []*Value { - return append(rands, &s.Cond) -} - -func (s *ConstantSwitch) Operands(rands []*Value) []*Value { - rands = append(rands, &s.Tag) - for i := range s.Conds { - rands = append(rands, &s.Conds[i]) - } - return rands -} - -func (s *TypeSwitch) Operands(rands []*Value) []*Value { - rands = append(rands, &s.Tag) - return rands -} - -func (v *Index) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (v *IndexAddr) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (*Jump) Operands(rands []*Value) []*Value { - return rands -} - -func (*Unreachable) Operands(rands []*Value) []*Value { - return rands -} - -func (v *MapLookup) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (v *StringLookup) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (v *MakeChan) Operands(rands []*Value) []*Value { - return append(rands, &v.Size) -} - -func (v *MakeClosure) Operands(rands []*Value) []*Value { - rands = append(rands, &v.Fn) - for i := range v.Bindings { - rands = append(rands, &v.Bindings[i]) - } - return rands -} - -func (v *MakeInterface) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *MakeMap) Operands(rands []*Value) []*Value { - return append(rands, &v.Reserve) -} - -func (v *MakeSlice) Operands(rands []*Value) []*Value { - return append(rands, &v.Len, &v.Cap) -} - -func (v *MapUpdate) Operands(rands []*Value) []*Value { - return append(rands, &v.Map, &v.Key, &v.Value) -} - -func (v *Next) Operands(rands []*Value) []*Value { - return append(rands, &v.Iter) -} - -func (s *Panic) Operands(rands []*Value) []*Value { - return append(rands, &s.X) -} - -func (v *Sigma) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *Phi) Operands(rands []*Value) []*Value { - for i := range v.Edges { - rands = append(rands, &v.Edges[i]) - } - return rands -} - -func (v *Range) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (s *Return) Operands(rands []*Value) []*Value { - for i := range s.Results { - rands = append(rands, &s.Results[i]) - } - return rands -} - -func (*RunDefers) Operands(rands []*Value) []*Value { - return rands -} - -func (v *Select) Operands(rands []*Value) []*Value { - for i := range v.States { - rands = append(rands, &v.States[i].Chan, &v.States[i].Send) - } - return rands -} - -func (s *Send) Operands(rands []*Value) []*Value { - return append(rands, &s.Chan, &s.X) -} - -func (recv *Recv) Operands(rands []*Value) []*Value { - return append(rands, &recv.Chan) -} - -func (v *Slice) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Low, &v.High, &v.Max) -} - -func (s *Store) Operands(rands []*Value) []*Value { - return append(rands, &s.Addr, &s.Val) -} - -func (s *BlankStore) Operands(rands []*Value) []*Value { - return append(rands, &s.Val) -} - -func (v *TypeAssert) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *UnOp) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *Load) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *AggregateConst) Operands(rands []*Value) []*Value { - for i := range v.Values { - rands = append(rands, &v.Values[i]) - } - return rands -} - -func (v *CompositeValue) Operands(rands []*Value) []*Value { - for i := range v.Values { - rands = append(rands, &v.Values[i]) - } - return rands -} - -// Non-Instruction Values: -func (v *Builtin) Operands(rands []*Value) []*Value { return rands } -func (v *FreeVar) Operands(rands []*Value) []*Value { return rands } -func (v *Const) Operands(rands []*Value) []*Value { return rands } -func (v *ArrayConst) Operands(rands []*Value) []*Value { return rands } -func (v *GenericConst) Operands(rands []*Value) []*Value { return rands } -func (v *Function) Operands(rands []*Value) []*Value { return rands } -func (v *Global) Operands(rands []*Value) []*Value { return rands } -func (v *Parameter) Operands(rands []*Value) []*Value { return rands } diff --git a/vendor/honnef.co/go/tools/go/ir/util.go b/vendor/honnef.co/go/tools/go/ir/util.go deleted file mode 100644 index 3a0e3ad92..000000000 --- a/vendor/honnef.co/go/tools/go/ir/util.go +++ /dev/null @@ -1,162 +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. - -package ir - -// This file defines a number of miscellaneous utility functions. - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "io" - "os" - - "honnef.co/go/tools/go/ast/astutil" - "honnef.co/go/tools/go/types/typeutil" - - "golang.org/x/exp/typeparams" -) - -//// AST utilities - -func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) } - -// isBlankIdent returns true iff e is an Ident with name "_". -// They have no associated types.Object, and thus no type. -func isBlankIdent(e ast.Expr) bool { - id, ok := e.(*ast.Ident) - return ok && id.Name == "_" -} - -//// Type utilities. Some of these belong in go/types. - -// isPointer returns true for types whose underlying type is a pointer, -// and for type parameters whose core type is a pointer. -func isPointer(typ types.Type) bool { - if ctyp := typeutil.CoreType(typ); ctyp != nil { - _, ok := ctyp.(*types.Pointer) - return ok - } - _, ok := typ.Underlying().(*types.Pointer) - return ok -} - -// deref returns a pointer's element type; otherwise it returns typ. -func deref(typ types.Type) types.Type { - orig := typ - typ = types.Unalias(typ) - - if t, ok := typ.(*types.TypeParam); ok { - if ctyp := typeutil.CoreType(t); ctyp != nil { - // This can happen, for example, with len(T) where T is a - // type parameter whose core type is a pointer to array. - typ = ctyp - } - } - if p, ok := typ.Underlying().(*types.Pointer); ok { - return p.Elem() - } - return orig -} - -// recvType returns the receiver type of method obj. -func recvType(obj *types.Func) types.Type { - return obj.Type().(*types.Signature).Recv().Type() -} - -// logStack prints the formatted "start" message to stderr and -// returns a closure that prints the corresponding "end" message. -// Call using 'defer logStack(...)()' to show builder stack on panic. -// Don't forget trailing parens! -func logStack(format string, args ...interface{}) func() { - msg := fmt.Sprintf(format, args...) - io.WriteString(os.Stderr, msg) - io.WriteString(os.Stderr, "\n") - return func() { - io.WriteString(os.Stderr, msg) - io.WriteString(os.Stderr, " end\n") - } -} - -// newVar creates a 'var' for use in a types.Tuple. -func newVar(name string, typ types.Type) *types.Var { - return types.NewParam(token.NoPos, nil, name, typ) -} - -// anonVar creates an anonymous 'var' for use in a types.Tuple. -func anonVar(typ types.Type) *types.Var { - return newVar("", typ) -} - -var lenResults = types.NewTuple(anonVar(tInt)) - -// makeLen returns the len builtin specialized to type func(T)int. -func makeLen(T types.Type) *Builtin { - lenParams := types.NewTuple(anonVar(T)) - return &Builtin{ - name: "len", - sig: types.NewSignatureType(nil, nil, nil, lenParams, lenResults, false), - } -} - -type StackMap struct { - m []map[Value]Value -} - -func (m *StackMap) Push() { - m.m = append(m.m, map[Value]Value{}) -} - -func (m *StackMap) Pop() { - m.m = m.m[:len(m.m)-1] -} - -func (m *StackMap) Get(key Value) (Value, bool) { - for i := len(m.m) - 1; i >= 0; i-- { - if v, ok := m.m[i][key]; ok { - return v, true - } - } - return nil, false -} - -func (m *StackMap) Set(k Value, v Value) { - m.m[len(m.m)-1][k] = v -} - -// Unwrap recursively unwraps Sigma and Copy nodes. -func Unwrap(v Value) Value { - for { - switch vv := v.(type) { - case *Sigma: - v = vv.X - case *Copy: - v = vv.X - default: - return v - } - } -} - -func assert(x bool) { - if !x { - panic("failed assertion") - } -} - -// BlockMap is a mapping from basic blocks (identified by their indices) to values. -type BlockMap[T any] []T - -// isBasic reports whether t is a basic type. -func isBasic(t types.Type) bool { - _, ok := t.(*types.Basic) - return ok -} - -// isNonTypeParamInterface reports whether t is an interface type but not a type parameter. -func isNonTypeParamInterface(t types.Type) bool { - return !typeparams.IsTypeParam(t) && types.IsInterface(t) -} diff --git a/vendor/honnef.co/go/tools/go/ir/wrappers.go b/vendor/honnef.co/go/tools/go/ir/wrappers.go deleted file mode 100644 index d5afb2cda..000000000 --- a/vendor/honnef.co/go/tools/go/ir/wrappers.go +++ /dev/null @@ -1,343 +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. - -package ir - -// This file defines synthesis of Functions that delegate to declared -// methods; they come in three kinds: -// -// (1) wrappers: methods that wrap declared methods, performing -// implicit pointer indirections and embedded field selections. -// -// (2) thunks: funcs that wrap declared methods. Like wrappers, -// thunks perform indirections and field selections. The thunk's -// first parameter is used as the receiver for the method call. -// -// (3) bounds: funcs that wrap declared methods. The bound's sole -// free variable, supplied by a closure, is used as the receiver -// for the method call. No indirections or field selections are -// performed since they can be done before the call. - -import ( - "fmt" - "go/types" -) - -// -- wrappers ----------------------------------------------------------- - -// makeWrapper returns a synthetic method that delegates to the -// declared method denoted by meth.Obj(), first performing any -// necessary pointer indirections or field selections implied by meth. -// -// The resulting method's receiver type is meth.Recv(). -// -// This function is versatile but quite subtle! Consider the -// following axes of variation when making changes: -// - optional receiver indirection -// - optional implicit field selections -// - meth.Obj() may denote a concrete or an interface method -// - the result may be a thunk or a wrapper. -// -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -func makeWrapper(prog *Program, sel *types.Selection) *Function { - obj := sel.Obj().(*types.Func) // the declared function - sig := sel.Type().(*types.Signature) // type of this wrapper - - var recv *types.Var // wrapper's receiver or thunk's params[0] - name := obj.Name() - var description Synthetic - var start int // first regular param - if sel.Kind() == types.MethodExpr { - name += "$thunk" - description = SyntheticThunk - recv = sig.Params().At(0) - start = 1 - } else { - description = SyntheticWrapper - recv = sig.Recv() - } - - if prog.mode&LogSource != 0 { - defer logStack("make %s to (%s)", description, recv.Type())() - } - fn := &Function{ - name: name, - method: sel, - object: obj, - Signature: sig, - Synthetic: description, - Prog: prog, - functionBody: new(functionBody), - } - fn.initHTML(prog.PrintFunc) - fn.startBody() - fn.addSpilledParam(recv, nil) - createParams(fn, start) - - indices := sel.Index() - - var v Value = fn.Locals[0] // spilled receiver - if isPointer(sel.Recv()) { - v = emitLoad(fn, v, nil) - - // For simple indirection wrappers, perform an informative nil-check: - // "value method (T).f called using nil *T pointer" - if len(indices) == 1 && !isPointer(recvType(obj)) { - var c Call - c.Call.Value = &Builtin{ - name: "ir:wrapnilchk", - sig: types.NewSignatureType(nil, nil, nil, - types.NewTuple(anonVar(sel.Recv()), anonVar(tString), anonVar(tString)), - types.NewTuple(anonVar(sel.Recv())), false), - } - c.Call.Args = []Value{ - v, - emitConst(fn, stringConst(deref(sel.Recv()).String(), nil)), - emitConst(fn, stringConst(sel.Obj().Name(), nil)), - } - c.setType(v.Type()) - v = fn.emit(&c, nil) - } - } - - // Invariant: v is a pointer, either - // value of *A receiver param, or - // address of A spilled receiver. - - // We use pointer arithmetic (FieldAddr possibly followed by - // Load) in preference to value extraction (Field possibly - // preceded by Load). - - v = emitImplicitSelections(fn, v, indices[:len(indices)-1], nil) - - // Invariant: v is a pointer, either - // value of implicit *C field, or - // address of implicit C field. - - var c Call - if r := recvType(obj); !types.IsInterface(r) { // concrete method - if !isPointer(r) { - v = emitLoad(fn, v, nil) - } - c.Call.Value = prog.declaredFunc(obj) - c.Call.Args = append(c.Call.Args, v) - } else { - c.Call.Method = obj - c.Call.Value = emitLoad(fn, v, nil) - } - for _, arg := range fn.Params[1:] { - c.Call.Args = append(c.Call.Args, arg) - } - emitTailCall(fn, &c, nil) - fn.finishBody() - return fn -} - -// createParams creates parameters for wrapper method fn based on its -// Signature.Params, which do not include the receiver. -// start is the index of the first regular parameter to use. -func createParams(fn *Function, start int) { - tparams := fn.Signature.Params() - for i, n := start, tparams.Len(); i < n; i++ { - fn.addParamVar(tparams.At(i), nil) - } -} - -// -- bounds ----------------------------------------------------------- - -// makeBound returns a bound method wrapper (or "bound"), a synthetic -// function that delegates to a concrete or interface method denoted -// by obj. The resulting function has no receiver, but has one free -// variable which will be used as the method's receiver in the -// tail-call. -// -// Use MakeClosure with such a wrapper to construct a bound method -// closure. e.g.: -// -// type T int or: type T interface { meth() } -// func (t T) meth() -// var t T -// f := t.meth -// f() // calls t.meth() -// -// f is a closure of a synthetic wrapper defined as if by: -// -// f := func() { return t.meth() } -// -// Unlike makeWrapper, makeBound need perform no indirection or field -// selections because that can be done before the closure is -// constructed. -// -// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu) -func makeBound(prog *Program, obj *types.Func) *Function { - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - if prog.mode&LogSource != 0 { - defer logStack("%s", SyntheticBound)() - } - fn := &Function{ - name: obj.Name() + "$bound", - object: obj, - Signature: changeRecv(obj.Type().(*types.Signature), nil), // drop receiver - Synthetic: SyntheticBound, - Prog: prog, - functionBody: new(functionBody), - } - fn.initHTML(prog.PrintFunc) - - fv := &FreeVar{name: "recv", typ: recvType(obj), parent: fn} - fn.FreeVars = []*FreeVar{fv} - fn.startBody() - createParams(fn, 0) - var c Call - - if !types.IsInterface(recvType(obj)) { // concrete - c.Call.Value = prog.declaredFunc(obj) - c.Call.Args = []Value{fv} - } else { - c.Call.Value = fv - c.Call.Method = obj - } - for _, arg := range fn.Params { - c.Call.Args = append(c.Call.Args, arg) - } - emitTailCall(fn, &c, nil) - fn.finishBody() - return fn -} - -// -- thunks ----------------------------------------------------------- - -// makeThunk returns a thunk, a synthetic function that delegates to a -// concrete or interface method denoted by sel.Obj(). The resulting -// function has no receiver, but has an additional (first) regular -// parameter. -// -// Precondition: sel.Kind() == types.MethodExpr. -// -// type T int or: type T interface { meth() } -// func (t T) meth() -// f := T.meth -// var t T -// f(t) // calls t.meth() -// -// f is a synthetic wrapper defined as if by: -// -// f := func(t T) { return t.meth() } -// -// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu) -func makeThunk(prog *Program, sel *types.Selection) *Function { - if sel.Kind() != types.MethodExpr { - panic(sel) - } - - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - - fn := makeWrapper(prog, sel) - if fn.Signature.Recv() != nil { - panic(fn) // unexpected receiver - } - return fn -} - -func changeRecv(s *types.Signature, recv *types.Var) *types.Signature { - return types.NewSignatureType(recv, nil, nil, s.Params(), s.Results(), s.Variadic()) -} - -// makeInstance creates a wrapper function with signature sig that calls the generic function fn. -// If targs is not nil, fn is a function and targs describes the concrete type arguments. -// If targs is nil, fn is a method and the type arguments are derived from the receiver. -func makeInstance(prog *Program, fn *Function, sig *types.Signature, targs *types.TypeList) *Function { - if sig.Recv() != nil { - assert(targs == nil) - // Methods don't have their own type parameters, but the receiver does - targs = types.Unalias(deref(sig.Recv().Type())).(*types.Named).TypeArgs() - } else { - assert(targs != nil) - } - - wrapper := fn.generics.At(targs) - if wrapper != nil { - return wrapper - } - - var name string - if sig.Recv() != nil { - name = fn.name - } else { - name = fmt.Sprintf("%s$generic#%d", fn.name, fn.generics.Len()) - } - w := &Function{ - name: name, - object: fn.object, - Signature: sig, - Synthetic: SyntheticGeneric, - Prog: prog, - functionBody: new(functionBody), - } - w.initHTML(prog.PrintFunc) - w.startBody() - if sig.Recv() != nil { - w.addParamVar(sig.Recv(), nil) - } - createParams(w, 0) - var c Call - c.Call.Value = fn - tresults := fn.Signature.Results() - if tresults.Len() == 1 { - c.typ = tresults.At(0).Type() - } else { - c.typ = tresults - } - - changeType := func(v Value, typ types.Type) Value { - if types.Identical(v.Type(), typ) { - return v - } - var c ChangeType - c.X = v - c.typ = typ - return w.emit(&c, nil) - } - - for i, arg := range w.Params { - if sig.Recv() != nil { - if i == 0 { - c.Call.Args = append(c.Call.Args, changeType(w.Params[0], fn.Signature.Recv().Type())) - } else { - c.Call.Args = append(c.Call.Args, changeType(arg, fn.Signature.Params().At(i-1).Type())) - } - } else { - c.Call.Args = append(c.Call.Args, changeType(arg, fn.Signature.Params().At(i).Type())) - } - } - for i := 0; i < targs.Len(); i++ { - arg := targs.At(i) - c.Call.TypeArgs = append(c.Call.TypeArgs, arg) - } - results := w.emit(&c, nil) - var ret Return - switch tresults.Len() { - case 0: - case 1: - ret.Results = []Value{changeType(results, sig.Results().At(0).Type())} - default: - for i := 0; i < tresults.Len(); i++ { - v := emitExtract(w, results, i, nil) - ret.Results = append(ret.Results, changeType(v, sig.Results().At(i).Type())) - } - } - - w.Exit = w.newBasicBlock("exit") - emitJump(w, w.Exit, nil) - w.currentBlock = w.Exit - w.emit(&ret, nil) - w.currentBlock = nil - - w.finishBody() - - fn.generics.Set(targs, w) - return w -} diff --git a/vendor/honnef.co/go/tools/go/ir/write.go b/vendor/honnef.co/go/tools/go/ir/write.go deleted file mode 100644 index 139c8cf32..000000000 --- a/vendor/honnef.co/go/tools/go/ir/write.go +++ /dev/null @@ -1,5 +0,0 @@ -package ir - -func NewJump(parent *BasicBlock) *Jump { - return &Jump{anInstruction{block: parent}} -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/ext.go b/vendor/honnef.co/go/tools/go/types/typeutil/ext.go deleted file mode 100644 index 19b4ae5a7..000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/ext.go +++ /dev/null @@ -1,27 +0,0 @@ -package typeutil - -import ( - "fmt" - "go/types" -) - -type Iterator struct { - elem types.Type -} - -func (t *Iterator) Underlying() types.Type { return t } -func (t *Iterator) String() string { return fmt.Sprintf("iterator(%s)", t.elem) } -func (t *Iterator) Elem() types.Type { return t.elem } - -func NewIterator(elem types.Type) *Iterator { - return &Iterator{elem: elem} -} - -type DeferStack struct{} - -func (t *DeferStack) Underlying() types.Type { return t } -func (t *DeferStack) String() string { return "deferStack" } - -func NewDeferStack() *DeferStack { - return &DeferStack{} -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/typeparams.go b/vendor/honnef.co/go/tools/go/types/typeutil/typeparams.go deleted file mode 100644 index 2bf6ec609..000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/typeparams.go +++ /dev/null @@ -1,110 +0,0 @@ -package typeutil - -import ( - "errors" - "go/types" - - "golang.org/x/exp/typeparams" -) - -type TypeSet struct { - Terms []*types.Term - empty bool -} - -func NewTypeSet(typ types.Type) TypeSet { - terms, err := typeparams.NormalTerms(typ) - if err != nil { - if errors.Is(err, typeparams.ErrEmptyTypeSet) { - return TypeSet{nil, true} - } else { - // We couldn't determine the type set. Assume it's all types. - return TypeSet{nil, false} - } - } - return TypeSet{terms, false} -} - -// CoreType returns the type set's core type, or nil if it has none. -// The function only looks at type terms and may thus return core types for some empty type sets, such as -// 'interface { map[int]string; foo() }' -func (ts TypeSet) CoreType() types.Type { - if len(ts.Terms) == 0 { - // Either the type set is empty, or it isn't constrained. Either way it doesn't have a core type. - return nil - } - typ := ts.Terms[0].Type().Underlying() - for _, term := range ts.Terms[1:] { - ut := term.Type().Underlying() - if types.Identical(typ, ut) { - continue - } - - ch1, ok := typ.(*types.Chan) - if !ok { - return nil - } - ch2, ok := ut.(*types.Chan) - if !ok { - return nil - } - if ch1.Dir() == types.SendRecv { - // typ is currently a bidirectional channel. The term's type is either also bidirectional, or - // unidirectional. Use the term's type. - typ = ut - } else if ch2.Dir() == types.SendRecv { - // typ is currently a unidirectional channel and the term's type is bidirectional, which means it has no - // effect. - continue - } else if ch1.Dir() != ch2.Dir() { - // typ is not bidirectional and typ and term disagree about the direction - return nil - } - } - return typ -} - -// CoreType is a wrapper for NewTypeSet(typ).CoreType() -func CoreType(typ types.Type) types.Type { - return NewTypeSet(typ).CoreType() -} - -// All calls fn for each term in the type set and reports whether all invocations returned true. -// If the type set is empty or unconstrained, All immediately returns false. -func (ts TypeSet) All(fn func(*types.Term) bool) bool { - if len(ts.Terms) == 0 { - return false - } - for _, term := range ts.Terms { - if !fn(term) { - return false - } - } - return true -} - -// Any calls fn for each term in the type set and reports whether any invocation returned true. -// It stops after the first call that returned true. -func (ts TypeSet) Any(fn func(*types.Term) bool) bool { - for _, term := range ts.Terms { - if fn(term) { - return true - } - } - return false -} - -// All is a wrapper for NewTypeSet(typ).All(fn). -func All(typ types.Type, fn func(*types.Term) bool) bool { - return NewTypeSet(typ).All(fn) -} - -// Any is a wrapper for NewTypeSet(typ).Any(fn). -func Any(typ types.Type, fn func(*types.Term) bool) bool { - return NewTypeSet(typ).Any(fn) -} - -func IsSlice(term *types.Term) bool { - _, ok := term.Type().Underlying().(*types.Slice) - return ok -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/upstream.go b/vendor/honnef.co/go/tools/go/types/typeutil/upstream.go deleted file mode 100644 index 04d8c21ba..000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/upstream.go +++ /dev/null @@ -1,52 +0,0 @@ -package typeutil - -import ( - "go/ast" - "go/types" - _ "unsafe" - - "golang.org/x/tools/go/types/typeutil" -) - -type MethodSetCache = typeutil.MethodSetCache -type Hasher = typeutil.Hasher - -func Callee(info *types.Info, call *ast.CallExpr) types.Object { - return typeutil.Callee(info, call) -} - -func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { - return typeutil.IntuitiveMethodSet(T, msets) -} - -func MakeHasher() Hasher { - return typeutil.MakeHasher() -} - -type Map[V any] struct { - m typeutil.Map -} - -func (m *Map[V]) Delete(key types.Type) bool { return m.m.Delete(key) } -func (m *Map[V]) At(key types.Type) (V, bool) { - v := m.m.At(key) - if v == nil { - var zero V - return zero, false - } else { - return v.(V), true - } -} -func (m *Map[V]) Set(key types.Type, value V) { m.m.Set(key, value) } -func (m *Map[V]) Len() int { return m.m.Len() } -func (m *Map[V]) Iterate(f func(key types.Type, value V)) { - ff := func(key types.Type, value interface{}) { - f(key, value.(V)) - } - m.m.Iterate(ff) - -} -func (m *Map[V]) Keys() []types.Type { return m.m.Keys() } -func (m *Map[V]) String() string { return m.m.String() } -func (m *Map[V]) KeysString() string { return m.m.KeysString() } -func (m *Map[V]) SetHasher(h typeutil.Hasher) { m.m.SetHasher(h) } diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/util.go b/vendor/honnef.co/go/tools/go/types/typeutil/util.go deleted file mode 100644 index ef11564c7..000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/util.go +++ /dev/null @@ -1,211 +0,0 @@ -package typeutil - -import ( - "bytes" - "go/types" - "strings" - "sync" - - "golang.org/x/exp/typeparams" -) - -var bufferPool = &sync.Pool{ - New: func() interface{} { - buf := bytes.NewBuffer(nil) - buf.Grow(64) - return buf - }, -} - -func FuncName(f *types.Func) string { - // We don't care about aliases in this function because we use FuncName to check calls - // to known methods, and method receivers are determined by the method declaration, - // not the call. Thus, even if a user does 'type Alias = *sync.Mutex' and calls - // Alias.Lock, we'll still see it as (*sync.Mutex).Lock. - - buf := bufferPool.Get().(*bytes.Buffer) - buf.Reset() - if f.Type() != nil { - sig := f.Type().(*types.Signature) - if recv := sig.Recv(); recv != nil { - buf.WriteByte('(') - if _, ok := recv.Type().(*types.Interface); ok { - // gcimporter creates abstract methods of - // named interfaces using the interface type - // (not the named type) as the receiver. - // Don't print it in full. - buf.WriteString("interface") - } else { - types.WriteType(buf, recv.Type(), nil) - } - buf.WriteByte(')') - buf.WriteByte('.') - } else if f.Pkg() != nil { - writePackage(buf, f.Pkg()) - } - } - buf.WriteString(f.Name()) - s := buf.String() - bufferPool.Put(buf) - return s -} - -func writePackage(buf *bytes.Buffer, pkg *types.Package) { - if pkg == nil { - return - } - s := pkg.Path() - if s != "" { - buf.WriteString(s) - buf.WriteByte('.') - } -} - -// Dereference returns a pointer's element type; otherwise it returns -// T. -func Dereference(T types.Type) types.Type { - if p, ok := T.Underlying().(*types.Pointer); ok { - return p.Elem() - } - return T -} - -// DereferenceR returns a pointer's element type; otherwise it returns -// T. If the element type is itself a pointer, DereferenceR will be -// applied recursively. -func DereferenceR(T types.Type) types.Type { - if p, ok := T.Underlying().(*types.Pointer); ok { - return DereferenceR(p.Elem()) - } - return T -} - -func IsObject(obj types.Object, name string) bool { - var path string - if pkg := obj.Pkg(); pkg != nil { - path = pkg.Path() + "." - } - return path+obj.Name() == name -} - -// IsTypeName reports whether obj represents the qualified name. If obj is a type alias, -// IsTypeName checks both the alias and the aliased type, if the aliased type has a type -// name. -func IsTypeName(obj *types.TypeName, name string) bool { - var qf string - if idx := strings.LastIndex(name, "."); idx != -1 { - qf = name[:idx] - name = name[idx+1:] - } - if obj.Name() == name && - ((qf == "" && obj.Pkg() == nil) || (obj.Pkg() != nil && obj.Pkg().Path() == qf)) { - return true - } - - if !obj.IsAlias() { - return false - } - - // FIXME(dh): we should peel away one layer of alias at a time; this is blocked on - // github.com/golang/go/issues/66559 - if typ, ok := types.Unalias(obj.Type()).(interface{ Obj() *types.TypeName }); ok { - return IsTypeName(typ.Obj(), name) - } - - return false -} - -func IsPointerToTypeWithName(typ types.Type, name string) bool { - ptr, ok := types.Unalias(typ).(*types.Pointer) - if !ok { - return false - } - return IsTypeWithName(ptr.Elem(), name) -} - -// IsTypeWithName reports whether typ represents a type with the qualified name, If typ is -// a type alias, IsTypeWithName checks both the alias and the aliased type. The following -// types can have names: Basic, Named, Alias. -func IsTypeWithName(typ types.Type, name string) bool { - switch typ := typ.(type) { - case *types.Basic: - return typ.Name() == name - case *types.Named: - return IsTypeName(typ.Obj(), name) - case *types.Alias: - // FIXME(dh): we should peel away one layer of alias at a time; this is blocked on - // github.com/golang/go/issues/66559 - - // IsTypeName already handles aliases to other aliases or named types; our - // fallback is required for aliases to basic types. - return IsTypeName(typ.Obj(), name) || IsTypeWithName(types.Unalias(typ), name) - default: - return false - } -} - -// IsPointerLike returns true if type T is like a pointer. This returns true for all nillable types, -// unsafe.Pointer, and type sets where at least one term is pointer-like. -func IsPointerLike(T types.Type) bool { - switch T := T.Underlying().(type) { - case *types.Interface: - if T.IsMethodSet() { - return true - } else { - terms, err := typeparams.NormalTerms(T) - if err != nil { - return false - } - for _, term := range terms { - if IsPointerLike(term.Type()) { - return true - } - } - return false - } - case *types.Chan, *types.Map, *types.Signature, *types.Pointer, *types.Slice: - return true - case *types.Basic: - return T.Kind() == types.UnsafePointer - } - return false -} - -type Field struct { - Var *types.Var - Tag string - Path []int -} - -// FlattenFields recursively flattens T and embedded structs, -// returning a list of fields. If multiple fields with the same name -// exist, all will be returned. -func FlattenFields(T *types.Struct) []Field { - return flattenFields(T, nil, nil) -} - -func flattenFields(T *types.Struct, path []int, seen map[types.Type]bool) []Field { - if seen == nil { - seen = map[types.Type]bool{} - } - if seen[T] { - return nil - } - seen[T] = true - var out []Field - for i := 0; i < T.NumFields(); i++ { - field := T.Field(i) - tag := T.Tag(i) - np := append(path[:len(path):len(path)], i) - if field.Anonymous() { - if s, ok := Dereference(field.Type()).Underlying().(*types.Struct); ok { - out = append(out, flattenFields(s, np, seen)...) - } else { - out = append(out, Field{field, tag, np}) - } - } else { - out = append(out, Field{field, tag, np}) - } - } - return out -} diff --git a/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go b/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go deleted file mode 100644 index dc26a6721..000000000 --- a/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go +++ /dev/null @@ -1,107 +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 buildir defines an Analyzer that constructs the IR -// of an error-free package and returns the set of all -// functions within it. It does not report any diagnostics itself but -// may be used as an input to other analyzers. -// -// THIS INTERFACE IS EXPERIMENTAL AND MAY BE SUBJECT TO INCOMPATIBLE CHANGE. -package buildir - -import ( - "go/ast" - "go/types" - "reflect" - - "honnef.co/go/tools/go/ir" - - "golang.org/x/tools/go/analysis" -) - -type noReturn struct { - Kind ir.NoReturn -} - -func (*noReturn) AFact() {} - -var Analyzer = &analysis.Analyzer{ - Name: "buildir", - Doc: "build IR for later passes", - Run: run, - ResultType: reflect.TypeOf(new(IR)), - FactTypes: []analysis.Fact{new(noReturn)}, -} - -// IR provides intermediate representation for all the -// source functions in the current package. -type IR struct { - Pkg *ir.Package - SrcFuncs []*ir.Function -} - -func run(pass *analysis.Pass) (interface{}, error) { - // Plundered from ssautil.BuildPackage. - - // We must create a new Program for each Package because the - // analysis API provides no place to hang a Program shared by - // all Packages. Consequently, IR Packages and Functions do not - // have a canonical representation across an analysis session of - // multiple packages. This is unlikely to be a problem in - // practice because the analysis API essentially forces all - // packages to be analysed independently, so any given call to - // Analysis.Run on a package will see only IR objects belonging - // to a single Program. - - mode := ir.GlobalDebug - - prog := ir.NewProgram(pass.Fset, mode) - - // Create IR packages for all imports. - // Order is not significant. - created := make(map[*types.Package]bool) - var createAll func(pkgs []*types.Package) - createAll = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !created[p] { - created[p] = true - irpkg := prog.CreatePackage(p, nil, nil, true) - for _, fn := range irpkg.Functions { - if ast.IsExported(fn.Name()) { - var noRet noReturn - if pass.ImportObjectFact(fn.Object(), &noRet) { - fn.NoReturn = noRet.Kind - } - } - } - createAll(p.Imports()) - } - } - } - createAll(pass.Pkg.Imports()) - - // Create and build the primary package. - irpkg := prog.CreatePackage(pass.Pkg, pass.Files, pass.TypesInfo, false) - irpkg.Build() - - // Compute list of source functions, including literals, - // in source order. - var addAnons func(f *ir.Function) - funcs := make([]*ir.Function, len(irpkg.Functions)) - copy(funcs, irpkg.Functions) - addAnons = func(f *ir.Function) { - for _, anon := range f.AnonFuncs { - funcs = append(funcs, anon) - addAnons(anon) - } - } - for _, fn := range irpkg.Functions { - addAnons(fn) - if fn.NoReturn > 0 { - pass.ExportObjectFact(fn.Object(), &noReturn{fn.NoReturn}) - } - } - - return &IR{Pkg: irpkg, SrcFuncs: funcs}, nil -} diff --git a/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go b/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go deleted file mode 100644 index b78899ab5..000000000 --- a/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go +++ /dev/null @@ -1,209 +0,0 @@ -package sharedcheck - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - - "honnef.co/go/tools/analysis/code" - "honnef.co/go/tools/analysis/edit" - "honnef.co/go/tools/analysis/facts/generated" - "honnef.co/go/tools/analysis/facts/tokenfile" - "honnef.co/go/tools/analysis/report" - "honnef.co/go/tools/go/ast/astutil" - "honnef.co/go/tools/go/ir" - "honnef.co/go/tools/go/ir/irutil" - "honnef.co/go/tools/go/types/typeutil" - "honnef.co/go/tools/internal/passes/buildir" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" -) - -func CheckRangeStringRunes(pass *analysis.Pass) (interface{}, error) { - for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs { - cb := func(node ast.Node) bool { - rng, ok := node.(*ast.RangeStmt) - if !ok || !astutil.IsBlank(rng.Key) { - return true - } - - v, _ := fn.ValueForExpr(rng.X) - - // Check that we're converting from string to []rune - val, _ := v.(*ir.Convert) - if val == nil { - return true - } - Tsrc, ok := typeutil.CoreType(val.X.Type()).(*types.Basic) - if !ok || Tsrc.Kind() != types.String { - return true - } - Tdst, ok := typeutil.CoreType(val.Type()).(*types.Slice) - if !ok { - return true - } - TdstElem, ok := types.Unalias(Tdst.Elem()).(*types.Basic) - if !ok || TdstElem.Kind() != types.Int32 { - return true - } - - // Check that the result of the conversion is only used to - // range over - refs := val.Referrers() - if refs == nil { - return true - } - - // Expect two refs: one for obtaining the length of the slice, - // one for accessing the elements - if len(irutil.FilterDebug(*refs)) != 2 { - // TODO(dh): right now, we check that only one place - // refers to our slice. This will miss cases such as - // ranging over the slice twice. Ideally, we'd ensure that - // the slice is only used for ranging over (without - // accessing the key), but that is harder to do because in - // IR form, ranging over a slice looks like an ordinary - // loop with index increments and slice accesses. We'd - // have to look at the associated AST node to check that - // it's a range statement. - return true - } - - pass.Reportf(rng.Pos(), "should range over string, not []rune(string)") - - return true - } - if source := fn.Source(); source != nil { - ast.Inspect(source, cb) - } - } - return nil, nil -} - -// RedundantTypeInDeclarationChecker returns a checker that flags variable declarations with redundantly specified types. -// That is, it flags 'var v T = e' where e's type is identical to T and 'var v = e' (or 'v := e') would have the same effect. -// -// It does not flag variables under the following conditions, to reduce the number of false positives: -// - global variables – these often specify types to aid godoc -// - files that use cgo – cgo code generation and pointer checking emits redundant types -// -// It does not flag variables under the following conditions, unless flagHelpfulTypes is true, to reduce the number of noisy positives: -// - packages that import syscall or unsafe – these sometimes use this form of assignment to make sure types are as expected -// - variables named the blank identifier – a pattern used to confirm the types of variables -// - untyped expressions on the rhs – the explicitness might aid readability -func RedundantTypeInDeclarationChecker(verb string, flagHelpfulTypes bool) *analysis.Analyzer { - fn := func(pass *analysis.Pass) (interface{}, error) { - eval := func(expr ast.Expr) (types.TypeAndValue, error) { - info := &types.Info{ - Types: map[ast.Expr]types.TypeAndValue{}, - } - err := types.CheckExpr(pass.Fset, pass.Pkg, expr.Pos(), expr, info) - return info.Types[expr], err - } - - if !flagHelpfulTypes { - // Don't look at code in low-level packages - for _, imp := range pass.Pkg.Imports() { - if imp.Path() == "syscall" || imp.Path() == "unsafe" { - return nil, nil - } - } - } - - fn := func(node ast.Node) { - decl := node.(*ast.GenDecl) - if decl.Tok != token.VAR { - return - } - - gen, _ := code.Generator(pass, decl.Pos()) - if gen == generated.Cgo { - // TODO(dh): remove this exception once we can use UsesCgo - return - } - - // Delay looking up parent AST nodes until we have to - checkedDecl := false - - specLoop: - for _, spec := range decl.Specs { - spec := spec.(*ast.ValueSpec) - if spec.Type == nil { - continue - } - if len(spec.Names) != len(spec.Values) { - continue - } - Tlhs := pass.TypesInfo.TypeOf(spec.Type) - for i, v := range spec.Values { - if !flagHelpfulTypes && spec.Names[i].Name == "_" { - continue specLoop - } - Trhs := pass.TypesInfo.TypeOf(v) - if !types.Identical(Tlhs, Trhs) { - continue specLoop - } - - // Some expressions are untyped and get converted to the lhs type implicitly. - // This applies to untyped constants, shift operations with an untyped lhs, and possibly others. - // - // Check if the type is truly redundant, i.e. if the type on the lhs doesn't match the default type of the untyped constant. - tv, err := eval(v) - if err != nil { - panic(err) - } - if b, ok := types.Unalias(tv.Type).(*types.Basic); ok && (b.Info()&types.IsUntyped) != 0 { - if Tlhs != types.Default(b) { - // The rhs is untyped and its default type differs from the explicit type on the lhs - continue specLoop - } - switch v := v.(type) { - case *ast.Ident: - // Only flag named constant rhs if it's a predeclared identifier. - // Don't flag other named constants, as the explicit type may aid readability. - if pass.TypesInfo.ObjectOf(v).Pkg() != nil && !flagHelpfulTypes { - continue specLoop - } - case *ast.BasicLit: - // Do flag basic literals - default: - // Don't flag untyped rhs expressions unless flagHelpfulTypes is set - if !flagHelpfulTypes { - continue specLoop - } - } - } - } - - if !checkedDecl { - // Don't flag global variables. These often have explicit types for godoc's sake. - path, _ := astutil.PathEnclosingInterval(code.File(pass, decl), decl.Pos(), decl.Pos()) - pathLoop: - for _, el := range path { - switch el.(type) { - case *ast.FuncDecl, *ast.FuncLit: - checkedDecl = true - break pathLoop - } - } - if !checkedDecl { - // decl is not inside a function - break specLoop - } - } - - report.Report(pass, spec.Type, fmt.Sprintf("%s omit type %s from declaration; it will be inferred from the right-hand side", verb, report.Render(pass, spec.Type)), report.FilterGenerated(), - report.Fixes(edit.Fix("Remove redundant type", edit.Delete(spec.Type)))) - } - } - code.Preorder(pass, fn, (*ast.GenDecl)(nil)) - return nil, nil - } - - return &analysis.Analyzer{ - Run: fn, - Requires: []*analysis.Analyzer{generated.Analyzer, inspect.Analyzer, tokenfile.Analyzer}, - } -} diff --git a/vendor/honnef.co/go/tools/knowledge/arg.go b/vendor/honnef.co/go/tools/knowledge/arg.go deleted file mode 100644 index 4fab2eba1..000000000 --- a/vendor/honnef.co/go/tools/knowledge/arg.go +++ /dev/null @@ -1,77 +0,0 @@ -package knowledge - -var Args = map[string]int{ - "(*sync.Pool).Put.x": 0, - "(*text/template.Template).Parse.text": 0, - "(io.Seeker).Seek.offset": 0, - "(time.Time).Sub.u": 0, - "append.elems": 1, - "append.slice": 0, - "bytes.Equal.a": 0, - "bytes.Equal.b": 1, - "encoding/ascii85.Encode.dst": 0, - "encoding/ascii85.Encode.src": 1, - "(*encoding/base32.Encoding).Encode.dst": 0, - "(*encoding/base32.Encoding).Encode.src": 1, - "(*encoding/base64.Encoding).Encode.dst": 0, - "(*encoding/base64.Encoding).Encode.src": 1, - "encoding/binary.Write.data": 2, - "encoding/hex.Encode.dst": 0, - "encoding/hex.Encode.src": 1, - "(*encoding/json.Decoder).Decode.v": 0, - "(*encoding/json.Encoder).Encode.v": 0, - "(*encoding/xml.Decoder).Decode.v": 0, - "(*encoding/xml.Encoder).Encode.v": 0, - "errors.New.text": 0, - "fmt.Fprintf.format": 1, - "fmt.Printf.format": 0, - "fmt.Sprintf.a[0]": 1, - "fmt.Sprintf.format": 0, - "json.Marshal.v": 0, - "json.Unmarshal.v": 1, - "len.v": 0, - "make.size[0]": 1, - "make.size[1]": 2, - "make.t": 0, - "net/url.Parse.rawurl": 0, - "os.OpenFile.flag": 1, - "os/exec.Command.name": 0, - "os/signal.Notify.c": 0, - "regexp.Compile.expr": 0, - "runtime.SetFinalizer.finalizer": 1, - "runtime.SetFinalizer.obj": 0, - "sort.Sort.data": 0, - "strconv.AppendFloat.bitSize": 4, - "strconv.AppendFloat.fmt": 2, - "strconv.AppendInt.base": 2, - "strconv.AppendUint.base": 2, - "strconv.FormatComplex.bitSize": 3, - "strconv.FormatComplex.fmt": 1, - "strconv.FormatFloat.bitSize": 3, - "strconv.FormatFloat.fmt": 1, - "strconv.FormatInt.base": 1, - "strconv.FormatUint.base": 1, - "strconv.ParseComplex.bitSize": 1, - "strconv.ParseFloat.bitSize": 1, - "strconv.ParseInt.base": 1, - "strconv.ParseInt.bitSize": 2, - "strconv.ParseUint.base": 1, - "strconv.ParseUint.bitSize": 2, - "time.Parse.layout": 0, - "time.Sleep.d": 0, - "xml.Marshal.v": 0, - "xml.Unmarshal.v": 1, -} - -// Arg turns the name of an argument into an argument index. -// Indices are zero-based and method receivers do not count as arguments. -// -// Arg refers to a manually compiled mapping (see the Args variable.) -// Modify the knowledge package to add new arguments. -func Arg(name string) int { - n, ok := Args[name] - if !ok { - panic("unknown argument " + name) - } - return n -} diff --git a/vendor/honnef.co/go/tools/knowledge/deprecated.go b/vendor/honnef.co/go/tools/knowledge/deprecated.go deleted file mode 100644 index 854e5bd1f..000000000 --- a/vendor/honnef.co/go/tools/knowledge/deprecated.go +++ /dev/null @@ -1,214 +0,0 @@ -package knowledge - -const ( - // DeprecatedNeverUse indicates that an API should never be used, regardless of Go version. - DeprecatedNeverUse = "never" - // DeprecatedUseNoLonger indicates that an API has no use anymore. - DeprecatedUseNoLonger = "no longer" -) - -// Deprecation describes when a Go API has been deprecated. -type Deprecation struct { - // The minor Go version since which this API has been deprecated. - DeprecatedSince string - // The minor Go version since which an alternative API has been available. - // May also be one of DeprecatedNeverUse or DeprecatedUseNoLonger. - AlternativeAvailableSince string -} - -// go/importer.ForCompiler contains "Deprecated:", but it refers to a single argument, not the whole function. -// Luckily, the notice starts in the middle of a paragraph, and as such isn't detected by us. - -// TODO(dh): StdlibDeprecations doesn't contain entries for internal packages and unexported API. That's fine for normal -// users, but makes the Deprecated check less useful for people working on Go itself. - -// StdlibDeprecations contains a mapping of Go API (such as variables, methods, or fields, among others) -// to information about when it has been deprecated. -var StdlibDeprecations = map[string]Deprecation{ - // FIXME(dh): AllowBinary isn't being detected as deprecated - // because the comment has a newline right after "Deprecated:" - "go/build.AllowBinary": {"go1.7", "go1.7"}, - "(archive/zip.FileHeader).CompressedSize": {"go1.1", "go1.1"}, - "(archive/zip.FileHeader).UncompressedSize": {"go1.1", "go1.1"}, - "(archive/zip.FileHeader).ModifiedTime": {"go1.10", "go1.10"}, - "(archive/zip.FileHeader).ModifiedDate": {"go1.10", "go1.10"}, - "(*archive/zip.FileHeader).ModTime": {"go1.10", "go1.10"}, - "(*archive/zip.FileHeader).SetModTime": {"go1.10", "go1.10"}, - "(go/doc.Package).Bugs": {"go1.1", "go1.1"}, - "os.SEEK_SET": {"go1.7", "go1.7"}, - "os.SEEK_CUR": {"go1.7", "go1.7"}, - "os.SEEK_END": {"go1.7", "go1.7"}, - "(net.Dialer).Cancel": {"go1.7", "go1.7"}, - "runtime.CPUProfile": {"go1.9", "go1.0"}, - "compress/flate.ReadError": {"go1.6", DeprecatedUseNoLonger}, - "compress/flate.WriteError": {"go1.6", DeprecatedUseNoLonger}, - "path/filepath.HasPrefix": {"go1.0", DeprecatedNeverUse}, - "(net/http.Transport).Dial": {"go1.7", "go1.7"}, - "(net/http.Transport).DialTLS": {"go1.14", "go1.14"}, - "(*net/http.Transport).CancelRequest": {"go1.6", "go1.5"}, - "net/http.ErrWriteAfterFlush": {"go1.7", DeprecatedUseNoLonger}, - "net/http.ErrHeaderTooLong": {"go1.8", DeprecatedUseNoLonger}, - "net/http.ErrShortBody": {"go1.8", DeprecatedUseNoLonger}, - "net/http.ErrMissingContentLength": {"go1.8", DeprecatedUseNoLonger}, - "net/http/httputil.ErrPersistEOF": {"go1.0", DeprecatedUseNoLonger}, - "net/http/httputil.ErrClosed": {"go1.0", DeprecatedUseNoLonger}, - "net/http/httputil.ErrPipeline": {"go1.0", DeprecatedUseNoLonger}, - "net/http/httputil.ServerConn": {"go1.0", "go1.0"}, - "net/http/httputil.NewServerConn": {"go1.0", "go1.0"}, - "net/http/httputil.ClientConn": {"go1.0", "go1.0"}, - "net/http/httputil.NewClientConn": {"go1.0", "go1.0"}, - "net/http/httputil.NewProxyClientConn": {"go1.0", "go1.0"}, - "(net/http.Request).Cancel": {"go1.7", "go1.7"}, - "(text/template/parse.PipeNode).Line": {"go1.1", DeprecatedUseNoLonger}, - "(text/template/parse.ActionNode).Line": {"go1.1", DeprecatedUseNoLonger}, - "(text/template/parse.BranchNode).Line": {"go1.1", DeprecatedUseNoLonger}, - "(text/template/parse.TemplateNode).Line": {"go1.1", DeprecatedUseNoLonger}, - "database/sql/driver.ColumnConverter": {"go1.9", "go1.9"}, - "database/sql/driver.Execer": {"go1.8", "go1.8"}, - "database/sql/driver.Queryer": {"go1.8", "go1.8"}, - "(database/sql/driver.Conn).Begin": {"go1.8", "go1.8"}, - "(database/sql/driver.Stmt).Exec": {"go1.8", "go1.8"}, - "(database/sql/driver.Stmt).Query": {"go1.8", "go1.8"}, - "syscall.StringByteSlice": {"go1.1", "go1.1"}, - "syscall.StringBytePtr": {"go1.1", "go1.1"}, - "syscall.StringSlicePtr": {"go1.1", "go1.1"}, - "syscall.StringToUTF16": {"go1.1", "go1.1"}, - "syscall.StringToUTF16Ptr": {"go1.1", "go1.1"}, - "(*regexp.Regexp).Copy": {"go1.12", DeprecatedUseNoLonger}, - "(archive/tar.Header).Xattrs": {"go1.10", "go1.10"}, - "archive/tar.TypeRegA": {"go1.11", "go1.1"}, - "go/types.NewInterface": {"go1.11", "go1.11"}, - "(*go/types.Interface).Embedded": {"go1.11", "go1.11"}, - "go/importer.For": {"go1.12", "go1.12"}, - "encoding/json.InvalidUTF8Error": {"go1.2", DeprecatedUseNoLonger}, - "encoding/json.UnmarshalFieldError": {"go1.2", DeprecatedUseNoLonger}, - "encoding/csv.ErrTrailingComma": {"go1.2", DeprecatedUseNoLonger}, - "(encoding/csv.Reader).TrailingComma": {"go1.2", DeprecatedUseNoLonger}, - "(net.Dialer).DualStack": {"go1.12", "go1.12"}, - "net/http.ErrUnexpectedTrailer": {"go1.12", DeprecatedUseNoLonger}, - "net/http.CloseNotifier": {"go1.11", "go1.7"}, - // This is hairy. The notice says "Not all errors in the http package related to protocol errors are of type ProtocolError", but doesn't that imply that some errors do? - "net/http.ProtocolError": {"go1.8", DeprecatedUseNoLonger}, - "(crypto/x509.CertificateRequest).Attributes": {"go1.5", "go1.3"}, - "(*crypto/x509.Certificate).CheckCRLSignature": {"go1.19", "go1.19"}, - "crypto/x509.ParseCRL": {"go1.19", "go1.19"}, - "crypto/x509.ParseDERCRL": {"go1.19", "go1.19"}, - "(*crypto/x509.Certificate).CreateCRL": {"go1.19", "go1.19"}, - "crypto/x509/pkix.TBSCertificateList": {"go1.19", "go1.19"}, - "crypto/x509/pkix.RevokedCertificate": {"go1.19", "go1.19"}, - "go/doc.ToHTML": {"go1.20", "go1.20"}, - "go/doc.ToText": {"go1.20", "go1.20"}, - "go/doc.Synopsis": {"go1.20", "go1.20"}, - "math/rand.Seed": {"go1.20", "go1.0"}, - "math/rand.Read": {"go1.20", DeprecatedNeverUse}, - - // These functions have no direct alternative, but they are insecure and should no longer be used. - "crypto/x509.IsEncryptedPEMBlock": {"go1.16", DeprecatedNeverUse}, - "crypto/x509.DecryptPEMBlock": {"go1.16", DeprecatedNeverUse}, - "crypto/x509.EncryptPEMBlock": {"go1.16", DeprecatedNeverUse}, - "crypto/dsa": {"go1.16", DeprecatedNeverUse}, - - // This function has no alternative, but also no purpose. - "(*crypto/rc4.Cipher).Reset": {"go1.12", DeprecatedNeverUse}, - "(net/http/httptest.ResponseRecorder).HeaderMap": {"go1.11", "go1.7"}, - "image.ZP": {"go1.13", "go1.0"}, - "image.ZR": {"go1.13", "go1.0"}, - "(*debug/gosym.LineTable).LineToPC": {"go1.2", "go1.2"}, - "(*debug/gosym.LineTable).PCToLine": {"go1.2", "go1.2"}, - "crypto/tls.VersionSSL30": {"go1.13", DeprecatedNeverUse}, - "(crypto/tls.Config).NameToCertificate": {"go1.14", DeprecatedUseNoLonger}, - "(*crypto/tls.Config).BuildNameToCertificate": {"go1.14", DeprecatedUseNoLonger}, - "(crypto/tls.Config).SessionTicketKey": {"go1.16", "go1.5"}, - // No alternative, no use - "(crypto/tls.ConnectionState).NegotiatedProtocolIsMutual": {"go1.16", DeprecatedNeverUse}, - // No alternative, but insecure - "(crypto/tls.ConnectionState).TLSUnique": {"go1.16", DeprecatedNeverUse}, - "image/jpeg.Reader": {"go1.4", DeprecatedNeverUse}, - - // All of these have been deprecated in favour of external libraries - "syscall.AttachLsf": {"go1.7", "go1.0"}, - "syscall.DetachLsf": {"go1.7", "go1.0"}, - "syscall.LsfSocket": {"go1.7", "go1.0"}, - "syscall.SetLsfPromisc": {"go1.7", "go1.0"}, - "syscall.LsfJump": {"go1.7", "go1.0"}, - "syscall.LsfStmt": {"go1.7", "go1.0"}, - "syscall.BpfStmt": {"go1.7", "go1.0"}, - "syscall.BpfJump": {"go1.7", "go1.0"}, - "syscall.BpfBuflen": {"go1.7", "go1.0"}, - "syscall.SetBpfBuflen": {"go1.7", "go1.0"}, - "syscall.BpfDatalink": {"go1.7", "go1.0"}, - "syscall.SetBpfDatalink": {"go1.7", "go1.0"}, - "syscall.SetBpfPromisc": {"go1.7", "go1.0"}, - "syscall.FlushBpf": {"go1.7", "go1.0"}, - "syscall.BpfInterface": {"go1.7", "go1.0"}, - "syscall.SetBpfInterface": {"go1.7", "go1.0"}, - "syscall.BpfTimeout": {"go1.7", "go1.0"}, - "syscall.SetBpfTimeout": {"go1.7", "go1.0"}, - "syscall.BpfStats": {"go1.7", "go1.0"}, - "syscall.SetBpfImmediate": {"go1.7", "go1.0"}, - "syscall.SetBpf": {"go1.7", "go1.0"}, - "syscall.CheckBpfVersion": {"go1.7", "go1.0"}, - "syscall.BpfHeadercmpl": {"go1.7", "go1.0"}, - "syscall.SetBpfHeadercmpl": {"go1.7", "go1.0"}, - "syscall.RouteRIB": {"go1.8", "go1.0"}, - "syscall.RoutingMessage": {"go1.8", "go1.0"}, - "syscall.RouteMessage": {"go1.8", "go1.0"}, - "syscall.InterfaceMessage": {"go1.8", "go1.0"}, - "syscall.InterfaceAddrMessage": {"go1.8", "go1.0"}, - "syscall.ParseRoutingMessage": {"go1.8", "go1.0"}, - "syscall.ParseRoutingSockaddr": {"go1.8", "go1.0"}, - "syscall.InterfaceAnnounceMessage": {"go1.7", "go1.0"}, - "syscall.InterfaceMulticastAddrMessage": {"go1.7", "go1.0"}, - "syscall.FormatMessage": {"go1.5", "go1.0"}, - "syscall.PostQueuedCompletionStatus": {"go1.17", "go1.0"}, - "syscall.GetQueuedCompletionStatus": {"go1.17", "go1.0"}, - "syscall.CreateIoCompletionPort": {"go1.17", "go1.0"}, - - // We choose to only track the package itself, even though all functions are derecated individually, too. Anyone - // using ioutil directly will have to import it, and this keeps the noise down. - "io/ioutil": {"go1.19", "go1.19"}, - - "bytes.Title": {"go1.18", "go1.0"}, - "strings.Title": {"go1.18", "go1.0"}, - "(crypto/tls.Config).PreferServerCipherSuites": {"go1.18", DeprecatedUseNoLonger}, - // It's not clear if Subjects was okay to use in the past, so we err on the less noisy side of assuming that it was. - "(*crypto/x509.CertPool).Subjects": {"go1.18", DeprecatedUseNoLonger}, - "go/types.NewSignature": {"go1.18", "go1.18"}, - "(net.Error).Temporary": {"go1.18", DeprecatedNeverUse}, - // InterfaceData is another tricky case. It was deprecated in Go 1.18, but has been useless since Go 1.4, and an - // "alternative" (using your own unsafe hacks) has existed forever. We don't want to get into hairsplitting with - // users who somehow successfully used this between 1.4 and 1.18, so we'll just tag it as deprecated since 1.18. - "(reflect.Value).InterfaceData": {"go1.18", "go1.18"}, - - // The following objects are only deprecated on Windows. - "syscall.Syscall": {"go1.18", "go1.18"}, - "syscall.Syscall12": {"go1.18", "go1.18"}, - "syscall.Syscall15": {"go1.18", "go1.18"}, - "syscall.Syscall18": {"go1.18", "go1.18"}, - "syscall.Syscall6": {"go1.18", "go1.18"}, - "syscall.Syscall9": {"go1.18", "go1.18"}, - - "reflect.SliceHeader": {"go1.21", "go1.17"}, - "reflect.StringHeader": {"go1.21", "go1.20"}, - "crypto/elliptic.GenerateKey": {"go1.21", "go1.21"}, - "crypto/elliptic.Marshal": {"go1.21", "go1.21"}, - "crypto/elliptic.Unmarshal": {"go1.21", "go1.21"}, - "(*crypto/elliptic.CurveParams).Add": {"go1.21", "go1.21"}, - "(*crypto/elliptic.CurveParams).Double": {"go1.21", "go1.21"}, - "(*crypto/elliptic.CurveParams).IsOnCurve": {"go1.21", "go1.21"}, - "(*crypto/elliptic.CurveParams).ScalarBaseMult": {"go1.21", "go1.21"}, - "(*crypto/elliptic.CurveParams).ScalarMult": {"go1.21", "go1.21"}, - "crypto/rsa.GenerateMultiPrimeKey": {"go1.21", DeprecatedNeverUse}, - "(crypto/rsa.PrecomputedValues).CRTValues": {"go1.21", DeprecatedNeverUse}, - "(crypto/x509.RevocationList).RevokedCertificates": {"go1.21", "go1.21"}, - - "go/ast.NewPackage": {"go1.22", "go1.0"}, - "go/ast.Importer": {"go1.22", "go1.0"}, - "go/ast.Object": {"go1.22", "go1.0"}, - "go/ast.Package": {"go1.22", "go1.0"}, - "go/ast.Scope": {"go1.22", "go1.0"}, - "html/template.ErrJSTemplate": {"go1.22", DeprecatedUseNoLonger}, - "reflect.PtrTo": {"go1.22", "go1.18"}, -} - -// Last imported from Go at e8ee1dc4f9e2632ba1018610d1a1187743ae397f diff --git a/vendor/honnef.co/go/tools/knowledge/doc.go b/vendor/honnef.co/go/tools/knowledge/doc.go deleted file mode 100644 index 72ff52444..000000000 --- a/vendor/honnef.co/go/tools/knowledge/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package knowledge contains manually collected information about Go APIs. -package knowledge diff --git a/vendor/honnef.co/go/tools/knowledge/signatures.go b/vendor/honnef.co/go/tools/knowledge/signatures.go deleted file mode 100644 index 03f4d53e8..000000000 --- a/vendor/honnef.co/go/tools/knowledge/signatures.go +++ /dev/null @@ -1,107 +0,0 @@ -package knowledge - -import ( - "go/token" - "go/types" -) - -var Signatures = map[string]*types.Signature{ - "(io.Seeker).Seek": types.NewSignatureType(nil, nil, nil, - types.NewTuple( - types.NewParam(token.NoPos, nil, "", types.Typ[types.Int64]), - types.NewParam(token.NoPos, nil, "", types.Typ[types.Int]), - ), - types.NewTuple( - types.NewParam(token.NoPos, nil, "", types.Typ[types.Int64]), - types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()), - ), - false, - ), - - "(io.Writer).Write": types.NewSignatureType(nil, nil, nil, - types.NewTuple( - types.NewParam(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])), - ), - types.NewTuple( - types.NewParam(token.NoPos, nil, "", types.Typ[types.Int]), - types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()), - ), - false, - ), - - "(io.StringWriter).WriteString": types.NewSignatureType(nil, nil, nil, - types.NewTuple( - types.NewParam(token.NoPos, nil, "", types.Typ[types.String]), - ), - types.NewTuple( - types.NewParam(token.NoPos, nil, "", types.Typ[types.Int]), - types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()), - ), - false, - ), - - "(encoding.TextMarshaler).MarshalText": types.NewSignatureType(nil, nil, nil, - types.NewTuple(), - types.NewTuple( - types.NewParam(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])), - types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()), - ), - false, - ), - - "(encoding/json.Marshaler).MarshalJSON": types.NewSignatureType(nil, nil, nil, - types.NewTuple(), - types.NewTuple( - types.NewParam(token.NoPos, nil, "", types.NewSlice(types.Typ[types.Byte])), - types.NewParam(token.NoPos, nil, "", types.Universe.Lookup("error").Type()), - ), - false, - ), - - "(fmt.Stringer).String": types.NewSignatureType(nil, nil, nil, - types.NewTuple(), - types.NewTuple( - types.NewParam(token.NoPos, nil, "", types.Typ[types.String]), - ), - false, - ), -} - -var Interfaces = map[string]*types.Interface{ - "fmt.Stringer": types.NewInterfaceType( - []*types.Func{ - types.NewFunc(token.NoPos, nil, "String", Signatures["(fmt.Stringer).String"]), - }, - nil, - ).Complete(), - - "error": types.Universe.Lookup("error").Type().Underlying().(*types.Interface), - - "io.Writer": types.NewInterfaceType( - []*types.Func{ - types.NewFunc(token.NoPos, nil, "Write", Signatures["(io.Writer).Write"]), - }, - nil, - ).Complete(), - - "io.StringWriter": types.NewInterfaceType( - []*types.Func{ - types.NewFunc(token.NoPos, nil, "WriteString", Signatures["(io.StringWriter).WriteString"]), - }, - nil, - ).Complete(), - - "encoding.TextMarshaler": types.NewInterfaceType( - []*types.Func{ - types.NewFunc(token.NoPos, nil, "MarshalText", Signatures["(encoding.TextMarshaler).MarshalText"]), - }, - nil, - ).Complete(), - - "encoding/json.Marshaler": types.NewInterfaceType( - []*types.Func{ - types.NewFunc(token.NoPos, nil, "MarshalJSON", Signatures["(encoding/json.Marshaler).MarshalJSON"]), - }, - nil, - ).Complete(), -} diff --git a/vendor/honnef.co/go/tools/knowledge/targets.go b/vendor/honnef.co/go/tools/knowledge/targets.go deleted file mode 100644 index d9c44f83f..000000000 --- a/vendor/honnef.co/go/tools/knowledge/targets.go +++ /dev/null @@ -1,38 +0,0 @@ -package knowledge - -var KnownGOOS = map[string]struct{}{ - "aix": {}, - "android": {}, - "darwin": {}, - "dragonfly": {}, - "freebsd": {}, - "hurd": {}, - "illumos": {}, - "ios": {}, - "js": {}, - "linux": {}, - "netbsd": {}, - "openbsd": {}, - "plan9": {}, - "solaris": {}, - "wasip1": {}, - "windows": {}, -} - -var KnownGOARCH = map[string]struct{}{ - "386": {}, - "amd64": {}, - "arm": {}, - "arm64": {}, - "loong64": {}, - "mips": {}, - "mipsle": {}, - "mips64": {}, - "mips64le": {}, - "ppc64": {}, - "ppc64le": {}, - "riscv64": {}, - "s390x": {}, - "sparc64": {}, - "wasm": {}, -} diff --git a/vendor/honnef.co/go/tools/pattern/convert.go b/vendor/honnef.co/go/tools/pattern/convert.go deleted file mode 100644 index aed3617cd..000000000 --- a/vendor/honnef.co/go/tools/pattern/convert.go +++ /dev/null @@ -1,243 +0,0 @@ -package pattern - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "reflect" -) - -var astTypes = map[string]reflect.Type{ - "Ellipsis": reflect.TypeOf(ast.Ellipsis{}), - "RangeStmt": reflect.TypeOf(ast.RangeStmt{}), - "AssignStmt": reflect.TypeOf(ast.AssignStmt{}), - "IndexExpr": reflect.TypeOf(ast.IndexExpr{}), - "IndexListExpr": reflect.TypeOf(ast.IndexListExpr{}), - "Ident": reflect.TypeOf(ast.Ident{}), - "ValueSpec": reflect.TypeOf(ast.ValueSpec{}), - "GenDecl": reflect.TypeOf(ast.GenDecl{}), - "BinaryExpr": reflect.TypeOf(ast.BinaryExpr{}), - "ForStmt": reflect.TypeOf(ast.ForStmt{}), - "ArrayType": reflect.TypeOf(ast.ArrayType{}), - "DeferStmt": reflect.TypeOf(ast.DeferStmt{}), - "MapType": reflect.TypeOf(ast.MapType{}), - "ReturnStmt": reflect.TypeOf(ast.ReturnStmt{}), - "SliceExpr": reflect.TypeOf(ast.SliceExpr{}), - "StarExpr": reflect.TypeOf(ast.StarExpr{}), - "UnaryExpr": reflect.TypeOf(ast.UnaryExpr{}), - "SendStmt": reflect.TypeOf(ast.SendStmt{}), - "SelectStmt": reflect.TypeOf(ast.SelectStmt{}), - "ImportSpec": reflect.TypeOf(ast.ImportSpec{}), - "IfStmt": reflect.TypeOf(ast.IfStmt{}), - "GoStmt": reflect.TypeOf(ast.GoStmt{}), - "Field": reflect.TypeOf(ast.Field{}), - "SelectorExpr": reflect.TypeOf(ast.SelectorExpr{}), - "StructType": reflect.TypeOf(ast.StructType{}), - "KeyValueExpr": reflect.TypeOf(ast.KeyValueExpr{}), - "FuncType": reflect.TypeOf(ast.FuncType{}), - "FuncLit": reflect.TypeOf(ast.FuncLit{}), - "FuncDecl": reflect.TypeOf(ast.FuncDecl{}), - "ChanType": reflect.TypeOf(ast.ChanType{}), - "CallExpr": reflect.TypeOf(ast.CallExpr{}), - "CaseClause": reflect.TypeOf(ast.CaseClause{}), - "CommClause": reflect.TypeOf(ast.CommClause{}), - "CompositeLit": reflect.TypeOf(ast.CompositeLit{}), - "EmptyStmt": reflect.TypeOf(ast.EmptyStmt{}), - "SwitchStmt": reflect.TypeOf(ast.SwitchStmt{}), - "TypeSwitchStmt": reflect.TypeOf(ast.TypeSwitchStmt{}), - "TypeAssertExpr": reflect.TypeOf(ast.TypeAssertExpr{}), - "TypeSpec": reflect.TypeOf(ast.TypeSpec{}), - "InterfaceType": reflect.TypeOf(ast.InterfaceType{}), - "BranchStmt": reflect.TypeOf(ast.BranchStmt{}), - "IncDecStmt": reflect.TypeOf(ast.IncDecStmt{}), - "BasicLit": reflect.TypeOf(ast.BasicLit{}), -} - -func ASTToNode(node interface{}) Node { - switch node := node.(type) { - case *ast.File: - panic("cannot convert *ast.File to Node") - case nil: - return Nil{} - case string: - return String(node) - case token.Token: - return Token(node) - case *ast.ExprStmt: - return ASTToNode(node.X) - case *ast.BlockStmt: - if node == nil { - return Nil{} - } - return ASTToNode(node.List) - case *ast.FieldList: - if node == nil { - return Nil{} - } - return ASTToNode(node.List) - case *ast.BasicLit: - if node == nil { - return Nil{} - } - case *ast.ParenExpr: - return ASTToNode(node.X) - } - - if node, ok := node.(ast.Node); ok { - name := reflect.TypeOf(node).Elem().Name() - T, ok := structNodes[name] - if !ok { - panic(fmt.Sprintf("internal error: unhandled type %T", node)) - } - - if reflect.ValueOf(node).IsNil() { - return Nil{} - } - v := reflect.ValueOf(node).Elem() - objs := make([]Node, T.NumField()) - for i := 0; i < T.NumField(); i++ { - f := v.FieldByName(T.Field(i).Name) - objs[i] = ASTToNode(f.Interface()) - } - - n, err := populateNode(name, objs, false) - if err != nil { - panic(fmt.Sprintf("internal error: %s", err)) - } - return n - } - - s := reflect.ValueOf(node) - if s.Kind() == reflect.Slice { - if s.Len() == 0 { - return List{} - } - if s.Len() == 1 { - return ASTToNode(s.Index(0).Interface()) - } - - tail := List{} - for i := s.Len() - 1; i >= 0; i-- { - head := ASTToNode(s.Index(i).Interface()) - l := List{ - Head: head, - Tail: tail, - } - tail = l - } - return tail - } - - panic(fmt.Sprintf("internal error: unhandled type %T", node)) -} - -func NodeToAST(node Node, state State) interface{} { - switch node := node.(type) { - case Binding: - v, ok := state[node.Name] - if !ok { - // really we want to return an error here - panic("XXX") - } - switch v := v.(type) { - case types.Object: - return &ast.Ident{Name: v.Name()} - default: - return v - } - case Builtin, Any, Object, Symbol, Not, Or: - panic("XXX") - case List: - if (node == List{}) { - return []ast.Node{} - } - x := []ast.Node{NodeToAST(node.Head, state).(ast.Node)} - x = append(x, NodeToAST(node.Tail, state).([]ast.Node)...) - return x - case Token: - return token.Token(node) - case String: - return string(node) - case Nil: - return nil - } - - name := reflect.TypeOf(node).Name() - T, ok := astTypes[name] - if !ok { - panic(fmt.Sprintf("internal error: unhandled type %T", node)) - } - v := reflect.ValueOf(node) - out := reflect.New(T) - for i := 0; i < T.NumField(); i++ { - fNode := v.FieldByName(T.Field(i).Name) - if (fNode == reflect.Value{}) { - continue - } - fAST := out.Elem().FieldByName(T.Field(i).Name) - switch fAST.Type().Kind() { - case reflect.Slice: - c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state)) - if c.Kind() != reflect.Slice { - // it's a single node in the pattern, we have to wrap - // it in a slice - slice := reflect.MakeSlice(fAST.Type(), 1, 1) - slice.Index(0).Set(c) - c = slice - } - switch fAST.Interface().(type) { - case []ast.Node: - switch cc := c.Interface().(type) { - case []ast.Node: - fAST.Set(c) - case []ast.Expr: - var slice []ast.Node - for _, el := range cc { - slice = append(slice, el) - } - fAST.Set(reflect.ValueOf(slice)) - default: - panic("XXX") - } - case []ast.Expr: - switch cc := c.Interface().(type) { - case []ast.Node: - var slice []ast.Expr - for _, el := range cc { - slice = append(slice, el.(ast.Expr)) - } - fAST.Set(reflect.ValueOf(slice)) - case []ast.Expr: - fAST.Set(c) - default: - panic("XXX") - } - default: - panic("XXX") - } - case reflect.Int: - c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state)) - switch c.Kind() { - case reflect.String: - tok, ok := tokensByString[c.Interface().(string)] - if !ok { - // really we want to return an error here - panic("XXX") - } - fAST.SetInt(int64(tok)) - case reflect.Int: - fAST.Set(c) - default: - panic(fmt.Sprintf("internal error: unexpected kind %s", c.Kind())) - } - default: - r := NodeToAST(fNode.Interface().(Node), state) - if r != nil { - fAST.Set(reflect.ValueOf(r)) - } - } - } - - return out.Interface().(ast.Node) -} diff --git a/vendor/honnef.co/go/tools/pattern/doc.go b/vendor/honnef.co/go/tools/pattern/doc.go deleted file mode 100644 index 22fe2cf30..000000000 --- a/vendor/honnef.co/go/tools/pattern/doc.go +++ /dev/null @@ -1,272 +0,0 @@ -/* -Package pattern implements a simple language for pattern matching Go ASTs. - -# Design decisions and trade-offs - -The language is designed specifically for the task of filtering ASTs -to simplify the implementation of analyses in staticcheck. -It is also intended to be trivial to parse and execute. - -To that end, we make certain decisions that make the language more -suited to its task, while making certain queries infeasible. - -Furthermore, it is fully expected that the majority of analyses will still require ordinary Go code -to further process the filtered AST, to make use of type information and to enforce complex invariants. -It is not our goal to design a scripting language for writing entire checks in. - -# The language - -At its core, patterns are a representation of Go ASTs, allowing for the use of placeholders to enable pattern matching. -Their syntax is inspired by LISP and Haskell, but unlike LISP, the core unit of patterns isn't the list, but the node. -There is a fixed set of nodes, identified by name, and with the exception of the Or node, all nodes have a fixed number of arguments. -In addition to nodes, there are atoms, which represent basic units such as strings or the nil value. - -Pattern matching is implemented via bindings, represented by the Binding node. -A Binding can match nodes and associate them with names, to later recall the nodes. -This allows for expressing "this node must be equal to that node" constraints. - -To simplify writing and reading patterns, a small amount of additional syntax exists on top of nodes and atoms. -This additional syntax doesn't add any new features of its own, it simply provides shortcuts to creating nodes and atoms. - -To show an example of a pattern, first consider this snippet of Go code: - - if x := fn(); x != nil { - for _, v := range x { - println(v, x) - } - } - -The corresponding AST expressed as an idiomatic pattern would look as follows: - - (IfStmt - (AssignStmt (Ident "x") ":=" (CallExpr (Ident "fn") [])) - (BinaryExpr (Ident "x") "!=" (Ident "nil")) - (RangeStmt - (Ident "_") (Ident "v") ":=" (Ident "x") - (CallExpr (Ident "println") [(Ident "v") (Ident "x")])) - nil) - -Two things are worth noting about this representation. -First, the [el1 el2 ...] syntax is a short-hand for creating lists. -It is a short-hand for el1:el2:[], which itself is a short-hand for (List el1 (List el2 (List nil nil)). -Second, note the absence of a lot of lists in places that normally accept lists. -For example, assignment assigns a number of right-hands to a number of left-hands, yet our AssignStmt is lacking any form of list. -This is due to the fact that a single node can match a list of exactly one element. -Thus, the two following forms have identical matching behavior: - - (AssignStmt (Ident "x") ":=" (CallExpr (Ident "fn") [])) - (AssignStmt [(Ident "x")] ":=" [(CallExpr (Ident "fn") [])]) - -This section serves as an overview of the language's syntax. -More in-depth explanations of the matching behavior as well as an exhaustive list of node types follows in the coming sections. - -# Pattern matching - -# TODO write about pattern matching - -- inspired by haskell syntax, but much, much simpler and naive - -# Node types - -The language contains two kinds of nodes: those that map to nodes in the AST, and those that implement additional logic. - -Nodes that map directly to AST nodes are named identically to the types in the go/ast package. -What follows is an exhaustive list of these nodes: - - (ArrayType len elt) - (AssignStmt lhs tok rhs) - (BasicLit kind value) - (BinaryExpr x op y) - (BranchStmt tok label) - (CallExpr fun args) - (CaseClause list body) - (ChanType dir value) - (CommClause comm body) - (CompositeLit type elts) - (DeferStmt call) - (Ellipsis elt) - (EmptyStmt) - (Field names type tag) - (ForStmt init cond post body) - (FuncDecl recv name type body) - (FuncLit type body) - (FuncType params results) - (GenDecl specs) - (GoStmt call) - (Ident name) - (IfStmt init cond body else) - (ImportSpec name path) - (IncDecStmt x tok) - (IndexExpr x index) - (InterfaceType methods) - (KeyValueExpr key value) - (MapType key value) - (RangeStmt key value tok x body) - (ReturnStmt results) - (SelectStmt body) - (SelectorExpr x sel) - (SendStmt chan value) - (SliceExpr x low high max) - (StarExpr x) - (StructType fields) - (SwitchStmt init tag body) - (TypeAssertExpr) - (TypeSpec name type) - (TypeSwitchStmt init assign body) - (UnaryExpr op x) - (ValueSpec names type values) - -Additionally, there are the String, Token and nil atoms. -Strings are double-quoted string literals, as in (Ident "someName"). -Tokens are also represented as double-quoted string literals, but are converted to token.Token values in contexts that require tokens, -such as in (BinaryExpr x "<" y), where "<" is transparently converted to token.LSS during matching. -The keyword 'nil' denotes the nil value, which represents the absence of any value. - -We also define the (List head tail) node, which is used to represent sequences of elements as a singly linked list. -The head is a single element, and the tail is the remainder of the list. -For example, - - (List "foo" (List "bar" (List "baz" (List nil nil)))) - -represents a list of three elements, "foo", "bar" and "baz". There is dedicated syntax for writing lists, which looks as follows: - - ["foo" "bar" "baz"] - -This syntax is itself syntactic sugar for the following form: - - "foo":"bar":"baz":[] - -This form is of particular interest for pattern matching, as it allows matching on the head and tail. For example, - - "foo":"bar":_ - -would match any list with at least two elements, where the first two elements are "foo" and "bar". This is equivalent to writing - - (List "foo" (List "bar" _)) - -Note that it is not possible to match from the end of the list. -That is, there is no way to express a query such as "a list of any length where the last element is foo". - -Note that unlike in LISP, nil and empty lists are distinct from one another. -In patterns, with respect to lists, nil is akin to Go's untyped nil. -It will match a nil ast.Node, but it will not match a nil []ast.Expr. Nil will, however, match pointers to named types such as *ast.Ident. -Similarly, lists are akin to Go's -slices. An empty list will match both a nil and an empty []ast.Expr, but it will not match a nil ast.Node. - -Due to the difference between nil and empty lists, an empty list is represented as (List nil nil), i.e. a list with no head or tail. -Similarly, a list of one element is represented as (List el (List nil nil)). Unlike in LISP, it cannot be represented by (List el nil). - -Finally, there are nodes that implement special logic or matching behavior. - -(Any) matches any value. The underscore (_) maps to this node, making the following two forms equivalent: - - (Ident _) - (Ident (Any)) - -(Builtin name) matches a built-in identifier or function by name. -This is a type-aware variant of (Ident name). -Instead of only comparing the name, it resolves the object behind the name and makes sure it's a pre-declared identifier. - -For example, in the following piece of code - - func fn() { - println(true) - true := false - println(true) - } - -the pattern - - (Builtin "true") - -will match exactly once, on the first use of 'true' in the function. -Subsequent occurrences of 'true' no longer refer to the pre-declared identifier. - -(Object name) matches an identifier by name, but yields the -types.Object it refers to. - -(Symbol name) matches ast.Idents and ast.SelectorExprs that refer to a symbol with a given fully qualified name. -For example, "net/url.PathEscape" matches the PathEscape function in the net/url package, -and "(net/url.EscapeError).Error" refers to the Error method on the net/url.EscapeError type, -either on an instance of the type, or on the type itself. - -For example, the following patterns match the following lines of code: - - (CallExpr (Symbol "fmt.Println") _) // pattern 1 - (CallExpr (Symbol "(net/url.EscapeError).Error") _) // pattern 2 - - fmt.Println("hello, world") // matches pattern 1 - var x url.EscapeError - x.Error() // matches pattern 2 - (url.EscapeError).Error(x) // also matches pattern 2 - -(Binding name node) creates or uses a binding. -Bindings work like variable assignments, allowing referring to already matched nodes. -As an example, bindings are necessary to match self-assignment of the form "x = x", -since we need to express that the right-hand side is identical to the left-hand side. - -If a binding's node is not nil, the matcher will attempt to match a node according to the pattern. -If a binding's node is nil, the binding will either recall an existing value, or match the Any node. -It is an error to provide a non-nil node to a binding that has already been bound. - -Referring back to the earlier example, the following pattern will match self-assignment of idents: - - (AssignStmt (Binding "lhs" (Ident _)) "=" (Binding "lhs" nil)) - -Because bindings are a crucial component of pattern matching, there is special syntax for creating and recalling bindings. -Lower-case names refer to bindings. If standing on its own, the name "foo" will be equivalent to (Binding "foo" nil). -If a name is followed by an at-sign (@) then it will create a binding for the node that follows. -Together, this allows us to rewrite the earlier example as follows: - - (AssignStmt lhs@(Ident _) "=" lhs) - -(Or nodes...) is a variadic node that tries matching each node until one succeeds. For example, the following pattern matches all idents of name "foo" or "bar": - - (Ident (Or "foo" "bar")) - -We could also have written - - (Or (Ident "foo") (Ident "bar")) - -and achieved the same result. We can also mix different kinds of nodes: - - (Or (Ident "foo") (CallExpr (Ident "bar") _)) - -When using bindings inside of nodes used inside Or, all or none of the bindings will be bound. -That is, partially matched nodes that ultimately failed to match will not produce any bindings observable outside of the matching attempt. -We can thus write - - (Or (Ident name) (CallExpr name)) - -and 'name' will either be a String if the first option matched, or an Ident or SelectorExpr if the second option matched. - -(Not node) - -The Not node negates a match. For example, (Not (Ident _)) will match all nodes that aren't identifiers. - -ChanDir(0) - -# Automatic unnesting of AST nodes - -The Go AST has several types of nodes that wrap other nodes. -To simplify matching, we automatically unwrap some of these nodes. - -These nodes are ExprStmt (for using expressions in a statement context), -ParenExpr (for parenthesized expressions), -DeclStmt (for declarations in a statement context), -and LabeledStmt (for labeled statements). - -Thus, the query - - (FuncLit _ [(CallExpr _ _)] - -will match a function literal containing a single function call, -even though in the actual Go AST, the CallExpr is nested inside an ExprStmt, -as function bodies are made up of sequences of statements. - -On the flip-side, there is no way to specifically match these wrapper nodes. -For example, there is no way of searching for unnecessary parentheses, like in the following piece of Go code: - - ((x)) += 2 -*/ -package pattern diff --git a/vendor/honnef.co/go/tools/pattern/lexer.go b/vendor/honnef.co/go/tools/pattern/lexer.go deleted file mode 100644 index fb72e392b..000000000 --- a/vendor/honnef.co/go/tools/pattern/lexer.go +++ /dev/null @@ -1,221 +0,0 @@ -package pattern - -import ( - "fmt" - "go/token" - "unicode" - "unicode/utf8" -) - -type lexer struct { - f *token.File - - input string - start int - pos int - width int - items chan item -} - -type itemType int - -const eof = -1 - -const ( - itemError itemType = iota - itemLeftParen - itemRightParen - itemLeftBracket - itemRightBracket - itemTypeName - itemVariable - itemAt - itemColon - itemBlank - itemString - itemEOF -) - -func (typ itemType) String() string { - switch typ { - case itemError: - return "ERROR" - case itemLeftParen: - return "(" - case itemRightParen: - return ")" - case itemLeftBracket: - return "[" - case itemRightBracket: - return "]" - case itemTypeName: - return "TYPE" - case itemVariable: - return "VAR" - case itemAt: - return "@" - case itemColon: - return ":" - case itemBlank: - return "_" - case itemString: - return "STRING" - case itemEOF: - return "EOF" - default: - return fmt.Sprintf("itemType(%d)", typ) - } -} - -type item struct { - typ itemType - val string - pos int -} - -type stateFn func(*lexer) stateFn - -func (l *lexer) run() { - for state := lexStart; state != nil; { - state = state(l) - } - close(l.items) -} - -func (l *lexer) emitValue(t itemType, value string) { - l.items <- item{t, value, l.start} - l.start = l.pos -} - -func (l *lexer) emit(t itemType) { - l.items <- item{t, l.input[l.start:l.pos], l.start} - l.start = l.pos -} - -func lexStart(l *lexer) stateFn { - switch r := l.next(); { - case r == eof: - l.emit(itemEOF) - return nil - case unicode.IsSpace(r): - l.ignore() - case r == '(': - l.emit(itemLeftParen) - case r == ')': - l.emit(itemRightParen) - case r == '[': - l.emit(itemLeftBracket) - case r == ']': - l.emit(itemRightBracket) - case r == '@': - l.emit(itemAt) - case r == ':': - l.emit(itemColon) - case r == '_': - l.emit(itemBlank) - case r == '"': - l.backup() - return lexString - case unicode.IsUpper(r): - l.backup() - return lexType - case unicode.IsLower(r): - l.backup() - return lexVariable - default: - return l.errorf("unexpected character %c", r) - } - return lexStart -} - -func (l *lexer) next() (r rune) { - if l.pos >= len(l.input) { - l.width = 0 - return eof - } - r, l.width = utf8.DecodeRuneInString(l.input[l.pos:]) - - if r == '\n' { - l.f.AddLine(l.pos) - } - - l.pos += l.width - - return r -} - -func (l *lexer) ignore() { - l.start = l.pos -} - -func (l *lexer) backup() { - l.pos -= l.width -} - -func (l *lexer) errorf(format string, args ...interface{}) stateFn { - // TODO(dh): emit position information in errors - l.items <- item{ - itemError, - fmt.Sprintf(format, args...), - l.start, - } - return nil -} - -func isAlphaNumeric(r rune) bool { - return r >= '0' && r <= '9' || - r >= 'a' && r <= 'z' || - r >= 'A' && r <= 'Z' -} - -func lexString(l *lexer) stateFn { - l.next() // skip quote - escape := false - - var runes []rune - for { - switch r := l.next(); r { - case eof: - return l.errorf("unterminated string") - case '"': - if !escape { - l.emitValue(itemString, string(runes)) - return lexStart - } else { - runes = append(runes, '"') - escape = false - } - case '\\': - if escape { - runes = append(runes, '\\') - escape = false - } else { - escape = true - } - default: - runes = append(runes, r) - } - } -} - -func lexType(l *lexer) stateFn { - l.next() - for { - if !isAlphaNumeric(l.next()) { - l.backup() - l.emit(itemTypeName) - return lexStart - } - } -} - -func lexVariable(l *lexer) stateFn { - l.next() - for { - if !isAlphaNumeric(l.next()) { - l.backup() - l.emit(itemVariable) - return lexStart - } - } -} diff --git a/vendor/honnef.co/go/tools/pattern/match.go b/vendor/honnef.co/go/tools/pattern/match.go deleted file mode 100644 index 4fb4f8ec6..000000000 --- a/vendor/honnef.co/go/tools/pattern/match.go +++ /dev/null @@ -1,714 +0,0 @@ -package pattern - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "reflect" - - "golang.org/x/tools/go/ast/astutil" -) - -var tokensByString = map[string]Token{ - "INT": Token(token.INT), - "FLOAT": Token(token.FLOAT), - "IMAG": Token(token.IMAG), - "CHAR": Token(token.CHAR), - "STRING": Token(token.STRING), - "+": Token(token.ADD), - "-": Token(token.SUB), - "*": Token(token.MUL), - "/": Token(token.QUO), - "%": Token(token.REM), - "&": Token(token.AND), - "|": Token(token.OR), - "^": Token(token.XOR), - "<<": Token(token.SHL), - ">>": Token(token.SHR), - "&^": Token(token.AND_NOT), - "+=": Token(token.ADD_ASSIGN), - "-=": Token(token.SUB_ASSIGN), - "*=": Token(token.MUL_ASSIGN), - "/=": Token(token.QUO_ASSIGN), - "%=": Token(token.REM_ASSIGN), - "&=": Token(token.AND_ASSIGN), - "|=": Token(token.OR_ASSIGN), - "^=": Token(token.XOR_ASSIGN), - "<<=": Token(token.SHL_ASSIGN), - ">>=": Token(token.SHR_ASSIGN), - "&^=": Token(token.AND_NOT_ASSIGN), - "&&": Token(token.LAND), - "||": Token(token.LOR), - "<-": Token(token.ARROW), - "++": Token(token.INC), - "--": Token(token.DEC), - "==": Token(token.EQL), - "<": Token(token.LSS), - ">": Token(token.GTR), - "=": Token(token.ASSIGN), - "!": Token(token.NOT), - "!=": Token(token.NEQ), - "<=": Token(token.LEQ), - ">=": Token(token.GEQ), - ":=": Token(token.DEFINE), - "...": Token(token.ELLIPSIS), - "IMPORT": Token(token.IMPORT), - "VAR": Token(token.VAR), - "TYPE": Token(token.TYPE), - "CONST": Token(token.CONST), - "BREAK": Token(token.BREAK), - "CONTINUE": Token(token.CONTINUE), - "GOTO": Token(token.GOTO), - "FALLTHROUGH": Token(token.FALLTHROUGH), -} - -func maybeToken(node Node) (Node, bool) { - if node, ok := node.(String); ok { - if tok, ok := tokensByString[string(node)]; ok { - return tok, true - } - return node, false - } - return node, false -} - -func isNil(v interface{}) bool { - if v == nil { - return true - } - if _, ok := v.(Nil); ok { - return true - } - return false -} - -type matcher interface { - Match(*Matcher, interface{}) (interface{}, bool) -} - -type State = map[string]any - -type Matcher struct { - TypesInfo *types.Info - State State - - bindingsMapping []string - - setBindings []uint64 -} - -func (m *Matcher) set(b Binding, value interface{}) { - m.State[b.Name] = value - m.setBindings[len(m.setBindings)-1] |= 1 << b.idx -} - -func (m *Matcher) push() { - m.setBindings = append(m.setBindings, 0) -} - -func (m *Matcher) pop() { - set := m.setBindings[len(m.setBindings)-1] - if set != 0 { - for i := 0; i < len(m.bindingsMapping); i++ { - if (set & (1 << i)) != 0 { - key := m.bindingsMapping[i] - delete(m.State, key) - } - } - } - m.setBindings = m.setBindings[:len(m.setBindings)-1] -} - -func (m *Matcher) merge() { - m.setBindings = m.setBindings[:len(m.setBindings)-1] -} - -func (m *Matcher) Match(a Pattern, b ast.Node) bool { - m.bindingsMapping = a.Bindings - m.State = State{} - m.push() - _, ok := match(m, a.Root, b) - m.merge() - if len(m.setBindings) != 0 { - panic(fmt.Sprintf("%d entries left on the stack, expected none", len(m.setBindings))) - } - return ok -} - -func Match(a Pattern, b ast.Node) (*Matcher, bool) { - m := &Matcher{} - ret := m.Match(a, b) - return m, ret -} - -// Match two items, which may be (Node, AST) or (AST, AST) -func match(m *Matcher, l, r interface{}) (interface{}, bool) { - if _, ok := r.(Node); ok { - panic("Node mustn't be on right side of match") - } - - switch l := l.(type) { - case *ast.ParenExpr: - return match(m, l.X, r) - case *ast.ExprStmt: - return match(m, l.X, r) - case *ast.DeclStmt: - return match(m, l.Decl, r) - case *ast.LabeledStmt: - return match(m, l.Stmt, r) - case *ast.BlockStmt: - return match(m, l.List, r) - case *ast.FieldList: - if l == nil { - return match(m, nil, r) - } else { - return match(m, l.List, r) - } - } - - switch r := r.(type) { - case *ast.ParenExpr: - return match(m, l, r.X) - case *ast.ExprStmt: - return match(m, l, r.X) - case *ast.DeclStmt: - return match(m, l, r.Decl) - case *ast.LabeledStmt: - return match(m, l, r.Stmt) - case *ast.BlockStmt: - if r == nil { - return match(m, l, nil) - } - return match(m, l, r.List) - case *ast.FieldList: - if r == nil { - return match(m, l, nil) - } - return match(m, l, r.List) - case *ast.BasicLit: - if r == nil { - return match(m, l, nil) - } - } - - if l, ok := l.(matcher); ok { - return l.Match(m, r) - } - - if l, ok := l.(Node); ok { - // Matching of pattern with concrete value - return matchNodeAST(m, l, r) - } - - if l == nil || r == nil { - return nil, l == r - } - - { - ln, ok1 := l.(ast.Node) - rn, ok2 := r.(ast.Node) - if ok1 && ok2 { - return matchAST(m, ln, rn) - } - } - - { - obj, ok := l.(types.Object) - if ok { - switch r := r.(type) { - case *ast.Ident: - return obj, obj == m.TypesInfo.ObjectOf(r) - case *ast.SelectorExpr: - return obj, obj == m.TypesInfo.ObjectOf(r.Sel) - default: - return obj, false - } - } - } - - // TODO(dh): the three blocks handling slices can be combined into a single block if we use reflection - - { - ln, ok1 := l.([]ast.Expr) - rn, ok2 := r.([]ast.Expr) - if ok1 || ok2 { - if ok1 && !ok2 { - cast, ok := r.(ast.Expr) - if !ok { - return nil, false - } - rn = []ast.Expr{cast} - } else if !ok1 && ok2 { - cast, ok := l.(ast.Expr) - if !ok { - return nil, false - } - ln = []ast.Expr{cast} - } - - if len(ln) != len(rn) { - return nil, false - } - for i, ll := range ln { - if _, ok := match(m, ll, rn[i]); !ok { - return nil, false - } - } - return r, true - } - } - - { - ln, ok1 := l.([]ast.Stmt) - rn, ok2 := r.([]ast.Stmt) - if ok1 || ok2 { - if ok1 && !ok2 { - cast, ok := r.(ast.Stmt) - if !ok { - return nil, false - } - rn = []ast.Stmt{cast} - } else if !ok1 && ok2 { - cast, ok := l.(ast.Stmt) - if !ok { - return nil, false - } - ln = []ast.Stmt{cast} - } - - if len(ln) != len(rn) { - return nil, false - } - for i, ll := range ln { - if _, ok := match(m, ll, rn[i]); !ok { - return nil, false - } - } - return r, true - } - } - - { - ln, ok1 := l.([]*ast.Field) - rn, ok2 := r.([]*ast.Field) - if ok1 || ok2 { - if ok1 && !ok2 { - cast, ok := r.(*ast.Field) - if !ok { - return nil, false - } - rn = []*ast.Field{cast} - } else if !ok1 && ok2 { - cast, ok := l.(*ast.Field) - if !ok { - return nil, false - } - ln = []*ast.Field{cast} - } - - if len(ln) != len(rn) { - return nil, false - } - for i, ll := range ln { - if _, ok := match(m, ll, rn[i]); !ok { - return nil, false - } - } - return r, true - } - } - - return nil, false -} - -// Match a Node with an AST node -func matchNodeAST(m *Matcher, a Node, b interface{}) (interface{}, bool) { - switch b := b.(type) { - case []ast.Stmt: - // 'a' is not a List or we'd be using its Match - // implementation. - - if len(b) != 1 { - return nil, false - } - return match(m, a, b[0]) - case []ast.Expr: - // 'a' is not a List or we'd be using its Match - // implementation. - - if len(b) != 1 { - return nil, false - } - return match(m, a, b[0]) - case []*ast.Field: - // 'a' is not a List or we'd be using its Match - // implementation - if len(b) != 1 { - return nil, false - } - return match(m, a, b[0]) - case ast.Node: - ra := reflect.ValueOf(a) - rb := reflect.ValueOf(b).Elem() - - if ra.Type().Name() != rb.Type().Name() { - return nil, false - } - - for i := 0; i < ra.NumField(); i++ { - af := ra.Field(i) - fieldName := ra.Type().Field(i).Name - bf := rb.FieldByName(fieldName) - if (bf == reflect.Value{}) { - panic(fmt.Sprintf("internal error: could not find field %s in type %t when comparing with %T", fieldName, b, a)) - } - ai := af.Interface() - bi := bf.Interface() - if ai == nil { - return b, bi == nil - } - if _, ok := match(m, ai.(Node), bi); !ok { - return b, false - } - } - return b, true - case nil: - return nil, a == Nil{} - case string, token.Token: - // 'a' can't be a String, Token, or Binding or we'd be using their Match implementations. - return nil, false - default: - panic(fmt.Sprintf("unhandled type %T", b)) - } -} - -// Match two AST nodes -func matchAST(m *Matcher, a, b ast.Node) (interface{}, bool) { - ra := reflect.ValueOf(a) - rb := reflect.ValueOf(b) - - if ra.Type() != rb.Type() { - return nil, false - } - if ra.IsNil() || rb.IsNil() { - return rb, ra.IsNil() == rb.IsNil() - } - - ra = ra.Elem() - rb = rb.Elem() - for i := 0; i < ra.NumField(); i++ { - af := ra.Field(i) - bf := rb.Field(i) - if af.Type() == rtTokPos || af.Type() == rtObject || af.Type() == rtCommentGroup { - continue - } - - switch af.Kind() { - case reflect.Slice: - if af.Len() != bf.Len() { - return nil, false - } - for j := 0; j < af.Len(); j++ { - if _, ok := match(m, af.Index(j).Interface().(ast.Node), bf.Index(j).Interface().(ast.Node)); !ok { - return nil, false - } - } - case reflect.String: - if af.String() != bf.String() { - return nil, false - } - case reflect.Int: - if af.Int() != bf.Int() { - return nil, false - } - case reflect.Bool: - if af.Bool() != bf.Bool() { - return nil, false - } - case reflect.Ptr, reflect.Interface: - if _, ok := match(m, af.Interface(), bf.Interface()); !ok { - return nil, false - } - default: - panic(fmt.Sprintf("internal error: unhandled kind %s (%T)", af.Kind(), af.Interface())) - } - } - return b, true -} - -func (b Binding) Match(m *Matcher, node interface{}) (interface{}, bool) { - if isNil(b.Node) { - v, ok := m.State[b.Name] - if ok { - // Recall value - return match(m, v, node) - } - // Matching anything - b.Node = Any{} - } - - // Store value - if _, ok := m.State[b.Name]; ok { - panic(fmt.Sprintf("binding already created: %s", b.Name)) - } - new, ret := match(m, b.Node, node) - if ret { - m.set(b, new) - } - return new, ret -} - -func (Any) Match(m *Matcher, node interface{}) (interface{}, bool) { - return node, true -} - -func (l List) Match(m *Matcher, node interface{}) (interface{}, bool) { - v := reflect.ValueOf(node) - if v.Kind() == reflect.Slice { - if isNil(l.Head) { - return node, v.Len() == 0 - } - if v.Len() == 0 { - return nil, false - } - // OPT(dh): don't check the entire tail if head didn't match - _, ok1 := match(m, l.Head, v.Index(0).Interface()) - _, ok2 := match(m, l.Tail, v.Slice(1, v.Len()).Interface()) - return node, ok1 && ok2 - } - // Our empty list does not equal an untyped Go nil. This way, we can - // tell apart an if with no else and an if with an empty else. - return nil, false -} - -func (s String) Match(m *Matcher, node interface{}) (interface{}, bool) { - switch o := node.(type) { - case token.Token: - if tok, ok := maybeToken(s); ok { - return match(m, tok, node) - } - return nil, false - case string: - return o, string(s) == o - case types.TypeAndValue: - return o, o.Value != nil && o.Value.String() == string(s) - default: - return nil, false - } -} - -func (tok Token) Match(m *Matcher, node interface{}) (interface{}, bool) { - o, ok := node.(token.Token) - if !ok { - return nil, false - } - return o, token.Token(tok) == o -} - -func (Nil) Match(m *Matcher, node interface{}) (interface{}, bool) { - if isNil(node) { - return nil, true - } - v := reflect.ValueOf(node) - switch v.Kind() { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice: - return nil, v.IsNil() - default: - return nil, false - } -} - -func (builtin Builtin) Match(m *Matcher, node interface{}) (interface{}, bool) { - r, ok := match(m, Ident(builtin), node) - if !ok { - return nil, false - } - ident := r.(*ast.Ident) - obj := m.TypesInfo.ObjectOf(ident) - if obj != types.Universe.Lookup(ident.Name) { - return nil, false - } - return ident, true -} - -func (obj Object) Match(m *Matcher, node interface{}) (interface{}, bool) { - r, ok := match(m, Ident(obj), node) - if !ok { - return nil, false - } - ident := r.(*ast.Ident) - - id := m.TypesInfo.ObjectOf(ident) - _, ok = match(m, obj.Name, ident.Name) - return id, ok -} - -func (fn Symbol) Match(m *Matcher, node interface{}) (interface{}, bool) { - var name string - var obj types.Object - - base := []Node{ - Ident{Any{}}, - SelectorExpr{Any{}, Any{}}, - } - p := Or{ - Nodes: append(base, - IndexExpr{Or{Nodes: base}, Any{}}, - IndexListExpr{Or{Nodes: base}, Any{}})} - - r, ok := match(m, p, node) - if !ok { - return nil, false - } - - fun := r.(ast.Expr) - switch idx := fun.(type) { - case *ast.IndexExpr: - fun = idx.X - case *ast.IndexListExpr: - fun = idx.X - } - fun = astutil.Unparen(fun) - - switch fun := fun.(type) { - case *ast.Ident: - obj = m.TypesInfo.ObjectOf(fun) - case *ast.SelectorExpr: - obj = m.TypesInfo.ObjectOf(fun.Sel) - default: - panic("unreachable") - } - switch obj := obj.(type) { - case *types.Func: - // OPT(dh): optimize this similar to code.FuncName - name = obj.FullName() - case *types.Builtin: - name = obj.Name() - case *types.TypeName: - origObj := obj - for { - if obj.Parent() != obj.Pkg().Scope() { - return nil, false - } - name = types.TypeString(obj.Type(), nil) - _, ok = match(m, fn.Name, name) - if ok || !obj.IsAlias() { - return origObj, ok - } else { - // FIXME(dh): we should peel away one layer of alias at a time; this is blocked on - // github.com/golang/go/issues/66559 - switch typ := types.Unalias(obj.Type()).(type) { - case interface{ Obj() *types.TypeName }: - obj = typ.Obj() - case *types.Basic: - return match(m, fn.Name, typ.Name()) - default: - return nil, false - } - } - } - case *types.Const, *types.Var: - if obj.Pkg() == nil { - return nil, false - } - if obj.Parent() != obj.Pkg().Scope() { - return nil, false - } - name = fmt.Sprintf("%s.%s", obj.Pkg().Path(), obj.Name()) - default: - return nil, false - } - - _, ok = match(m, fn.Name, name) - return obj, ok -} - -func (or Or) Match(m *Matcher, node interface{}) (interface{}, bool) { - for _, opt := range or.Nodes { - m.push() - if ret, ok := match(m, opt, node); ok { - m.merge() - return ret, true - } else { - m.pop() - } - } - return nil, false -} - -func (not Not) Match(m *Matcher, node interface{}) (interface{}, bool) { - _, ok := match(m, not.Node, node) - if ok { - return nil, false - } - return node, true -} - -var integerLiteralQ = MustParse(`(Or (BasicLit "INT" _) (UnaryExpr (Or "+" "-") (IntegerLiteral _)))`) - -func (lit IntegerLiteral) Match(m *Matcher, node interface{}) (interface{}, bool) { - matched, ok := match(m, integerLiteralQ.Root, node) - if !ok { - return nil, false - } - tv, ok := m.TypesInfo.Types[matched.(ast.Expr)] - if !ok { - return nil, false - } - if tv.Value == nil { - return nil, false - } - _, ok = match(m, lit.Value, tv) - return matched, ok -} - -func (texpr TrulyConstantExpression) Match(m *Matcher, node interface{}) (interface{}, bool) { - expr, ok := node.(ast.Expr) - if !ok { - return nil, false - } - tv, ok := m.TypesInfo.Types[expr] - if !ok { - return nil, false - } - if tv.Value == nil { - return nil, false - } - truly := true - ast.Inspect(expr, func(node ast.Node) bool { - if _, ok := node.(*ast.Ident); ok { - truly = false - return false - } - return true - }) - if !truly { - return nil, false - } - _, ok = match(m, texpr.Value, tv) - return expr, ok -} - -var ( - // Types of fields in go/ast structs that we want to skip - rtTokPos = reflect.TypeOf(token.Pos(0)) - rtObject = reflect.TypeOf((*ast.Object)(nil)) - rtCommentGroup = reflect.TypeOf((*ast.CommentGroup)(nil)) -) - -var ( - _ matcher = Binding{} - _ matcher = Any{} - _ matcher = List{} - _ matcher = String("") - _ matcher = Token(0) - _ matcher = Nil{} - _ matcher = Builtin{} - _ matcher = Object{} - _ matcher = Symbol{} - _ matcher = Or{} - _ matcher = Not{} - _ matcher = IntegerLiteral{} - _ matcher = TrulyConstantExpression{} -) diff --git a/vendor/honnef.co/go/tools/pattern/parser.go b/vendor/honnef.co/go/tools/pattern/parser.go deleted file mode 100644 index ba0897524..000000000 --- a/vendor/honnef.co/go/tools/pattern/parser.go +++ /dev/null @@ -1,526 +0,0 @@ -package pattern - -import ( - "errors" - "fmt" - "go/ast" - "go/token" - "reflect" -) - -type Pattern struct { - Root Node - // Relevant contains instances of ast.Node that could potentially - // initiate a successful match of the pattern. - Relevant map[reflect.Type]struct{} - - // Mapping from binding index to binding name - Bindings []string -} - -func MustParse(s string) Pattern { - p := &Parser{AllowTypeInfo: true} - pat, err := p.Parse(s) - if err != nil { - panic(err) - } - return pat -} - -func roots(node Node, m map[reflect.Type]struct{}) { - switch node := node.(type) { - case Or: - for _, el := range node.Nodes { - roots(el, m) - } - case Not: - roots(node.Node, m) - case Binding: - roots(node.Node, m) - case Nil, nil: - // this branch is reached via bindings - for _, T := range allTypes { - m[T] = struct{}{} - } - default: - Ts, ok := nodeToASTTypes[reflect.TypeOf(node)] - if !ok { - panic(fmt.Sprintf("internal error: unhandled type %T", node)) - } - for _, T := range Ts { - m[T] = struct{}{} - } - } -} - -var allTypes = []reflect.Type{ - reflect.TypeOf((*ast.RangeStmt)(nil)), - reflect.TypeOf((*ast.AssignStmt)(nil)), - reflect.TypeOf((*ast.IndexExpr)(nil)), - reflect.TypeOf((*ast.Ident)(nil)), - reflect.TypeOf((*ast.ValueSpec)(nil)), - reflect.TypeOf((*ast.GenDecl)(nil)), - reflect.TypeOf((*ast.BinaryExpr)(nil)), - reflect.TypeOf((*ast.ForStmt)(nil)), - reflect.TypeOf((*ast.ArrayType)(nil)), - reflect.TypeOf((*ast.DeferStmt)(nil)), - reflect.TypeOf((*ast.MapType)(nil)), - reflect.TypeOf((*ast.ReturnStmt)(nil)), - reflect.TypeOf((*ast.SliceExpr)(nil)), - reflect.TypeOf((*ast.StarExpr)(nil)), - reflect.TypeOf((*ast.UnaryExpr)(nil)), - reflect.TypeOf((*ast.SendStmt)(nil)), - reflect.TypeOf((*ast.SelectStmt)(nil)), - reflect.TypeOf((*ast.ImportSpec)(nil)), - reflect.TypeOf((*ast.IfStmt)(nil)), - reflect.TypeOf((*ast.GoStmt)(nil)), - reflect.TypeOf((*ast.Field)(nil)), - reflect.TypeOf((*ast.SelectorExpr)(nil)), - reflect.TypeOf((*ast.StructType)(nil)), - reflect.TypeOf((*ast.KeyValueExpr)(nil)), - reflect.TypeOf((*ast.FuncType)(nil)), - reflect.TypeOf((*ast.FuncLit)(nil)), - reflect.TypeOf((*ast.FuncDecl)(nil)), - reflect.TypeOf((*ast.ChanType)(nil)), - reflect.TypeOf((*ast.CallExpr)(nil)), - reflect.TypeOf((*ast.CaseClause)(nil)), - reflect.TypeOf((*ast.CommClause)(nil)), - reflect.TypeOf((*ast.CompositeLit)(nil)), - reflect.TypeOf((*ast.EmptyStmt)(nil)), - reflect.TypeOf((*ast.SwitchStmt)(nil)), - reflect.TypeOf((*ast.TypeSwitchStmt)(nil)), - reflect.TypeOf((*ast.TypeAssertExpr)(nil)), - reflect.TypeOf((*ast.TypeSpec)(nil)), - reflect.TypeOf((*ast.InterfaceType)(nil)), - reflect.TypeOf((*ast.BranchStmt)(nil)), - reflect.TypeOf((*ast.IncDecStmt)(nil)), - reflect.TypeOf((*ast.BasicLit)(nil)), -} - -var nodeToASTTypes = map[reflect.Type][]reflect.Type{ - reflect.TypeOf(String("")): nil, - reflect.TypeOf(Token(0)): nil, - reflect.TypeOf(List{}): {reflect.TypeOf((*ast.BlockStmt)(nil)), reflect.TypeOf((*ast.FieldList)(nil))}, - reflect.TypeOf(Builtin{}): {reflect.TypeOf((*ast.Ident)(nil))}, - reflect.TypeOf(Object{}): {reflect.TypeOf((*ast.Ident)(nil))}, - reflect.TypeOf(Symbol{}): {reflect.TypeOf((*ast.Ident)(nil)), reflect.TypeOf((*ast.SelectorExpr)(nil))}, - reflect.TypeOf(Any{}): allTypes, - reflect.TypeOf(RangeStmt{}): {reflect.TypeOf((*ast.RangeStmt)(nil))}, - reflect.TypeOf(AssignStmt{}): {reflect.TypeOf((*ast.AssignStmt)(nil))}, - reflect.TypeOf(IndexExpr{}): {reflect.TypeOf((*ast.IndexExpr)(nil))}, - reflect.TypeOf(Ident{}): {reflect.TypeOf((*ast.Ident)(nil))}, - reflect.TypeOf(ValueSpec{}): {reflect.TypeOf((*ast.ValueSpec)(nil))}, - reflect.TypeOf(GenDecl{}): {reflect.TypeOf((*ast.GenDecl)(nil))}, - reflect.TypeOf(BinaryExpr{}): {reflect.TypeOf((*ast.BinaryExpr)(nil))}, - reflect.TypeOf(ForStmt{}): {reflect.TypeOf((*ast.ForStmt)(nil))}, - reflect.TypeOf(ArrayType{}): {reflect.TypeOf((*ast.ArrayType)(nil))}, - reflect.TypeOf(DeferStmt{}): {reflect.TypeOf((*ast.DeferStmt)(nil))}, - reflect.TypeOf(MapType{}): {reflect.TypeOf((*ast.MapType)(nil))}, - reflect.TypeOf(ReturnStmt{}): {reflect.TypeOf((*ast.ReturnStmt)(nil))}, - reflect.TypeOf(SliceExpr{}): {reflect.TypeOf((*ast.SliceExpr)(nil))}, - reflect.TypeOf(StarExpr{}): {reflect.TypeOf((*ast.StarExpr)(nil))}, - reflect.TypeOf(UnaryExpr{}): {reflect.TypeOf((*ast.UnaryExpr)(nil))}, - reflect.TypeOf(SendStmt{}): {reflect.TypeOf((*ast.SendStmt)(nil))}, - reflect.TypeOf(SelectStmt{}): {reflect.TypeOf((*ast.SelectStmt)(nil))}, - reflect.TypeOf(ImportSpec{}): {reflect.TypeOf((*ast.ImportSpec)(nil))}, - reflect.TypeOf(IfStmt{}): {reflect.TypeOf((*ast.IfStmt)(nil))}, - reflect.TypeOf(GoStmt{}): {reflect.TypeOf((*ast.GoStmt)(nil))}, - reflect.TypeOf(Field{}): {reflect.TypeOf((*ast.Field)(nil))}, - reflect.TypeOf(SelectorExpr{}): {reflect.TypeOf((*ast.SelectorExpr)(nil))}, - reflect.TypeOf(StructType{}): {reflect.TypeOf((*ast.StructType)(nil))}, - reflect.TypeOf(KeyValueExpr{}): {reflect.TypeOf((*ast.KeyValueExpr)(nil))}, - reflect.TypeOf(FuncType{}): {reflect.TypeOf((*ast.FuncType)(nil))}, - reflect.TypeOf(FuncLit{}): {reflect.TypeOf((*ast.FuncLit)(nil))}, - reflect.TypeOf(FuncDecl{}): {reflect.TypeOf((*ast.FuncDecl)(nil))}, - reflect.TypeOf(ChanType{}): {reflect.TypeOf((*ast.ChanType)(nil))}, - reflect.TypeOf(CallExpr{}): {reflect.TypeOf((*ast.CallExpr)(nil))}, - reflect.TypeOf(CaseClause{}): {reflect.TypeOf((*ast.CaseClause)(nil))}, - reflect.TypeOf(CommClause{}): {reflect.TypeOf((*ast.CommClause)(nil))}, - reflect.TypeOf(CompositeLit{}): {reflect.TypeOf((*ast.CompositeLit)(nil))}, - reflect.TypeOf(EmptyStmt{}): {reflect.TypeOf((*ast.EmptyStmt)(nil))}, - reflect.TypeOf(SwitchStmt{}): {reflect.TypeOf((*ast.SwitchStmt)(nil))}, - reflect.TypeOf(TypeSwitchStmt{}): {reflect.TypeOf((*ast.TypeSwitchStmt)(nil))}, - reflect.TypeOf(TypeAssertExpr{}): {reflect.TypeOf((*ast.TypeAssertExpr)(nil))}, - reflect.TypeOf(TypeSpec{}): {reflect.TypeOf((*ast.TypeSpec)(nil))}, - reflect.TypeOf(InterfaceType{}): {reflect.TypeOf((*ast.InterfaceType)(nil))}, - reflect.TypeOf(BranchStmt{}): {reflect.TypeOf((*ast.BranchStmt)(nil))}, - reflect.TypeOf(IncDecStmt{}): {reflect.TypeOf((*ast.IncDecStmt)(nil))}, - reflect.TypeOf(BasicLit{}): {reflect.TypeOf((*ast.BasicLit)(nil))}, - reflect.TypeOf(IntegerLiteral{}): {reflect.TypeOf((*ast.BasicLit)(nil)), reflect.TypeOf((*ast.UnaryExpr)(nil))}, - reflect.TypeOf(TrulyConstantExpression{}): allTypes, // this is an over-approximation, which is fine -} - -var requiresTypeInfo = map[string]bool{ - "Symbol": true, - "Builtin": true, - "Object": true, - "IntegerLiteral": true, - "TrulyConstantExpression": true, -} - -type Parser struct { - // Allow nodes that rely on type information - AllowTypeInfo bool - - lex *lexer - cur item - last *item - items chan item - - bindings map[string]int -} - -func (p *Parser) bindingIndex(name string) int { - if p.bindings == nil { - p.bindings = map[string]int{} - } - if idx, ok := p.bindings[name]; ok { - return idx - } - idx := len(p.bindings) - p.bindings[name] = idx - return idx -} - -func (p *Parser) Parse(s string) (Pattern, error) { - p.cur = item{} - p.last = nil - p.items = nil - - fset := token.NewFileSet() - p.lex = &lexer{ - f: fset.AddFile("

    ") - } - p.text(out, x.Text) - out.WriteString("\n") - - case *Heading: - out.WriteString("") - p.text(out, x.Text) - out.WriteString("\n") - - case *Code: - out.WriteString("

    ")
    -		p.escape(out, x.Text)
    -		out.WriteString("
    \n") - - case *List: - kind := "ol>\n" - if x.Items[0].Number == "" { - kind = "ul>\n" - } - out.WriteString("<") - out.WriteString(kind) - next := "1" - for _, item := range x.Items { - out.WriteString("") - p.tight = !x.BlankBetween() - for _, blk := range item.Content { - p.block(out, blk) - } - p.tight = false - } - out.WriteString("= 0; i-- { - if b[i] < '9' { - b[i]++ - return string(b) - } - b[i] = '0' - } - return "1" + string(b) -} - -// text prints the text sequence x to out. -func (p *htmlPrinter) text(out *bytes.Buffer, x []Text) { - for _, t := range x { - switch t := t.(type) { - case Plain: - p.escape(out, string(t)) - case Italic: - out.WriteString("") - p.escape(out, string(t)) - out.WriteString("") - case *Link: - out.WriteString(``) - p.text(out, t.Text) - out.WriteString("") - case *DocLink: - url := p.docLinkURL(t) - if url != "" { - out.WriteString(``) - } - p.text(out, t.Text) - if url != "" { - out.WriteString("") - } - } - } -} - -// escape prints s to out as plain text, -// escaping < & " ' and > to avoid being misinterpreted -// in larger HTML constructs. -func (p *htmlPrinter) escape(out *bytes.Buffer, s string) { - start := 0 - for i := 0; i < len(s); i++ { - switch s[i] { - case '<': - out.WriteString(s[start:i]) - out.WriteString("<") - start = i + 1 - case '&': - out.WriteString(s[start:i]) - out.WriteString("&") - start = i + 1 - case '"': - out.WriteString(s[start:i]) - out.WriteString(""") - start = i + 1 - case '\'': - out.WriteString(s[start:i]) - out.WriteString("'") - start = i + 1 - case '>': - out.WriteString(s[start:i]) - out.WriteString(">") - start = i + 1 - } - } - out.WriteString(s[start:]) -} diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/markdown.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/markdown.go deleted file mode 100644 index d8550f2e3..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/markdown.go +++ /dev/null @@ -1,188 +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 comment - -import ( - "bytes" - "fmt" - "strings" -) - -// An mdPrinter holds the state needed for printing a Doc as Markdown. -type mdPrinter struct { - *Printer - headingPrefix string - raw bytes.Buffer -} - -// Markdown returns a Markdown formatting of the Doc. -// See the [Printer] documentation for ways to customize the Markdown output. -func (p *Printer) Markdown(d *Doc) []byte { - mp := &mdPrinter{ - Printer: p, - headingPrefix: strings.Repeat("#", p.headingLevel()) + " ", - } - - var out bytes.Buffer - for i, x := range d.Content { - if i > 0 { - out.WriteByte('\n') - } - mp.block(&out, x) - } - return out.Bytes() -} - -// block prints the block x to out. -func (p *mdPrinter) block(out *bytes.Buffer, x Block) { - switch x := x.(type) { - default: - fmt.Fprintf(out, "?%T", x) - - case *Paragraph: - p.text(out, x.Text) - out.WriteString("\n") - - case *Heading: - out.WriteString(p.headingPrefix) - p.text(out, x.Text) - if id := p.headingID(x); id != "" { - out.WriteString(" {#") - out.WriteString(id) - out.WriteString("}") - } - out.WriteString("\n") - - case *Code: - md := x.Text - for md != "" { - var line string - line, md, _ = strings.Cut(md, "\n") - if line != "" { - out.WriteString("\t") - out.WriteString(line) - } - out.WriteString("\n") - } - - case *List: - loose := x.BlankBetween() - for i, item := range x.Items { - if i > 0 && loose { - out.WriteString("\n") - } - if n := item.Number; n != "" { - out.WriteString(" ") - out.WriteString(n) - out.WriteString(". ") - } else { - out.WriteString(" - ") // SP SP - SP - } - for i, blk := range item.Content { - const fourSpace = " " - if i > 0 { - out.WriteString("\n" + fourSpace) - } - p.text(out, blk.(*Paragraph).Text) - out.WriteString("\n") - } - } - } -} - -// text prints the text sequence x to out. -func (p *mdPrinter) text(out *bytes.Buffer, x []Text) { - p.raw.Reset() - p.rawText(&p.raw, x) - line := bytes.TrimSpace(p.raw.Bytes()) - if len(line) == 0 { - return - } - switch line[0] { - case '+', '-', '*', '#': - // Escape what would be the start of an unordered list or heading. - out.WriteByte('\\') - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - i := 1 - for i < len(line) && '0' <= line[i] && line[i] <= '9' { - i++ - } - if i < len(line) && (line[i] == '.' || line[i] == ')') { - // Escape what would be the start of an ordered list. - out.Write(line[:i]) - out.WriteByte('\\') - line = line[i:] - } - } - out.Write(line) -} - -// rawText prints the text sequence x to out, -// without worrying about escaping characters -// that have special meaning at the start of a Markdown line. -func (p *mdPrinter) rawText(out *bytes.Buffer, x []Text) { - for _, t := range x { - switch t := t.(type) { - case Plain: - p.escape(out, string(t)) - case Italic: - out.WriteString("*") - p.escape(out, string(t)) - out.WriteString("*") - case *Link: - out.WriteString("[") - p.rawText(out, t.Text) - out.WriteString("](") - out.WriteString(t.URL) - out.WriteString(")") - case *DocLink: - url := p.docLinkURL(t) - if url != "" { - out.WriteString("[") - } - p.rawText(out, t.Text) - if url != "" { - out.WriteString("](") - url = strings.ReplaceAll(url, "(", "%28") - url = strings.ReplaceAll(url, ")", "%29") - out.WriteString(url) - out.WriteString(")") - } - } - } -} - -// escape prints s to out as plain text, -// escaping special characters to avoid being misinterpreted -// as Markdown markup sequences. -func (p *mdPrinter) escape(out *bytes.Buffer, s string) { - start := 0 - for i := 0; i < len(s); i++ { - switch s[i] { - case '\n': - // Turn all \n into spaces, for a few reasons: - // - Avoid introducing paragraph breaks accidentally. - // - Avoid the need to reindent after the newline. - // - Avoid problems with Markdown renderers treating - // every mid-paragraph newline as a
    . - out.WriteString(s[start:i]) - out.WriteByte(' ') - start = i + 1 - continue - case '`', '_', '*', '[', '<', '\\': - // Not all of these need to be escaped all the time, - // but is valid and easy to do so. - // We assume the Markdown is being passed to a - // Markdown renderer, not edited by a person, - // so it's fine to have escapes that are not strictly - // necessary in some cases. - out.WriteString(s[start:i]) - out.WriteByte('\\') - out.WriteByte(s[i]) - start = i + 1 - } - } - out.WriteString(s[start:]) -} diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/parse.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/parse.go deleted file mode 100644 index bd42c55ec..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/parse.go +++ /dev/null @@ -1,1260 +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 comment - -import ( - "slices" - "strings" - "unicode" - "unicode/utf8" -) - -// A Doc is a parsed Go doc comment. -type Doc struct { - // Content is the sequence of content blocks in the comment. - Content []Block - - // Links is the link definitions in the comment. - Links []*LinkDef -} - -// A LinkDef is a single link definition. -type LinkDef struct { - Text string // the link text - URL string // the link URL - Used bool // whether the comment uses the definition -} - -// A Block is block-level content in a doc comment, -// one of [*Code], [*Heading], [*List], or [*Paragraph]. -type Block interface { - block() -} - -// A Heading is a doc comment heading. -type Heading struct { - Text []Text // the heading text -} - -func (*Heading) block() {} - -// A List is a numbered or bullet list. -// Lists are always non-empty: len(Items) > 0. -// In a numbered list, every Items[i].Number is a non-empty string. -// In a bullet list, every Items[i].Number is an empty string. -type List struct { - // Items is the list items. - Items []*ListItem - - // ForceBlankBefore indicates that the list must be - // preceded by a blank line when reformatting the comment, - // overriding the usual conditions. See the BlankBefore method. - // - // The comment parser sets ForceBlankBefore for any list - // that is preceded by a blank line, to make sure - // the blank line is preserved when printing. - ForceBlankBefore bool - - // ForceBlankBetween indicates that list items must be - // separated by blank lines when reformatting the comment, - // overriding the usual conditions. See the BlankBetween method. - // - // The comment parser sets ForceBlankBetween for any list - // that has a blank line between any two of its items, to make sure - // the blank lines are preserved when printing. - ForceBlankBetween bool -} - -func (*List) block() {} - -// BlankBefore reports whether a reformatting of the comment -// should include a blank line before the list. -// The default rule is the same as for [BlankBetween]: -// if the list item content contains any blank lines -// (meaning at least one item has multiple paragraphs) -// then the list itself must be preceded by a blank line. -// A preceding blank line can be forced by setting [List].ForceBlankBefore. -func (l *List) BlankBefore() bool { - return l.ForceBlankBefore || l.BlankBetween() -} - -// BlankBetween reports whether a reformatting of the comment -// should include a blank line between each pair of list items. -// The default rule is that if the list item content contains any blank lines -// (meaning at least one item has multiple paragraphs) -// then list items must themselves be separated by blank lines. -// Blank line separators can be forced by setting [List].ForceBlankBetween. -func (l *List) BlankBetween() bool { - if l.ForceBlankBetween { - return true - } - for _, item := range l.Items { - if len(item.Content) != 1 { - // Unreachable for parsed comments today, - // since the only way to get multiple item.Content - // is multiple paragraphs, which must have been - // separated by a blank line. - return true - } - } - return false -} - -// A ListItem is a single item in a numbered or bullet list. -type ListItem struct { - // Number is a decimal string in a numbered list - // or an empty string in a bullet list. - Number string // "1", "2", ...; "" for bullet list - - // Content is the list content. - // Currently, restrictions in the parser and printer - // require every element of Content to be a *Paragraph. - Content []Block // Content of this item. -} - -// A Paragraph is a paragraph of text. -type Paragraph struct { - Text []Text -} - -func (*Paragraph) block() {} - -// A Code is a preformatted code block. -type Code struct { - // Text is the preformatted text, ending with a newline character. - // It may be multiple lines, each of which ends with a newline character. - // It is never empty, nor does it start or end with a blank line. - Text string -} - -func (*Code) block() {} - -// A Text is text-level content in a doc comment, -// one of [Plain], [Italic], [*Link], or [*DocLink]. -type Text interface { - text() -} - -// A Plain is a string rendered as plain text (not italicized). -type Plain string - -func (Plain) text() {} - -// An Italic is a string rendered as italicized text. -type Italic string - -func (Italic) text() {} - -// A Link is a link to a specific URL. -type Link struct { - Auto bool // is this an automatic (implicit) link of a literal URL? - Text []Text // text of link - URL string // target URL of link -} - -func (*Link) text() {} - -// A DocLink is a link to documentation for a Go package or symbol. -type DocLink struct { - Text []Text // text of link - - // ImportPath, Recv, and Name identify the Go package or symbol - // that is the link target. The potential combinations of - // non-empty fields are: - // - ImportPath: a link to another package - // - ImportPath, Name: a link to a const, func, type, or var in another package - // - ImportPath, Recv, Name: a link to a method in another package - // - Name: a link to a const, func, type, or var in this package - // - Recv, Name: a link to a method in this package - ImportPath string // import path - Recv string // receiver type, without any pointer star, for methods - Name string // const, func, type, var, or method name -} - -func (*DocLink) text() {} - -// A Parser is a doc comment parser. -// The fields in the struct can be filled in before calling [Parser.Parse] -// in order to customize the details of the parsing process. -type Parser struct { - // Words is a map of Go identifier words that - // should be italicized and potentially linked. - // If Words[w] is the empty string, then the word w - // is only italicized. Otherwise it is linked, using - // Words[w] as the link target. - // Words corresponds to the [go/doc.ToHTML] words parameter. - Words map[string]string - - // LookupPackage resolves a package name to an import path. - // - // If LookupPackage(name) returns ok == true, then [name] - // (or [name.Sym] or [name.Sym.Method]) - // is considered a documentation link to importPath's package docs. - // It is valid to return "", true, in which case name is considered - // to refer to the current package. - // - // If LookupPackage(name) returns ok == false, - // then [name] (or [name.Sym] or [name.Sym.Method]) - // will not be considered a documentation link, - // except in the case where name is the full (but single-element) import path - // of a package in the standard library, such as in [math] or [io.Reader]. - // LookupPackage is still called for such names, - // in order to permit references to imports of other packages - // with the same package names. - // - // Setting LookupPackage to nil is equivalent to setting it to - // a function that always returns "", false. - LookupPackage func(name string) (importPath string, ok bool) - - // LookupSym reports whether a symbol name or method name - // exists in the current package. - // - // If LookupSym("", "Name") returns true, then [Name] - // is considered a documentation link for a const, func, type, or var. - // - // Similarly, if LookupSym("Recv", "Name") returns true, - // then [Recv.Name] is considered a documentation link for - // type Recv's method Name. - // - // Setting LookupSym to nil is equivalent to setting it to a function - // that always returns false. - LookupSym func(recv, name string) (ok bool) -} - -// parseDoc is parsing state for a single doc comment. -type parseDoc struct { - *Parser - *Doc - links map[string]*LinkDef - lines []string - lookupSym func(recv, name string) bool -} - -// lookupPkg is called to look up the pkg in [pkg], [pkg.Name], and [pkg.Name.Recv]. -// If pkg has a slash, it is assumed to be the full import path and is returned with ok = true. -// -// Otherwise, pkg is probably a simple package name like "rand" (not "crypto/rand" or "math/rand"). -// d.LookupPackage provides a way for the caller to allow resolving such names with reference -// to the imports in the surrounding package. -// -// There is one collision between these two cases: single-element standard library names -// like "math" are full import paths but don't contain slashes. We let d.LookupPackage have -// the first chance to resolve it, in case there's a different package imported as math, -// and otherwise we refer to a built-in list of single-element standard library package names. -func (d *parseDoc) lookupPkg(pkg string) (importPath string, ok bool) { - if strings.Contains(pkg, "/") { // assume a full import path - if validImportPath(pkg) { - return pkg, true - } - return "", false - } - if d.LookupPackage != nil { - // Give LookupPackage a chance. - if path, ok := d.LookupPackage(pkg); ok { - return path, true - } - } - return DefaultLookupPackage(pkg) -} - -func isStdPkg(path string) bool { - _, ok := slices.BinarySearch(stdPkgs, path) - return ok -} - -// DefaultLookupPackage is the default package lookup -// function, used when [Parser.LookupPackage] is nil. -// It recognizes names of the packages from the standard -// library with single-element import paths, such as math, -// which would otherwise be impossible to name. -// -// Note that the go/doc package provides a more sophisticated -// lookup based on the imports used in the current package. -func DefaultLookupPackage(name string) (importPath string, ok bool) { - if isStdPkg(name) { - return name, true - } - return "", false -} - -// Parse parses the doc comment text and returns the *[Doc] form. -// Comment markers (/* // and */) in the text must have already been removed. -func (p *Parser) Parse(text string) *Doc { - lines := unindent(strings.Split(text, "\n")) - d := &parseDoc{ - Parser: p, - Doc: new(Doc), - links: make(map[string]*LinkDef), - lines: lines, - lookupSym: func(recv, name string) bool { return false }, - } - if p.LookupSym != nil { - d.lookupSym = p.LookupSym - } - - // First pass: break into block structure and collect known links. - // The text is all recorded as Plain for now. - var prev span - for _, s := range parseSpans(lines) { - var b Block - switch s.kind { - default: - panic("mvdan.cc/gofumpt/internal/govendor/go/doc/comment: internal error: unknown span kind") - case spanList: - b = d.list(lines[s.start:s.end], prev.end < s.start) - case spanCode: - b = d.code(lines[s.start:s.end]) - case spanOldHeading: - b = d.oldHeading(lines[s.start]) - case spanHeading: - b = d.heading(lines[s.start]) - case spanPara: - b = d.paragraph(lines[s.start:s.end]) - } - if b != nil { - d.Content = append(d.Content, b) - } - prev = s - } - - // Second pass: interpret all the Plain text now that we know the links. - for _, b := range d.Content { - switch b := b.(type) { - case *Paragraph: - b.Text = d.parseLinkedText(string(b.Text[0].(Plain))) - case *List: - for _, i := range b.Items { - for _, c := range i.Content { - p := c.(*Paragraph) - p.Text = d.parseLinkedText(string(p.Text[0].(Plain))) - } - } - } - } - - return d.Doc -} - -// A span represents a single span of comment lines (lines[start:end]) -// of an identified kind (code, heading, paragraph, and so on). -type span struct { - start int - end int - kind spanKind -} - -// A spanKind describes the kind of span. -type spanKind int - -const ( - _ spanKind = iota - spanCode - spanHeading - spanList - spanOldHeading - spanPara -) - -func parseSpans(lines []string) []span { - var spans []span - - // The loop may process a line twice: once as unindented - // and again forced indented. So the maximum expected - // number of iterations is 2*len(lines). The repeating logic - // can be subtle, though, and to protect against introduction - // of infinite loops in future changes, we watch to see that - // we are not looping too much. A panic is better than a - // quiet infinite loop. - watchdog := 2 * len(lines) - - i := 0 - forceIndent := 0 -Spans: - for { - // Skip blank lines. - for i < len(lines) && lines[i] == "" { - i++ - } - if i >= len(lines) { - break - } - if watchdog--; watchdog < 0 { - panic("mvdan.cc/gofumpt/internal/govendor/go/doc/comment: internal error: not making progress") - } - - var kind spanKind - start := i - end := i - if i < forceIndent || indented(lines[i]) { - // Indented (or force indented). - // Ends before next unindented. (Blank lines are OK.) - // If this is an unindented list that we are heuristically treating as indented, - // then accept unindented list item lines up to the first blank lines. - // The heuristic is disabled at blank lines to contain its effect - // to non-gofmt'ed sections of the comment. - unindentedListOK := isList(lines[i]) && i < forceIndent - i++ - for i < len(lines) && (lines[i] == "" || i < forceIndent || indented(lines[i]) || (unindentedListOK && isList(lines[i]))) { - if lines[i] == "" { - unindentedListOK = false - } - i++ - } - - // Drop trailing blank lines. - end = i - for end > start && lines[end-1] == "" { - end-- - } - - // If indented lines are followed (without a blank line) - // by an unindented line ending in a brace, - // take that one line too. This fixes the common mistake - // of pasting in something like - // - // func main() { - // fmt.Println("hello, world") - // } - // - // and forgetting to indent it. - // The heuristic will never trigger on a gofmt'ed comment, - // because any gofmt'ed code block or list would be - // followed by a blank line or end of comment. - if end < len(lines) && strings.HasPrefix(lines[end], "}") { - end++ - } - - if isList(lines[start]) { - kind = spanList - } else { - kind = spanCode - } - } else { - // Unindented. Ends at next blank or indented line. - i++ - for i < len(lines) && lines[i] != "" && !indented(lines[i]) { - i++ - } - end = i - - // If unindented lines are followed (without a blank line) - // by an indented line that would start a code block, - // check whether the final unindented lines - // should be left for the indented section. - // This can happen for the common mistakes of - // unindented code or unindented lists. - // The heuristic will never trigger on a gofmt'ed comment, - // because any gofmt'ed code block would have a blank line - // preceding it after the unindented lines. - if i < len(lines) && lines[i] != "" && !isList(lines[i]) { - switch { - case isList(lines[i-1]): - // If the final unindented line looks like a list item, - // this may be the first indented line wrap of - // a mistakenly unindented list. - // Leave all the unindented list items. - forceIndent = end - end-- - for end > start && isList(lines[end-1]) { - end-- - } - - case strings.HasSuffix(lines[i-1], "{") || strings.HasSuffix(lines[i-1], `\`): - // If the final unindented line ended in { or \ - // it is probably the start of a misindented code block. - // Give the user a single line fix. - // Often that's enough; if not, the user can fix the others themselves. - forceIndent = end - end-- - } - - if start == end && forceIndent > start { - i = start - continue Spans - } - } - - // Span is either paragraph or heading. - if end-start == 1 && isHeading(lines[start]) { - kind = spanHeading - } else if end-start == 1 && isOldHeading(lines[start], lines, start) { - kind = spanOldHeading - } else { - kind = spanPara - } - } - - spans = append(spans, span{start, end, kind}) - i = end - } - - return spans -} - -// indented reports whether line is indented -// (starts with a leading space or tab). -func indented(line string) bool { - return line != "" && (line[0] == ' ' || line[0] == '\t') -} - -// unindent removes any common space/tab prefix -// from each line in lines, returning a copy of lines in which -// those prefixes have been trimmed from each line. -// It also replaces any lines containing only spaces with blank lines (empty strings). -func unindent(lines []string) []string { - // Trim leading and trailing blank lines. - for len(lines) > 0 && isBlank(lines[0]) { - lines = lines[1:] - } - for len(lines) > 0 && isBlank(lines[len(lines)-1]) { - lines = lines[:len(lines)-1] - } - if len(lines) == 0 { - return nil - } - - // Compute and remove common indentation. - prefix := leadingSpace(lines[0]) - for _, line := range lines[1:] { - if !isBlank(line) { - prefix = commonPrefix(prefix, leadingSpace(line)) - } - } - - out := make([]string, len(lines)) - for i, line := range lines { - line = strings.TrimPrefix(line, prefix) - if strings.TrimSpace(line) == "" { - line = "" - } - out[i] = line - } - for len(out) > 0 && out[0] == "" { - out = out[1:] - } - for len(out) > 0 && out[len(out)-1] == "" { - out = out[:len(out)-1] - } - return out -} - -// isBlank reports whether s is a blank line. -func isBlank(s string) bool { - return len(s) == 0 || (len(s) == 1 && s[0] == '\n') -} - -// commonPrefix returns the longest common prefix of a and b. -func commonPrefix(a, b string) string { - i := 0 - for i < len(a) && i < len(b) && a[i] == b[i] { - i++ - } - return a[0:i] -} - -// leadingSpace returns the longest prefix of s consisting of spaces and tabs. -func leadingSpace(s string) string { - i := 0 - for i < len(s) && (s[i] == ' ' || s[i] == '\t') { - i++ - } - return s[:i] -} - -// isOldHeading reports whether line is an old-style section heading. -// line is all[off]. -func isOldHeading(line string, all []string, off int) bool { - if off <= 0 || all[off-1] != "" || off+2 >= len(all) || all[off+1] != "" || leadingSpace(all[off+2]) != "" { - return false - } - - line = strings.TrimSpace(line) - - // a heading must start with an uppercase letter - r, _ := utf8.DecodeRuneInString(line) - if !unicode.IsLetter(r) || !unicode.IsUpper(r) { - return false - } - - // it must end in a letter or digit: - r, _ = utf8.DecodeLastRuneInString(line) - if !unicode.IsLetter(r) && !unicode.IsDigit(r) { - return false - } - - // exclude lines with illegal characters. we allow "()," - if strings.ContainsAny(line, ";:!?+*/=[]{}_^°&§~%#@<\">\\") { - return false - } - - // allow "'" for possessive "'s" only - for b := line; ; { - var ok bool - if _, b, ok = strings.Cut(b, "'"); !ok { - break - } - if b != "s" && !strings.HasPrefix(b, "s ") { - return false // ' not followed by s and then end-of-word - } - } - - // allow "." when followed by non-space - for b := line; ; { - var ok bool - if _, b, ok = strings.Cut(b, "."); !ok { - break - } - if b == "" || strings.HasPrefix(b, " ") { - return false // not followed by non-space - } - } - - return true -} - -// oldHeading returns the *Heading for the given old-style section heading line. -func (d *parseDoc) oldHeading(line string) Block { - return &Heading{Text: []Text{Plain(strings.TrimSpace(line))}} -} - -// isHeading reports whether line is a new-style section heading. -func isHeading(line string) bool { - return len(line) >= 2 && - line[0] == '#' && - (line[1] == ' ' || line[1] == '\t') && - strings.TrimSpace(line) != "#" -} - -// heading returns the *Heading for the given new-style section heading line. -func (d *parseDoc) heading(line string) Block { - return &Heading{Text: []Text{Plain(strings.TrimSpace(line[1:]))}} -} - -// code returns a code block built from the lines. -func (d *parseDoc) code(lines []string) *Code { - body := unindent(lines) - body = append(body, "") // to get final \n from Join - return &Code{Text: strings.Join(body, "\n")} -} - -// paragraph returns a paragraph block built from the lines. -// If the lines are link definitions, paragraph adds them to d and returns nil. -func (d *parseDoc) paragraph(lines []string) Block { - // Is this a block of known links? Handle. - var defs []*LinkDef - for _, line := range lines { - def, ok := parseLink(line) - if !ok { - goto NoDefs - } - defs = append(defs, def) - } - for _, def := range defs { - d.Links = append(d.Links, def) - if d.links[def.Text] == nil { - d.links[def.Text] = def - } - } - return nil -NoDefs: - - return &Paragraph{Text: []Text{Plain(strings.Join(lines, "\n"))}} -} - -// parseLink parses a single link definition line: -// -// [text]: url -// -// It returns the link definition and whether the line was well formed. -func parseLink(line string) (*LinkDef, bool) { - if line == "" || line[0] != '[' { - return nil, false - } - i := strings.Index(line, "]:") - if i < 0 || i+3 >= len(line) || (line[i+2] != ' ' && line[i+2] != '\t') { - return nil, false - } - - text := line[1:i] - url := strings.TrimSpace(line[i+3:]) - j := strings.Index(url, "://") - if j < 0 || !isScheme(url[:j]) { - return nil, false - } - - // Line has right form and has valid scheme://. - // That's good enough for us - we are not as picky - // about the characters beyond the :// as we are - // when extracting inline URLs from text. - return &LinkDef{Text: text, URL: url}, true -} - -// list returns a list built from the indented lines, -// using forceBlankBefore as the value of the List's ForceBlankBefore field. -func (d *parseDoc) list(lines []string, forceBlankBefore bool) *List { - num, _, _ := listMarker(lines[0]) - var ( - list *List = &List{ForceBlankBefore: forceBlankBefore} - item *ListItem - text []string - ) - flush := func() { - if item != nil { - if para := d.paragraph(text); para != nil { - item.Content = append(item.Content, para) - } - } - text = nil - } - - for _, line := range lines { - if n, after, ok := listMarker(line); ok && (n != "") == (num != "") { - // start new list item - flush() - - item = &ListItem{Number: n} - list.Items = append(list.Items, item) - line = after - } - line = strings.TrimSpace(line) - if line == "" { - list.ForceBlankBetween = true - flush() - continue - } - text = append(text, strings.TrimSpace(line)) - } - flush() - return list -} - -// listMarker parses the line as beginning with a list marker. -// If it can do that, it returns the numeric marker ("" for a bullet list), -// the rest of the line, and ok == true. -// Otherwise, it returns "", "", false. -func listMarker(line string) (num, rest string, ok bool) { - line = strings.TrimSpace(line) - if line == "" { - return "", "", false - } - - // Can we find a marker? - if r, n := utf8.DecodeRuneInString(line); r == '•' || r == '*' || r == '+' || r == '-' { - num, rest = "", line[n:] - } else if '0' <= line[0] && line[0] <= '9' { - n := 1 - for n < len(line) && '0' <= line[n] && line[n] <= '9' { - n++ - } - if n >= len(line) || (line[n] != '.' && line[n] != ')') { - return "", "", false - } - num, rest = line[:n], line[n+1:] - } else { - return "", "", false - } - - if !indented(rest) || strings.TrimSpace(rest) == "" { - return "", "", false - } - - return num, rest, true -} - -// isList reports whether the line is the first line of a list, -// meaning starts with a list marker after any indentation. -// (The caller is responsible for checking the line is indented, as appropriate.) -func isList(line string) bool { - _, _, ok := listMarker(line) - return ok -} - -// parseLinkedText parses text that is allowed to contain explicit links, -// such as [math.Sin] or [Go home page], into a slice of Text items. -// -// A “pkg” is only assumed to be a full import path if it starts with -// a domain name (a path element with a dot) or is one of the packages -// from the standard library (“[os]”, “[encoding/json]”, and so on). -// To avoid problems with maps, generics, and array types, doc links -// must be both preceded and followed by punctuation, spaces, tabs, -// or the start or end of a line. An example problem would be treating -// map[ast.Expr]TypeAndValue as containing a link. -func (d *parseDoc) parseLinkedText(text string) []Text { - var out []Text - wrote := 0 - flush := func(i int) { - if wrote < i { - out = d.parseText(out, text[wrote:i], true) - wrote = i - } - } - - start := -1 - var buf []byte - for i := 0; i < len(text); i++ { - c := text[i] - if c == '\n' || c == '\t' { - c = ' ' - } - switch c { - case '[': - start = i - case ']': - if start >= 0 { - if def, ok := d.links[string(buf)]; ok { - def.Used = true - flush(start) - out = append(out, &Link{ - Text: d.parseText(nil, text[start+1:i], false), - URL: def.URL, - }) - wrote = i + 1 - } else if link, ok := d.docLink(text[start+1:i], text[:start], text[i+1:]); ok { - flush(start) - link.Text = d.parseText(nil, text[start+1:i], false) - out = append(out, link) - wrote = i + 1 - } - } - start = -1 - buf = buf[:0] - } - if start >= 0 && i != start { - buf = append(buf, c) - } - } - - flush(len(text)) - return out -} - -// docLink parses text, which was found inside [ ] brackets, -// as a doc link if possible, returning the DocLink and ok == true -// or else nil, false. -// The before and after strings are the text before the [ and after the ] -// on the same line. Doc links must be preceded and followed by -// punctuation, spaces, tabs, or the start or end of a line. -func (d *parseDoc) docLink(text, before, after string) (link *DocLink, ok bool) { - if before != "" { - r, _ := utf8.DecodeLastRuneInString(before) - if !unicode.IsPunct(r) && r != ' ' && r != '\t' && r != '\n' { - return nil, false - } - } - if after != "" { - r, _ := utf8.DecodeRuneInString(after) - if !unicode.IsPunct(r) && r != ' ' && r != '\t' && r != '\n' { - return nil, false - } - } - text = strings.TrimPrefix(text, "*") - pkg, name, ok := splitDocName(text) - var recv string - if ok { - pkg, recv, _ = splitDocName(pkg) - } - if pkg != "" { - if pkg, ok = d.lookupPkg(pkg); !ok { - return nil, false - } - } else { - if ok = d.lookupSym(recv, name); !ok { - return nil, false - } - } - link = &DocLink{ - ImportPath: pkg, - Recv: recv, - Name: name, - } - return link, true -} - -// If text is of the form before.Name, where Name is a capitalized Go identifier, -// then splitDocName returns before, name, true. -// Otherwise it returns text, "", false. -func splitDocName(text string) (before, name string, foundDot bool) { - i := strings.LastIndex(text, ".") - name = text[i+1:] - if !isName(name) { - return text, "", false - } - if i >= 0 { - before = text[:i] - } - return before, name, true -} - -// parseText parses s as text and returns the result of appending -// those parsed Text elements to out. -// parseText does not handle explicit links like [math.Sin] or [Go home page]: -// those are handled by parseLinkedText. -// If autoLink is true, then parseText recognizes URLs and words from d.Words -// and converts those to links as appropriate. -func (d *parseDoc) parseText(out []Text, s string, autoLink bool) []Text { - var w strings.Builder - wrote := 0 - writeUntil := func(i int) { - w.WriteString(s[wrote:i]) - wrote = i - } - flush := func(i int) { - writeUntil(i) - if w.Len() > 0 { - out = append(out, Plain(w.String())) - w.Reset() - } - } - for i := 0; i < len(s); { - t := s[i:] - if autoLink { - if url, ok := autoURL(t); ok { - flush(i) - // Note: The old comment parser would look up the URL in words - // and replace the target with words[URL] if it was non-empty. - // That would allow creating links that display as one URL but - // when clicked go to a different URL. Not sure what the point - // of that is, so we're not doing that lookup here. - out = append(out, &Link{Auto: true, Text: []Text{Plain(url)}, URL: url}) - i += len(url) - wrote = i - continue - } - if id, ok := ident(t); ok { - url, italics := d.Words[id] - if !italics { - i += len(id) - continue - } - flush(i) - if url == "" { - out = append(out, Italic(id)) - } else { - out = append(out, &Link{Auto: true, Text: []Text{Italic(id)}, URL: url}) - } - i += len(id) - wrote = i - continue - } - } - switch { - case strings.HasPrefix(t, "``"): - if len(t) >= 3 && t[2] == '`' { - // Do not convert `` inside ```, in case people are mistakenly writing Markdown. - i += 3 - for i < len(t) && t[i] == '`' { - i++ - } - break - } - writeUntil(i) - w.WriteRune('“') - i += 2 - wrote = i - case strings.HasPrefix(t, "''"): - writeUntil(i) - w.WriteRune('”') - i += 2 - wrote = i - default: - i++ - } - } - flush(len(s)) - return out -} - -// autoURL checks whether s begins with a URL that should be hyperlinked. -// If so, it returns the URL, which is a prefix of s, and ok == true. -// Otherwise it returns "", false. -// The caller should skip over the first len(url) bytes of s -// before further processing. -func autoURL(s string) (url string, ok bool) { - // Find the ://. Fast path to pick off non-URL, - // since we call this at every position in the string. - // The shortest possible URL is ftp://x, 7 bytes. - var i int - switch { - case len(s) < 7: - return "", false - case s[3] == ':': - i = 3 - case s[4] == ':': - i = 4 - case s[5] == ':': - i = 5 - case s[6] == ':': - i = 6 - default: - return "", false - } - if i+3 > len(s) || s[i:i+3] != "://" { - return "", false - } - - // Check valid scheme. - if !isScheme(s[:i]) { - return "", false - } - - // Scan host part. Must have at least one byte, - // and must start and end in non-punctuation. - i += 3 - if i >= len(s) || !isHost(s[i]) || isPunct(s[i]) { - return "", false - } - i++ - end := i - for i < len(s) && isHost(s[i]) { - if !isPunct(s[i]) { - end = i + 1 - } - i++ - } - i = end - - // At this point we are definitely returning a URL (scheme://host). - // We just have to find the longest path we can add to it. - // Heuristics abound. - // We allow parens, braces, and brackets, - // but only if they match (#5043, #22285). - // We allow .,:;?! in the path but not at the end, - // to avoid end-of-sentence punctuation (#18139, #16565). - stk := []byte{} - end = i -Path: - for ; i < len(s); i++ { - if isPunct(s[i]) { - continue - } - if !isPath(s[i]) { - break - } - switch s[i] { - case '(': - stk = append(stk, ')') - case '{': - stk = append(stk, '}') - case '[': - stk = append(stk, ']') - case ')', '}', ']': - if len(stk) == 0 || stk[len(stk)-1] != s[i] { - break Path - } - stk = stk[:len(stk)-1] - } - if len(stk) == 0 { - end = i + 1 - } - } - - return s[:end], true -} - -// isScheme reports whether s is a recognized URL scheme. -// Note that if strings of new length (beyond 3-7) -// are added here, the fast path at the top of autoURL will need updating. -func isScheme(s string) bool { - switch s { - case "file", - "ftp", - "gopher", - "http", - "https", - "mailto", - "nntp": - return true - } - return false -} - -// isHost reports whether c is a byte that can appear in a URL host, -// like www.example.com or user@[::1]:8080 -func isHost(c byte) bool { - // mask is a 128-bit bitmap with 1s for allowed bytes, - // so that the byte c can be tested with a shift and an and. - // If c > 128, then 1<>64)) != 0 -} - -// isPunct reports whether c is a punctuation byte that can appear -// inside a path but not at the end. -func isPunct(c byte) bool { - // mask is a 128-bit bitmap with 1s for allowed bytes, - // so that the byte c can be tested with a shift and an and. - // If c > 128, then 1<>64)) != 0 -} - -// isPath reports whether c is a (non-punctuation) path byte. -func isPath(c byte) bool { - // mask is a 128-bit bitmap with 1s for allowed bytes, - // so that the byte c can be tested with a shift and an and. - // If c > 128, then 1<>64)) != 0 -} - -// isName reports whether s is a capitalized Go identifier (like Name). -func isName(s string) bool { - t, ok := ident(s) - if !ok || t != s { - return false - } - r, _ := utf8.DecodeRuneInString(s) - return unicode.IsUpper(r) -} - -// ident checks whether s begins with a Go identifier. -// If so, it returns the identifier, which is a prefix of s, and ok == true. -// Otherwise it returns "", false. -// The caller should skip over the first len(id) bytes of s -// before further processing. -func ident(s string) (id string, ok bool) { - // Scan [\pL_][\pL_0-9]* - n := 0 - for n < len(s) { - if c := s[n]; c < utf8.RuneSelf { - if isIdentASCII(c) && (n > 0 || c < '0' || c > '9') { - n++ - continue - } - break - } - r, nr := utf8.DecodeRuneInString(s[n:]) - if unicode.IsLetter(r) { - n += nr - continue - } - break - } - return s[:n], n > 0 -} - -// isIdentASCII reports whether c is an ASCII identifier byte. -func isIdentASCII(c byte) bool { - // mask is a 128-bit bitmap with 1s for allowed bytes, - // so that the byte c can be tested with a shift and an and. - // If c > 128, then 1<>64)) != 0 -} - -// validImportPath reports whether path is a valid import path. -// It is a lightly edited copy of golang.org/x/mod/module.CheckImportPath. -func validImportPath(path string) bool { - if !utf8.ValidString(path) { - return false - } - if path == "" { - return false - } - if path[0] == '-' { - return false - } - if strings.Contains(path, "//") { - return false - } - if path[len(path)-1] == '/' { - return false - } - elemStart := 0 - for i, r := range path { - if r == '/' { - if !validImportPathElem(path[elemStart:i]) { - return false - } - elemStart = i + 1 - } - } - return validImportPathElem(path[elemStart:]) -} - -func validImportPathElem(elem string) bool { - if elem == "" || elem[0] == '.' || elem[len(elem)-1] == '.' { - return false - } - for i := 0; i < len(elem); i++ { - if !importPathOK(elem[i]) { - return false - } - } - return true -} - -func importPathOK(c byte) bool { - // mask is a 128-bit bitmap with 1s for allowed bytes, - // so that the byte c can be tested with a shift and an and. - // If c > 128, then 1<>64)) != 0 -} diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/print.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/print.go deleted file mode 100644 index a6ae8210b..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/print.go +++ /dev/null @@ -1,288 +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 comment - -import ( - "bytes" - "fmt" - "strings" -) - -// A Printer is a doc comment printer. -// The fields in the struct can be filled in before calling -// any of the printing methods -// in order to customize the details of the printing process. -type Printer struct { - // HeadingLevel is the nesting level used for - // HTML and Markdown headings. - // If HeadingLevel is zero, it defaults to level 3, - // meaning to use

    and ###. - HeadingLevel int - - // HeadingID is a function that computes the heading ID - // (anchor tag) to use for the heading h when generating - // HTML and Markdown. If HeadingID returns an empty string, - // then the heading ID is omitted. - // If HeadingID is nil, h.DefaultID is used. - HeadingID func(h *Heading) string - - // DocLinkURL is a function that computes the URL for the given DocLink. - // If DocLinkURL is nil, then link.DefaultURL(p.DocLinkBaseURL) is used. - DocLinkURL func(link *DocLink) string - - // DocLinkBaseURL is used when DocLinkURL is nil, - // passed to [DocLink.DefaultURL] to construct a DocLink's URL. - // See that method's documentation for details. - DocLinkBaseURL string - - // TextPrefix is a prefix to print at the start of every line - // when generating text output using the Text method. - TextPrefix string - - // TextCodePrefix is the prefix to print at the start of each - // preformatted (code block) line when generating text output, - // instead of (not in addition to) TextPrefix. - // If TextCodePrefix is the empty string, it defaults to TextPrefix+"\t". - TextCodePrefix string - - // TextWidth is the maximum width text line to generate, - // measured in Unicode code points, - // excluding TextPrefix and the newline character. - // If TextWidth is zero, it defaults to 80 minus the number of code points in TextPrefix. - // If TextWidth is negative, there is no limit. - TextWidth int -} - -func (p *Printer) headingLevel() int { - if p.HeadingLevel <= 0 { - return 3 - } - return p.HeadingLevel -} - -func (p *Printer) headingID(h *Heading) string { - if p.HeadingID == nil { - return h.DefaultID() - } - return p.HeadingID(h) -} - -func (p *Printer) docLinkURL(link *DocLink) string { - if p.DocLinkURL != nil { - return p.DocLinkURL(link) - } - return link.DefaultURL(p.DocLinkBaseURL) -} - -// DefaultURL constructs and returns the documentation URL for l, -// using baseURL as a prefix for links to other packages. -// -// The possible forms returned by DefaultURL are: -// - baseURL/ImportPath, for a link to another package -// - baseURL/ImportPath#Name, for a link to a const, func, type, or var in another package -// - baseURL/ImportPath#Recv.Name, for a link to a method in another package -// - #Name, for a link to a const, func, type, or var in this package -// - #Recv.Name, for a link to a method in this package -// -// If baseURL ends in a trailing slash, then DefaultURL inserts -// a slash between ImportPath and # in the anchored forms. -// For example, here are some baseURL values and URLs they can generate: -// -// "/pkg/" → "/pkg/math/#Sqrt" -// "/pkg" → "/pkg/math#Sqrt" -// "/" → "/math/#Sqrt" -// "" → "/math#Sqrt" -func (l *DocLink) DefaultURL(baseURL string) string { - if l.ImportPath != "" { - slash := "" - if strings.HasSuffix(baseURL, "/") { - slash = "/" - } else { - baseURL += "/" - } - switch { - case l.Name == "": - return baseURL + l.ImportPath + slash - case l.Recv != "": - return baseURL + l.ImportPath + slash + "#" + l.Recv + "." + l.Name - default: - return baseURL + l.ImportPath + slash + "#" + l.Name - } - } - if l.Recv != "" { - return "#" + l.Recv + "." + l.Name - } - return "#" + l.Name -} - -// DefaultID returns the default anchor ID for the heading h. -// -// The default anchor ID is constructed by converting every -// rune that is not alphanumeric ASCII to an underscore -// and then adding the prefix “hdr-”. -// For example, if the heading text is “Go Doc Comments”, -// the default ID is “hdr-Go_Doc_Comments”. -func (h *Heading) DefaultID() string { - // Note: The “hdr-” prefix is important to avoid DOM clobbering attacks. - // See https://pkg.go.dev/github.com/google/safehtml#Identifier. - var out strings.Builder - var p textPrinter - p.oneLongLine(&out, h.Text) - s := strings.TrimSpace(out.String()) - if s == "" { - return "" - } - out.Reset() - out.WriteString("hdr-") - for _, r := range s { - if r < 0x80 && isIdentASCII(byte(r)) { - out.WriteByte(byte(r)) - } else { - out.WriteByte('_') - } - } - return out.String() -} - -type commentPrinter struct { - *Printer -} - -// Comment returns the standard Go formatting of the [Doc], -// without any comment markers. -func (p *Printer) Comment(d *Doc) []byte { - cp := &commentPrinter{Printer: p} - var out bytes.Buffer - for i, x := range d.Content { - if i > 0 && blankBefore(x) { - out.WriteString("\n") - } - cp.block(&out, x) - } - - // Print one block containing all the link definitions that were used, - // and then a second block containing all the unused ones. - // This makes it easy to clean up the unused ones: gofmt and - // delete the final block. And it's a nice visual signal without - // affecting the way the comment formats for users. - for i := 0; i < 2; i++ { - used := i == 0 - first := true - for _, def := range d.Links { - if def.Used == used { - if first { - out.WriteString("\n") - first = false - } - out.WriteString("[") - out.WriteString(def.Text) - out.WriteString("]: ") - out.WriteString(def.URL) - out.WriteString("\n") - } - } - } - - return out.Bytes() -} - -// blankBefore reports whether the block x requires a blank line before it. -// All blocks do, except for Lists that return false from x.BlankBefore(). -func blankBefore(x Block) bool { - if x, ok := x.(*List); ok { - return x.BlankBefore() - } - return true -} - -// block prints the block x to out. -func (p *commentPrinter) block(out *bytes.Buffer, x Block) { - switch x := x.(type) { - default: - fmt.Fprintf(out, "?%T", x) - - case *Paragraph: - p.text(out, "", x.Text) - out.WriteString("\n") - - case *Heading: - out.WriteString("# ") - p.text(out, "", x.Text) - out.WriteString("\n") - - case *Code: - md := x.Text - for md != "" { - var line string - line, md, _ = strings.Cut(md, "\n") - if line != "" { - out.WriteString("\t") - out.WriteString(line) - } - out.WriteString("\n") - } - - case *List: - loose := x.BlankBetween() - for i, item := range x.Items { - if i > 0 && loose { - out.WriteString("\n") - } - out.WriteString(" ") - if item.Number == "" { - out.WriteString(" - ") - } else { - out.WriteString(item.Number) - out.WriteString(". ") - } - for i, blk := range item.Content { - const fourSpace = " " - if i > 0 { - out.WriteString("\n" + fourSpace) - } - p.text(out, fourSpace, blk.(*Paragraph).Text) - out.WriteString("\n") - } - } - } -} - -// text prints the text sequence x to out. -func (p *commentPrinter) text(out *bytes.Buffer, indent string, x []Text) { - for _, t := range x { - switch t := t.(type) { - case Plain: - p.indent(out, indent, string(t)) - case Italic: - p.indent(out, indent, string(t)) - case *Link: - if t.Auto { - p.text(out, indent, t.Text) - } else { - out.WriteString("[") - p.text(out, indent, t.Text) - out.WriteString("]") - } - case *DocLink: - out.WriteString("[") - p.text(out, indent, t.Text) - out.WriteString("]") - } - } -} - -// indent prints s to out, indenting with the indent string -// after each newline in s. -func (p *commentPrinter) indent(out *bytes.Buffer, indent, s string) { - for s != "" { - line, rest, ok := strings.Cut(s, "\n") - out.WriteString(line) - if ok { - out.WriteString("\n") - out.WriteString(indent) - } - s = rest - } -} diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/std.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/std.go deleted file mode 100644 index 35e26abb3..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/std.go +++ /dev/null @@ -1,50 +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. - -// Code generated by 'go generate' DO NOT EDIT. -//disabled go:generate ./mkstd.sh - -package comment - -var stdPkgs = []string{ - "bufio", - "bytes", - "cmp", - "context", - "crypto", - "embed", - "encoding", - "errors", - "expvar", - "flag", - "fmt", - "hash", - "html", - "image", - "io", - "iter", - "log", - "maps", - "math", - "mime", - "net", - "os", - "path", - "plugin", - "reflect", - "regexp", - "runtime", - "slices", - "sort", - "strconv", - "strings", - "structs", - "sync", - "syscall", - "testing", - "time", - "unicode", - "unique", - "unsafe", -} diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/text.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/text.go deleted file mode 100644 index 4e4214e08..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/doc/comment/text.go +++ /dev/null @@ -1,337 +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 comment - -import ( - "bytes" - "fmt" - "sort" - "strings" - "unicode/utf8" -) - -// A textPrinter holds the state needed for printing a Doc as plain text. -type textPrinter struct { - *Printer - long strings.Builder - prefix string - codePrefix string - width int -} - -// Text returns a textual formatting of the [Doc]. -// See the [Printer] documentation for ways to customize the text output. -func (p *Printer) Text(d *Doc) []byte { - tp := &textPrinter{ - Printer: p, - prefix: p.TextPrefix, - codePrefix: p.TextCodePrefix, - width: p.TextWidth, - } - if tp.codePrefix == "" { - tp.codePrefix = p.TextPrefix + "\t" - } - if tp.width == 0 { - tp.width = 80 - utf8.RuneCountInString(tp.prefix) - } - - var out bytes.Buffer - for i, x := range d.Content { - if i > 0 && blankBefore(x) { - out.WriteString(tp.prefix) - writeNL(&out) - } - tp.block(&out, x) - } - anyUsed := false - for _, def := range d.Links { - if def.Used { - anyUsed = true - break - } - } - if anyUsed { - writeNL(&out) - for _, def := range d.Links { - if def.Used { - fmt.Fprintf(&out, "[%s]: %s\n", def.Text, def.URL) - } - } - } - return out.Bytes() -} - -// writeNL calls out.WriteByte('\n') -// but first trims trailing spaces on the previous line. -func writeNL(out *bytes.Buffer) { - // Trim trailing spaces. - data := out.Bytes() - n := 0 - for n < len(data) && (data[len(data)-n-1] == ' ' || data[len(data)-n-1] == '\t') { - n++ - } - if n > 0 { - out.Truncate(len(data) - n) - } - out.WriteByte('\n') -} - -// block prints the block x to out. -func (p *textPrinter) block(out *bytes.Buffer, x Block) { - switch x := x.(type) { - default: - fmt.Fprintf(out, "?%T\n", x) - - case *Paragraph: - out.WriteString(p.prefix) - p.text(out, "", x.Text) - - case *Heading: - out.WriteString(p.prefix) - out.WriteString("# ") - p.text(out, "", x.Text) - - case *Code: - text := x.Text - for text != "" { - var line string - line, text, _ = strings.Cut(text, "\n") - if line != "" { - out.WriteString(p.codePrefix) - out.WriteString(line) - } - writeNL(out) - } - - case *List: - loose := x.BlankBetween() - for i, item := range x.Items { - if i > 0 && loose { - out.WriteString(p.prefix) - writeNL(out) - } - out.WriteString(p.prefix) - out.WriteString(" ") - if item.Number == "" { - out.WriteString(" - ") - } else { - out.WriteString(item.Number) - out.WriteString(". ") - } - for i, blk := range item.Content { - const fourSpace = " " - if i > 0 { - writeNL(out) - out.WriteString(p.prefix) - out.WriteString(fourSpace) - } - p.text(out, fourSpace, blk.(*Paragraph).Text) - } - } - } -} - -// text prints the text sequence x to out. -func (p *textPrinter) text(out *bytes.Buffer, indent string, x []Text) { - p.oneLongLine(&p.long, x) - words := strings.Fields(p.long.String()) - p.long.Reset() - - var seq []int - if p.width < 0 || len(words) == 0 { - seq = []int{0, len(words)} // one long line - } else { - seq = wrap(words, p.width-utf8.RuneCountInString(indent)) - } - for i := 0; i+1 < len(seq); i++ { - if i > 0 { - out.WriteString(p.prefix) - out.WriteString(indent) - } - for j, w := range words[seq[i]:seq[i+1]] { - if j > 0 { - out.WriteString(" ") - } - out.WriteString(w) - } - writeNL(out) - } -} - -// oneLongLine prints the text sequence x to out as one long line, -// without worrying about line wrapping. -// Explicit links have the [ ] dropped to improve readability. -func (p *textPrinter) oneLongLine(out *strings.Builder, x []Text) { - for _, t := range x { - switch t := t.(type) { - case Plain: - out.WriteString(string(t)) - case Italic: - out.WriteString(string(t)) - case *Link: - p.oneLongLine(out, t.Text) - case *DocLink: - p.oneLongLine(out, t.Text) - } - } -} - -// wrap wraps words into lines of at most max runes, -// minimizing the sum of the squares of the leftover lengths -// at the end of each line (except the last, of course), -// with a preference for ending lines at punctuation (.,:;). -// -// The returned slice gives the indexes of the first words -// on each line in the wrapped text with a final entry of len(words). -// Thus the lines are words[seq[0]:seq[1]], words[seq[1]:seq[2]], -// ..., words[seq[len(seq)-2]:seq[len(seq)-1]]. -// -// The implementation runs in O(n log n) time, where n = len(words), -// using the algorithm described in D. S. Hirschberg and L. L. Larmore, -// “[The least weight subsequence problem],” FOCS 1985, pp. 137-143. -// -// [The least weight subsequence problem]: https://doi.org/10.1109/SFCS.1985.60 -func wrap(words []string, max int) (seq []int) { - // The algorithm requires that our scoring function be concave, - // meaning that for all i₀ ≤ i₁ < j₀ ≤ j₁, - // weight(i₀, j₀) + weight(i₁, j₁) ≤ weight(i₀, j₁) + weight(i₁, j₀). - // - // Our weights are two-element pairs [hi, lo] - // ordered by elementwise comparison. - // The hi entry counts the weight for lines that are longer than max, - // and the lo entry counts the weight for lines that are not. - // This forces the algorithm to first minimize the number of lines - // that are longer than max, which correspond to lines with - // single very long words. Having done that, it can move on to - // minimizing the lo score, which is more interesting. - // - // The lo score is the sum for each line of the square of the - // number of spaces remaining at the end of the line and a - // penalty of 64 given out for not ending the line in a - // punctuation character (.,:;). - // The penalty is somewhat arbitrarily chosen by trying - // different amounts and judging how nice the wrapped text looks. - // Roughly speaking, using 64 means that we are willing to - // end a line with eight blank spaces in order to end at a - // punctuation character, even if the next word would fit in - // those spaces. - // - // We care about ending in punctuation characters because - // it makes the text easier to skim if not too many sentences - // or phrases begin with a single word on the previous line. - - // A score is the score (also called weight) for a given line. - // add and cmp add and compare scores. - type score struct { - hi int64 - lo int64 - } - add := func(s, t score) score { return score{s.hi + t.hi, s.lo + t.lo} } - cmp := func(s, t score) int { - switch { - case s.hi < t.hi: - return -1 - case s.hi > t.hi: - return +1 - case s.lo < t.lo: - return -1 - case s.lo > t.lo: - return +1 - } - return 0 - } - - // total[j] is the total number of runes - // (including separating spaces) in words[:j]. - total := make([]int, len(words)+1) - total[0] = 0 - for i, s := range words { - total[1+i] = total[i] + utf8.RuneCountInString(s) + 1 - } - - // weight returns weight(i, j). - weight := func(i, j int) score { - // On the last line, there is zero weight for being too short. - n := total[j] - 1 - total[i] - if j == len(words) && n <= max { - return score{0, 0} - } - - // Otherwise the weight is the penalty plus the square of the number of - // characters remaining on the line or by which the line goes over. - // In the latter case, that value goes in the hi part of the score. - // (See note above.) - p := wrapPenalty(words[j-1]) - v := int64(max-n) * int64(max-n) - if n > max { - return score{v, p} - } - return score{0, v + p} - } - - // The rest of this function is “The Basic Algorithm” from - // Hirschberg and Larmore's conference paper, - // using the same names as in the paper. - f := []score{{0, 0}} - g := func(i, j int) score { return add(f[i], weight(i, j)) } - - bridge := func(a, b, c int) bool { - k := c + sort.Search(len(words)+1-c, func(k int) bool { - k += c - return cmp(g(a, k), g(b, k)) > 0 - }) - if k > len(words) { - return true - } - return cmp(g(c, k), g(b, k)) <= 0 - } - - // d is a one-ended deque implemented as a slice. - d := make([]int, 1, len(words)) - d[0] = 0 - bestleft := make([]int, 1, len(words)) - bestleft[0] = -1 - for m := 1; m < len(words); m++ { - f = append(f, g(d[0], m)) - bestleft = append(bestleft, d[0]) - for len(d) > 1 && cmp(g(d[1], m+1), g(d[0], m+1)) <= 0 { - d = d[1:] // “Retire” - } - for len(d) > 1 && bridge(d[len(d)-2], d[len(d)-1], m) { - d = d[:len(d)-1] // “Fire” - } - if cmp(g(m, len(words)), g(d[len(d)-1], len(words))) < 0 { - d = append(d, m) // “Hire” - // The next few lines are not in the paper but are necessary - // to handle two-word inputs correctly. It appears to be - // just a bug in the paper's pseudocode. - if len(d) == 2 && cmp(g(d[1], m+1), g(d[0], m+1)) <= 0 { - d = d[1:] - } - } - } - bestleft = append(bestleft, d[0]) - - // Recover least weight sequence from bestleft. - n := 1 - for m := len(words); m > 0; m = bestleft[m] { - n++ - } - seq = make([]int, n) - for m := len(words); m > 0; m = bestleft[m] { - n-- - seq[n] = m - } - return seq -} - -// wrapPenalty is the penalty for inserting a line break after word s. -func wrapPenalty(s string) int64 { - switch s[len(s)-1] { - case '.', ',', ':', ';': - return 0 - } - return 64 -} diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/format/format.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/format/format.go deleted file mode 100644 index 63e65e905..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/format/format.go +++ /dev/null @@ -1,134 +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. - -// Package format implements standard formatting of Go source. -// -// Note that formatting of Go source code changes over time, so tools relying on -// consistent formatting should execute a specific version of the gofmt binary -// instead of using this package. That way, the formatting will be stable, and -// the tools won't need to be recompiled each time gofmt changes. -// -// For example, pre-submit checks that use this package directly would behave -// differently depending on what Go version each developer uses, causing the -// check to be inherently fragile. -package format - -import ( - "bytes" - "fmt" - "go/ast" - "go/parser" - "go/token" - "io" - - "mvdan.cc/gofumpt/internal/govendor/go/printer" -) - -// Keep these in sync with cmd/gofmt/gofmt.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 mvdan.cc/gofumpt/internal/govendor/go/printer specifically for mvdan.cc/gofumpt/internal/govendor/go/format and cmd/gofmt. - printerNormalizeNumbers = 1 << 30 -) - -var config = printer.Config{Mode: printerMode, Tabwidth: tabWidth} - -const parserMode = parser.ParseComments | parser.SkipObjectResolution - -// Node formats node in canonical gofmt style and writes the result to dst. -// -// The node type must be *[ast.File], *[printer.CommentedNode], [][ast.Decl], -// [][ast.Stmt], or assignment-compatible to [ast.Expr], [ast.Decl], [ast.Spec], -// or [ast.Stmt]. Node does not modify node. Imports are not sorted for -// nodes representing partial source files (for instance, if the node is -// not an *[ast.File] or a *[printer.CommentedNode] not wrapping an *[ast.File]). -// -// The function may return early (before the entire result is written) -// and return a formatting error, for instance due to an incorrect AST. -func Node(dst io.Writer, fset *token.FileSet, node any) error { - // Determine if we have a complete source file (file != nil). - var file *ast.File - var cnode *printer.CommentedNode - switch n := node.(type) { - case *ast.File: - file = n - case *printer.CommentedNode: - if f, ok := n.Node.(*ast.File); ok { - file = f - cnode = n - } - } - - // Sort imports if necessary. - if file != nil && hasUnsortedImports(file) { - // Make a copy of the AST because ast.SortImports is destructive. - // TODO(gri) Do this more efficiently. - var buf bytes.Buffer - err := config.Fprint(&buf, fset, file) - if err != nil { - return err - } - file, err = parser.ParseFile(fset, "", buf.Bytes(), parserMode) - if err != nil { - // We should never get here. If we do, provide good diagnostic. - return fmt.Errorf("format.Node internal error (%s)", err) - } - ast.SortImports(fset, file) - - // Use new file with sorted imports. - node = file - if cnode != nil { - node = &printer.CommentedNode{Node: file, Comments: cnode.Comments} - } - } - - return config.Fprint(dst, fset, node) -} - -// Source formats src in canonical gofmt style and returns the result -// or an (I/O or syntax) error. src is expected to be a syntactically -// correct Go source file, or a list of Go declarations or statements. -// -// If src is a partial source file, the leading and trailing space of src -// is applied to the result (such that it has the same leading and trailing -// space as src), and the result is indented by the same amount as the first -// line of src containing code. Imports are not sorted for partial source files. -func Source(src []byte) ([]byte, error) { - fset := token.NewFileSet() - file, sourceAdj, indentAdj, err := parse(fset, "", src, true) - if err != nil { - return nil, err - } - - if sourceAdj == nil { - // Complete source file. - // TODO(gri) consider doing this always. - ast.SortImports(fset, file) - } - - return format(fset, file, sourceAdj, indentAdj, src, config) -} - -func hasUnsortedImports(file *ast.File) bool { - for _, d := range file.Decls { - d, ok := d.(*ast.GenDecl) - if !ok || d.Tok != token.IMPORT { - // Not an import declaration, so we're done. - // Imports are always first. - return false - } - if d.Lparen.IsValid() { - // For now assume all grouped imports are unsorted. - // TODO(gri) Should check if they are sorted already. - return true - } - // Ungrouped imports are sorted by default. - } - return false -} diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/format/internal.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/format/internal.go deleted file mode 100644 index df0358714..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/format/internal.go +++ /dev/null @@ -1,177 +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/cmd/gofmt/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 format - -import ( - "bytes" - "go/ast" - "go/parser" - "go/token" - "strings" - - "mvdan.cc/gofumpt/internal/govendor/go/printer" -) - -// 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, -) { - // 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/mvdan.cc/gofumpt/internal/govendor/go/printer/comment.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/comment.go deleted file mode 100644 index 1f0e7df9d..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/comment.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 printer - -import ( - "go/ast" - "strings" - - "mvdan.cc/gofumpt/internal/govendor/go/doc/comment" -) - -// formatDocComment reformats the doc comment list, -// returning the canonical formatting. -func formatDocComment(list []*ast.Comment) []*ast.Comment { - // Extract comment text (removing comment markers). - var kind, text string - var directives []*ast.Comment - if len(list) == 1 && strings.HasPrefix(list[0].Text, "/*") { - kind = "/*" - text = list[0].Text - if !strings.Contains(text, "\n") || allStars(text) { - // Single-line /* .. */ comment in doc comment position, - // or multiline old-style comment like - // /* - // * Comment - // * text here. - // */ - // Should not happen, since it will not work well as a - // doc comment, but if it does, just ignore: - // reformatting it will only make the situation worse. - return list - } - text = text[2 : len(text)-2] // cut /* and */ - } else if strings.HasPrefix(list[0].Text, "//") { - kind = "//" - var b strings.Builder - for _, c := range list { - after, found := strings.CutPrefix(c.Text, "//") - if !found { - return list - } - // Accumulate //go:build etc lines separately. - if isDirective(after) { - directives = append(directives, c) - continue - } - b.WriteString(strings.TrimPrefix(after, " ")) - b.WriteString("\n") - } - text = b.String() - } else { - // Not sure what this is, so leave alone. - return list - } - - if text == "" { - return list - } - - // Parse comment and reformat as text. - var p comment.Parser - d := p.Parse(text) - - var pr comment.Printer - text = string(pr.Comment(d)) - - // For /* */ comment, return one big comment with text inside. - slash := list[0].Slash - if kind == "/*" { - c := &ast.Comment{ - Slash: slash, - Text: "/*\n" + text + "*/", - } - return []*ast.Comment{c} - } - - // For // comment, return sequence of // lines. - var out []*ast.Comment - for text != "" { - var line string - line, text, _ = strings.Cut(text, "\n") - if line == "" { - line = "//" - } else if strings.HasPrefix(line, "\t") { - line = "//" + line - } else { - line = "// " + line - } - out = append(out, &ast.Comment{ - Slash: slash, - Text: line, - }) - } - if len(directives) > 0 { - out = append(out, &ast.Comment{ - Slash: slash, - Text: "//", - }) - for _, c := range directives { - out = append(out, &ast.Comment{ - Slash: slash, - Text: c.Text, - }) - } - } - return out -} - -// isDirective reports whether c is a comment directive. -// See go.dev/issue/37974. -// This code is also in go/ast. -func isDirective(c string) bool { - // "//line " is a line directive. - // "//extern " is for gccgo. - // "//export " is for cgo. - // (The // has been removed.) - if strings.HasPrefix(c, "line ") || strings.HasPrefix(c, "extern ") || strings.HasPrefix(c, "export ") { - return true - } - - // "//[a-z0-9]+:[a-z0-9]" - // (The // has been removed.) - colon := strings.Index(c, ":") - if colon <= 0 || colon+1 >= len(c) { - return false - } - for i := 0; i <= colon+1; i++ { - if i == colon { - continue - } - b := c[i] - if !('a' <= b && b <= 'z' || '0' <= b && b <= '9') { - return false - } - } - return true -} - -// allStars reports whether text is the interior of an -// old-style /* */ comment with a star at the start of each line. -func allStars(text string) bool { - for i := 0; i < len(text); i++ { - if text[i] == '\n' { - j := i + 1 - for j < len(text) && (text[j] == ' ' || text[j] == '\t') { - j++ - } - if j < len(text) && text[j] != '*' { - return false - } - } - } - return true -} diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/gobuild.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/gobuild.go deleted file mode 100644 index 6f04cf6d6..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/gobuild.go +++ /dev/null @@ -1,170 +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 printer - -import ( - "go/build/constraint" - "slices" - "text/tabwriter" -) - -func (p *printer) fixGoBuildLines() { - if len(p.goBuild)+len(p.plusBuild) == 0 { - return - } - - // Find latest possible placement of //go:build and // +build comments. - // That's just after the last blank line before we find a non-comment. - // (We'll add another blank line after our comment block.) - // When we start dropping // +build comments, we can skip over /* */ comments too. - // Note that we are processing tabwriter input, so every comment - // begins and ends with a tabwriter.Escape byte. - // And some newlines have turned into \f bytes. - insert := 0 - for pos := 0; ; { - // Skip leading space at beginning of line. - blank := true - for pos < len(p.output) && (p.output[pos] == ' ' || p.output[pos] == '\t') { - pos++ - } - // Skip over // comment if any. - if pos+3 < len(p.output) && p.output[pos] == tabwriter.Escape && p.output[pos+1] == '/' && p.output[pos+2] == '/' { - blank = false - for pos < len(p.output) && !isNL(p.output[pos]) { - pos++ - } - } - // Skip over \n at end of line. - if pos >= len(p.output) || !isNL(p.output[pos]) { - break - } - pos++ - - if blank { - insert = pos - } - } - - // If there is a //go:build comment before the place we identified, - // use that point instead. (Earlier in the file is always fine.) - if len(p.goBuild) > 0 && p.goBuild[0] < insert { - insert = p.goBuild[0] - } else if len(p.plusBuild) > 0 && p.plusBuild[0] < insert { - insert = p.plusBuild[0] - } - - var x constraint.Expr - switch len(p.goBuild) { - case 0: - // Synthesize //go:build expression from // +build lines. - for _, pos := range p.plusBuild { - y, err := constraint.Parse(p.commentTextAt(pos)) - if err != nil { - x = nil - break - } - if x == nil { - x = y - } else { - x = &constraint.AndExpr{X: x, Y: y} - } - } - case 1: - // Parse //go:build expression. - x, _ = constraint.Parse(p.commentTextAt(p.goBuild[0])) - } - - var block []byte - if x == nil { - // Don't have a valid //go:build expression to treat as truth. - // Bring all the lines together but leave them alone. - // Note that these are already tabwriter-escaped. - for _, pos := range p.goBuild { - block = append(block, p.lineAt(pos)...) - } - for _, pos := range p.plusBuild { - block = append(block, p.lineAt(pos)...) - } - } else { - block = append(block, tabwriter.Escape) - block = append(block, "//go:build "...) - block = append(block, x.String()...) - block = append(block, tabwriter.Escape, '\n') - if len(p.plusBuild) > 0 { - lines, err := constraint.PlusBuildLines(x) - if err != nil { - lines = []string{"// +build error: " + err.Error()} - } - for _, line := range lines { - block = append(block, tabwriter.Escape) - block = append(block, line...) - block = append(block, tabwriter.Escape, '\n') - } - } - } - block = append(block, '\n') - - // Build sorted list of lines to delete from remainder of output. - toDelete := append(p.goBuild, p.plusBuild...) - slices.Sort(toDelete) - - // Collect output after insertion point, with lines deleted, into after. - var after []byte - start := insert - for _, end := range toDelete { - if end < start { - continue - } - after = appendLines(after, p.output[start:end]) - start = end + len(p.lineAt(end)) - } - after = appendLines(after, p.output[start:]) - if n := len(after); n >= 2 && isNL(after[n-1]) && isNL(after[n-2]) { - after = after[:n-1] - } - - p.output = p.output[:insert] - p.output = append(p.output, block...) - p.output = append(p.output, after...) -} - -// appendLines is like append(x, y...) -// but it avoids creating doubled blank lines, -// which would not be gofmt-standard output. -// It assumes that only whole blocks of lines are being appended, -// not line fragments. -func appendLines(x, y []byte) []byte { - if len(y) > 0 && isNL(y[0]) && // y starts in blank line - (len(x) == 0 || len(x) >= 2 && isNL(x[len(x)-1]) && isNL(x[len(x)-2])) { // x is empty or ends in blank line - y = y[1:] // delete y's leading blank line - } - return append(x, y...) -} - -func (p *printer) lineAt(start int) []byte { - pos := start - for pos < len(p.output) && !isNL(p.output[pos]) { - pos++ - } - if pos < len(p.output) { - pos++ - } - return p.output[start:pos] -} - -func (p *printer) commentTextAt(start int) string { - if start < len(p.output) && p.output[start] == tabwriter.Escape { - start++ - } - pos := start - for pos < len(p.output) && p.output[pos] != tabwriter.Escape && !isNL(p.output[pos]) { - pos++ - } - return string(p.output[start:pos]) -} - -func isNL(b byte) bool { - return b == '\n' || b == '\f' -} diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/nodes.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/nodes.go deleted file mode 100644 index b8c7dedf0..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/nodes.go +++ /dev/null @@ -1,2001 +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 printing of AST nodes; specifically -// expressions, statements, declarations, and files. It uses -// the print functionality implemented in printer.go. - -package printer - -import ( - "go/ast" - "go/token" - "math" - "strconv" - "strings" - "unicode" - "unicode/utf8" -) - -// Formatting issues: -// - better comment formatting for /*-style comments at the end of a line (e.g. a declaration) -// when the comment spans multiple lines; if such a comment is just two lines, formatting is -// not idempotent -// - formatting of expression lists -// - should use blank instead of tab to separate one-line function bodies from -// the function header unless there is a group of consecutive one-liners - -// ---------------------------------------------------------------------------- -// Common AST nodes. - -// Print as many newlines as necessary (but at least min newlines) to get to -// the current line. ws is printed before the first line break. If newSection -// is set, the first line break is printed as formfeed. Returns 0 if no line -// breaks were printed, returns 1 if there was exactly one newline printed, -// and returns a value > 1 if there was a formfeed or more than one newline -// printed. -// -// TODO(gri): linebreak may add too many lines if the next statement at "line" -// is preceded by comments because the computation of n assumes -// the current position before the comment and the target position -// after the comment. Thus, after interspersing such comments, the -// space taken up by them is not considered to reduce the number of -// linebreaks. At the moment there is no easy way to know about -// future (not yet interspersed) comments in this function. -func (p *printer) linebreak(line, min int, ws whiteSpace, newSection bool) (nbreaks int) { - n := max(nlimit(line-p.pos.Line), min) - if n > 0 { - p.print(ws) - if newSection { - p.print(formfeed) - n-- - nbreaks = 2 - } - nbreaks += n - for ; n > 0; n-- { - p.print(newline) - } - } - return -} - -// setComment sets g as the next comment if g != nil and if node comments -// are enabled - this mode is used when printing source code fragments such -// as exports only. It assumes that there is no pending comment in p.comments -// and at most one pending comment in the p.comment cache. -func (p *printer) setComment(g *ast.CommentGroup) { - if g == nil || !p.useNodeComments { - return - } - if p.comments == nil { - // initialize p.comments lazily - p.comments = make([]*ast.CommentGroup, 1) - } else if p.cindex < len(p.comments) { - // for some reason there are pending comments; this - // should never happen - handle gracefully and flush - // all comments up to g, ignore anything after that - p.flush(p.posFor(g.List[0].Pos()), token.ILLEGAL) - p.comments = p.comments[0:1] - // in debug mode, report error - p.internalError("setComment found pending comments") - } - p.comments[0] = g - p.cindex = 0 - // don't overwrite any pending comment in the p.comment cache - // (there may be a pending comment when a line comment is - // immediately followed by a lead comment with no other - // tokens between) - if p.commentOffset == infinity { - p.nextComment() // get comment ready for use - } -} - -type exprListMode uint - -const ( - commaTerm exprListMode = 1 << iota // list is optionally terminated by a comma - noIndent // no extra indentation in multi-line lists -) - -// If indent is set, a multi-line identifier list is indented after the -// first linebreak encountered. -func (p *printer) identList(list []*ast.Ident, indent bool) { - // convert into an expression list so we can re-use exprList formatting - xlist := make([]ast.Expr, len(list)) - for i, x := range list { - xlist[i] = x - } - var mode exprListMode - if !indent { - mode = noIndent - } - p.exprList(token.NoPos, xlist, 1, mode, token.NoPos, false) -} - -const filteredMsg = "contains filtered or unexported fields" - -// Print a list of expressions. If the list spans multiple -// source lines, the original line breaks are respected between -// expressions. -// -// TODO(gri) Consider rewriting this to be independent of []ast.Expr -// so that we can use the algorithm for any kind of list -// -// (e.g., pass list via a channel over which to range). -func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exprListMode, next0 token.Pos, isIncomplete bool) { - if len(list) == 0 { - if isIncomplete { - prev := p.posFor(prev0) - next := p.posFor(next0) - if prev.IsValid() && prev.Line == next.Line { - p.print("/* " + filteredMsg + " */") - } else { - p.print(newline) - p.print(indent, "// "+filteredMsg, unindent, newline) - } - } - return - } - - prev := p.posFor(prev0) - next := p.posFor(next0) - line := p.lineFor(list[0].Pos()) - endLine := p.lineFor(list[len(list)-1].End()) - - if prev.IsValid() && prev.Line == line && line == endLine { - // all list entries on a single line - for i, x := range list { - if i > 0 { - // use position of expression following the comma as - // comma position for correct comment placement - p.setPos(x.Pos()) - p.print(token.COMMA, blank) - } - p.expr0(x, depth) - } - if isIncomplete { - p.print(token.COMMA, blank, "/* "+filteredMsg+" */") - } - return - } - - // list entries span multiple lines; - // use source code positions to guide line breaks - - // Don't add extra indentation if noIndent is set; - // i.e., pretend that the first line is already indented. - ws := ignore - if mode&noIndent == 0 { - ws = indent - } - - // The first linebreak is always a formfeed since this section must not - // depend on any previous formatting. - prevBreak := -1 // index of last expression that was followed by a linebreak - if prev.IsValid() && prev.Line < line && p.linebreak(line, 0, ws, true) > 0 { - ws = ignore - prevBreak = 0 - } - - // initialize expression/key size: a zero value indicates expr/key doesn't fit on a single line - size := 0 - - // We use the ratio between the geometric mean of the previous key sizes and - // the current size to determine if there should be a break in the alignment. - // To compute the geometric mean we accumulate the ln(size) values (lnsum) - // and the number of sizes included (count). - lnsum := 0.0 - count := 0 - - // print all list elements - prevLine := prev.Line - for i, x := range list { - line = p.lineFor(x.Pos()) - - // Determine if the next linebreak, if any, needs to use formfeed: - // in general, use the entire node size to make the decision; for - // key:value expressions, use the key size. - // TODO(gri) for a better result, should probably incorporate both - // the key and the node size into the decision process - useFF := true - - // Determine element size: All bets are off if we don't have - // position information for the previous and next token (likely - // generated code - simply ignore the size in this case by setting - // it to 0). - prevSize := size - const infinity = 1e6 // larger than any source line - size = p.nodeSize(x, infinity) - pair, isPair := x.(*ast.KeyValueExpr) - if size <= infinity && prev.IsValid() && next.IsValid() { - // x fits on a single line - if isPair { - size = p.nodeSize(pair.Key, infinity) // size <= infinity - } - } else { - // size too large or we don't have good layout information - size = 0 - } - - // If the previous line and the current line had single- - // line-expressions and the key sizes are small or the - // ratio between the current key and the geometric mean - // if the previous key sizes does not exceed a threshold, - // align columns and do not use formfeed. - if prevSize > 0 && size > 0 { - const smallSize = 40 - if count == 0 || prevSize <= smallSize && size <= smallSize { - useFF = false - } else { - const r = 2.5 // threshold - geomean := math.Exp(lnsum / float64(count)) // count > 0 - ratio := float64(size) / geomean - useFF = r*ratio <= 1 || r <= ratio - } - } - - needsLinebreak := 0 < prevLine && prevLine < line - if i > 0 { - // Use position of expression following the comma as - // comma position for correct comment placement, but - // only if the expression is on the same line. - if !needsLinebreak { - p.setPos(x.Pos()) - } - p.print(token.COMMA) - needsBlank := true - if needsLinebreak { - // Lines are broken using newlines so comments remain aligned - // unless useFF is set or there are multiple expressions on - // the same line in which case formfeed is used. - nbreaks := p.linebreak(line, 0, ws, useFF || prevBreak+1 < i) - if nbreaks > 0 { - ws = ignore - prevBreak = i - needsBlank = false // we got a line break instead - } - // If there was a new section or more than one new line - // (which means that the tabwriter will implicitly break - // the section), reset the geomean variables since we are - // starting a new group of elements with the next element. - if nbreaks > 1 { - lnsum = 0 - count = 0 - } - } - if needsBlank { - p.print(blank) - } - } - - if len(list) > 1 && isPair && size > 0 && needsLinebreak { - // We have a key:value expression that fits onto one line - // and it's not on the same line as the prior expression: - // Use a column for the key such that consecutive entries - // can align if possible. - // (needsLinebreak is set if we started a new line before) - p.expr(pair.Key) - p.setPos(pair.Colon) - p.print(token.COLON, vtab) - p.expr(pair.Value) - } else { - p.expr0(x, depth) - } - - if size > 0 { - lnsum += math.Log(float64(size)) - count++ - } - - prevLine = line - } - - if mode&commaTerm != 0 && next.IsValid() && p.pos.Line < next.Line { - // Print a terminating comma if the next token is on a new line. - p.print(token.COMMA) - if isIncomplete { - p.print(newline) - p.print("// " + filteredMsg) - } - if ws == ignore && mode&noIndent == 0 { - // unindent if we indented - p.print(unindent) - } - p.print(formfeed) // terminating comma needs a line break to look good - return - } - - if isIncomplete { - p.print(token.COMMA, newline) - p.print("// "+filteredMsg, newline) - } - - if ws == ignore && mode&noIndent == 0 { - // unindent if we indented - p.print(unindent) - } -} - -type paramMode int - -const ( - funcParam paramMode = iota - funcTParam - typeTParam -) - -func (p *printer) parameters(fields *ast.FieldList, mode paramMode) { - openTok, closeTok := token.LPAREN, token.RPAREN - if mode != funcParam { - openTok, closeTok = token.LBRACK, token.RBRACK - } - p.setPos(fields.Opening) - p.print(openTok) - if len(fields.List) > 0 { - prevLine := p.lineFor(fields.Opening) - ws := indent - for i, par := range fields.List { - // determine par begin and end line (may be different - // if there are multiple parameter names for this par - // or the type is on a separate line) - parLineBeg := p.lineFor(par.Pos()) - parLineEnd := p.lineFor(par.End()) - // separating "," if needed - needsLinebreak := 0 < prevLine && prevLine < parLineBeg - if i > 0 { - // use position of parameter following the comma as - // comma position for correct comma placement, but - // only if the next parameter is on the same line - if !needsLinebreak { - p.setPos(par.Pos()) - } - p.print(token.COMMA) - } - // separator if needed (linebreak or blank) - if needsLinebreak && p.linebreak(parLineBeg, 0, ws, true) > 0 { - // break line if the opening "(" or previous parameter ended on a different line - ws = ignore - } else if i > 0 { - p.print(blank) - } - // parameter names - if len(par.Names) > 0 { - // Very subtle: If we indented before (ws == ignore), identList - // won't indent again. If we didn't (ws == indent), identList will - // indent if the identList spans multiple lines, and it will outdent - // again at the end (and still ws == indent). Thus, a subsequent indent - // by a linebreak call after a type, or in the next multi-line identList - // will do the right thing. - p.identList(par.Names, ws == indent) - p.print(blank) - } - // parameter type - p.expr(stripParensAlways(par.Type)) - prevLine = parLineEnd - } - - // if the closing ")" is on a separate line from the last parameter, - // print an additional "," and line break - if closing := p.lineFor(fields.Closing); 0 < prevLine && prevLine < closing { - p.print(token.COMMA) - p.linebreak(closing, 0, ignore, true) - } else if mode == typeTParam && fields.NumFields() == 1 && combinesWithName(fields.List[0].Type) { - // A type parameter list [P T] where the name P and the type expression T syntactically - // combine to another valid (value) expression requires a trailing comma, as in [P *T,] - // (or an enclosing interface as in [P interface(*T)]), so that the type parameter list - // is not parsed as an array length [P*T]. - p.print(token.COMMA) - } - - // unindent if we indented - if ws == ignore { - p.print(unindent) - } - } - - p.setPos(fields.Closing) - p.print(closeTok) -} - -// combinesWithName reports whether a name followed by the expression x -// syntactically combines to another valid (value) expression. For instance -// using *T for x, "name *T" syntactically appears as the expression x*T. -// On the other hand, using P|Q or *P|~Q for x, "name P|Q" or name *P|~Q" -// cannot be combined into a valid (value) expression. -func combinesWithName(x ast.Expr) bool { - switch x := x.(type) { - case *ast.StarExpr: - // name *x.X combines to name*x.X if x.X is not a type element - return !isTypeElem(x.X) - case *ast.BinaryExpr: - return combinesWithName(x.X) && !isTypeElem(x.Y) - case *ast.ParenExpr: - // name(x) combines but we are making sure at - // the call site that x is never parenthesized. - panic("unexpected parenthesized expression") - } - return false -} - -// isTypeElem reports whether x is a (possibly parenthesized) type element expression. -// The result is false if x could be a type element OR an ordinary (value) expression. -func isTypeElem(x ast.Expr) bool { - switch x := x.(type) { - case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType: - return true - case *ast.UnaryExpr: - return x.Op == token.TILDE - case *ast.BinaryExpr: - return isTypeElem(x.X) || isTypeElem(x.Y) - case *ast.ParenExpr: - return isTypeElem(x.X) - } - return false -} - -func (p *printer) signature(sig *ast.FuncType) { - if sig.TypeParams != nil { - p.parameters(sig.TypeParams, funcTParam) - } - if sig.Params != nil { - p.parameters(sig.Params, funcParam) - } else { - p.print(token.LPAREN, token.RPAREN) - } - res := sig.Results - n := res.NumFields() - if n > 0 { - // res != nil - p.print(blank) - if n == 1 && res.List[0].Names == nil { - // single anonymous res; no ()'s - p.expr(stripParensAlways(res.List[0].Type)) - return - } - p.parameters(res, funcParam) - } -} - -func identListSize(list []*ast.Ident, maxSize int) (size int) { - for i, x := range list { - if i > 0 { - size += len(", ") - } - size += utf8.RuneCountInString(x.Name) - if size >= maxSize { - break - } - } - return -} - -func (p *printer) isOneLineFieldList(list []*ast.Field) bool { - if len(list) != 1 { - return false // allow only one field - } - f := list[0] - if f.Tag != nil || f.Comment != nil { - return false // don't allow tags or comments - } - // only name(s) and type - const maxSize = 30 // adjust as appropriate, this is an approximate value - namesSize := identListSize(f.Names, maxSize) - if namesSize > 0 { - namesSize = 1 // blank between names and types - } - typeSize := p.nodeSize(f.Type, maxSize) - return namesSize+typeSize <= maxSize -} - -func (p *printer) setLineComment(text string) { - p.setComment(&ast.CommentGroup{List: []*ast.Comment{{Slash: token.NoPos, Text: text}}}) -} - -func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) { - lbrace := fields.Opening - list := fields.List - rbrace := fields.Closing - hasComments := isIncomplete || p.commentBefore(p.posFor(rbrace)) - srcIsOneLine := lbrace.IsValid() && rbrace.IsValid() && p.lineFor(lbrace) == p.lineFor(rbrace) - - if !hasComments && srcIsOneLine { - // possibly a one-line struct/interface - if len(list) == 0 { - // no blank between keyword and {} in this case - p.setPos(lbrace) - p.print(token.LBRACE) - p.setPos(rbrace) - p.print(token.RBRACE) - return - } else if p.isOneLineFieldList(list) { - // small enough - print on one line - // (don't use identList and ignore source line breaks) - p.setPos(lbrace) - p.print(token.LBRACE, blank) - f := list[0] - if isStruct { - for i, x := range f.Names { - if i > 0 { - // no comments so no need for comma position - p.print(token.COMMA, blank) - } - p.expr(x) - } - if len(f.Names) > 0 { - p.print(blank) - } - p.expr(f.Type) - } else { // interface - if len(f.Names) > 0 { - name := f.Names[0] // method name - p.expr(name) - p.signature(f.Type.(*ast.FuncType)) // don't print "func" - } else { - // embedded interface - p.expr(f.Type) - } - } - p.print(blank) - p.setPos(rbrace) - p.print(token.RBRACE) - return - } - } - // hasComments || !srcIsOneLine - - p.print(blank) - p.setPos(lbrace) - p.print(token.LBRACE, indent) - if hasComments || len(list) > 0 { - p.print(formfeed) - } - - if isStruct { - - sep := vtab - if len(list) == 1 { - sep = blank - } - var line int - for i, f := range list { - if i > 0 { - p.linebreak(p.lineFor(f.Pos()), 1, ignore, p.linesFrom(line) > 0) - } - extraTabs := 0 - p.setComment(f.Doc) - p.recordLine(&line) - if len(f.Names) > 0 { - // named fields - p.identList(f.Names, false) - p.print(sep) - p.expr(f.Type) - extraTabs = 1 - } else { - // anonymous field - p.expr(f.Type) - extraTabs = 2 - } - if f.Tag != nil { - if len(f.Names) > 0 && sep == vtab { - p.print(sep) - } - p.print(sep) - p.expr(f.Tag) - extraTabs = 0 - } - if f.Comment != nil { - for ; extraTabs > 0; extraTabs-- { - p.print(sep) - } - p.setComment(f.Comment) - } - } - if isIncomplete { - if len(list) > 0 { - p.print(formfeed) - } - p.flush(p.posFor(rbrace), token.RBRACE) // make sure we don't lose the last line comment - p.setLineComment("// " + filteredMsg) - } - - } else { // interface - - var line int - var prev *ast.Ident // previous "type" identifier - for i, f := range list { - var name *ast.Ident // first name, or nil - if len(f.Names) > 0 { - name = f.Names[0] - } - if i > 0 { - // don't do a line break (min == 0) if we are printing a list of types - // TODO(gri) this doesn't work quite right if the list of types is - // spread across multiple lines - min := 1 - if prev != nil && name == prev { - min = 0 - } - p.linebreak(p.lineFor(f.Pos()), min, ignore, p.linesFrom(line) > 0) - } - p.setComment(f.Doc) - p.recordLine(&line) - if name != nil { - // method - p.expr(name) - p.signature(f.Type.(*ast.FuncType)) // don't print "func" - prev = nil - } else { - // embedded interface - p.expr(f.Type) - prev = nil - } - p.setComment(f.Comment) - } - if isIncomplete { - if len(list) > 0 { - p.print(formfeed) - } - p.flush(p.posFor(rbrace), token.RBRACE) // make sure we don't lose the last line comment - p.setLineComment("// contains filtered or unexported methods") - } - - } - p.print(unindent, formfeed) - p.setPos(rbrace) - p.print(token.RBRACE) -} - -// ---------------------------------------------------------------------------- -// Expressions - -func walkBinary(e *ast.BinaryExpr) (has4, has5 bool, maxProblem int) { - switch e.Op.Precedence() { - case 4: - has4 = true - case 5: - has5 = true - } - - switch l := e.X.(type) { - case *ast.BinaryExpr: - if l.Op.Precedence() < e.Op.Precedence() { - // parens will be inserted. - // pretend this is an *ast.ParenExpr and do nothing. - break - } - h4, h5, mp := walkBinary(l) - has4 = has4 || h4 - has5 = has5 || h5 - maxProblem = max(maxProblem, mp) - } - - switch r := e.Y.(type) { - case *ast.BinaryExpr: - if r.Op.Precedence() <= e.Op.Precedence() { - // parens will be inserted. - // pretend this is an *ast.ParenExpr and do nothing. - break - } - h4, h5, mp := walkBinary(r) - has4 = has4 || h4 - has5 = has5 || h5 - maxProblem = max(maxProblem, mp) - - case *ast.StarExpr: - if e.Op == token.QUO { // `*/` - maxProblem = 5 - } - - case *ast.UnaryExpr: - switch e.Op.String() + r.Op.String() { - case "/*", "&&", "&^": - maxProblem = 5 - case "++", "--": - maxProblem = max(maxProblem, 4) - } - } - return -} - -func cutoff(e *ast.BinaryExpr, depth int) int { - has4, has5, maxProblem := walkBinary(e) - if maxProblem > 0 { - return maxProblem + 1 - } - if has4 && has5 { - if depth == 1 { - return 5 - } - return 4 - } - if depth == 1 { - return 6 - } - return 4 -} - -func diffPrec(expr ast.Expr, prec int) int { - x, ok := expr.(*ast.BinaryExpr) - if !ok || prec != x.Op.Precedence() { - return 1 - } - return 0 -} - -func reduceDepth(depth int) int { - depth-- - if depth < 1 { - depth = 1 - } - return depth -} - -// Format the binary expression: decide the cutoff and then format. -// Let's call depth == 1 Normal mode, and depth > 1 Compact mode. -// (Algorithm suggestion by Russ Cox.) -// -// The precedences are: -// -// 5 * / % << >> & &^ -// 4 + - | ^ -// 3 == != < <= > >= -// 2 && -// 1 || -// -// The only decision is whether there will be spaces around levels 4 and 5. -// There are never spaces at level 6 (unary), and always spaces at levels 3 and below. -// -// To choose the cutoff, look at the whole expression but excluding primary -// expressions (function calls, parenthesized exprs), and apply these rules: -// -// 1. If there is a binary operator with a right side unary operand -// that would clash without a space, the cutoff must be (in order): -// -// /* 6 -// && 6 -// &^ 6 -// ++ 5 -// -- 5 -// -// (Comparison operators always have spaces around them.) -// -// 2. If there is a mix of level 5 and level 4 operators, then the cutoff -// is 5 (use spaces to distinguish precedence) in Normal mode -// and 4 (never use spaces) in Compact mode. -// -// 3. If there are no level 4 operators or no level 5 operators, then the -// cutoff is 6 (always use spaces) in Normal mode -// and 4 (never use spaces) in Compact mode. -func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int) { - prec := x.Op.Precedence() - if prec < prec1 { - // parenthesis needed - // Note: The parser inserts an ast.ParenExpr node; thus this case - // can only occur if the AST is created in a different way. - p.print(token.LPAREN) - p.expr0(x, reduceDepth(depth)) // parentheses undo one level of depth - p.print(token.RPAREN) - return - } - - printBlank := prec < cutoff - - ws := indent - p.expr1(x.X, prec, depth+diffPrec(x.X, prec)) - if printBlank { - p.print(blank) - } - xline := p.pos.Line // before the operator (it may be on the next line!) - yline := p.lineFor(x.Y.Pos()) - p.setPos(x.OpPos) - p.print(x.Op) - if xline != yline && xline > 0 && yline > 0 { - // at least one line break, but respect an extra empty line - // in the source - if p.linebreak(yline, 1, ws, true) > 0 { - ws = ignore - printBlank = false // no blank after line break - } - } - if printBlank { - p.print(blank) - } - p.expr1(x.Y, prec+1, depth+1) - if ws == ignore { - p.print(unindent) - } -} - -func isBinary(expr ast.Expr) bool { - _, ok := expr.(*ast.BinaryExpr) - return ok -} - -func (p *printer) expr1(expr ast.Expr, prec1, depth int) { - p.setPos(expr.Pos()) - - switch x := expr.(type) { - case *ast.BadExpr: - p.print("BadExpr") - - case *ast.Ident: - p.print(x) - - case *ast.BinaryExpr: - if depth < 1 { - p.internalError("depth < 1:", depth) - depth = 1 - } - p.binaryExpr(x, prec1, cutoff(x, depth), depth) - - case *ast.KeyValueExpr: - p.expr(x.Key) - p.setPos(x.Colon) - p.print(token.COLON, blank) - p.expr(x.Value) - - case *ast.StarExpr: - const prec = token.UnaryPrec - if prec < prec1 { - // parenthesis needed - p.print(token.LPAREN) - p.print(token.MUL) - p.expr(x.X) - p.print(token.RPAREN) - } else { - // no parenthesis needed - p.print(token.MUL) - p.expr(x.X) - } - - case *ast.UnaryExpr: - const prec = token.UnaryPrec - if prec < prec1 { - // parenthesis needed - p.print(token.LPAREN) - p.expr(x) - p.print(token.RPAREN) - } else { - // no parenthesis needed - p.print(x.Op) - if x.Op == token.RANGE { - // TODO(gri) Remove this code if it cannot be reached. - p.print(blank) - } - p.expr1(x.X, prec, depth) - } - - case *ast.BasicLit: - if p.Config.Mode&normalizeNumbers != 0 { - x = normalizedNumber(x) - } - p.print(x) - - case *ast.FuncLit: - p.setPos(x.Type.Pos()) - p.print(token.FUNC) - // See the comment in funcDecl about how the header size is computed. - startCol := p.out.Column - len("func") - p.signature(x.Type) - p.funcBody(p.distanceFrom(x.Type.Pos(), startCol), blank, x.Body) - - case *ast.ParenExpr: - if _, hasParens := x.X.(*ast.ParenExpr); hasParens { - // don't print parentheses around an already parenthesized expression - // TODO(gri) consider making this more general and incorporate precedence levels - p.expr0(x.X, depth) - } else { - p.print(token.LPAREN) - p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth - p.setPos(x.Rparen) - p.print(token.RPAREN) - } - - case *ast.SelectorExpr: - p.selectorExpr(x, depth, false) - - case *ast.TypeAssertExpr: - p.expr1(x.X, token.HighestPrec, depth) - p.print(token.PERIOD) - p.setPos(x.Lparen) - p.print(token.LPAREN) - if x.Type != nil { - p.expr(x.Type) - } else { - p.print(token.TYPE) - } - p.setPos(x.Rparen) - p.print(token.RPAREN) - - case *ast.IndexExpr: - // TODO(gri): should treat[] like parentheses and undo one level of depth - p.expr1(x.X, token.HighestPrec, 1) - p.setPos(x.Lbrack) - p.print(token.LBRACK) - p.expr0(x.Index, depth+1) - p.setPos(x.Rbrack) - p.print(token.RBRACK) - - case *ast.IndexListExpr: - // TODO(gri): as for IndexExpr, should treat [] like parentheses and undo - // one level of depth - p.expr1(x.X, token.HighestPrec, 1) - p.setPos(x.Lbrack) - p.print(token.LBRACK) - p.exprList(x.Lbrack, x.Indices, depth+1, commaTerm, x.Rbrack, false) - p.setPos(x.Rbrack) - p.print(token.RBRACK) - - case *ast.SliceExpr: - // TODO(gri): should treat[] like parentheses and undo one level of depth - p.expr1(x.X, token.HighestPrec, 1) - p.setPos(x.Lbrack) - p.print(token.LBRACK) - indices := []ast.Expr{x.Low, x.High} - if x.Max != nil { - indices = append(indices, x.Max) - } - // determine if we need extra blanks around ':' - var needsBlanks bool - if depth <= 1 { - var indexCount int - var hasBinaries bool - for _, x := range indices { - if x != nil { - indexCount++ - if isBinary(x) { - hasBinaries = true - } - } - } - if indexCount > 1 && hasBinaries { - needsBlanks = true - } - } - for i, x := range indices { - if i > 0 { - if indices[i-1] != nil && needsBlanks { - p.print(blank) - } - p.print(token.COLON) - if x != nil && needsBlanks { - p.print(blank) - } - } - if x != nil { - p.expr0(x, depth+1) - } - } - p.setPos(x.Rbrack) - p.print(token.RBRACK) - - case *ast.CallExpr: - if len(x.Args) > 1 { - depth++ - } - - // Conversions to literal function types or <-chan - // types require parentheses around the type. - paren := false - switch t := x.Fun.(type) { - case *ast.FuncType: - paren = true - case *ast.ChanType: - paren = t.Dir == ast.RECV - } - if paren { - p.print(token.LPAREN) - } - wasIndented := p.possibleSelectorExpr(x.Fun, token.HighestPrec, depth) - if paren { - p.print(token.RPAREN) - } - - p.setPos(x.Lparen) - p.print(token.LPAREN) - if x.Ellipsis.IsValid() { - p.exprList(x.Lparen, x.Args, depth, 0, x.Ellipsis, false) - p.setPos(x.Ellipsis) - p.print(token.ELLIPSIS) - if x.Rparen.IsValid() && p.lineFor(x.Ellipsis) < p.lineFor(x.Rparen) { - p.print(token.COMMA, formfeed) - } - } else { - p.exprList(x.Lparen, x.Args, depth, commaTerm, x.Rparen, false) - } - p.setPos(x.Rparen) - p.print(token.RPAREN) - if wasIndented { - p.print(unindent) - } - - case *ast.CompositeLit: - // composite literal elements that are composite literals themselves may have the type omitted - if x.Type != nil { - p.expr1(x.Type, token.HighestPrec, depth) - } - p.level++ - p.setPos(x.Lbrace) - p.print(token.LBRACE) - p.exprList(x.Lbrace, x.Elts, 1, commaTerm, x.Rbrace, x.Incomplete) - // do not insert extra line break following a /*-style comment - // before the closing '}' as it might break the code if there - // is no trailing ',' - mode := noExtraLinebreak - // do not insert extra blank following a /*-style comment - // before the closing '}' unless the literal is empty - if len(x.Elts) > 0 { - mode |= noExtraBlank - } - // need the initial indent to print lone comments with - // the proper level of indentation - p.print(indent, unindent, mode) - p.setPos(x.Rbrace) - p.print(token.RBRACE, mode) - p.level-- - - case *ast.Ellipsis: - p.print(token.ELLIPSIS) - if x.Elt != nil { - p.expr(x.Elt) - } - - case *ast.ArrayType: - p.print(token.LBRACK) - if x.Len != nil { - p.expr(x.Len) - } - p.print(token.RBRACK) - p.expr(x.Elt) - - case *ast.StructType: - p.print(token.STRUCT) - p.fieldList(x.Fields, true, x.Incomplete) - - case *ast.FuncType: - p.print(token.FUNC) - p.signature(x) - - case *ast.InterfaceType: - p.print(token.INTERFACE) - p.fieldList(x.Methods, false, x.Incomplete) - - case *ast.MapType: - p.print(token.MAP, token.LBRACK) - p.expr(x.Key) - p.print(token.RBRACK) - p.expr(x.Value) - - case *ast.ChanType: - switch x.Dir { - case ast.SEND | ast.RECV: - p.print(token.CHAN) - case ast.RECV: - p.print(token.ARROW, token.CHAN) // x.Arrow and x.Pos() are the same - case ast.SEND: - p.print(token.CHAN) - p.setPos(x.Arrow) - p.print(token.ARROW) - } - p.print(blank) - p.expr(x.Value) - - default: - panic("unreachable") - } -} - -// normalizedNumber rewrites base prefixes and exponents -// of numbers to use lower-case letters (0X123 to 0x123 and 1.2E3 to 1.2e3), -// and removes leading 0's from integer imaginary literals (0765i to 765i). -// It leaves hexadecimal digits alone. -// -// normalizedNumber doesn't modify the ast.BasicLit value lit points to. -// If lit is not a number or a number in canonical format already, -// lit is returned as is. Otherwise a new ast.BasicLit is created. -func normalizedNumber(lit *ast.BasicLit) *ast.BasicLit { - if lit.Kind != token.INT && lit.Kind != token.FLOAT && lit.Kind != token.IMAG { - return lit // not a number - nothing to do - } - if len(lit.Value) < 2 { - return lit // only one digit (common case) - nothing to do - } - // len(lit.Value) >= 2 - - // We ignore lit.Kind because for lit.Kind == token.IMAG the literal may be an integer - // or floating-point value, decimal or not. Instead, just consider the literal pattern. - x := lit.Value - switch x[:2] { - default: - // 0-prefix octal, decimal int, or float (possibly with 'i' suffix) - if i := strings.LastIndexByte(x, 'E'); i >= 0 { - x = x[:i] + "e" + x[i+1:] - break - } - // remove leading 0's from integer (but not floating-point) imaginary literals - if x[len(x)-1] == 'i' && !strings.ContainsAny(x, ".e") { - x = strings.TrimLeft(x, "0_") - if x == "i" { - x = "0i" - } - } - case "0X": - x = "0x" + x[2:] - // possibly a hexadecimal float - if i := strings.LastIndexByte(x, 'P'); i >= 0 { - x = x[:i] + "p" + x[i+1:] - } - case "0x": - // possibly a hexadecimal float - i := strings.LastIndexByte(x, 'P') - if i == -1 { - return lit // nothing to do - } - x = x[:i] + "p" + x[i+1:] - case "0O": - x = "0o" + x[2:] - case "0o": - return lit // nothing to do - case "0B": - x = "0b" + x[2:] - case "0b": - return lit // nothing to do - } - - return &ast.BasicLit{ValuePos: lit.ValuePos, Kind: lit.Kind, Value: x} -} - -func (p *printer) possibleSelectorExpr(expr ast.Expr, prec1, depth int) bool { - if x, ok := expr.(*ast.SelectorExpr); ok { - return p.selectorExpr(x, depth, true) - } - p.expr1(expr, prec1, depth) - return false -} - -// selectorExpr handles an *ast.SelectorExpr node and reports whether x spans -// multiple lines. -func (p *printer) selectorExpr(x *ast.SelectorExpr, depth int, isMethod bool) bool { - p.expr1(x.X, token.HighestPrec, depth) - p.print(token.PERIOD) - if line := p.lineFor(x.Sel.Pos()); p.pos.IsValid() && p.pos.Line < line { - p.print(indent, newline) - p.setPos(x.Sel.Pos()) - p.print(x.Sel) - if !isMethod { - p.print(unindent) - } - return true - } - p.setPos(x.Sel.Pos()) - p.print(x.Sel) - return false -} - -func (p *printer) expr0(x ast.Expr, depth int) { - p.expr1(x, token.LowestPrec, depth) -} - -func (p *printer) expr(x ast.Expr) { - const depth = 1 - p.expr1(x, token.LowestPrec, depth) -} - -// ---------------------------------------------------------------------------- -// Statements - -// Print the statement list indented, but without a newline after the last statement. -// Extra line breaks between statements in the source are respected but at most one -// empty line is printed between statements. -func (p *printer) stmtList(list []ast.Stmt, nindent int, nextIsRBrace bool) { - if nindent > 0 { - p.print(indent) - } - var line int - i := 0 - for _, s := range list { - // ignore empty statements (was issue 3466) - if _, isEmpty := s.(*ast.EmptyStmt); !isEmpty { - // nindent == 0 only for lists of switch/select case clauses; - // in those cases each clause is a new section - if len(p.output) > 0 { - // only print line break if we are not at the beginning of the output - // (i.e., we are not printing only a partial program) - p.linebreak(p.lineFor(s.Pos()), 1, ignore, i == 0 || nindent == 0 || p.linesFrom(line) > 0) - } - p.recordLine(&line) - p.stmt(s, nextIsRBrace && i == len(list)-1) - // labeled statements put labels on a separate line, but here - // we only care about the start line of the actual statement - // without label - correct line for each label - for t := s; ; { - lt, _ := t.(*ast.LabeledStmt) - if lt == nil { - break - } - line++ - t = lt.Stmt - } - i++ - } - } - if nindent > 0 { - p.print(unindent) - } -} - -// block prints an *ast.BlockStmt; it always spans at least two lines. -func (p *printer) block(b *ast.BlockStmt, nindent int) { - p.setPos(b.Lbrace) - p.print(token.LBRACE) - p.stmtList(b.List, nindent, true) - p.linebreak(p.lineFor(b.Rbrace), 1, ignore, true) - p.setPos(b.Rbrace) - p.print(token.RBRACE) -} - -func isTypeName(x ast.Expr) bool { - switch t := x.(type) { - case *ast.Ident: - return true - case *ast.SelectorExpr: - return isTypeName(t.X) - } - return false -} - -func stripParens(x ast.Expr) ast.Expr { - if px, strip := x.(*ast.ParenExpr); strip { - // parentheses must not be stripped if there are any - // unparenthesized composite literals starting with - // a type name - ast.Inspect(px.X, func(node ast.Node) bool { - switch x := node.(type) { - case *ast.ParenExpr: - // parentheses protect enclosed composite literals - return false - case *ast.CompositeLit: - if isTypeName(x.Type) { - strip = false // do not strip parentheses - } - return false - } - // in all other cases, keep inspecting - return true - }) - if strip { - return stripParens(px.X) - } - } - return x -} - -func stripParensAlways(x ast.Expr) ast.Expr { - if x, ok := x.(*ast.ParenExpr); ok { - return stripParensAlways(x.X) - } - return x -} - -func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, post ast.Stmt) { - p.print(blank) - needsBlank := false - if init == nil && post == nil { - // no semicolons required - if expr != nil { - p.expr(stripParens(expr)) - needsBlank = true - } - } else { - // all semicolons required - // (they are not separators, print them explicitly) - if init != nil { - p.stmt(init, false) - } - p.print(token.SEMICOLON, blank) - if expr != nil { - p.expr(stripParens(expr)) - needsBlank = true - } - if isForStmt { - p.print(token.SEMICOLON, blank) - needsBlank = false - if post != nil { - p.stmt(post, false) - needsBlank = true - } - } - } - if needsBlank { - p.print(blank) - } -} - -// indentList reports whether an expression list would look better if it -// were indented wholesale (starting with the very first element, rather -// than starting at the first line break). -func (p *printer) indentList(list []ast.Expr) bool { - // Heuristic: indentList reports whether there are more than one multi- - // line element in the list, or if there is any element that is not - // starting on the same line as the previous one ends. - if len(list) >= 2 { - b := p.lineFor(list[0].Pos()) - e := p.lineFor(list[len(list)-1].End()) - if 0 < b && b < e { - // list spans multiple lines - n := 0 // multi-line element count - line := b - for _, x := range list { - xb := p.lineFor(x.Pos()) - xe := p.lineFor(x.End()) - if line < xb { - // x is not starting on the same - // line as the previous one ended - return true - } - if xb < xe { - // x is a multi-line element - n++ - } - line = xe - } - return n > 1 - } - } - return false -} - -func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) { - p.setPos(stmt.Pos()) - - switch s := stmt.(type) { - case *ast.BadStmt: - p.print("BadStmt") - - case *ast.DeclStmt: - p.decl(s.Decl) - - case *ast.EmptyStmt: - // nothing to do - - case *ast.LabeledStmt: - // a "correcting" unindent immediately following a line break - // is applied before the line break if there is no comment - // between (see writeWhitespace) - p.print(unindent) - p.expr(s.Label) - p.setPos(s.Colon) - p.print(token.COLON, indent) - if e, isEmpty := s.Stmt.(*ast.EmptyStmt); isEmpty { - if !nextIsRBrace { - p.print(newline) - p.setPos(e.Pos()) - p.print(token.SEMICOLON) - break - } - } else { - p.linebreak(p.lineFor(s.Stmt.Pos()), 1, ignore, true) - } - p.stmt(s.Stmt, nextIsRBrace) - - case *ast.ExprStmt: - const depth = 1 - p.expr0(s.X, depth) - - case *ast.SendStmt: - const depth = 1 - p.expr0(s.Chan, depth) - p.print(blank) - p.setPos(s.Arrow) - p.print(token.ARROW, blank) - p.expr0(s.Value, depth) - - case *ast.IncDecStmt: - const depth = 1 - p.expr0(s.X, depth+1) - p.setPos(s.TokPos) - p.print(s.Tok) - - case *ast.AssignStmt: - depth := 1 - if len(s.Lhs) > 1 && len(s.Rhs) > 1 { - depth++ - } - p.exprList(s.Pos(), s.Lhs, depth, 0, s.TokPos, false) - p.print(blank) - p.setPos(s.TokPos) - p.print(s.Tok, blank) - p.exprList(s.TokPos, s.Rhs, depth, 0, token.NoPos, false) - - case *ast.GoStmt: - p.print(token.GO, blank) - p.expr(s.Call) - - case *ast.DeferStmt: - p.print(token.DEFER, blank) - p.expr(s.Call) - - case *ast.ReturnStmt: - p.print(token.RETURN) - if s.Results != nil { - p.print(blank) - // Use indentList heuristic to make corner cases look - // better (issue 1207). A more systematic approach would - // always indent, but this would cause significant - // reformatting of the code base and not necessarily - // lead to more nicely formatted code in general. - if p.indentList(s.Results) { - p.print(indent) - // Use NoPos so that a newline never goes before - // the results (see issue #32854). - p.exprList(token.NoPos, s.Results, 1, noIndent, token.NoPos, false) - p.print(unindent) - } else { - p.exprList(token.NoPos, s.Results, 1, 0, token.NoPos, false) - } - } - - case *ast.BranchStmt: - p.print(s.Tok) - if s.Label != nil { - p.print(blank) - p.expr(s.Label) - } - - case *ast.BlockStmt: - p.block(s, 1) - - case *ast.IfStmt: - p.print(token.IF) - p.controlClause(false, s.Init, s.Cond, nil) - p.block(s.Body, 1) - if s.Else != nil { - p.print(blank, token.ELSE, blank) - switch s.Else.(type) { - case *ast.BlockStmt, *ast.IfStmt: - p.stmt(s.Else, nextIsRBrace) - default: - // This can only happen with an incorrectly - // constructed AST. Permit it but print so - // that it can be parsed without errors. - p.print(token.LBRACE, indent, formfeed) - p.stmt(s.Else, true) - p.print(unindent, formfeed, token.RBRACE) - } - } - - case *ast.CaseClause: - if s.List != nil { - p.print(token.CASE, blank) - p.exprList(s.Pos(), s.List, 1, 0, s.Colon, false) - } else { - p.print(token.DEFAULT) - } - p.setPos(s.Colon) - p.print(token.COLON) - p.stmtList(s.Body, 1, nextIsRBrace) - - case *ast.SwitchStmt: - p.print(token.SWITCH) - p.controlClause(false, s.Init, s.Tag, nil) - p.block(s.Body, 0) - - case *ast.TypeSwitchStmt: - p.print(token.SWITCH) - if s.Init != nil { - p.print(blank) - p.stmt(s.Init, false) - p.print(token.SEMICOLON) - } - p.print(blank) - p.stmt(s.Assign, false) - p.print(blank) - p.block(s.Body, 0) - - case *ast.CommClause: - if s.Comm != nil { - p.print(token.CASE, blank) - p.stmt(s.Comm, false) - } else { - p.print(token.DEFAULT) - } - p.setPos(s.Colon) - p.print(token.COLON) - p.stmtList(s.Body, 1, nextIsRBrace) - - case *ast.SelectStmt: - p.print(token.SELECT, blank) - body := s.Body - if len(body.List) == 0 && !p.commentBefore(p.posFor(body.Rbrace)) { - // print empty select statement w/o comments on one line - p.setPos(body.Lbrace) - p.print(token.LBRACE) - p.setPos(body.Rbrace) - p.print(token.RBRACE) - } else { - p.block(body, 0) - } - - case *ast.ForStmt: - p.print(token.FOR) - p.controlClause(true, s.Init, s.Cond, s.Post) - p.block(s.Body, 1) - - case *ast.RangeStmt: - p.print(token.FOR, blank) - if s.Key != nil { - p.expr(s.Key) - if s.Value != nil { - // use position of value following the comma as - // comma position for correct comment placement - p.setPos(s.Value.Pos()) - p.print(token.COMMA, blank) - p.expr(s.Value) - } - p.print(blank) - p.setPos(s.TokPos) - p.print(s.Tok, blank) - } - p.print(token.RANGE, blank) - p.expr(stripParens(s.X)) - p.print(blank) - p.block(s.Body, 1) - - default: - panic("unreachable") - } -} - -// ---------------------------------------------------------------------------- -// Declarations - -// The keepTypeColumn function determines if the type column of a series of -// consecutive const or var declarations must be kept, or if initialization -// values (V) can be placed in the type column (T) instead. The i'th entry -// in the result slice is true if the type column in spec[i] must be kept. -// -// For example, the declaration: -// -// const ( -// foobar int = 42 // comment -// x = 7 // comment -// foo -// bar = 991 -// ) -// -// leads to the type/values matrix below. A run of value columns (V) can -// be moved into the type column if there is no type for any of the values -// in that column (we only move entire columns so that they align properly). -// -// matrix formatted result -// matrix -// T V -> T V -> true there is a T and so the type -// - V - V true column must be kept -// - - - - false -// - V V - false V is moved into T column -func keepTypeColumn(specs []ast.Spec) []bool { - m := make([]bool, len(specs)) - - populate := func(i, j int, keepType bool) { - if keepType { - for ; i < j; i++ { - m[i] = true - } - } - } - - i0 := -1 // if i0 >= 0 we are in a run and i0 is the start of the run - var keepType bool - for i, s := range specs { - t := s.(*ast.ValueSpec) - if t.Values != nil { - if i0 < 0 { - // start of a run of ValueSpecs with non-nil Values - i0 = i - keepType = false - } - } else { - if i0 >= 0 { - // end of a run - populate(i0, i, keepType) - i0 = -1 - } - } - if t.Type != nil { - keepType = true - } - } - if i0 >= 0 { - // end of a run - populate(i0, len(specs), keepType) - } - - return m -} - -func (p *printer) valueSpec(s *ast.ValueSpec, keepType bool) { - p.setComment(s.Doc) - p.identList(s.Names, false) // always present - extraTabs := 3 - if s.Type != nil || keepType { - p.print(vtab) - extraTabs-- - } - if s.Type != nil { - p.expr(s.Type) - } - if s.Values != nil { - p.print(vtab, token.ASSIGN, blank) - p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos, false) - extraTabs-- - } - if s.Comment != nil { - for ; extraTabs > 0; extraTabs-- { - p.print(vtab) - } - p.setComment(s.Comment) - } -} - -func sanitizeImportPath(lit *ast.BasicLit) *ast.BasicLit { - // Note: An unmodified AST generated by go/parser will already - // contain a backward- or double-quoted path string that does - // not contain any invalid characters, and most of the work - // here is not needed. However, a modified or generated AST - // may possibly contain non-canonical paths. Do the work in - // all cases since it's not too hard and not speed-critical. - - // if we don't have a proper string, be conservative and return whatever we have - if lit.Kind != token.STRING { - return lit - } - s, err := strconv.Unquote(lit.Value) - if err != nil { - return lit - } - - // if the string is an invalid path, return whatever we have - // - // spec: "Implementation restriction: A compiler may restrict - // ImportPaths to non-empty strings using only characters belonging - // to Unicode's L, M, N, P, and S general categories (the Graphic - // characters without spaces) and may also exclude the characters - // !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character - // U+FFFD." - if s == "" { - return lit - } - const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" - for _, r := range s { - if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { - return lit - } - } - - // otherwise, return the double-quoted path - s = strconv.Quote(s) - if s == lit.Value { - return lit // nothing wrong with lit - } - return &ast.BasicLit{ValuePos: lit.ValuePos, Kind: token.STRING, Value: s} -} - -// The parameter n is the number of specs in the group. If doIndent is set, -// multi-line identifier lists in the spec are indented when the first -// linebreak is encountered. -func (p *printer) spec(spec ast.Spec, n int, doIndent bool) { - switch s := spec.(type) { - case *ast.ImportSpec: - p.setComment(s.Doc) - if s.Name != nil { - p.expr(s.Name) - p.print(blank) - } - p.expr(sanitizeImportPath(s.Path)) - p.setComment(s.Comment) - p.setPos(s.EndPos) - - case *ast.ValueSpec: - if n != 1 { - p.internalError("expected n = 1; got", n) - } - p.setComment(s.Doc) - p.identList(s.Names, doIndent) // always present - if s.Type != nil { - p.print(blank) - p.expr(s.Type) - } - if s.Values != nil { - p.print(blank, token.ASSIGN, blank) - p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos, false) - } - p.setComment(s.Comment) - - case *ast.TypeSpec: - p.setComment(s.Doc) - p.expr(s.Name) - if s.TypeParams != nil { - p.parameters(s.TypeParams, typeTParam) - } - if n == 1 { - p.print(blank) - } else { - p.print(vtab) - } - if s.Assign.IsValid() { - p.print(token.ASSIGN, blank) - } - p.expr(s.Type) - p.setComment(s.Comment) - - default: - panic("unreachable") - } -} - -func (p *printer) genDecl(d *ast.GenDecl) { - p.setComment(d.Doc) - p.setPos(d.Pos()) - p.print(d.Tok, blank) - - if d.Lparen.IsValid() || len(d.Specs) != 1 { - // group of parenthesized declarations - p.setPos(d.Lparen) - p.print(token.LPAREN) - if n := len(d.Specs); n > 0 { - p.print(indent, formfeed) - if n > 1 && (d.Tok == token.CONST || d.Tok == token.VAR) { - // two or more grouped const/var declarations: - // determine if the type column must be kept - keepType := keepTypeColumn(d.Specs) - var line int - for i, s := range d.Specs { - if i > 0 { - p.linebreak(p.lineFor(s.Pos()), 1, ignore, p.linesFrom(line) > 0) - } - p.recordLine(&line) - p.valueSpec(s.(*ast.ValueSpec), keepType[i]) - } - } else { - var line int - for i, s := range d.Specs { - if i > 0 { - p.linebreak(p.lineFor(s.Pos()), 1, ignore, p.linesFrom(line) > 0) - } - p.recordLine(&line) - p.spec(s, n, false) - } - } - p.print(unindent, formfeed) - } - p.setPos(d.Rparen) - p.print(token.RPAREN) - - } else if len(d.Specs) > 0 { - // single declaration - p.spec(d.Specs[0], 1, true) - } -} - -// sizeCounter is an io.Writer which counts the number of bytes written, -// as well as whether a newline character was seen. -type sizeCounter struct { - hasNewline bool - size int -} - -func (c *sizeCounter) Write(p []byte) (int, error) { - if !c.hasNewline { - for _, b := range p { - if b == '\n' || b == '\f' { - c.hasNewline = true - break - } - } - } - c.size += len(p) - return len(p), nil -} - -// nodeSize determines the size of n in chars after formatting. -// The result is <= maxSize if the node fits on one line with at -// most maxSize chars and the formatted output doesn't contain -// any control chars. Otherwise, the result is > maxSize. -func (p *printer) nodeSize(n ast.Node, maxSize int) (size int) { - // nodeSize invokes the printer, which may invoke nodeSize - // recursively. For deep composite literal nests, this can - // lead to an exponential algorithm. Remember previous - // results to prune the recursion (was issue 1628). - if size, found := p.nodeSizes[n]; found { - return size - } - - size = maxSize + 1 // assume n doesn't fit - p.nodeSizes[n] = size - - // nodeSize computation must be independent of particular - // style so that we always get the same decision; print - // in RawFormat - cfg := Config{Mode: RawFormat} - var counter sizeCounter - if err := cfg.fprint(&counter, p.fset, n, p.nodeSizes); err != nil { - return - } - if counter.size <= maxSize && !counter.hasNewline { - // n fits in a single line - size = counter.size - p.nodeSizes[n] = size - } - return -} - -// numLines returns the number of lines spanned by node n in the original source. -func (p *printer) numLines(n ast.Node) int { - if from := n.Pos(); from.IsValid() { - if to := n.End(); to.IsValid() { - return p.lineFor(to) - p.lineFor(from) + 1 - } - } - return infinity -} - -// bodySize is like nodeSize but it is specialized for *ast.BlockStmt's. -func (p *printer) bodySize(b *ast.BlockStmt, maxSize int) int { - pos1 := b.Pos() - pos2 := b.Rbrace - if pos1.IsValid() && pos2.IsValid() && p.lineFor(pos1) != p.lineFor(pos2) { - // opening and closing brace are on different lines - don't make it a one-liner - return maxSize + 1 - } - if len(b.List) > 5 { - // too many statements - don't make it a one-liner - return maxSize + 1 - } - // otherwise, estimate body size - bodySize := p.commentSizeBefore(p.posFor(pos2)) - for i, s := range b.List { - if bodySize > maxSize { - break // no need to continue - } - if i > 0 { - bodySize += 2 // space for a semicolon and blank - } - bodySize += p.nodeSize(s, maxSize) - } - return bodySize -} - -// funcBody prints a function body following a function header of given headerSize. -// If the header's and block's size are "small enough" and the block is "simple enough", -// the block is printed on the current line, without line breaks, spaced from the header -// by sep. Otherwise the block's opening "{" is printed on the current line, followed by -// lines for the block's statements and its closing "}". -func (p *printer) funcBody(headerSize int, sep whiteSpace, b *ast.BlockStmt) { - if b == nil { - return - } - - // save/restore composite literal nesting level - defer func(level int) { - p.level = level - }(p.level) - p.level = 0 - - const maxSize = 100 - if headerSize+p.bodySize(b, maxSize) <= maxSize { - p.print(sep) - p.setPos(b.Lbrace) - p.print(token.LBRACE) - if len(b.List) > 0 { - p.print(blank) - for i, s := range b.List { - if i > 0 { - p.print(token.SEMICOLON, blank) - } - p.stmt(s, i == len(b.List)-1) - } - p.print(blank) - } - p.print(noExtraLinebreak) - p.setPos(b.Rbrace) - p.print(token.RBRACE, noExtraLinebreak) - return - } - - if sep != ignore { - p.print(blank) // always use blank - } - p.block(b, 1) -} - -// distanceFrom returns the column difference between p.out (the current output -// position) and startOutCol. If the start position is on a different line from -// the current position (or either is unknown), the result is infinity. -func (p *printer) distanceFrom(startPos token.Pos, startOutCol int) int { - if startPos.IsValid() && p.pos.IsValid() && p.posFor(startPos).Line == p.pos.Line { - return p.out.Column - startOutCol - } - return infinity -} - -func (p *printer) funcDecl(d *ast.FuncDecl) { - p.setComment(d.Doc) - p.setPos(d.Pos()) - p.print(token.FUNC, blank) - // We have to save startCol only after emitting FUNC; otherwise it can be on a - // different line (all whitespace preceding the FUNC is emitted only when the - // FUNC is emitted). - startCol := p.out.Column - len("func ") - if d.Recv != nil { - p.parameters(d.Recv, funcParam) // method: print receiver - p.print(blank) - } - p.expr(d.Name) - p.signature(d.Type) - p.funcBody(p.distanceFrom(d.Pos(), startCol), vtab, d.Body) -} - -func (p *printer) decl(decl ast.Decl) { - switch d := decl.(type) { - case *ast.BadDecl: - p.setPos(d.Pos()) - p.print("BadDecl") - case *ast.GenDecl: - p.genDecl(d) - case *ast.FuncDecl: - p.funcDecl(d) - default: - panic("unreachable") - } -} - -// ---------------------------------------------------------------------------- -// Files - -func declToken(decl ast.Decl) (tok token.Token) { - tok = token.ILLEGAL - switch d := decl.(type) { - case *ast.GenDecl: - tok = d.Tok - case *ast.FuncDecl: - tok = token.FUNC - } - return -} - -func (p *printer) declList(list []ast.Decl) { - tok := token.ILLEGAL - for _, d := range list { - prev := tok - tok = declToken(d) - // If the declaration token changed (e.g., from CONST to TYPE) - // or the next declaration has documentation associated with it, - // print an empty line between top-level declarations. - // (because p.linebreak is called with the position of d, which - // is past any documentation, the minimum requirement is satisfied - // even w/o the extra getDoc(d) nil-check - leave it in case the - // linebreak logic improves - there's already a TODO). - if len(p.output) > 0 { - // only print line break if we are not at the beginning of the output - // (i.e., we are not printing only a partial program) - min := 1 - if prev != tok || getDoc(d) != nil { - min = 2 - } - // start a new section if the next declaration is a function - // that spans multiple lines (see also issue #19544) - p.linebreak(p.lineFor(d.Pos()), min, ignore, tok == token.FUNC && p.numLines(d) > 1) - } - p.decl(d) - } -} - -func (p *printer) file(src *ast.File) { - p.setComment(src.Doc) - p.setPos(src.Pos()) - p.print(token.PACKAGE, blank) - p.expr(src.Name) - p.declList(src.Decls) - p.print(newline) -} diff --git a/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/printer.go b/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/printer.go deleted file mode 100644 index 11c056d6b..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/govendor/go/printer/printer.go +++ /dev/null @@ -1,1432 +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 printer implements printing of AST nodes. -package printer - -import ( - "fmt" - "go/ast" - "go/build/constraint" - "go/token" - "io" - "os" - "strings" - "sync" - "text/tabwriter" - "unicode" -) - -const ( - maxNewlines = 2 // max. number of newlines between source text - debug = false // enable for debugging - infinity = 1 << 30 -) - -type whiteSpace byte - -const ( - ignore = whiteSpace(0) - blank = whiteSpace(' ') - vtab = whiteSpace('\v') - newline = whiteSpace('\n') - formfeed = whiteSpace('\f') - indent = whiteSpace('>') - unindent = whiteSpace('<') -) - -// A pmode value represents the current printer mode. -type pmode int - -const ( - noExtraBlank pmode = 1 << iota // disables extra blank after /*-style comment - noExtraLinebreak // disables extra line break after /*-style comment -) - -type commentInfo struct { - cindex int // current comment index - comment *ast.CommentGroup // = printer.comments[cindex]; or nil - commentOffset int // = printer.posFor(printer.comments[cindex].List[0].Pos()).Offset; or infinity - commentNewline bool // true if the comment group contains newlines -} - -type printer struct { - // Configuration (does not change after initialization) - Config - fset *token.FileSet - - // Current state - output []byte // raw printer result - indent int // current indentation - level int // level == 0: outside composite literal; level > 0: inside composite literal - mode pmode // current printer mode - endAlignment bool // if set, terminate alignment immediately - impliedSemi bool // if set, a linebreak implies a semicolon - lastTok token.Token // last token printed (token.ILLEGAL if it's whitespace) - prevOpen token.Token // previous non-brace "open" token (, [, or token.ILLEGAL - wsbuf []whiteSpace // delayed white space - goBuild []int // start index of all //go:build comments in output - plusBuild []int // start index of all // +build comments in output - - // Positions - // The out position differs from the pos position when the result - // formatting differs from the source formatting (in the amount of - // white space). If there's a difference and SourcePos is set in - // ConfigMode, //line directives are used in the output to restore - // original source positions for a reader. - pos token.Position // current position in AST (source) space - out token.Position // current position in output space - last token.Position // value of pos after calling writeString - linePtr *int // if set, record out.Line for the next token in *linePtr - sourcePosErr error // if non-nil, the first error emitting a //line directive - - // The list of all source comments, in order of appearance. - comments []*ast.CommentGroup // may be nil - useNodeComments bool // if not set, ignore lead and line comments of nodes - - // Information about p.comments[p.cindex]; set up by nextComment. - commentInfo - - // Cache of already computed node sizes. - nodeSizes map[ast.Node]int - - // Cache of most recently computed line position. - cachedPos token.Pos - cachedLine int // line corresponding to cachedPos -} - -func (p *printer) internalError(msg ...any) { - if debug { - fmt.Print(p.pos.String() + ": ") - fmt.Println(msg...) - panic("mvdan.cc/gofumpt/internal/govendor/go/printer") - } -} - -// commentsHaveNewline reports whether a list of comments belonging to -// an *ast.CommentGroup contains newlines. Because the position information -// may only be partially correct, we also have to read the comment text. -func (p *printer) commentsHaveNewline(list []*ast.Comment) bool { - // len(list) > 0 - line := p.lineFor(list[0].Pos()) - for i, c := range list { - if i > 0 && p.lineFor(list[i].Pos()) != line { - // not all comments on the same line - return true - } - if t := c.Text; len(t) >= 2 && (t[1] == '/' || strings.Contains(t, "\n")) { - return true - } - } - _ = line - return false -} - -func (p *printer) nextComment() { - for p.cindex < len(p.comments) { - c := p.comments[p.cindex] - p.cindex++ - if list := c.List; len(list) > 0 { - p.comment = c - p.commentOffset = p.posFor(list[0].Pos()).Offset - p.commentNewline = p.commentsHaveNewline(list) - return - } - // we should not reach here (correct ASTs don't have empty - // ast.CommentGroup nodes), but be conservative and try again - } - // no more comments - p.commentOffset = infinity -} - -// commentBefore reports whether the current comment group occurs -// before the next position in the source code and printing it does -// not introduce implicit semicolons. -func (p *printer) commentBefore(next token.Position) bool { - return p.commentOffset < next.Offset && (!p.impliedSemi || !p.commentNewline) -} - -// commentSizeBefore returns the estimated size of the -// comments on the same line before the next position. -func (p *printer) commentSizeBefore(next token.Position) int { - // save/restore current p.commentInfo (p.nextComment() modifies it) - defer func(info commentInfo) { - p.commentInfo = info - }(p.commentInfo) - - size := 0 - for p.commentBefore(next) { - for _, c := range p.comment.List { - size += len(c.Text) - } - p.nextComment() - } - return size -} - -// recordLine records the output line number for the next non-whitespace -// token in *linePtr. It is used to compute an accurate line number for a -// formatted construct, independent of pending (not yet emitted) whitespace -// or comments. -func (p *printer) recordLine(linePtr *int) { - p.linePtr = linePtr -} - -// linesFrom returns the number of output lines between the current -// output line and the line argument, ignoring any pending (not yet -// emitted) whitespace or comments. It is used to compute an accurate -// size (in number of lines) for a formatted construct. -func (p *printer) linesFrom(line int) int { - return p.out.Line - line -} - -func (p *printer) posFor(pos token.Pos) token.Position { - // not used frequently enough to cache entire token.Position - return p.fset.PositionFor(pos, false /* absolute position */) -} - -func (p *printer) lineFor(pos token.Pos) int { - if pos != p.cachedPos { - p.cachedPos = pos - p.cachedLine = p.fset.PositionFor(pos, false /* absolute position */).Line - } - return p.cachedLine -} - -// writeLineDirective writes a //line directive if necessary. -func (p *printer) writeLineDirective(pos token.Position) { - if pos.IsValid() && (p.out.Line != pos.Line || p.out.Filename != pos.Filename) { - if strings.ContainsAny(pos.Filename, "\r\n") { - if p.sourcePosErr == nil { - p.sourcePosErr = fmt.Errorf("mvdan.cc/gofumpt/internal/govendor/go/printer: source filename contains unexpected newline character: %q", pos.Filename) - } - return - } - - p.output = append(p.output, tabwriter.Escape) // protect '\n' in //line from tabwriter interpretation - p.output = append(p.output, fmt.Sprintf("//line %s:%d\n", pos.Filename, pos.Line)...) - p.output = append(p.output, tabwriter.Escape) - // p.out must match the //line directive - p.out.Filename = pos.Filename - p.out.Line = pos.Line - } -} - -// writeIndent writes indentation. -func (p *printer) writeIndent() { - // use "hard" htabs - indentation columns - // must not be discarded by the tabwriter - n := p.Config.Indent + p.indent // include base indentation - for i := 0; i < n; i++ { - p.output = append(p.output, '\t') - } - - // update positions - p.pos.Offset += n - p.pos.Column += n - p.out.Column += n -} - -// writeByte writes ch n times to p.output and updates p.pos. -// Only used to write formatting (white space) characters. -func (p *printer) writeByte(ch byte, n int) { - if p.endAlignment { - // Ignore any alignment control character; - // and at the end of the line, break with - // a formfeed to indicate termination of - // existing columns. - switch ch { - case '\t', '\v': - ch = ' ' - case '\n', '\f': - ch = '\f' - p.endAlignment = false - } - } - - if p.out.Column == 1 { - // no need to write line directives before white space - p.writeIndent() - } - - for i := 0; i < n; i++ { - p.output = append(p.output, ch) - } - - // update positions - p.pos.Offset += n - if ch == '\n' || ch == '\f' { - p.pos.Line += n - p.out.Line += n - p.pos.Column = 1 - p.out.Column = 1 - return - } - p.pos.Column += n - p.out.Column += n -} - -// writeString writes the string s to p.output and updates p.pos, p.out, -// and p.last. If isLit is set, s is escaped w/ tabwriter.Escape characters -// to protect s from being interpreted by the tabwriter. -// -// Note: writeString is only used to write Go tokens, literals, and -// comments, all of which must be written literally. Thus, it is correct -// to always set isLit = true. However, setting it explicitly only when -// needed (i.e., when we don't know that s contains no tabs or line breaks) -// avoids processing extra escape characters and reduces run time of the -// printer benchmark by up to 10%. -func (p *printer) writeString(pos token.Position, s string, isLit bool) { - if p.out.Column == 1 { - if p.Config.Mode&SourcePos != 0 { - p.writeLineDirective(pos) - } - p.writeIndent() - } - - if pos.IsValid() { - // update p.pos (if pos is invalid, continue with existing p.pos) - // Note: Must do this after handling line beginnings because - // writeIndent updates p.pos if there's indentation, but p.pos - // is the position of s. - p.pos = pos - } - - if isLit { - // Protect s such that is passes through the tabwriter - // unchanged. Note that valid Go programs cannot contain - // tabwriter.Escape bytes since they do not appear in legal - // UTF-8 sequences. - p.output = append(p.output, tabwriter.Escape) - } - - if debug { - p.output = append(p.output, fmt.Sprintf("/*%s*/", pos)...) // do not update p.pos! - } - p.output = append(p.output, s...) - - // update positions - nlines := 0 - var li int // index of last newline; valid if nlines > 0 - for i := 0; i < len(s); i++ { - // Raw string literals may contain any character except back quote (`). - if ch := s[i]; ch == '\n' || ch == '\f' { - // account for line break - nlines++ - li = i - // A line break inside a literal will break whatever column - // formatting is in place; ignore any further alignment through - // the end of the line. - p.endAlignment = true - } - } - p.pos.Offset += len(s) - if nlines > 0 { - p.pos.Line += nlines - p.out.Line += nlines - c := len(s) - li - p.pos.Column = c - p.out.Column = c - } else { - p.pos.Column += len(s) - p.out.Column += len(s) - } - - if isLit { - p.output = append(p.output, tabwriter.Escape) - } - - p.last = p.pos -} - -// writeCommentPrefix writes the whitespace before a comment. -// If there is any pending whitespace, it consumes as much of -// it as is likely to help position the comment nicely. -// pos is the comment position, next the position of the item -// after all pending comments, prev is the previous comment in -// a group of comments (or nil), and tok is the next token. -func (p *printer) writeCommentPrefix(pos, next token.Position, prev *ast.Comment, tok token.Token) { - if len(p.output) == 0 { - // the comment is the first item to be printed - don't write any whitespace - return - } - - if pos.IsValid() && pos.Filename != p.last.Filename { - // comment in a different file - separate with newlines - p.writeByte('\f', maxNewlines) - return - } - - if pos.Line == p.last.Line && (prev == nil || prev.Text[1] != '/') { - // comment on the same line as last item: - // separate with at least one separator - hasSep := false - if prev == nil { - // first comment of a comment group - j := 0 - for i, ch := range p.wsbuf { - switch ch { - case blank: - // ignore any blanks before a comment - p.wsbuf[i] = ignore - continue - case vtab: - // respect existing tabs - important - // for proper formatting of commented structs - hasSep = true - continue - case indent: - // apply pending indentation - continue - } - j = i - break - } - p.writeWhitespace(j) - } - // make sure there is at least one separator - if !hasSep { - sep := byte('\t') - if pos.Line == next.Line { - // next item is on the same line as the comment - // (which must be a /*-style comment): separate - // with a blank instead of a tab - sep = ' ' - } - p.writeByte(sep, 1) - } - - } else { - // comment on a different line: - // separate with at least one line break - droppedLinebreak := false - j := 0 - for i, ch := range p.wsbuf { - switch ch { - case blank, vtab: - // ignore any horizontal whitespace before line breaks - p.wsbuf[i] = ignore - continue - case indent: - // apply pending indentation - continue - case unindent: - // if this is not the last unindent, apply it - // as it is (likely) belonging to the last - // construct (e.g., a multi-line expression list) - // and is not part of closing a block - if i+1 < len(p.wsbuf) && p.wsbuf[i+1] == unindent { - continue - } - // if the next token is not a closing }, apply the unindent - // if it appears that the comment is aligned with the - // token; otherwise assume the unindent is part of a - // closing block and stop (this scenario appears with - // comments before a case label where the comments - // apply to the next case instead of the current one) - if tok != token.RBRACE && pos.Column == next.Column { - continue - } - case newline, formfeed: - p.wsbuf[i] = ignore - droppedLinebreak = prev == nil // record only if first comment of a group - } - j = i - break - } - p.writeWhitespace(j) - - // determine number of linebreaks before the comment - n := 0 - if pos.IsValid() && p.last.IsValid() { - n = pos.Line - p.last.Line - if n < 0 { // should never happen - n = 0 - } - } - - // at the package scope level only (p.indent == 0), - // add an extra newline if we dropped one before: - // this preserves a blank line before documentation - // comments at the package scope level (issue 2570) - if p.indent == 0 && droppedLinebreak { - n++ - } - - // make sure there is at least one line break - // if the previous comment was a line comment - if n == 0 && prev != nil && prev.Text[1] == '/' { - n = 1 - } - - if n > 0 { - // use formfeeds to break columns before a comment; - // this is analogous to using formfeeds to separate - // individual lines of /*-style comments - p.writeByte('\f', nlimit(n)) - } - } -} - -// Returns true if s contains only white space -// (only tabs and blanks can appear in the printer's context). -func isBlank(s string) bool { - for i := 0; i < len(s); i++ { - if s[i] > ' ' { - return false - } - } - return true -} - -// commonPrefix returns the common prefix of a and b. -func commonPrefix(a, b string) string { - i := 0 - for i < len(a) && i < len(b) && a[i] == b[i] && (a[i] <= ' ' || a[i] == '*') { - i++ - } - return a[0:i] -} - -// trimRight returns s with trailing whitespace removed. -func trimRight(s string) string { - return strings.TrimRightFunc(s, unicode.IsSpace) -} - -// stripCommonPrefix removes a common prefix from /*-style comment lines (unless no -// comment line is indented, all but the first line have some form of space prefix). -// The prefix is computed using heuristics such that is likely that the comment -// contents are nicely laid out after re-printing each line using the printer's -// current indentation. -func stripCommonPrefix(lines []string) { - if len(lines) <= 1 { - return // at most one line - nothing to do - } - // len(lines) > 1 - - // The heuristic in this function tries to handle a few - // common patterns of /*-style comments: Comments where - // the opening /* and closing */ are aligned and the - // rest of the comment text is aligned and indented with - // blanks or tabs, cases with a vertical "line of stars" - // on the left, and cases where the closing */ is on the - // same line as the last comment text. - - // Compute maximum common white prefix of all but the first, - // last, and blank lines, and replace blank lines with empty - // lines (the first line starts with /* and has no prefix). - // In cases where only the first and last lines are not blank, - // such as two-line comments, or comments where all inner lines - // are blank, consider the last line for the prefix computation - // since otherwise the prefix would be empty. - // - // Note that the first and last line are never empty (they - // contain the opening /* and closing */ respectively) and - // thus they can be ignored by the blank line check. - prefix := "" - prefixSet := false - if len(lines) > 2 { - for i, line := range lines[1 : len(lines)-1] { - if isBlank(line) { - lines[1+i] = "" // range starts with lines[1] - } else { - if !prefixSet { - prefix = line - prefixSet = true - } - prefix = commonPrefix(prefix, line) - } - } - } - // If we don't have a prefix yet, consider the last line. - if !prefixSet { - line := lines[len(lines)-1] - prefix = commonPrefix(line, line) - } - - /* - * Check for vertical "line of stars" and correct prefix accordingly. - */ - lineOfStars := false - if p, _, ok := strings.Cut(prefix, "*"); ok { - // remove trailing blank from prefix so stars remain aligned - prefix = strings.TrimSuffix(p, " ") - lineOfStars = true - } else { - // No line of stars present. - // Determine the white space on the first line after the /* - // and before the beginning of the comment text, assume two - // blanks instead of the /* unless the first character after - // the /* is a tab. If the first comment line is empty but - // for the opening /*, assume up to 3 blanks or a tab. This - // whitespace may be found as suffix in the common prefix. - first := lines[0] - if isBlank(first[2:]) { - // no comment text on the first line: - // reduce prefix by up to 3 blanks or a tab - // if present - this keeps comment text indented - // relative to the /* and */'s if it was indented - // in the first place - i := len(prefix) - for n := 0; n < 3 && i > 0 && prefix[i-1] == ' '; n++ { - i-- - } - if i == len(prefix) && i > 0 && prefix[i-1] == '\t' { - i-- - } - prefix = prefix[0:i] - } else { - // comment text on the first line - suffix := make([]byte, len(first)) - n := 2 // start after opening /* - for n < len(first) && first[n] <= ' ' { - suffix[n] = first[n] - n++ - } - if n > 2 && suffix[2] == '\t' { - // assume the '\t' compensates for the /* - suffix = suffix[2:n] - } else { - // otherwise assume two blanks - suffix[0], suffix[1] = ' ', ' ' - suffix = suffix[0:n] - } - // Shorten the computed common prefix by the length of - // suffix, if it is found as suffix of the prefix. - prefix = strings.TrimSuffix(prefix, string(suffix)) - } - } - - // Handle last line: If it only contains a closing */, align it - // with the opening /*, otherwise align the text with the other - // lines. - last := lines[len(lines)-1] - closing := "*/" - before, _, _ := strings.Cut(last, closing) // closing always present - if isBlank(before) { - // last line only contains closing */ - if lineOfStars { - closing = " */" // add blank to align final star - } - lines[len(lines)-1] = prefix + closing - } else { - // last line contains more comment text - assume - // it is aligned like the other lines and include - // in prefix computation - prefix = commonPrefix(prefix, last) - } - - // Remove the common prefix from all but the first and empty lines. - for i, line := range lines { - if i > 0 && line != "" { - lines[i] = line[len(prefix):] - } - } -} - -func (p *printer) writeComment(comment *ast.Comment) { - text := comment.Text - pos := p.posFor(comment.Pos()) - - const linePrefix = "//line " - if strings.HasPrefix(text, linePrefix) && (!pos.IsValid() || pos.Column == 1) { - // Possibly a //-style line directive. - // Suspend indentation temporarily to keep line directive valid. - defer func(indent int) { p.indent = indent }(p.indent) - p.indent = 0 - } - - // shortcut common case of //-style comments - if text[1] == '/' { - if constraint.IsGoBuild(text) { - p.goBuild = append(p.goBuild, len(p.output)) - } else if constraint.IsPlusBuild(text) { - p.plusBuild = append(p.plusBuild, len(p.output)) - } - p.writeString(pos, trimRight(text), true) - return - } - - // for /*-style comments, print line by line and let the - // write function take care of the proper indentation - lines := strings.Split(text, "\n") - - // The comment started in the first column but is going - // to be indented. For an idempotent result, add indentation - // to all lines such that they look like they were indented - // before - this will make sure the common prefix computation - // is the same independent of how many times formatting is - // applied (was issue 1835). - if pos.IsValid() && pos.Column == 1 && p.indent > 0 { - for i, line := range lines[1:] { - lines[1+i] = " " + line - } - } - - stripCommonPrefix(lines) - - // write comment lines, separated by formfeed, - // without a line break after the last line - for i, line := range lines { - if i > 0 { - p.writeByte('\f', 1) - pos = p.pos - } - if len(line) > 0 { - p.writeString(pos, trimRight(line), true) - } - } -} - -// writeCommentSuffix writes a line break after a comment if indicated -// and processes any leftover indentation information. If a line break -// is needed, the kind of break (newline vs formfeed) depends on the -// pending whitespace. The writeCommentSuffix result indicates if a -// newline was written or if a formfeed was dropped from the whitespace -// buffer. -func (p *printer) writeCommentSuffix(needsLinebreak bool) (wroteNewline, droppedFF bool) { - for i, ch := range p.wsbuf { - switch ch { - case blank, vtab: - // ignore trailing whitespace - p.wsbuf[i] = ignore - case indent, unindent: - // don't lose indentation information - case newline, formfeed: - // if we need a line break, keep exactly one - // but remember if we dropped any formfeeds - if needsLinebreak { - needsLinebreak = false - wroteNewline = true - } else { - if ch == formfeed { - droppedFF = true - } - p.wsbuf[i] = ignore - } - } - } - p.writeWhitespace(len(p.wsbuf)) - - // make sure we have a line break - if needsLinebreak { - p.writeByte('\n', 1) - wroteNewline = true - } - - return -} - -// containsLinebreak reports whether the whitespace buffer contains any line breaks. -func (p *printer) containsLinebreak() bool { - for _, ch := range p.wsbuf { - if ch == newline || ch == formfeed { - return true - } - } - return false -} - -// intersperseComments consumes all comments that appear before the next token -// tok and prints it together with the buffered whitespace (i.e., the whitespace -// that needs to be written before the next token). A heuristic is used to mix -// the comments and whitespace. The intersperseComments result indicates if a -// newline was written or if a formfeed was dropped from the whitespace buffer. -func (p *printer) intersperseComments(next token.Position, tok token.Token) (wroteNewline, droppedFF bool) { - var last *ast.Comment - for p.commentBefore(next) { - list := p.comment.List - changed := false - if p.lastTok != token.IMPORT && // do not rewrite cgo's import "C" comments - p.posFor(p.comment.Pos()).Column == 1 && - p.posFor(p.comment.End()+1) == next { - // Unindented comment abutting next token position: - // a top-level doc comment. - list = formatDocComment(list) - changed = true - - if len(p.comment.List) > 0 && len(list) == 0 { - // The doc comment was removed entirely. - // Keep preceding whitespace. - p.writeCommentPrefix(p.posFor(p.comment.Pos()), next, last, tok) - // Change print state to continue at next. - p.pos = next - p.last = next - // There can't be any more comments. - p.nextComment() - return p.writeCommentSuffix(false) - } - } - for _, c := range list { - p.writeCommentPrefix(p.posFor(c.Pos()), next, last, tok) - p.writeComment(c) - last = c - } - // In case list was rewritten, change print state to where - // the original list would have ended. - if len(p.comment.List) > 0 && changed { - last = p.comment.List[len(p.comment.List)-1] - p.pos = p.posFor(last.End()) - p.last = p.pos - } - p.nextComment() - } - - if last != nil { - // If the last comment is a /*-style comment and the next item - // follows on the same line but is not a comma, and not a "closing" - // token immediately following its corresponding "opening" token, - // add an extra separator unless explicitly disabled. Use a blank - // as separator unless we have pending linebreaks, they are not - // disabled, and we are outside a composite literal, in which case - // we want a linebreak (issue 15137). - // TODO(gri) This has become overly complicated. We should be able - // to track whether we're inside an expression or statement and - // use that information to decide more directly. - needsLinebreak := false - if p.mode&noExtraBlank == 0 && - last.Text[1] == '*' && p.lineFor(last.Pos()) == next.Line && - tok != token.COMMA && - (tok != token.RPAREN || p.prevOpen == token.LPAREN) && - (tok != token.RBRACK || p.prevOpen == token.LBRACK) { - if p.containsLinebreak() && p.mode&noExtraLinebreak == 0 && p.level == 0 { - needsLinebreak = true - } else { - p.writeByte(' ', 1) - } - } - // Ensure that there is a line break after a //-style comment, - // before EOF, and before a closing '}' unless explicitly disabled. - if last.Text[1] == '/' || - tok == token.EOF || - tok == token.RBRACE && p.mode&noExtraLinebreak == 0 { - needsLinebreak = true - } - return p.writeCommentSuffix(needsLinebreak) - } - - // no comment was written - we should never reach here since - // intersperseComments should not be called in that case - p.internalError("intersperseComments called without pending comments") - return -} - -// writeWhitespace writes the first n whitespace entries. -func (p *printer) writeWhitespace(n int) { - // write entries - for i := 0; i < n; i++ { - switch ch := p.wsbuf[i]; ch { - case ignore: - // ignore! - case indent: - p.indent++ - case unindent: - p.indent-- - if p.indent < 0 { - p.internalError("negative indentation:", p.indent) - p.indent = 0 - } - case newline, formfeed: - // A line break immediately followed by a "correcting" - // unindent is swapped with the unindent - this permits - // proper label positioning. If a comment is between - // the line break and the label, the unindent is not - // part of the comment whitespace prefix and the comment - // will be positioned correctly indented. - if i+1 < n && p.wsbuf[i+1] == unindent { - // Use a formfeed to terminate the current section. - // Otherwise, a long label name on the next line leading - // to a wide column may increase the indentation column - // of lines before the label; effectively leading to wrong - // indentation. - p.wsbuf[i], p.wsbuf[i+1] = unindent, formfeed - i-- // do it again - continue - } - fallthrough - default: - p.writeByte(byte(ch), 1) - } - } - - // shift remaining entries down - l := copy(p.wsbuf, p.wsbuf[n:]) - p.wsbuf = p.wsbuf[:l] -} - -// ---------------------------------------------------------------------------- -// Printing interface - -// nlimit limits n to maxNewlines. -func nlimit(n int) int { - return min(n, maxNewlines) -} - -func mayCombine(prev token.Token, next byte) (b bool) { - switch prev { - case token.INT: - b = next == '.' // 1. - case token.ADD: - b = next == '+' // ++ - case token.SUB: - b = next == '-' // -- - case token.QUO: - b = next == '*' // /* - case token.LSS: - b = next == '-' || next == '<' // <- or << - case token.AND: - b = next == '&' || next == '^' // && or &^ - } - return -} - -func (p *printer) setPos(pos token.Pos) { - if pos.IsValid() { - p.pos = p.posFor(pos) // accurate position of next item - } -} - -// print prints a list of "items" (roughly corresponding to syntactic -// tokens, but also including whitespace and formatting information). -// It is the only print function that should be called directly from -// any of the AST printing functions in nodes.go. -// -// Whitespace is accumulated until a non-whitespace token appears. Any -// comments that need to appear before that token are printed first, -// taking into account the amount and structure of any pending white- -// space for best comment placement. Then, any leftover whitespace is -// printed, followed by the actual token. -func (p *printer) print(args ...any) { - for _, arg := range args { - // information about the current arg - var data string - var isLit bool - var impliedSemi bool // value for p.impliedSemi after this arg - - // record previous opening token, if any - switch p.lastTok { - case token.ILLEGAL: - // ignore (white space) - case token.LPAREN, token.LBRACK: - p.prevOpen = p.lastTok - default: - // other tokens followed any opening token - p.prevOpen = token.ILLEGAL - } - - switch x := arg.(type) { - case pmode: - // toggle printer mode - p.mode ^= x - continue - - case whiteSpace: - if x == ignore { - // don't add ignore's to the buffer; they - // may screw up "correcting" unindents (see - // LabeledStmt) - continue - } - i := len(p.wsbuf) - if i == cap(p.wsbuf) { - // Whitespace sequences are very short so this should - // never happen. Handle gracefully (but possibly with - // bad comment placement) if it does happen. - p.writeWhitespace(i) - i = 0 - } - p.wsbuf = p.wsbuf[0 : i+1] - p.wsbuf[i] = x - if x == newline || x == formfeed { - // newlines affect the current state (p.impliedSemi) - // and not the state after printing arg (impliedSemi) - // because comments can be interspersed before the arg - // in this case - p.impliedSemi = false - } - p.lastTok = token.ILLEGAL - continue - - case *ast.Ident: - data = x.Name - impliedSemi = true - p.lastTok = token.IDENT - - case *ast.BasicLit: - data = x.Value - isLit = true - impliedSemi = true - p.lastTok = x.Kind - - case token.Token: - s := x.String() - if mayCombine(p.lastTok, s[0]) { - // the previous and the current token must be - // separated by a blank otherwise they combine - // into a different incorrect token sequence - // (except for token.INT followed by a '.' this - // should never happen because it is taken care - // of via binary expression formatting) - if len(p.wsbuf) != 0 { - p.internalError("whitespace buffer not empty") - } - p.wsbuf = p.wsbuf[0:1] - p.wsbuf[0] = ' ' - } - data = s - // some keywords followed by a newline imply a semicolon - switch x { - case token.BREAK, token.CONTINUE, token.FALLTHROUGH, token.RETURN, - token.INC, token.DEC, token.RPAREN, token.RBRACK, token.RBRACE: - impliedSemi = true - } - p.lastTok = x - - case string: - // incorrect AST - print error message - data = x - isLit = true - impliedSemi = true - p.lastTok = token.STRING - - default: - fmt.Fprintf(os.Stderr, "print: unsupported argument %v (%T)\n", arg, arg) - panic("mvdan.cc/gofumpt/internal/govendor/go/printer type") - } - // data != "" - - next := p.pos // estimated/accurate position of next item - wroteNewline, droppedFF := p.flush(next, p.lastTok) - - // intersperse extra newlines if present in the source and - // if they don't cause extra semicolons (don't do this in - // flush as it will cause extra newlines at the end of a file) - if !p.impliedSemi { - n := nlimit(next.Line - p.pos.Line) - // don't exceed maxNewlines if we already wrote one - if wroteNewline && n == maxNewlines { - n = maxNewlines - 1 - } - if n > 0 { - ch := byte('\n') - if droppedFF { - ch = '\f' // use formfeed since we dropped one before - } - p.writeByte(ch, n) - impliedSemi = false - } - } - - // the next token starts now - record its line number if requested - if p.linePtr != nil { - *p.linePtr = p.out.Line - p.linePtr = nil - } - - p.writeString(next, data, isLit) - p.impliedSemi = impliedSemi - } -} - -// flush prints any pending comments and whitespace occurring textually -// before the position of the next token tok. The flush result indicates -// if a newline was written or if a formfeed was dropped from the whitespace -// buffer. -func (p *printer) flush(next token.Position, tok token.Token) (wroteNewline, droppedFF bool) { - if p.commentBefore(next) { - // if there are comments before the next item, intersperse them - wroteNewline, droppedFF = p.intersperseComments(next, tok) - } else { - // otherwise, write any leftover whitespace - p.writeWhitespace(len(p.wsbuf)) - } - return -} - -// getDoc returns the ast.CommentGroup associated with n, if any. -func getDoc(n ast.Node) *ast.CommentGroup { - switch n := n.(type) { - case *ast.Field: - return n.Doc - case *ast.ImportSpec: - return n.Doc - case *ast.ValueSpec: - return n.Doc - case *ast.TypeSpec: - return n.Doc - case *ast.GenDecl: - return n.Doc - case *ast.FuncDecl: - return n.Doc - case *ast.File: - return n.Doc - } - return nil -} - -func getLastComment(n ast.Node) *ast.CommentGroup { - switch n := n.(type) { - case *ast.Field: - return n.Comment - case *ast.ImportSpec: - return n.Comment - case *ast.ValueSpec: - return n.Comment - case *ast.TypeSpec: - return n.Comment - case *ast.GenDecl: - if len(n.Specs) > 0 { - return getLastComment(n.Specs[len(n.Specs)-1]) - } - case *ast.File: - if len(n.Comments) > 0 { - return n.Comments[len(n.Comments)-1] - } - } - return nil -} - -func (p *printer) printNode(node any) error { - // unpack *CommentedNode, if any - var comments []*ast.CommentGroup - if cnode, ok := node.(*CommentedNode); ok { - node = cnode.Node - comments = cnode.Comments - } - - if comments != nil { - // commented node - restrict comment list to relevant range - n, ok := node.(ast.Node) - if !ok { - goto unsupported - } - beg := n.Pos() - end := n.End() - // if the node has associated documentation, - // include that commentgroup in the range - // (the comment list is sorted in the order - // of the comment appearance in the source code) - if doc := getDoc(n); doc != nil { - beg = doc.Pos() - } - if com := getLastComment(n); com != nil { - if e := com.End(); e > end { - end = e - } - } - // token.Pos values are global offsets, we can - // compare them directly - i := 0 - for i < len(comments) && comments[i].End() < beg { - i++ - } - j := i - for j < len(comments) && comments[j].Pos() < end { - j++ - } - if i < j { - p.comments = comments[i:j] - } - } else if n, ok := node.(*ast.File); ok { - // use ast.File comments, if any - p.comments = n.Comments - } - - // if there are no comments, use node comments - p.useNodeComments = p.comments == nil - - // get comments ready for use - p.nextComment() - - p.print(pmode(0)) - - // format node - switch n := node.(type) { - case ast.Expr: - p.expr(n) - case ast.Stmt: - // A labeled statement will un-indent to position the label. - // Set p.indent to 1 so we don't get indent "underflow". - if _, ok := n.(*ast.LabeledStmt); ok { - p.indent = 1 - } - p.stmt(n, false) - case ast.Decl: - p.decl(n) - case ast.Spec: - p.spec(n, 1, false) - case []ast.Stmt: - // A labeled statement will un-indent to position the label. - // Set p.indent to 1 so we don't get indent "underflow". - for _, s := range n { - if _, ok := s.(*ast.LabeledStmt); ok { - p.indent = 1 - } - } - p.stmtList(n, 0, false) - case []ast.Decl: - p.declList(n) - case *ast.File: - p.file(n) - default: - goto unsupported - } - - return p.sourcePosErr - -unsupported: - return fmt.Errorf("mvdan.cc/gofumpt/internal/govendor/go/printer: unsupported node type %T", node) -} - -// ---------------------------------------------------------------------------- -// Trimmer - -// A trimmer is an io.Writer filter for stripping tabwriter.Escape -// characters, trailing blanks and tabs, and for converting formfeed -// and vtab characters into newlines and htabs (in case no tabwriter -// is used). Text bracketed by tabwriter.Escape characters is passed -// through unchanged. -type trimmer struct { - output io.Writer - state int - space []byte -} - -// trimmer is implemented as a state machine. -// It can be in one of the following states: -const ( - inSpace = iota // inside space - inEscape // inside text bracketed by tabwriter.Escapes - inText // inside text -) - -func (p *trimmer) resetSpace() { - p.state = inSpace - p.space = p.space[0:0] -} - -// Design note: It is tempting to eliminate extra blanks occurring in -// whitespace in this function as it could simplify some -// of the blanks logic in the node printing functions. -// However, this would mess up any formatting done by -// the tabwriter. - -var aNewline = []byte("\n") - -func (p *trimmer) Write(data []byte) (n int, err error) { - // invariants: - // p.state == inSpace: - // p.space is unwritten - // p.state == inEscape, inText: - // data[m:n] is unwritten - m := 0 - var b byte - for n, b = range data { - if b == '\v' { - b = '\t' // convert to htab - } - switch p.state { - case inSpace: - switch b { - case '\t', ' ': - p.space = append(p.space, b) - case '\n', '\f': - p.resetSpace() // discard trailing space - _, err = p.output.Write(aNewline) - case tabwriter.Escape: - _, err = p.output.Write(p.space) - p.state = inEscape - m = n + 1 // +1: skip tabwriter.Escape - default: - _, err = p.output.Write(p.space) - p.state = inText - m = n - } - case inEscape: - if b == tabwriter.Escape { - _, err = p.output.Write(data[m:n]) - p.resetSpace() - } - case inText: - switch b { - case '\t', ' ': - _, err = p.output.Write(data[m:n]) - p.resetSpace() - p.space = append(p.space, b) - case '\n', '\f': - _, err = p.output.Write(data[m:n]) - p.resetSpace() - if err == nil { - _, err = p.output.Write(aNewline) - } - case tabwriter.Escape: - _, err = p.output.Write(data[m:n]) - p.state = inEscape - m = n + 1 // +1: skip tabwriter.Escape - } - default: - panic("unreachable") - } - if err != nil { - return - } - } - n = len(data) - - switch p.state { - case inEscape, inText: - _, err = p.output.Write(data[m:n]) - p.resetSpace() - } - - return -} - -// ---------------------------------------------------------------------------- -// Public interface - -// A Mode value is a set of flags (or 0). They control printing. -type Mode uint - -const ( - RawFormat Mode = 1 << iota // do not use a tabwriter; if set, UseSpaces is ignored - TabIndent // use tabs for indentation independent of UseSpaces - UseSpaces // use spaces instead of tabs for alignment - SourcePos // emit //line directives to preserve original source positions -) - -// The mode below is not included in printer's public API because -// editing code text is deemed out of scope. Because this mode is -// unexported, it's also possible to modify or remove it based on -// the evolving needs of mvdan.cc/gofumpt/internal/govendor/go/format and cmd/gofmt without breaking -// users. See discussion in CL 240683. -const ( - // normalizeNumbers means to canonicalize number - // literal prefixes and exponents while printing. - // - // This value is known in and used by mvdan.cc/gofumpt/internal/govendor/go/format and cmd/gofmt. - // It is currently more convenient and performant for those - // packages to apply number normalization during printing, - // rather than by modifying the AST in advance. - normalizeNumbers Mode = 1 << 30 -) - -// A Config node controls the output of Fprint. -type Config struct { - Mode Mode // default: 0 - Tabwidth int // default: 8 - Indent int // default: 0 (all code is indented at least by this much) -} - -var printerPool = sync.Pool{ - New: func() any { - return &printer{ - // Whitespace sequences are short. - wsbuf: make([]whiteSpace, 0, 16), - // We start the printer with a 16K output buffer, which is currently - // larger than about 80% of Go files in the standard library. - output: make([]byte, 0, 16<<10), - } - }, -} - -func newPrinter(cfg *Config, fset *token.FileSet, nodeSizes map[ast.Node]int) *printer { - p := printerPool.Get().(*printer) - *p = printer{ - Config: *cfg, - fset: fset, - pos: token.Position{Line: 1, Column: 1}, - out: token.Position{Line: 1, Column: 1}, - wsbuf: p.wsbuf[:0], - nodeSizes: nodeSizes, - cachedPos: -1, - output: p.output[:0], - } - return p -} - -func (p *printer) free() { - // Hard limit on buffer size; see https://golang.org/issue/23199. - if cap(p.output) > 64<<10 { - return - } - - printerPool.Put(p) -} - -// fprint implements Fprint and takes a nodesSizes map for setting up the printer state. -func (cfg *Config) fprint(output io.Writer, fset *token.FileSet, node any, nodeSizes map[ast.Node]int) (err error) { - // print node - p := newPrinter(cfg, fset, nodeSizes) - defer p.free() - if err = p.printNode(node); err != nil { - return - } - // print outstanding comments - p.impliedSemi = false // EOF acts like a newline - p.flush(token.Position{Offset: infinity, Line: infinity}, token.EOF) - - // output is buffered in p.output now. - // fix //go:build and // +build comments if needed. - p.fixGoBuildLines() - - // redirect output through a trimmer to eliminate trailing whitespace - // (Input to a tabwriter must be untrimmed since trailing tabs provide - // formatting information. The tabwriter could provide trimming - // functionality but no tabwriter is used when RawFormat is set.) - output = &trimmer{output: output} - - // redirect output through a tabwriter if necessary - if cfg.Mode&RawFormat == 0 { - minwidth := cfg.Tabwidth - - padchar := byte('\t') - if cfg.Mode&UseSpaces != 0 { - padchar = ' ' - } - - twmode := tabwriter.DiscardEmptyColumns - if cfg.Mode&TabIndent != 0 { - minwidth = 0 - twmode |= tabwriter.TabIndent - } - - output = tabwriter.NewWriter(output, minwidth, cfg.Tabwidth, 1, padchar, twmode) - } - - // write printer result via tabwriter/trimmer to output - if _, err = output.Write(p.output); err != nil { - return - } - - // flush tabwriter, if any - if tw, _ := output.(*tabwriter.Writer); tw != nil { - err = tw.Flush() - } - - return -} - -// A CommentedNode bundles an AST node and corresponding comments. -// It may be provided as argument to any of the [Fprint] functions. -type CommentedNode struct { - Node any // *ast.File, or ast.Expr, ast.Decl, ast.Spec, or ast.Stmt - Comments []*ast.CommentGroup -} - -// Fprint "pretty-prints" an AST node to output for a given configuration cfg. -// Position information is interpreted relative to the file set fset. -// The node type must be *[ast.File], *[CommentedNode], [][ast.Decl], [][ast.Stmt], -// or assignment-compatible to [ast.Expr], [ast.Decl], [ast.Spec], or [ast.Stmt]. -func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node any) error { - return cfg.fprint(output, fset, node, make(map[ast.Node]int)) -} - -// Fprint "pretty-prints" an AST node to output. -// It calls [Config.Fprint] with default settings. -// Note that gofmt uses tabs for indentation but spaces for alignment; -// use format.Node (package mvdan.cc/gofumpt/internal/govendor/go/format) for output that matches gofmt. -func Fprint(output io.Writer, fset *token.FileSet, node any) error { - return (&Config{Tabwidth: 8}).Fprint(output, fset, node) -} diff --git a/vendor/mvdan.cc/gofumpt/internal/version/version.go b/vendor/mvdan.cc/gofumpt/internal/version/version.go deleted file mode 100644 index 785b6b317..000000000 --- a/vendor/mvdan.cc/gofumpt/internal/version/version.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2020, Daniel Martí -// See LICENSE for licensing information - -package version - -import ( - "encoding/json" - "fmt" - "os" - "runtime" - "runtime/debug" - "time" - - "golang.org/x/mod/module" -) - -// Note that this is not a main package, so a "var version" will not work with -// our go-cross script which uses -ldflags=main.version=xxx. - -const ourModulePath = "mvdan.cc/gofumpt" - -const fallbackVersion = "(devel)" // to match the default from runtime/debug - -func findModule(info *debug.BuildInfo, modulePath string) *debug.Module { - if info.Main.Path == modulePath { - return &info.Main - } - for _, dep := range info.Deps { - if dep.Path == modulePath { - return dep - } - } - return nil -} - -func gofumptVersion() string { - info, ok := debug.ReadBuildInfo() - if !ok { - return fallbackVersion // no build info available - } - // Note that gofumpt may be used as a library via the format package, - // so we cannot assume it is the main module in the build. - mod := findModule(info, ourModulePath) - if mod == nil { - return fallbackVersion // not found? - } - if mod.Replace != nil { - mod = mod.Replace - } - - // If we found a meaningful version, we are done. - // If gofumpt is not the main module, stop as well, - // as VCS info is only for the main module. - if mod.Version != "(devel)" || mod != &info.Main { - return mod.Version - } - - // Fall back to trying to use VCS information. - // Until https://github.com/golang/go/issues/50603 is implemented, - // manually construct something like a pseudo-version. - // TODO: remove when this code is dead, hopefully in Go 1.20. - - // For the tests, as we don't want the VCS information to change over time. - if v := os.Getenv("GARBLE_TEST_BUILDSETTINGS"); v != "" { - var extra []debug.BuildSetting - if err := json.Unmarshal([]byte(v), &extra); err != nil { - panic(err) - } - info.Settings = append(info.Settings, extra...) - } - - var vcsTime time.Time - var vcsRevision string - for _, setting := range info.Settings { - switch setting.Key { - case "vcs.time": - // If the format is invalid, we'll print a zero timestamp. - vcsTime, _ = time.Parse(time.RFC3339Nano, setting.Value) - case "vcs.revision": - vcsRevision = setting.Value - if len(vcsRevision) > 12 { - vcsRevision = vcsRevision[:12] - } - } - } - if vcsRevision != "" { - return module.PseudoVersion("", "", vcsTime, vcsRevision) - } - return fallbackVersion -} - -func goVersion() string { - // For the tests, as we don't want the Go version to change over time. - if testVersion := os.Getenv("GO_VERSION_TEST"); testVersion != "" { - return testVersion - } - return runtime.Version() -} - -func String(injected string) string { - if injected != "" { - return fmt.Sprintf("%s (%s)", injected, goVersion()) - } - return fmt.Sprintf("%s (%s)", gofumptVersion(), goVersion()) -} diff --git a/vendor/mvdan.cc/unparam/LICENSE b/vendor/mvdan.cc/unparam/LICENSE deleted file mode 100644 index a06c5ebfc..000000000 --- a/vendor/mvdan.cc/unparam/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2017, Daniel Martí. 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 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 -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/mvdan.cc/unparam/check/check.go b/vendor/mvdan.cc/unparam/check/check.go deleted file mode 100644 index 2bda01305..000000000 --- a/vendor/mvdan.cc/unparam/check/check.go +++ /dev/null @@ -1,1025 +0,0 @@ -// Copyright (c) 2017, Daniel Martí -// See LICENSE for licensing information - -// Package check implements the unparam linter. Note that its API is not -// stable. -package check - -import ( - "bytes" - "fmt" - "go/ast" - "go/constant" - "go/parser" - "go/printer" - "go/token" - "go/types" - "io" - "os" - "path/filepath" - "regexp" - "sort" - "strings" - - "golang.org/x/tools/go/packages" - "golang.org/x/tools/go/ssa" - "golang.org/x/tools/go/ssa/ssautil" -) - -// UnusedParams returns a list of human-readable issues that point out unused -// function parameters. -func UnusedParams(tests, exported, debug bool, args ...string) ([]string, error) { - wd, err := os.Getwd() - if err != nil { - return nil, err - } - c := &Checker{ - wd: wd, - tests: tests, - exported: exported, - } - if debug { - c.debugLog = os.Stderr - } - return c.lines(args...) -} - -// Checker finds unused parameters in a program. You probably want to use -// UnusedParams instead, unless you want to use a *loader.Program and -// *ssa.Program directly. -type Checker struct { - pkgs []*packages.Package - prog *ssa.Program - - wd string - - tests bool - exported bool - debugLog io.Writer - - issues []Issue - - cachedDeclCounts map[string]map[string]int - - // callByPos maps from a call site position to its CallExpr. - callByPos map[token.Pos]*ast.CallExpr - - // funcBodyByPos maps from a function position to its body. We can't map - // to the declaration, as that could be either a FuncDecl or FuncLit. - funcBodyByPos map[token.Pos]*ast.BlockStmt - - // typesImplementing records the method names that each named type needs - // to typecheck properly, as they're required to implement interfaces. - typesImplementing map[*types.Named][]string - - // localCallSites is a very simple form of a callgraph, only recording - // direct function calls within a single package. - localCallSites map[*ssa.Function][]ssa.CallInstruction - - // These three maps record whether an entire func's signature cannot be - // changed, or only its list of parameters or results. - - signRequiredBy map[*ssa.Function]string - paramsRequiredBy map[*ssa.Function]string - resultsRequiredBy map[*ssa.Function]string -} - -var errorType = types.Universe.Lookup("error").Type() - -// lines runs the checker and returns the list of readable issues. -func (c *Checker) lines(args ...string) ([]string, error) { - cfg := &packages.Config{ - Mode: packages.LoadSyntax, - Tests: c.tests, - } - pkgs, err := packages.Load(cfg, args...) - if err != nil { - return nil, err - } - if packages.PrintErrors(pkgs) > 0 { - return nil, fmt.Errorf("encountered errors") - } - - prog, _ := ssautil.Packages(pkgs, 0) - prog.Build() - c.Packages(pkgs) - c.ProgramSSA(prog) - issues, err := c.Check() - if err != nil { - return nil, err - } - lines := make([]string, 0, len(issues)) - prevLine := "" - for _, issue := range issues { - fpos := prog.Fset.Position(issue.Pos()).String() - if strings.HasPrefix(fpos, c.wd) { - fpos = fpos[len(c.wd)+1:] - } - line := fmt.Sprintf("%s: %s", fpos, issue.Message()) - if line == prevLine { - // Deduplicate lines, since we may look at the same - // package multiple times if tests are involved. - // TODO: is there a better way to handle this? - continue - } - prevLine = line - lines = append(lines, fmt.Sprintf("%s: %s", fpos, issue.Message())) - } - return lines, nil -} - -// Issue identifies a found unused parameter. -type Issue struct { - pos token.Pos - fname string - msg string -} - -func (i Issue) Pos() token.Pos { return i.pos } -func (i Issue) Message() string { return i.fname + " - " + i.msg } - -// Program supplies Checker with the needed *loader.Program. -func (c *Checker) Packages(pkgs []*packages.Package) { - c.pkgs = pkgs -} - -// ProgramSSA supplies Checker with the needed *ssa.Program. -func (c *Checker) ProgramSSA(prog *ssa.Program) { - c.prog = prog -} - -// CheckExportedFuncs sets whether to inspect exported functions -func (c *Checker) CheckExportedFuncs(exported bool) { - c.exported = exported -} - -func (c *Checker) debug(format string, a ...interface{}) { - if c.debugLog != nil { - fmt.Fprintf(c.debugLog, format, a...) - } -} - -// generatedDoc reports whether a comment text describes its file as being code -// generated. -func generatedDoc(text string) bool { - return strings.Contains(text, "Code generated") || - strings.Contains(text, "DO NOT EDIT") -} - -// eqlConsts reports whether two constant values, possibly nil, are equal. -func eqlConsts(c1, c2 *ssa.Const) bool { - if c1 == nil || c2 == nil { - return c1 == c2 - } - if c1.Type() != c2.Type() { - return false - } - if c1.Value == nil || c2.Value == nil { - return c1.Value == c2.Value - } - return constant.Compare(c1.Value, token.EQL, c2.Value) -} - -var stdSizes = types.SizesFor("gc", "amd64") - -// Check runs the unused parameter check and returns the list of found issues, -// and any error encountered. -func (c *Checker) Check() ([]Issue, error) { - c.cachedDeclCounts = make(map[string]map[string]int) - c.callByPos = make(map[token.Pos]*ast.CallExpr) - c.funcBodyByPos = make(map[token.Pos]*ast.BlockStmt) - c.typesImplementing = make(map[*types.Named][]string) - - wantPkg := make(map[*types.Package]*packages.Package) - genFiles := make(map[string]bool) - for _, pkg := range c.pkgs { - wantPkg[pkg.Types] = pkg - for _, f := range pkg.Syntax { - if len(f.Comments) > 0 && generatedDoc(f.Comments[0].Text()) { - fname := c.prog.Fset.Position(f.Pos()).Filename - genFiles[fname] = true - } - ast.Inspect(f, func(node ast.Node) bool { - switch node := node.(type) { - case *ast.ValueSpec: - if len(node.Values) == 0 || node.Type == nil || - len(node.Names) != 1 || node.Names[0].Name != "_" { - break - } - iface, ok := pkg.TypesInfo.TypeOf(node.Type).Underlying().(*types.Interface) - if !ok { - break - } - // var _ someIface = named - valTyp := pkg.TypesInfo.Types[node.Values[0]].Type - c.addImplementing(findNamed(valTyp), iface) - case *ast.CallExpr: - c.callByPos[node.Lparen] = node - // ssa.Function.Pos returns the declaring - // FuncLit.Type.Func or the position of the - // FuncDecl.Name. - case *ast.FuncDecl: - c.funcBodyByPos[node.Name.Pos()] = node.Body - case *ast.FuncLit: - c.funcBodyByPos[node.Pos()] = node.Body - } - return true - }) - } - } - allFuncs := ssautil.AllFunctions(c.prog) - - // map from *ssa.FreeVar to *ssa.Function, to find function literals - // behind closure vars in the simpler scenarios. - freeVars := map[*ssa.FreeVar]*ssa.Function{} - for curFunc := range allFuncs { - for _, b := range curFunc.Blocks { - for _, instr := range b.Instrs { - instr, ok := instr.(*ssa.MakeClosure) - if !ok { - continue - } - fn := instr.Fn.(*ssa.Function) - for i, fv := range fn.FreeVars { - binding := instr.Bindings[i] - alloc, ok := binding.(*ssa.Alloc) - if !ok { - continue - } - for _, ref := range *alloc.Referrers() { - store, ok := ref.(*ssa.Store) - if !ok { - continue - } - if fn, ok := store.Val.(*ssa.Function); ok { - freeVars[fv] = fn - break - } - } - } - } - } - } - - c.signRequiredBy = make(map[*ssa.Function]string) - c.paramsRequiredBy = make(map[*ssa.Function]string) - c.resultsRequiredBy = make(map[*ssa.Function]string) - c.localCallSites = make(map[*ssa.Function][]ssa.CallInstruction) - for curFunc := range allFuncs { - if strings.HasPrefix(curFunc.Synthetic, "wrapper for func") { - // Synthetic func wrappers are uninteresting, and can - // lead to false negatives. - continue - } - for _, b := range curFunc.Blocks { - for _, instr := range b.Instrs { - if instr, ok := instr.(ssa.CallInstruction); ok { - if fn := findFunction(freeVars, instr.Common().Value); fn != nil { - c.localCallSites[fn] = append(c.localCallSites[fn], instr) - } - fn := receivesExtractedArgs(freeVars, instr) - if fn != nil { - // fn(someFunc()) fixes params - c.paramsRequiredBy[fn] = "forwarded call" - } - } - switch instr := instr.(type) { - case *ssa.Call: - for _, arg := range instr.Call.Args { - if fn := findFunction(freeVars, arg); fn != nil { - // someFunc(fn) - c.signRequiredBy[fn] = "call" - } - } - case *ssa.Phi: - for _, val := range instr.Edges { - if fn := findFunction(freeVars, val); fn != nil { - // nonConstVar = fn - c.signRequiredBy[fn] = "phi" - } - } - case *ssa.Return: - for _, val := range instr.Results { - if fn := findFunction(freeVars, val); fn != nil { - // return fn - c.signRequiredBy[fn] = "result" - } - } - if call := callExtract(instr, instr.Results); call != nil { - if fn := findFunction(freeVars, call.Call.Value); fn != nil { - // return fn() - c.resultsRequiredBy[fn] = "return" - } - } - case *ssa.Store: - as := "" - switch instr.Addr.(type) { - case *ssa.FieldAddr: - // x.someField = fn - as = "field" - case *ssa.IndexAddr: - // x[someIndex] = fn - as = "element" - case *ssa.Global: - // someGlobal = fn - as = "global" - default: - continue - } - if fn := findFunction(freeVars, instr.Val); fn != nil { - c.signRequiredBy[fn] = as - } - case *ssa.MakeInterface: - // someIface(named) - iface := instr.Type().Underlying().(*types.Interface) - c.addImplementing(findNamed(instr.X.Type()), iface) - - if fn := findFunction(freeVars, instr.X); fn != nil { - // emptyIface = fn - c.signRequiredBy[fn] = "interface" - } - case *ssa.ChangeType: - if fn := findFunction(freeVars, instr.X); fn != nil { - // someType(fn) - c.signRequiredBy[fn] = "type conversion" - } - } - } - } - } - - for fn := range allFuncs { - switch { - case fn.Pkg == nil: // builtin? - continue - case fn.Name() == "init": - continue - case len(fn.Blocks) == 0: // stub - continue - } - pkg := wantPkg[fn.Pkg.Pkg] - if pkg == nil { // not part of given pkgs - continue - } - if c.exported || fn.Pkg.Pkg.Name() == "main" { - // we want exported funcs, or this is a main package so - // nothing is exported - } else if strings.Contains(fn.Name(), "$") { - // anonymous function within a possibly exported func - } else if ast.IsExported(fn.Name()) { - continue // user doesn't want to change signatures here - } - fname := c.prog.Fset.Position(fn.Pos()).Filename - if genFiles[fname] { - continue // generated file - } - - c.checkFunc(fn, pkg) - } - sort.Slice(c.issues, func(i, j int) bool { - p1 := c.prog.Fset.Position(c.issues[i].Pos()) - p2 := c.prog.Fset.Position(c.issues[j].Pos()) - if p1.Filename == p2.Filename { - return p1.Offset < p2.Offset - } - return p1.Filename < p2.Filename - }) - return c.issues, nil -} - -func stringsContains(list []string, elem string) bool { - for _, e := range list { - if e == elem { - return true - } - } - return false -} - -func (c *Checker) addImplementing(named *types.Named, iface *types.Interface) { - if named == nil || iface == nil { - return - } - list := c.typesImplementing[named] - for i := 0; i < iface.NumMethods(); i++ { - name := iface.Method(i).Name() - if !stringsContains(list, name) { - list = append(list, name) - } - } - c.typesImplementing[named] = list -} - -func findNamed(typ types.Type) *types.Named { - switch typ := typ.(type) { - case *types.Pointer: - return findNamed(typ.Elem()) - case *types.Named: - return typ - } - return nil -} - -// findFunction returns the function that is behind a value, if any. -func findFunction(freeVars map[*ssa.FreeVar]*ssa.Function, value ssa.Value) *ssa.Function { - switch value := value.(type) { - case *ssa.Function: - name := value.Name() - if strings.HasSuffix(name, "$thunk") || strings.HasSuffix(name, "$bound") { - // Method wrapper funcs contain a single block, which - // calls the function being wrapped, and returns. We - // want the function being wrapped. - for _, instr := range value.Blocks[0].Instrs { - call, ok := instr.(*ssa.Call) - if !ok { - continue - } - if callee := call.Call.StaticCallee(); callee != nil { - return callee - } - } - return nil // no static callee? - } - return value - case *ssa.MakeClosure: - // closure of a func - return findFunction(freeVars, value.Fn) - case *ssa.UnOp: - if value.Op != token.MUL { - break - } - if fv, ok := value.X.(*ssa.FreeVar); ok { - return freeVars[fv] - } - } - return nil -} - -// addIssue records a newly found unused parameter. -func (c *Checker) addIssue(fn *ssa.Function, pos token.Pos, format string, args ...interface{}) { - c.issues = append(c.issues, Issue{ - pos: pos, - fname: fn.RelString(fn.Package().Pkg), - msg: fmt.Sprintf(format, args...), - }) -} - -// constValueString is cnst.Value.String() without panicking on untyped nils. -func constValueString(cnst *ssa.Const) string { - if cnst.Value == nil { - return "nil" - } - return cnst.Value.String() -} - -// checkFunc checks a single function for unused parameters. -func (c *Checker) checkFunc(fn *ssa.Function, pkg *packages.Package) { - c.debug("func %s\n", fn.RelString(fn.Package().Pkg)) - if dummyImpl(fn.Blocks[0]) { // panic implementation - c.debug(" skip - dummy implementation\n") - return - } - if by := c.signRequiredBy[fn]; by != "" { - c.debug(" skip - func signature required by %s\n", by) - return - } - if recv := fn.Signature.Recv(); recv != nil { - named := findNamed(recv.Type()) - if stringsContains(c.typesImplementing[named], fn.Name()) { - c.debug(" skip - method required to implement an interface\n") - return - } - } - if c.multipleImpls(pkg, fn) { - c.debug(" skip - multiple implementations via build tags\n") - return - } - paramsBy := c.paramsRequiredBy[fn] - resultsBy := c.resultsRequiredBy[fn] - callSites := c.localCallSites[fn] - - results := fn.Signature.Results() - sameConsts := make([]*ssa.Const, results.Len()) - numRets := 0 - allRetsExtracting := true - for _, block := range fn.Blocks { - if resultsBy != "" { - continue // we can't change the returns - } - last := block.Instrs[len(block.Instrs)-1] - ret, ok := last.(*ssa.Return) - if !ok { - continue - } - for i, val := range ret.Results { - if _, ok := val.(*ssa.Extract); !ok { - allRetsExtracting = false - } - cnst := constValue(val) - if numRets == 0 { - sameConsts[i] = cnst - } else if !eqlConsts(sameConsts[i], cnst) { - sameConsts[i] = nil - } - } - numRets++ - } - for i, cnst := range sameConsts { - if cnst == nil { - // no consistent returned constant - continue - } - if cnst.Value != nil && numRets == 1 { - // just one return and it's not untyped nil (too many - // false positives) - continue - } - res := results.At(i) - name := paramDesc(i, res) - c.addIssue(fn, res.Pos(), "result %s is always %s", name, constValueString(cnst)) - } - -resLoop: - for i := 0; i < results.Len(); i++ { - if resultsBy != "" { - continue // we can't change the returns - } - if allRetsExtracting { - continue - } - res := results.At(i) - if res.Type() == errorType { - // "error is never used" is less useful, and it's up to - // tools like errcheck anyway. - continue - } - count := 0 - for _, site := range callSites { - val := site.Value() - if val == nil { // e.g. go statement - count++ - continue - } - for _, instr := range *val.Referrers() { - extract, ok := instr.(*ssa.Extract) - if !ok { - continue resLoop // direct, real use - } - if extract.Index != i { - continue // not the same result param - } - if len(*extract.Referrers()) > 0 { - continue resLoop // real use after extraction - } - } - count++ - } - if count < 2 { - continue // require ignoring at least twice - } - name := paramDesc(i, res) - c.addIssue(fn, res.Pos(), "result %s is never used", name) - } - - fnIsGeneric := fn.TypeParams().Len() > 0 - - for i, par := range fn.Params { - if paramsBy != "" { - continue // we can't change the params - } - if i == 0 && fn.Signature.Recv() != nil { // receiver - continue - } - c.debug("%s\n", par.String()) - if name := par.Object().Name(); name == "" || name[0] == '_' { - c.debug(" skip - no name or underscore name\n") - continue - } - t := par.Type() - // asking for the size of a type param would panic, as it is unknowable - if !fnIsGeneric || !containsTypeParam(t) { - if stdSizes.Sizeof(par.Type()) == 0 { - c.debug(" skip - zero size\n") - continue - } - } else { - c.debug(" examine - type parameter\n") - } - reason := "is unused" - constStr := c.alwaysReceivedConst(callSites, par, i) - if constStr != "" { - reason = fmt.Sprintf("always receives %s", constStr) - } else if c.anyRealUse(par, i, pkg) { - c.debug(" skip - used somewhere in the func body\n") - continue - } - c.addIssue(fn, par.Pos(), "%s %s", par.Name(), reason) - } -} - -func containsTypeParam(t types.Type) bool { - switch t := t.(type) { - case *types.TypeParam, *types.Union: - return true - case *types.Struct: - nf := t.NumFields() - for i := 0; i < nf; i++ { - if containsTypeParam(t.Field(nf).Type()) { - return true - } - } - case *types.Array: - return containsTypeParam(t.Elem()) - case *types.Named: - args := t.TypeArgs() - for i := 0; i < args.Len(); i++ { - if containsTypeParam(args.At(i)) { - return true - } - } - } - return false -} - -// nodeStr stringifies a syntax tree node. It is only meant for simple nodes, -// such as short value expressions. -func nodeStr(node ast.Node) string { - var buf bytes.Buffer - fset := token.NewFileSet() - if err := printer.Fprint(&buf, fset, node); err != nil { - panic(err) - } - return buf.String() -} - -// alwaysReceivedConst checks if a function parameter always receives the same -// constant value, given a list of inbound calls. If it does, a description of -// the value is returned. If not, an empty string is returned. -// -// This function is used to recommend that the parameter be replaced by a direct -// use of the constant. To avoid false positives, the function will return false -// if the number of inbound calls is too low. -func (c *Checker) alwaysReceivedConst(callSites []ssa.CallInstruction, par *ssa.Parameter, pos int) string { - if len(callSites) < 4 { - // We can't possibly receive the same constant value enough - // times, hence a potential false positive. - return "" - } - if ast.IsExported(par.Parent().Name()) { - // we might not have all call sites for an exported func - return "" - } - var seen *ssa.Const - origPos := pos - if par.Parent().Signature.Recv() != nil { - // go/ast's CallExpr.Args does not include the receiver, but - // go/ssa's equivalent does. - origPos-- - } - seenOrig := "" - for _, site := range callSites { - call := site.Common() - if pos >= len(call.Args) { - // TODO: investigate? Weird crash in - // internal/x/net/http2/hpack/hpack_test.go, where we - // roughly do: "at := d.mustAt; at(3)". - return "" - } - cnst := constValue(call.Args[pos]) - if cnst == nil { - return "" // not a constant - } - origArg := "" - origCall := c.callByPos[call.Pos()] - if origPos >= len(origCall.Args) { - // variadic parameter that wasn't given - } else { - origArg = nodeStr(origCall.Args[origPos]) - } - if seen == nil { - seen = cnst // first constant - seenOrig = origArg - } else if !eqlConsts(seen, cnst) { - return "" // different constants - } else if origArg != seenOrig { - seenOrig = "" - } - } - seenStr := constValueString(seen) - if seenOrig != "" && seenStr != seenOrig { - return fmt.Sprintf("%s (%s)", seenOrig, seenStr) - } - return seenStr -} - -func constValue(value ssa.Value) *ssa.Const { - switch x := value.(type) { - case *ssa.Const: - return x - case *ssa.MakeInterface: - return constValue(x.X) - } - return nil -} - -// anyRealUse reports whether a parameter has any relevant use within its -// function body. Certain uses are ignored, such as recursive calls where the -// parameter is re-used as itself. -func (c *Checker) anyRealUse(par *ssa.Parameter, pos int, pkg *packages.Package) bool { - refs := *par.Referrers() - if len(refs) == 0 { - // Look for any uses like "_ = par", which are the developer's - // way to tell they want to keep the parameter. SSA does not - // keep that kind of statement around. - body := c.funcBodyByPos[par.Parent().Pos()] - any := false - ast.Inspect(body, func(node ast.Node) bool { - if any { - return false - } - asgn, ok := node.(*ast.AssignStmt) - if !ok || asgn.Tok != token.ASSIGN || len(asgn.Lhs) != 1 || len(asgn.Rhs) != 1 { - return true - } - if left, ok := asgn.Lhs[0].(*ast.Ident); !ok || left.Name != "_" { - return true - } - if right, ok := asgn.Rhs[0].(*ast.Ident); ok { - obj := pkg.TypesInfo.Uses[right] - if obj != nil && obj.Pos() == par.Pos() { - any = true - } - } - return true - }) - return any - } -refLoop: - for _, ref := range refs { - switch x := ref.(type) { - case *ssa.Call: - if x.Call.Value != par.Parent() { - return true // not a recursive call - } - for i, arg := range x.Call.Args { - if arg != par { - continue - } - if i == pos { - // reused directly in a recursive call - continue refLoop - } - } - return true - case *ssa.Store: - if insertedStore(x) { - continue // inserted by go/ssa, not from the code - } - return true - default: - return true - } - } - return false -} - -// insertedStore reports whether a SSA instruction was inserted by the SSA -// building algorithm. That is, the store was not directly translated from an -// original Go statement. -func insertedStore(instr ssa.Instruction) bool { - if instr.Pos() != token.NoPos { - return false - } - store, ok := instr.(*ssa.Store) - if !ok { - return false - } - alloc, ok := store.Addr.(*ssa.Alloc) - // we want exactly one use of this alloc value for it to be - // inserted by ssa and dummy - the alloc instruction itself. - return ok && len(*alloc.Referrers()) == 1 -} - -// rxHarmlessCall matches all the function expression strings which are allowed -// in a dummy implementation. -var rxHarmlessCall = regexp.MustCompile(`(?i)\b(log(ger)?|errors)\b|\bf?print|errorf?$`) - -// dummyImpl reports whether a block is a dummy implementation. This is -// true if the block will almost immediately panic, throw or return -// constants only. -func dummyImpl(blk *ssa.BasicBlock) bool { - var ops [8]*ssa.Value - for _, instr := range blk.Instrs { - if insertedStore(instr) { - continue // inserted by go/ssa, not from the code - } - for _, val := range instr.Operands(ops[:0]) { - switch x := (*val).(type) { - case nil, *ssa.Const, *ssa.ChangeType, *ssa.Alloc, - *ssa.MakeInterface, *ssa.MakeMap, - *ssa.Function, *ssa.Global, - *ssa.IndexAddr, *ssa.Slice, - *ssa.UnOp, *ssa.Parameter: - case *ssa.Call: - if rxHarmlessCall.MatchString(x.Call.Value.String()) { - continue - } - default: - return false - } - } - switch x := instr.(type) { - case *ssa.Alloc, *ssa.Store, *ssa.UnOp, *ssa.BinOp, - *ssa.MakeInterface, *ssa.MakeMap, *ssa.Extract, - *ssa.IndexAddr, *ssa.FieldAddr, *ssa.Slice, - *ssa.Lookup, *ssa.ChangeType, *ssa.TypeAssert, - *ssa.Convert, *ssa.ChangeInterface: - // non-trivial expressions in panic/log/print calls - case *ssa.Return, *ssa.Panic: - return true - case *ssa.Call: - if rxHarmlessCall.MatchString(x.Call.Value.String()) { - continue - } - return x.Call.Value.Name() == "throw" // runtime's panic - default: - return false - } - } - return false -} - -// declCounts reports how many times a package's functions are declared. This is -// used, for example, to find if a function has many implementations. -// -// Since this function parses all of the package's Go source files on disk, its -// results are cached. -func (c *Checker) declCounts(pkgDir, pkgName string) map[string]int { - key := pkgDir + ":" + pkgName - if m, ok := c.cachedDeclCounts[key]; ok { - return m - } - fset := token.NewFileSet() - pkgs, err := parser.ParseDir(fset, pkgDir, nil, 0) - if err != nil { - // Don't panic or error here. In some part of the go/* libraries - // stack, we sometimes end up with a package directory that is - // wrong. That's not our fault, and we can't simply break the - // tool until we fix the underlying issue. - println(err.Error()) - c.cachedDeclCounts[pkgDir] = nil - return nil - } - if len(pkgs) == 0 { - // TODO: investigate why this started happening after switching - // to go/packages - return nil - } - pkg := pkgs[pkgName] - count := make(map[string]int) - for _, file := range pkg.Files { - for _, decl := range file.Decls { - fd, ok := decl.(*ast.FuncDecl) - if !ok { - continue - } - name := recvPrefix(fd.Recv) + fd.Name.Name - count[name]++ - } - } - c.cachedDeclCounts[key] = count - return count -} - -// recvPrefix returns the string prefix for a receiver field list. Star -// expressions are ignored, so as to conservatively assume that pointer and -// non-pointer receivers may still implement the same function. -// -// For example, for "function (*Foo) Bar()", recvPrefix will return "Foo.". -func recvPrefix(recv *ast.FieldList) string { - if recv == nil { - return "" - } - expr := recv.List[0].Type - for { - star, ok := expr.(*ast.StarExpr) - if !ok { - break - } - expr = star.X - } - - return identName(expr) -} - -func identName(expr ast.Expr) string { - switch expr := expr.(type) { - case *ast.Ident: - return expr.Name + "." - case *ast.IndexExpr: - return identName(expr.X) - case *ast.ParenExpr: - return identName(expr.X) - case *ast.IndexListExpr: - return identName(expr.X) - default: - panic(fmt.Sprintf("unexpected receiver AST node: %T", expr)) - } -} - -// multipleImpls reports whether a function has multiple implementations in the -// source code. For example, if there are different function bodies depending on -// the operating system or architecture. That tends to mean that an unused -// parameter in one implementation may not be unused in another. -func (c *Checker) multipleImpls(pkg *packages.Package, fn *ssa.Function) bool { - if fn.Parent() != nil { // nested func - return false - } - path := c.prog.Fset.Position(fn.Pos()).Filename - count := c.declCounts(filepath.Dir(path), pkg.Types.Name()) - name := fn.Name() - if recv := fn.Signature.Recv(); recv != nil { - named := findNamed(recv.Type()) - name = named.Obj().Name() + "." + name - } - return count[name] > 1 -} - -// receivesExtractedArgs returns the statically called function, if its multiple -// arguments were all received via another function call. That is, if a call to -// function "foo" was of the form "foo(bar())". This often means that the -// parameters in "foo" are difficult to remove, even if unused. -func receivesExtractedArgs(freeVars map[*ssa.FreeVar]*ssa.Function, call ssa.CallInstruction) *ssa.Function { - comm := call.Common() - callee := findFunction(freeVars, comm.Value) - if callee == nil { - return nil - } - if callee.Signature.Params().Len() < 2 { - // there aren't multiple parameters - return nil - } - args := comm.Args - if callee.Signature.Recv() != nil { - // skip the receiver argument - args = args[1:] - } - if c := callExtract(call, args); c != nil { - return callee - } - return nil -} - -// callExtract returns the call instruction fn(...) if it is used directly as -// arguments to the parent instruction, such as fn2(fn(...)) or return fn(...). -func callExtract(parent ssa.Instruction, values []ssa.Value) *ssa.Call { - if len(values) == 1 { - if call, ok := values[0].(*ssa.Call); ok { - return call - } - } - var prev *ssa.Call - for i, val := range values { - ext, ok := val.(*ssa.Extract) - if !ok { - return nil - } - if ext.Index != i { - return nil // not extracted in the same order - } - call, ok := ext.Tuple.(*ssa.Call) - if !ok { - return nil // not a call - } - if prev == nil { - prev = call - } else if prev != call { - return nil // not the same calls - } - } - if prev == nil { - return nil - } - if prev.Call.Signature().Results().Len() != len(values) { - return nil // not extracting all the results - } - if prev.Pos() < parent.Pos() { - // Of the form: - // - // a, b := fn() - // fn2(a, b) - return nil - } - return prev -} - -// paramDesc returns a string describing a parameter variable. If the parameter -// had no name, the function will fall back to describing the parameter by its -// position within the parameter list and its type. -func paramDesc(i int, v *types.Var) string { - name := v.Name() - if name != "" && name != "_" { - return name - } - return fmt.Sprintf("%d (%s)", i, v.Type().String()) -} From 0f51dfb23de100304904969216311950dd114c85 Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Wed, 4 Dec 2024 13:20:46 +0100 Subject: [PATCH 2/5] Clean up Makefile --- Makefile | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 6a9b57a98..b8c601fb1 100644 --- a/Makefile +++ b/Makefile @@ -1,25 +1,25 @@ # Copyright © 2018 by PACE Telematics GmbH. All rights reserved. -.PHONY: install test jsonapi build integration ci - JSONAPITEST=http/jsonapi/generator/internal JSONAPIGEN="./tools/jsonapigen/main.go" GOPATH?=~/go GO:=go -GO_TEST_FLAGS:=-mod=vendor -count=1 -v -cover -race -PROTO_TMP:=$(shell pwd)/proto.tmp +GO_TEST_FLAGS:=-count=1 -v -cover -race export JAEGER_SERVICE_NAME:=unittest -export JAEGER_SAMPLER_TYPE:=const -export JAEGER_SAMPLER_PARAM:=1 export LOG_FORMAT:=console +.PHONY: install install: $(GO) install ./cmd/pb +.PHONY: vuln-scan vuln-scan: - $(GO) run -mod=vendor golang.org/x/vuln/cmd/govulncheck ./... + (cd /; $(GO) install -v -x golang.org/x/vuln/cmd/govulncheck@latest) + + govulncheck ./... +.PHONY: jsonapi jsonapi: $(GO) run $(JSONAPIGEN) -pkg poi \ -path $(JSONAPITEST)/poi/open-api_test.go \ @@ -40,29 +40,34 @@ jsonapi: -path tools/testserver/simple/open-api.go \ -source tools/testserver/simple/open-api.json +.PHONY: grpc grpc: tools/testserver/math/math.pb.go tools/testserver/math/math.pb.go: tools/testserver/math/math.proto - mkdir -p $(PROTO_TMP) - GOBIN=$(PROTO_TMP) $(GO) install -mod=vendor google.golang.org/grpc/cmd/protoc-gen-go-grpc - GOBIN=$(PROTO_TMP) $(GO) install -mod=vendor google.golang.org/protobuf/cmd/protoc-gen-go - protoc --plugin=$(PROTO_TMP)/protoc-gen-go-grpc \ - --plugin=$(PROTO_TMP)/protoc-gen-go \ - -I=./ --go-grpc_out=$(dir @) --go_out=$(dir @) $< - rm -rf $(PROTO_TMP) + (cd /; $(GO) install -v -x google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest) + (cd /; $(GO) install -v -x google.golang.org/protobuf/cmd/protoc-gen-go@latest) + protoc -I=./ --go-grpc_out=$(dir @) --go_out=$(dir @) $< + +.PHONY: lint lint: - $(GO) run -mod=vendor github.com/golangci/golangci-lint/cmd/golangci-lint run --timeout 2m + (cd /; $(GO) install -v -x github.com/golangci/golangci-lint/cmd/golangci-lint@latest) + + golangci-lint run --timeout 2m +.PHONY: test test: $(GO) test $(GO_TEST_FLAGS) -covermode=atomic -coverprofile=coverage.out -short ./... +.PHONY: integration integration: $(GO) test $(GO_TEST_FLAGS) -run TestIntegration ./... $(GO) test $(GO_TEST_FLAGS) -run Example_clusterBackgroundTask ./pkg/routine +.PHONY: testserver testserver: docker-compose up +.PHONY: ci ci: $(GO) test $(GO_TEST_FLAGS) -covermode=atomic -coverprofile=coverage.out ./... From 8e402618aa0e8dfbba7065dc65ab99491749aba7 Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Wed, 4 Dec 2024 13:22:15 +0100 Subject: [PATCH 3/5] Drop tools.go --- tools.go | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 tools.go diff --git a/tools.go b/tools.go deleted file mode 100644 index e08665405..000000000 --- a/tools.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build tools -// +build tools - -package bricks - -import ( - _ "github.com/golangci/golangci-lint/cmd/golangci-lint" - _ "github.com/mattn/goveralls" - _ "golang.org/x/vuln/cmd/govulncheck" - _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" - _ "google.golang.org/protobuf/cmd/protoc-gen-go" -) From cacbef9e8e197cfad0e5449621b9d322a6e87c2e Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Wed, 4 Dec 2024 13:22:49 +0100 Subject: [PATCH 4/5] gomod: Update dependencies --- go.mod | 167 +-------------------- go.sum | 450 +-------------------------------------------------------- 2 files changed, 7 insertions(+), 610 deletions(-) diff --git a/go.mod b/go.mod index 9c7c513bc..fec91672a 100644 --- a/go.mod +++ b/go.mod @@ -18,14 +18,12 @@ require ( github.com/go-kivik/kivik/v3 v3.2.3 github.com/go-pg/pg v6.14.5+incompatible github.com/golang-jwt/jwt/v5 v5.2.1 - github.com/golangci/golangci-lint v1.61.0 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0 github.com/jpillora/backoff v1.0.0 github.com/mattn/go-isatty v0.0.20 - github.com/mattn/goveralls v0.0.12 github.com/minio/minio-go/v7 v7.0.7 github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 @@ -39,202 +37,49 @@ require ( github.com/stretchr/testify v1.9.0 github.com/zenazn/goji v1.0.1 golang.org/x/text v0.18.0 - golang.org/x/vuln v1.1.3 google.golang.org/grpc v1.66.0 - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.34.2 ) require ( - 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect - 4d63.com/gochecknoglobals v0.2.1 // indirect - github.com/4meepo/tagalign v1.3.4 // indirect - github.com/Abirdcfly/dupword v0.1.1 // indirect - github.com/Antonboom/errname v0.1.13 // indirect - github.com/Antonboom/nilnil v0.1.9 // indirect - github.com/Antonboom/testifylint v1.4.3 // indirect - github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect - github.com/Crocmagnon/fatcontext v0.5.2 // indirect - github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect - github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 // indirect - github.com/Masterminds/semver/v3 v3.3.0 // indirect - github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect - github.com/alecthomas/go-check-sumtype v0.1.4 // indirect - github.com/alexkohler/nakedret/v2 v2.0.4 // indirect - github.com/alexkohler/prealloc v1.0.0 // indirect + cloud.google.com/go/compute/metadata v0.5.0 // indirect github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect github.com/alicebob/miniredis/v2 v2.30.4 // indirect - github.com/alingse/asasalint v0.0.11 // indirect - github.com/ashanbrown/forbidigo v1.6.0 // indirect - github.com/ashanbrown/makezero v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bkielbasa/cyclop v1.2.1 // indirect - github.com/blizzy78/varnamelen v0.8.0 // indirect - github.com/bombsimon/wsl/v4 v4.4.1 // indirect - github.com/breml/bidichk v0.2.7 // indirect - github.com/breml/errchkjson v0.3.6 // indirect - github.com/butuzov/ireturn v0.3.0 // indirect - github.com/butuzov/mirror v1.2.0 // indirect - github.com/catenacyber/perfsprint v0.7.1 // indirect - github.com/ccojocar/zxcvbn-go v1.0.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/charithe/durationcheck v0.0.10 // indirect - github.com/chavacava/garif v0.1.0 // indirect - github.com/ckaznocha/intrange v0.2.0 // indirect - github.com/curioswitch/go-reassign v0.2.0 // indirect - github.com/daixiang0/gci v0.13.5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/denis-tingaikin/go-header v0.5.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/ettle/strcase v0.2.0 // indirect - github.com/fatih/color v1.17.0 // indirect - github.com/fatih/structtag v1.2.0 // indirect - github.com/firefart/nonamedreturns v1.0.5 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect - github.com/fzipp/gocyclo v0.6.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect - github.com/ghostiam/protogetter v0.3.6 // indirect - github.com/go-critic/go-critic v0.11.4 // 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.1.0 // indirect - github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect - github.com/gobwas/glob v0.2.3 // indirect - github.com/gofrs/flock v0.12.1 // indirect - github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect - github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9 // indirect - github.com/golangci/misspell v0.6.0 // indirect - github.com/golangci/modinfo v0.3.4 // indirect - github.com/golangci/plugin-module-register v0.1.1 // indirect - github.com/golangci/revgrep v0.5.3 // indirect - github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/gordonklaus/ineffassign v0.1.0 // indirect - github.com/gostaticanalysis/analysisutil v0.7.1 // indirect - github.com/gostaticanalysis/comment v1.4.2 // indirect - github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect - github.com/gostaticanalysis/nilerr v0.1.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jgautheron/goconst v1.7.1 // indirect - github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect - github.com/jjti/go-spancheck v0.6.2 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/julz/importas v0.1.0 // indirect - github.com/karamaru-alpha/copyloopvar v1.1.0 // indirect - github.com/kisielk/errcheck v1.7.0 // indirect - github.com/kkHAIKE/contextcheck v1.1.5 // indirect github.com/klauspost/cpuid v1.3.1 // indirect - github.com/kulti/thelper v0.6.3 // indirect - github.com/kunwardeep/paralleltest v1.0.10 // indirect - github.com/kyoh86/exportloopref v0.1.11 // indirect - github.com/lasiar/canonicalheader v1.1.1 // indirect - github.com/ldez/gomoddirectives v0.2.4 // indirect - github.com/ldez/tagliatelle v0.5.0 // indirect - github.com/leonklingele/grouper v1.1.2 // indirect - github.com/lufeee/execinquery v1.2.1 // indirect - github.com/macabu/inamedparam v0.1.3 // indirect - github.com/magiconair/properties v1.8.6 // indirect - github.com/maratori/testableexamples v1.0.0 // indirect - github.com/maratori/testpackage v1.1.1 // indirect - github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect + github.com/kr/text v0.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/mgechev/revive v1.3.9 // indirect github.com/minio/md5-simd v1.1.0 // indirect github.com/minio/sha256-simd v0.1.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/moricho/tparallel v0.3.2 // 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.16.2 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onsi/ginkgo v1.16.5 // indirect + github.com/onsi/gomega v1.34.2 // indirect github.com/opentracing/opentracing-go v1.1.0 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.2.3 // indirect - github.com/polyfloyd/go-errorlint v1.6.0 // indirect + github.com/otiai10/copy v1.14.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect - github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1 // indirect - github.com/quasilyte/go-ruleguard/dsl v0.3.22 // 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/rivo/uniseg v0.2.0 // indirect - github.com/ryancurrah/gomodguard v1.3.5 // indirect - github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect - github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect - github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect - github.com/sashamelentyev/interfacebloat v1.1.0 // indirect - github.com/sashamelentyev/usestdlibvars v1.27.0 // indirect - github.com/securego/gosec/v2 v2.21.2 // indirect - github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/sivchari/containedctx v1.0.3 // indirect - github.com/sivchari/tenv v1.10.0 // indirect - github.com/sonatard/noctx v0.0.2 // indirect - github.com/sourcegraph/go-diff v0.7.0 // indirect - github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/spf13/pflag v1.0.5 // 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.1.1 // indirect - github.com/stretchr/objx v0.5.2 // indirect - github.com/subosito/gotenv v1.4.1 // indirect - github.com/tdakkota/asciicheck v0.2.0 // indirect - github.com/tetafro/godot v1.4.17 // indirect - github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect - github.com/timonwong/loggercheck v0.9.4 // indirect - github.com/tomarrell/wrapcheck/v2 v2.9.0 // indirect - github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect - github.com/ultraware/funlen v0.1.0 // indirect - github.com/ultraware/whitespace v0.1.1 // indirect - github.com/uudashr/gocognit v1.1.3 // indirect - github.com/xen0n/gosmopolitan v1.2.2 // 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/yuin/gopher-lua v1.1.0 // indirect - gitlab.com/bosi/decorder v0.4.2 // indirect - go-simpler.org/musttag v0.12.2 // indirect - go-simpler.org/sloglint v0.7.2 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/automaxprocs v1.5.3 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.24.0 // indirect golang.org/x/crypto v0.27.0 // indirect - golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect - golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect - golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.28.0 // indirect - golang.org/x/sync v0.8.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sys v0.25.0 // indirect - golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7 // indirect - golang.org/x/tools v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // 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.5.1 // indirect - mvdan.cc/gofumpt v0.7.0 // indirect - mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect ) diff --git a/go.sum b/go.sum index 0a0e60068..66147666e 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,3 @@ -4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA= -4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= -4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= -4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= 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= @@ -18,14 +14,12 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV 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 v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ= 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/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= @@ -40,118 +34,51 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl 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= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/4meepo/tagalign v1.3.4 h1:P51VcvBnf04YkHzjfclN6BbsopfJR5rxs1n+5zHt+w8= -github.com/4meepo/tagalign v1.3.4/go.mod h1:M+pnkHH2vG8+qhE5bVc/zeP7HS/j910Fwa9TUSyZVI0= -github.com/Abirdcfly/dupword v0.1.1 h1:Bsxe0fIw6OwBtXMIncaTxCLHYO5BB+3mcsR5E8VXloY= -github.com/Abirdcfly/dupword v0.1.1/go.mod h1:B49AcJdTYYkpd4HjgAcutNGG9HZ2JWwKunH9Y2BA6sM= -github.com/Antonboom/errname v0.1.13 h1:JHICqsewj/fNckzrfVSe+T33svwQxmjC+1ntDsHOVvM= -github.com/Antonboom/errname v0.1.13/go.mod h1:uWyefRYRN54lBg6HseYCFhs6Qjcy41Y3Jl/dVhA87Ns= -github.com/Antonboom/nilnil v0.1.9 h1:eKFMejSxPSA9eLSensFmjW2XTgTwJMjZ8hUHtV4s/SQ= -github.com/Antonboom/nilnil v0.1.9/go.mod h1:iGe2rYwCq5/Me1khrysB4nwI7swQvjclR8/YRPl5ihQ= -github.com/Antonboom/testifylint v1.4.3 h1:ohMt6AHuHgttaQ1xb6SSnxCeK4/rnK7KKzbvs7DmEck= -github.com/Antonboom/testifylint v1.4.3/go.mod h1:+8Q9+AOLsz5ZiQiiYujJKs9mNz398+M6UgslP4qgJLA= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= -github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Crocmagnon/fatcontext v0.5.2 h1:vhSEg8Gqng8awhPju2w7MKHqMlg4/NI+gSDHtR3xgwA= -github.com/Crocmagnon/fatcontext v0.5.2/go.mod h1:87XhRMaInHP44Q7Tlc7jkgKKB7kZAOPiDkFMdKCC+74= -github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= -github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 h1:/fTUt5vmbkAcMBt4YQiuC23cV0kEsN1MVMNqeOW43cU= -github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0/go.mod h1:ONJg5sxcbsdQQ4pOW8TGdTidT2TMAUy/2Xhr8mrYaao= -github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= -github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= -github.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJPdp74zmpA= -github.com/OpenPeeDeeP/depguard/v2 v2.2.0/go.mod h1:CIzddKRvLBC4Au5aYP/i3nyaWQ+ClszLIuVocRiCYFQ= github.com/PuerkitoBio/rehttp v1.4.0 h1:rIN7A2s+O9fmHUM1vUcInvlHj9Ysql4hE+Y0wcl/xk8= github.com/PuerkitoBio/rehttp v1.4.0/go.mod h1:LUwKPoDbDIA2RL5wYZCNsQ90cx4OJ4AWBmq6KzWZL1s= github.com/adjust/rmq/v5 v5.2.0 h1:ENPC+3i8N/LAvAfHpEpTMVl7q8zmwh4nl+hhxkao6KE= github.com/adjust/rmq/v5 v5.2.0/go.mod h1:FfA6MzYJHeLbuATsNYaZYZaISyxxADDXQLN9QBroFCw= -github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= -github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= -github.com/alecthomas/go-check-sumtype v0.1.4 h1:WCvlB3l5Vq5dZQTFmodqL2g68uHiSwwlWcT5a2FGK0c= -github.com/alecthomas/go-check-sumtype v0.1.4/go.mod h1:WyYPfhfkdhyrdaligV6svFopZV8Lqdzn5pyVBaV6jhQ= -github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= -github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= -github.com/alexkohler/nakedret/v2 v2.0.4 h1:yZuKmjqGi0pSmjGpOC016LtPJysIL0WEUiaXW5SUnNg= -github.com/alexkohler/nakedret/v2 v2.0.4/go.mod h1:bF5i0zF2Wo2o4X4USt9ntUWve6JbFv02Ff4vlkmS/VU= -github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= -github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE= github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis/v2 v2.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOSchFS7Eo= github.com/alicebob/miniredis/v2 v2.30.4/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6uH3VlUfb/HS5zKg= -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/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8gerOIVIY= -github.com/ashanbrown/forbidigo v1.6.0/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU= -github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= -github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 h1:0NmehRCgyk5rljDQLKUO+cRJCnduDyn11+zGZIc9Z48= github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0/go.mod h1:6L7zgvqo0idzI7IO8de6ZC051AfXb5ipkIJ7bIA2tGA= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJY= -github.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM= -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.4.1 h1:jfUaCkN+aUpobrMO24zwyAMwMAV5eSziCkOKEauOLdw= -github.com/bombsimon/wsl/v4 v4.4.1/go.mod h1:Xu/kDxGZTofQcDGCtQe9KCzhHphIe0fDuyWTxER9Feo= -github.com/breml/bidichk v0.2.7 h1:dAkKQPLl/Qrk7hnP6P+E0xOodrq8Us7+U0o4UBOAlQY= -github.com/breml/bidichk v0.2.7/go.mod h1:YodjipAGI9fGcYM7II6wFvGhdMYsC5pHDlGzqvEW3tQ= -github.com/breml/errchkjson v0.3.6 h1:VLhVkqSBH96AvXEyclMR37rZslRrY2kcyq+31HCsVrA= -github.com/breml/errchkjson v0.3.6/go.mod h1:jhSDoFheAF2RSDOlCfhHO9KqhZgAYLyvHe7bRCX8f/U= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/bsm/redislock v0.9.3 h1:osmvugkXGiLDEhzUPdM0EUtKpTEgLLuli4Ky2Z4vx38= github.com/bsm/redislock v0.9.3/go.mod h1:Epf7AJLiSFwLCiZcfi6pWFO/8eAYrYpQXFxEDPoDeAk= -github.com/butuzov/ireturn v0.3.0 h1:hTjMqWw3y5JC3kpnC5vXmFJAWI/m31jaCYQqzkS6PL0= -github.com/butuzov/ireturn v0.3.0/go.mod h1:A09nIiwiqzN/IoVo9ogpa0Hzi9fex1kd9PSD6edP5ZA= -github.com/butuzov/mirror v1.2.0 h1:9YVK1qIjNspaqWutSv8gsge2e/Xpq1eqEkslEUHy5cs= -github.com/butuzov/mirror v1.2.0/go.mod h1:DqZZDtzm42wIAIyHXeN8W/qb1EPlb9Qn/if9icBOpdQ= github.com/caarlos0/env/v10 v10.0.0 h1:yIHUBZGsyqCnpTkbjk8asUlx6RFhhEs+h7TOBdgdzXA= github.com/caarlos0/env/v10 v10.0.0/go.mod h1:ZfulV76NvVPw3tm591U4SwL3Xx9ldzBP9aGxzeN7G18= -github.com/catenacyber/perfsprint v0.7.1 h1:PGW5G/Kxn+YrN04cRAZKC+ZuvlVwolYMrIyyTJ/rMmc= -github.com/catenacyber/perfsprint v0.7.1/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50= -github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg= -github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d h1:S2NE3iHSwP0XV47EEXL8mWmRdEfGscSJ+7EgePNgt0s= github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= 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.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= -github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= -github.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc= -github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww= github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= 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.2.0 h1:FykcZuJ8BD7oX93YbO1UY9oZtkRbp+1/kJcDjkefYLs= -github.com/ckaznocha/intrange v0.2.0/go.mod h1:r5I7nUlAAG56xmkOpw4XVr16BXhwYTUdcuRFeevn1oE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= -github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= -github.com/daixiang0/gci v0.13.5 h1:kThgmH1yBmZSBCh1EJVxQ7JsHpm5Oms0AMed/0LaH4c= -github.com/daixiang0/gci v0.13.5/go.mod h1:12etP2OniiIdP4q+kjUGrC/rUagga7ODbqsom5Eo5Yk= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/dave/jennifer v1.4.1 h1:XyqG6cn5RQsTj3qlWQTKlRGAyrTcsk1kUmWdZBzRjDw= github.com/dave/jennifer v1.4.1/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/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/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -160,35 +87,19 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 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.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= -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.5 h1:tM+Me2ZaXs8tfdDw3X6DOX++wMCOqzYUho6tUTYIdRA= -github.com/firefart/nonamedreturns v1.0.5/go.mod h1:gHJjDqhGM4WyPt639SOZs+G89Ko7QKH5R5BhnO6xJhw= github.com/flimzy/diff v0.1.5/go.mod h1:lFJtC7SPsK0EroDmGTSrdtWKAxOk3rO+q+e04LL05Hs= github.com/flimzy/testy v0.1.17-0.20190521133342-95b386c3ece6/go.mod h1:3szguN8NXqgq9bt9Gu8TQVj698PJWmyx/VY1frwwKrM= -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.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 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/getkin/kin-openapi v0.0.0-20180813063848-e1956e8013e5 h1:gXUMwj0PndSd+Ub1PptoPX0nAwrrS8/SVFTJwOIzjyk= github.com/getkin/kin-openapi v0.0.0-20180813063848-e1956e8013e5/go.mod h1:+0ZtELZf+SlWH8ZdA/IeFb3L/PKOKJx8eGxAlUZ/sOU= github.com/getsentry/sentry-go v0.29.0 h1:YtWluuCFg9OfcqnaujpY918N/AhCCwarIDWOYSBAjCA= github.com/getsentry/sentry-go v0.29.0/go.mod h1:jhPesDAL0Q0W2+2YEuVOvdWmVtdsr1+jtBrlDEVWwLY= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/ghostiam/protogetter v0.3.6 h1:R7qEWaSgFCsy20yYHNIJsU9ZOb8TziSRRxuAOTVKeOk= -github.com/ghostiam/protogetter v0.3.6/go.mod h1:7lpeDnEJ1ZjL/YtyoN99ljO4z0pd3H0d18/t2dPBxHw= -github.com/go-critic/go-critic v0.11.4 h1:O7kGOCx0NDIni4czrkRIXTnit0mkyKOCePh3My6OyEU= -github.com/go-critic/go-critic v0.11.4/go.mod h1:2QAdo4iuLik5S9YG0rT4wcZ8QxwHYkrr6/2MWAiv/vc= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -204,45 +115,11 @@ github.com/go-kivik/kivik/v3 v3.2.3/go.mod h1:chqVuHKAU9j2C7qL0cAH2FCO26oL+0B4aI github.com/go-kivik/kiviktest/v3 v3.0.3 h1:4zX1F1eLTbIvyKiylzdWDgPqofJWiuQzQhKwZwUXMB0= github.com/go-kivik/kiviktest/v3 v3.0.3/go.mod h1:sqsz3M2sJxTxAUdOj+2SU21y4phcpYc0FJIn+hbf1D0= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-pg/pg v6.14.5+incompatible h1:Tc74MTCCIVd8sAJshYHqutcHhO64/EBHBTydzCGt3Js= github.com/go-pg/pg v6.14.5+incompatible/go.mod h1:a2oXow+aFOrvwcKs3eIA0lNFmMilrxK2sOkB5NWe0vA= -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 v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -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-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.1.0 h1:gHnMa2Y/pIxElCH2GlZZ1lZSsn6XMtufpGyP1XxdC/w= -github.com/go-viper/mapstructure/v2 v2.1.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U= -github.com/go-xmlfmt/xmlfmt v1.1.2/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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= -github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -275,26 +152,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9 h1:/1322Qns6BtQxUZDTAT4SdcoxknUki7IAoK4SAXr8ME= -github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9/go.mod h1:Oesb/0uFAyWoaw1U1qS5zyjCg5NP9C9iwjnI4tIsXEE= -github.com/golangci/golangci-lint v1.61.0 h1:VvbOLaRVWmyxCnUIMTbf1kDsaJbTzH20FAMXTAlQGu8= -github.com/golangci/golangci-lint v1.61.0/go.mod h1:e4lztIrJJgLPhWvFPDkhiMwEFRrWlmFbrZea3FsJyN8= -github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs= -github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo= -github.com/golangci/modinfo v0.3.4 h1:oU5huX3fbxqQXdfspamej74DFX0kyGLkw1ppvXoJ8GA= -github.com/golangci/modinfo v0.3.4/go.mod h1:wytF1M5xl9u0ij8YSvhkEVPP3M5Mc7XLl1pxH3B2aUM= -github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c= -github.com/golangci/plugin-module-register v0.1.1/go.mod h1:TTpqoB6KkwOJMV8u7+NyXMrkwwESJLOkfl9TxR1DGFc= -github.com/golangci/revgrep v0.5.3 h1:3tL7c1XBMtWHHqVpS5ChmiAAoe4PF/d5+ULzV9sLAzs= -github.com/golangci/revgrep v0.5.3/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k= -github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed h1:IURFTjxeTfNFP0hTEi1YKjB/ub8zkpaOqFFMApi2EAs= -github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed/go.mod h1:XLXN8bNw4CGRPaqgl3bv/lhz7bsGPh4/xSaMTbo2vkQ= 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-cmdtest v0.4.1-0.20220921163831-55ab3332a786 h1:rcv+Ippz6RAtvaGgKxc+8FQIpxHgsF+HBzPyYL2cyVU= -github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786/go.mod h1:apVn/GCasLZUVpAJ6oWAuyP7Ne7CEsQbTnc0plM3m+o= 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= @@ -302,11 +161,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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.6/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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -319,9 +174,6 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf 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-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= -github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -333,51 +185,22 @@ github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORR github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s= -github.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -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.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= -github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= -github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= -github.com/gostaticanalysis/forcetypeassert v0.1.0 h1:6eUflI3DiGusXGK6X7cCcIgVCpZ2CiZ1Q7jl6ZxNV70= -github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= -github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= -github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= -github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= -github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= -github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0 h1:f4tggROQKKcnh4eItay6z/HbHLqghBxS8g7pyMhmDio= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0/go.mod h1:hKAkSgNkL0FII46ZkJcpVEAai4KV+swlIWCKfekd1pA= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E= -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/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 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/jgautheron/goconst v1.7.1 h1:VpdAG7Ca7yvvJk5n8dMwQhfEZJh95kl/Hl9S1OI5Jkk= -github.com/jgautheron/goconst v1.7.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= -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/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= -github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jjti/go-spancheck v0.6.2 h1:iYtoxqPMzHUPp7St+5yA8+cONdyXD3ug6KK15n7Pklk= -github.com/jjti/go-spancheck v0.6.2/go.mod h1:+X7lvIrR5ZdUTkxFYqzJ0abr8Sb5LOo80uOhWNqIrYA= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -386,16 +209,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm 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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= -github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= -github.com/karamaru-alpha/copyloopvar v1.1.0 h1:x7gNyKcC2vRBO1H2Mks5u1VxQtYvFiym7fCjIP8RPos= -github.com/karamaru-alpha/copyloopvar v1.1.0/go.mod h1:u7CIfztblY0jZLOQZgH3oYsJzpC2A7S6u/lfgSXHy0k= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/errcheck v1.7.0 h1:+SbscKmWJ5mOK/bO1zS60F5I9WwZDWOfRsC4RwfwRV0= -github.com/kisielk/errcheck v1.7.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkHAIKE/contextcheck v1.1.5 h1:CdnJh63tcDe53vG+RebdpdXJTc9atMgGqdx8LXxiilg= -github.com/kkHAIKE/contextcheck v1.1.5/go.mod h1:O930cpht4xb1YQpK+1+AgoM3mFsvxr7uyFptcnWTYUA= github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s= github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4= @@ -407,34 +222,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.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= -github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= -github.com/kunwardeep/paralleltest v1.0.10 h1:wrodoaKYzS2mdNVnc4/w31YaXFtsc21PCTdvWJ/lDDs= -github.com/kunwardeep/paralleltest v1.0.10/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY= -github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= -github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= -github.com/lasiar/canonicalheader v1.1.1 h1:wC+dY9ZfiqiPwAexUApFush/csSPXeIi4QqyxXmng8I= -github.com/lasiar/canonicalheader v1.1.1/go.mod h1:cXkb3Dlk6XXy+8MVQnF23CYKWlyA7kfQhSw2CcZtZb0= -github.com/ldez/gomoddirectives v0.2.4 h1:j3YjBIjEBbqZ0NKtBNzr8rtMHTOrLPeiwTkfUJZ3alg= -github.com/ldez/gomoddirectives v0.2.4/go.mod h1:oWu9i62VcQDYp9EQ0ONTfqLNh+mDLWWDO+SO0qSQw5g= -github.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSioo= -github.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4= -github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY= -github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA= -github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= -github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= -github.com/macabu/inamedparam v0.1.3 h1:2tk/phHkMlEL/1GNe/Yf6kkR/hkcUdAEY3L0hjYV1Mk= -github.com/macabu/inamedparam v0.1.3/go.mod h1:93FLICAIk/quk7eaPPQvbzihUdn/QkGDwIZEoLtpH6I= -github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= -github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= -github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= -github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= -github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= -github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= -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.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -445,13 +232,6 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D 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.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/goveralls v0.0.12 h1:PEEeF0k1SsTjOBQ8FOmrOAoCu4ytuMaWCnWe94zxbCg= -github.com/mattn/goveralls v0.0.12/go.mod h1:44ImGEUfmqH8bBtaMrYKsM65LXfNLWmwaxFGjZwgMSQ= -github.com/mgechev/revive v1.3.9 h1:18Y3R4a2USSBF+QZKFQwVkBROUda7uoBlkEuBD+YD1A= -github.com/mgechev/revive v1.3.9/go.mod h1:+uxEIr5UH0TjXWHTno3xh4u7eg6jDpXKzQccA9UGhHU= github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4= github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= github.com/minio/minio-go/v7 v7.0.7 h1:Qld/xb8C1Pwbu0jU46xAceyn9xXKCMW+3XfNbpmTB70= @@ -461,8 +241,6 @@ github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl github.com/minio/sio v0.2.1/go.mod h1:8b0yPp2avGThviy/+OCJBI6OMpvxoUuiLvE6F1lebhw= 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/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -470,28 +248,14 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 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/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.16.2 h1:8iLqHIZvN4fTLDC0Ke9tbSZVcyVHoBs0HIbnVSxfHJk= -github.com/nunnatsa/ginkgolinter v0.16.2/go.mod h1:4tWRinDN1FeJgU+iJANW/kz7xKN5nYRAOfJDQUS9dOQ= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= -github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= @@ -499,19 +263,12 @@ github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1 github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/otiai10/copy v1.0.2/go.mod h1:c7RpqBkwMom4bYTSkLSym4VSJz/XtncWRAj/J4PEIMY= -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 v0.0.0-20190513014714-f5a3d24e5776/go.mod h1:3HNVkVOU7vZeFXocWuvtcS0XSFLcf2XUSDHkq9t1jU4= -github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= 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.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= -github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pieceofsoul/govalidator v0.0.0-20230607103513-8dce951b10b8 h1:cQraHfaehYYI/SZydx2eEgv6N4bS6jYbkLdY7i8m++s= github.com/pieceofsoul/govalidator v0.0.0-20230607103513-8dce951b10b8/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -521,10 +278,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polyfloyd/go-errorlint v1.6.0 h1:tftWV9DE7txiFzPpztTAwyoRLKNj9gpVm2cg8/OwcYY= -github.com/polyfloyd/go-errorlint v1.6.0/go.mod h1:HR7u8wuP1kb1NeN1zqTd1ZMlqUKPPHF+Id4vIPvDqVw= -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 v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -534,20 +287,8 @@ github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSz github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1 h1:+Wl/0aFp0hpuHM3H//KMft64WQ1yX9LdJY64Qm/gFCo= -github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1/go.mod h1:GJLgqsLeo4qgavUoL8JeGFNS7qcisx3awV/w9eWTmNI= -github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE= -github.com/quasilyte/go-ruleguard/dsl v0.3.22/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/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= @@ -557,145 +298,47 @@ github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.3.5 h1:cShyguSwUEeC0jS7ylOiG/idnd1TpJ1LfHGpV3oJmPU= -github.com/ryancurrah/gomodguard v1.3.5/go.mod h1:MXlEPQRxgfPQa62O8wzK3Ozbkv9Rkqr+wKjSxTdsNJE= -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.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= -github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= -github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= -github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= -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.27.0 h1:t/3jZpSXtRPRf2xr0m63i32ZrusyurIGT9E5wAvXQnI= -github.com/sashamelentyev/usestdlibvars v1.27.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8= -github.com/securego/gosec/v2 v2.21.2 h1:deZp5zmYf3TWwU7A7cR2+SolbTpZ3HQiwFqnzQyEl3M= -github.com/securego/gosec/v2 v2.21.2/go.mod h1:au33kg78rNseF5PwPnTWhuYBFf534bvJRvOrgZ/bFzU= -github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= -github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -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/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -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/sivchari/tenv v1.10.0 h1:g/hzMA+dBCKqGXgW8AV/1xIWhAvDrx0zFKNR48NFMg0= -github.com/sivchari/tenv v1.10.0/go.mod h1:tdY24masnVoZFxYrHv/nD6Tc8FbkEtAQEEziXpyMgqY= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00= -github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -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.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -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.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -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 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/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.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= -github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= 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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -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/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= -github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= -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.4.17 h1:pGzu+Ye7ZUEFx7LHU0dAKmCOXWsPjl7qA6iMGndsjPs= -github.com/tetafro/godot v1.4.17/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio= -github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 h1:quvGphlmUVU+nhpFa4gg4yJyTRJ13reZMDHrKwYw53M= -github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= -github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= -github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= -github.com/tomarrell/wrapcheck/v2 v2.9.0 h1:801U2YCAjLhdN8zhZ/7tdjB3EnAoRlJHt/s+9hijLQ4= -github.com/tomarrell/wrapcheck/v2 v2.9.0/go.mod h1:g9vNIyhb5/9TQgumxQyOEqDHsmGYcGsVMOx/xGkqdMo= -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.1.0 h1:BuqclbkY6pO+cvxoq7OsktIXZpgBSkYTQtmwhAK81vI= -github.com/ultraware/funlen v0.1.0/go.mod h1:XJqmOQja6DpxarLj6Jj1U7JuoS8PvL4nEqDaQhy22p4= -github.com/ultraware/whitespace v0.1.1 h1:bTPOGejYFulW3PkcrqkeQwOd6NKOOXvmGD9bo/Gk8VQ= -github.com/ultraware/whitespace v0.1.1/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8= -github.com/uudashr/gocognit v1.1.3 h1:l+a111VcDbKfynh+airAy/DJQKaXh2m9vkoysMPSZyM= -github.com/uudashr/gocognit v1.1.3/go.mod h1:aKH8/e8xbTRBwjbCkwZ8qt4l2EpKXl31KMHgSS+lZ2U= -github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= -github.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg= -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/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/zenazn/goji v1.0.1 h1:4lbD8Mx2h7IvloP7r2C0D6ltZP6Ufip8Hn0wmSK5LR8= github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo= -gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8= gitlab.com/flimzy/testy v0.0.3/go.mod h1:YObF4cq711ubd/3U0ydRQQVz7Cnq/ChgJpVwNr/AJac= gitlab.com/flimzy/testy v0.3.2 h1:4djQFwBJ1ayM681Zx7Y3+OKns/E9zAfGFsLc967jfdk= gitlab.com/flimzy/testy v0.3.2/go.mod h1:YObF4cq711ubd/3U0ydRQQVz7Cnq/ChgJpVwNr/AJac= -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.12.2 h1:J7lRc2ysXOq7eM8rwaTYnNrHd5JwjppzB6mScysB2Cs= -go-simpler.org/musttag v0.12.2/go.mod h1:uN1DVIasMTQKk6XSik7yrJoEysGtR2GRqvWnI9S7TYM= -go-simpler.org/sloglint v0.7.2 h1:Wc9Em/Zeuu7JYpl+oKoYOsQSy2X560aVueCW/m6IijY= -go-simpler.org/sloglint v0.7.2/go.mod h1:US+9C80ppl7VsThQclkM7BkCHQAzuz8kHLsW3ppuluo= 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.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= -go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= 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-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -703,8 +346,6 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U 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-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -717,12 +358,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 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-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk= -golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= -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-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= -golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= 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= @@ -743,17 +378,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB 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.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -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.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -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.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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -784,17 +408,8 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R 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-20201110031124-69a78807bb2b/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-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210510120150-4163338589ed/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.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -814,9 +429,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ 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-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.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -856,49 +468,21 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w 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-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/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-20210615035016-665e8c7367d1/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-20211025201205-69cdffdb9359/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-20220412211240-33da011f77ad/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.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/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.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7 h1:FemxDzfMUcK2f3YY4H+05K9CDzbSVr2+q/JKN45pey0= -golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= 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.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -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.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -910,7 +494,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 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-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/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= @@ -919,7 +502,6 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw 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-20190910044552-dd2b5c81c578/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-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -940,39 +522,17 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK 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-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -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-20200619180055-7c47624df98f/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-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -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.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -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.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= -golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= -golang.org/x/vuln v1.1.3 h1:NPGnvPOTgnjBc9HTaUx+nj+EaUYxl5SJOWqaDYGaFYw= -golang.org/x/vuln v1.1.3/go.mod h1:7Le6Fadm5FOqE9C926BCD0g12NWyhg7cxV4BwcPFuNY= 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= @@ -1049,8 +609,6 @@ google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= 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= @@ -1094,12 +652,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh 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.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I= -honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs= -mvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU= -mvdan.cc/gofumpt v0.7.0/go.mod h1:txVFJy/Sc/mvaycET54pV8SW8gWxTlUuGHVEcncmNUo= -mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8XzX0u72NttUGVFjO3U= -mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ= 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= From 0e753a10d6b2bd5639c8e261ea48dc51fc3ae9a7 Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Wed, 4 Dec 2024 14:12:44 +0100 Subject: [PATCH 5/5] lint: Drop vendoring --- .golangci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 1f771c922..b34322498 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,6 +1,5 @@ # for further options, see https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml run: - modules-download-mode: vendor timeout: 4m issues: include: