diff --git a/src/go.mod b/src/go.mod index 17c1a601..f55009b7 100644 --- a/src/go.mod +++ b/src/go.mod @@ -1,14 +1,14 @@ module github.com/dechristopher/lio -go 1.25.7 +go 1.26.0 require ( github.com/a-h/templ v0.3.1020 github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef github.com/dechristopher/octad/v2 v2.1.0 github.com/go-webauthn/webauthn v0.17.4 - github.com/gofiber/contrib/v3/websocket v1.2.2 - github.com/gofiber/fiber/v3 v3.4.0 + github.com/gofiber/contrib/v3/websocket v1.2.6 + github.com/gofiber/fiber/v3 v3.5.0 github.com/google/uuid v1.6.0 github.com/jackc/pgx/v5 v5.10.0 github.com/joho/godotenv v1.5.1 @@ -21,10 +21,10 @@ require ( github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef github.com/valyala/fastjson v1.6.10 - golang.org/x/crypto v0.54.0 + golang.org/x/crypto v0.57.0 golang.org/x/image v0.44.0 - golang.org/x/sync v0.22.0 - golang.org/x/text v0.40.0 + golang.org/x/sync v0.23.0 + golang.org/x/text v0.42.0 ) require ( @@ -33,38 +33,39 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/fasthttp/websocket v1.5.12 // indirect - github.com/fxamacker/cbor/v2 v2.9.2 // indirect + github.com/fxamacker/cbor/v2 v2.9.3 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/go-webauthn/x v0.2.6 // indirect - github.com/gofiber/schema v1.8.3 // indirect - github.com/gofiber/utils/v2 v2.2.0 // indirect + github.com/gofiber/schema v1.8.6 // indirect + github.com/gofiber/utils/v2 v2.5.1 // indirect github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/google/go-tpm v0.9.8 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/klauspost/compress v1.19.1 // indirect + github.com/klauspost/compress v1.20.0 // indirect github.com/klauspost/cpuid/v2 v2.4.0 // indirect github.com/klauspost/crc32 v1.3.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/mattn/go-colorable v0.1.15 // indirect - github.com/mattn/go-isatty v0.0.23 // indirect + github.com/mattn/go-isatty v0.0.24 // indirect github.com/mfridman/interpolate v0.0.2 // indirect github.com/minio/crc64nvme v1.1.1 // indirect github.com/minio/md5-simd v1.1.2 // indirect + github.com/molecule-man/go-brrr v1.0.1 // indirect github.com/philhofer/fwd v1.2.0 // indirect github.com/rs/xid v1.6.0 // indirect github.com/savsgio/gotils v0.0.0-20250924091648-bce9a52d7761 // indirect github.com/sethvargo/go-retry v0.4.0 // indirect github.com/tinylib/msgp v1.6.4 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.72.0 // indirect + github.com/valyala/fasthttp v1.74.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.57.0 // indirect - golang.org/x/sys v0.47.0 // indirect + go.yaml.in/yaml/v3 v3.0.5 // indirect + golang.org/x/net v0.59.0 // indirect + golang.org/x/sys v0.48.0 // indirect gopkg.in/ini.v1 v1.67.3 // indirect ) diff --git a/src/go.sum b/src/go.sum index e463bac9..ee1eb112 100644 --- a/src/go.sum +++ b/src/go.sum @@ -25,6 +25,8 @@ github.com/fasthttp/websocket v1.5.12 h1:e4RGPpWW2HTbL3zV0Y/t7g0ub294LkiuXXUuTOU github.com/fasthttp/websocket v1.5.12/go.mod h1:I+liyL7/4moHojiOgUOIKEWm9EIxHqxZChS+aMFltyg= github.com/fxamacker/cbor/v2 v2.9.2 h1:X4Ksno9+x3cz0TZv69ec1hxP/+tymuR8PXQJyDwfh78= github.com/fxamacker/cbor/v2 v2.9.2/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.3 h1:oQBnFATpNdY8gJHTndDDv5Xl4QqNaz51G5LLEPhng3Q= +github.com/fxamacker/cbor/v2 v2.9.3/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-webauthn/webauthn v0.17.4 h1:KFTSz3R2RYDiUn/0cDi3XTJgFenSG74eKTTHlqWhlxk= @@ -35,16 +37,24 @@ github.com/gofiber/contrib/v3/websocket v1.2.1 h1:E4I1dVCvNF56ELdKksUJilo1r7dpw7 github.com/gofiber/contrib/v3/websocket v1.2.1/go.mod h1:rQO2z0SbC/l8lP36gXTKrD1QZBXzHKwt9E8c5em1IiA= github.com/gofiber/contrib/v3/websocket v1.2.2 h1:kmoD+A0f4btoDSOnZJUHzJyBi1tQqL9tNhn4n0nPJSQ= github.com/gofiber/contrib/v3/websocket v1.2.2/go.mod h1:H0kwFA9iXc5RJca4QqCjWwc2kIpuOGQSZJONqsxwWXI= +github.com/gofiber/contrib/v3/websocket v1.2.6 h1:5XcHejNCq460uLSdDAAp11RIrDGMHax07d0zWUZXgYc= +github.com/gofiber/contrib/v3/websocket v1.2.6/go.mod h1:QHnpSvNDsoVHrfSvnMl9ptx6x4l83moCtiT+4XM++nw= github.com/gofiber/fiber/v3 v3.4.0 h1:F0aND4vwZF7dR7cbvSwFQQEpBU902XHKWxrLsFBkVqw= github.com/gofiber/fiber/v3 v3.4.0/go.mod h1:nAhJfdxUIJJph2tPWPmqWf8QDIN2iiqQiQf3lENZpdk= +github.com/gofiber/fiber/v3 v3.5.0 h1:dk7TOUH6DXJGtOLsN2XEG+0ZML7cznzHILTVozbNEK8= +github.com/gofiber/fiber/v3 v3.5.0/go.mod h1:GOVDTW+gjJvfe0iJyVujbQ1Lnx+JUjFySJRI/9/xX/w= github.com/gofiber/schema v1.8.0 h1:NGsC9toPHmj8Xg4KpznuXBzNmHG6V5YV0tXKpKMcmis= github.com/gofiber/schema v1.8.0/go.mod h1:lmbXPQ8hvzXSLkdS2DS7pb4kpunC2Roh7Sj3HMjGfzA= github.com/gofiber/schema v1.8.3 h1:06ZedxIYjngzc0095PYy7uWnFnbRflWFpikvZH61fDc= github.com/gofiber/schema v1.8.3/go.mod h1:jWnnZdhcW1mHyV+VnfRxKJDPNcepJsTZ9RIWxrr32Ng= +github.com/gofiber/schema v1.8.6 h1:xVlbSg3vsyKVlfzRBps2tJ7pHx1d8mSgiaJye6Lb3xs= +github.com/gofiber/schema v1.8.6/go.mod h1:Cxh3loYVG3FLA7FzW4C5G83pL/pmCmAnuaIJ5y2HwkU= github.com/gofiber/utils/v2 v2.1.1 h1:kGnoGjwEnFW6w0x45W+kLlmMJvqBGkuUA4oMWKn/T/I= github.com/gofiber/utils/v2 v2.1.1/go.mod h1:DdOgEVwQTi8cou/AKWPqhXOR4fHGRVhA/rEWL3IXG7Q= github.com/gofiber/utils/v2 v2.2.0 h1:YSSmCzQponq/f9uSOg2HtXC5qK1Dmor0o6DqaQVz8GE= github.com/gofiber/utils/v2 v2.2.0/go.mod h1:Ieopk6sQh7rbhQ12aBNCJtJuG0gxAg0nz63sFCrrOmE= +github.com/gofiber/utils/v2 v2.5.1 h1:Yrt/ljbfsgnDSHymoMvVX5PFrb9kCV/OJnDu6sYuT4A= +github.com/gofiber/utils/v2 v2.5.1/go.mod h1:5GyHTNQA1I6Qwlw7BWxQsZl8iuFS4yPjLFck+wYR304= github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= @@ -69,6 +79,8 @@ github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2o github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk= github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA= +github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw= github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU= @@ -86,6 +98,8 @@ github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= github.com/mattn/go-isatty v0.0.23 h1:cYwCQTQf3HB6xUC+BtyCLZNr7IzbOmoZbmssVNzSyiQ= github.com/mattn/go-isatty v0.0.23/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= +github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI= +github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI= @@ -94,6 +108,8 @@ github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/minio-go/v7 v7.2.1 h1:PfBfwvKB/MmqyN8Vb1G9voWisaM9OrLv+WwOvMwS9Dw= github.com/minio/minio-go/v7 v7.2.1/go.mod h1:EU9hENAStx/xXduNdrGO5e4X5vk19NtgB+RIPjZO8o0= +github.com/molecule-man/go-brrr v1.0.1 h1:cEjgx8hgNw6UGdhQ94SPDbPkKuRbkUcxBO3IzbGpA/o= +github.com/molecule-man/go-brrr v1.0.1/go.mod h1:7ybW6/7gA3oKY45jOfVNjSJDtrr6ea4tzbsTkjmQDC4= github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w= github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= @@ -146,6 +162,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.72.0 h1:R7kYdoWhn1ye1fVpP+cDHDJwYm3NkwLliwgzJ/Abg7M= github.com/valyala/fasthttp v1.72.0/go.mod h1:zsbLTYqcpIktdQytlVBwIjY9La5d6bs990nBxWg8efk= +github.com/valyala/fasthttp v1.74.0 h1:wMS9fnO2QTALozYx5pId2Vi7ZwU/epUkY8i/KPWCHoU= +github.com/valyala/fasthttp v1.74.0/go.mod h1:3ARmLamUcw7ElxVtC8PXaGzQ6VEuvnetlkrwIklQBSE= github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADTh4= github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -164,24 +182,36 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/image v0.44.0 h1:+tDekMZED9+LrtB3G5xzRggpVh9CARjZqROla3R3R+I= golang.org/x/image v0.44.0/go.mod h1:V8K3KE9KKKE+pLpQDOeN18w9oacNSvy1tDOirTu4xtY= golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= +golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues= +golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/src/vendor/github.com/andybalholm/brotli/.gitignore b/src/vendor/github.com/andybalholm/brotli/.gitignore deleted file mode 100644 index 7fd17523..00000000 --- a/src/vendor/github.com/andybalholm/brotli/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -cpu.out -brotli.test diff --git a/src/vendor/github.com/andybalholm/brotli/README.md b/src/vendor/github.com/andybalholm/brotli/README.md deleted file mode 100644 index 3494ec47..00000000 --- a/src/vendor/github.com/andybalholm/brotli/README.md +++ /dev/null @@ -1,19 +0,0 @@ -This package is a brotli compressor and decompressor implemented in Go. -It was translated from the reference implementation (https://github.com/google/brotli) -with the `c2go` tool at https://github.com/andybalholm/c2go. - -I am using it in production with https://github.com/andybalholm/redwood. - -API documentation is found at https://pkg.go.dev/github.com/andybalholm/brotli?tab=doc. - -## Roadmap - -I have been working on new compression algorithms (not translated from C) -in the matchfinder package. -You can use them with the NewWriterV2 function. -Currently they give better results than the old implementation -(at least for compressing my test file, Newton’s *Opticks*) -on levels 0 to 9. - -The new APIs are currently considered experimental, -and are not covered by any SemVer compatibility guarantees. diff --git a/src/vendor/github.com/andybalholm/brotli/backward_references.go b/src/vendor/github.com/andybalholm/brotli/backward_references.go deleted file mode 100644 index 008c054d..00000000 --- a/src/vendor/github.com/andybalholm/brotli/backward_references.go +++ /dev/null @@ -1,185 +0,0 @@ -package brotli - -import ( - "sync" -) - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Function to find backward reference copies. */ - -func computeDistanceCode(distance uint, max_distance uint, dist_cache []int) uint { - if distance <= max_distance { - var distance_plus_3 uint = distance + 3 - var offset0 uint = distance_plus_3 - uint(dist_cache[0]) - var offset1 uint = distance_plus_3 - uint(dist_cache[1]) - if distance == uint(dist_cache[0]) { - return 0 - } else if distance == uint(dist_cache[1]) { - return 1 - } else if offset0 < 7 { - return (0x9750468 >> (4 * offset0)) & 0xF - } else if offset1 < 7 { - return (0xFDB1ACE >> (4 * offset1)) & 0xF - } else if distance == uint(dist_cache[2]) { - return 2 - } else if distance == uint(dist_cache[3]) { - return 3 - } - } - - return distance + numDistanceShortCodes - 1 -} - -var hasherSearchResultPool sync.Pool - -func createBackwardReferences(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, hasher hasherHandle, dist_cache []int, last_insert_len *uint, commands *[]command, num_literals *uint) { - var max_backward_limit uint = maxBackwardLimit(params.lgwin) - var insert_length uint = *last_insert_len - var pos_end uint = position + num_bytes - var store_end uint - if num_bytes >= hasher.StoreLookahead() { - store_end = position + num_bytes - hasher.StoreLookahead() + 1 - } else { - store_end = position - } - var random_heuristics_window_size uint = literalSpreeLengthForSparseSearch(params) - var apply_random_heuristics uint = position + random_heuristics_window_size - var gap uint = 0 - /* Set maximum distance, see section 9.1. of the spec. */ - - const kMinScore uint = scoreBase + 100 - - /* For speed up heuristics for random data. */ - - /* Minimum score to accept a backward reference. */ - hasher.PrepareDistanceCache(dist_cache) - sr2, _ := hasherSearchResultPool.Get().(*hasherSearchResult) - if sr2 == nil { - sr2 = &hasherSearchResult{} - } - sr, _ := hasherSearchResultPool.Get().(*hasherSearchResult) - if sr == nil { - sr = &hasherSearchResult{} - } - - for position+hasher.HashTypeLength() < pos_end { - var max_length uint = pos_end - position - var max_distance uint = brotli_min_size_t(position, max_backward_limit) - sr.len = 0 - sr.len_code_delta = 0 - sr.distance = 0 - sr.score = kMinScore - hasher.FindLongestMatch(¶ms.dictionary, ringbuffer, ringbuffer_mask, dist_cache, position, max_length, max_distance, gap, params.dist.max_distance, sr) - if sr.score > kMinScore { - /* Found a match. Let's look for something even better ahead. */ - var delayed_backward_references_in_row int = 0 - max_length-- - for ; ; max_length-- { - var cost_diff_lazy uint = 175 - if params.quality < minQualityForExtensiveReferenceSearch { - sr2.len = brotli_min_size_t(sr.len-1, max_length) - } else { - sr2.len = 0 - } - sr2.len_code_delta = 0 - sr2.distance = 0 - sr2.score = kMinScore - max_distance = brotli_min_size_t(position+1, max_backward_limit) - hasher.FindLongestMatch(¶ms.dictionary, ringbuffer, ringbuffer_mask, dist_cache, position+1, max_length, max_distance, gap, params.dist.max_distance, sr2) - if sr2.score >= sr.score+cost_diff_lazy { - /* Ok, let's just write one byte for now and start a match from the - next byte. */ - position++ - - insert_length++ - *sr = *sr2 - delayed_backward_references_in_row++ - if delayed_backward_references_in_row < 4 && position+hasher.HashTypeLength() < pos_end { - continue - } - } - - break - } - - apply_random_heuristics = position + 2*sr.len + random_heuristics_window_size - max_distance = brotli_min_size_t(position, max_backward_limit) - { - /* The first 16 codes are special short-codes, - and the minimum offset is 1. */ - var distance_code uint = computeDistanceCode(sr.distance, max_distance+gap, dist_cache) - if (sr.distance <= (max_distance + gap)) && distance_code > 0 { - dist_cache[3] = dist_cache[2] - dist_cache[2] = dist_cache[1] - dist_cache[1] = dist_cache[0] - dist_cache[0] = int(sr.distance) - hasher.PrepareDistanceCache(dist_cache) - } - - *commands = append(*commands, makeCommand(¶ms.dist, insert_length, sr.len, sr.len_code_delta, distance_code)) - } - - *num_literals += insert_length - insert_length = 0 - /* Put the hash keys into the table, if there are enough bytes left. - Depending on the hasher implementation, it can push all positions - in the given range or only a subset of them. - Avoid hash poisoning with RLE data. */ - { - var range_start uint = position + 2 - var range_end uint = brotli_min_size_t(position+sr.len, store_end) - if sr.distance < sr.len>>2 { - range_start = brotli_min_size_t(range_end, brotli_max_size_t(range_start, position+sr.len-(sr.distance<<2))) - } - - hasher.StoreRange(ringbuffer, ringbuffer_mask, range_start, range_end) - } - - position += sr.len - } else { - insert_length++ - position++ - - /* If we have not seen matches for a long time, we can skip some - match lookups. Unsuccessful match lookups are very very expensive - and this kind of a heuristic speeds up compression quite - a lot. */ - if position > apply_random_heuristics { - /* Going through uncompressible data, jump. */ - if position > apply_random_heuristics+4*random_heuristics_window_size { - var kMargin uint = brotli_max_size_t(hasher.StoreLookahead()-1, 4) - /* It is quite a long time since we saw a copy, so we assume - that this data is not compressible, and store hashes less - often. Hashes of non compressible data are less likely to - turn out to be useful in the future, too, so we store less of - them to not to flood out the hash table of good compressible - data. */ - - var pos_jump uint = brotli_min_size_t(position+16, pos_end-kMargin) - for ; position < pos_jump; position += 4 { - hasher.Store(ringbuffer, ringbuffer_mask, position) - insert_length += 4 - } - } else { - var kMargin uint = brotli_max_size_t(hasher.StoreLookahead()-1, 2) - var pos_jump uint = brotli_min_size_t(position+8, pos_end-kMargin) - for ; position < pos_jump; position += 2 { - hasher.Store(ringbuffer, ringbuffer_mask, position) - insert_length += 2 - } - } - } - } - } - - insert_length += pos_end - position - *last_insert_len = insert_length - - hasherSearchResultPool.Put(sr) - hasherSearchResultPool.Put(sr2) -} diff --git a/src/vendor/github.com/andybalholm/brotli/backward_references_hq.go b/src/vendor/github.com/andybalholm/brotli/backward_references_hq.go deleted file mode 100644 index 21629c1c..00000000 --- a/src/vendor/github.com/andybalholm/brotli/backward_references_hq.go +++ /dev/null @@ -1,796 +0,0 @@ -package brotli - -import "math" - -type zopfliNode struct { - length uint32 - distance uint32 - dcode_insert_length uint32 - u struct { - cost float32 - next uint32 - shortcut uint32 - } -} - -const maxEffectiveDistanceAlphabetSize = 544 - -const kInfinity float32 = 1.7e38 /* ~= 2 ^ 127 */ - -var kDistanceCacheIndex = []uint32{0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1} - -var kDistanceCacheOffset = []int{0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3} - -func initZopfliNodes(array []zopfliNode, length uint) { - var stub zopfliNode - var i uint - stub.length = 1 - stub.distance = 0 - stub.dcode_insert_length = 0 - stub.u.cost = kInfinity - for i = 0; i < length; i++ { - array[i] = stub - } -} - -func zopfliNodeCopyLength(self *zopfliNode) uint32 { - return self.length & 0x1FFFFFF -} - -func zopfliNodeLengthCode(self *zopfliNode) uint32 { - var modifier uint32 = self.length >> 25 - return zopfliNodeCopyLength(self) + 9 - modifier -} - -func zopfliNodeCopyDistance(self *zopfliNode) uint32 { - return self.distance -} - -func zopfliNodeDistanceCode(self *zopfliNode) uint32 { - var short_code uint32 = self.dcode_insert_length >> 27 - if short_code == 0 { - return zopfliNodeCopyDistance(self) + numDistanceShortCodes - 1 - } else { - return short_code - 1 - } -} - -func zopfliNodeCommandLength(self *zopfliNode) uint32 { - return zopfliNodeCopyLength(self) + (self.dcode_insert_length & 0x7FFFFFF) -} - -/* Histogram based cost model for zopflification. */ -type zopfliCostModel struct { - cost_cmd_ [numCommandSymbols]float32 - cost_dist_ []float32 - distance_histogram_size uint32 - literal_costs_ []float32 - min_cost_cmd_ float32 - num_bytes_ uint -} - -func initZopfliCostModel(self *zopfliCostModel, dist *distanceParams, num_bytes uint) { - var distance_histogram_size uint32 = dist.alphabet_size - if distance_histogram_size > maxEffectiveDistanceAlphabetSize { - distance_histogram_size = maxEffectiveDistanceAlphabetSize - } - - self.num_bytes_ = num_bytes - self.literal_costs_ = make([]float32, (num_bytes + 2)) - self.cost_dist_ = make([]float32, (dist.alphabet_size)) - self.distance_histogram_size = distance_histogram_size -} - -func cleanupZopfliCostModel(self *zopfliCostModel) { - self.literal_costs_ = nil - self.cost_dist_ = nil -} - -func setCost(histogram []uint32, histogram_size uint, literal_histogram bool, cost []float32) { - var sum uint = 0 - var missing_symbol_sum uint - var log2sum float32 - var missing_symbol_cost float32 - var i uint - for i = 0; i < histogram_size; i++ { - sum += uint(histogram[i]) - } - - log2sum = float32(fastLog2(sum)) - missing_symbol_sum = sum - if !literal_histogram { - for i = 0; i < histogram_size; i++ { - if histogram[i] == 0 { - missing_symbol_sum++ - } - } - } - - missing_symbol_cost = float32(fastLog2(missing_symbol_sum)) + 2 - for i = 0; i < histogram_size; i++ { - if histogram[i] == 0 { - cost[i] = missing_symbol_cost - continue - } - - /* Shannon bits for this symbol. */ - cost[i] = log2sum - float32(fastLog2(uint(histogram[i]))) - - /* Cannot be coded with less than 1 bit */ - if cost[i] < 1 { - cost[i] = 1 - } - } -} - -func zopfliCostModelSetFromCommands(self *zopfliCostModel, position uint, ringbuffer []byte, ringbuffer_mask uint, commands []command, last_insert_len uint) { - var histogram_literal [numLiteralSymbols]uint32 - var histogram_cmd [numCommandSymbols]uint32 - var histogram_dist [maxEffectiveDistanceAlphabetSize]uint32 - var cost_literal [numLiteralSymbols]float32 - var pos uint = position - last_insert_len - var min_cost_cmd float32 = kInfinity - var cost_cmd []float32 = self.cost_cmd_[:] - var literal_costs []float32 - - histogram_literal = [numLiteralSymbols]uint32{} - histogram_cmd = [numCommandSymbols]uint32{} - histogram_dist = [maxEffectiveDistanceAlphabetSize]uint32{} - - for i := range commands { - var inslength uint = uint(commands[i].insert_len_) - var copylength uint = uint(commandCopyLen(&commands[i])) - var distcode uint = uint(commands[i].dist_prefix_) & 0x3FF - var cmdcode uint = uint(commands[i].cmd_prefix_) - var j uint - - histogram_cmd[cmdcode]++ - if cmdcode >= 128 { - histogram_dist[distcode]++ - } - - for j = 0; j < inslength; j++ { - histogram_literal[ringbuffer[(pos+j)&ringbuffer_mask]]++ - } - - pos += inslength + copylength - } - - setCost(histogram_literal[:], numLiteralSymbols, true, cost_literal[:]) - setCost(histogram_cmd[:], numCommandSymbols, false, cost_cmd) - setCost(histogram_dist[:], uint(self.distance_histogram_size), false, self.cost_dist_) - - for i := 0; i < numCommandSymbols; i++ { - min_cost_cmd = brotli_min_float(min_cost_cmd, cost_cmd[i]) - } - - self.min_cost_cmd_ = min_cost_cmd - { - literal_costs = self.literal_costs_ - var literal_carry float32 = 0.0 - num_bytes := int(self.num_bytes_) - literal_costs[0] = 0.0 - for i := 0; i < num_bytes; i++ { - literal_carry += cost_literal[ringbuffer[(position+uint(i))&ringbuffer_mask]] - literal_costs[i+1] = literal_costs[i] + literal_carry - literal_carry -= literal_costs[i+1] - literal_costs[i] - } - } -} - -func zopfliCostModelSetFromLiteralCosts(self *zopfliCostModel, position uint, ringbuffer []byte, ringbuffer_mask uint) { - var literal_costs []float32 = self.literal_costs_ - var literal_carry float32 = 0.0 - var cost_dist []float32 = self.cost_dist_ - var cost_cmd []float32 = self.cost_cmd_[:] - var num_bytes uint = self.num_bytes_ - var i uint - estimateBitCostsForLiterals(position, num_bytes, ringbuffer_mask, ringbuffer, literal_costs[1:]) - literal_costs[0] = 0.0 - for i = 0; i < num_bytes; i++ { - literal_carry += literal_costs[i+1] - literal_costs[i+1] = literal_costs[i] + literal_carry - literal_carry -= literal_costs[i+1] - literal_costs[i] - } - - for i = 0; i < numCommandSymbols; i++ { - cost_cmd[i] = float32(fastLog2(uint(11 + uint32(i)))) - } - - for i = 0; uint32(i) < self.distance_histogram_size; i++ { - cost_dist[i] = float32(fastLog2(uint(20 + uint32(i)))) - } - - self.min_cost_cmd_ = float32(fastLog2(11)) -} - -func zopfliCostModelGetCommandCost(self *zopfliCostModel, cmdcode uint16) float32 { - return self.cost_cmd_[cmdcode] -} - -func zopfliCostModelGetDistanceCost(self *zopfliCostModel, distcode uint) float32 { - return self.cost_dist_[distcode] -} - -func zopfliCostModelGetLiteralCosts(self *zopfliCostModel, from uint, to uint) float32 { - return self.literal_costs_[to] - self.literal_costs_[from] -} - -func zopfliCostModelGetMinCostCmd(self *zopfliCostModel) float32 { - return self.min_cost_cmd_ -} - -/* REQUIRES: len >= 2, start_pos <= pos */ -/* REQUIRES: cost < kInfinity, nodes[start_pos].cost < kInfinity */ -/* Maintains the "ZopfliNode array invariant". */ -func updateZopfliNode(nodes []zopfliNode, pos uint, start_pos uint, len uint, len_code uint, dist uint, short_code uint, cost float32) { - var next *zopfliNode = &nodes[pos+len] - next.length = uint32(len | (len+9-len_code)<<25) - next.distance = uint32(dist) - next.dcode_insert_length = uint32(short_code<<27 | (pos - start_pos)) - next.u.cost = cost -} - -type posData struct { - pos uint - distance_cache [4]int - costdiff float32 - cost float32 -} - -/* Maintains the smallest 8 cost difference together with their positions */ -type startPosQueue struct { - q_ [8]posData - idx_ uint -} - -func initStartPosQueue(self *startPosQueue) { - self.idx_ = 0 -} - -func startPosQueueSize(self *startPosQueue) uint { - return brotli_min_size_t(self.idx_, 8) -} - -func startPosQueuePush(self *startPosQueue, posdata *posData) { - var offset uint = ^(self.idx_) & 7 - self.idx_++ - var len uint = startPosQueueSize(self) - var i uint - var q []posData = self.q_[:] - q[offset] = *posdata - - /* Restore the sorted order. In the list of |len| items at most |len - 1| - adjacent element comparisons / swaps are required. */ - for i = 1; i < len; i++ { - if q[offset&7].costdiff > q[(offset+1)&7].costdiff { - var tmp posData = q[offset&7] - q[offset&7] = q[(offset+1)&7] - q[(offset+1)&7] = tmp - } - - offset++ - } -} - -func startPosQueueAt(self *startPosQueue, k uint) *posData { - return &self.q_[(k-self.idx_)&7] -} - -/* Returns the minimum possible copy length that can improve the cost of any */ -/* future position. */ -func computeMinimumCopyLength(start_cost float32, nodes []zopfliNode, num_bytes uint, pos uint) uint { - var min_cost float32 = start_cost - var len uint = 2 - var next_len_bucket uint = 4 - /* Compute the minimum possible cost of reaching any future position. */ - - var next_len_offset uint = 10 - for pos+len <= num_bytes && nodes[pos+len].u.cost <= min_cost { - /* We already reached (pos + len) with no more cost than the minimum - possible cost of reaching anything from this pos, so there is no point in - looking for lengths <= len. */ - len++ - - if len == next_len_offset { - /* We reached the next copy length code bucket, so we add one more - extra bit to the minimum cost. */ - min_cost += 1.0 - - next_len_offset += next_len_bucket - next_len_bucket *= 2 - } - } - - return uint(len) -} - -/* REQUIRES: nodes[pos].cost < kInfinity - REQUIRES: nodes[0..pos] satisfies that "ZopfliNode array invariant". */ -func computeDistanceShortcut(block_start uint, pos uint, max_backward_limit uint, gap uint, nodes []zopfliNode) uint32 { - var clen uint = uint(zopfliNodeCopyLength(&nodes[pos])) - var ilen uint = uint(nodes[pos].dcode_insert_length & 0x7FFFFFF) - var dist uint = uint(zopfliNodeCopyDistance(&nodes[pos])) - - /* Since |block_start + pos| is the end position of the command, the copy part - starts from |block_start + pos - clen|. Distances that are greater than - this or greater than |max_backward_limit| + |gap| are static dictionary - references, and do not update the last distances. - Also distance code 0 (last distance) does not update the last distances. */ - if pos == 0 { - return 0 - } else if dist+clen <= block_start+pos+gap && dist <= max_backward_limit+gap && zopfliNodeDistanceCode(&nodes[pos]) > 0 { - return uint32(pos) - } else { - return nodes[pos-clen-ilen].u.shortcut - } -} - -/* Fills in dist_cache[0..3] with the last four distances (as defined by - Section 4. of the Spec) that would be used at (block_start + pos) if we - used the shortest path of commands from block_start, computed from - nodes[0..pos]. The last four distances at block_start are in - starting_dist_cache[0..3]. - REQUIRES: nodes[pos].cost < kInfinity - REQUIRES: nodes[0..pos] satisfies that "ZopfliNode array invariant". */ -func computeDistanceCache(pos uint, starting_dist_cache []int, nodes []zopfliNode, dist_cache []int) { - var idx int = 0 - var p uint = uint(nodes[pos].u.shortcut) - for idx < 4 && p > 0 { - var ilen uint = uint(nodes[p].dcode_insert_length & 0x7FFFFFF) - var clen uint = uint(zopfliNodeCopyLength(&nodes[p])) - var dist uint = uint(zopfliNodeCopyDistance(&nodes[p])) - dist_cache[idx] = int(dist) - idx++ - - /* Because of prerequisite, p >= clen + ilen >= 2. */ - p = uint(nodes[p-clen-ilen].u.shortcut) - } - - for ; idx < 4; idx++ { - dist_cache[idx] = starting_dist_cache[0] - starting_dist_cache = starting_dist_cache[1:] - } -} - -/* Maintains "ZopfliNode array invariant" and pushes node to the queue, if it - is eligible. */ -func evaluateNode(block_start uint, pos uint, max_backward_limit uint, gap uint, starting_dist_cache []int, model *zopfliCostModel, queue *startPosQueue, nodes []zopfliNode) { - /* Save cost, because ComputeDistanceCache invalidates it. */ - var node_cost float32 = nodes[pos].u.cost - nodes[pos].u.shortcut = computeDistanceShortcut(block_start, pos, max_backward_limit, gap, nodes) - if node_cost <= zopfliCostModelGetLiteralCosts(model, 0, pos) { - var posdata posData - posdata.pos = pos - posdata.cost = node_cost - posdata.costdiff = node_cost - zopfliCostModelGetLiteralCosts(model, 0, pos) - computeDistanceCache(pos, starting_dist_cache, nodes, posdata.distance_cache[:]) - startPosQueuePush(queue, &posdata) - } -} - -/* Returns longest copy length. */ -func updateNodes(num_bytes uint, block_start uint, pos uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, max_backward_limit uint, starting_dist_cache []int, num_matches uint, matches []backwardMatch, model *zopfliCostModel, queue *startPosQueue, nodes []zopfliNode) uint { - var cur_ix uint = block_start + pos - var cur_ix_masked uint = cur_ix & ringbuffer_mask - var max_distance uint = brotli_min_size_t(cur_ix, max_backward_limit) - var max_len uint = num_bytes - pos - var max_zopfli_len uint = maxZopfliLen(params) - var max_iters uint = maxZopfliCandidates(params) - var min_len uint - var result uint = 0 - var k uint - var gap uint = 0 - - evaluateNode(block_start, pos, max_backward_limit, gap, starting_dist_cache, model, queue, nodes) - { - var posdata *posData = startPosQueueAt(queue, 0) - var min_cost float32 = (posdata.cost + zopfliCostModelGetMinCostCmd(model) + zopfliCostModelGetLiteralCosts(model, posdata.pos, pos)) - min_len = computeMinimumCopyLength(min_cost, nodes, num_bytes, pos) - } - - /* Go over the command starting positions in order of increasing cost - difference. */ - for k = 0; k < max_iters && k < startPosQueueSize(queue); k++ { - var posdata *posData = startPosQueueAt(queue, k) - var start uint = posdata.pos - var inscode uint16 = getInsertLengthCode(pos - start) - var start_costdiff float32 = posdata.costdiff - var base_cost float32 = start_costdiff + float32(getInsertExtra(inscode)) + zopfliCostModelGetLiteralCosts(model, 0, pos) - var best_len uint = min_len - 1 - var j uint = 0 - /* Look for last distance matches using the distance cache from this - starting position. */ - for ; j < numDistanceShortCodes && best_len < max_len; j++ { - var idx uint = uint(kDistanceCacheIndex[j]) - var backward uint = uint(posdata.distance_cache[idx] + kDistanceCacheOffset[j]) - var prev_ix uint = cur_ix - backward - var len uint = 0 - var continuation byte = ringbuffer[cur_ix_masked+best_len] - if cur_ix_masked+best_len > ringbuffer_mask { - break - } - - if backward > max_distance+gap { - /* Word dictionary -> ignore. */ - continue - } - - if backward <= max_distance { - /* Regular backward reference. */ - if prev_ix >= cur_ix { - continue - } - - prev_ix &= ringbuffer_mask - if prev_ix+best_len > ringbuffer_mask || continuation != ringbuffer[prev_ix+best_len] { - continue - } - - len = findMatchLengthWithLimit(ringbuffer[prev_ix:], ringbuffer[cur_ix_masked:], max_len) - } else { - continue - } - { - var dist_cost float32 = base_cost + zopfliCostModelGetDistanceCost(model, j) - var l uint - for l = best_len + 1; l <= len; l++ { - var copycode uint16 = getCopyLengthCode(l) - var cmdcode uint16 = combineLengthCodes(inscode, copycode, j == 0) - var tmp float32 - if cmdcode < 128 { - tmp = base_cost - } else { - tmp = dist_cost - } - var cost float32 = tmp + float32(getCopyExtra(copycode)) + zopfliCostModelGetCommandCost(model, cmdcode) - if cost < nodes[pos+l].u.cost { - updateZopfliNode(nodes, pos, start, l, l, backward, j+1, cost) - result = brotli_max_size_t(result, l) - } - - best_len = l - } - } - } - - /* At higher iterations look only for new last distance matches, since - looking only for new command start positions with the same distances - does not help much. */ - if k >= 2 { - continue - } - { - /* Loop through all possible copy lengths at this position. */ - var len uint = min_len - for j = 0; j < num_matches; j++ { - var match backwardMatch = matches[j] - var dist uint = uint(match.distance) - var is_dictionary_match bool = (dist > max_distance+gap) - var dist_code uint = dist + numDistanceShortCodes - 1 - var dist_symbol uint16 - var distextra uint32 - var distnumextra uint32 - var dist_cost float32 - var max_match_len uint - /* We already tried all possible last distance matches, so we can use - normal distance code here. */ - prefixEncodeCopyDistance(dist_code, uint(params.dist.num_direct_distance_codes), uint(params.dist.distance_postfix_bits), &dist_symbol, &distextra) - - distnumextra = uint32(dist_symbol) >> 10 - dist_cost = base_cost + float32(distnumextra) + zopfliCostModelGetDistanceCost(model, uint(dist_symbol)&0x3FF) - - /* Try all copy lengths up until the maximum copy length corresponding - to this distance. If the distance refers to the static dictionary, or - the maximum length is long enough, try only one maximum length. */ - max_match_len = backwardMatchLength(&match) - - if len < max_match_len && (is_dictionary_match || max_match_len > max_zopfli_len) { - len = max_match_len - } - - for ; len <= max_match_len; len++ { - var len_code uint - if is_dictionary_match { - len_code = backwardMatchLengthCode(&match) - } else { - len_code = len - } - var copycode uint16 = getCopyLengthCode(len_code) - var cmdcode uint16 = combineLengthCodes(inscode, copycode, false) - var cost float32 = dist_cost + float32(getCopyExtra(copycode)) + zopfliCostModelGetCommandCost(model, cmdcode) - if cost < nodes[pos+len].u.cost { - updateZopfliNode(nodes, pos, start, uint(len), len_code, dist, 0, cost) - if len > result { - result = len - } - } - } - } - } - } - - return result -} - -func computeShortestPathFromNodes(num_bytes uint, nodes []zopfliNode) uint { - var index uint = num_bytes - var num_commands uint = 0 - for nodes[index].dcode_insert_length&0x7FFFFFF == 0 && nodes[index].length == 1 { - index-- - } - nodes[index].u.next = math.MaxUint32 - for index != 0 { - var len uint = uint(zopfliNodeCommandLength(&nodes[index])) - index -= uint(len) - nodes[index].u.next = uint32(len) - num_commands++ - } - - return num_commands -} - -/* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */ -func zopfliCreateCommands(num_bytes uint, block_start uint, nodes []zopfliNode, dist_cache []int, last_insert_len *uint, params *encoderParams, commands *[]command, num_literals *uint) { - var max_backward_limit uint = maxBackwardLimit(params.lgwin) - var pos uint = 0 - var offset uint32 = nodes[0].u.next - var i uint - var gap uint = 0 - for i = 0; offset != math.MaxUint32; i++ { - var next *zopfliNode = &nodes[uint32(pos)+offset] - var copy_length uint = uint(zopfliNodeCopyLength(next)) - var insert_length uint = uint(next.dcode_insert_length & 0x7FFFFFF) - pos += insert_length - offset = next.u.next - if i == 0 { - insert_length += *last_insert_len - *last_insert_len = 0 - } - { - var distance uint = uint(zopfliNodeCopyDistance(next)) - var len_code uint = uint(zopfliNodeLengthCode(next)) - var max_distance uint = brotli_min_size_t(block_start+pos, max_backward_limit) - var is_dictionary bool = (distance > max_distance+gap) - var dist_code uint = uint(zopfliNodeDistanceCode(next)) - *commands = append(*commands, makeCommand(¶ms.dist, insert_length, copy_length, int(len_code)-int(copy_length), dist_code)) - - if !is_dictionary && dist_code > 0 { - dist_cache[3] = dist_cache[2] - dist_cache[2] = dist_cache[1] - dist_cache[1] = dist_cache[0] - dist_cache[0] = int(distance) - } - } - - *num_literals += insert_length - pos += copy_length - } - - *last_insert_len += num_bytes - pos -} - -func zopfliIterate(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, gap uint, dist_cache []int, model *zopfliCostModel, num_matches []uint32, matches []backwardMatch, nodes []zopfliNode) uint { - var max_backward_limit uint = maxBackwardLimit(params.lgwin) - var max_zopfli_len uint = maxZopfliLen(params) - var queue startPosQueue - var cur_match_pos uint = 0 - var i uint - nodes[0].length = 0 - nodes[0].u.cost = 0 - initStartPosQueue(&queue) - for i = 0; i+3 < num_bytes; i++ { - var skip uint = updateNodes(num_bytes, position, i, ringbuffer, ringbuffer_mask, params, max_backward_limit, dist_cache, uint(num_matches[i]), matches[cur_match_pos:], model, &queue, nodes) - if skip < longCopyQuickStep { - skip = 0 - } - cur_match_pos += uint(num_matches[i]) - if num_matches[i] == 1 && backwardMatchLength(&matches[cur_match_pos-1]) > max_zopfli_len { - skip = brotli_max_size_t(backwardMatchLength(&matches[cur_match_pos-1]), skip) - } - - if skip > 1 { - skip-- - for skip != 0 { - i++ - if i+3 >= num_bytes { - break - } - evaluateNode(position, i, max_backward_limit, gap, dist_cache, model, &queue, nodes) - cur_match_pos += uint(num_matches[i]) - skip-- - } - } - } - - return computeShortestPathFromNodes(num_bytes, nodes) -} - -/* Computes the shortest path of commands from position to at most - position + num_bytes. - - On return, path->size() is the number of commands found and path[i] is the - length of the i-th command (copy length plus insert length). - Note that the sum of the lengths of all commands can be less than num_bytes. - - On return, the nodes[0..num_bytes] array will have the following - "ZopfliNode array invariant": - For each i in [1..num_bytes], if nodes[i].cost < kInfinity, then - (1) nodes[i].copy_length() >= 2 - (2) nodes[i].command_length() <= i and - (3) nodes[i - nodes[i].command_length()].cost < kInfinity - - REQUIRES: nodes != nil and len(nodes) >= num_bytes + 1 */ -func zopfliComputeShortestPath(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, dist_cache []int, hasher *h10, nodes []zopfliNode) uint { - var max_backward_limit uint = maxBackwardLimit(params.lgwin) - var max_zopfli_len uint = maxZopfliLen(params) - var model zopfliCostModel - var queue startPosQueue - var matches [2 * (maxNumMatchesH10 + 64)]backwardMatch - var store_end uint - if num_bytes >= hasher.StoreLookahead() { - store_end = position + num_bytes - hasher.StoreLookahead() + 1 - } else { - store_end = position - } - var i uint - var gap uint = 0 - var lz_matches_offset uint = 0 - nodes[0].length = 0 - nodes[0].u.cost = 0 - initZopfliCostModel(&model, ¶ms.dist, num_bytes) - zopfliCostModelSetFromLiteralCosts(&model, position, ringbuffer, ringbuffer_mask) - initStartPosQueue(&queue) - for i = 0; i+hasher.HashTypeLength()-1 < num_bytes; i++ { - var pos uint = position + i - var max_distance uint = brotli_min_size_t(pos, max_backward_limit) - var skip uint - var num_matches uint - num_matches = findAllMatchesH10(hasher, ¶ms.dictionary, ringbuffer, ringbuffer_mask, pos, num_bytes-i, max_distance, gap, params, matches[lz_matches_offset:]) - if num_matches > 0 && backwardMatchLength(&matches[num_matches-1]) > max_zopfli_len { - matches[0] = matches[num_matches-1] - num_matches = 1 - } - - skip = updateNodes(num_bytes, position, i, ringbuffer, ringbuffer_mask, params, max_backward_limit, dist_cache, num_matches, matches[:], &model, &queue, nodes) - if skip < longCopyQuickStep { - skip = 0 - } - if num_matches == 1 && backwardMatchLength(&matches[0]) > max_zopfli_len { - skip = brotli_max_size_t(backwardMatchLength(&matches[0]), skip) - } - - if skip > 1 { - /* Add the tail of the copy to the hasher. */ - hasher.StoreRange(ringbuffer, ringbuffer_mask, pos+1, brotli_min_size_t(pos+skip, store_end)) - - skip-- - for skip != 0 { - i++ - if i+hasher.HashTypeLength()-1 >= num_bytes { - break - } - evaluateNode(position, i, max_backward_limit, gap, dist_cache, &model, &queue, nodes) - skip-- - } - } - } - - cleanupZopfliCostModel(&model) - return computeShortestPathFromNodes(num_bytes, nodes) -} - -func createZopfliBackwardReferences(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, hasher *h10, dist_cache []int, last_insert_len *uint, commands *[]command, num_literals *uint) { - var nodes []zopfliNode - nodes = make([]zopfliNode, (num_bytes + 1)) - initZopfliNodes(nodes, num_bytes+1) - zopfliComputeShortestPath(num_bytes, position, ringbuffer, ringbuffer_mask, params, dist_cache, hasher, nodes) - zopfliCreateCommands(num_bytes, position, nodes, dist_cache, last_insert_len, params, commands, num_literals) - nodes = nil -} - -func createHqZopfliBackwardReferences(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint, params *encoderParams, hasher hasherHandle, dist_cache []int, last_insert_len *uint, commands *[]command, num_literals *uint) { - var max_backward_limit uint = maxBackwardLimit(params.lgwin) - var num_matches []uint32 = make([]uint32, num_bytes) - var matches_size uint = 4 * num_bytes - var store_end uint - if num_bytes >= hasher.StoreLookahead() { - store_end = position + num_bytes - hasher.StoreLookahead() + 1 - } else { - store_end = position - } - var cur_match_pos uint = 0 - var i uint - var orig_num_literals uint - var orig_last_insert_len uint - var orig_dist_cache [4]int - var orig_num_commands int - var model zopfliCostModel - var nodes []zopfliNode - var matches []backwardMatch = make([]backwardMatch, matches_size) - var gap uint = 0 - var shadow_matches uint = 0 - var new_array []backwardMatch - for i = 0; i+hasher.HashTypeLength()-1 < num_bytes; i++ { - var pos uint = position + i - var max_distance uint = brotli_min_size_t(pos, max_backward_limit) - var max_length uint = num_bytes - i - var num_found_matches uint - var cur_match_end uint - var j uint - - /* Ensure that we have enough free slots. */ - if matches_size < cur_match_pos+maxNumMatchesH10+shadow_matches { - var new_size uint = matches_size - if new_size == 0 { - new_size = cur_match_pos + maxNumMatchesH10 + shadow_matches - } - - for new_size < cur_match_pos+maxNumMatchesH10+shadow_matches { - new_size *= 2 - } - - new_array = make([]backwardMatch, new_size) - if matches_size != 0 { - copy(new_array, matches[:matches_size]) - } - - matches = new_array - matches_size = new_size - } - - num_found_matches = findAllMatchesH10(hasher.(*h10), ¶ms.dictionary, ringbuffer, ringbuffer_mask, pos, max_length, max_distance, gap, params, matches[cur_match_pos+shadow_matches:]) - cur_match_end = cur_match_pos + num_found_matches - for j = cur_match_pos; j+1 < cur_match_end; j++ { - assert(backwardMatchLength(&matches[j]) <= backwardMatchLength(&matches[j+1])) - } - - num_matches[i] = uint32(num_found_matches) - if num_found_matches > 0 { - var match_len uint = backwardMatchLength(&matches[cur_match_end-1]) - if match_len > maxZopfliLenQuality11 { - var skip uint = match_len - 1 - matches[cur_match_pos] = matches[cur_match_end-1] - cur_match_pos++ - num_matches[i] = 1 - - /* Add the tail of the copy to the hasher. */ - hasher.StoreRange(ringbuffer, ringbuffer_mask, pos+1, brotli_min_size_t(pos+match_len, store_end)) - var pos uint = i - for i := 0; i < int(skip); i++ { - num_matches[pos+1:][i] = 0 - } - i += skip - } else { - cur_match_pos = cur_match_end - } - } - } - - orig_num_literals = *num_literals - orig_last_insert_len = *last_insert_len - copy(orig_dist_cache[:], dist_cache[:4]) - orig_num_commands = len(*commands) - nodes = make([]zopfliNode, (num_bytes + 1)) - initZopfliCostModel(&model, ¶ms.dist, num_bytes) - for i = 0; i < 2; i++ { - initZopfliNodes(nodes, num_bytes+1) - if i == 0 { - zopfliCostModelSetFromLiteralCosts(&model, position, ringbuffer, ringbuffer_mask) - } else { - zopfliCostModelSetFromCommands(&model, position, ringbuffer, ringbuffer_mask, (*commands)[orig_num_commands:], orig_last_insert_len) - } - - *commands = (*commands)[:orig_num_commands] - *num_literals = orig_num_literals - *last_insert_len = orig_last_insert_len - copy(dist_cache, orig_dist_cache[:4]) - zopfliIterate(num_bytes, position, ringbuffer, ringbuffer_mask, params, gap, dist_cache, &model, num_matches, matches, nodes) - zopfliCreateCommands(num_bytes, position, nodes, dist_cache, last_insert_len, params, commands, num_literals) - } - - cleanupZopfliCostModel(&model) - nodes = nil - matches = nil - num_matches = nil -} diff --git a/src/vendor/github.com/andybalholm/brotli/bit_cost.go b/src/vendor/github.com/andybalholm/brotli/bit_cost.go deleted file mode 100644 index 0005fc15..00000000 --- a/src/vendor/github.com/andybalholm/brotli/bit_cost.go +++ /dev/null @@ -1,436 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Functions to estimate the bit cost of Huffman trees. */ -func shannonEntropy(population []uint32, size uint, total *uint) float64 { - var sum uint = 0 - var retval float64 = 0 - var population_end []uint32 = population[size:] - var p uint - for -cap(population) < -cap(population_end) { - p = uint(population[0]) - population = population[1:] - sum += p - retval -= float64(p) * fastLog2(p) - } - - if sum != 0 { - retval += float64(sum) * fastLog2(sum) - } - *total = sum - return retval -} - -func bitsEntropy(population []uint32, size uint) float64 { - var sum uint - var retval float64 = shannonEntropy(population, size, &sum) - if retval < float64(sum) { - /* At least one bit per literal is needed. */ - retval = float64(sum) - } - - return retval -} - -const kOneSymbolHistogramCost float64 = 12 -const kTwoSymbolHistogramCost float64 = 20 -const kThreeSymbolHistogramCost float64 = 28 -const kFourSymbolHistogramCost float64 = 37 - -func populationCostLiteral(histogram *histogramLiteral) float64 { - var data_size uint = histogramDataSizeLiteral() - var count int = 0 - var s [5]uint - var bits float64 = 0.0 - var i uint - if histogram.total_count_ == 0 { - return kOneSymbolHistogramCost - } - - for i = 0; i < data_size; i++ { - if histogram.data_[i] > 0 { - s[count] = i - count++ - if count > 4 { - break - } - } - } - - if count == 1 { - return kOneSymbolHistogramCost - } - - if count == 2 { - return kTwoSymbolHistogramCost + float64(histogram.total_count_) - } - - if count == 3 { - var histo0 uint32 = histogram.data_[s[0]] - var histo1 uint32 = histogram.data_[s[1]] - var histo2 uint32 = histogram.data_[s[2]] - var histomax uint32 = brotli_max_uint32_t(histo0, brotli_max_uint32_t(histo1, histo2)) - return kThreeSymbolHistogramCost + 2*(float64(histo0)+float64(histo1)+float64(histo2)) - float64(histomax) - } - - if count == 4 { - var histo [4]uint32 - var h23 uint32 - var histomax uint32 - for i = 0; i < 4; i++ { - histo[i] = histogram.data_[s[i]] - } - - /* Sort */ - for i = 0; i < 4; i++ { - var j uint - for j = i + 1; j < 4; j++ { - if histo[j] > histo[i] { - var tmp uint32 = histo[j] - histo[j] = histo[i] - histo[i] = tmp - } - } - } - - h23 = histo[2] + histo[3] - histomax = brotli_max_uint32_t(h23, histo[0]) - return kFourSymbolHistogramCost + 3*float64(h23) + 2*(float64(histo[0])+float64(histo[1])) - float64(histomax) - } - { - var max_depth uint = 1 - var depth_histo = [codeLengthCodes]uint32{0} - /* In this loop we compute the entropy of the histogram and simultaneously - build a simplified histogram of the code length codes where we use the - zero repeat code 17, but we don't use the non-zero repeat code 16. */ - - var log2total float64 = fastLog2(histogram.total_count_) - for i = 0; i < data_size; { - if histogram.data_[i] > 0 { - var log2p float64 = log2total - fastLog2(uint(histogram.data_[i])) - /* Compute -log2(P(symbol)) = -log2(count(symbol)/total_count) = - = log2(total_count) - log2(count(symbol)) */ - - var depth uint = uint(log2p + 0.5) - /* Approximate the bit depth by round(-log2(P(symbol))) */ - bits += float64(histogram.data_[i]) * log2p - - if depth > 15 { - depth = 15 - } - - if depth > max_depth { - max_depth = depth - } - - depth_histo[depth]++ - i++ - } else { - var reps uint32 = 1 - /* Compute the run length of zeros and add the appropriate number of 0 - and 17 code length codes to the code length code histogram. */ - - var k uint - for k = i + 1; k < data_size && histogram.data_[k] == 0; k++ { - reps++ - } - - i += uint(reps) - if i == data_size { - /* Don't add any cost for the last zero run, since these are encoded - only implicitly. */ - break - } - - if reps < 3 { - depth_histo[0] += reps - } else { - reps -= 2 - for reps > 0 { - depth_histo[repeatZeroCodeLength]++ - - /* Add the 3 extra bits for the 17 code length code. */ - bits += 3 - - reps >>= 3 - } - } - } - } - - /* Add the estimated encoding cost of the code length code histogram. */ - bits += float64(18 + 2*max_depth) - - /* Add the entropy of the code length code histogram. */ - bits += bitsEntropy(depth_histo[:], codeLengthCodes) - } - - return bits -} - -func populationCostCommand(histogram *histogramCommand) float64 { - var data_size uint = histogramDataSizeCommand() - var count int = 0 - var s [5]uint - var bits float64 = 0.0 - var i uint - if histogram.total_count_ == 0 { - return kOneSymbolHistogramCost - } - - for i = 0; i < data_size; i++ { - if histogram.data_[i] > 0 { - s[count] = i - count++ - if count > 4 { - break - } - } - } - - if count == 1 { - return kOneSymbolHistogramCost - } - - if count == 2 { - return kTwoSymbolHistogramCost + float64(histogram.total_count_) - } - - if count == 3 { - var histo0 uint32 = histogram.data_[s[0]] - var histo1 uint32 = histogram.data_[s[1]] - var histo2 uint32 = histogram.data_[s[2]] - var histomax uint32 = brotli_max_uint32_t(histo0, brotli_max_uint32_t(histo1, histo2)) - return kThreeSymbolHistogramCost + 2*(float64(histo0)+float64(histo1)+float64(histo2)) - float64(histomax) - } - - if count == 4 { - var histo [4]uint32 - var h23 uint32 - var histomax uint32 - for i = 0; i < 4; i++ { - histo[i] = histogram.data_[s[i]] - } - - /* Sort */ - for i = 0; i < 4; i++ { - var j uint - for j = i + 1; j < 4; j++ { - if histo[j] > histo[i] { - var tmp uint32 = histo[j] - histo[j] = histo[i] - histo[i] = tmp - } - } - } - - h23 = histo[2] + histo[3] - histomax = brotli_max_uint32_t(h23, histo[0]) - return kFourSymbolHistogramCost + 3*float64(h23) + 2*(float64(histo[0])+float64(histo[1])) - float64(histomax) - } - { - var max_depth uint = 1 - var depth_histo = [codeLengthCodes]uint32{0} - /* In this loop we compute the entropy of the histogram and simultaneously - build a simplified histogram of the code length codes where we use the - zero repeat code 17, but we don't use the non-zero repeat code 16. */ - - var log2total float64 = fastLog2(histogram.total_count_) - for i = 0; i < data_size; { - if histogram.data_[i] > 0 { - var log2p float64 = log2total - fastLog2(uint(histogram.data_[i])) - /* Compute -log2(P(symbol)) = -log2(count(symbol)/total_count) = - = log2(total_count) - log2(count(symbol)) */ - - var depth uint = uint(log2p + 0.5) - /* Approximate the bit depth by round(-log2(P(symbol))) */ - bits += float64(histogram.data_[i]) * log2p - - if depth > 15 { - depth = 15 - } - - if depth > max_depth { - max_depth = depth - } - - depth_histo[depth]++ - i++ - } else { - var reps uint32 = 1 - /* Compute the run length of zeros and add the appropriate number of 0 - and 17 code length codes to the code length code histogram. */ - - var k uint - for k = i + 1; k < data_size && histogram.data_[k] == 0; k++ { - reps++ - } - - i += uint(reps) - if i == data_size { - /* Don't add any cost for the last zero run, since these are encoded - only implicitly. */ - break - } - - if reps < 3 { - depth_histo[0] += reps - } else { - reps -= 2 - for reps > 0 { - depth_histo[repeatZeroCodeLength]++ - - /* Add the 3 extra bits for the 17 code length code. */ - bits += 3 - - reps >>= 3 - } - } - } - } - - /* Add the estimated encoding cost of the code length code histogram. */ - bits += float64(18 + 2*max_depth) - - /* Add the entropy of the code length code histogram. */ - bits += bitsEntropy(depth_histo[:], codeLengthCodes) - } - - return bits -} - -func populationCostDistance(histogram *histogramDistance) float64 { - var data_size uint = histogramDataSizeDistance() - var count int = 0 - var s [5]uint - var bits float64 = 0.0 - var i uint - if histogram.total_count_ == 0 { - return kOneSymbolHistogramCost - } - - for i = 0; i < data_size; i++ { - if histogram.data_[i] > 0 { - s[count] = i - count++ - if count > 4 { - break - } - } - } - - if count == 1 { - return kOneSymbolHistogramCost - } - - if count == 2 { - return kTwoSymbolHistogramCost + float64(histogram.total_count_) - } - - if count == 3 { - var histo0 uint32 = histogram.data_[s[0]] - var histo1 uint32 = histogram.data_[s[1]] - var histo2 uint32 = histogram.data_[s[2]] - var histomax uint32 = brotli_max_uint32_t(histo0, brotli_max_uint32_t(histo1, histo2)) - return kThreeSymbolHistogramCost + 2*(float64(histo0)+float64(histo1)+float64(histo2)) - float64(histomax) - } - - if count == 4 { - var histo [4]uint32 - var h23 uint32 - var histomax uint32 - for i = 0; i < 4; i++ { - histo[i] = histogram.data_[s[i]] - } - - /* Sort */ - for i = 0; i < 4; i++ { - var j uint - for j = i + 1; j < 4; j++ { - if histo[j] > histo[i] { - var tmp uint32 = histo[j] - histo[j] = histo[i] - histo[i] = tmp - } - } - } - - h23 = histo[2] + histo[3] - histomax = brotli_max_uint32_t(h23, histo[0]) - return kFourSymbolHistogramCost + 3*float64(h23) + 2*(float64(histo[0])+float64(histo[1])) - float64(histomax) - } - { - var max_depth uint = 1 - var depth_histo = [codeLengthCodes]uint32{0} - /* In this loop we compute the entropy of the histogram and simultaneously - build a simplified histogram of the code length codes where we use the - zero repeat code 17, but we don't use the non-zero repeat code 16. */ - - var log2total float64 = fastLog2(histogram.total_count_) - for i = 0; i < data_size; { - if histogram.data_[i] > 0 { - var log2p float64 = log2total - fastLog2(uint(histogram.data_[i])) - /* Compute -log2(P(symbol)) = -log2(count(symbol)/total_count) = - = log2(total_count) - log2(count(symbol)) */ - - var depth uint = uint(log2p + 0.5) - /* Approximate the bit depth by round(-log2(P(symbol))) */ - bits += float64(histogram.data_[i]) * log2p - - if depth > 15 { - depth = 15 - } - - if depth > max_depth { - max_depth = depth - } - - depth_histo[depth]++ - i++ - } else { - var reps uint32 = 1 - /* Compute the run length of zeros and add the appropriate number of 0 - and 17 code length codes to the code length code histogram. */ - - var k uint - for k = i + 1; k < data_size && histogram.data_[k] == 0; k++ { - reps++ - } - - i += uint(reps) - if i == data_size { - /* Don't add any cost for the last zero run, since these are encoded - only implicitly. */ - break - } - - if reps < 3 { - depth_histo[0] += reps - } else { - reps -= 2 - for reps > 0 { - depth_histo[repeatZeroCodeLength]++ - - /* Add the 3 extra bits for the 17 code length code. */ - bits += 3 - - reps >>= 3 - } - } - } - } - - /* Add the estimated encoding cost of the code length code histogram. */ - bits += float64(18 + 2*max_depth) - - /* Add the entropy of the code length code histogram. */ - bits += bitsEntropy(depth_histo[:], codeLengthCodes) - } - - return bits -} diff --git a/src/vendor/github.com/andybalholm/brotli/bit_reader.go b/src/vendor/github.com/andybalholm/brotli/bit_reader.go deleted file mode 100644 index fba8687c..00000000 --- a/src/vendor/github.com/andybalholm/brotli/bit_reader.go +++ /dev/null @@ -1,266 +0,0 @@ -package brotli - -import "encoding/binary" - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Bit reading helpers */ - -const shortFillBitWindowRead = (8 >> 1) - -var kBitMask = [33]uint32{ - 0x00000000, - 0x00000001, - 0x00000003, - 0x00000007, - 0x0000000F, - 0x0000001F, - 0x0000003F, - 0x0000007F, - 0x000000FF, - 0x000001FF, - 0x000003FF, - 0x000007FF, - 0x00000FFF, - 0x00001FFF, - 0x00003FFF, - 0x00007FFF, - 0x0000FFFF, - 0x0001FFFF, - 0x0003FFFF, - 0x0007FFFF, - 0x000FFFFF, - 0x001FFFFF, - 0x003FFFFF, - 0x007FFFFF, - 0x00FFFFFF, - 0x01FFFFFF, - 0x03FFFFFF, - 0x07FFFFFF, - 0x0FFFFFFF, - 0x1FFFFFFF, - 0x3FFFFFFF, - 0x7FFFFFFF, - 0xFFFFFFFF, -} - -func bitMask(n uint32) uint32 { - return kBitMask[n] -} - -type bitReader struct { - val_ uint64 - bit_pos_ uint32 - input []byte - input_len uint - byte_pos uint -} - -type bitReaderState struct { - val_ uint64 - bit_pos_ uint32 - input []byte - input_len uint - byte_pos uint -} - -/* Initializes the BrotliBitReader fields. */ - -/* Ensures that accumulator is not empty. - May consume up to sizeof(brotli_reg_t) - 1 bytes of input. - Returns false if data is required but there is no input available. - For BROTLI_ALIGNED_READ this function also prepares bit reader for aligned - reading. */ -func bitReaderSaveState(from *bitReader, to *bitReaderState) { - to.val_ = from.val_ - to.bit_pos_ = from.bit_pos_ - to.input = from.input - to.input_len = from.input_len - to.byte_pos = from.byte_pos -} - -func bitReaderRestoreState(to *bitReader, from *bitReaderState) { - to.val_ = from.val_ - to.bit_pos_ = from.bit_pos_ - to.input = from.input - to.input_len = from.input_len - to.byte_pos = from.byte_pos -} - -func getAvailableBits(br *bitReader) uint32 { - return 64 - br.bit_pos_ -} - -/* Returns amount of unread bytes the bit reader still has buffered from the - BrotliInput, including whole bytes in br->val_. */ -func getRemainingBytes(br *bitReader) uint { - return uint(uint32(br.input_len-br.byte_pos) + (getAvailableBits(br) >> 3)) -} - -/* Checks if there is at least |num| bytes left in the input ring-buffer - (excluding the bits remaining in br->val_). */ -func checkInputAmount(br *bitReader, num uint) bool { - return br.input_len-br.byte_pos >= num -} - -/* Guarantees that there are at least |n_bits| + 1 bits in accumulator. - Precondition: accumulator contains at least 1 bit. - |n_bits| should be in the range [1..24] for regular build. For portable - non-64-bit little-endian build only 16 bits are safe to request. */ -func fillBitWindow(br *bitReader, n_bits uint32) { - if br.bit_pos_ >= 32 { - br.val_ >>= 32 - br.bit_pos_ ^= 32 /* here same as -= 32 because of the if condition */ - br.val_ |= (uint64(binary.LittleEndian.Uint32(br.input[br.byte_pos:]))) << 32 - br.byte_pos += 4 - } -} - -/* Mostly like BrotliFillBitWindow, but guarantees only 16 bits and reads no - more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input. */ -func fillBitWindow16(br *bitReader) { - fillBitWindow(br, 17) -} - -/* Tries to pull one byte of input to accumulator. - Returns false if there is no input available. */ -func pullByte(br *bitReader) bool { - if br.byte_pos == br.input_len { - return false - } - - br.val_ >>= 8 - br.val_ |= (uint64(br.input[br.byte_pos])) << 56 - br.bit_pos_ -= 8 - br.byte_pos++ - return true -} - -/* Returns currently available bits. - The number of valid bits could be calculated by BrotliGetAvailableBits. */ -func getBitsUnmasked(br *bitReader) uint64 { - return br.val_ >> br.bit_pos_ -} - -/* Like BrotliGetBits, but does not mask the result. - The result contains at least 16 valid bits. */ -func get16BitsUnmasked(br *bitReader) uint32 { - fillBitWindow(br, 16) - return uint32(getBitsUnmasked(br)) -} - -/* Returns the specified number of bits from |br| without advancing bit - position. */ -func getBits(br *bitReader, n_bits uint32) uint32 { - fillBitWindow(br, n_bits) - return uint32(getBitsUnmasked(br)) & bitMask(n_bits) -} - -/* Tries to peek the specified amount of bits. Returns false, if there - is not enough input. */ -func safeGetBits(br *bitReader, n_bits uint32, val *uint32) bool { - for getAvailableBits(br) < n_bits { - if !pullByte(br) { - return false - } - } - - *val = uint32(getBitsUnmasked(br)) & bitMask(n_bits) - return true -} - -/* Advances the bit pos by |n_bits|. */ -func dropBits(br *bitReader, n_bits uint32) { - br.bit_pos_ += n_bits -} - -func bitReaderUnload(br *bitReader) { - var unused_bytes uint32 = getAvailableBits(br) >> 3 - var unused_bits uint32 = unused_bytes << 3 - br.byte_pos -= uint(unused_bytes) - if unused_bits == 64 { - br.val_ = 0 - } else { - br.val_ <<= unused_bits - } - - br.bit_pos_ += unused_bits -} - -/* Reads the specified number of bits from |br| and advances the bit pos. - Precondition: accumulator MUST contain at least |n_bits|. */ -func takeBits(br *bitReader, n_bits uint32, val *uint32) { - *val = uint32(getBitsUnmasked(br)) & bitMask(n_bits) - dropBits(br, n_bits) -} - -/* Reads the specified number of bits from |br| and advances the bit pos. - Assumes that there is enough input to perform BrotliFillBitWindow. */ -func readBits(br *bitReader, n_bits uint32) uint32 { - var val uint32 - fillBitWindow(br, n_bits) - takeBits(br, n_bits, &val) - return val -} - -/* Tries to read the specified amount of bits. Returns false, if there - is not enough input. |n_bits| MUST be positive. */ -func safeReadBits(br *bitReader, n_bits uint32, val *uint32) bool { - for getAvailableBits(br) < n_bits { - if !pullByte(br) { - return false - } - } - - takeBits(br, n_bits, val) - return true -} - -/* Advances the bit reader position to the next byte boundary and verifies - that any skipped bits are set to zero. */ -func bitReaderJumpToByteBoundary(br *bitReader) bool { - var pad_bits_count uint32 = getAvailableBits(br) & 0x7 - var pad_bits uint32 = 0 - if pad_bits_count != 0 { - takeBits(br, pad_bits_count, &pad_bits) - } - - return pad_bits == 0 -} - -/* Copies remaining input bytes stored in the bit reader to the output. Value - |num| may not be larger than BrotliGetRemainingBytes. The bit reader must be - warmed up again after this. */ -func copyBytes(dest []byte, br *bitReader, num uint) { - for getAvailableBits(br) >= 8 && num > 0 { - dest[0] = byte(getBitsUnmasked(br)) - dropBits(br, 8) - dest = dest[1:] - num-- - } - - copy(dest, br.input[br.byte_pos:][:num]) - br.byte_pos += num -} - -func initBitReader(br *bitReader) { - br.val_ = 0 - br.bit_pos_ = 64 -} - -func warmupBitReader(br *bitReader) bool { - /* Fixing alignment after unaligned BrotliFillWindow would result accumulator - overflow. If unalignment is caused by BrotliSafeReadBits, then there is - enough space in accumulator to fix alignment. */ - if getAvailableBits(br) == 0 { - if !pullByte(br) { - return false - } - } - - return true -} diff --git a/src/vendor/github.com/andybalholm/brotli/bitwriter.go b/src/vendor/github.com/andybalholm/brotli/bitwriter.go deleted file mode 100644 index dfc60360..00000000 --- a/src/vendor/github.com/andybalholm/brotli/bitwriter.go +++ /dev/null @@ -1,56 +0,0 @@ -package brotli - -/* Copyright 2010 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Write bits into a byte array. */ - -type bitWriter struct { - dst []byte - - // Data waiting to be written is the low nbits of bits. - bits uint64 - nbits uint -} - -func (w *bitWriter) writeBits(nb uint, b uint64) { - w.bits |= b << w.nbits - w.nbits += nb - if w.nbits >= 32 { - bits := w.bits - w.bits >>= 32 - w.nbits -= 32 - w.dst = append(w.dst, - byte(bits), - byte(bits>>8), - byte(bits>>16), - byte(bits>>24), - ) - } -} - -func (w *bitWriter) writeSingleBit(bit bool) { - if bit { - w.writeBits(1, 1) - } else { - w.writeBits(1, 0) - } -} - -func (w *bitWriter) jumpToByteBoundary() { - dst := w.dst - for w.nbits != 0 { - dst = append(dst, byte(w.bits)) - w.bits >>= 8 - if w.nbits > 8 { // Avoid underflow - w.nbits -= 8 - } else { - w.nbits = 0 - } - } - w.bits = 0 - w.dst = dst -} diff --git a/src/vendor/github.com/andybalholm/brotli/block_splitter.go b/src/vendor/github.com/andybalholm/brotli/block_splitter.go deleted file mode 100644 index 978a1314..00000000 --- a/src/vendor/github.com/andybalholm/brotli/block_splitter.go +++ /dev/null @@ -1,144 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Block split point selection utilities. */ - -type blockSplit struct { - num_types uint - num_blocks uint - types []byte - lengths []uint32 - types_alloc_size uint - lengths_alloc_size uint -} - -const ( - kMaxLiteralHistograms uint = 100 - kMaxCommandHistograms uint = 50 - kLiteralBlockSwitchCost float64 = 28.1 - kCommandBlockSwitchCost float64 = 13.5 - kDistanceBlockSwitchCost float64 = 14.6 - kLiteralStrideLength uint = 70 - kCommandStrideLength uint = 40 - kSymbolsPerLiteralHistogram uint = 544 - kSymbolsPerCommandHistogram uint = 530 - kSymbolsPerDistanceHistogram uint = 544 - kMinLengthForBlockSplitting uint = 128 - kIterMulForRefining uint = 2 - kMinItersForRefining uint = 100 -) - -func countLiterals(cmds []command) uint { - var total_length uint = 0 - /* Count how many we have. */ - - for i := range cmds { - total_length += uint(cmds[i].insert_len_) - } - - return total_length -} - -func copyLiteralsToByteArray(cmds []command, data []byte, offset uint, mask uint, literals []byte) { - var pos uint = 0 - var from_pos uint = offset & mask - for i := range cmds { - var insert_len uint = uint(cmds[i].insert_len_) - if from_pos+insert_len > mask { - var head_size uint = mask + 1 - from_pos - copy(literals[pos:], data[from_pos:][:head_size]) - from_pos = 0 - pos += head_size - insert_len -= head_size - } - - if insert_len > 0 { - copy(literals[pos:], data[from_pos:][:insert_len]) - pos += insert_len - } - - from_pos = uint((uint32(from_pos+insert_len) + commandCopyLen(&cmds[i])) & uint32(mask)) - } -} - -func myRand(seed *uint32) uint32 { - /* Initial seed should be 7. In this case, loop length is (1 << 29). */ - *seed *= 16807 - - return *seed -} - -func bitCost(count uint) float64 { - if count == 0 { - return -2.0 - } else { - return fastLog2(count) - } -} - -const histogramsPerBatch = 64 - -const clustersPerBatch = 16 - -func initBlockSplit(self *blockSplit) { - self.num_types = 0 - self.num_blocks = 0 - self.types = self.types[:0] - self.lengths = self.lengths[:0] - self.types_alloc_size = 0 - self.lengths_alloc_size = 0 -} - -func splitBlock(cmds []command, data []byte, pos uint, mask uint, params *encoderParams, literal_split *blockSplit, insert_and_copy_split *blockSplit, dist_split *blockSplit) { - { - var literals_count uint = countLiterals(cmds) - var literals []byte = make([]byte, literals_count) - - /* Create a continuous array of literals. */ - copyLiteralsToByteArray(cmds, data, pos, mask, literals) - - /* Create the block split on the array of literals. - Literal histograms have alphabet size 256. */ - splitByteVectorLiteral(literals, literals_count, kSymbolsPerLiteralHistogram, kMaxLiteralHistograms, kLiteralStrideLength, kLiteralBlockSwitchCost, params, literal_split) - - literals = nil - } - { - var insert_and_copy_codes []uint16 = make([]uint16, len(cmds)) - /* Compute prefix codes for commands. */ - - for i := range cmds { - insert_and_copy_codes[i] = cmds[i].cmd_prefix_ - } - - /* Create the block split on the array of command prefixes. */ - splitByteVectorCommand(insert_and_copy_codes, kSymbolsPerCommandHistogram, kMaxCommandHistograms, kCommandStrideLength, kCommandBlockSwitchCost, params, insert_and_copy_split) - - /* TODO: reuse for distances? */ - - insert_and_copy_codes = nil - } - { - var distance_prefixes []uint16 = make([]uint16, len(cmds)) - var j uint = 0 - /* Create a continuous array of distance prefixes. */ - - for i := range cmds { - var cmd *command = &cmds[i] - if commandCopyLen(cmd) != 0 && cmd.cmd_prefix_ >= 128 { - distance_prefixes[j] = cmd.dist_prefix_ & 0x3FF - j++ - } - } - - /* Create the block split on the array of distance prefixes. */ - splitByteVectorDistance(distance_prefixes, j, kSymbolsPerDistanceHistogram, kMaxCommandHistograms, kCommandStrideLength, kDistanceBlockSwitchCost, params, dist_split) - - distance_prefixes = nil - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/block_splitter_command.go b/src/vendor/github.com/andybalholm/brotli/block_splitter_command.go deleted file mode 100644 index 9dec13e4..00000000 --- a/src/vendor/github.com/andybalholm/brotli/block_splitter_command.go +++ /dev/null @@ -1,434 +0,0 @@ -package brotli - -import "math" - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -func initialEntropyCodesCommand(data []uint16, length uint, stride uint, num_histograms uint, histograms []histogramCommand) { - var seed uint32 = 7 - var block_length uint = length / num_histograms - var i uint - clearHistogramsCommand(histograms, num_histograms) - for i = 0; i < num_histograms; i++ { - var pos uint = length * i / num_histograms - if i != 0 { - pos += uint(myRand(&seed) % uint32(block_length)) - } - - if pos+stride >= length { - pos = length - stride - 1 - } - - histogramAddVectorCommand(&histograms[i], data[pos:], stride) - } -} - -func randomSampleCommand(seed *uint32, data []uint16, length uint, stride uint, sample *histogramCommand) { - var pos uint = 0 - if stride >= length { - stride = length - } else { - pos = uint(myRand(seed) % uint32(length-stride+1)) - } - - histogramAddVectorCommand(sample, data[pos:], stride) -} - -func refineEntropyCodesCommand(data []uint16, length uint, stride uint, num_histograms uint, histograms []histogramCommand) { - var iters uint = kIterMulForRefining*length/stride + kMinItersForRefining - var seed uint32 = 7 - var iter uint - iters = ((iters + num_histograms - 1) / num_histograms) * num_histograms - for iter = 0; iter < iters; iter++ { - var sample histogramCommand - histogramClearCommand(&sample) - randomSampleCommand(&seed, data, length, stride, &sample) - histogramAddHistogramCommand(&histograms[iter%num_histograms], &sample) - } -} - -/* Assigns a block id from the range [0, num_histograms) to each data element - in data[0..length) and fills in block_id[0..length) with the assigned values. - Returns the number of blocks, i.e. one plus the number of block switches. */ -func findBlocksCommand(data []uint16, length uint, block_switch_bitcost float64, num_histograms uint, histograms []histogramCommand, insert_cost []float64, cost []float64, switch_signal []byte, block_id []byte) uint { - var data_size uint = histogramDataSizeCommand() - var bitmaplen uint = (num_histograms + 7) >> 3 - var num_blocks uint = 1 - var i uint - var j uint - assert(num_histograms <= 256) - if num_histograms <= 1 { - for i = 0; i < length; i++ { - block_id[i] = 0 - } - - return 1 - } - - for i := 0; i < int(data_size*num_histograms); i++ { - insert_cost[i] = 0 - } - for i = 0; i < num_histograms; i++ { - insert_cost[i] = fastLog2(uint(uint32(histograms[i].total_count_))) - } - - for i = data_size; i != 0; { - i-- - for j = 0; j < num_histograms; j++ { - insert_cost[i*num_histograms+j] = insert_cost[j] - bitCost(uint(histograms[j].data_[i])) - } - } - - for i := 0; i < int(num_histograms); i++ { - cost[i] = 0 - } - for i := 0; i < int(length*bitmaplen); i++ { - switch_signal[i] = 0 - } - - /* After each iteration of this loop, cost[k] will contain the difference - between the minimum cost of arriving at the current byte position using - entropy code k, and the minimum cost of arriving at the current byte - position. This difference is capped at the block switch cost, and if it - reaches block switch cost, it means that when we trace back from the last - position, we need to switch here. */ - for i = 0; i < length; i++ { - var byte_ix uint = i - var ix uint = byte_ix * bitmaplen - var insert_cost_ix uint = uint(data[byte_ix]) * num_histograms - var min_cost float64 = 1e99 - var block_switch_cost float64 = block_switch_bitcost - var k uint - for k = 0; k < num_histograms; k++ { - /* We are coding the symbol in data[byte_ix] with entropy code k. */ - cost[k] += insert_cost[insert_cost_ix+k] - - if cost[k] < min_cost { - min_cost = cost[k] - block_id[byte_ix] = byte(k) - } - } - - /* More blocks for the beginning. */ - if byte_ix < 2000 { - block_switch_cost *= 0.77 + 0.07*float64(byte_ix)/2000 - } - - for k = 0; k < num_histograms; k++ { - cost[k] -= min_cost - if cost[k] >= block_switch_cost { - var mask byte = byte(1 << (k & 7)) - cost[k] = block_switch_cost - assert(k>>3 < bitmaplen) - switch_signal[ix+(k>>3)] |= mask - /* Trace back from the last position and switch at the marked places. */ - } - } - } - { - var byte_ix uint = length - 1 - var ix uint = byte_ix * bitmaplen - var cur_id byte = block_id[byte_ix] - for byte_ix > 0 { - var mask byte = byte(1 << (cur_id & 7)) - assert(uint(cur_id)>>3 < bitmaplen) - byte_ix-- - ix -= bitmaplen - if switch_signal[ix+uint(cur_id>>3)]&mask != 0 { - if cur_id != block_id[byte_ix] { - cur_id = block_id[byte_ix] - num_blocks++ - } - } - - block_id[byte_ix] = cur_id - } - } - - return num_blocks -} - -var remapBlockIdsCommand_kInvalidId uint16 = 256 - -func remapBlockIdsCommand(block_ids []byte, length uint, new_id []uint16, num_histograms uint) uint { - var next_id uint16 = 0 - var i uint - for i = 0; i < num_histograms; i++ { - new_id[i] = remapBlockIdsCommand_kInvalidId - } - - for i = 0; i < length; i++ { - assert(uint(block_ids[i]) < num_histograms) - if new_id[block_ids[i]] == remapBlockIdsCommand_kInvalidId { - new_id[block_ids[i]] = next_id - next_id++ - } - } - - for i = 0; i < length; i++ { - block_ids[i] = byte(new_id[block_ids[i]]) - assert(uint(block_ids[i]) < num_histograms) - } - - assert(uint(next_id) <= num_histograms) - return uint(next_id) -} - -func buildBlockHistogramsCommand(data []uint16, length uint, block_ids []byte, num_histograms uint, histograms []histogramCommand) { - var i uint - clearHistogramsCommand(histograms, num_histograms) - for i = 0; i < length; i++ { - histogramAddCommand(&histograms[block_ids[i]], uint(data[i])) - } -} - -var clusterBlocksCommand_kInvalidIndex uint32 = math.MaxUint32 - -func clusterBlocksCommand(data []uint16, length uint, num_blocks uint, block_ids []byte, split *blockSplit) { - var histogram_symbols []uint32 = make([]uint32, num_blocks) - var block_lengths []uint32 = make([]uint32, num_blocks) - var expected_num_clusters uint = clustersPerBatch * (num_blocks + histogramsPerBatch - 1) / histogramsPerBatch - var all_histograms_size uint = 0 - var all_histograms_capacity uint = expected_num_clusters - var all_histograms []histogramCommand = make([]histogramCommand, all_histograms_capacity) - var cluster_size_size uint = 0 - var cluster_size_capacity uint = expected_num_clusters - var cluster_size []uint32 = make([]uint32, cluster_size_capacity) - var num_clusters uint = 0 - var histograms []histogramCommand = make([]histogramCommand, brotli_min_size_t(num_blocks, histogramsPerBatch)) - var max_num_pairs uint = histogramsPerBatch * histogramsPerBatch / 2 - var pairs_capacity uint = max_num_pairs + 1 - var pairs []histogramPair = make([]histogramPair, pairs_capacity) - var pos uint = 0 - var clusters []uint32 - var num_final_clusters uint - var new_index []uint32 - var i uint - var sizes = [histogramsPerBatch]uint32{0} - var new_clusters = [histogramsPerBatch]uint32{0} - var symbols = [histogramsPerBatch]uint32{0} - var remap = [histogramsPerBatch]uint32{0} - - for i := 0; i < int(num_blocks); i++ { - block_lengths[i] = 0 - } - { - var block_idx uint = 0 - for i = 0; i < length; i++ { - assert(block_idx < num_blocks) - block_lengths[block_idx]++ - if i+1 == length || block_ids[i] != block_ids[i+1] { - block_idx++ - } - } - - assert(block_idx == num_blocks) - } - - for i = 0; i < num_blocks; i += histogramsPerBatch { - var num_to_combine uint = brotli_min_size_t(num_blocks-i, histogramsPerBatch) - var num_new_clusters uint - var j uint - for j = 0; j < num_to_combine; j++ { - var k uint - histogramClearCommand(&histograms[j]) - for k = 0; uint32(k) < block_lengths[i+j]; k++ { - histogramAddCommand(&histograms[j], uint(data[pos])) - pos++ - } - - histograms[j].bit_cost_ = populationCostCommand(&histograms[j]) - new_clusters[j] = uint32(j) - symbols[j] = uint32(j) - sizes[j] = 1 - } - - num_new_clusters = histogramCombineCommand(histograms, sizes[:], symbols[:], new_clusters[:], []histogramPair(pairs), num_to_combine, num_to_combine, histogramsPerBatch, max_num_pairs) - if all_histograms_capacity < (all_histograms_size + num_new_clusters) { - var _new_size uint - if all_histograms_capacity == 0 { - _new_size = all_histograms_size + num_new_clusters - } else { - _new_size = all_histograms_capacity - } - var new_array []histogramCommand - for _new_size < (all_histograms_size + num_new_clusters) { - _new_size *= 2 - } - new_array = make([]histogramCommand, _new_size) - if all_histograms_capacity != 0 { - copy(new_array, all_histograms[:all_histograms_capacity]) - } - - all_histograms = new_array - all_histograms_capacity = _new_size - } - - brotli_ensure_capacity_uint32_t(&cluster_size, &cluster_size_capacity, cluster_size_size+num_new_clusters) - for j = 0; j < num_new_clusters; j++ { - all_histograms[all_histograms_size] = histograms[new_clusters[j]] - all_histograms_size++ - cluster_size[cluster_size_size] = sizes[new_clusters[j]] - cluster_size_size++ - remap[new_clusters[j]] = uint32(j) - } - - for j = 0; j < num_to_combine; j++ { - histogram_symbols[i+j] = uint32(num_clusters) + remap[symbols[j]] - } - - num_clusters += num_new_clusters - assert(num_clusters == cluster_size_size) - assert(num_clusters == all_histograms_size) - } - - histograms = nil - - max_num_pairs = brotli_min_size_t(64*num_clusters, (num_clusters/2)*num_clusters) - if pairs_capacity < max_num_pairs+1 { - pairs = nil - pairs = make([]histogramPair, (max_num_pairs + 1)) - } - - clusters = make([]uint32, num_clusters) - for i = 0; i < num_clusters; i++ { - clusters[i] = uint32(i) - } - - num_final_clusters = histogramCombineCommand(all_histograms, cluster_size, histogram_symbols, clusters, pairs, num_clusters, num_blocks, maxNumberOfBlockTypes, max_num_pairs) - pairs = nil - cluster_size = nil - - new_index = make([]uint32, num_clusters) - for i = 0; i < num_clusters; i++ { - new_index[i] = clusterBlocksCommand_kInvalidIndex - } - pos = 0 - { - var next_index uint32 = 0 - for i = 0; i < num_blocks; i++ { - var histo histogramCommand - var j uint - var best_out uint32 - var best_bits float64 - histogramClearCommand(&histo) - for j = 0; uint32(j) < block_lengths[i]; j++ { - histogramAddCommand(&histo, uint(data[pos])) - pos++ - } - - if i == 0 { - best_out = histogram_symbols[0] - } else { - best_out = histogram_symbols[i-1] - } - best_bits = histogramBitCostDistanceCommand(&histo, &all_histograms[best_out]) - for j = 0; j < num_final_clusters; j++ { - var cur_bits float64 = histogramBitCostDistanceCommand(&histo, &all_histograms[clusters[j]]) - if cur_bits < best_bits { - best_bits = cur_bits - best_out = clusters[j] - } - } - - histogram_symbols[i] = best_out - if new_index[best_out] == clusterBlocksCommand_kInvalidIndex { - new_index[best_out] = next_index - next_index++ - } - } - } - - clusters = nil - all_histograms = nil - brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, num_blocks) - brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, num_blocks) - { - var cur_length uint32 = 0 - var block_idx uint = 0 - var max_type byte = 0 - for i = 0; i < num_blocks; i++ { - cur_length += block_lengths[i] - if i+1 == num_blocks || histogram_symbols[i] != histogram_symbols[i+1] { - var id byte = byte(new_index[histogram_symbols[i]]) - split.types[block_idx] = id - split.lengths[block_idx] = cur_length - max_type = brotli_max_uint8_t(max_type, id) - cur_length = 0 - block_idx++ - } - } - - split.num_blocks = block_idx - split.num_types = uint(max_type) + 1 - } - - new_index = nil - block_lengths = nil - histogram_symbols = nil -} - -func splitByteVectorCommand(data []uint16, literals_per_histogram uint, max_histograms uint, sampling_stride_length uint, block_switch_cost float64, params *encoderParams, split *blockSplit) { - length := uint(len(data)) - var data_size uint = histogramDataSizeCommand() - var num_histograms uint = length/literals_per_histogram + 1 - var histograms []histogramCommand - if num_histograms > max_histograms { - num_histograms = max_histograms - } - - if length == 0 { - split.num_types = 1 - return - } else if length < kMinLengthForBlockSplitting { - brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, split.num_blocks+1) - brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, split.num_blocks+1) - split.num_types = 1 - split.types[split.num_blocks] = 0 - split.lengths[split.num_blocks] = uint32(length) - split.num_blocks++ - return - } - - histograms = make([]histogramCommand, num_histograms) - - /* Find good entropy codes. */ - initialEntropyCodesCommand(data, length, sampling_stride_length, num_histograms, histograms) - - refineEntropyCodesCommand(data, length, sampling_stride_length, num_histograms, histograms) - { - var block_ids []byte = make([]byte, length) - var num_blocks uint = 0 - var bitmaplen uint = (num_histograms + 7) >> 3 - var insert_cost []float64 = make([]float64, (data_size * num_histograms)) - var cost []float64 = make([]float64, num_histograms) - var switch_signal []byte = make([]byte, (length * bitmaplen)) - var new_id []uint16 = make([]uint16, num_histograms) - var iters uint - if params.quality < hqZopflificationQuality { - iters = 3 - } else { - iters = 10 - } - /* Find a good path through literals with the good entropy codes. */ - - var i uint - for i = 0; i < iters; i++ { - num_blocks = findBlocksCommand(data, length, block_switch_cost, num_histograms, histograms, insert_cost, cost, switch_signal, block_ids) - num_histograms = remapBlockIdsCommand(block_ids, length, new_id, num_histograms) - buildBlockHistogramsCommand(data, length, block_ids, num_histograms, histograms) - } - - insert_cost = nil - cost = nil - switch_signal = nil - new_id = nil - histograms = nil - clusterBlocksCommand(data, length, num_blocks, block_ids, split) - block_ids = nil - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/block_splitter_distance.go b/src/vendor/github.com/andybalholm/brotli/block_splitter_distance.go deleted file mode 100644 index 953530d5..00000000 --- a/src/vendor/github.com/andybalholm/brotli/block_splitter_distance.go +++ /dev/null @@ -1,433 +0,0 @@ -package brotli - -import "math" - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -func initialEntropyCodesDistance(data []uint16, length uint, stride uint, num_histograms uint, histograms []histogramDistance) { - var seed uint32 = 7 - var block_length uint = length / num_histograms - var i uint - clearHistogramsDistance(histograms, num_histograms) - for i = 0; i < num_histograms; i++ { - var pos uint = length * i / num_histograms - if i != 0 { - pos += uint(myRand(&seed) % uint32(block_length)) - } - - if pos+stride >= length { - pos = length - stride - 1 - } - - histogramAddVectorDistance(&histograms[i], data[pos:], stride) - } -} - -func randomSampleDistance(seed *uint32, data []uint16, length uint, stride uint, sample *histogramDistance) { - var pos uint = 0 - if stride >= length { - stride = length - } else { - pos = uint(myRand(seed) % uint32(length-stride+1)) - } - - histogramAddVectorDistance(sample, data[pos:], stride) -} - -func refineEntropyCodesDistance(data []uint16, length uint, stride uint, num_histograms uint, histograms []histogramDistance) { - var iters uint = kIterMulForRefining*length/stride + kMinItersForRefining - var seed uint32 = 7 - var iter uint - iters = ((iters + num_histograms - 1) / num_histograms) * num_histograms - for iter = 0; iter < iters; iter++ { - var sample histogramDistance - histogramClearDistance(&sample) - randomSampleDistance(&seed, data, length, stride, &sample) - histogramAddHistogramDistance(&histograms[iter%num_histograms], &sample) - } -} - -/* Assigns a block id from the range [0, num_histograms) to each data element - in data[0..length) and fills in block_id[0..length) with the assigned values. - Returns the number of blocks, i.e. one plus the number of block switches. */ -func findBlocksDistance(data []uint16, length uint, block_switch_bitcost float64, num_histograms uint, histograms []histogramDistance, insert_cost []float64, cost []float64, switch_signal []byte, block_id []byte) uint { - var data_size uint = histogramDataSizeDistance() - var bitmaplen uint = (num_histograms + 7) >> 3 - var num_blocks uint = 1 - var i uint - var j uint - assert(num_histograms <= 256) - if num_histograms <= 1 { - for i = 0; i < length; i++ { - block_id[i] = 0 - } - - return 1 - } - - for i := 0; i < int(data_size*num_histograms); i++ { - insert_cost[i] = 0 - } - for i = 0; i < num_histograms; i++ { - insert_cost[i] = fastLog2(uint(uint32(histograms[i].total_count_))) - } - - for i = data_size; i != 0; { - i-- - for j = 0; j < num_histograms; j++ { - insert_cost[i*num_histograms+j] = insert_cost[j] - bitCost(uint(histograms[j].data_[i])) - } - } - - for i := 0; i < int(num_histograms); i++ { - cost[i] = 0 - } - for i := 0; i < int(length*bitmaplen); i++ { - switch_signal[i] = 0 - } - - /* After each iteration of this loop, cost[k] will contain the difference - between the minimum cost of arriving at the current byte position using - entropy code k, and the minimum cost of arriving at the current byte - position. This difference is capped at the block switch cost, and if it - reaches block switch cost, it means that when we trace back from the last - position, we need to switch here. */ - for i = 0; i < length; i++ { - var byte_ix uint = i - var ix uint = byte_ix * bitmaplen - var insert_cost_ix uint = uint(data[byte_ix]) * num_histograms - var min_cost float64 = 1e99 - var block_switch_cost float64 = block_switch_bitcost - var k uint - for k = 0; k < num_histograms; k++ { - /* We are coding the symbol in data[byte_ix] with entropy code k. */ - cost[k] += insert_cost[insert_cost_ix+k] - - if cost[k] < min_cost { - min_cost = cost[k] - block_id[byte_ix] = byte(k) - } - } - - /* More blocks for the beginning. */ - if byte_ix < 2000 { - block_switch_cost *= 0.77 + 0.07*float64(byte_ix)/2000 - } - - for k = 0; k < num_histograms; k++ { - cost[k] -= min_cost - if cost[k] >= block_switch_cost { - var mask byte = byte(1 << (k & 7)) - cost[k] = block_switch_cost - assert(k>>3 < bitmaplen) - switch_signal[ix+(k>>3)] |= mask - /* Trace back from the last position and switch at the marked places. */ - } - } - } - { - var byte_ix uint = length - 1 - var ix uint = byte_ix * bitmaplen - var cur_id byte = block_id[byte_ix] - for byte_ix > 0 { - var mask byte = byte(1 << (cur_id & 7)) - assert(uint(cur_id)>>3 < bitmaplen) - byte_ix-- - ix -= bitmaplen - if switch_signal[ix+uint(cur_id>>3)]&mask != 0 { - if cur_id != block_id[byte_ix] { - cur_id = block_id[byte_ix] - num_blocks++ - } - } - - block_id[byte_ix] = cur_id - } - } - - return num_blocks -} - -var remapBlockIdsDistance_kInvalidId uint16 = 256 - -func remapBlockIdsDistance(block_ids []byte, length uint, new_id []uint16, num_histograms uint) uint { - var next_id uint16 = 0 - var i uint - for i = 0; i < num_histograms; i++ { - new_id[i] = remapBlockIdsDistance_kInvalidId - } - - for i = 0; i < length; i++ { - assert(uint(block_ids[i]) < num_histograms) - if new_id[block_ids[i]] == remapBlockIdsDistance_kInvalidId { - new_id[block_ids[i]] = next_id - next_id++ - } - } - - for i = 0; i < length; i++ { - block_ids[i] = byte(new_id[block_ids[i]]) - assert(uint(block_ids[i]) < num_histograms) - } - - assert(uint(next_id) <= num_histograms) - return uint(next_id) -} - -func buildBlockHistogramsDistance(data []uint16, length uint, block_ids []byte, num_histograms uint, histograms []histogramDistance) { - var i uint - clearHistogramsDistance(histograms, num_histograms) - for i = 0; i < length; i++ { - histogramAddDistance(&histograms[block_ids[i]], uint(data[i])) - } -} - -var clusterBlocksDistance_kInvalidIndex uint32 = math.MaxUint32 - -func clusterBlocksDistance(data []uint16, length uint, num_blocks uint, block_ids []byte, split *blockSplit) { - var histogram_symbols []uint32 = make([]uint32, num_blocks) - var block_lengths []uint32 = make([]uint32, num_blocks) - var expected_num_clusters uint = clustersPerBatch * (num_blocks + histogramsPerBatch - 1) / histogramsPerBatch - var all_histograms_size uint = 0 - var all_histograms_capacity uint = expected_num_clusters - var all_histograms []histogramDistance = make([]histogramDistance, all_histograms_capacity) - var cluster_size_size uint = 0 - var cluster_size_capacity uint = expected_num_clusters - var cluster_size []uint32 = make([]uint32, cluster_size_capacity) - var num_clusters uint = 0 - var histograms []histogramDistance = make([]histogramDistance, brotli_min_size_t(num_blocks, histogramsPerBatch)) - var max_num_pairs uint = histogramsPerBatch * histogramsPerBatch / 2 - var pairs_capacity uint = max_num_pairs + 1 - var pairs []histogramPair = make([]histogramPair, pairs_capacity) - var pos uint = 0 - var clusters []uint32 - var num_final_clusters uint - var new_index []uint32 - var i uint - var sizes = [histogramsPerBatch]uint32{0} - var new_clusters = [histogramsPerBatch]uint32{0} - var symbols = [histogramsPerBatch]uint32{0} - var remap = [histogramsPerBatch]uint32{0} - - for i := 0; i < int(num_blocks); i++ { - block_lengths[i] = 0 - } - { - var block_idx uint = 0 - for i = 0; i < length; i++ { - assert(block_idx < num_blocks) - block_lengths[block_idx]++ - if i+1 == length || block_ids[i] != block_ids[i+1] { - block_idx++ - } - } - - assert(block_idx == num_blocks) - } - - for i = 0; i < num_blocks; i += histogramsPerBatch { - var num_to_combine uint = brotli_min_size_t(num_blocks-i, histogramsPerBatch) - var num_new_clusters uint - var j uint - for j = 0; j < num_to_combine; j++ { - var k uint - histogramClearDistance(&histograms[j]) - for k = 0; uint32(k) < block_lengths[i+j]; k++ { - histogramAddDistance(&histograms[j], uint(data[pos])) - pos++ - } - - histograms[j].bit_cost_ = populationCostDistance(&histograms[j]) - new_clusters[j] = uint32(j) - symbols[j] = uint32(j) - sizes[j] = 1 - } - - num_new_clusters = histogramCombineDistance(histograms, sizes[:], symbols[:], new_clusters[:], []histogramPair(pairs), num_to_combine, num_to_combine, histogramsPerBatch, max_num_pairs) - if all_histograms_capacity < (all_histograms_size + num_new_clusters) { - var _new_size uint - if all_histograms_capacity == 0 { - _new_size = all_histograms_size + num_new_clusters - } else { - _new_size = all_histograms_capacity - } - var new_array []histogramDistance - for _new_size < (all_histograms_size + num_new_clusters) { - _new_size *= 2 - } - new_array = make([]histogramDistance, _new_size) - if all_histograms_capacity != 0 { - copy(new_array, all_histograms[:all_histograms_capacity]) - } - - all_histograms = new_array - all_histograms_capacity = _new_size - } - - brotli_ensure_capacity_uint32_t(&cluster_size, &cluster_size_capacity, cluster_size_size+num_new_clusters) - for j = 0; j < num_new_clusters; j++ { - all_histograms[all_histograms_size] = histograms[new_clusters[j]] - all_histograms_size++ - cluster_size[cluster_size_size] = sizes[new_clusters[j]] - cluster_size_size++ - remap[new_clusters[j]] = uint32(j) - } - - for j = 0; j < num_to_combine; j++ { - histogram_symbols[i+j] = uint32(num_clusters) + remap[symbols[j]] - } - - num_clusters += num_new_clusters - assert(num_clusters == cluster_size_size) - assert(num_clusters == all_histograms_size) - } - - histograms = nil - - max_num_pairs = brotli_min_size_t(64*num_clusters, (num_clusters/2)*num_clusters) - if pairs_capacity < max_num_pairs+1 { - pairs = nil - pairs = make([]histogramPair, (max_num_pairs + 1)) - } - - clusters = make([]uint32, num_clusters) - for i = 0; i < num_clusters; i++ { - clusters[i] = uint32(i) - } - - num_final_clusters = histogramCombineDistance(all_histograms, cluster_size, histogram_symbols, clusters, pairs, num_clusters, num_blocks, maxNumberOfBlockTypes, max_num_pairs) - pairs = nil - cluster_size = nil - - new_index = make([]uint32, num_clusters) - for i = 0; i < num_clusters; i++ { - new_index[i] = clusterBlocksDistance_kInvalidIndex - } - pos = 0 - { - var next_index uint32 = 0 - for i = 0; i < num_blocks; i++ { - var histo histogramDistance - var j uint - var best_out uint32 - var best_bits float64 - histogramClearDistance(&histo) - for j = 0; uint32(j) < block_lengths[i]; j++ { - histogramAddDistance(&histo, uint(data[pos])) - pos++ - } - - if i == 0 { - best_out = histogram_symbols[0] - } else { - best_out = histogram_symbols[i-1] - } - best_bits = histogramBitCostDistanceDistance(&histo, &all_histograms[best_out]) - for j = 0; j < num_final_clusters; j++ { - var cur_bits float64 = histogramBitCostDistanceDistance(&histo, &all_histograms[clusters[j]]) - if cur_bits < best_bits { - best_bits = cur_bits - best_out = clusters[j] - } - } - - histogram_symbols[i] = best_out - if new_index[best_out] == clusterBlocksDistance_kInvalidIndex { - new_index[best_out] = next_index - next_index++ - } - } - } - - clusters = nil - all_histograms = nil - brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, num_blocks) - brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, num_blocks) - { - var cur_length uint32 = 0 - var block_idx uint = 0 - var max_type byte = 0 - for i = 0; i < num_blocks; i++ { - cur_length += block_lengths[i] - if i+1 == num_blocks || histogram_symbols[i] != histogram_symbols[i+1] { - var id byte = byte(new_index[histogram_symbols[i]]) - split.types[block_idx] = id - split.lengths[block_idx] = cur_length - max_type = brotli_max_uint8_t(max_type, id) - cur_length = 0 - block_idx++ - } - } - - split.num_blocks = block_idx - split.num_types = uint(max_type) + 1 - } - - new_index = nil - block_lengths = nil - histogram_symbols = nil -} - -func splitByteVectorDistance(data []uint16, length uint, literals_per_histogram uint, max_histograms uint, sampling_stride_length uint, block_switch_cost float64, params *encoderParams, split *blockSplit) { - var data_size uint = histogramDataSizeDistance() - var num_histograms uint = length/literals_per_histogram + 1 - var histograms []histogramDistance - if num_histograms > max_histograms { - num_histograms = max_histograms - } - - if length == 0 { - split.num_types = 1 - return - } else if length < kMinLengthForBlockSplitting { - brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, split.num_blocks+1) - brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, split.num_blocks+1) - split.num_types = 1 - split.types[split.num_blocks] = 0 - split.lengths[split.num_blocks] = uint32(length) - split.num_blocks++ - return - } - - histograms = make([]histogramDistance, num_histograms) - - /* Find good entropy codes. */ - initialEntropyCodesDistance(data, length, sampling_stride_length, num_histograms, histograms) - - refineEntropyCodesDistance(data, length, sampling_stride_length, num_histograms, histograms) - { - var block_ids []byte = make([]byte, length) - var num_blocks uint = 0 - var bitmaplen uint = (num_histograms + 7) >> 3 - var insert_cost []float64 = make([]float64, (data_size * num_histograms)) - var cost []float64 = make([]float64, num_histograms) - var switch_signal []byte = make([]byte, (length * bitmaplen)) - var new_id []uint16 = make([]uint16, num_histograms) - var iters uint - if params.quality < hqZopflificationQuality { - iters = 3 - } else { - iters = 10 - } - /* Find a good path through literals with the good entropy codes. */ - - var i uint - for i = 0; i < iters; i++ { - num_blocks = findBlocksDistance(data, length, block_switch_cost, num_histograms, histograms, insert_cost, cost, switch_signal, block_ids) - num_histograms = remapBlockIdsDistance(block_ids, length, new_id, num_histograms) - buildBlockHistogramsDistance(data, length, block_ids, num_histograms, histograms) - } - - insert_cost = nil - cost = nil - switch_signal = nil - new_id = nil - histograms = nil - clusterBlocksDistance(data, length, num_blocks, block_ids, split) - block_ids = nil - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/block_splitter_literal.go b/src/vendor/github.com/andybalholm/brotli/block_splitter_literal.go deleted file mode 100644 index 1c895cf3..00000000 --- a/src/vendor/github.com/andybalholm/brotli/block_splitter_literal.go +++ /dev/null @@ -1,433 +0,0 @@ -package brotli - -import "math" - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -func initialEntropyCodesLiteral(data []byte, length uint, stride uint, num_histograms uint, histograms []histogramLiteral) { - var seed uint32 = 7 - var block_length uint = length / num_histograms - var i uint - clearHistogramsLiteral(histograms, num_histograms) - for i = 0; i < num_histograms; i++ { - var pos uint = length * i / num_histograms - if i != 0 { - pos += uint(myRand(&seed) % uint32(block_length)) - } - - if pos+stride >= length { - pos = length - stride - 1 - } - - histogramAddVectorLiteral(&histograms[i], data[pos:], stride) - } -} - -func randomSampleLiteral(seed *uint32, data []byte, length uint, stride uint, sample *histogramLiteral) { - var pos uint = 0 - if stride >= length { - stride = length - } else { - pos = uint(myRand(seed) % uint32(length-stride+1)) - } - - histogramAddVectorLiteral(sample, data[pos:], stride) -} - -func refineEntropyCodesLiteral(data []byte, length uint, stride uint, num_histograms uint, histograms []histogramLiteral) { - var iters uint = kIterMulForRefining*length/stride + kMinItersForRefining - var seed uint32 = 7 - var iter uint - iters = ((iters + num_histograms - 1) / num_histograms) * num_histograms - for iter = 0; iter < iters; iter++ { - var sample histogramLiteral - histogramClearLiteral(&sample) - randomSampleLiteral(&seed, data, length, stride, &sample) - histogramAddHistogramLiteral(&histograms[iter%num_histograms], &sample) - } -} - -/* Assigns a block id from the range [0, num_histograms) to each data element - in data[0..length) and fills in block_id[0..length) with the assigned values. - Returns the number of blocks, i.e. one plus the number of block switches. */ -func findBlocksLiteral(data []byte, length uint, block_switch_bitcost float64, num_histograms uint, histograms []histogramLiteral, insert_cost []float64, cost []float64, switch_signal []byte, block_id []byte) uint { - var data_size uint = histogramDataSizeLiteral() - var bitmaplen uint = (num_histograms + 7) >> 3 - var num_blocks uint = 1 - var i uint - var j uint - assert(num_histograms <= 256) - if num_histograms <= 1 { - for i = 0; i < length; i++ { - block_id[i] = 0 - } - - return 1 - } - - for i := 0; i < int(data_size*num_histograms); i++ { - insert_cost[i] = 0 - } - for i = 0; i < num_histograms; i++ { - insert_cost[i] = fastLog2(uint(uint32(histograms[i].total_count_))) - } - - for i = data_size; i != 0; { - i-- - for j = 0; j < num_histograms; j++ { - insert_cost[i*num_histograms+j] = insert_cost[j] - bitCost(uint(histograms[j].data_[i])) - } - } - - for i := 0; i < int(num_histograms); i++ { - cost[i] = 0 - } - for i := 0; i < int(length*bitmaplen); i++ { - switch_signal[i] = 0 - } - - /* After each iteration of this loop, cost[k] will contain the difference - between the minimum cost of arriving at the current byte position using - entropy code k, and the minimum cost of arriving at the current byte - position. This difference is capped at the block switch cost, and if it - reaches block switch cost, it means that when we trace back from the last - position, we need to switch here. */ - for i = 0; i < length; i++ { - var byte_ix uint = i - var ix uint = byte_ix * bitmaplen - var insert_cost_ix uint = uint(data[byte_ix]) * num_histograms - var min_cost float64 = 1e99 - var block_switch_cost float64 = block_switch_bitcost - var k uint - for k = 0; k < num_histograms; k++ { - /* We are coding the symbol in data[byte_ix] with entropy code k. */ - cost[k] += insert_cost[insert_cost_ix+k] - - if cost[k] < min_cost { - min_cost = cost[k] - block_id[byte_ix] = byte(k) - } - } - - /* More blocks for the beginning. */ - if byte_ix < 2000 { - block_switch_cost *= 0.77 + 0.07*float64(byte_ix)/2000 - } - - for k = 0; k < num_histograms; k++ { - cost[k] -= min_cost - if cost[k] >= block_switch_cost { - var mask byte = byte(1 << (k & 7)) - cost[k] = block_switch_cost - assert(k>>3 < bitmaplen) - switch_signal[ix+(k>>3)] |= mask - /* Trace back from the last position and switch at the marked places. */ - } - } - } - { - var byte_ix uint = length - 1 - var ix uint = byte_ix * bitmaplen - var cur_id byte = block_id[byte_ix] - for byte_ix > 0 { - var mask byte = byte(1 << (cur_id & 7)) - assert(uint(cur_id)>>3 < bitmaplen) - byte_ix-- - ix -= bitmaplen - if switch_signal[ix+uint(cur_id>>3)]&mask != 0 { - if cur_id != block_id[byte_ix] { - cur_id = block_id[byte_ix] - num_blocks++ - } - } - - block_id[byte_ix] = cur_id - } - } - - return num_blocks -} - -var remapBlockIdsLiteral_kInvalidId uint16 = 256 - -func remapBlockIdsLiteral(block_ids []byte, length uint, new_id []uint16, num_histograms uint) uint { - var next_id uint16 = 0 - var i uint - for i = 0; i < num_histograms; i++ { - new_id[i] = remapBlockIdsLiteral_kInvalidId - } - - for i = 0; i < length; i++ { - assert(uint(block_ids[i]) < num_histograms) - if new_id[block_ids[i]] == remapBlockIdsLiteral_kInvalidId { - new_id[block_ids[i]] = next_id - next_id++ - } - } - - for i = 0; i < length; i++ { - block_ids[i] = byte(new_id[block_ids[i]]) - assert(uint(block_ids[i]) < num_histograms) - } - - assert(uint(next_id) <= num_histograms) - return uint(next_id) -} - -func buildBlockHistogramsLiteral(data []byte, length uint, block_ids []byte, num_histograms uint, histograms []histogramLiteral) { - var i uint - clearHistogramsLiteral(histograms, num_histograms) - for i = 0; i < length; i++ { - histogramAddLiteral(&histograms[block_ids[i]], uint(data[i])) - } -} - -var clusterBlocksLiteral_kInvalidIndex uint32 = math.MaxUint32 - -func clusterBlocksLiteral(data []byte, length uint, num_blocks uint, block_ids []byte, split *blockSplit) { - var histogram_symbols []uint32 = make([]uint32, num_blocks) - var block_lengths []uint32 = make([]uint32, num_blocks) - var expected_num_clusters uint = clustersPerBatch * (num_blocks + histogramsPerBatch - 1) / histogramsPerBatch - var all_histograms_size uint = 0 - var all_histograms_capacity uint = expected_num_clusters - var all_histograms []histogramLiteral = make([]histogramLiteral, all_histograms_capacity) - var cluster_size_size uint = 0 - var cluster_size_capacity uint = expected_num_clusters - var cluster_size []uint32 = make([]uint32, cluster_size_capacity) - var num_clusters uint = 0 - var histograms []histogramLiteral = make([]histogramLiteral, brotli_min_size_t(num_blocks, histogramsPerBatch)) - var max_num_pairs uint = histogramsPerBatch * histogramsPerBatch / 2 - var pairs_capacity uint = max_num_pairs + 1 - var pairs []histogramPair = make([]histogramPair, pairs_capacity) - var pos uint = 0 - var clusters []uint32 - var num_final_clusters uint - var new_index []uint32 - var i uint - var sizes = [histogramsPerBatch]uint32{0} - var new_clusters = [histogramsPerBatch]uint32{0} - var symbols = [histogramsPerBatch]uint32{0} - var remap = [histogramsPerBatch]uint32{0} - - for i := 0; i < int(num_blocks); i++ { - block_lengths[i] = 0 - } - { - var block_idx uint = 0 - for i = 0; i < length; i++ { - assert(block_idx < num_blocks) - block_lengths[block_idx]++ - if i+1 == length || block_ids[i] != block_ids[i+1] { - block_idx++ - } - } - - assert(block_idx == num_blocks) - } - - for i = 0; i < num_blocks; i += histogramsPerBatch { - var num_to_combine uint = brotli_min_size_t(num_blocks-i, histogramsPerBatch) - var num_new_clusters uint - var j uint - for j = 0; j < num_to_combine; j++ { - var k uint - histogramClearLiteral(&histograms[j]) - for k = 0; uint32(k) < block_lengths[i+j]; k++ { - histogramAddLiteral(&histograms[j], uint(data[pos])) - pos++ - } - - histograms[j].bit_cost_ = populationCostLiteral(&histograms[j]) - new_clusters[j] = uint32(j) - symbols[j] = uint32(j) - sizes[j] = 1 - } - - num_new_clusters = histogramCombineLiteral(histograms, sizes[:], symbols[:], new_clusters[:], []histogramPair(pairs), num_to_combine, num_to_combine, histogramsPerBatch, max_num_pairs) - if all_histograms_capacity < (all_histograms_size + num_new_clusters) { - var _new_size uint - if all_histograms_capacity == 0 { - _new_size = all_histograms_size + num_new_clusters - } else { - _new_size = all_histograms_capacity - } - var new_array []histogramLiteral - for _new_size < (all_histograms_size + num_new_clusters) { - _new_size *= 2 - } - new_array = make([]histogramLiteral, _new_size) - if all_histograms_capacity != 0 { - copy(new_array, all_histograms[:all_histograms_capacity]) - } - - all_histograms = new_array - all_histograms_capacity = _new_size - } - - brotli_ensure_capacity_uint32_t(&cluster_size, &cluster_size_capacity, cluster_size_size+num_new_clusters) - for j = 0; j < num_new_clusters; j++ { - all_histograms[all_histograms_size] = histograms[new_clusters[j]] - all_histograms_size++ - cluster_size[cluster_size_size] = sizes[new_clusters[j]] - cluster_size_size++ - remap[new_clusters[j]] = uint32(j) - } - - for j = 0; j < num_to_combine; j++ { - histogram_symbols[i+j] = uint32(num_clusters) + remap[symbols[j]] - } - - num_clusters += num_new_clusters - assert(num_clusters == cluster_size_size) - assert(num_clusters == all_histograms_size) - } - - histograms = nil - - max_num_pairs = brotli_min_size_t(64*num_clusters, (num_clusters/2)*num_clusters) - if pairs_capacity < max_num_pairs+1 { - pairs = nil - pairs = make([]histogramPair, (max_num_pairs + 1)) - } - - clusters = make([]uint32, num_clusters) - for i = 0; i < num_clusters; i++ { - clusters[i] = uint32(i) - } - - num_final_clusters = histogramCombineLiteral(all_histograms, cluster_size, histogram_symbols, clusters, pairs, num_clusters, num_blocks, maxNumberOfBlockTypes, max_num_pairs) - pairs = nil - cluster_size = nil - - new_index = make([]uint32, num_clusters) - for i = 0; i < num_clusters; i++ { - new_index[i] = clusterBlocksLiteral_kInvalidIndex - } - pos = 0 - { - var next_index uint32 = 0 - for i = 0; i < num_blocks; i++ { - var histo histogramLiteral - var j uint - var best_out uint32 - var best_bits float64 - histogramClearLiteral(&histo) - for j = 0; uint32(j) < block_lengths[i]; j++ { - histogramAddLiteral(&histo, uint(data[pos])) - pos++ - } - - if i == 0 { - best_out = histogram_symbols[0] - } else { - best_out = histogram_symbols[i-1] - } - best_bits = histogramBitCostDistanceLiteral(&histo, &all_histograms[best_out]) - for j = 0; j < num_final_clusters; j++ { - var cur_bits float64 = histogramBitCostDistanceLiteral(&histo, &all_histograms[clusters[j]]) - if cur_bits < best_bits { - best_bits = cur_bits - best_out = clusters[j] - } - } - - histogram_symbols[i] = best_out - if new_index[best_out] == clusterBlocksLiteral_kInvalidIndex { - new_index[best_out] = next_index - next_index++ - } - } - } - - clusters = nil - all_histograms = nil - brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, num_blocks) - brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, num_blocks) - { - var cur_length uint32 = 0 - var block_idx uint = 0 - var max_type byte = 0 - for i = 0; i < num_blocks; i++ { - cur_length += block_lengths[i] - if i+1 == num_blocks || histogram_symbols[i] != histogram_symbols[i+1] { - var id byte = byte(new_index[histogram_symbols[i]]) - split.types[block_idx] = id - split.lengths[block_idx] = cur_length - max_type = brotli_max_uint8_t(max_type, id) - cur_length = 0 - block_idx++ - } - } - - split.num_blocks = block_idx - split.num_types = uint(max_type) + 1 - } - - new_index = nil - block_lengths = nil - histogram_symbols = nil -} - -func splitByteVectorLiteral(data []byte, length uint, literals_per_histogram uint, max_histograms uint, sampling_stride_length uint, block_switch_cost float64, params *encoderParams, split *blockSplit) { - var data_size uint = histogramDataSizeLiteral() - var num_histograms uint = length/literals_per_histogram + 1 - var histograms []histogramLiteral - if num_histograms > max_histograms { - num_histograms = max_histograms - } - - if length == 0 { - split.num_types = 1 - return - } else if length < kMinLengthForBlockSplitting { - brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, split.num_blocks+1) - brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, split.num_blocks+1) - split.num_types = 1 - split.types[split.num_blocks] = 0 - split.lengths[split.num_blocks] = uint32(length) - split.num_blocks++ - return - } - - histograms = make([]histogramLiteral, num_histograms) - - /* Find good entropy codes. */ - initialEntropyCodesLiteral(data, length, sampling_stride_length, num_histograms, histograms) - - refineEntropyCodesLiteral(data, length, sampling_stride_length, num_histograms, histograms) - { - var block_ids []byte = make([]byte, length) - var num_blocks uint = 0 - var bitmaplen uint = (num_histograms + 7) >> 3 - var insert_cost []float64 = make([]float64, (data_size * num_histograms)) - var cost []float64 = make([]float64, num_histograms) - var switch_signal []byte = make([]byte, (length * bitmaplen)) - var new_id []uint16 = make([]uint16, num_histograms) - var iters uint - if params.quality < hqZopflificationQuality { - iters = 3 - } else { - iters = 10 - } - /* Find a good path through literals with the good entropy codes. */ - - var i uint - for i = 0; i < iters; i++ { - num_blocks = findBlocksLiteral(data, length, block_switch_cost, num_histograms, histograms, insert_cost, cost, switch_signal, block_ids) - num_histograms = remapBlockIdsLiteral(block_ids, length, new_id, num_histograms) - buildBlockHistogramsLiteral(data, length, block_ids, num_histograms, histograms) - } - - insert_cost = nil - cost = nil - switch_signal = nil - new_id = nil - histograms = nil - clusterBlocksLiteral(data, length, num_blocks, block_ids, split) - block_ids = nil - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/brotli_bit_stream.go b/src/vendor/github.com/andybalholm/brotli/brotli_bit_stream.go deleted file mode 100644 index d098d320..00000000 --- a/src/vendor/github.com/andybalholm/brotli/brotli_bit_stream.go +++ /dev/null @@ -1,1435 +0,0 @@ -package brotli - -import ( - "slices" - "sync" -) - -const maxHuffmanTreeSize = (2*numCommandSymbols + 1) - -/* -The maximum size of Huffman dictionary for distances assuming that - - NPOSTFIX = 0 and NDIRECT = 0. -*/ -const maxSimpleDistanceAlphabetSize = 140 - -/* -Represents the range of values belonging to a prefix code: - - [offset, offset + 2^nbits) -*/ -type prefixCodeRange struct { - offset uint32 - nbits uint32 -} - -var kBlockLengthPrefixCode = [numBlockLenSymbols]prefixCodeRange{ - prefixCodeRange{1, 2}, - prefixCodeRange{5, 2}, - prefixCodeRange{9, 2}, - prefixCodeRange{13, 2}, - prefixCodeRange{17, 3}, - prefixCodeRange{25, 3}, - prefixCodeRange{33, 3}, - prefixCodeRange{41, 3}, - prefixCodeRange{49, 4}, - prefixCodeRange{65, 4}, - prefixCodeRange{81, 4}, - prefixCodeRange{97, 4}, - prefixCodeRange{113, 5}, - prefixCodeRange{145, 5}, - prefixCodeRange{177, 5}, - prefixCodeRange{209, 5}, - prefixCodeRange{241, 6}, - prefixCodeRange{305, 6}, - prefixCodeRange{369, 7}, - prefixCodeRange{497, 8}, - prefixCodeRange{753, 9}, - prefixCodeRange{1265, 10}, - prefixCodeRange{2289, 11}, - prefixCodeRange{4337, 12}, - prefixCodeRange{8433, 13}, - prefixCodeRange{16625, 24}, -} - -func blockLengthPrefixCode(len uint32) uint32 { - var code uint32 - if len >= 177 { - if len >= 753 { - code = 20 - } else { - code = 14 - } - } else if len >= 41 { - code = 7 - } else { - code = 0 - } - for code < (numBlockLenSymbols-1) && len >= kBlockLengthPrefixCode[code+1].offset { - code++ - } - return code -} - -func getBlockLengthPrefixCode(len uint32, code *uint, n_extra *uint32, extra *uint32) { - *code = uint(blockLengthPrefixCode(uint32(len))) - *n_extra = kBlockLengthPrefixCode[*code].nbits - *extra = len - kBlockLengthPrefixCode[*code].offset -} - -type blockTypeCodeCalculator struct { - last_type uint - second_last_type uint -} - -func initBlockTypeCodeCalculator(self *blockTypeCodeCalculator) { - self.last_type = 1 - self.second_last_type = 0 -} - -func nextBlockTypeCode(calculator *blockTypeCodeCalculator, type_ byte) uint { - var type_code uint - if uint(type_) == calculator.last_type+1 { - type_code = 1 - } else if uint(type_) == calculator.second_last_type { - type_code = 0 - } else { - type_code = uint(type_) + 2 - } - calculator.second_last_type = calculator.last_type - calculator.last_type = uint(type_) - return type_code -} - -/* -|nibblesbits| represents the 2 bits to encode MNIBBLES (0-3) - - REQUIRES: length > 0 - REQUIRES: length <= (1 << 24) -*/ -func encodeMlen(length uint, bits *uint64, numbits *uint, nibblesbits *uint64) { - var lg uint - if length == 1 { - lg = 1 - } else { - lg = uint(log2FloorNonZero(uint(uint32(length-1)))) + 1 - } - var tmp uint - if lg < 16 { - tmp = 16 - } else { - tmp = (lg + 3) - } - var mnibbles uint = tmp / 4 - assert(length > 0) - assert(length <= 1<<24) - assert(lg <= 24) - *nibblesbits = uint64(mnibbles) - 4 - *numbits = mnibbles * 4 - *bits = uint64(length) - 1 -} - -func storeCommandExtra(cmd *command, storage_ix *uint, storage []byte) { - var copylen_code uint32 = commandCopyLenCode(cmd) - var inscode uint16 = getInsertLengthCode(uint(cmd.insert_len_)) - var copycode uint16 = getCopyLengthCode(uint(copylen_code)) - var insnumextra uint32 = getInsertExtra(inscode) - var insextraval uint64 = uint64(cmd.insert_len_) - uint64(getInsertBase(inscode)) - var copyextraval uint64 = uint64(copylen_code) - uint64(getCopyBase(copycode)) - var bits uint64 = copyextraval< 0 - REQUIRES: length <= (1 << 24) -*/ -func storeCompressedMetaBlockHeader(is_final_block bool, length uint, storage_ix *uint, storage []byte) { - var lenbits uint64 - var nlenbits uint - var nibblesbits uint64 - var is_final uint64 - if is_final_block { - is_final = 1 - } else { - is_final = 0 - } - - /* Write ISLAST bit. */ - writeBits(1, is_final, storage_ix, storage) - - /* Write ISEMPTY bit. */ - if is_final_block { - writeBits(1, 0, storage_ix, storage) - } - - encodeMlen(length, &lenbits, &nlenbits, &nibblesbits) - writeBits(2, nibblesbits, storage_ix, storage) - writeBits(nlenbits, lenbits, storage_ix, storage) - - if !is_final_block { - /* Write ISUNCOMPRESSED bit. */ - writeBits(1, 0, storage_ix, storage) - } -} - -/* -Stores the uncompressed meta-block header. - - REQUIRES: length > 0 - REQUIRES: length <= (1 << 24) -*/ -func storeUncompressedMetaBlockHeader(length uint, storage_ix *uint, storage []byte) { - var lenbits uint64 - var nlenbits uint - var nibblesbits uint64 - - /* Write ISLAST bit. - Uncompressed block cannot be the last one, so set to 0. */ - writeBits(1, 0, storage_ix, storage) - - encodeMlen(length, &lenbits, &nlenbits, &nibblesbits) - writeBits(2, nibblesbits, storage_ix, storage) - writeBits(nlenbits, lenbits, storage_ix, storage) - - /* Write ISUNCOMPRESSED bit. */ - writeBits(1, 1, storage_ix, storage) -} - -var storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder = [codeLengthCodes]byte{1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15} - -var storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeSymbols = [6]byte{0, 7, 3, 2, 1, 15} -var storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeBitLengths = [6]byte{2, 4, 3, 2, 2, 4} - -func storeHuffmanTreeOfHuffmanTreeToBitMask(num_codes int, code_length_bitdepth []byte, storage_ix *uint, storage []byte) { - var skip_some uint = 0 - var codes_to_store uint = codeLengthCodes - /* The bit lengths of the Huffman code over the code length alphabet - are compressed with the following static Huffman code: - Symbol Code - ------ ---- - 0 00 - 1 1110 - 2 110 - 3 01 - 4 10 - 5 1111 */ - - /* Throw away trailing zeros: */ - if num_codes > 1 { - for ; codes_to_store > 0; codes_to_store-- { - if code_length_bitdepth[storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder[codes_to_store-1]] != 0 { - break - } - } - } - - if code_length_bitdepth[storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder[0]] == 0 && code_length_bitdepth[storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder[1]] == 0 { - skip_some = 2 /* skips two. */ - if code_length_bitdepth[storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder[2]] == 0 { - skip_some = 3 /* skips three. */ - } - } - - writeBits(2, uint64(skip_some), storage_ix, storage) - { - var i uint - for i = skip_some; i < codes_to_store; i++ { - var l uint = uint(code_length_bitdepth[storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder[i]]) - writeBits(uint(storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeBitLengths[l]), uint64(storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeSymbols[l]), storage_ix, storage) - } - } -} - -func storeHuffmanTreeToBitMask(huffman_tree_size uint, huffman_tree []byte, huffman_tree_extra_bits []byte, code_length_bitdepth []byte, code_length_bitdepth_symbols []uint16, storage_ix *uint, storage []byte) { - var i uint - for i = 0; i < huffman_tree_size; i++ { - var ix uint = uint(huffman_tree[i]) - writeBits(uint(code_length_bitdepth[ix]), uint64(code_length_bitdepth_symbols[ix]), storage_ix, storage) - - /* Extra bits */ - switch ix { - case repeatPreviousCodeLength: - writeBits(2, uint64(huffman_tree_extra_bits[i]), storage_ix, storage) - - case repeatZeroCodeLength: - writeBits(3, uint64(huffman_tree_extra_bits[i]), storage_ix, storage) - } - } -} - -func storeSimpleHuffmanTree(depths []byte, symbols []uint, num_symbols uint, max_bits uint, storage_ix *uint, storage []byte) { - /* value of 1 indicates a simple Huffman code */ - writeBits(2, 1, storage_ix, storage) - - writeBits(2, uint64(num_symbols)-1, storage_ix, storage) /* NSYM - 1 */ - { - /* Sort */ - var i uint - for i = 0; i < num_symbols; i++ { - var j uint - for j = i + 1; j < num_symbols; j++ { - if depths[symbols[j]] < depths[symbols[i]] { - var tmp uint = symbols[j] - symbols[j] = symbols[i] - symbols[i] = tmp - } - } - } - } - - if num_symbols == 2 { - writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) - } else if num_symbols == 3 { - writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) - } else { - writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[3]), storage_ix, storage) - - /* tree-select */ - var tmp int - if depths[symbols[0]] == 1 { - tmp = 1 - } else { - tmp = 0 - } - writeBits(1, uint64(tmp), storage_ix, storage) - } -} - -/* -num = alphabet size - - depths = symbol depths -*/ -func storeHuffmanTree(depths []byte, num uint, tree []huffmanTree, storage_ix *uint, storage []byte) { - var huffman_tree [numCommandSymbols]byte - var huffman_tree_extra_bits [numCommandSymbols]byte - var huffman_tree_size uint = 0 - var code_length_bitdepth = [codeLengthCodes]byte{0} - var code_length_bitdepth_symbols [codeLengthCodes]uint16 - var huffman_tree_histogram = [codeLengthCodes]uint32{0} - var i uint - var num_codes int = 0 - /* Write the Huffman tree into the brotli-representation. - The command alphabet is the largest, so this allocation will fit all - alphabets. */ - - var code uint = 0 - - assert(num <= numCommandSymbols) - - writeHuffmanTree(depths, num, &huffman_tree_size, huffman_tree[:], huffman_tree_extra_bits[:]) - - /* Calculate the statistics of the Huffman tree in brotli-representation. */ - for i = 0; i < huffman_tree_size; i++ { - huffman_tree_histogram[huffman_tree[i]]++ - } - - for i = 0; i < codeLengthCodes; i++ { - if huffman_tree_histogram[i] != 0 { - if num_codes == 0 { - code = i - num_codes = 1 - } else if num_codes == 1 { - num_codes = 2 - break - } - } - } - - /* Calculate another Huffman tree to use for compressing both the - earlier Huffman tree with. */ - createHuffmanTree(huffman_tree_histogram[:], codeLengthCodes, 5, tree, code_length_bitdepth[:]) - - convertBitDepthsToSymbols(code_length_bitdepth[:], codeLengthCodes, code_length_bitdepth_symbols[:]) - - /* Now, we have all the data, let's start storing it */ - storeHuffmanTreeOfHuffmanTreeToBitMask(num_codes, code_length_bitdepth[:], storage_ix, storage) - - if num_codes == 1 { - code_length_bitdepth[code] = 0 - } - - /* Store the real Huffman tree now. */ - storeHuffmanTreeToBitMask(huffman_tree_size, huffman_tree[:], huffman_tree_extra_bits[:], code_length_bitdepth[:], code_length_bitdepth_symbols[:], storage_ix, storage) -} - -/* -Builds a Huffman tree from histogram[0:length] into depth[0:length] and - - bits[0:length] and stores the encoded tree to the bit stream. -*/ -func buildAndStoreHuffmanTree(histogram []uint32, histogram_length uint, alphabet_size uint, tree []huffmanTree, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { - var count uint = 0 - var s4 = [4]uint{0} - var i uint - var max_bits uint = 0 - for i = 0; i < histogram_length; i++ { - if histogram[i] != 0 { - if count < 4 { - s4[count] = i - } else if count > 4 { - break - } - - count++ - } - } - { - var max_bits_counter uint = alphabet_size - 1 - for max_bits_counter != 0 { - max_bits_counter >>= 1 - max_bits++ - } - } - - if count <= 1 { - writeBits(4, 1, storage_ix, storage) - writeBits(max_bits, uint64(s4[0]), storage_ix, storage) - depth[s4[0]] = 0 - bits[s4[0]] = 0 - return - } - - for i := 0; i < int(histogram_length); i++ { - depth[i] = 0 - } - createHuffmanTree(histogram, histogram_length, 15, tree, depth) - convertBitDepthsToSymbols(depth, histogram_length, bits) - - if count <= 4 { - storeSimpleHuffmanTree(depth, s4[:], count, max_bits, storage_ix, storage) - } else { - storeHuffmanTree(depth, histogram_length, tree, storage_ix, storage) - } -} - -func buildAndStoreHuffmanTreeFast(histogram []uint32, histogram_total uint, max_bits uint, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { - var count uint = 0 - var symbols = [4]uint{0} - var length uint = 0 - var total uint = histogram_total - for total != 0 { - if histogram[length] != 0 { - if count < 4 { - symbols[count] = length - } - - count++ - total -= uint(histogram[length]) - } - - length++ - } - - if count <= 1 { - writeBits(4, 1, storage_ix, storage) - writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) - depth[symbols[0]] = 0 - bits[symbols[0]] = 0 - return - } - - chooseBitDepths(histogram[:length], depth[:length], 14) - - convertBitDepthsToSymbols(depth, length, bits) - if count <= 4 { - var i uint - - /* value of 1 indicates a simple Huffman code */ - writeBits(2, 1, storage_ix, storage) - - writeBits(2, uint64(count)-1, storage_ix, storage) /* NSYM - 1 */ - - /* Sort */ - for i = 0; i < count; i++ { - var j uint - for j = i + 1; j < count; j++ { - if depth[symbols[j]] < depth[symbols[i]] { - var tmp uint = symbols[j] - symbols[j] = symbols[i] - symbols[i] = tmp - } - } - } - - if count == 2 { - writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) - } else if count == 3 { - writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) - } else { - writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) - writeBits(max_bits, uint64(symbols[3]), storage_ix, storage) - - /* tree-select */ - var tmp int - if depth[symbols[0]] == 1 { - tmp = 1 - } else { - tmp = 0 - } - writeBits(1, uint64(tmp), storage_ix, storage) - } - } else { - var previous_value byte = 8 - var i uint - - /* Complex Huffman Tree */ - storeStaticCodeLengthCode(storage_ix, storage) - - /* Actual RLE coding. */ - for i = 0; i < length; { - var value byte = depth[i] - var reps uint = 1 - var k uint - for k = i + 1; k < length && depth[k] == value; k++ { - reps++ - } - - i += reps - if value == 0 { - writeBits(uint(kZeroRepsDepth[reps]), kZeroRepsBits[reps], storage_ix, storage) - } else { - if previous_value != value { - writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value]), storage_ix, storage) - reps-- - } - - if reps < 3 { - for reps != 0 { - reps-- - writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value]), storage_ix, storage) - } - } else { - reps -= 3 - writeBits(uint(kNonZeroRepsDepth[reps]), kNonZeroRepsBits[reps], storage_ix, storage) - } - - previous_value = value - } - } - } -} - -type symbolAndCount struct { - symbol uint32 - count uint32 -} - -func chooseBitDepths(histogram []uint32, depth []byte, maxBits int) { - totalCodeSpace := 1 << maxBits - symbols := make([]symbolAndCount, 0, 704 /* static capacity so that it will be stack allocated */) - var totalCount uint32 = 0 - for i, n := range histogram { - if n != 0 { - symbols = append(symbols, symbolAndCount{ - symbol: uint32(i), - count: n, - }) - totalCount += n - } - } - slices.SortFunc(symbols, func(a, b symbolAndCount) int { - return int(b.count) - int(a.count) - }) - - // boundaries contains indexes into symbols such that (for example) - // boundaries[8] is the index of the first 8-bit symbol. - boundaries := make([]int, maxBits+1, 20 /* static capacity for stack allocation */) - - codeSpaceUsed := 0 - - // Assign initial boundaries conservatively, making sure no symbol uses more - // than its share of code space. - totalRatio := float64(totalCount) / float64(totalCodeSpace) - currentDepth := 1 - for i, symbol := range symbols { - for currentDepth < maxBits && float64(symbol.count)/float64(int(1)<<(maxBits-currentDepth)) < totalRatio { - currentDepth++ - boundaries[currentDepth] = i - } - codeSpaceUsed += 1 << (maxBits - currentDepth) - } - for i := currentDepth + 1; i <= maxBits; i++ { - boundaries[i] = len(symbols) - } - - // Move the boundaries till the code space is filled. - for codeSpaceUsed < totalCodeSpace { - available := totalCodeSpace - codeSpaceUsed - // Find the most efficient boundary to move, based on the ratio of how - // many times the symbol was used to how much code space will be consumed. - bestRatio := 0.0 - bestBoundary := 0 - for i := 2; i <= maxBits; i++ { - cost := 1 << (maxBits - i) // code space that would be used by moving this boundary - if cost > available { - continue - } - if boundaries[i] == len(symbols) { - continue - } - if i < maxBits && boundaries[i] == boundaries[i+1] { - continue - } - ratio := float64(symbols[boundaries[i]].count) / float64(cost) - if ratio > bestRatio { - bestRatio = ratio - bestBoundary = i - } - } - boundaries[bestBoundary]++ - codeSpaceUsed += 1 << (maxBits - bestBoundary) - } - - for i := range depth { - depth[i] = 0 - } - for i := 1; i < maxBits; i++ { - for j := boundaries[i]; j < boundaries[i+1]; j++ { - depth[symbols[j].symbol] = byte(i) - } - } - for j := boundaries[maxBits]; j < len(symbols); j++ { - depth[symbols[j].symbol] = byte(maxBits) - } -} - -func buildAndStoreHuffmanTreeFastBW(histogram []uint32, histogram_total uint, max_bits uint, depth []byte, bits []uint16, bw *bitWriter) { - var count uint = 0 - var symbols = [4]uint{0} - var length uint = 0 - var total uint = histogram_total - for total != 0 { - if histogram[length] != 0 { - if count < 4 { - symbols[count] = length - } - - count++ - total -= uint(histogram[length]) - } - - length++ - } - - if count <= 1 { - bw.writeBits(4, 1) - bw.writeBits(max_bits, uint64(symbols[0])) - depth[symbols[0]] = 0 - bits[symbols[0]] = 0 - return - } - - chooseBitDepths(histogram[:length], depth[:length], 14) - - convertBitDepthsToSymbols(depth, length, bits) - if count <= 4 { - var i uint - - /* value of 1 indicates a simple Huffman code */ - bw.writeBits(2, 1) - - bw.writeBits(2, uint64(count)-1) /* NSYM - 1 */ - - /* Sort */ - for i = 0; i < count; i++ { - var j uint - for j = i + 1; j < count; j++ { - if depth[symbols[j]] < depth[symbols[i]] { - var tmp uint = symbols[j] - symbols[j] = symbols[i] - symbols[i] = tmp - } - } - } - - if count == 2 { - bw.writeBits(max_bits, uint64(symbols[0])) - bw.writeBits(max_bits, uint64(symbols[1])) - } else if count == 3 { - bw.writeBits(max_bits, uint64(symbols[0])) - bw.writeBits(max_bits, uint64(symbols[1])) - bw.writeBits(max_bits, uint64(symbols[2])) - } else { - bw.writeBits(max_bits, uint64(symbols[0])) - bw.writeBits(max_bits, uint64(symbols[1])) - bw.writeBits(max_bits, uint64(symbols[2])) - bw.writeBits(max_bits, uint64(symbols[3])) - - /* tree-select */ - bw.writeSingleBit(depth[symbols[0]] == 1) - } - } else { - var previous_value byte = 8 - var i uint - - /* Complex Huffman Tree */ - storeStaticCodeLengthCodeBW(bw) - - /* Actual RLE coding. */ - for i = 0; i < length; { - var value byte = depth[i] - var reps uint = 1 - var k uint - for k = i + 1; k < length && depth[k] == value; k++ { - reps++ - } - - i += reps - if value == 0 { - bw.writeBits(uint(kZeroRepsDepth[reps]), kZeroRepsBits[reps]) - } else { - if previous_value != value { - bw.writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value])) - reps-- - } - - if reps < 3 { - for reps != 0 { - reps-- - bw.writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value])) - } - } else { - reps -= 3 - bw.writeBits(uint(kNonZeroRepsDepth[reps]), kNonZeroRepsBits[reps]) - } - - previous_value = value - } - } - } -} - -func indexOf(v []byte, v_size uint, value byte) uint { - var i uint = 0 - for ; i < v_size; i++ { - if v[i] == value { - return i - } - } - - return i -} - -func moveToFront(v []byte, index uint) { - var value byte = v[index] - var i uint - for i = index; i != 0; i-- { - v[i] = v[i-1] - } - - v[0] = value -} - -func moveToFrontTransform(v_in []uint32, v_size uint, v_out []uint32) { - var i uint - var mtf [256]byte - var max_value uint32 - if v_size == 0 { - return - } - - max_value = v_in[0] - for i = 1; i < v_size; i++ { - if v_in[i] > max_value { - max_value = v_in[i] - } - } - - assert(max_value < 256) - for i = 0; uint32(i) <= max_value; i++ { - mtf[i] = byte(i) - } - { - var mtf_size uint = uint(max_value + 1) - for i = 0; i < v_size; i++ { - var index uint = indexOf(mtf[:], mtf_size, byte(v_in[i])) - assert(index < mtf_size) - v_out[i] = uint32(index) - moveToFront(mtf[:], index) - } - } -} - -/* -Finds runs of zeros in v[0..in_size) and replaces them with a prefix code of - - the run length plus extra bits (lower 9 bits is the prefix code and the rest - are the extra bits). Non-zero values in v[] are shifted by - *max_length_prefix. Will not create prefix codes bigger than the initial - value of *max_run_length_prefix. The prefix code of run length L is simply - Log2Floor(L) and the number of extra bits is the same as the prefix code. -*/ -func runLengthCodeZeros(in_size uint, v []uint32, out_size *uint, max_run_length_prefix *uint32) { - var max_reps uint32 = 0 - var i uint - var max_prefix uint32 - for i = 0; i < in_size; { - var reps uint32 = 0 - for ; i < in_size && v[i] != 0; i++ { - } - for ; i < in_size && v[i] == 0; i++ { - reps++ - } - - max_reps = brotli_max_uint32_t(reps, max_reps) - } - - if max_reps > 0 { - max_prefix = log2FloorNonZero(uint(max_reps)) - } else { - max_prefix = 0 - } - max_prefix = brotli_min_uint32_t(max_prefix, *max_run_length_prefix) - *max_run_length_prefix = max_prefix - *out_size = 0 - for i = 0; i < in_size; { - assert(*out_size <= i) - if v[i] != 0 { - v[*out_size] = v[i] + *max_run_length_prefix - i++ - (*out_size)++ - } else { - var reps uint32 = 1 - var k uint - for k = i + 1; k < in_size && v[k] == 0; k++ { - reps++ - } - - i += uint(reps) - for reps != 0 { - if reps < 2< 0) - writeSingleBit(use_rle, storage_ix, storage) - if use_rle { - writeBits(4, uint64(max_run_length_prefix)-1, storage_ix, storage) - } - } - - buildAndStoreHuffmanTree(histogram[:], uint(uint32(num_clusters)+max_run_length_prefix), uint(uint32(num_clusters)+max_run_length_prefix), tree, depths[:], bits[:], storage_ix, storage) - for i = 0; i < num_rle_symbols; i++ { - var rle_symbol uint32 = rle_symbols[i] & encodeContextMap_kSymbolMask - var extra_bits_val uint32 = rle_symbols[i] >> symbolBits - writeBits(uint(depths[rle_symbol]), uint64(bits[rle_symbol]), storage_ix, storage) - if rle_symbol > 0 && rle_symbol <= max_run_length_prefix { - writeBits(uint(rle_symbol), uint64(extra_bits_val), storage_ix, storage) - } - } - - writeBits(1, 1, storage_ix, storage) /* use move-to-front */ - rle_symbols = nil -} - -/* Stores the block switch command with index block_ix to the bit stream. */ -func storeBlockSwitch(code *blockSplitCode, block_len uint32, block_type byte, is_first_block bool, storage_ix *uint, storage []byte) { - var typecode uint = nextBlockTypeCode(&code.type_code_calculator, block_type) - var lencode uint - var len_nextra uint32 - var len_extra uint32 - if !is_first_block { - writeBits(uint(code.type_depths[typecode]), uint64(code.type_bits[typecode]), storage_ix, storage) - } - - getBlockLengthPrefixCode(block_len, &lencode, &len_nextra, &len_extra) - - writeBits(uint(code.length_depths[lencode]), uint64(code.length_bits[lencode]), storage_ix, storage) - writeBits(uint(len_nextra), uint64(len_extra), storage_ix, storage) -} - -/* -Builds a BlockSplitCode data structure from the block split given by the - - vector of block types and block lengths and stores it to the bit stream. -*/ -func buildAndStoreBlockSplitCode(types []byte, lengths []uint32, num_blocks uint, num_types uint, tree []huffmanTree, code *blockSplitCode, storage_ix *uint, storage []byte) { - var type_histo [maxBlockTypeSymbols]uint32 - var length_histo [numBlockLenSymbols]uint32 - var i uint - var type_code_calculator blockTypeCodeCalculator - for i := 0; i < int(num_types+2); i++ { - type_histo[i] = 0 - } - length_histo = [numBlockLenSymbols]uint32{} - initBlockTypeCodeCalculator(&type_code_calculator) - for i = 0; i < num_blocks; i++ { - var type_code uint = nextBlockTypeCode(&type_code_calculator, types[i]) - if i != 0 { - type_histo[type_code]++ - } - length_histo[blockLengthPrefixCode(lengths[i])]++ - } - - storeVarLenUint8(num_types-1, storage_ix, storage) - if num_types > 1 { /* TODO: else? could StoreBlockSwitch occur? */ - buildAndStoreHuffmanTree(type_histo[0:], num_types+2, num_types+2, tree, code.type_depths[0:], code.type_bits[0:], storage_ix, storage) - buildAndStoreHuffmanTree(length_histo[0:], numBlockLenSymbols, numBlockLenSymbols, tree, code.length_depths[0:], code.length_bits[0:], storage_ix, storage) - storeBlockSwitch(code, lengths[0], types[0], true, storage_ix, storage) - } -} - -/* Stores a context map where the histogram type is always the block type. */ -func storeTrivialContextMap(num_types uint, context_bits uint, tree []huffmanTree, storage_ix *uint, storage []byte) { - storeVarLenUint8(num_types-1, storage_ix, storage) - if num_types > 1 { - var repeat_code uint = context_bits - 1 - var repeat_bits uint = (1 << repeat_code) - 1 - var alphabet_size uint = num_types + repeat_code - var histogram [maxContextMapSymbols]uint32 - var depths [maxContextMapSymbols]byte - var bits [maxContextMapSymbols]uint16 - var i uint - for i := 0; i < int(alphabet_size); i++ { - histogram[i] = 0 - } - - /* Write RLEMAX. */ - writeBits(1, 1, storage_ix, storage) - - writeBits(4, uint64(repeat_code)-1, storage_ix, storage) - histogram[repeat_code] = uint32(num_types) - histogram[0] = 1 - for i = context_bits; i < alphabet_size; i++ { - histogram[i] = 1 - } - - buildAndStoreHuffmanTree(histogram[:], alphabet_size, alphabet_size, tree, depths[:], bits[:], storage_ix, storage) - for i = 0; i < num_types; i++ { - var tmp uint - if i == 0 { - tmp = 0 - } else { - tmp = i + context_bits - 1 - } - var code uint = tmp - writeBits(uint(depths[code]), uint64(bits[code]), storage_ix, storage) - writeBits(uint(depths[repeat_code]), uint64(bits[repeat_code]), storage_ix, storage) - writeBits(repeat_code, uint64(repeat_bits), storage_ix, storage) - } - - /* Write IMTF (inverse-move-to-front) bit. */ - writeBits(1, 1, storage_ix, storage) - } -} - -/* Manages the encoding of one block category (literal, command or distance). */ -type blockEncoder struct { - histogram_length_ uint - num_block_types_ uint - block_types_ []byte - block_lengths_ []uint32 - num_blocks_ uint - block_split_code_ blockSplitCode - block_ix_ uint - block_len_ uint - entropy_ix_ uint - depths_ []byte - bits_ []uint16 -} - -var blockEncoderPool sync.Pool - -func getBlockEncoder(histogram_length uint, num_block_types uint, block_types []byte, block_lengths []uint32, num_blocks uint) *blockEncoder { - self, _ := blockEncoderPool.Get().(*blockEncoder) - - if self != nil { - self.block_ix_ = 0 - self.entropy_ix_ = 0 - self.depths_ = self.depths_[:0] - self.bits_ = self.bits_[:0] - } else { - self = &blockEncoder{} - } - - self.histogram_length_ = histogram_length - self.num_block_types_ = num_block_types - self.block_types_ = block_types - self.block_lengths_ = block_lengths - self.num_blocks_ = num_blocks - initBlockTypeCodeCalculator(&self.block_split_code_.type_code_calculator) - if num_blocks == 0 { - self.block_len_ = 0 - } else { - self.block_len_ = uint(block_lengths[0]) - } - - return self -} - -func cleanupBlockEncoder(self *blockEncoder) { - blockEncoderPool.Put(self) -} - -/* -Creates entropy codes of block lengths and block types and stores them - - to the bit stream. -*/ -func buildAndStoreBlockSwitchEntropyCodes(self *blockEncoder, tree []huffmanTree, storage_ix *uint, storage []byte) { - buildAndStoreBlockSplitCode(self.block_types_, self.block_lengths_, self.num_blocks_, self.num_block_types_, tree, &self.block_split_code_, storage_ix, storage) -} - -/* -Stores the next symbol with the entropy code of the current block type. - - Updates the block type and block length at block boundaries. -*/ -func storeSymbol(self *blockEncoder, symbol uint, storage_ix *uint, storage []byte) { - if self.block_len_ == 0 { - self.block_ix_++ - var block_ix uint = self.block_ix_ - var block_len uint32 = self.block_lengths_[block_ix] - var block_type byte = self.block_types_[block_ix] - self.block_len_ = uint(block_len) - self.entropy_ix_ = uint(block_type) * self.histogram_length_ - storeBlockSwitch(&self.block_split_code_, block_len, block_type, false, storage_ix, storage) - } - - self.block_len_-- - { - var ix uint = self.entropy_ix_ + symbol - writeBits(uint(self.depths_[ix]), uint64(self.bits_[ix]), storage_ix, storage) - } -} - -/* -Stores the next symbol with the entropy code of the current block type and - - context value. - Updates the block type and block length at block boundaries. -*/ -func storeSymbolWithContext(self *blockEncoder, symbol uint, context uint, context_map []uint32, storage_ix *uint, storage []byte, context_bits uint) { - if self.block_len_ == 0 { - self.block_ix_++ - var block_ix uint = self.block_ix_ - var block_len uint32 = self.block_lengths_[block_ix] - var block_type byte = self.block_types_[block_ix] - self.block_len_ = uint(block_len) - self.entropy_ix_ = uint(block_type) << context_bits - storeBlockSwitch(&self.block_split_code_, block_len, block_type, false, storage_ix, storage) - } - - self.block_len_-- - { - var histo_ix uint = uint(context_map[self.entropy_ix_+context]) - var ix uint = histo_ix*self.histogram_length_ + symbol - writeBits(uint(self.depths_[ix]), uint64(self.bits_[ix]), storage_ix, storage) - } -} - -func buildAndStoreEntropyCodesLiteral(self *blockEncoder, histograms []histogramLiteral, histograms_size uint, alphabet_size uint, tree []huffmanTree, storage_ix *uint, storage []byte) { - var table_size uint = histograms_size * self.histogram_length_ - if cap(self.depths_) < int(table_size) { - self.depths_ = make([]byte, table_size) - } else { - self.depths_ = self.depths_[:table_size] - } - if cap(self.bits_) < int(table_size) { - self.bits_ = make([]uint16, table_size) - } else { - self.bits_ = self.bits_[:table_size] - } - { - var i uint - for i = 0; i < histograms_size; i++ { - var ix uint = i * self.histogram_length_ - buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], storage_ix, storage) - } - } -} - -func buildAndStoreEntropyCodesCommand(self *blockEncoder, histograms []histogramCommand, histograms_size uint, alphabet_size uint, tree []huffmanTree, storage_ix *uint, storage []byte) { - var table_size uint = histograms_size * self.histogram_length_ - if cap(self.depths_) < int(table_size) { - self.depths_ = make([]byte, table_size) - } else { - self.depths_ = self.depths_[:table_size] - } - if cap(self.bits_) < int(table_size) { - self.bits_ = make([]uint16, table_size) - } else { - self.bits_ = self.bits_[:table_size] - } - { - var i uint - for i = 0; i < histograms_size; i++ { - var ix uint = i * self.histogram_length_ - buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], storage_ix, storage) - } - } -} - -func buildAndStoreEntropyCodesDistance(self *blockEncoder, histograms []histogramDistance, histograms_size uint, alphabet_size uint, tree []huffmanTree, storage_ix *uint, storage []byte) { - var table_size uint = histograms_size * self.histogram_length_ - if cap(self.depths_) < int(table_size) { - self.depths_ = make([]byte, table_size) - } else { - self.depths_ = self.depths_[:table_size] - } - if cap(self.bits_) < int(table_size) { - self.bits_ = make([]uint16, table_size) - } else { - self.bits_ = self.bits_[:table_size] - } - { - var i uint - for i = 0; i < histograms_size; i++ { - var ix uint = i * self.histogram_length_ - buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], storage_ix, storage) - } - } -} - -func jumpToByteBoundary(storage_ix *uint, storage []byte) { - *storage_ix = (*storage_ix + 7) &^ 7 - storage[*storage_ix>>3] = 0 -} - -func storeMetaBlock(input []byte, start_pos uint, length uint, mask uint, prev_byte byte, prev_byte2 byte, is_last bool, params *encoderParams, literal_context_mode int, commands []command, mb *metaBlockSplit, storage_ix *uint, storage []byte) { - var pos uint = start_pos - var i uint - var num_distance_symbols uint32 = params.dist.alphabet_size - var num_effective_distance_symbols uint32 = num_distance_symbols - var tree []huffmanTree - var literal_context_lut contextLUT = getContextLUT(literal_context_mode) - var dist *distanceParams = ¶ms.dist - if params.large_window && num_effective_distance_symbols > numHistogramDistanceSymbols { - num_effective_distance_symbols = numHistogramDistanceSymbols - } - - storeCompressedMetaBlockHeader(is_last, length, storage_ix, storage) - - tree = make([]huffmanTree, maxHuffmanTreeSize) - literal_enc := getBlockEncoder(numLiteralSymbols, mb.literal_split.num_types, mb.literal_split.types, mb.literal_split.lengths, mb.literal_split.num_blocks) - command_enc := getBlockEncoder(numCommandSymbols, mb.command_split.num_types, mb.command_split.types, mb.command_split.lengths, mb.command_split.num_blocks) - distance_enc := getBlockEncoder(uint(num_effective_distance_symbols), mb.distance_split.num_types, mb.distance_split.types, mb.distance_split.lengths, mb.distance_split.num_blocks) - - buildAndStoreBlockSwitchEntropyCodes(literal_enc, tree, storage_ix, storage) - buildAndStoreBlockSwitchEntropyCodes(command_enc, tree, storage_ix, storage) - buildAndStoreBlockSwitchEntropyCodes(distance_enc, tree, storage_ix, storage) - - writeBits(2, uint64(dist.distance_postfix_bits), storage_ix, storage) - writeBits(4, uint64(dist.num_direct_distance_codes)>>dist.distance_postfix_bits, storage_ix, storage) - for i = 0; i < mb.literal_split.num_types; i++ { - writeBits(2, uint64(literal_context_mode), storage_ix, storage) - } - - if mb.literal_context_map_size == 0 { - storeTrivialContextMap(mb.literal_histograms_size, literalContextBits, tree, storage_ix, storage) - } else { - encodeContextMap(mb.literal_context_map, mb.literal_context_map_size, mb.literal_histograms_size, tree, storage_ix, storage) - } - - if mb.distance_context_map_size == 0 { - storeTrivialContextMap(mb.distance_histograms_size, distanceContextBits, tree, storage_ix, storage) - } else { - encodeContextMap(mb.distance_context_map, mb.distance_context_map_size, mb.distance_histograms_size, tree, storage_ix, storage) - } - - buildAndStoreEntropyCodesLiteral(literal_enc, mb.literal_histograms, mb.literal_histograms_size, numLiteralSymbols, tree, storage_ix, storage) - buildAndStoreEntropyCodesCommand(command_enc, mb.command_histograms, mb.command_histograms_size, numCommandSymbols, tree, storage_ix, storage) - buildAndStoreEntropyCodesDistance(distance_enc, mb.distance_histograms, mb.distance_histograms_size, uint(num_distance_symbols), tree, storage_ix, storage) - tree = nil - - for _, cmd := range commands { - var cmd_code uint = uint(cmd.cmd_prefix_) - storeSymbol(command_enc, cmd_code, storage_ix, storage) - storeCommandExtra(&cmd, storage_ix, storage) - if mb.literal_context_map_size == 0 { - var j uint - for j = uint(cmd.insert_len_); j != 0; j-- { - storeSymbol(literal_enc, uint(input[pos&mask]), storage_ix, storage) - pos++ - } - } else { - var j uint - for j = uint(cmd.insert_len_); j != 0; j-- { - var context uint = uint(getContext(prev_byte, prev_byte2, literal_context_lut)) - var literal byte = input[pos&mask] - storeSymbolWithContext(literal_enc, uint(literal), context, mb.literal_context_map, storage_ix, storage, literalContextBits) - prev_byte2 = prev_byte - prev_byte = literal - pos++ - } - } - - pos += uint(commandCopyLen(&cmd)) - if commandCopyLen(&cmd) != 0 { - prev_byte2 = input[(pos-2)&mask] - prev_byte = input[(pos-1)&mask] - if cmd.cmd_prefix_ >= 128 { - var dist_code uint = uint(cmd.dist_prefix_) & 0x3FF - var distnumextra uint32 = uint32(cmd.dist_prefix_) >> 10 - var distextra uint64 = uint64(cmd.dist_extra_) - if mb.distance_context_map_size == 0 { - storeSymbol(distance_enc, dist_code, storage_ix, storage) - } else { - var context uint = uint(commandDistanceContext(&cmd)) - storeSymbolWithContext(distance_enc, dist_code, context, mb.distance_context_map, storage_ix, storage, distanceContextBits) - } - - writeBits(uint(distnumextra), distextra, storage_ix, storage) - } - } - } - - cleanupBlockEncoder(distance_enc) - cleanupBlockEncoder(command_enc) - cleanupBlockEncoder(literal_enc) - if is_last { - jumpToByteBoundary(storage_ix, storage) - } -} - -func buildHistograms(input []byte, start_pos uint, mask uint, commands []command, lit_histo *histogramLiteral, cmd_histo *histogramCommand, dist_histo *histogramDistance) { - var pos uint = start_pos - for _, cmd := range commands { - var j uint - histogramAddCommand(cmd_histo, uint(cmd.cmd_prefix_)) - for j = uint(cmd.insert_len_); j != 0; j-- { - histogramAddLiteral(lit_histo, uint(input[pos&mask])) - pos++ - } - - pos += uint(commandCopyLen(&cmd)) - if commandCopyLen(&cmd) != 0 && cmd.cmd_prefix_ >= 128 { - histogramAddDistance(dist_histo, uint(cmd.dist_prefix_)&0x3FF) - } - } -} - -func storeDataWithHuffmanCodes(input []byte, start_pos uint, mask uint, commands []command, lit_depth []byte, lit_bits []uint16, cmd_depth []byte, cmd_bits []uint16, dist_depth []byte, dist_bits []uint16, storage_ix *uint, storage []byte) { - var pos uint = start_pos - for _, cmd := range commands { - var cmd_code uint = uint(cmd.cmd_prefix_) - var j uint - writeBits(uint(cmd_depth[cmd_code]), uint64(cmd_bits[cmd_code]), storage_ix, storage) - storeCommandExtra(&cmd, storage_ix, storage) - for j = uint(cmd.insert_len_); j != 0; j-- { - var literal byte = input[pos&mask] - writeBits(uint(lit_depth[literal]), uint64(lit_bits[literal]), storage_ix, storage) - pos++ - } - - pos += uint(commandCopyLen(&cmd)) - if commandCopyLen(&cmd) != 0 && cmd.cmd_prefix_ >= 128 { - var dist_code uint = uint(cmd.dist_prefix_) & 0x3FF - var distnumextra uint32 = uint32(cmd.dist_prefix_) >> 10 - var distextra uint32 = cmd.dist_extra_ - writeBits(uint(dist_depth[dist_code]), uint64(dist_bits[dist_code]), storage_ix, storage) - writeBits(uint(distnumextra), uint64(distextra), storage_ix, storage) - } - } -} - -func storeMetaBlockTrivial(input []byte, start_pos uint, length uint, mask uint, is_last bool, params *encoderParams, commands []command, storage_ix *uint, storage []byte) { - var lit_histo histogramLiteral - var cmd_histo histogramCommand - var dist_histo histogramDistance - var lit_depth [numLiteralSymbols]byte - var lit_bits [numLiteralSymbols]uint16 - var cmd_depth [numCommandSymbols]byte - var cmd_bits [numCommandSymbols]uint16 - var dist_depth [maxSimpleDistanceAlphabetSize]byte - var dist_bits [maxSimpleDistanceAlphabetSize]uint16 - var tree []huffmanTree - var num_distance_symbols uint32 = params.dist.alphabet_size - - storeCompressedMetaBlockHeader(is_last, length, storage_ix, storage) - - histogramClearLiteral(&lit_histo) - histogramClearCommand(&cmd_histo) - histogramClearDistance(&dist_histo) - - buildHistograms(input, start_pos, mask, commands, &lit_histo, &cmd_histo, &dist_histo) - - writeBits(13, 0, storage_ix, storage) - - tree = make([]huffmanTree, maxHuffmanTreeSize) - buildAndStoreHuffmanTree(lit_histo.data_[:], numLiteralSymbols, numLiteralSymbols, tree, lit_depth[:], lit_bits[:], storage_ix, storage) - buildAndStoreHuffmanTree(cmd_histo.data_[:], numCommandSymbols, numCommandSymbols, tree, cmd_depth[:], cmd_bits[:], storage_ix, storage) - buildAndStoreHuffmanTree(dist_histo.data_[:], maxSimpleDistanceAlphabetSize, uint(num_distance_symbols), tree, dist_depth[:], dist_bits[:], storage_ix, storage) - tree = nil - storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], cmd_depth[:], cmd_bits[:], dist_depth[:], dist_bits[:], storage_ix, storage) - if is_last { - jumpToByteBoundary(storage_ix, storage) - } -} - -func storeMetaBlockFast(input []byte, start_pos uint, length uint, mask uint, is_last bool, params *encoderParams, commands []command, storage_ix *uint, storage []byte) { - var num_distance_symbols uint32 = params.dist.alphabet_size - var distance_alphabet_bits uint32 = log2FloorNonZero(uint(num_distance_symbols-1)) + 1 - - storeCompressedMetaBlockHeader(is_last, length, storage_ix, storage) - - writeBits(13, 0, storage_ix, storage) - - if len(commands) <= 128 { - var histogram = [numLiteralSymbols]uint32{0} - var pos uint = start_pos - var num_literals uint = 0 - var lit_depth [numLiteralSymbols]byte - var lit_bits [numLiteralSymbols]uint16 - for _, cmd := range commands { - var j uint - for j = uint(cmd.insert_len_); j != 0; j-- { - histogram[input[pos&mask]]++ - pos++ - } - - num_literals += uint(cmd.insert_len_) - pos += uint(commandCopyLen(&cmd)) - } - - buildAndStoreHuffmanTreeFast(histogram[:], num_literals, /* max_bits = */ - 8, lit_depth[:], lit_bits[:], storage_ix, storage) - - storeStaticCommandHuffmanTree(storage_ix, storage) - storeStaticDistanceHuffmanTree(storage_ix, storage) - storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], kStaticCommandCodeDepth[:], kStaticCommandCodeBits[:], kStaticDistanceCodeDepth[:], kStaticDistanceCodeBits[:], storage_ix, storage) - } else { - var lit_histo histogramLiteral - var cmd_histo histogramCommand - var dist_histo histogramDistance - var lit_depth [numLiteralSymbols]byte - var lit_bits [numLiteralSymbols]uint16 - var cmd_depth [numCommandSymbols]byte - var cmd_bits [numCommandSymbols]uint16 - var dist_depth [maxSimpleDistanceAlphabetSize]byte - var dist_bits [maxSimpleDistanceAlphabetSize]uint16 - histogramClearLiteral(&lit_histo) - histogramClearCommand(&cmd_histo) - histogramClearDistance(&dist_histo) - buildHistograms(input, start_pos, mask, commands, &lit_histo, &cmd_histo, &dist_histo) - buildAndStoreHuffmanTreeFast(lit_histo.data_[:], lit_histo.total_count_, /* max_bits = */ - 8, lit_depth[:], lit_bits[:], storage_ix, storage) - - buildAndStoreHuffmanTreeFast(cmd_histo.data_[:], cmd_histo.total_count_, /* max_bits = */ - 10, cmd_depth[:], cmd_bits[:], storage_ix, storage) - - buildAndStoreHuffmanTreeFast(dist_histo.data_[:], dist_histo.total_count_, /* max_bits = */ - uint(distance_alphabet_bits), dist_depth[:], dist_bits[:], storage_ix, storage) - - storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], cmd_depth[:], cmd_bits[:], dist_depth[:], dist_bits[:], storage_ix, storage) - } - - if is_last { - jumpToByteBoundary(storage_ix, storage) - } -} - -/* -This is for storing uncompressed blocks (simple raw storage of - - bytes-as-bytes). -*/ -func storeUncompressedMetaBlock(is_final_block bool, input []byte, position uint, mask uint, len uint, storage_ix *uint, storage []byte) { - var masked_pos uint = position & mask - storeUncompressedMetaBlockHeader(uint(len), storage_ix, storage) - jumpToByteBoundary(storage_ix, storage) - - if masked_pos+len > mask+1 { - var len1 uint = mask + 1 - masked_pos - copy(storage[*storage_ix>>3:], input[masked_pos:][:len1]) - *storage_ix += len1 << 3 - len -= len1 - masked_pos = 0 - } - - copy(storage[*storage_ix>>3:], input[masked_pos:][:len]) - *storage_ix += uint(len << 3) - - /* We need to clear the next 4 bytes to continue to be - compatible with BrotliWriteBits. */ - writeBitsPrepareStorage(*storage_ix, storage) - - /* Since the uncompressed block itself may not be the final block, add an - empty one after this. */ - if is_final_block { - writeBits(1, 1, storage_ix, storage) /* islast */ - writeBits(1, 1, storage_ix, storage) /* isempty */ - jumpToByteBoundary(storage_ix, storage) - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/cluster.go b/src/vendor/github.com/andybalholm/brotli/cluster.go deleted file mode 100644 index df8a3282..00000000 --- a/src/vendor/github.com/andybalholm/brotli/cluster.go +++ /dev/null @@ -1,30 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Functions for clustering similar histograms together. */ - -type histogramPair struct { - idx1 uint32 - idx2 uint32 - cost_combo float64 - cost_diff float64 -} - -func histogramPairIsLess(p1 *histogramPair, p2 *histogramPair) bool { - if p1.cost_diff != p2.cost_diff { - return p1.cost_diff > p2.cost_diff - } - - return (p1.idx2 - p1.idx1) > (p2.idx2 - p2.idx1) -} - -/* Returns entropy reduction of the context map when we combine two clusters. */ -func clusterCostDiff(size_a uint, size_b uint) float64 { - var size_c uint = size_a + size_b - return float64(size_a)*fastLog2(size_a) + float64(size_b)*fastLog2(size_b) - float64(size_c)*fastLog2(size_c) -} diff --git a/src/vendor/github.com/andybalholm/brotli/cluster_command.go b/src/vendor/github.com/andybalholm/brotli/cluster_command.go deleted file mode 100644 index 45b569bb..00000000 --- a/src/vendor/github.com/andybalholm/brotli/cluster_command.go +++ /dev/null @@ -1,164 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Computes the bit cost reduction by combining out[idx1] and out[idx2] and if - it is below a threshold, stores the pair (idx1, idx2) in the *pairs queue. */ -func compareAndPushToQueueCommand(out []histogramCommand, cluster_size []uint32, idx1 uint32, idx2 uint32, max_num_pairs uint, pairs []histogramPair, num_pairs *uint) { - var is_good_pair bool = false - var p histogramPair - p.idx2 = 0 - p.idx1 = p.idx2 - p.cost_combo = 0 - p.cost_diff = p.cost_combo - if idx1 == idx2 { - return - } - - if idx2 < idx1 { - var t uint32 = idx2 - idx2 = idx1 - idx1 = t - } - - p.idx1 = idx1 - p.idx2 = idx2 - p.cost_diff = 0.5 * clusterCostDiff(uint(cluster_size[idx1]), uint(cluster_size[idx2])) - p.cost_diff -= out[idx1].bit_cost_ - p.cost_diff -= out[idx2].bit_cost_ - - if out[idx1].total_count_ == 0 { - p.cost_combo = out[idx2].bit_cost_ - is_good_pair = true - } else if out[idx2].total_count_ == 0 { - p.cost_combo = out[idx1].bit_cost_ - is_good_pair = true - } else { - var threshold float64 - if *num_pairs == 0 { - threshold = 1e99 - } else { - threshold = brotli_max_double(0.0, pairs[0].cost_diff) - } - var combo histogramCommand = out[idx1] - var cost_combo float64 - histogramAddHistogramCommand(&combo, &out[idx2]) - cost_combo = populationCostCommand(&combo) - if cost_combo < threshold-p.cost_diff { - p.cost_combo = cost_combo - is_good_pair = true - } - } - - if is_good_pair { - p.cost_diff += p.cost_combo - if *num_pairs > 0 && histogramPairIsLess(&pairs[0], &p) { - /* Replace the top of the queue if needed. */ - if *num_pairs < max_num_pairs { - pairs[*num_pairs] = pairs[0] - (*num_pairs)++ - } - - pairs[0] = p - } else if *num_pairs < max_num_pairs { - pairs[*num_pairs] = p - (*num_pairs)++ - } - } -} - -func histogramCombineCommand(out []histogramCommand, cluster_size []uint32, symbols []uint32, clusters []uint32, pairs []histogramPair, num_clusters uint, symbols_size uint, max_clusters uint, max_num_pairs uint) uint { - var cost_diff_threshold float64 = 0.0 - var min_cluster_size uint = 1 - var num_pairs uint = 0 - { - /* We maintain a vector of histogram pairs, with the property that the pair - with the maximum bit cost reduction is the first. */ - var idx1 uint - for idx1 = 0; idx1 < num_clusters; idx1++ { - var idx2 uint - for idx2 = idx1 + 1; idx2 < num_clusters; idx2++ { - compareAndPushToQueueCommand(out, cluster_size, clusters[idx1], clusters[idx2], max_num_pairs, pairs[0:], &num_pairs) - } - } - } - - for num_clusters > min_cluster_size { - var best_idx1 uint32 - var best_idx2 uint32 - var i uint - if pairs[0].cost_diff >= cost_diff_threshold { - cost_diff_threshold = 1e99 - min_cluster_size = max_clusters - continue - } - - /* Take the best pair from the top of heap. */ - best_idx1 = pairs[0].idx1 - - best_idx2 = pairs[0].idx2 - histogramAddHistogramCommand(&out[best_idx1], &out[best_idx2]) - out[best_idx1].bit_cost_ = pairs[0].cost_combo - cluster_size[best_idx1] += cluster_size[best_idx2] - for i = 0; i < symbols_size; i++ { - if symbols[i] == best_idx2 { - symbols[i] = best_idx1 - } - } - - for i = 0; i < num_clusters; i++ { - if clusters[i] == best_idx2 { - copy(clusters[i:], clusters[i+1:][:num_clusters-i-1]) - break - } - } - - num_clusters-- - { - /* Remove pairs intersecting the just combined best pair. */ - var copy_to_idx uint = 0 - for i = 0; i < num_pairs; i++ { - var p *histogramPair = &pairs[i] - if p.idx1 == best_idx1 || p.idx2 == best_idx1 || p.idx1 == best_idx2 || p.idx2 == best_idx2 { - /* Remove invalid pair from the queue. */ - continue - } - - if histogramPairIsLess(&pairs[0], p) { - /* Replace the top of the queue if needed. */ - var front histogramPair = pairs[0] - pairs[0] = *p - pairs[copy_to_idx] = front - } else { - pairs[copy_to_idx] = *p - } - - copy_to_idx++ - } - - num_pairs = copy_to_idx - } - - /* Push new pairs formed with the combined histogram to the heap. */ - for i = 0; i < num_clusters; i++ { - compareAndPushToQueueCommand(out, cluster_size, best_idx1, clusters[i], max_num_pairs, pairs[0:], &num_pairs) - } - } - - return num_clusters -} - -/* What is the bit cost of moving histogram from cur_symbol to candidate. */ -func histogramBitCostDistanceCommand(histogram *histogramCommand, candidate *histogramCommand) float64 { - if histogram.total_count_ == 0 { - return 0.0 - } else { - var tmp histogramCommand = *histogram - histogramAddHistogramCommand(&tmp, candidate) - return populationCostCommand(&tmp) - candidate.bit_cost_ - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/cluster_distance.go b/src/vendor/github.com/andybalholm/brotli/cluster_distance.go deleted file mode 100644 index 1aaa86e6..00000000 --- a/src/vendor/github.com/andybalholm/brotli/cluster_distance.go +++ /dev/null @@ -1,326 +0,0 @@ -package brotli - -import "math" - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Computes the bit cost reduction by combining out[idx1] and out[idx2] and if - it is below a threshold, stores the pair (idx1, idx2) in the *pairs queue. */ -func compareAndPushToQueueDistance(out []histogramDistance, cluster_size []uint32, idx1 uint32, idx2 uint32, max_num_pairs uint, pairs []histogramPair, num_pairs *uint) { - var is_good_pair bool = false - var p histogramPair - p.idx2 = 0 - p.idx1 = p.idx2 - p.cost_combo = 0 - p.cost_diff = p.cost_combo - if idx1 == idx2 { - return - } - - if idx2 < idx1 { - var t uint32 = idx2 - idx2 = idx1 - idx1 = t - } - - p.idx1 = idx1 - p.idx2 = idx2 - p.cost_diff = 0.5 * clusterCostDiff(uint(cluster_size[idx1]), uint(cluster_size[idx2])) - p.cost_diff -= out[idx1].bit_cost_ - p.cost_diff -= out[idx2].bit_cost_ - - if out[idx1].total_count_ == 0 { - p.cost_combo = out[idx2].bit_cost_ - is_good_pair = true - } else if out[idx2].total_count_ == 0 { - p.cost_combo = out[idx1].bit_cost_ - is_good_pair = true - } else { - var threshold float64 - if *num_pairs == 0 { - threshold = 1e99 - } else { - threshold = brotli_max_double(0.0, pairs[0].cost_diff) - } - var combo histogramDistance = out[idx1] - var cost_combo float64 - histogramAddHistogramDistance(&combo, &out[idx2]) - cost_combo = populationCostDistance(&combo) - if cost_combo < threshold-p.cost_diff { - p.cost_combo = cost_combo - is_good_pair = true - } - } - - if is_good_pair { - p.cost_diff += p.cost_combo - if *num_pairs > 0 && histogramPairIsLess(&pairs[0], &p) { - /* Replace the top of the queue if needed. */ - if *num_pairs < max_num_pairs { - pairs[*num_pairs] = pairs[0] - (*num_pairs)++ - } - - pairs[0] = p - } else if *num_pairs < max_num_pairs { - pairs[*num_pairs] = p - (*num_pairs)++ - } - } -} - -func histogramCombineDistance(out []histogramDistance, cluster_size []uint32, symbols []uint32, clusters []uint32, pairs []histogramPair, num_clusters uint, symbols_size uint, max_clusters uint, max_num_pairs uint) uint { - var cost_diff_threshold float64 = 0.0 - var min_cluster_size uint = 1 - var num_pairs uint = 0 - { - /* We maintain a vector of histogram pairs, with the property that the pair - with the maximum bit cost reduction is the first. */ - var idx1 uint - for idx1 = 0; idx1 < num_clusters; idx1++ { - var idx2 uint - for idx2 = idx1 + 1; idx2 < num_clusters; idx2++ { - compareAndPushToQueueDistance(out, cluster_size, clusters[idx1], clusters[idx2], max_num_pairs, pairs[0:], &num_pairs) - } - } - } - - for num_clusters > min_cluster_size { - var best_idx1 uint32 - var best_idx2 uint32 - var i uint - if pairs[0].cost_diff >= cost_diff_threshold { - cost_diff_threshold = 1e99 - min_cluster_size = max_clusters - continue - } - - /* Take the best pair from the top of heap. */ - best_idx1 = pairs[0].idx1 - - best_idx2 = pairs[0].idx2 - histogramAddHistogramDistance(&out[best_idx1], &out[best_idx2]) - out[best_idx1].bit_cost_ = pairs[0].cost_combo - cluster_size[best_idx1] += cluster_size[best_idx2] - for i = 0; i < symbols_size; i++ { - if symbols[i] == best_idx2 { - symbols[i] = best_idx1 - } - } - - for i = 0; i < num_clusters; i++ { - if clusters[i] == best_idx2 { - copy(clusters[i:], clusters[i+1:][:num_clusters-i-1]) - break - } - } - - num_clusters-- - { - /* Remove pairs intersecting the just combined best pair. */ - var copy_to_idx uint = 0 - for i = 0; i < num_pairs; i++ { - var p *histogramPair = &pairs[i] - if p.idx1 == best_idx1 || p.idx2 == best_idx1 || p.idx1 == best_idx2 || p.idx2 == best_idx2 { - /* Remove invalid pair from the queue. */ - continue - } - - if histogramPairIsLess(&pairs[0], p) { - /* Replace the top of the queue if needed. */ - var front histogramPair = pairs[0] - pairs[0] = *p - pairs[copy_to_idx] = front - } else { - pairs[copy_to_idx] = *p - } - - copy_to_idx++ - } - - num_pairs = copy_to_idx - } - - /* Push new pairs formed with the combined histogram to the heap. */ - for i = 0; i < num_clusters; i++ { - compareAndPushToQueueDistance(out, cluster_size, best_idx1, clusters[i], max_num_pairs, pairs[0:], &num_pairs) - } - } - - return num_clusters -} - -/* What is the bit cost of moving histogram from cur_symbol to candidate. */ -func histogramBitCostDistanceDistance(histogram *histogramDistance, candidate *histogramDistance) float64 { - if histogram.total_count_ == 0 { - return 0.0 - } else { - var tmp histogramDistance = *histogram - histogramAddHistogramDistance(&tmp, candidate) - return populationCostDistance(&tmp) - candidate.bit_cost_ - } -} - -/* Find the best 'out' histogram for each of the 'in' histograms. - When called, clusters[0..num_clusters) contains the unique values from - symbols[0..in_size), but this property is not preserved in this function. - Note: we assume that out[]->bit_cost_ is already up-to-date. */ -func histogramRemapDistance(in []histogramDistance, in_size uint, clusters []uint32, num_clusters uint, out []histogramDistance, symbols []uint32) { - var i uint - for i = 0; i < in_size; i++ { - var best_out uint32 - if i == 0 { - best_out = symbols[0] - } else { - best_out = symbols[i-1] - } - var best_bits float64 = histogramBitCostDistanceDistance(&in[i], &out[best_out]) - var j uint - for j = 0; j < num_clusters; j++ { - var cur_bits float64 = histogramBitCostDistanceDistance(&in[i], &out[clusters[j]]) - if cur_bits < best_bits { - best_bits = cur_bits - best_out = clusters[j] - } - } - - symbols[i] = best_out - } - - /* Recompute each out based on raw and symbols. */ - for i = 0; i < num_clusters; i++ { - histogramClearDistance(&out[clusters[i]]) - } - - for i = 0; i < in_size; i++ { - histogramAddHistogramDistance(&out[symbols[i]], &in[i]) - } -} - -/* Reorders elements of the out[0..length) array and changes values in - symbols[0..length) array in the following way: - * when called, symbols[] contains indexes into out[], and has N unique - values (possibly N < length) - * on return, symbols'[i] = f(symbols[i]) and - out'[symbols'[i]] = out[symbols[i]], for each 0 <= i < length, - where f is a bijection between the range of symbols[] and [0..N), and - the first occurrences of values in symbols'[i] come in consecutive - increasing order. - Returns N, the number of unique values in symbols[]. */ - -var histogramReindexDistance_kInvalidIndex uint32 = math.MaxUint32 - -func histogramReindexDistance(out []histogramDistance, symbols []uint32, length uint) uint { - var new_index []uint32 = make([]uint32, length) - var next_index uint32 - var tmp []histogramDistance - var i uint - for i = 0; i < length; i++ { - new_index[i] = histogramReindexDistance_kInvalidIndex - } - - next_index = 0 - for i = 0; i < length; i++ { - if new_index[symbols[i]] == histogramReindexDistance_kInvalidIndex { - new_index[symbols[i]] = next_index - next_index++ - } - } - - /* TODO: by using idea of "cycle-sort" we can avoid allocation of - tmp and reduce the number of copying by the factor of 2. */ - tmp = make([]histogramDistance, next_index) - - next_index = 0 - for i = 0; i < length; i++ { - if new_index[symbols[i]] == next_index { - tmp[next_index] = out[symbols[i]] - next_index++ - } - - symbols[i] = new_index[symbols[i]] - } - - new_index = nil - for i = 0; uint32(i) < next_index; i++ { - out[i] = tmp[i] - } - - tmp = nil - return uint(next_index) -} - -func clusterHistogramsDistance(in []histogramDistance, in_size uint, max_histograms uint, out []histogramDistance, out_size *uint, histogram_symbols []uint32) { - var cluster_size []uint32 = make([]uint32, in_size) - var clusters []uint32 = make([]uint32, in_size) - var num_clusters uint = 0 - var max_input_histograms uint = 64 - var pairs_capacity uint = max_input_histograms * max_input_histograms / 2 - var pairs []histogramPair = make([]histogramPair, (pairs_capacity + 1)) - var i uint - - /* For the first pass of clustering, we allow all pairs. */ - for i = 0; i < in_size; i++ { - cluster_size[i] = 1 - } - - for i = 0; i < in_size; i++ { - out[i] = in[i] - out[i].bit_cost_ = populationCostDistance(&in[i]) - histogram_symbols[i] = uint32(i) - } - - for i = 0; i < in_size; i += max_input_histograms { - var num_to_combine uint = brotli_min_size_t(in_size-i, max_input_histograms) - var num_new_clusters uint - var j uint - for j = 0; j < num_to_combine; j++ { - clusters[num_clusters+j] = uint32(i + j) - } - - num_new_clusters = histogramCombineDistance(out, cluster_size, histogram_symbols[i:], clusters[num_clusters:], pairs, num_to_combine, num_to_combine, max_histograms, pairs_capacity) - num_clusters += num_new_clusters - } - { - /* For the second pass, we limit the total number of histogram pairs. - After this limit is reached, we only keep searching for the best pair. */ - var max_num_pairs uint = brotli_min_size_t(64*num_clusters, (num_clusters/2)*num_clusters) - if pairs_capacity < (max_num_pairs + 1) { - var _new_size uint - if pairs_capacity == 0 { - _new_size = max_num_pairs + 1 - } else { - _new_size = pairs_capacity - } - var new_array []histogramPair - for _new_size < (max_num_pairs + 1) { - _new_size *= 2 - } - new_array = make([]histogramPair, _new_size) - if pairs_capacity != 0 { - copy(new_array, pairs[:pairs_capacity]) - } - - pairs = new_array - pairs_capacity = _new_size - } - - /* Collapse similar histograms. */ - num_clusters = histogramCombineDistance(out, cluster_size, histogram_symbols, clusters, pairs, num_clusters, in_size, max_histograms, max_num_pairs) - } - - pairs = nil - cluster_size = nil - - /* Find the optimal map from original histograms to the final ones. */ - histogramRemapDistance(in, in_size, clusters, num_clusters, out, histogram_symbols) - - clusters = nil - - /* Convert the context map to a canonical form. */ - *out_size = histogramReindexDistance(out, histogram_symbols, in_size) -} diff --git a/src/vendor/github.com/andybalholm/brotli/cluster_literal.go b/src/vendor/github.com/andybalholm/brotli/cluster_literal.go deleted file mode 100644 index 6ba66f31..00000000 --- a/src/vendor/github.com/andybalholm/brotli/cluster_literal.go +++ /dev/null @@ -1,326 +0,0 @@ -package brotli - -import "math" - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Computes the bit cost reduction by combining out[idx1] and out[idx2] and if - it is below a threshold, stores the pair (idx1, idx2) in the *pairs queue. */ -func compareAndPushToQueueLiteral(out []histogramLiteral, cluster_size []uint32, idx1 uint32, idx2 uint32, max_num_pairs uint, pairs []histogramPair, num_pairs *uint) { - var is_good_pair bool = false - var p histogramPair - p.idx2 = 0 - p.idx1 = p.idx2 - p.cost_combo = 0 - p.cost_diff = p.cost_combo - if idx1 == idx2 { - return - } - - if idx2 < idx1 { - var t uint32 = idx2 - idx2 = idx1 - idx1 = t - } - - p.idx1 = idx1 - p.idx2 = idx2 - p.cost_diff = 0.5 * clusterCostDiff(uint(cluster_size[idx1]), uint(cluster_size[idx2])) - p.cost_diff -= out[idx1].bit_cost_ - p.cost_diff -= out[idx2].bit_cost_ - - if out[idx1].total_count_ == 0 { - p.cost_combo = out[idx2].bit_cost_ - is_good_pair = true - } else if out[idx2].total_count_ == 0 { - p.cost_combo = out[idx1].bit_cost_ - is_good_pair = true - } else { - var threshold float64 - if *num_pairs == 0 { - threshold = 1e99 - } else { - threshold = brotli_max_double(0.0, pairs[0].cost_diff) - } - var combo histogramLiteral = out[idx1] - var cost_combo float64 - histogramAddHistogramLiteral(&combo, &out[idx2]) - cost_combo = populationCostLiteral(&combo) - if cost_combo < threshold-p.cost_diff { - p.cost_combo = cost_combo - is_good_pair = true - } - } - - if is_good_pair { - p.cost_diff += p.cost_combo - if *num_pairs > 0 && histogramPairIsLess(&pairs[0], &p) { - /* Replace the top of the queue if needed. */ - if *num_pairs < max_num_pairs { - pairs[*num_pairs] = pairs[0] - (*num_pairs)++ - } - - pairs[0] = p - } else if *num_pairs < max_num_pairs { - pairs[*num_pairs] = p - (*num_pairs)++ - } - } -} - -func histogramCombineLiteral(out []histogramLiteral, cluster_size []uint32, symbols []uint32, clusters []uint32, pairs []histogramPair, num_clusters uint, symbols_size uint, max_clusters uint, max_num_pairs uint) uint { - var cost_diff_threshold float64 = 0.0 - var min_cluster_size uint = 1 - var num_pairs uint = 0 - { - /* We maintain a vector of histogram pairs, with the property that the pair - with the maximum bit cost reduction is the first. */ - var idx1 uint - for idx1 = 0; idx1 < num_clusters; idx1++ { - var idx2 uint - for idx2 = idx1 + 1; idx2 < num_clusters; idx2++ { - compareAndPushToQueueLiteral(out, cluster_size, clusters[idx1], clusters[idx2], max_num_pairs, pairs[0:], &num_pairs) - } - } - } - - for num_clusters > min_cluster_size { - var best_idx1 uint32 - var best_idx2 uint32 - var i uint - if pairs[0].cost_diff >= cost_diff_threshold { - cost_diff_threshold = 1e99 - min_cluster_size = max_clusters - continue - } - - /* Take the best pair from the top of heap. */ - best_idx1 = pairs[0].idx1 - - best_idx2 = pairs[0].idx2 - histogramAddHistogramLiteral(&out[best_idx1], &out[best_idx2]) - out[best_idx1].bit_cost_ = pairs[0].cost_combo - cluster_size[best_idx1] += cluster_size[best_idx2] - for i = 0; i < symbols_size; i++ { - if symbols[i] == best_idx2 { - symbols[i] = best_idx1 - } - } - - for i = 0; i < num_clusters; i++ { - if clusters[i] == best_idx2 { - copy(clusters[i:], clusters[i+1:][:num_clusters-i-1]) - break - } - } - - num_clusters-- - { - /* Remove pairs intersecting the just combined best pair. */ - var copy_to_idx uint = 0 - for i = 0; i < num_pairs; i++ { - var p *histogramPair = &pairs[i] - if p.idx1 == best_idx1 || p.idx2 == best_idx1 || p.idx1 == best_idx2 || p.idx2 == best_idx2 { - /* Remove invalid pair from the queue. */ - continue - } - - if histogramPairIsLess(&pairs[0], p) { - /* Replace the top of the queue if needed. */ - var front histogramPair = pairs[0] - pairs[0] = *p - pairs[copy_to_idx] = front - } else { - pairs[copy_to_idx] = *p - } - - copy_to_idx++ - } - - num_pairs = copy_to_idx - } - - /* Push new pairs formed with the combined histogram to the heap. */ - for i = 0; i < num_clusters; i++ { - compareAndPushToQueueLiteral(out, cluster_size, best_idx1, clusters[i], max_num_pairs, pairs[0:], &num_pairs) - } - } - - return num_clusters -} - -/* What is the bit cost of moving histogram from cur_symbol to candidate. */ -func histogramBitCostDistanceLiteral(histogram *histogramLiteral, candidate *histogramLiteral) float64 { - if histogram.total_count_ == 0 { - return 0.0 - } else { - var tmp histogramLiteral = *histogram - histogramAddHistogramLiteral(&tmp, candidate) - return populationCostLiteral(&tmp) - candidate.bit_cost_ - } -} - -/* Find the best 'out' histogram for each of the 'in' histograms. - When called, clusters[0..num_clusters) contains the unique values from - symbols[0..in_size), but this property is not preserved in this function. - Note: we assume that out[]->bit_cost_ is already up-to-date. */ -func histogramRemapLiteral(in []histogramLiteral, in_size uint, clusters []uint32, num_clusters uint, out []histogramLiteral, symbols []uint32) { - var i uint - for i = 0; i < in_size; i++ { - var best_out uint32 - if i == 0 { - best_out = symbols[0] - } else { - best_out = symbols[i-1] - } - var best_bits float64 = histogramBitCostDistanceLiteral(&in[i], &out[best_out]) - var j uint - for j = 0; j < num_clusters; j++ { - var cur_bits float64 = histogramBitCostDistanceLiteral(&in[i], &out[clusters[j]]) - if cur_bits < best_bits { - best_bits = cur_bits - best_out = clusters[j] - } - } - - symbols[i] = best_out - } - - /* Recompute each out based on raw and symbols. */ - for i = 0; i < num_clusters; i++ { - histogramClearLiteral(&out[clusters[i]]) - } - - for i = 0; i < in_size; i++ { - histogramAddHistogramLiteral(&out[symbols[i]], &in[i]) - } -} - -/* Reorders elements of the out[0..length) array and changes values in - symbols[0..length) array in the following way: - * when called, symbols[] contains indexes into out[], and has N unique - values (possibly N < length) - * on return, symbols'[i] = f(symbols[i]) and - out'[symbols'[i]] = out[symbols[i]], for each 0 <= i < length, - where f is a bijection between the range of symbols[] and [0..N), and - the first occurrences of values in symbols'[i] come in consecutive - increasing order. - Returns N, the number of unique values in symbols[]. */ - -var histogramReindexLiteral_kInvalidIndex uint32 = math.MaxUint32 - -func histogramReindexLiteral(out []histogramLiteral, symbols []uint32, length uint) uint { - var new_index []uint32 = make([]uint32, length) - var next_index uint32 - var tmp []histogramLiteral - var i uint - for i = 0; i < length; i++ { - new_index[i] = histogramReindexLiteral_kInvalidIndex - } - - next_index = 0 - for i = 0; i < length; i++ { - if new_index[symbols[i]] == histogramReindexLiteral_kInvalidIndex { - new_index[symbols[i]] = next_index - next_index++ - } - } - - /* TODO: by using idea of "cycle-sort" we can avoid allocation of - tmp and reduce the number of copying by the factor of 2. */ - tmp = make([]histogramLiteral, next_index) - - next_index = 0 - for i = 0; i < length; i++ { - if new_index[symbols[i]] == next_index { - tmp[next_index] = out[symbols[i]] - next_index++ - } - - symbols[i] = new_index[symbols[i]] - } - - new_index = nil - for i = 0; uint32(i) < next_index; i++ { - out[i] = tmp[i] - } - - tmp = nil - return uint(next_index) -} - -func clusterHistogramsLiteral(in []histogramLiteral, in_size uint, max_histograms uint, out []histogramLiteral, out_size *uint, histogram_symbols []uint32) { - var cluster_size []uint32 = make([]uint32, in_size) - var clusters []uint32 = make([]uint32, in_size) - var num_clusters uint = 0 - var max_input_histograms uint = 64 - var pairs_capacity uint = max_input_histograms * max_input_histograms / 2 - var pairs []histogramPair = make([]histogramPair, (pairs_capacity + 1)) - var i uint - - /* For the first pass of clustering, we allow all pairs. */ - for i = 0; i < in_size; i++ { - cluster_size[i] = 1 - } - - for i = 0; i < in_size; i++ { - out[i] = in[i] - out[i].bit_cost_ = populationCostLiteral(&in[i]) - histogram_symbols[i] = uint32(i) - } - - for i = 0; i < in_size; i += max_input_histograms { - var num_to_combine uint = brotli_min_size_t(in_size-i, max_input_histograms) - var num_new_clusters uint - var j uint - for j = 0; j < num_to_combine; j++ { - clusters[num_clusters+j] = uint32(i + j) - } - - num_new_clusters = histogramCombineLiteral(out, cluster_size, histogram_symbols[i:], clusters[num_clusters:], pairs, num_to_combine, num_to_combine, max_histograms, pairs_capacity) - num_clusters += num_new_clusters - } - { - /* For the second pass, we limit the total number of histogram pairs. - After this limit is reached, we only keep searching for the best pair. */ - var max_num_pairs uint = brotli_min_size_t(64*num_clusters, (num_clusters/2)*num_clusters) - if pairs_capacity < (max_num_pairs + 1) { - var _new_size uint - if pairs_capacity == 0 { - _new_size = max_num_pairs + 1 - } else { - _new_size = pairs_capacity - } - var new_array []histogramPair - for _new_size < (max_num_pairs + 1) { - _new_size *= 2 - } - new_array = make([]histogramPair, _new_size) - if pairs_capacity != 0 { - copy(new_array, pairs[:pairs_capacity]) - } - - pairs = new_array - pairs_capacity = _new_size - } - - /* Collapse similar histograms. */ - num_clusters = histogramCombineLiteral(out, cluster_size, histogram_symbols, clusters, pairs, num_clusters, in_size, max_histograms, max_num_pairs) - } - - pairs = nil - cluster_size = nil - - /* Find the optimal map from original histograms to the final ones. */ - histogramRemapLiteral(in, in_size, clusters, num_clusters, out, histogram_symbols) - - clusters = nil - - /* Convert the context map to a canonical form. */ - *out_size = histogramReindexLiteral(out, histogram_symbols, in_size) -} diff --git a/src/vendor/github.com/andybalholm/brotli/command.go b/src/vendor/github.com/andybalholm/brotli/command.go deleted file mode 100644 index b1662a55..00000000 --- a/src/vendor/github.com/andybalholm/brotli/command.go +++ /dev/null @@ -1,254 +0,0 @@ -package brotli - -var kInsBase = []uint32{ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 8, - 10, - 14, - 18, - 26, - 34, - 50, - 66, - 98, - 130, - 194, - 322, - 578, - 1090, - 2114, - 6210, - 22594, -} - -var kInsExtra = []uint32{ - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 2, - 2, - 3, - 3, - 4, - 4, - 5, - 5, - 6, - 7, - 8, - 9, - 10, - 12, - 14, - 24, -} - -var kCopyBase = []uint32{ - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 12, - 14, - 18, - 22, - 30, - 38, - 54, - 70, - 102, - 134, - 198, - 326, - 582, - 1094, - 2118, -} - -var kCopyExtra = []uint32{ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 2, - 2, - 3, - 3, - 4, - 4, - 5, - 5, - 6, - 7, - 8, - 9, - 10, - 24, -} - -func getInsertLengthCode(insertlen uint) uint16 { - if insertlen < 6 { - return uint16(insertlen) - } else if insertlen < 130 { - var nbits uint32 = log2FloorNonZero(insertlen-2) - 1 - return uint16((nbits << 1) + uint32((insertlen-2)>>nbits) + 2) - } else if insertlen < 2114 { - return uint16(log2FloorNonZero(insertlen-66) + 10) - } else if insertlen < 6210 { - return 21 - } else if insertlen < 22594 { - return 22 - } else { - return 23 - } -} - -func getCopyLengthCode(copylen uint) uint16 { - if copylen < 10 { - return uint16(copylen - 2) - } else if copylen < 134 { - var nbits uint32 = log2FloorNonZero(copylen-6) - 1 - return uint16((nbits << 1) + uint32((copylen-6)>>nbits) + 4) - } else if copylen < 2118 { - return uint16(log2FloorNonZero(copylen-70) + 12) - } else { - return 23 - } -} - -func combineLengthCodes(inscode uint16, copycode uint16, use_last_distance bool) uint16 { - var bits64 uint16 = uint16(copycode&0x7 | (inscode&0x7)<<3) - if use_last_distance && inscode < 8 && copycode < 16 { - if copycode < 8 { - return bits64 - } else { - return bits64 | 64 - } - } else { - /* Specification: 5 Encoding of ... (last table) */ - /* offset = 2 * index, where index is in range [0..8] */ - var offset uint32 = 2 * ((uint32(copycode) >> 3) + 3*(uint32(inscode)>>3)) - - /* All values in specification are K * 64, - where K = [2, 3, 6, 4, 5, 8, 7, 9, 10], - i + 1 = [1, 2, 3, 4, 5, 6, 7, 8, 9], - K - i - 1 = [1, 1, 3, 0, 0, 2, 0, 1, 2] = D. - All values in D require only 2 bits to encode. - Magic constant is shifted 6 bits left, to avoid final multiplication. */ - offset = (offset << 5) + 0x40 + ((0x520D40 >> offset) & 0xC0) - - return uint16(offset | uint32(bits64)) - } -} - -func getLengthCode(insertlen uint, copylen uint, use_last_distance bool, code *uint16) { - var inscode uint16 = getInsertLengthCode(insertlen) - var copycode uint16 = getCopyLengthCode(copylen) - *code = combineLengthCodes(inscode, copycode, use_last_distance) -} - -func getInsertBase(inscode uint16) uint32 { - return kInsBase[inscode] -} - -func getInsertExtra(inscode uint16) uint32 { - return kInsExtra[inscode] -} - -func getCopyBase(copycode uint16) uint32 { - return kCopyBase[copycode] -} - -func getCopyExtra(copycode uint16) uint32 { - return kCopyExtra[copycode] -} - -type command struct { - insert_len_ uint32 - copy_len_ uint32 - dist_extra_ uint32 - cmd_prefix_ uint16 - dist_prefix_ uint16 -} - -/* distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1. */ -func makeCommand(dist *distanceParams, insertlen uint, copylen uint, copylen_code_delta int, distance_code uint) (cmd command) { - /* Don't rely on signed int representation, use honest casts. */ - var delta uint32 = uint32(byte(int8(copylen_code_delta))) - cmd.insert_len_ = uint32(insertlen) - cmd.copy_len_ = uint32(uint32(copylen) | delta<<25) - - /* The distance prefix and extra bits are stored in this Command as if - npostfix and ndirect were 0, they are only recomputed later after the - clustering if needed. */ - prefixEncodeCopyDistance(distance_code, uint(dist.num_direct_distance_codes), uint(dist.distance_postfix_bits), &cmd.dist_prefix_, &cmd.dist_extra_) - getLengthCode(insertlen, uint(int(copylen)+copylen_code_delta), (cmd.dist_prefix_&0x3FF == 0), &cmd.cmd_prefix_) - - return cmd -} - -func makeInsertCommand(insertlen uint) (cmd command) { - cmd.insert_len_ = uint32(insertlen) - cmd.copy_len_ = 4 << 25 - cmd.dist_extra_ = 0 - cmd.dist_prefix_ = numDistanceShortCodes - getLengthCode(insertlen, 4, false, &cmd.cmd_prefix_) - return cmd -} - -func commandRestoreDistanceCode(self *command, dist *distanceParams) uint32 { - if uint32(self.dist_prefix_&0x3FF) < numDistanceShortCodes+dist.num_direct_distance_codes { - return uint32(self.dist_prefix_) & 0x3FF - } else { - var dcode uint32 = uint32(self.dist_prefix_) & 0x3FF - var nbits uint32 = uint32(self.dist_prefix_) >> 10 - var extra uint32 = self.dist_extra_ - var postfix_mask uint32 = (1 << dist.distance_postfix_bits) - 1 - var hcode uint32 = (dcode - dist.num_direct_distance_codes - numDistanceShortCodes) >> dist.distance_postfix_bits - var lcode uint32 = (dcode - dist.num_direct_distance_codes - numDistanceShortCodes) & postfix_mask - var offset uint32 = ((2 + (hcode & 1)) << nbits) - 4 - return ((offset + extra) << dist.distance_postfix_bits) + lcode + dist.num_direct_distance_codes + numDistanceShortCodes - } -} - -func commandDistanceContext(self *command) uint32 { - var r uint32 = uint32(self.cmd_prefix_) >> 6 - var c uint32 = uint32(self.cmd_prefix_) & 7 - if (r == 0 || r == 2 || r == 4 || r == 7) && (c <= 2) { - return c - } - - return 3 -} - -func commandCopyLen(self *command) uint32 { - return self.copy_len_ & 0x1FFFFFF -} - -func commandCopyLenCode(self *command) uint32 { - var modifier uint32 = self.copy_len_ >> 25 - var delta int32 = int32(int8(byte(modifier | (modifier&0x40)<<1))) - return uint32(int32(self.copy_len_&0x1FFFFFF) + delta) -} diff --git a/src/vendor/github.com/andybalholm/brotli/compress_fragment.go b/src/vendor/github.com/andybalholm/brotli/compress_fragment.go deleted file mode 100644 index c9bd0577..00000000 --- a/src/vendor/github.com/andybalholm/brotli/compress_fragment.go +++ /dev/null @@ -1,834 +0,0 @@ -package brotli - -import "encoding/binary" - -/* Copyright 2015 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Function for fast encoding of an input fragment, independently from the input - history. This function uses one-pass processing: when we find a backward - match, we immediately emit the corresponding command and literal codes to - the bit stream. - - Adapted from the CompressFragment() function in - https://github.com/google/snappy/blob/master/snappy.cc */ - -const maxDistance_compress_fragment = 262128 - -func hash5(p []byte, shift uint) uint32 { - var h uint64 = (binary.LittleEndian.Uint64(p) << 24) * uint64(kHashMul32) - return uint32(h >> shift) -} - -func hashBytesAtOffset5(v uint64, offset int, shift uint) uint32 { - assert(offset >= 0) - assert(offset <= 3) - { - var h uint64 = ((v >> uint(8*offset)) << 24) * uint64(kHashMul32) - return uint32(h >> shift) - } -} - -func isMatch5(p1 []byte, p2 []byte) bool { - return binary.LittleEndian.Uint32(p1) == binary.LittleEndian.Uint32(p2) && - p1[4] == p2[4] -} - -/* Builds a literal prefix code into "depths" and "bits" based on the statistics - of the "input" string and stores it into the bit stream. - Note that the prefix code here is built from the pre-LZ77 input, therefore - we can only approximate the statistics of the actual literal stream. - Moreover, for long inputs we build a histogram from a sample of the input - and thus have to assign a non-zero depth for each literal. - Returns estimated compression ratio millibytes/char for encoding given input - with generated code. */ -func buildAndStoreLiteralPrefixCode(input []byte, input_size uint, depths []byte, bits []uint16, storage_ix *uint, storage []byte) uint { - var histogram = [256]uint32{0} - var histogram_total uint - var i uint - if input_size < 1<<15 { - for i = 0; i < input_size; i++ { - histogram[input[i]]++ - } - - histogram_total = input_size - for i = 0; i < 256; i++ { - /* We weigh the first 11 samples with weight 3 to account for the - balancing effect of the LZ77 phase on the histogram. */ - var adjust uint32 = 2 * brotli_min_uint32_t(histogram[i], 11) - histogram[i] += adjust - histogram_total += uint(adjust) - } - } else { - const kSampleRate uint = 29 - for i = 0; i < input_size; i += kSampleRate { - histogram[input[i]]++ - } - - histogram_total = (input_size + kSampleRate - 1) / kSampleRate - for i = 0; i < 256; i++ { - /* We add 1 to each population count to avoid 0 bit depths (since this is - only a sample and we don't know if the symbol appears or not), and we - weigh the first 11 samples with weight 3 to account for the balancing - effect of the LZ77 phase on the histogram (more frequent symbols are - more likely to be in backward references instead as literals). */ - var adjust uint32 = 1 + 2*brotli_min_uint32_t(histogram[i], 11) - histogram[i] += adjust - histogram_total += uint(adjust) - } - } - - buildAndStoreHuffmanTreeFast(histogram[:], histogram_total, /* max_bits = */ - 8, depths, bits, storage_ix, storage) - { - var literal_ratio uint = 0 - for i = 0; i < 256; i++ { - if histogram[i] != 0 { - literal_ratio += uint(histogram[i] * uint32(depths[i])) - } - } - - /* Estimated encoding ratio, millibytes per symbol. */ - return (literal_ratio * 125) / histogram_total - } -} - -/* Builds a command and distance prefix code (each 64 symbols) into "depth" and - "bits" based on "histogram" and stores it into the bit stream. */ -func buildAndStoreCommandPrefixCode1(histogram []uint32, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { - var tree [129]huffmanTree - var cmd_depth = [numCommandSymbols]byte{0} - /* Tree size for building a tree over 64 symbols is 2 * 64 + 1. */ - - var cmd_bits [64]uint16 - - createHuffmanTree(histogram, 64, 15, tree[:], depth) - createHuffmanTree(histogram[64:], 64, 14, tree[:], depth[64:]) - - /* We have to jump through a few hoops here in order to compute - the command bits because the symbols are in a different order than in - the full alphabet. This looks complicated, but having the symbols - in this order in the command bits saves a few branches in the Emit* - functions. */ - copy(cmd_depth[:], depth[:24]) - - copy(cmd_depth[24:][:], depth[40:][:8]) - copy(cmd_depth[32:][:], depth[24:][:8]) - copy(cmd_depth[40:][:], depth[48:][:8]) - copy(cmd_depth[48:][:], depth[32:][:8]) - copy(cmd_depth[56:][:], depth[56:][:8]) - convertBitDepthsToSymbols(cmd_depth[:], 64, cmd_bits[:]) - copy(bits, cmd_bits[:24]) - copy(bits[24:], cmd_bits[32:][:8]) - copy(bits[32:], cmd_bits[48:][:8]) - copy(bits[40:], cmd_bits[24:][:8]) - copy(bits[48:], cmd_bits[40:][:8]) - copy(bits[56:], cmd_bits[56:][:8]) - convertBitDepthsToSymbols(depth[64:], 64, bits[64:]) - { - /* Create the bit length array for the full command alphabet. */ - var i uint - for i := 0; i < int(64); i++ { - cmd_depth[i] = 0 - } /* only 64 first values were used */ - copy(cmd_depth[:], depth[:8]) - copy(cmd_depth[64:][:], depth[8:][:8]) - copy(cmd_depth[128:][:], depth[16:][:8]) - copy(cmd_depth[192:][:], depth[24:][:8]) - copy(cmd_depth[384:][:], depth[32:][:8]) - for i = 0; i < 8; i++ { - cmd_depth[128+8*i] = depth[40+i] - cmd_depth[256+8*i] = depth[48+i] - cmd_depth[448+8*i] = depth[56+i] - } - - storeHuffmanTree(cmd_depth[:], numCommandSymbols, tree[:], storage_ix, storage) - } - - storeHuffmanTree(depth[64:], 64, tree[:], storage_ix, storage) -} - -/* REQUIRES: insertlen < 6210 */ -func emitInsertLen1(insertlen uint, depth []byte, bits []uint16, histo []uint32, storage_ix *uint, storage []byte) { - if insertlen < 6 { - var code uint = insertlen + 40 - writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) - histo[code]++ - } else if insertlen < 130 { - var tail uint = insertlen - 2 - var nbits uint32 = log2FloorNonZero(tail) - 1 - var prefix uint = tail >> nbits - var inscode uint = uint((nbits << 1) + uint32(prefix) + 42) - writeBits(uint(depth[inscode]), uint64(bits[inscode]), storage_ix, storage) - writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<> nbits - var code uint = uint((nbits << 1) + uint32(prefix) + 20) - writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) - writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<> nbits - var code uint = uint((nbits << 1) + uint32(prefix) + 4) - writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) - writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<> 5) + 30 - writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) - writeBits(5, uint64(tail)&31, storage_ix, storage) - writeBits(uint(depth[64]), uint64(bits[64]), storage_ix, storage) - histo[code]++ - histo[64]++ - } else if copylen < 2120 { - var tail uint = copylen - 72 - var nbits uint32 = log2FloorNonZero(tail) - var code uint = uint(nbits + 28) - writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) - writeBits(uint(nbits), uint64(tail)-(uint64(uint(1))<> nbits) & 1 - var offset uint = (2 + prefix) << nbits - var distcode uint = uint(2*(nbits-1) + uint32(prefix) + 80) - writeBits(uint(depth[distcode]), uint64(bits[distcode]), storage_ix, storage) - writeBits(uint(nbits), uint64(d)-uint64(offset), storage_ix, storage) - histo[distcode]++ -} - -func emitLiterals(input []byte, len uint, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { - var j uint - for j = 0; j < len; j++ { - var lit byte = input[j] - writeBits(uint(depth[lit]), uint64(bits[lit]), storage_ix, storage) - } -} - -/* REQUIRES: len <= 1 << 24. */ -func storeMetaBlockHeader1(len uint, is_uncompressed bool, storage_ix *uint, storage []byte) { - var nibbles uint = 6 - - /* ISLAST */ - writeBits(1, 0, storage_ix, storage) - - if len <= 1<<16 { - nibbles = 4 - } else if len <= 1<<20 { - nibbles = 5 - } - - writeBits(2, uint64(nibbles)-4, storage_ix, storage) - writeBits(nibbles*4, uint64(len)-1, storage_ix, storage) - - /* ISUNCOMPRESSED */ - writeSingleBit(is_uncompressed, storage_ix, storage) -} - -func updateBits(n_bits uint, bits uint32, pos uint, array []byte) { - for n_bits > 0 { - var byte_pos uint = pos >> 3 - var n_unchanged_bits uint = pos & 7 - var n_changed_bits uint = brotli_min_size_t(n_bits, 8-n_unchanged_bits) - var total_bits uint = n_unchanged_bits + n_changed_bits - var mask uint32 = (^((1 << total_bits) - 1)) | ((1 << n_unchanged_bits) - 1) - var unchanged_bits uint32 = uint32(array[byte_pos]) & mask - var changed_bits uint32 = bits & ((1 << n_changed_bits) - 1) - array[byte_pos] = byte(changed_bits<>= n_changed_bits - pos += n_changed_bits - } -} - -func rewindBitPosition1(new_storage_ix uint, storage_ix *uint, storage []byte) { - var bitpos uint = new_storage_ix & 7 - var mask uint = (1 << bitpos) - 1 - storage[new_storage_ix>>3] &= byte(mask) - *storage_ix = new_storage_ix -} - -var shouldMergeBlock_kSampleRate uint = 43 - -func shouldMergeBlock(data []byte, len uint, depths []byte) bool { - var histo = [256]uint{0} - var i uint - for i = 0; i < len; i += shouldMergeBlock_kSampleRate { - histo[data[i]]++ - } - { - var total uint = (len + shouldMergeBlock_kSampleRate - 1) / shouldMergeBlock_kSampleRate - var r float64 = (fastLog2(total)+0.5)*float64(total) + 200 - for i = 0; i < 256; i++ { - r -= float64(histo[i]) * (float64(depths[i]) + fastLog2(histo[i])) - } - - return r >= 0.0 - } -} - -func shouldUseUncompressedMode(metablock_start []byte, next_emit []byte, insertlen uint, literal_ratio uint) bool { - var compressed uint = uint(-cap(next_emit) + cap(metablock_start)) - if compressed*50 > insertlen { - return false - } else { - return literal_ratio > 980 - } -} - -func emitUncompressedMetaBlock1(begin []byte, end []byte, storage_ix_start uint, storage_ix *uint, storage []byte) { - var len uint = uint(-cap(end) + cap(begin)) - rewindBitPosition1(storage_ix_start, storage_ix, storage) - storeMetaBlockHeader1(uint(len), true, storage_ix, storage) - *storage_ix = (*storage_ix + 7) &^ 7 - copy(storage[*storage_ix>>3:], begin[:len]) - *storage_ix += uint(len << 3) - storage[*storage_ix>>3] = 0 -} - -var kCmdHistoSeed = [128]uint32{ - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, -} - -var compressFragmentFastImpl_kFirstBlockSize uint = 3 << 15 -var compressFragmentFastImpl_kMergeBlockSize uint = 1 << 16 - -func compressFragmentFastImpl(in []byte, input_size uint, is_last bool, table []int, table_bits uint, cmd_depth []byte, cmd_bits []uint16, cmd_code_numbits *uint, cmd_code []byte, storage_ix *uint, storage []byte) { - var cmd_histo [128]uint32 - var ip_end int - var next_emit int = 0 - var base_ip int = 0 - var input int = 0 - const kInputMarginBytes uint = windowGap - const kMinMatchLen uint = 5 - var metablock_start int = input - var block_size uint = brotli_min_size_t(input_size, compressFragmentFastImpl_kFirstBlockSize) - var total_block_size uint = block_size - var mlen_storage_ix uint = *storage_ix + 3 - var lit_depth [256]byte - var lit_bits [256]uint16 - var literal_ratio uint - var ip int - var last_distance int - var shift uint = 64 - table_bits - - /* "next_emit" is a pointer to the first byte that is not covered by a - previous copy. Bytes between "next_emit" and the start of the next copy or - the end of the input will be emitted as literal bytes. */ - - /* Save the start of the first block for position and distance computations. - */ - - /* Save the bit position of the MLEN field of the meta-block header, so that - we can update it later if we decide to extend this meta-block. */ - storeMetaBlockHeader1(block_size, false, storage_ix, storage) - - /* No block splits, no contexts. */ - writeBits(13, 0, storage_ix, storage) - - literal_ratio = buildAndStoreLiteralPrefixCode(in[input:], block_size, lit_depth[:], lit_bits[:], storage_ix, storage) - { - /* Store the pre-compressed command and distance prefix codes. */ - var i uint - for i = 0; i+7 < *cmd_code_numbits; i += 8 { - writeBits(8, uint64(cmd_code[i>>3]), storage_ix, storage) - } - } - - writeBits(*cmd_code_numbits&7, uint64(cmd_code[*cmd_code_numbits>>3]), storage_ix, storage) - - /* Initialize the command and distance histograms. We will gather - statistics of command and distance codes during the processing - of this block and use it to update the command and distance - prefix codes for the next block. */ -emit_commands: - copy(cmd_histo[:], kCmdHistoSeed[:]) - - /* "ip" is the input pointer. */ - ip = input - - last_distance = -1 - ip_end = int(uint(input) + block_size) - - if block_size >= kInputMarginBytes { - var len_limit uint = brotli_min_size_t(block_size-kMinMatchLen, input_size-kInputMarginBytes) - var ip_limit int = int(uint(input) + len_limit) - /* For the last block, we need to keep a 16 bytes margin so that we can be - sure that all distances are at most window size - 16. - For all other blocks, we only need to keep a margin of 5 bytes so that - we don't go over the block size with a copy. */ - - var next_hash uint32 - ip++ - for next_hash = hash5(in[ip:], shift); ; { - var skip uint32 = 32 - var next_ip int = ip - /* Step 1: Scan forward in the input looking for a 5-byte-long match. - If we get close to exhausting the input then goto emit_remainder. - - Heuristic match skipping: If 32 bytes are scanned with no matches - found, start looking only at every other byte. If 32 more bytes are - scanned, look at every third byte, etc.. When a match is found, - immediately go back to looking at every byte. This is a small loss - (~5% performance, ~0.1% density) for compressible data due to more - bookkeeping, but for non-compressible data (such as JPEG) it's a huge - win since the compressor quickly "realizes" the data is incompressible - and doesn't bother looking for matches everywhere. - - The "skip" variable keeps track of how many bytes there are since the - last match; dividing it by 32 (i.e. right-shifting by five) gives the - number of bytes to move ahead for each iteration. */ - - var candidate int - assert(next_emit < ip) - - trawl: - for { - var hash uint32 = next_hash - var bytes_between_hash_lookups uint32 = skip >> 5 - skip++ - assert(hash == hash5(in[next_ip:], shift)) - ip = next_ip - next_ip = int(uint32(ip) + bytes_between_hash_lookups) - if next_ip > ip_limit { - goto emit_remainder - } - - next_hash = hash5(in[next_ip:], shift) - candidate = ip - last_distance - if isMatch5(in[ip:], in[candidate:]) { - if candidate < ip { - table[hash] = int(ip - base_ip) - break - } - } - - candidate = base_ip + table[hash] - assert(candidate >= base_ip) - assert(candidate < ip) - - table[hash] = int(ip - base_ip) - if isMatch5(in[ip:], in[candidate:]) { - break - } - } - - /* Check copy distance. If candidate is not feasible, continue search. - Checking is done outside of hot loop to reduce overhead. */ - if ip-candidate > maxDistance_compress_fragment { - goto trawl - } - - /* Step 2: Emit the found match together with the literal bytes from - "next_emit" to the bit stream, and then see if we can find a next match - immediately afterwards. Repeat until we find no match for the input - without emitting some literal bytes. */ - { - var base int = ip - /* > 0 */ - var matched uint = 5 + findMatchLengthWithLimit(in[candidate+5:], in[ip+5:], uint(ip_end-ip)-5) - var distance int = int(base - candidate) - /* We have a 5-byte match at ip, and we need to emit bytes in - [next_emit, ip). */ - - var insert uint = uint(base - next_emit) - ip += int(matched) - if insert < 6210 { - emitInsertLen1(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) - } else if shouldUseUncompressedMode(in[metablock_start:], in[next_emit:], insert, literal_ratio) { - emitUncompressedMetaBlock1(in[metablock_start:], in[base:], mlen_storage_ix-3, storage_ix, storage) - input_size -= uint(base - input) - input = base - next_emit = input - goto next_block - } else { - emitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) - } - - emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], storage_ix, storage) - if distance == last_distance { - writeBits(uint(cmd_depth[64]), uint64(cmd_bits[64]), storage_ix, storage) - cmd_histo[64]++ - } else { - emitDistance1(uint(distance), cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) - last_distance = distance - } - - emitCopyLenLastDistance1(matched, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) - - next_emit = ip - if ip >= ip_limit { - goto emit_remainder - } - - /* We could immediately start working at ip now, but to improve - compression we first update "table" with the hashes of some positions - within the last copy. */ - { - var input_bytes uint64 = binary.LittleEndian.Uint64(in[ip-3:]) - var prev_hash uint32 = hashBytesAtOffset5(input_bytes, 0, shift) - var cur_hash uint32 = hashBytesAtOffset5(input_bytes, 3, shift) - table[prev_hash] = int(ip - base_ip - 3) - prev_hash = hashBytesAtOffset5(input_bytes, 1, shift) - table[prev_hash] = int(ip - base_ip - 2) - prev_hash = hashBytesAtOffset5(input_bytes, 2, shift) - table[prev_hash] = int(ip - base_ip - 1) - - candidate = base_ip + table[cur_hash] - table[cur_hash] = int(ip - base_ip) - } - } - - for isMatch5(in[ip:], in[candidate:]) { - var base int = ip - /* We have a 5-byte match at ip, and no need to emit any literal bytes - prior to ip. */ - - var matched uint = 5 + findMatchLengthWithLimit(in[candidate+5:], in[ip+5:], uint(ip_end-ip)-5) - if ip-candidate > maxDistance_compress_fragment { - break - } - ip += int(matched) - last_distance = int(base - candidate) /* > 0 */ - emitCopyLen1(matched, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) - emitDistance1(uint(last_distance), cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) - - next_emit = ip - if ip >= ip_limit { - goto emit_remainder - } - - /* We could immediately start working at ip now, but to improve - compression we first update "table" with the hashes of some positions - within the last copy. */ - { - var input_bytes uint64 = binary.LittleEndian.Uint64(in[ip-3:]) - var prev_hash uint32 = hashBytesAtOffset5(input_bytes, 0, shift) - var cur_hash uint32 = hashBytesAtOffset5(input_bytes, 3, shift) - table[prev_hash] = int(ip - base_ip - 3) - prev_hash = hashBytesAtOffset5(input_bytes, 1, shift) - table[prev_hash] = int(ip - base_ip - 2) - prev_hash = hashBytesAtOffset5(input_bytes, 2, shift) - table[prev_hash] = int(ip - base_ip - 1) - - candidate = base_ip + table[cur_hash] - table[cur_hash] = int(ip - base_ip) - } - } - - ip++ - next_hash = hash5(in[ip:], shift) - } - } - -emit_remainder: - assert(next_emit <= ip_end) - input += int(block_size) - input_size -= block_size - block_size = brotli_min_size_t(input_size, compressFragmentFastImpl_kMergeBlockSize) - - /* Decide if we want to continue this meta-block instead of emitting the - last insert-only command. */ - if input_size > 0 && total_block_size+block_size <= 1<<20 && shouldMergeBlock(in[input:], block_size, lit_depth[:]) { - assert(total_block_size > 1<<16) - - /* Update the size of the current meta-block and continue emitting commands. - We can do this because the current size and the new size both have 5 - nibbles. */ - total_block_size += block_size - - updateBits(20, uint32(total_block_size-1), mlen_storage_ix, storage) - goto emit_commands - } - - /* Emit the remaining bytes as literals. */ - if next_emit < ip_end { - var insert uint = uint(ip_end - next_emit) - if insert < 6210 { - emitInsertLen1(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) - emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], storage_ix, storage) - } else if shouldUseUncompressedMode(in[metablock_start:], in[next_emit:], insert, literal_ratio) { - emitUncompressedMetaBlock1(in[metablock_start:], in[ip_end:], mlen_storage_ix-3, storage_ix, storage) - } else { - emitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) - emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], storage_ix, storage) - } - } - - next_emit = ip_end - - /* If we have more data, write a new meta-block header and prefix codes and - then continue emitting commands. */ -next_block: - if input_size > 0 { - metablock_start = input - block_size = brotli_min_size_t(input_size, compressFragmentFastImpl_kFirstBlockSize) - total_block_size = block_size - - /* Save the bit position of the MLEN field of the meta-block header, so that - we can update it later if we decide to extend this meta-block. */ - mlen_storage_ix = *storage_ix + 3 - - storeMetaBlockHeader1(block_size, false, storage_ix, storage) - - /* No block splits, no contexts. */ - writeBits(13, 0, storage_ix, storage) - - literal_ratio = buildAndStoreLiteralPrefixCode(in[input:], block_size, lit_depth[:], lit_bits[:], storage_ix, storage) - buildAndStoreCommandPrefixCode1(cmd_histo[:], cmd_depth, cmd_bits, storage_ix, storage) - goto emit_commands - } - - if !is_last { - /* If this is not the last block, update the command and distance prefix - codes for the next block and store the compressed forms. */ - cmd_code[0] = 0 - - *cmd_code_numbits = 0 - buildAndStoreCommandPrefixCode1(cmd_histo[:], cmd_depth, cmd_bits, cmd_code_numbits, cmd_code) - } -} - -/* Compresses "input" string to the "*storage" buffer as one or more complete - meta-blocks, and updates the "*storage_ix" bit position. - - If "is_last" is 1, emits an additional empty last meta-block. - - "cmd_depth" and "cmd_bits" contain the command and distance prefix codes - (see comment in encode.h) used for the encoding of this input fragment. - If "is_last" is 0, they are updated to reflect the statistics - of this input fragment, to be used for the encoding of the next fragment. - - "*cmd_code_numbits" is the number of bits of the compressed representation - of the command and distance prefix codes, and "cmd_code" is an array of - at least "(*cmd_code_numbits + 7) >> 3" size that contains the compressed - command and distance prefix codes. If "is_last" is 0, these are also - updated to represent the updated "cmd_depth" and "cmd_bits". - - REQUIRES: "input_size" is greater than zero, or "is_last" is 1. - REQUIRES: "input_size" is less or equal to maximal metablock size (1 << 24). - REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero. - REQUIRES: "table_size" is an odd (9, 11, 13, 15) power of two - OUTPUT: maximal copy distance <= |input_size| - OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */ -func compressFragmentFast(input []byte, input_size uint, is_last bool, table []int, table_size uint, cmd_depth []byte, cmd_bits []uint16, cmd_code_numbits *uint, cmd_code []byte, storage_ix *uint, storage []byte) { - var initial_storage_ix uint = *storage_ix - var table_bits uint = uint(log2FloorNonZero(table_size)) - - if input_size == 0 { - assert(is_last) - writeBits(1, 1, storage_ix, storage) /* islast */ - writeBits(1, 1, storage_ix, storage) /* isempty */ - *storage_ix = (*storage_ix + 7) &^ 7 - return - } - - compressFragmentFastImpl(input, input_size, is_last, table, table_bits, cmd_depth, cmd_bits, cmd_code_numbits, cmd_code, storage_ix, storage) - - /* If output is larger than single uncompressed block, rewrite it. */ - if *storage_ix-initial_storage_ix > 31+(input_size<<3) { - emitUncompressedMetaBlock1(input, input[input_size:], initial_storage_ix, storage_ix, storage) - } - - if is_last { - writeBits(1, 1, storage_ix, storage) /* islast */ - writeBits(1, 1, storage_ix, storage) /* isempty */ - *storage_ix = (*storage_ix + 7) &^ 7 - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go b/src/vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go deleted file mode 100644 index c5c663a5..00000000 --- a/src/vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go +++ /dev/null @@ -1,775 +0,0 @@ -package brotli - -import "encoding/binary" - -/* Copyright 2015 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Function for fast encoding of an input fragment, independently from the input - history. This function uses two-pass processing: in the first pass we save - the found backward matches and literal bytes into a buffer, and in the - second pass we emit them into the bit stream using prefix codes built based - on the actual command and literal byte histograms. */ - -const kCompressFragmentTwoPassBlockSize uint = 1 << 17 - -func hash1(p []byte, shift uint, length uint) uint32 { - var h uint64 = (binary.LittleEndian.Uint64(p) << ((8 - length) * 8)) * uint64(kHashMul32) - return uint32(h >> shift) -} - -func hashBytesAtOffset(v uint64, offset uint, shift uint, length uint) uint32 { - assert(offset <= 8-length) - { - var h uint64 = ((v >> (8 * offset)) << ((8 - length) * 8)) * uint64(kHashMul32) - return uint32(h >> shift) - } -} - -func isMatch1(p1 []byte, p2 []byte, length uint) bool { - if binary.LittleEndian.Uint32(p1) != binary.LittleEndian.Uint32(p2) { - return false - } - if length == 4 { - return true - } - return p1[4] == p2[4] && p1[5] == p2[5] -} - -/* -Builds a command and distance prefix code (each 64 symbols) into "depth" and - - "bits" based on "histogram" and stores it into the bit stream. -*/ -func buildAndStoreCommandPrefixCode(histogram []uint32, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { - var tree [129]huffmanTree - var cmd_depth = [numCommandSymbols]byte{0} - /* Tree size for building a tree over 64 symbols is 2 * 64 + 1. */ - - var cmd_bits [64]uint16 - createHuffmanTree(histogram, 64, 15, tree[:], depth) - createHuffmanTree(histogram[64:], 64, 14, tree[:], depth[64:]) - - /* We have to jump through a few hoops here in order to compute - the command bits because the symbols are in a different order than in - the full alphabet. This looks complicated, but having the symbols - in this order in the command bits saves a few branches in the Emit* - functions. */ - copy(cmd_depth[:], depth[24:][:24]) - - copy(cmd_depth[24:][:], depth[:8]) - copy(cmd_depth[32:][:], depth[48:][:8]) - copy(cmd_depth[40:][:], depth[8:][:8]) - copy(cmd_depth[48:][:], depth[56:][:8]) - copy(cmd_depth[56:][:], depth[16:][:8]) - convertBitDepthsToSymbols(cmd_depth[:], 64, cmd_bits[:]) - copy(bits, cmd_bits[24:][:8]) - copy(bits[8:], cmd_bits[40:][:8]) - copy(bits[16:], cmd_bits[56:][:8]) - copy(bits[24:], cmd_bits[:24]) - copy(bits[48:], cmd_bits[32:][:8]) - copy(bits[56:], cmd_bits[48:][:8]) - convertBitDepthsToSymbols(depth[64:], 64, bits[64:]) - { - /* Create the bit length array for the full command alphabet. */ - var i uint - for i := 0; i < int(64); i++ { - cmd_depth[i] = 0 - } /* only 64 first values were used */ - copy(cmd_depth[:], depth[24:][:8]) - copy(cmd_depth[64:][:], depth[32:][:8]) - copy(cmd_depth[128:][:], depth[40:][:8]) - copy(cmd_depth[192:][:], depth[48:][:8]) - copy(cmd_depth[384:][:], depth[56:][:8]) - for i = 0; i < 8; i++ { - cmd_depth[128+8*i] = depth[i] - cmd_depth[256+8*i] = depth[8+i] - cmd_depth[448+8*i] = depth[16+i] - } - - storeHuffmanTree(cmd_depth[:], numCommandSymbols, tree[:], storage_ix, storage) - } - - storeHuffmanTree(depth[64:], 64, tree[:], storage_ix, storage) -} - -func emitInsertLen(insertlen uint32, commands *[]uint32) { - if insertlen < 6 { - (*commands)[0] = insertlen - } else if insertlen < 130 { - var tail uint32 = insertlen - 2 - var nbits uint32 = log2FloorNonZero(uint(tail)) - 1 - var prefix uint32 = tail >> nbits - var inscode uint32 = (nbits << 1) + prefix + 2 - var extra uint32 = tail - (prefix << nbits) - (*commands)[0] = inscode | extra<<8 - } else if insertlen < 2114 { - var tail uint32 = insertlen - 66 - var nbits uint32 = log2FloorNonZero(uint(tail)) - var code uint32 = nbits + 10 - var extra uint32 = tail - (1 << nbits) - (*commands)[0] = code | extra<<8 - } else if insertlen < 6210 { - var extra uint32 = insertlen - 2114 - (*commands)[0] = 21 | extra<<8 - } else if insertlen < 22594 { - var extra uint32 = insertlen - 6210 - (*commands)[0] = 22 | extra<<8 - } else { - var extra uint32 = insertlen - 22594 - (*commands)[0] = 23 | extra<<8 - } - - *commands = (*commands)[1:] -} - -func emitCopyLen(copylen uint, commands *[]uint32) { - if copylen < 10 { - (*commands)[0] = uint32(copylen + 38) - } else if copylen < 134 { - var tail uint = copylen - 6 - var nbits uint = uint(log2FloorNonZero(tail) - 1) - var prefix uint = tail >> nbits - var code uint = (nbits << 1) + prefix + 44 - var extra uint = tail - (prefix << nbits) - (*commands)[0] = uint32(code | extra<<8) - } else if copylen < 2118 { - var tail uint = copylen - 70 - var nbits uint = uint(log2FloorNonZero(tail)) - var code uint = nbits + 52 - var extra uint = tail - (uint(1) << nbits) - (*commands)[0] = uint32(code | extra<<8) - } else { - var extra uint = copylen - 2118 - (*commands)[0] = uint32(63 | extra<<8) - } - - *commands = (*commands)[1:] -} - -func emitCopyLenLastDistance(copylen uint, commands *[]uint32) { - if copylen < 12 { - (*commands)[0] = uint32(copylen + 20) - *commands = (*commands)[1:] - } else if copylen < 72 { - var tail uint = copylen - 8 - var nbits uint = uint(log2FloorNonZero(tail) - 1) - var prefix uint = tail >> nbits - var code uint = (nbits << 1) + prefix + 28 - var extra uint = tail - (prefix << nbits) - (*commands)[0] = uint32(code | extra<<8) - *commands = (*commands)[1:] - } else if copylen < 136 { - var tail uint = copylen - 8 - var code uint = (tail >> 5) + 54 - var extra uint = tail & 31 - (*commands)[0] = uint32(code | extra<<8) - *commands = (*commands)[1:] - (*commands)[0] = 64 - *commands = (*commands)[1:] - } else if copylen < 2120 { - var tail uint = copylen - 72 - var nbits uint = uint(log2FloorNonZero(tail)) - var code uint = nbits + 52 - var extra uint = tail - (uint(1) << nbits) - (*commands)[0] = uint32(code | extra<<8) - *commands = (*commands)[1:] - (*commands)[0] = 64 - *commands = (*commands)[1:] - } else { - var extra uint = copylen - 2120 - (*commands)[0] = uint32(63 | extra<<8) - *commands = (*commands)[1:] - (*commands)[0] = 64 - *commands = (*commands)[1:] - } -} - -func emitDistance(distance uint32, commands *[]uint32) { - var d uint32 = distance + 3 - var nbits uint32 = log2FloorNonZero(uint(d)) - 1 - var prefix uint32 = (d >> nbits) & 1 - var offset uint32 = (2 + prefix) << nbits - var distcode uint32 = 2*(nbits-1) + prefix + 80 - var extra uint32 = d - offset - (*commands)[0] = distcode | extra<<8 - *commands = (*commands)[1:] -} - -/* REQUIRES: len <= 1 << 24. */ -func storeMetaBlockHeader(len uint, is_uncompressed bool, storage_ix *uint, storage []byte) { - var nibbles uint = 6 - - /* ISLAST */ - writeBits(1, 0, storage_ix, storage) - - if len <= 1<<16 { - nibbles = 4 - } else if len <= 1<<20 { - nibbles = 5 - } - - writeBits(2, uint64(nibbles)-4, storage_ix, storage) - writeBits(nibbles*4, uint64(len)-1, storage_ix, storage) - - /* ISUNCOMPRESSED */ - writeSingleBit(is_uncompressed, storage_ix, storage) -} - -func storeMetaBlockHeaderBW(len uint, is_uncompressed bool, bw *bitWriter) { - var nibbles uint = 6 - - /* ISLAST */ - bw.writeBits(1, 0) - - if len <= 1<<16 { - nibbles = 4 - } else if len <= 1<<20 { - nibbles = 5 - } else if len > 1<<24 { - panic("metablock too long") - } - - bw.writeBits(2, uint64(nibbles)-4) - bw.writeBits(nibbles*4, uint64(len)-1) - - /* ISUNCOMPRESSED */ - bw.writeSingleBit(is_uncompressed) -} - -func createCommands(input []byte, block_size uint, input_size uint, base_ip_ptr []byte, table []int, table_bits uint, min_match uint, literals *[]byte, commands *[]uint32) { - var ip int = 0 - var shift uint = 64 - table_bits - var ip_end int = int(block_size) - var base_ip int = -cap(base_ip_ptr) + cap(input) - var next_emit int = 0 - var last_distance int = -1 - /* "ip" is the input pointer. */ - - const kInputMarginBytes uint = windowGap - - /* "next_emit" is a pointer to the first byte that is not covered by a - previous copy. Bytes between "next_emit" and the start of the next copy or - the end of the input will be emitted as literal bytes. */ - if block_size >= kInputMarginBytes { - var len_limit uint = brotli_min_size_t(block_size-min_match, input_size-kInputMarginBytes) - var ip_limit int = int(len_limit) - /* For the last block, we need to keep a 16 bytes margin so that we can be - sure that all distances are at most window size - 16. - For all other blocks, we only need to keep a margin of 5 bytes so that - we don't go over the block size with a copy. */ - - var next_hash uint32 - ip++ - for next_hash = hash1(input[ip:], shift, min_match); ; { - var skip uint32 = 32 - var next_ip int = ip - /* Step 1: Scan forward in the input looking for a 6-byte-long match. - If we get close to exhausting the input then goto emit_remainder. - - Heuristic match skipping: If 32 bytes are scanned with no matches - found, start looking only at every other byte. If 32 more bytes are - scanned, look at every third byte, etc.. When a match is found, - immediately go back to looking at every byte. This is a small loss - (~5% performance, ~0.1% density) for compressible data due to more - bookkeeping, but for non-compressible data (such as JPEG) it's a huge - win since the compressor quickly "realizes" the data is incompressible - and doesn't bother looking for matches everywhere. - - The "skip" variable keeps track of how many bytes there are since the - last match; dividing it by 32 (ie. right-shifting by five) gives the - number of bytes to move ahead for each iteration. */ - - var candidate int - - assert(next_emit < ip) - - trawl: - for { - var hash uint32 = next_hash - var bytes_between_hash_lookups uint32 = skip >> 5 - skip++ - ip = next_ip - assert(hash == hash1(input[ip:], shift, min_match)) - next_ip = int(uint32(ip) + bytes_between_hash_lookups) - if next_ip > ip_limit { - goto emit_remainder - } - - next_hash = hash1(input[next_ip:], shift, min_match) - candidate = ip - last_distance - if isMatch1(input[ip:], base_ip_ptr[candidate-base_ip:], min_match) { - if candidate < ip { - table[hash] = int(ip - base_ip) - break - } - } - - candidate = base_ip + table[hash] - assert(candidate >= base_ip) - assert(candidate < ip) - - table[hash] = int(ip - base_ip) - if isMatch1(input[ip:], base_ip_ptr[candidate-base_ip:], min_match) { - break - } - } - - /* Check copy distance. If candidate is not feasible, continue search. - Checking is done outside of hot loop to reduce overhead. */ - if ip-candidate > maxDistance_compress_fragment { - goto trawl - } - - /* Step 2: Emit the found match together with the literal bytes from - "next_emit", and then see if we can find a next match immediately - afterwards. Repeat until we find no match for the input - without emitting some literal bytes. */ - { - var base int = ip - /* > 0 */ - var matched uint = min_match + findMatchLengthWithLimit(base_ip_ptr[uint(candidate-base_ip)+min_match:], input[uint(ip)+min_match:], uint(ip_end-ip)-min_match) - var distance int = int(base - candidate) - /* We have a 6-byte match at ip, and we need to emit bytes in - [next_emit, ip). */ - - var insert int = int(base - next_emit) - ip += int(matched) - emitInsertLen(uint32(insert), commands) - copy(*literals, input[next_emit:][:uint(insert)]) - *literals = (*literals)[insert:] - if distance == last_distance { - (*commands)[0] = 64 - *commands = (*commands)[1:] - } else { - emitDistance(uint32(distance), commands) - last_distance = distance - } - - emitCopyLenLastDistance(matched, commands) - - next_emit = ip - if ip >= ip_limit { - goto emit_remainder - } - { - var input_bytes uint64 - var cur_hash uint32 - /* We could immediately start working at ip now, but to improve - compression we first update "table" with the hashes of some - positions within the last copy. */ - - var prev_hash uint32 - if min_match == 4 { - input_bytes = binary.LittleEndian.Uint64(input[ip-3:]) - cur_hash = hashBytesAtOffset(input_bytes, 3, shift, min_match) - prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) - table[prev_hash] = int(ip - base_ip - 3) - prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) - table[prev_hash] = int(ip - base_ip - 2) - prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) - table[prev_hash] = int(ip - base_ip - 1) - } else { - input_bytes = binary.LittleEndian.Uint64(input[ip-5:]) - prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) - table[prev_hash] = int(ip - base_ip - 5) - prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) - table[prev_hash] = int(ip - base_ip - 4) - prev_hash = hashBytesAtOffset(input_bytes, 2, shift, min_match) - table[prev_hash] = int(ip - base_ip - 3) - input_bytes = binary.LittleEndian.Uint64(input[ip-2:]) - cur_hash = hashBytesAtOffset(input_bytes, 2, shift, min_match) - prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) - table[prev_hash] = int(ip - base_ip - 2) - prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) - table[prev_hash] = int(ip - base_ip - 1) - } - - candidate = base_ip + table[cur_hash] - table[cur_hash] = int(ip - base_ip) - } - } - - for ip-candidate <= maxDistance_compress_fragment && isMatch1(input[ip:], base_ip_ptr[candidate-base_ip:], min_match) { - var base int = ip - /* We have a 6-byte match at ip, and no need to emit any - literal bytes prior to ip. */ - - var matched uint = min_match + findMatchLengthWithLimit(base_ip_ptr[uint(candidate-base_ip)+min_match:], input[uint(ip)+min_match:], uint(ip_end-ip)-min_match) - ip += int(matched) - last_distance = int(base - candidate) /* > 0 */ - emitCopyLen(matched, commands) - emitDistance(uint32(last_distance), commands) - - next_emit = ip - if ip >= ip_limit { - goto emit_remainder - } - { - var input_bytes uint64 - var cur_hash uint32 - /* We could immediately start working at ip now, but to improve - compression we first update "table" with the hashes of some - positions within the last copy. */ - - var prev_hash uint32 - if min_match == 4 { - input_bytes = binary.LittleEndian.Uint64(input[ip-3:]) - cur_hash = hashBytesAtOffset(input_bytes, 3, shift, min_match) - prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) - table[prev_hash] = int(ip - base_ip - 3) - prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) - table[prev_hash] = int(ip - base_ip - 2) - prev_hash = hashBytesAtOffset(input_bytes, 2, shift, min_match) - table[prev_hash] = int(ip - base_ip - 1) - } else { - input_bytes = binary.LittleEndian.Uint64(input[ip-5:]) - prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) - table[prev_hash] = int(ip - base_ip - 5) - prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) - table[prev_hash] = int(ip - base_ip - 4) - prev_hash = hashBytesAtOffset(input_bytes, 2, shift, min_match) - table[prev_hash] = int(ip - base_ip - 3) - input_bytes = binary.LittleEndian.Uint64(input[ip-2:]) - cur_hash = hashBytesAtOffset(input_bytes, 2, shift, min_match) - prev_hash = hashBytesAtOffset(input_bytes, 0, shift, min_match) - table[prev_hash] = int(ip - base_ip - 2) - prev_hash = hashBytesAtOffset(input_bytes, 1, shift, min_match) - table[prev_hash] = int(ip - base_ip - 1) - } - - candidate = base_ip + table[cur_hash] - table[cur_hash] = int(ip - base_ip) - } - } - - ip++ - next_hash = hash1(input[ip:], shift, min_match) - } - } - -emit_remainder: - assert(next_emit <= ip_end) - - /* Emit the remaining bytes as literals. */ - if next_emit < ip_end { - var insert uint32 = uint32(ip_end - next_emit) - emitInsertLen(insert, commands) - copy(*literals, input[next_emit:][:insert]) - *literals = (*literals)[insert:] - } -} - -var storeCommands_kNumExtraBits = [128]uint32{ - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 2, - 2, - 3, - 3, - 4, - 4, - 5, - 5, - 6, - 7, - 8, - 9, - 10, - 12, - 14, - 24, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 2, - 2, - 3, - 3, - 4, - 4, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 2, - 2, - 3, - 3, - 4, - 4, - 5, - 5, - 6, - 7, - 8, - 9, - 10, - 24, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 2, - 2, - 3, - 3, - 4, - 4, - 5, - 5, - 6, - 6, - 7, - 7, - 8, - 8, - 9, - 9, - 10, - 10, - 11, - 11, - 12, - 12, - 13, - 13, - 14, - 14, - 15, - 15, - 16, - 16, - 17, - 17, - 18, - 18, - 19, - 19, - 20, - 20, - 21, - 21, - 22, - 22, - 23, - 23, - 24, - 24, -} -var storeCommands_kInsertOffset = [24]uint32{ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 8, - 10, - 14, - 18, - 26, - 34, - 50, - 66, - 98, - 130, - 194, - 322, - 578, - 1090, - 2114, - 6210, - 22594, -} - -func storeCommands(literals []byte, num_literals uint, commands []uint32, num_commands uint, storage_ix *uint, storage []byte) { - var lit_depths [256]byte - var lit_bits [256]uint16 - var lit_histo = [256]uint32{0} - var cmd_depths = [128]byte{0} - var cmd_bits = [128]uint16{0} - var cmd_histo = [128]uint32{0} - var i uint - for i = 0; i < num_literals; i++ { - lit_histo[literals[i]]++ - } - - buildAndStoreHuffmanTreeFast(lit_histo[:], num_literals, /* max_bits = */ - 8, lit_depths[:], lit_bits[:], storage_ix, storage) - - for i = 0; i < num_commands; i++ { - var code uint32 = commands[i] & 0xFF - assert(code < 128) - cmd_histo[code]++ - } - - cmd_histo[1] += 1 - cmd_histo[2] += 1 - cmd_histo[64] += 1 - cmd_histo[84] += 1 - buildAndStoreCommandPrefixCode(cmd_histo[:], cmd_depths[:], cmd_bits[:], storage_ix, storage) - - for i = 0; i < num_commands; i++ { - var cmd uint32 = commands[i] - var code uint32 = cmd & 0xFF - var extra uint32 = cmd >> 8 - assert(code < 128) - writeBits(uint(cmd_depths[code]), uint64(cmd_bits[code]), storage_ix, storage) - writeBits(uint(storeCommands_kNumExtraBits[code]), uint64(extra), storage_ix, storage) - if code < 24 { - var insert uint32 = storeCommands_kInsertOffset[code] + extra - var j uint32 - for j = 0; j < insert; j++ { - var lit byte = literals[0] - writeBits(uint(lit_depths[lit]), uint64(lit_bits[lit]), storage_ix, storage) - literals = literals[1:] - } - } - } -} - -/* Acceptable loss for uncompressible speedup is 2% */ -const minRatio = 0.98 - -const sampleRate = 43 - -func shouldCompress(input []byte, input_size uint, num_literals uint) bool { - var corpus_size float64 = float64(input_size) - if float64(num_literals) < minRatio*corpus_size { - return true - } else { - var literal_histo = [256]uint32{0} - var max_total_bit_cost float64 = corpus_size * 8 * minRatio / sampleRate - var i uint - for i = 0; i < input_size; i += sampleRate { - literal_histo[input[i]]++ - } - - return bitsEntropy(literal_histo[:], 256) < max_total_bit_cost - } -} - -func rewindBitPosition(new_storage_ix uint, storage_ix *uint, storage []byte) { - var bitpos uint = new_storage_ix & 7 - var mask uint = (1 << bitpos) - 1 - storage[new_storage_ix>>3] &= byte(mask) - *storage_ix = new_storage_ix -} - -func emitUncompressedMetaBlock(input []byte, input_size uint, storage_ix *uint, storage []byte) { - storeMetaBlockHeader(input_size, true, storage_ix, storage) - *storage_ix = (*storage_ix + 7) &^ 7 - copy(storage[*storage_ix>>3:], input[:input_size]) - *storage_ix += input_size << 3 - storage[*storage_ix>>3] = 0 -} - -func compressFragmentTwoPassImpl(input []byte, input_size uint, is_last bool, command_buf []uint32, literal_buf []byte, table []int, table_bits uint, min_match uint, storage_ix *uint, storage []byte) { - /* Save the start of the first block for position and distance computations. - */ - var base_ip []byte = input - - for input_size > 0 { - var block_size uint = brotli_min_size_t(input_size, kCompressFragmentTwoPassBlockSize) - var commands []uint32 = command_buf - var literals []byte = literal_buf - var num_literals uint - createCommands(input, block_size, input_size, base_ip, table, table_bits, min_match, &literals, &commands) - num_literals = uint(-cap(literals) + cap(literal_buf)) - if shouldCompress(input, block_size, num_literals) { - var num_commands uint = uint(-cap(commands) + cap(command_buf)) - storeMetaBlockHeader(block_size, false, storage_ix, storage) - - /* No block splits, no contexts. */ - writeBits(13, 0, storage_ix, storage) - - storeCommands(literal_buf, num_literals, command_buf, num_commands, storage_ix, storage) - } else { - /* Since we did not find many backward references and the entropy of - the data is close to 8 bits, we can simply emit an uncompressed block. - This makes compression speed of uncompressible data about 3x faster. */ - emitUncompressedMetaBlock(input, block_size, storage_ix, storage) - } - - input = input[block_size:] - input_size -= block_size - } -} - -/* -Compresses "input" string to the "*storage" buffer as one or more complete - - meta-blocks, and updates the "*storage_ix" bit position. - - If "is_last" is 1, emits an additional empty last meta-block. - - REQUIRES: "input_size" is greater than zero, or "is_last" is 1. - REQUIRES: "input_size" is less or equal to maximal metablock size (1 << 24). - REQUIRES: "command_buf" and "literal_buf" point to at least - kCompressFragmentTwoPassBlockSize long arrays. - REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero. - REQUIRES: "table_size" is a power of two - OUTPUT: maximal copy distance <= |input_size| - OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) -*/ -func compressFragmentTwoPass(input []byte, input_size uint, is_last bool, command_buf []uint32, literal_buf []byte, table []int, table_size uint, storage_ix *uint, storage []byte) { - var initial_storage_ix uint = *storage_ix - var table_bits uint = uint(log2FloorNonZero(table_size)) - var min_match uint - if table_bits <= 15 { - min_match = 4 - } else { - min_match = 6 - } - compressFragmentTwoPassImpl(input, input_size, is_last, command_buf, literal_buf, table, table_bits, min_match, storage_ix, storage) - - /* If output is larger than single uncompressed block, rewrite it. */ - if *storage_ix-initial_storage_ix > 31+(input_size<<3) { - rewindBitPosition(initial_storage_ix, storage_ix, storage) - emitUncompressedMetaBlock(input, input_size, storage_ix, storage) - } - - if is_last { - writeBits(1, 1, storage_ix, storage) /* islast */ - writeBits(1, 1, storage_ix, storage) /* isempty */ - *storage_ix = (*storage_ix + 7) &^ 7 - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/constants.go b/src/vendor/github.com/andybalholm/brotli/constants.go deleted file mode 100644 index a880dff7..00000000 --- a/src/vendor/github.com/andybalholm/brotli/constants.go +++ /dev/null @@ -1,77 +0,0 @@ -package brotli - -/* Copyright 2016 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Specification: 7.3. Encoding of the context map */ -const contextMapMaxRle = 16 - -/* Specification: 2. Compressed representation overview */ -const maxNumberOfBlockTypes = 256 - -/* Specification: 3.3. Alphabet sizes: insert-and-copy length */ -const numLiteralSymbols = 256 - -const numCommandSymbols = 704 - -const numBlockLenSymbols = 26 - -const maxContextMapSymbols = (maxNumberOfBlockTypes + contextMapMaxRle) - -const maxBlockTypeSymbols = (maxNumberOfBlockTypes + 2) - -/* Specification: 3.5. Complex prefix codes */ -const repeatPreviousCodeLength = 16 - -const repeatZeroCodeLength = 17 - -const codeLengthCodes = (repeatZeroCodeLength + 1) - -/* "code length of 8 is repeated" */ -const initialRepeatedCodeLength = 8 - -/* "Large Window Brotli" */ -const largeMaxDistanceBits = 62 - -const largeMinWbits = 10 - -const largeMaxWbits = 30 - -/* Specification: 4. Encoding of distances */ -const numDistanceShortCodes = 16 - -const maxNpostfix = 3 - -const maxNdirect = 120 - -const maxDistanceBits = 24 - -func distanceAlphabetSize(NPOSTFIX uint, NDIRECT uint, MAXNBITS uint) uint { - return numDistanceShortCodes + NDIRECT + uint(MAXNBITS<<(NPOSTFIX+1)) -} - -/* numDistanceSymbols == 1128 */ -const numDistanceSymbols = 1128 - -const maxDistance = 0x3FFFFFC - -const maxAllowedDistance = 0x7FFFFFFC - -/* 7.1. Context modes and context ID lookup for literals */ -/* "context IDs for literals are in the range of 0..63" */ -const literalContextBits = 6 - -/* 7.2. Context ID for distances */ -const distanceContextBits = 2 - -/* 9.1. Format of the Stream Header */ -/* Number of slack bytes for window size. Don't confuse - with BROTLI_NUM_DISTANCE_SHORT_CODES. */ -const windowGap = 16 - -func maxBackwardLimit(W uint) uint { - return (uint(1) << W) - windowGap -} diff --git a/src/vendor/github.com/andybalholm/brotli/context.go b/src/vendor/github.com/andybalholm/brotli/context.go deleted file mode 100644 index 884ff8a2..00000000 --- a/src/vendor/github.com/andybalholm/brotli/context.go +++ /dev/null @@ -1,2176 +0,0 @@ -package brotli - -/* Lookup table to map the previous two bytes to a context id. - -There are four different context modeling modes defined here: - contextLSB6: context id is the least significant 6 bits of the last byte, - contextMSB6: context id is the most significant 6 bits of the last byte, - contextUTF8: second-order context model tuned for UTF8-encoded text, - contextSigned: second-order context model tuned for signed integers. - -If |p1| and |p2| are the previous two bytes, and |mode| is current context -mode, we calculate the context as: - - context = ContextLut(mode)[p1] | ContextLut(mode)[p2 + 256]. - -For contextUTF8 mode, if the previous two bytes are ASCII characters -(i.e. < 128), this will be equivalent to - - context = 4 * context1(p1) + context2(p2), - -where context1 is based on the previous byte in the following way: - - 0 : non-ASCII control - 1 : \t, \n, \r - 2 : space - 3 : other punctuation - 4 : " ' - 5 : % - 6 : ( < [ { - 7 : ) > ] } - 8 : , ; : - 9 : . - 10 : = - 11 : number - 12 : upper-case vowel - 13 : upper-case consonant - 14 : lower-case vowel - 15 : lower-case consonant - -and context2 is based on the second last byte: - - 0 : control, space - 1 : punctuation - 2 : upper-case letter, number - 3 : lower-case letter - -If the last byte is ASCII, and the second last byte is not (in a valid UTF8 -stream it will be a continuation byte, value between 128 and 191), the -context is the same as if the second last byte was an ASCII control or space. - -If the last byte is a UTF8 lead byte (value >= 192), then the next byte will -be a continuation byte and the context id is 2 or 3 depending on the LSB of -the last byte and to a lesser extent on the second last byte if it is ASCII. - -If the last byte is a UTF8 continuation byte, the second last byte can be: - - continuation byte: the next byte is probably ASCII or lead byte (assuming - 4-byte UTF8 characters are rare) and the context id is 0 or 1. - - lead byte (192 - 207): next byte is ASCII or lead byte, context is 0 or 1 - - lead byte (208 - 255): next byte is continuation byte, context is 2 or 3 - -The possible value combinations of the previous two bytes, the range of -context ids and the type of the next byte is summarized in the table below: - -|--------\-----------------------------------------------------------------| -| \ Last byte | -| Second \---------------------------------------------------------------| -| last byte \ ASCII | cont. byte | lead byte | -| \ (0-127) | (128-191) | (192-) | -|=============|===================|=====================|==================| -| ASCII | next: ASCII/lead | not valid | next: cont. | -| (0-127) | context: 4 - 63 | | context: 2 - 3 | -|-------------|-------------------|---------------------|------------------| -| cont. byte | next: ASCII/lead | next: ASCII/lead | next: cont. | -| (128-191) | context: 4 - 63 | context: 0 - 1 | context: 2 - 3 | -|-------------|-------------------|---------------------|------------------| -| lead byte | not valid | next: ASCII/lead | not valid | -| (192-207) | | context: 0 - 1 | | -|-------------|-------------------|---------------------|------------------| -| lead byte | not valid | next: cont. | not valid | -| (208-) | | context: 2 - 3 | | -|-------------|-------------------|---------------------|------------------| -*/ - -const ( - contextLSB6 = 0 - contextMSB6 = 1 - contextUTF8 = 2 - contextSigned = 3 -) - -/* Common context lookup table for all context modes. */ -var kContextLookup = [2048]byte{ - /* CONTEXT_LSB6, last byte. */ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - - /* CONTEXT_LSB6, second last byte, */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - - /* CONTEXT_MSB6, last byte. */ - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 4, - 4, - 4, - 4, - 5, - 5, - 5, - 5, - 6, - 6, - 6, - 6, - 7, - 7, - 7, - 7, - 8, - 8, - 8, - 8, - 9, - 9, - 9, - 9, - 10, - 10, - 10, - 10, - 11, - 11, - 11, - 11, - 12, - 12, - 12, - 12, - 13, - 13, - 13, - 13, - 14, - 14, - 14, - 14, - 15, - 15, - 15, - 15, - 16, - 16, - 16, - 16, - 17, - 17, - 17, - 17, - 18, - 18, - 18, - 18, - 19, - 19, - 19, - 19, - 20, - 20, - 20, - 20, - 21, - 21, - 21, - 21, - 22, - 22, - 22, - 22, - 23, - 23, - 23, - 23, - 24, - 24, - 24, - 24, - 25, - 25, - 25, - 25, - 26, - 26, - 26, - 26, - 27, - 27, - 27, - 27, - 28, - 28, - 28, - 28, - 29, - 29, - 29, - 29, - 30, - 30, - 30, - 30, - 31, - 31, - 31, - 31, - 32, - 32, - 32, - 32, - 33, - 33, - 33, - 33, - 34, - 34, - 34, - 34, - 35, - 35, - 35, - 35, - 36, - 36, - 36, - 36, - 37, - 37, - 37, - 37, - 38, - 38, - 38, - 38, - 39, - 39, - 39, - 39, - 40, - 40, - 40, - 40, - 41, - 41, - 41, - 41, - 42, - 42, - 42, - 42, - 43, - 43, - 43, - 43, - 44, - 44, - 44, - 44, - 45, - 45, - 45, - 45, - 46, - 46, - 46, - 46, - 47, - 47, - 47, - 47, - 48, - 48, - 48, - 48, - 49, - 49, - 49, - 49, - 50, - 50, - 50, - 50, - 51, - 51, - 51, - 51, - 52, - 52, - 52, - 52, - 53, - 53, - 53, - 53, - 54, - 54, - 54, - 54, - 55, - 55, - 55, - 55, - 56, - 56, - 56, - 56, - 57, - 57, - 57, - 57, - 58, - 58, - 58, - 58, - 59, - 59, - 59, - 59, - 60, - 60, - 60, - 60, - 61, - 61, - 61, - 61, - 62, - 62, - 62, - 62, - 63, - 63, - 63, - 63, - - /* CONTEXT_MSB6, second last byte, */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - - /* CONTEXT_UTF8, last byte. */ - /* ASCII range. */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4, - 4, - 0, - 0, - 4, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8, - 12, - 16, - 12, - 12, - 20, - 12, - 16, - 24, - 28, - 12, - 12, - 32, - 12, - 36, - 12, - 44, - 44, - 44, - 44, - 44, - 44, - 44, - 44, - 44, - 44, - 32, - 32, - 24, - 40, - 28, - 12, - 12, - 48, - 52, - 52, - 52, - 48, - 52, - 52, - 52, - 48, - 52, - 52, - 52, - 52, - 52, - 48, - 52, - 52, - 52, - 52, - 52, - 48, - 52, - 52, - 52, - 52, - 52, - 24, - 12, - 28, - 12, - 12, - 12, - 56, - 60, - 60, - 60, - 56, - 60, - 60, - 60, - 56, - 60, - 60, - 60, - 60, - 60, - 56, - 60, - 60, - 60, - 60, - 60, - 56, - 60, - 60, - 60, - 60, - 60, - 24, - 12, - 28, - 12, - 0, - - /* UTF8 continuation byte range. */ - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - - /* UTF8 lead byte range. */ - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - - /* CONTEXT_UTF8 second last byte. */ - /* ASCII range. */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 1, - 1, - 1, - 1, - 0, - - /* UTF8 continuation byte range. */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - - /* UTF8 lead byte range. */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - - /* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */ - 0, - 8, - 8, - 8, - 8, - 8, - 8, - 8, - 8, - 8, - 8, - 8, - 8, - 8, - 8, - 8, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 32, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 40, - 48, - 48, - 48, - 48, - 48, - 48, - 48, - 48, - 48, - 48, - 48, - 48, - 48, - 48, - 48, - 56, - - /* CONTEXT_SIGNED, second last byte. */ - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 5, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 7, -} - -type contextLUT []byte - -func getContextLUT(mode int) contextLUT { - return kContextLookup[mode<<9:] -} - -func getContext(p1 byte, p2 byte, lut contextLUT) byte { - return lut[p1] | lut[256+int(p2)] -} diff --git a/src/vendor/github.com/andybalholm/brotli/decode.go b/src/vendor/github.com/andybalholm/brotli/decode.go deleted file mode 100644 index 1a27c0a6..00000000 --- a/src/vendor/github.com/andybalholm/brotli/decode.go +++ /dev/null @@ -1,2570 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -const ( - decoderResultError = 0 - decoderResultSuccess = 1 - decoderResultNeedsMoreInput = 2 - decoderResultNeedsMoreOutput = 3 -) - -/** - * Error code for detailed logging / production debugging. - * - * See ::BrotliDecoderGetErrorCode and ::BROTLI_LAST_ERROR_CODE. - */ -const ( - decoderNoError = 0 - decoderSuccess = 1 - decoderNeedsMoreInput = 2 - decoderNeedsMoreOutput = 3 - decoderErrorFormatExuberantNibble = -1 - decoderErrorFormatReserved = -2 - decoderErrorFormatExuberantMetaNibble = -3 - decoderErrorFormatSimpleHuffmanAlphabet = -4 - decoderErrorFormatSimpleHuffmanSame = -5 - decoderErrorFormatClSpace = -6 - decoderErrorFormatHuffmanSpace = -7 - decoderErrorFormatContextMapRepeat = -8 - decoderErrorFormatBlockLength1 = -9 - decoderErrorFormatBlockLength2 = -10 - decoderErrorFormatTransform = -11 - decoderErrorFormatDictionary = -12 - decoderErrorFormatWindowBits = -13 - decoderErrorFormatPadding1 = -14 - decoderErrorFormatPadding2 = -15 - decoderErrorFormatDistance = -16 - decoderErrorDictionaryNotSet = -19 - decoderErrorInvalidArguments = -20 - decoderErrorAllocContextModes = -21 - decoderErrorAllocTreeGroups = -22 - decoderErrorAllocContextMap = -25 - decoderErrorAllocRingBuffer1 = -26 - decoderErrorAllocRingBuffer2 = -27 - decoderErrorAllocBlockTypeTrees = -30 - decoderErrorUnreachable = -31 -) - -const huffmanTableBits = 8 - -const huffmanTableMask = 0xFF - -/* We need the slack region for the following reasons: - - doing up to two 16-byte copies for fast backward copying - - inserting transformed dictionary word (5 prefix + 24 base + 8 suffix) */ -const kRingBufferWriteAheadSlack uint32 = 42 - -var kCodeLengthCodeOrder = [codeLengthCodes]byte{1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15} - -/* Static prefix code for the complex code length code lengths. */ -var kCodeLengthPrefixLength = [16]byte{2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4} - -var kCodeLengthPrefixValue = [16]byte{0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5} - -/* Saves error code and converts it to BrotliDecoderResult. */ -func saveErrorCode(s *Reader, e int) int { - s.error_code = int(e) - switch e { - case decoderSuccess: - return decoderResultSuccess - - case decoderNeedsMoreInput: - return decoderResultNeedsMoreInput - - case decoderNeedsMoreOutput: - return decoderResultNeedsMoreOutput - - default: - return decoderResultError - } -} - -/* Decodes WBITS by reading 1 - 7 bits, or 0x11 for "Large Window Brotli". - Precondition: bit-reader accumulator has at least 8 bits. */ -func decodeWindowBits(s *Reader, br *bitReader) int { - var n uint32 - var large_window bool = s.large_window - s.large_window = false - takeBits(br, 1, &n) - if n == 0 { - s.window_bits = 16 - return decoderSuccess - } - - takeBits(br, 3, &n) - if n != 0 { - s.window_bits = 17 + n - return decoderSuccess - } - - takeBits(br, 3, &n) - if n == 1 { - if large_window { - takeBits(br, 1, &n) - if n == 1 { - return decoderErrorFormatWindowBits - } - - s.large_window = true - return decoderSuccess - } else { - return decoderErrorFormatWindowBits - } - } - - if n != 0 { - s.window_bits = 8 + n - return decoderSuccess - } - - s.window_bits = 17 - return decoderSuccess -} - -/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */ -func decodeVarLenUint8(s *Reader, br *bitReader, value *uint32) int { - var bits uint32 - switch s.substate_decode_uint8 { - case stateDecodeUint8None: - if !safeReadBits(br, 1, &bits) { - return decoderNeedsMoreInput - } - - if bits == 0 { - *value = 0 - return decoderSuccess - } - fallthrough - - /* Fall through. */ - case stateDecodeUint8Short: - if !safeReadBits(br, 3, &bits) { - s.substate_decode_uint8 = stateDecodeUint8Short - return decoderNeedsMoreInput - } - - if bits == 0 { - *value = 1 - s.substate_decode_uint8 = stateDecodeUint8None - return decoderSuccess - } - - /* Use output value as a temporary storage. It MUST be persisted. */ - *value = bits - fallthrough - - /* Fall through. */ - case stateDecodeUint8Long: - if !safeReadBits(br, *value, &bits) { - s.substate_decode_uint8 = stateDecodeUint8Long - return decoderNeedsMoreInput - } - - *value = (1 << *value) + bits - s.substate_decode_uint8 = stateDecodeUint8None - return decoderSuccess - - default: - return decoderErrorUnreachable - } -} - -/* Decodes a metablock length and flags by reading 2 - 31 bits. */ -func decodeMetaBlockLength(s *Reader, br *bitReader) int { - var bits uint32 - var i int - for { - switch s.substate_metablock_header { - case stateMetablockHeaderNone: - if !safeReadBits(br, 1, &bits) { - return decoderNeedsMoreInput - } - - if bits != 0 { - s.is_last_metablock = 1 - } else { - s.is_last_metablock = 0 - } - s.meta_block_remaining_len = 0 - s.is_uncompressed = 0 - s.is_metadata = 0 - if s.is_last_metablock == 0 { - s.substate_metablock_header = stateMetablockHeaderNibbles - break - } - - s.substate_metablock_header = stateMetablockHeaderEmpty - fallthrough - - /* Fall through. */ - case stateMetablockHeaderEmpty: - if !safeReadBits(br, 1, &bits) { - return decoderNeedsMoreInput - } - - if bits != 0 { - s.substate_metablock_header = stateMetablockHeaderNone - return decoderSuccess - } - - s.substate_metablock_header = stateMetablockHeaderNibbles - fallthrough - - /* Fall through. */ - case stateMetablockHeaderNibbles: - if !safeReadBits(br, 2, &bits) { - return decoderNeedsMoreInput - } - - s.size_nibbles = uint(byte(bits + 4)) - s.loop_counter = 0 - if bits == 3 { - s.is_metadata = 1 - s.substate_metablock_header = stateMetablockHeaderReserved - break - } - - s.substate_metablock_header = stateMetablockHeaderSize - fallthrough - - /* Fall through. */ - case stateMetablockHeaderSize: - i = s.loop_counter - - for ; i < int(s.size_nibbles); i++ { - if !safeReadBits(br, 4, &bits) { - s.loop_counter = i - return decoderNeedsMoreInput - } - - if uint(i+1) == s.size_nibbles && s.size_nibbles > 4 && bits == 0 { - return decoderErrorFormatExuberantNibble - } - - s.meta_block_remaining_len |= int(bits << uint(i*4)) - } - - s.substate_metablock_header = stateMetablockHeaderUncompressed - fallthrough - - /* Fall through. */ - case stateMetablockHeaderUncompressed: - if s.is_last_metablock == 0 { - if !safeReadBits(br, 1, &bits) { - return decoderNeedsMoreInput - } - - if bits != 0 { - s.is_uncompressed = 1 - } else { - s.is_uncompressed = 0 - } - } - - s.meta_block_remaining_len++ - s.substate_metablock_header = stateMetablockHeaderNone - return decoderSuccess - - case stateMetablockHeaderReserved: - if !safeReadBits(br, 1, &bits) { - return decoderNeedsMoreInput - } - - if bits != 0 { - return decoderErrorFormatReserved - } - - s.substate_metablock_header = stateMetablockHeaderBytes - fallthrough - - /* Fall through. */ - case stateMetablockHeaderBytes: - if !safeReadBits(br, 2, &bits) { - return decoderNeedsMoreInput - } - - if bits == 0 { - s.substate_metablock_header = stateMetablockHeaderNone - return decoderSuccess - } - - s.size_nibbles = uint(byte(bits)) - s.substate_metablock_header = stateMetablockHeaderMetadata - fallthrough - - /* Fall through. */ - case stateMetablockHeaderMetadata: - i = s.loop_counter - - for ; i < int(s.size_nibbles); i++ { - if !safeReadBits(br, 8, &bits) { - s.loop_counter = i - return decoderNeedsMoreInput - } - - if uint(i+1) == s.size_nibbles && s.size_nibbles > 1 && bits == 0 { - return decoderErrorFormatExuberantMetaNibble - } - - s.meta_block_remaining_len |= int(bits << uint(i*8)) - } - - s.meta_block_remaining_len++ - s.substate_metablock_header = stateMetablockHeaderNone - return decoderSuccess - - default: - return decoderErrorUnreachable - } - } -} - -/* Decodes the Huffman code. - This method doesn't read data from the bit reader, BUT drops the amount of - bits that correspond to the decoded symbol. - bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */ -func decodeSymbol(bits uint32, table []huffmanCode, br *bitReader) uint32 { - table = table[bits&huffmanTableMask:] - if table[0].bits > huffmanTableBits { - var nbits uint32 = uint32(table[0].bits) - huffmanTableBits - dropBits(br, huffmanTableBits) - table = table[uint32(table[0].value)+((bits>>huffmanTableBits)&bitMask(nbits)):] - } - - dropBits(br, uint32(table[0].bits)) - return uint32(table[0].value) -} - -/* Reads and decodes the next Huffman code from bit-stream. - This method peeks 16 bits of input and drops 0 - 15 of them. */ -func readSymbol(table []huffmanCode, br *bitReader) uint32 { - return decodeSymbol(get16BitsUnmasked(br), table, br) -} - -/* Same as DecodeSymbol, but it is known that there is less than 15 bits of - input are currently available. */ -func safeDecodeSymbol(table []huffmanCode, br *bitReader, result *uint32) bool { - var val uint32 - var available_bits uint32 = getAvailableBits(br) - if available_bits == 0 { - if table[0].bits == 0 { - *result = uint32(table[0].value) - return true - } - - return false /* No valid bits at all. */ - } - - val = uint32(getBitsUnmasked(br)) - table = table[val&huffmanTableMask:] - if table[0].bits <= huffmanTableBits { - if uint32(table[0].bits) <= available_bits { - dropBits(br, uint32(table[0].bits)) - *result = uint32(table[0].value) - return true - } else { - return false /* Not enough bits for the first level. */ - } - } - - if available_bits <= huffmanTableBits { - return false /* Not enough bits to move to the second level. */ - } - - /* Speculatively drop HUFFMAN_TABLE_BITS. */ - val = (val & bitMask(uint32(table[0].bits))) >> huffmanTableBits - - available_bits -= huffmanTableBits - table = table[uint32(table[0].value)+val:] - if available_bits < uint32(table[0].bits) { - return false /* Not enough bits for the second level. */ - } - - dropBits(br, huffmanTableBits+uint32(table[0].bits)) - *result = uint32(table[0].value) - return true -} - -func safeReadSymbol(table []huffmanCode, br *bitReader, result *uint32) bool { - var val uint32 - if safeGetBits(br, 15, &val) { - *result = decodeSymbol(val, table, br) - return true - } - - return safeDecodeSymbol(table, br, result) -} - -/* Makes a look-up in first level Huffman table. Peeks 8 bits. */ -func preloadSymbol(safe int, table []huffmanCode, br *bitReader, bits *uint32, value *uint32) { - if safe != 0 { - return - } - - table = table[getBits(br, huffmanTableBits):] - *bits = uint32(table[0].bits) - *value = uint32(table[0].value) -} - -/* Decodes the next Huffman code using data prepared by PreloadSymbol. - Reads 0 - 15 bits. Also peeks 8 following bits. */ -func readPreloadedSymbol(table []huffmanCode, br *bitReader, bits *uint32, value *uint32) uint32 { - var result uint32 = *value - var ext []huffmanCode - if *bits > huffmanTableBits { - var val uint32 = get16BitsUnmasked(br) - ext = table[val&huffmanTableMask:][*value:] - var mask uint32 = bitMask((*bits - huffmanTableBits)) - dropBits(br, huffmanTableBits) - ext = ext[(val>>huffmanTableBits)&mask:] - dropBits(br, uint32(ext[0].bits)) - result = uint32(ext[0].value) - } else { - dropBits(br, *bits) - } - - preloadSymbol(0, table, br, bits, value) - return result -} - -func log2Floor(x uint32) uint32 { - var result uint32 = 0 - for x != 0 { - x >>= 1 - result++ - } - - return result -} - -/* Reads (s->symbol + 1) symbols. - Totally 1..4 symbols are read, 1..11 bits each. - The list of symbols MUST NOT contain duplicates. */ -func readSimpleHuffmanSymbols(alphabet_size uint32, max_symbol uint32, s *Reader) int { - var br *bitReader = &s.br - var max_bits uint32 = log2Floor(alphabet_size - 1) - var i uint32 = s.sub_loop_counter - /* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */ - - var num_symbols uint32 = s.symbol - for i <= num_symbols { - var v uint32 - if !safeReadBits(br, max_bits, &v) { - s.sub_loop_counter = i - s.substate_huffman = stateHuffmanSimpleRead - return decoderNeedsMoreInput - } - - if v >= max_symbol { - return decoderErrorFormatSimpleHuffmanAlphabet - } - - s.symbols_lists_array[i] = uint16(v) - i++ - } - - for i = 0; i < num_symbols; i++ { - var k uint32 = i + 1 - for ; k <= num_symbols; k++ { - if s.symbols_lists_array[i] == s.symbols_lists_array[k] { - return decoderErrorFormatSimpleHuffmanSame - } - } - } - - return decoderSuccess -} - -/* Process single decoded symbol code length: - A) reset the repeat variable - B) remember code length (if it is not 0) - C) extend corresponding index-chain - D) reduce the Huffman space - E) update the histogram */ -func processSingleCodeLength(code_len uint32, symbol *uint32, repeat *uint32, space *uint32, prev_code_len *uint32, symbol_lists symbolList, code_length_histo []uint16, next_symbol []int) { - *repeat = 0 - if code_len != 0 { /* code_len == 1..15 */ - symbolListPut(symbol_lists, next_symbol[code_len], uint16(*symbol)) - next_symbol[code_len] = int(*symbol) - *prev_code_len = code_len - *space -= 32768 >> code_len - code_length_histo[code_len]++ - } - - (*symbol)++ -} - -/* Process repeated symbol code length. - A) Check if it is the extension of previous repeat sequence; if the decoded - value is not BROTLI_REPEAT_PREVIOUS_CODE_LENGTH, then it is a new - symbol-skip - B) Update repeat variable - C) Check if operation is feasible (fits alphabet) - D) For each symbol do the same operations as in ProcessSingleCodeLength - - PRECONDITION: code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH or - code_len == BROTLI_REPEAT_ZERO_CODE_LENGTH */ -func processRepeatedCodeLength(code_len uint32, repeat_delta uint32, alphabet_size uint32, symbol *uint32, repeat *uint32, space *uint32, prev_code_len *uint32, repeat_code_len *uint32, symbol_lists symbolList, code_length_histo []uint16, next_symbol []int) { - var old_repeat uint32 /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */ /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */ - var extra_bits uint32 = 3 - var new_len uint32 = 0 - if code_len == repeatPreviousCodeLength { - new_len = *prev_code_len - extra_bits = 2 - } - - if *repeat_code_len != new_len { - *repeat = 0 - *repeat_code_len = new_len - } - - old_repeat = *repeat - if *repeat > 0 { - *repeat -= 2 - *repeat <<= extra_bits - } - - *repeat += repeat_delta + 3 - repeat_delta = *repeat - old_repeat - if *symbol+repeat_delta > alphabet_size { - *symbol = alphabet_size - *space = 0xFFFFF - return - } - - if *repeat_code_len != 0 { - var last uint = uint(*symbol + repeat_delta) - var next int = next_symbol[*repeat_code_len] - for { - symbolListPut(symbol_lists, next, uint16(*symbol)) - next = int(*symbol) - (*symbol)++ - if (*symbol) == uint32(last) { - break - } - } - - next_symbol[*repeat_code_len] = next - *space -= repeat_delta << (15 - *repeat_code_len) - code_length_histo[*repeat_code_len] = uint16(uint32(code_length_histo[*repeat_code_len]) + repeat_delta) - } else { - *symbol += repeat_delta - } -} - -/* Reads and decodes symbol codelengths. */ -func readSymbolCodeLengths(alphabet_size uint32, s *Reader) int { - var br *bitReader = &s.br - var symbol uint32 = s.symbol - var repeat uint32 = s.repeat - var space uint32 = s.space - var prev_code_len uint32 = s.prev_code_len - var repeat_code_len uint32 = s.repeat_code_len - var symbol_lists symbolList = s.symbol_lists - var code_length_histo []uint16 = s.code_length_histo[:] - var next_symbol []int = s.next_symbol[:] - if !warmupBitReader(br) { - return decoderNeedsMoreInput - } - var p []huffmanCode - for symbol < alphabet_size && space > 0 { - p = s.table[:] - var code_len uint32 - if !checkInputAmount(br, shortFillBitWindowRead) { - s.symbol = symbol - s.repeat = repeat - s.prev_code_len = prev_code_len - s.repeat_code_len = repeat_code_len - s.space = space - return decoderNeedsMoreInput - } - - fillBitWindow16(br) - p = p[getBitsUnmasked(br)&uint64(bitMask(huffmanMaxCodeLengthCodeLength)):] - dropBits(br, uint32(p[0].bits)) /* Use 1..5 bits. */ - code_len = uint32(p[0].value) /* code_len == 0..17 */ - if code_len < repeatPreviousCodeLength { - processSingleCodeLength(code_len, &symbol, &repeat, &space, &prev_code_len, symbol_lists, code_length_histo, next_symbol) /* code_len == 16..17, extra_bits == 2..3 */ - } else { - var extra_bits uint32 - if code_len == repeatPreviousCodeLength { - extra_bits = 2 - } else { - extra_bits = 3 - } - var repeat_delta uint32 = uint32(getBitsUnmasked(br)) & bitMask(extra_bits) - dropBits(br, extra_bits) - processRepeatedCodeLength(code_len, repeat_delta, alphabet_size, &symbol, &repeat, &space, &prev_code_len, &repeat_code_len, symbol_lists, code_length_histo, next_symbol) - } - } - - s.space = space - return decoderSuccess -} - -func safeReadSymbolCodeLengths(alphabet_size uint32, s *Reader) int { - var br *bitReader = &s.br - var get_byte bool = false - var p []huffmanCode - for s.symbol < alphabet_size && s.space > 0 { - p = s.table[:] - var code_len uint32 - var available_bits uint32 - var bits uint32 = 0 - if get_byte && !pullByte(br) { - return decoderNeedsMoreInput - } - get_byte = false - available_bits = getAvailableBits(br) - if available_bits != 0 { - bits = uint32(getBitsUnmasked(br)) - } - - p = p[bits&bitMask(huffmanMaxCodeLengthCodeLength):] - if uint32(p[0].bits) > available_bits { - get_byte = true - continue - } - - code_len = uint32(p[0].value) /* code_len == 0..17 */ - if code_len < repeatPreviousCodeLength { - dropBits(br, uint32(p[0].bits)) - processSingleCodeLength(code_len, &s.symbol, &s.repeat, &s.space, &s.prev_code_len, s.symbol_lists, s.code_length_histo[:], s.next_symbol[:]) /* code_len == 16..17, extra_bits == 2..3 */ - } else { - var extra_bits uint32 = code_len - 14 - var repeat_delta uint32 = (bits >> p[0].bits) & bitMask(extra_bits) - if available_bits < uint32(p[0].bits)+extra_bits { - get_byte = true - continue - } - - dropBits(br, uint32(p[0].bits)+extra_bits) - processRepeatedCodeLength(code_len, repeat_delta, alphabet_size, &s.symbol, &s.repeat, &s.space, &s.prev_code_len, &s.repeat_code_len, s.symbol_lists, s.code_length_histo[:], s.next_symbol[:]) - } - } - - return decoderSuccess -} - -/* Reads and decodes 15..18 codes using static prefix code. - Each code is 2..4 bits long. In total 30..72 bits are used. */ -func readCodeLengthCodeLengths(s *Reader) int { - var br *bitReader = &s.br - var num_codes uint32 = s.repeat - var space uint32 = s.space - var i uint32 = s.sub_loop_counter - for ; i < codeLengthCodes; i++ { - var code_len_idx byte = kCodeLengthCodeOrder[i] - var ix uint32 - var v uint32 - if !safeGetBits(br, 4, &ix) { - var available_bits uint32 = getAvailableBits(br) - if available_bits != 0 { - ix = uint32(getBitsUnmasked(br) & 0xF) - } else { - ix = 0 - } - - if uint32(kCodeLengthPrefixLength[ix]) > available_bits { - s.sub_loop_counter = i - s.repeat = num_codes - s.space = space - s.substate_huffman = stateHuffmanComplex - return decoderNeedsMoreInput - } - } - - v = uint32(kCodeLengthPrefixValue[ix]) - dropBits(br, uint32(kCodeLengthPrefixLength[ix])) - s.code_length_code_lengths[code_len_idx] = byte(v) - if v != 0 { - space = space - (32 >> v) - num_codes++ - s.code_length_histo[v]++ - if space-1 >= 32 { - /* space is 0 or wrapped around. */ - break - } - } - } - - if num_codes != 1 && space != 0 { - return decoderErrorFormatClSpace - } - - return decoderSuccess -} - -/* Decodes the Huffman tables. - There are 2 scenarios: - A) Huffman code contains only few symbols (1..4). Those symbols are read - directly; their code lengths are defined by the number of symbols. - For this scenario 4 - 49 bits will be read. - - B) 2-phase decoding: - B.1) Small Huffman table is decoded; it is specified with code lengths - encoded with predefined entropy code. 32 - 74 bits are used. - B.2) Decoded table is used to decode code lengths of symbols in resulting - Huffman table. In worst case 3520 bits are read. */ -func readHuffmanCode(alphabet_size uint32, max_symbol uint32, table []huffmanCode, opt_table_size *uint32, s *Reader) int { - var br *bitReader = &s.br - - /* Unnecessary masking, but might be good for safety. */ - alphabet_size &= 0x7FF - - /* State machine. */ - for { - switch s.substate_huffman { - case stateHuffmanNone: - if !safeReadBits(br, 2, &s.sub_loop_counter) { - return decoderNeedsMoreInput - } - - /* The value is used as follows: - 1 for simple code; - 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */ - if s.sub_loop_counter != 1 { - s.space = 32 - s.repeat = 0 /* num_codes */ - var i int - for i = 0; i <= huffmanMaxCodeLengthCodeLength; i++ { - s.code_length_histo[i] = 0 - } - - for i = 0; i < codeLengthCodes; i++ { - s.code_length_code_lengths[i] = 0 - } - - s.substate_huffman = stateHuffmanComplex - continue - } - fallthrough - - /* Read symbols, codes & code lengths directly. */ - case stateHuffmanSimpleSize: - if !safeReadBits(br, 2, &s.symbol) { /* num_symbols */ - s.substate_huffman = stateHuffmanSimpleSize - return decoderNeedsMoreInput - } - - s.sub_loop_counter = 0 - fallthrough - - case stateHuffmanSimpleRead: - { - var result int = readSimpleHuffmanSymbols(alphabet_size, max_symbol, s) - if result != decoderSuccess { - return result - } - } - fallthrough - - case stateHuffmanSimpleBuild: - var table_size uint32 - if s.symbol == 3 { - var bits uint32 - if !safeReadBits(br, 1, &bits) { - s.substate_huffman = stateHuffmanSimpleBuild - return decoderNeedsMoreInput - } - - s.symbol += bits - } - - table_size = buildSimpleHuffmanTable(table, huffmanTableBits, s.symbols_lists_array[:], s.symbol) - if opt_table_size != nil { - *opt_table_size = table_size - } - - s.substate_huffman = stateHuffmanNone - return decoderSuccess - - /* Decode Huffman-coded code lengths. */ - case stateHuffmanComplex: - { - var i uint32 - var result int = readCodeLengthCodeLengths(s) - if result != decoderSuccess { - return result - } - - buildCodeLengthsHuffmanTable(s.table[:], s.code_length_code_lengths[:], s.code_length_histo[:]) - for i = 0; i < 16; i++ { - s.code_length_histo[i] = 0 - } - - for i = 0; i <= huffmanMaxCodeLength; i++ { - s.next_symbol[i] = int(i) - (huffmanMaxCodeLength + 1) - symbolListPut(s.symbol_lists, s.next_symbol[i], 0xFFFF) - } - - s.symbol = 0 - s.prev_code_len = initialRepeatedCodeLength - s.repeat = 0 - s.repeat_code_len = 0 - s.space = 32768 - s.substate_huffman = stateHuffmanLengthSymbols - } - fallthrough - - case stateHuffmanLengthSymbols: - var table_size uint32 - var result int = readSymbolCodeLengths(max_symbol, s) - if result == decoderNeedsMoreInput { - result = safeReadSymbolCodeLengths(max_symbol, s) - } - - if result != decoderSuccess { - return result - } - - if s.space != 0 { - return decoderErrorFormatHuffmanSpace - } - - table_size = buildHuffmanTable(table, huffmanTableBits, s.symbol_lists, s.code_length_histo[:]) - if opt_table_size != nil { - *opt_table_size = table_size - } - - s.substate_huffman = stateHuffmanNone - return decoderSuccess - - default: - return decoderErrorUnreachable - } - } -} - -/* Decodes a block length by reading 3..39 bits. */ -func readBlockLength(table []huffmanCode, br *bitReader) uint32 { - var code uint32 - var nbits uint32 - code = readSymbol(table, br) - nbits = kBlockLengthPrefixCode[code].nbits /* nbits == 2..24 */ - return kBlockLengthPrefixCode[code].offset + readBits(br, nbits) -} - -/* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then - reading can't be continued with ReadBlockLength. */ -func safeReadBlockLength(s *Reader, result *uint32, table []huffmanCode, br *bitReader) bool { - var index uint32 - if s.substate_read_block_length == stateReadBlockLengthNone { - if !safeReadSymbol(table, br, &index) { - return false - } - } else { - index = s.block_length_index - } - { - var bits uint32 /* nbits == 2..24 */ - var nbits uint32 = kBlockLengthPrefixCode[index].nbits - if !safeReadBits(br, nbits, &bits) { - s.block_length_index = index - s.substate_read_block_length = stateReadBlockLengthSuffix - return false - } - - *result = kBlockLengthPrefixCode[index].offset + bits - s.substate_read_block_length = stateReadBlockLengthNone - return true - } -} - -/* Transform: - 1) initialize list L with values 0, 1,... 255 - 2) For each input element X: - 2.1) let Y = L[X] - 2.2) remove X-th element from L - 2.3) prepend Y to L - 2.4) append Y to output - - In most cases max(Y) <= 7, so most of L remains intact. - To reduce the cost of initialization, we reuse L, remember the upper bound - of Y values, and reinitialize only first elements in L. - - Most of input values are 0 and 1. To reduce number of branches, we replace - inner for loop with do-while. */ -func inverseMoveToFrontTransform(v []byte, v_len uint32, state *Reader) { - var mtf [256]byte - var i int - for i = 1; i < 256; i++ { - mtf[i] = byte(i) - } - var mtf_1 byte - - /* Transform the input. */ - for i = 0; uint32(i) < v_len; i++ { - var index int = int(v[i]) - var value byte = mtf[index] - v[i] = value - mtf_1 = value - for index >= 1 { - index-- - mtf[index+1] = mtf[index] - } - - mtf[0] = mtf_1 - } -} - -/* Decodes a series of Huffman table using ReadHuffmanCode function. */ -func huffmanTreeGroupDecode(group *huffmanTreeGroup, s *Reader) int { - if s.substate_tree_group != stateTreeGroupLoop { - s.next = group.codes - s.htree_index = 0 - s.substate_tree_group = stateTreeGroupLoop - } - - for s.htree_index < int(group.num_htrees) { - var table_size uint32 - var result int = readHuffmanCode(uint32(group.alphabet_size), uint32(group.max_symbol), s.next, &table_size, s) - if result != decoderSuccess { - return result - } - group.htrees[s.htree_index] = s.next - s.next = s.next[table_size:] - s.htree_index++ - } - - s.substate_tree_group = stateTreeGroupNone - return decoderSuccess -} - -/* Decodes a context map. - Decoding is done in 4 phases: - 1) Read auxiliary information (6..16 bits) and allocate memory. - In case of trivial context map, decoding is finished at this phase. - 2) Decode Huffman table using ReadHuffmanCode function. - This table will be used for reading context map items. - 3) Read context map items; "0" values could be run-length encoded. - 4) Optionally, apply InverseMoveToFront transform to the resulting map. */ -func decodeContextMap(context_map_size uint32, num_htrees *uint32, context_map_arg *[]byte, s *Reader) int { - var br *bitReader = &s.br - var result int = decoderSuccess - - switch int(s.substate_context_map) { - case stateContextMapNone: - result = decodeVarLenUint8(s, br, num_htrees) - if result != decoderSuccess { - return result - } - - (*num_htrees)++ - s.context_index = 0 - *context_map_arg = make([]byte, uint(context_map_size)) - if *context_map_arg == nil { - return decoderErrorAllocContextMap - } - - if *num_htrees <= 1 { - for i := 0; i < int(context_map_size); i++ { - (*context_map_arg)[i] = 0 - } - return decoderSuccess - } - - s.substate_context_map = stateContextMapReadPrefix - fallthrough - /* Fall through. */ - case stateContextMapReadPrefix: - { - var bits uint32 - - /* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe - to peek 4 bits ahead. */ - if !safeGetBits(br, 5, &bits) { - return decoderNeedsMoreInput - } - - if bits&1 != 0 { /* Use RLE for zeros. */ - s.max_run_length_prefix = (bits >> 1) + 1 - dropBits(br, 5) - } else { - s.max_run_length_prefix = 0 - dropBits(br, 1) - } - - s.substate_context_map = stateContextMapHuffman - } - fallthrough - - /* Fall through. */ - case stateContextMapHuffman: - { - var alphabet_size uint32 = *num_htrees + s.max_run_length_prefix - result = readHuffmanCode(alphabet_size, alphabet_size, s.context_map_table[:], nil, s) - if result != decoderSuccess { - return result - } - s.code = 0xFFFF - s.substate_context_map = stateContextMapDecode - } - fallthrough - - /* Fall through. */ - case stateContextMapDecode: - { - var context_index uint32 = s.context_index - var max_run_length_prefix uint32 = s.max_run_length_prefix - var context_map []byte = *context_map_arg - var code uint32 = s.code - var skip_preamble bool = (code != 0xFFFF) - for context_index < context_map_size || skip_preamble { - if !skip_preamble { - if !safeReadSymbol(s.context_map_table[:], br, &code) { - s.code = 0xFFFF - s.context_index = context_index - return decoderNeedsMoreInput - } - - if code == 0 { - context_map[context_index] = 0 - context_index++ - continue - } - - if code > max_run_length_prefix { - context_map[context_index] = byte(code - max_run_length_prefix) - context_index++ - continue - } - } else { - skip_preamble = false - } - - /* RLE sub-stage. */ - { - var reps uint32 - if !safeReadBits(br, code, &reps) { - s.code = code - s.context_index = context_index - return decoderNeedsMoreInput - } - - reps += 1 << code - if context_index+reps > context_map_size { - return decoderErrorFormatContextMapRepeat - } - - for { - context_map[context_index] = 0 - context_index++ - reps-- - if reps == 0 { - break - } - } - } - } - } - fallthrough - - case stateContextMapTransform: - var bits uint32 - if !safeReadBits(br, 1, &bits) { - s.substate_context_map = stateContextMapTransform - return decoderNeedsMoreInput - } - - if bits != 0 { - inverseMoveToFrontTransform(*context_map_arg, context_map_size, s) - } - - s.substate_context_map = stateContextMapNone - return decoderSuccess - - default: - return decoderErrorUnreachable - } -} - -/* Decodes a command or literal and updates block type ring-buffer. - Reads 3..54 bits. */ -func decodeBlockTypeAndLength(safe int, s *Reader, tree_type int) bool { - var max_block_type uint32 = s.num_block_types[tree_type] - type_tree := s.block_type_trees[tree_type*huffmanMaxSize258:] - len_tree := s.block_len_trees[tree_type*huffmanMaxSize26:] - var br *bitReader = &s.br - var ringbuffer []uint32 = s.block_type_rb[tree_type*2:] - var block_type uint32 - if max_block_type <= 1 { - return false - } - - /* Read 0..15 + 3..39 bits. */ - if safe == 0 { - block_type = readSymbol(type_tree, br) - s.block_length[tree_type] = readBlockLength(len_tree, br) - } else { - var memento bitReaderState - bitReaderSaveState(br, &memento) - if !safeReadSymbol(type_tree, br, &block_type) { - return false - } - if !safeReadBlockLength(s, &s.block_length[tree_type], len_tree, br) { - s.substate_read_block_length = stateReadBlockLengthNone - bitReaderRestoreState(br, &memento) - return false - } - } - - if block_type == 1 { - block_type = ringbuffer[1] + 1 - } else if block_type == 0 { - block_type = ringbuffer[0] - } else { - block_type -= 2 - } - - if block_type >= max_block_type { - block_type -= max_block_type - } - - ringbuffer[0] = ringbuffer[1] - ringbuffer[1] = block_type - return true -} - -func detectTrivialLiteralBlockTypes(s *Reader) { - var i uint - for i = 0; i < 8; i++ { - s.trivial_literal_contexts[i] = 0 - } - for i = 0; uint32(i) < s.num_block_types[0]; i++ { - var offset uint = i << literalContextBits - var error uint = 0 - var sample uint = uint(s.context_map[offset]) - var j uint - for j = 0; j < 1<>5] |= 1 << (i & 31) - } - } -} - -func prepareLiteralDecoding(s *Reader) { - var context_mode byte - var trivial uint - var block_type uint32 = s.block_type_rb[1] - var context_offset uint32 = block_type << literalContextBits - s.context_map_slice = s.context_map[context_offset:] - trivial = uint(s.trivial_literal_contexts[block_type>>5]) - s.trivial_literal_context = int((trivial >> (block_type & 31)) & 1) - s.literal_htree = []huffmanCode(s.literal_hgroup.htrees[s.context_map_slice[0]]) - context_mode = s.context_modes[block_type] & 3 - s.context_lookup = getContextLUT(int(context_mode)) -} - -/* Decodes the block type and updates the state for literal context. - Reads 3..54 bits. */ -func decodeLiteralBlockSwitchInternal(safe int, s *Reader) bool { - if !decodeBlockTypeAndLength(safe, s, 0) { - return false - } - - prepareLiteralDecoding(s) - return true -} - -func decodeLiteralBlockSwitch(s *Reader) { - decodeLiteralBlockSwitchInternal(0, s) -} - -func safeDecodeLiteralBlockSwitch(s *Reader) bool { - return decodeLiteralBlockSwitchInternal(1, s) -} - -/* Block switch for insert/copy length. - Reads 3..54 bits. */ -func decodeCommandBlockSwitchInternal(safe int, s *Reader) bool { - if !decodeBlockTypeAndLength(safe, s, 1) { - return false - } - - s.htree_command = []huffmanCode(s.insert_copy_hgroup.htrees[s.block_type_rb[3]]) - return true -} - -func decodeCommandBlockSwitch(s *Reader) { - decodeCommandBlockSwitchInternal(0, s) -} - -func safeDecodeCommandBlockSwitch(s *Reader) bool { - return decodeCommandBlockSwitchInternal(1, s) -} - -/* Block switch for distance codes. - Reads 3..54 bits. */ -func decodeDistanceBlockSwitchInternal(safe int, s *Reader) bool { - if !decodeBlockTypeAndLength(safe, s, 2) { - return false - } - - s.dist_context_map_slice = s.dist_context_map[s.block_type_rb[5]< s.ringbuffer_size { - pos = uint(s.ringbuffer_size) - } else { - pos = uint(s.pos) - } - var partial_pos_rb uint = (s.rb_roundtrips * uint(s.ringbuffer_size)) + pos - return partial_pos_rb - s.partial_pos_out -} - -/* Dumps output. - Returns BROTLI_DECODER_NEEDS_MORE_OUTPUT only if there is more output to push - and either ring-buffer is as big as window size, or |force| is true. */ -func writeRingBuffer(s *Reader, available_out *uint, next_out *[]byte, total_out *uint, force bool) int { - start := s.ringbuffer[s.partial_pos_out&uint(s.ringbuffer_mask):] - var to_write uint = unwrittenBytes(s, true) - var num_written uint = *available_out - if num_written > to_write { - num_written = to_write - } - - if s.meta_block_remaining_len < 0 { - return decoderErrorFormatBlockLength1 - } - - if next_out != nil && *next_out == nil { - *next_out = start - } else { - if next_out != nil { - copy(*next_out, start[:num_written]) - *next_out = (*next_out)[num_written:] - } - } - - *available_out -= num_written - s.partial_pos_out += num_written - if total_out != nil { - *total_out = s.partial_pos_out - } - - if num_written < to_write { - if s.ringbuffer_size == 1<= s.ringbuffer_size { - s.pos -= s.ringbuffer_size - s.rb_roundtrips++ - if uint(s.pos) != 0 { - s.should_wrap_ringbuffer = 1 - } else { - s.should_wrap_ringbuffer = 0 - } - } - - return decoderSuccess -} - -func wrapRingBuffer(s *Reader) { - if s.should_wrap_ringbuffer != 0 { - copy(s.ringbuffer, s.ringbuffer_end[:uint(s.pos)]) - s.should_wrap_ringbuffer = 0 - } -} - -/* Allocates ring-buffer. - - s->ringbuffer_size MUST be updated by BrotliCalculateRingBufferSize before - this function is called. - - Last two bytes of ring-buffer are initialized to 0, so context calculation - could be done uniformly for the first two and all other positions. */ -func ensureRingBuffer(s *Reader) bool { - var old_ringbuffer []byte - if s.ringbuffer_size == s.new_ringbuffer_size { - return true - } - spaceNeeded := int(s.new_ringbuffer_size) + int(kRingBufferWriteAheadSlack) - if len(s.ringbuffer) < spaceNeeded { - old_ringbuffer = s.ringbuffer - s.ringbuffer = make([]byte, spaceNeeded) - } - - s.ringbuffer[s.new_ringbuffer_size-2] = 0 - s.ringbuffer[s.new_ringbuffer_size-1] = 0 - - if old_ringbuffer != nil { - copy(s.ringbuffer, old_ringbuffer[:uint(s.pos)]) - } - - s.ringbuffer_size = s.new_ringbuffer_size - s.ringbuffer_mask = s.new_ringbuffer_size - 1 - s.ringbuffer_end = s.ringbuffer[s.ringbuffer_size:] - - return true -} - -func copyUncompressedBlockToOutput(available_out *uint, next_out *[]byte, total_out *uint, s *Reader) int { - /* TODO: avoid allocation for single uncompressed block. */ - if !ensureRingBuffer(s) { - return decoderErrorAllocRingBuffer1 - } - - /* State machine */ - for { - switch s.substate_uncompressed { - case stateUncompressedNone: - { - var nbytes int = int(getRemainingBytes(&s.br)) - if nbytes > s.meta_block_remaining_len { - nbytes = s.meta_block_remaining_len - } - - if s.pos+nbytes > s.ringbuffer_size { - nbytes = s.ringbuffer_size - s.pos - } - - /* Copy remaining bytes from s->br.buf_ to ring-buffer. */ - copyBytes(s.ringbuffer[s.pos:], &s.br, uint(nbytes)) - - s.pos += nbytes - s.meta_block_remaining_len -= nbytes - if s.pos < 1<>1 >= min_size { - new_ringbuffer_size >>= 1 - } - } - - s.new_ringbuffer_size = new_ringbuffer_size -} - -/* Reads 1..256 2-bit context modes. */ -func readContextModes(s *Reader) int { - var br *bitReader = &s.br - var i int = s.loop_counter - - for i < int(s.num_block_types[0]) { - var bits uint32 - if !safeReadBits(br, 2, &bits) { - s.loop_counter = i - return decoderNeedsMoreInput - } - - s.context_modes[i] = byte(bits) - i++ - } - - return decoderSuccess -} - -func takeDistanceFromRingBuffer(s *Reader) { - if s.distance_code == 0 { - s.dist_rb_idx-- - s.distance_code = s.dist_rb[s.dist_rb_idx&3] - - /* Compensate double distance-ring-buffer roll for dictionary items. */ - s.distance_context = 1 - } else { - var distance_code int = s.distance_code << 1 - const kDistanceShortCodeIndexOffset uint32 = 0xAAAFFF1B - const kDistanceShortCodeValueOffset uint32 = 0xFA5FA500 - var v int = (s.dist_rb_idx + int(kDistanceShortCodeIndexOffset>>uint(distance_code))) & 0x3 - /* kDistanceShortCodeIndexOffset has 2-bit values from LSB: - 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 */ - - /* kDistanceShortCodeValueOffset has 2-bit values from LSB: - -0, 0,-0, 0,-1, 1,-2, 2,-3, 3,-1, 1,-2, 2,-3, 3 */ - s.distance_code = s.dist_rb[v] - - v = int(kDistanceShortCodeValueOffset>>uint(distance_code)) & 0x3 - if distance_code&0x3 != 0 { - s.distance_code += v - } else { - s.distance_code -= v - if s.distance_code <= 0 { - /* A huge distance will cause a () soon. - This is a little faster than failing here. */ - s.distance_code = 0x7FFFFFFF - } - } - } -} - -func safeReadBitsMaybeZero(br *bitReader, n_bits uint32, val *uint32) bool { - if n_bits != 0 { - return safeReadBits(br, n_bits, val) - } else { - *val = 0 - return true - } -} - -/* Precondition: s->distance_code < 0. */ -func readDistanceInternal(safe int, s *Reader, br *bitReader) bool { - var distval int - var memento bitReaderState - var distance_tree []huffmanCode = []huffmanCode(s.distance_hgroup.htrees[s.dist_htree_index]) - if safe == 0 { - s.distance_code = int(readSymbol(distance_tree, br)) - } else { - var code uint32 - bitReaderSaveState(br, &memento) - if !safeReadSymbol(distance_tree, br, &code) { - return false - } - - s.distance_code = int(code) - } - - /* Convert the distance code to the actual distance by possibly - looking up past distances from the s->ringbuffer. */ - s.distance_context = 0 - - if s.distance_code&^0xF == 0 { - takeDistanceFromRingBuffer(s) - s.block_length[2]-- - return true - } - - distval = s.distance_code - int(s.num_direct_distance_codes) - if distval >= 0 { - var nbits uint32 - var postfix int - var offset int - if safe == 0 && (s.distance_postfix_bits == 0) { - nbits = (uint32(distval) >> 1) + 1 - offset = ((2 + (distval & 1)) << nbits) - 4 - s.distance_code = int(s.num_direct_distance_codes) + offset + int(readBits(br, nbits)) - } else { - /* This branch also works well when s->distance_postfix_bits == 0. */ - var bits uint32 - postfix = distval & s.distance_postfix_mask - distval >>= s.distance_postfix_bits - nbits = (uint32(distval) >> 1) + 1 - if safe != 0 { - if !safeReadBitsMaybeZero(br, nbits, &bits) { - s.distance_code = -1 /* Restore precondition. */ - bitReaderRestoreState(br, &memento) - return false - } - } else { - bits = readBits(br, nbits) - } - - offset = ((2 + (distval & 1)) << nbits) - 4 - s.distance_code = int(s.num_direct_distance_codes) + ((offset + int(bits)) << s.distance_postfix_bits) + postfix - } - } - - s.distance_code = s.distance_code - numDistanceShortCodes + 1 - s.block_length[2]-- - return true -} - -func readDistance(s *Reader, br *bitReader) { - readDistanceInternal(0, s, br) -} - -func safeReadDistance(s *Reader, br *bitReader) bool { - return readDistanceInternal(1, s, br) -} - -func readCommandInternal(safe int, s *Reader, br *bitReader, insert_length *int) bool { - var cmd_code uint32 - var insert_len_extra uint32 = 0 - var copy_length uint32 - var v cmdLutElement - var memento bitReaderState - if safe == 0 { - cmd_code = readSymbol(s.htree_command, br) - } else { - bitReaderSaveState(br, &memento) - if !safeReadSymbol(s.htree_command, br, &cmd_code) { - return false - } - } - - v = kCmdLut[cmd_code] - s.distance_code = int(v.distance_code) - s.distance_context = int(v.context) - s.dist_htree_index = s.dist_context_map_slice[s.distance_context] - *insert_length = int(v.insert_len_offset) - if safe == 0 { - if v.insert_len_extra_bits != 0 { - insert_len_extra = readBits(br, uint32(v.insert_len_extra_bits)) - } - - copy_length = readBits(br, uint32(v.copy_len_extra_bits)) - } else { - if !safeReadBitsMaybeZero(br, uint32(v.insert_len_extra_bits), &insert_len_extra) || !safeReadBitsMaybeZero(br, uint32(v.copy_len_extra_bits), ©_length) { - bitReaderRestoreState(br, &memento) - return false - } - } - - s.copy_length = int(copy_length) + int(v.copy_len_offset) - s.block_length[1]-- - *insert_length += int(insert_len_extra) - return true -} - -func readCommand(s *Reader, br *bitReader, insert_length *int) { - readCommandInternal(0, s, br, insert_length) -} - -func safeReadCommand(s *Reader, br *bitReader, insert_length *int) bool { - return readCommandInternal(1, s, br, insert_length) -} - -func checkInputAmountMaybeSafe(safe int, br *bitReader, num uint) bool { - if safe != 0 { - return true - } - - return checkInputAmount(br, num) -} - -func processCommandsInternal(safe int, s *Reader) int { - var pos int = s.pos - var i int = s.loop_counter - var result int = decoderSuccess - var br *bitReader = &s.br - var hc []huffmanCode - - if !checkInputAmountMaybeSafe(safe, br, 28) { - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - - if safe == 0 { - warmupBitReader(br) - } - - /* Jump into state machine. */ - if s.state == stateCommandBegin { - goto CommandBegin - } else if s.state == stateCommandInner { - goto CommandInner - } else if s.state == stateCommandPostDecodeLiterals { - goto CommandPostDecodeLiterals - } else if s.state == stateCommandPostWrapCopy { - goto CommandPostWrapCopy - } else { - return decoderErrorUnreachable - } - -CommandBegin: - if safe != 0 { - s.state = stateCommandBegin - } - - if !checkInputAmountMaybeSafe(safe, br, 28) { /* 156 bits + 7 bytes */ - s.state = stateCommandBegin - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - - if s.block_length[1] == 0 { - if safe != 0 { - if !safeDecodeCommandBlockSwitch(s) { - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - } else { - decodeCommandBlockSwitch(s) - } - - goto CommandBegin - } - - /* Read the insert/copy length in the command. */ - if safe != 0 { - if !safeReadCommand(s, br, &i) { - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - } else { - readCommand(s, br, &i) - } - - if i == 0 { - goto CommandPostDecodeLiterals - } - - s.meta_block_remaining_len -= i - -CommandInner: - if safe != 0 { - s.state = stateCommandInner - } - - /* Read the literals in the command. */ - if s.trivial_literal_context != 0 { - var bits uint32 - var value uint32 - preloadSymbol(safe, s.literal_htree, br, &bits, &value) - for { - if !checkInputAmountMaybeSafe(safe, br, 28) { /* 162 bits + 7 bytes */ - s.state = stateCommandInner - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - - if s.block_length[0] == 0 { - if safe != 0 { - if !safeDecodeLiteralBlockSwitch(s) { - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - } else { - decodeLiteralBlockSwitch(s) - } - - preloadSymbol(safe, s.literal_htree, br, &bits, &value) - if s.trivial_literal_context == 0 { - goto CommandInner - } - } - - if safe == 0 { - s.ringbuffer[pos] = byte(readPreloadedSymbol(s.literal_htree, br, &bits, &value)) - } else { - var literal uint32 - if !safeReadSymbol(s.literal_htree, br, &literal) { - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - - s.ringbuffer[pos] = byte(literal) - } - - s.block_length[0]-- - pos++ - if pos == s.ringbuffer_size { - s.state = stateCommandInnerWrite - i-- - goto saveStateAndReturn - } - i-- - if i == 0 { - break - } - } - } else { - var p1 byte = s.ringbuffer[(pos-1)&s.ringbuffer_mask] - var p2 byte = s.ringbuffer[(pos-2)&s.ringbuffer_mask] - for { - var context byte - if !checkInputAmountMaybeSafe(safe, br, 28) { /* 162 bits + 7 bytes */ - s.state = stateCommandInner - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - - if s.block_length[0] == 0 { - if safe != 0 { - if !safeDecodeLiteralBlockSwitch(s) { - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - } else { - decodeLiteralBlockSwitch(s) - } - - if s.trivial_literal_context != 0 { - goto CommandInner - } - } - - context = getContext(p1, p2, s.context_lookup) - hc = []huffmanCode(s.literal_hgroup.htrees[s.context_map_slice[context]]) - p2 = p1 - if safe == 0 { - p1 = byte(readSymbol(hc, br)) - } else { - var literal uint32 - if !safeReadSymbol(hc, br, &literal) { - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - - p1 = byte(literal) - } - - s.ringbuffer[pos] = p1 - s.block_length[0]-- - pos++ - if pos == s.ringbuffer_size { - s.state = stateCommandInnerWrite - i-- - goto saveStateAndReturn - } - i-- - if i == 0 { - break - } - } - } - - if s.meta_block_remaining_len <= 0 { - s.state = stateMetablockDone - goto saveStateAndReturn - } - -CommandPostDecodeLiterals: - if safe != 0 { - s.state = stateCommandPostDecodeLiterals - } - - if s.distance_code >= 0 { - /* Implicit distance case. */ - if s.distance_code != 0 { - s.distance_context = 0 - } else { - s.distance_context = 1 - } - - s.dist_rb_idx-- - s.distance_code = s.dist_rb[s.dist_rb_idx&3] - } else { - /* Read distance code in the command, unless it was implicitly zero. */ - if s.block_length[2] == 0 { - if safe != 0 { - if !safeDecodeDistanceBlockSwitch(s) { - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - } else { - decodeDistanceBlockSwitch(s) - } - } - - if safe != 0 { - if !safeReadDistance(s, br) { - result = decoderNeedsMoreInput - goto saveStateAndReturn - } - } else { - readDistance(s, br) - } - } - - if s.max_distance != s.max_backward_distance { - if pos < s.max_backward_distance { - s.max_distance = pos - } else { - s.max_distance = s.max_backward_distance - } - } - - i = s.copy_length - - /* Apply copy of LZ77 back-reference, or static dictionary reference if - the distance is larger than the max LZ77 distance */ - if s.distance_code > s.max_distance { - /* The maximum allowed distance is BROTLI_MAX_ALLOWED_DISTANCE = 0x7FFFFFFC. - With this choice, no signed overflow can occur after decoding - a special distance code (e.g., after adding 3 to the last distance). */ - if s.distance_code > maxAllowedDistance { - return decoderErrorFormatDistance - } - - if i >= minDictionaryWordLength && i <= maxDictionaryWordLength { - var address int = s.distance_code - s.max_distance - 1 - var words *dictionary = s.dictionary - var trans *transforms = s.transforms - var offset int = int(s.dictionary.offsets_by_length[i]) - var shift uint32 = uint32(s.dictionary.size_bits_by_length[i]) - var mask int = int(bitMask(shift)) - var word_idx int = address & mask - var transform_idx int = address >> shift - - /* Compensate double distance-ring-buffer roll. */ - s.dist_rb_idx += s.distance_context - - offset += word_idx * i - if words.data == nil { - return decoderErrorDictionaryNotSet - } - - if transform_idx < int(trans.num_transforms) { - word := words.data[offset:] - var len int = i - if transform_idx == int(trans.cutOffTransforms[0]) { - copy(s.ringbuffer[pos:], word[:uint(len)]) - } else { - len = transformDictionaryWord(s.ringbuffer[pos:], word, int(len), trans, transform_idx) - } - - pos += int(len) - s.meta_block_remaining_len -= int(len) - if pos >= s.ringbuffer_size { - s.state = stateCommandPostWrite1 - goto saveStateAndReturn - } - } else { - return decoderErrorFormatTransform - } - } else { - return decoderErrorFormatDictionary - } - } else { - var src_start int = (pos - s.distance_code) & s.ringbuffer_mask - copy_dst := s.ringbuffer[pos:] - copy_src := s.ringbuffer[src_start:] - var dst_end int = pos + i - var src_end int = src_start + i - - /* Update the recent distances cache. */ - s.dist_rb[s.dist_rb_idx&3] = s.distance_code - - s.dist_rb_idx++ - s.meta_block_remaining_len -= i - - /* There are 32+ bytes of slack in the ring-buffer allocation. - Also, we have 16 short codes, that make these 16 bytes irrelevant - in the ring-buffer. Let's copy over them as a first guess. */ - copy(copy_dst, copy_src[:16]) - - if src_end > pos && dst_end > src_start { - /* Regions intersect. */ - goto CommandPostWrapCopy - } - - if dst_end >= s.ringbuffer_size || src_end >= s.ringbuffer_size { - /* At least one region wraps. */ - goto CommandPostWrapCopy - } - - pos += i - if i > 16 { - if i > 32 { - copy(copy_dst[16:], copy_src[16:][:uint(i-16)]) - } else { - /* This branch covers about 45% cases. - Fixed size short copy allows more compiler optimizations. */ - copy(copy_dst[16:], copy_src[16:][:16]) - } - } - } - - if s.meta_block_remaining_len <= 0 { - /* Next metablock, if any. */ - s.state = stateMetablockDone - - goto saveStateAndReturn - } else { - goto CommandBegin - } -CommandPostWrapCopy: - { - var wrap_guard int = s.ringbuffer_size - pos - for { - i-- - if i < 0 { - break - } - s.ringbuffer[pos] = s.ringbuffer[(pos-s.distance_code)&s.ringbuffer_mask] - pos++ - wrap_guard-- - if wrap_guard == 0 { - s.state = stateCommandPostWrite2 - goto saveStateAndReturn - } - } - } - - if s.meta_block_remaining_len <= 0 { - /* Next metablock, if any. */ - s.state = stateMetablockDone - - goto saveStateAndReturn - } else { - goto CommandBegin - } - -saveStateAndReturn: - s.pos = pos - s.loop_counter = i - return result -} - -func processCommands(s *Reader) int { - return processCommandsInternal(0, s) -} - -func safeProcessCommands(s *Reader) int { - return processCommandsInternal(1, s) -} - -/* Returns the maximum number of distance symbols which can only represent - distances not exceeding BROTLI_MAX_ALLOWED_DISTANCE. */ - -var maxDistanceSymbol_bound = [maxNpostfix + 1]uint32{0, 4, 12, 28} -var maxDistanceSymbol_diff = [maxNpostfix + 1]uint32{73, 126, 228, 424} - -func maxDistanceSymbol(ndirect uint32, npostfix uint32) uint32 { - var postfix uint32 = 1 << npostfix - if ndirect < maxDistanceSymbol_bound[npostfix] { - return ndirect + maxDistanceSymbol_diff[npostfix] + postfix - } else if ndirect > maxDistanceSymbol_bound[npostfix]+postfix { - return ndirect + maxDistanceSymbol_diff[npostfix] - } else { - return maxDistanceSymbol_bound[npostfix] + maxDistanceSymbol_diff[npostfix] + postfix - } -} - -/* Invariant: input stream is never overconsumed: - - invalid input implies that the whole stream is invalid -> any amount of - input could be read and discarded - - when result is "needs more input", then at least one more byte is REQUIRED - to complete decoding; all input data MUST be consumed by decoder, so - client could swap the input buffer - - when result is "needs more output" decoder MUST ensure that it doesn't - hold more than 7 bits in bit reader; this saves client from swapping input - buffer ahead of time - - when result is "success" decoder MUST return all unused data back to input - buffer; this is possible because the invariant is held on enter */ -func decoderDecompressStream(s *Reader, available_in *uint, next_in *[]byte, available_out *uint, next_out *[]byte) int { - var result int = decoderSuccess - var br *bitReader = &s.br - - /* Do not try to process further in a case of unrecoverable error. */ - if int(s.error_code) < 0 { - return decoderResultError - } - - if *available_out != 0 && (next_out == nil || *next_out == nil) { - return saveErrorCode(s, decoderErrorInvalidArguments) - } - - if *available_out == 0 { - next_out = nil - } - if s.buffer_length == 0 { /* Just connect bit reader to input stream. */ - br.input_len = *available_in - br.input = *next_in - br.byte_pos = 0 - } else { - /* At least one byte of input is required. More than one byte of input may - be required to complete the transaction -> reading more data must be - done in a loop -> do it in a main loop. */ - result = decoderNeedsMoreInput - - br.input = s.buffer.u8[:] - br.byte_pos = 0 - } - - /* State machine */ - for { - if result != decoderSuccess { - /* Error, needs more input/output. */ - if result == decoderNeedsMoreInput { - if s.ringbuffer != nil { /* Pro-actively push output. */ - var intermediate_result int = writeRingBuffer(s, available_out, next_out, nil, true) - - /* WriteRingBuffer checks s->meta_block_remaining_len validity. */ - if int(intermediate_result) < 0 { - result = intermediate_result - break - } - } - - if s.buffer_length != 0 { /* Used with internal buffer. */ - if br.byte_pos == br.input_len { - /* Successfully finished read transaction. - Accumulator contains less than 8 bits, because internal buffer - is expanded byte-by-byte until it is enough to complete read. */ - s.buffer_length = 0 - - /* Switch to input stream and restart. */ - result = decoderSuccess - - br.input_len = *available_in - br.input = *next_in - br.byte_pos = 0 - continue - } else if *available_in != 0 { - /* Not enough data in buffer, but can take one more byte from - input stream. */ - result = decoderSuccess - - s.buffer.u8[s.buffer_length] = (*next_in)[0] - s.buffer_length++ - br.input_len = uint(s.buffer_length) - *next_in = (*next_in)[1:] - (*available_in)-- - - /* Retry with more data in buffer. */ - continue - } - - /* Can't finish reading and no more input. */ - break - /* Input stream doesn't contain enough input. */ - } else { - /* Copy tail to internal buffer and return. */ - *next_in = br.input[br.byte_pos:] - - *available_in = br.input_len - br.byte_pos - for *available_in != 0 { - s.buffer.u8[s.buffer_length] = (*next_in)[0] - s.buffer_length++ - *next_in = (*next_in)[1:] - (*available_in)-- - } - - break - } - } - - /* Unreachable. */ - - /* Fail or needs more output. */ - if s.buffer_length != 0 { - /* Just consumed the buffered input and produced some output. Otherwise - it would result in "needs more input". Reset internal buffer. */ - s.buffer_length = 0 - } else { - /* Using input stream in last iteration. When decoder switches to input - stream it has less than 8 bits in accumulator, so it is safe to - return unused accumulator bits there. */ - bitReaderUnload(br) - - *available_in = br.input_len - br.byte_pos - *next_in = br.input[br.byte_pos:] - } - - break - } - - switch s.state { - /* Prepare to the first read. */ - case stateUninited: - if !warmupBitReader(br) { - result = decoderNeedsMoreInput - break - } - - /* Decode window size. */ - result = decodeWindowBits(s, br) /* Reads 1..8 bits. */ - if result != decoderSuccess { - break - } - - if s.large_window { - s.state = stateLargeWindowBits - break - } - - s.state = stateInitialize - - case stateLargeWindowBits: - if !safeReadBits(br, 6, &s.window_bits) { - result = decoderNeedsMoreInput - break - } - - if s.window_bits < largeMinWbits || s.window_bits > largeMaxWbits { - result = decoderErrorFormatWindowBits - break - } - - s.state = stateInitialize - fallthrough - - /* Maximum distance, see section 9.1. of the spec. */ - /* Fall through. */ - case stateInitialize: - s.max_backward_distance = (1 << s.window_bits) - windowGap - - if s.block_type_trees == nil { - /* Allocate memory for both block_type_trees and block_len_trees. */ - s.block_type_trees = make([]huffmanCode, (3 * (huffmanMaxSize258 + huffmanMaxSize26))) - } - - s.block_len_trees = s.block_type_trees[3*huffmanMaxSize258:] - - s.state = stateMetablockBegin - fallthrough - - /* Fall through. */ - case stateMetablockBegin: - decoderStateMetablockBegin(s) - - s.state = stateMetablockHeader - fallthrough - - /* Fall through. */ - case stateMetablockHeader: - result = decodeMetaBlockLength(s, br) - /* Reads 2 - 31 bits. */ - if result != decoderSuccess { - break - } - - if s.is_metadata != 0 || s.is_uncompressed != 0 { - if !bitReaderJumpToByteBoundary(br) { - result = decoderErrorFormatPadding1 - break - } - } - - if s.is_metadata != 0 { - s.state = stateMetadata - break - } - - if s.meta_block_remaining_len == 0 { - s.state = stateMetablockDone - break - } - - calculateRingBufferSize(s) - if s.is_uncompressed != 0 { - s.state = stateUncompressed - break - } - - s.loop_counter = 0 - s.state = stateHuffmanCode0 - - case stateUncompressed: - result = copyUncompressedBlockToOutput(available_out, next_out, nil, s) - if result == decoderSuccess { - s.state = stateMetablockDone - } - - case stateMetadata: - for ; s.meta_block_remaining_len > 0; s.meta_block_remaining_len-- { - var bits uint32 - - /* Read one byte and ignore it. */ - if !safeReadBits(br, 8, &bits) { - result = decoderNeedsMoreInput - break - } - } - - if result == decoderSuccess { - s.state = stateMetablockDone - } - - case stateHuffmanCode0: - if s.loop_counter >= 3 { - s.state = stateMetablockHeader2 - break - } - - /* Reads 1..11 bits. */ - result = decodeVarLenUint8(s, br, &s.num_block_types[s.loop_counter]) - - if result != decoderSuccess { - break - } - - s.num_block_types[s.loop_counter]++ - if s.num_block_types[s.loop_counter] < 2 { - s.loop_counter++ - break - } - - s.state = stateHuffmanCode1 - fallthrough - - case stateHuffmanCode1: - { - var alphabet_size uint32 = s.num_block_types[s.loop_counter] + 2 - var tree_offset int = s.loop_counter * huffmanMaxSize258 - result = readHuffmanCode(alphabet_size, alphabet_size, s.block_type_trees[tree_offset:], nil, s) - if result != decoderSuccess { - break - } - s.state = stateHuffmanCode2 - } - fallthrough - - case stateHuffmanCode2: - { - var alphabet_size uint32 = numBlockLenSymbols - var tree_offset int = s.loop_counter * huffmanMaxSize26 - result = readHuffmanCode(alphabet_size, alphabet_size, s.block_len_trees[tree_offset:], nil, s) - if result != decoderSuccess { - break - } - s.state = stateHuffmanCode3 - } - fallthrough - - case stateHuffmanCode3: - var tree_offset int = s.loop_counter * huffmanMaxSize26 - if !safeReadBlockLength(s, &s.block_length[s.loop_counter], s.block_len_trees[tree_offset:], br) { - result = decoderNeedsMoreInput - break - } - - s.loop_counter++ - s.state = stateHuffmanCode0 - - case stateMetablockHeader2: - { - var bits uint32 - if !safeReadBits(br, 6, &bits) { - result = decoderNeedsMoreInput - break - } - - s.distance_postfix_bits = bits & bitMask(2) - bits >>= 2 - s.num_direct_distance_codes = numDistanceShortCodes + (bits << s.distance_postfix_bits) - s.distance_postfix_mask = int(bitMask(s.distance_postfix_bits)) - s.context_modes = make([]byte, uint(s.num_block_types[0])) - if s.context_modes == nil { - result = decoderErrorAllocContextModes - break - } - - s.loop_counter = 0 - s.state = stateContextModes - } - fallthrough - - case stateContextModes: - result = readContextModes(s) - - if result != decoderSuccess { - break - } - - s.state = stateContextMap1 - fallthrough - - case stateContextMap1: - result = decodeContextMap(s.num_block_types[0]<= 3 { - prepareLiteralDecoding(s) - s.dist_context_map_slice = s.dist_context_map - s.htree_command = []huffmanCode(s.insert_copy_hgroup.htrees[0]) - if !ensureRingBuffer(s) { - result = decoderErrorAllocRingBuffer2 - break - } - - s.state = stateCommandBegin - } - - case stateCommandBegin, stateCommandInner, stateCommandPostDecodeLiterals, stateCommandPostWrapCopy: - result = processCommands(s) - - if result == decoderNeedsMoreInput { - result = safeProcessCommands(s) - } - - case stateCommandInnerWrite, stateCommandPostWrite1, stateCommandPostWrite2: - result = writeRingBuffer(s, available_out, next_out, nil, false) - - if result != decoderSuccess { - break - } - - wrapRingBuffer(s) - if s.ringbuffer_size == 1<= uint64(block_size) { - return 0 - } - return block_size - uint(delta) -} - -/* Wraps 64-bit input position to 32-bit ring-buffer position preserving - "not-a-first-lap" feature. */ -func wrapPosition(position uint64) uint32 { - var result uint32 = uint32(position) - var gb uint64 = position >> 30 - if gb > 2 { - /* Wrap every 2GiB; The first 3GB are continuous. */ - result = result&((1<<30)-1) | (uint32((gb-1)&1)+1)<<30 - } - - return result -} - -func (s *Writer) getStorage(size int) []byte { - if len(s.storage) < size { - s.storage = make([]byte, size) - } - - return s.storage -} - -func hashTableSize(max_table_size uint, input_size uint) uint { - var htsize uint = 256 - for htsize < max_table_size && htsize < input_size { - htsize <<= 1 - } - - return htsize -} - -func getHashTable(s *Writer, quality int, input_size uint, table_size *uint) []int { - var max_table_size uint = maxHashTableSize(quality) - var htsize uint = hashTableSize(max_table_size, input_size) - /* Use smaller hash table when input.size() is smaller, since we - fill the table, incurring O(hash table size) overhead for - compression, and if the input is short, we won't need that - many hash table entries anyway. */ - - var table []int - assert(max_table_size >= 256) - if quality == fastOnePassCompressionQuality { - /* Only odd shifts are supported by fast-one-pass. */ - if htsize&0xAAAAA == 0 { - htsize <<= 1 - } - } - - if htsize <= uint(len(s.small_table_)) { - table = s.small_table_[:] - } else { - if htsize > s.large_table_size_ { - s.large_table_size_ = htsize - s.large_table_ = nil - s.large_table_ = make([]int, htsize) - } - - table = s.large_table_ - } - - *table_size = htsize - for i := 0; i < int(htsize); i++ { - table[i] = 0 - } - return table -} - -func encodeWindowBits(lgwin int, large_window bool, last_bytes *uint16, last_bytes_bits *byte) { - if large_window { - *last_bytes = uint16((lgwin&0x3F)<<8 | 0x11) - *last_bytes_bits = 14 - } else { - if lgwin == 16 { - *last_bytes = 0 - *last_bytes_bits = 1 - } else if lgwin == 17 { - *last_bytes = 1 - *last_bytes_bits = 7 - } else if lgwin > 17 { - *last_bytes = uint16((lgwin-17)<<1 | 0x01) - *last_bytes_bits = 4 - } else { - *last_bytes = uint16((lgwin-8)<<4 | 0x01) - *last_bytes_bits = 7 - } - } -} - -/* Decide about the context map based on the ability of the prediction - ability of the previous byte UTF8-prefix on the next byte. The - prediction ability is calculated as Shannon entropy. Here we need - Shannon entropy instead of 'BitsEntropy' since the prefix will be - encoded with the remaining 6 bits of the following byte, and - BitsEntropy will assume that symbol to be stored alone using Huffman - coding. */ - -var kStaticContextMapContinuation = [64]uint32{ - 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -} -var kStaticContextMapSimpleUTF8 = [64]uint32{ - 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -} - -func chooseContextMap(quality int, bigram_histo []uint32, num_literal_contexts *uint, literal_context_map *[]uint32) { - var monogram_histo = [3]uint32{0} - var two_prefix_histo = [6]uint32{0} - var total uint - var i uint - var dummy uint - var entropy [4]float64 - for i = 0; i < 9; i++ { - monogram_histo[i%3] += bigram_histo[i] - two_prefix_histo[i%6] += bigram_histo[i] - } - - entropy[1] = shannonEntropy(monogram_histo[:], 3, &dummy) - entropy[2] = (shannonEntropy(two_prefix_histo[:], 3, &dummy) + shannonEntropy(two_prefix_histo[3:], 3, &dummy)) - entropy[3] = 0 - for i = 0; i < 3; i++ { - entropy[3] += shannonEntropy(bigram_histo[3*i:], 3, &dummy) - } - - total = uint(monogram_histo[0] + monogram_histo[1] + monogram_histo[2]) - assert(total != 0) - entropy[0] = 1.0 / float64(total) - entropy[1] *= entropy[0] - entropy[2] *= entropy[0] - entropy[3] *= entropy[0] - - if quality < minQualityForHqContextModeling { - /* 3 context models is a bit slower, don't use it at lower qualities. */ - entropy[3] = entropy[1] * 10 - } - - /* If expected savings by symbol are less than 0.2 bits, skip the - context modeling -- in exchange for faster decoding speed. */ - if entropy[1]-entropy[2] < 0.2 && entropy[1]-entropy[3] < 0.2 { - *num_literal_contexts = 1 - } else if entropy[2]-entropy[3] < 0.02 { - *num_literal_contexts = 2 - *literal_context_map = kStaticContextMapSimpleUTF8[:] - } else { - *num_literal_contexts = 3 - *literal_context_map = kStaticContextMapContinuation[:] - } -} - -/* Decide if we want to use a more complex static context map containing 13 - context values, based on the entropy reduction of histograms over the - first 5 bits of literals. */ - -var kStaticContextMapComplexUTF8 = [64]uint32{ - 11, 11, 12, 12, /* 0 special */ - 0, 0, 0, 0, /* 4 lf */ - 1, 1, 9, 9, /* 8 space */ - 2, 2, 2, 2, /* !, first after space/lf and after something else. */ - 1, 1, 1, 1, /* " */ - 8, 3, 3, 3, /* % */ - 1, 1, 1, 1, /* ({[ */ - 2, 2, 2, 2, /* }]) */ - 8, 4, 4, 4, /* :; */ - 8, 7, 4, 4, /* . */ - 8, 0, 0, 0, /* > */ - 3, 3, 3, 3, /* [0..9] */ - 5, 5, 10, 5, /* [A-Z] */ - 5, 5, 10, 5, - 6, 6, 6, 6, /* [a-z] */ - 6, 6, 6, 6, -} - -func shouldUseComplexStaticContextMap(input []byte, start_pos uint, length uint, mask uint, quality int, size_hint uint, num_literal_contexts *uint, literal_context_map *[]uint32) bool { - /* Try the more complex static context map only for long data. */ - if size_hint < 1<<20 { - return false - } else { - var end_pos uint = start_pos + length - var combined_histo = [32]uint32{0} - var context_histo = [13][32]uint32{[32]uint32{0}} - var total uint32 = 0 - var entropy [3]float64 - var dummy uint - var i uint - var utf8_lut contextLUT = getContextLUT(contextUTF8) - /* To make entropy calculations faster and to fit on the stack, we collect - histograms over the 5 most significant bits of literals. One histogram - without context and 13 additional histograms for each context value. */ - for ; start_pos+64 <= end_pos; start_pos += 4096 { - var stride_end_pos uint = start_pos + 64 - var prev2 byte = input[start_pos&mask] - var prev1 byte = input[(start_pos+1)&mask] - var pos uint - - /* To make the analysis of the data faster we only examine 64 byte long - strides at every 4kB intervals. */ - for pos = start_pos + 2; pos < stride_end_pos; pos++ { - var literal byte = input[pos&mask] - var context byte = byte(kStaticContextMapComplexUTF8[getContext(prev1, prev2, utf8_lut)]) - total++ - combined_histo[literal>>3]++ - context_histo[context][literal>>3]++ - prev2 = prev1 - prev1 = literal - } - } - - entropy[1] = shannonEntropy(combined_histo[:], 32, &dummy) - entropy[2] = 0 - for i = 0; i < 13; i++ { - entropy[2] += shannonEntropy(context_histo[i][0:], 32, &dummy) - } - - entropy[0] = 1.0 / float64(total) - entropy[1] *= entropy[0] - entropy[2] *= entropy[0] - - /* The triggering heuristics below were tuned by compressing the individual - files of the silesia corpus. If we skip this kind of context modeling - for not very well compressible input (i.e. entropy using context modeling - is 60% of maximal entropy) or if expected savings by symbol are less - than 0.2 bits, then in every case when it triggers, the final compression - ratio is improved. Note however that this heuristics might be too strict - for some cases and could be tuned further. */ - if entropy[2] > 3.0 || entropy[1]-entropy[2] < 0.2 { - return false - } else { - *num_literal_contexts = 13 - *literal_context_map = kStaticContextMapComplexUTF8[:] - return true - } - } -} - -func decideOverLiteralContextModeling(input []byte, start_pos uint, length uint, mask uint, quality int, size_hint uint, num_literal_contexts *uint, literal_context_map *[]uint32) { - if quality < minQualityForContextModeling || length < 64 { - return - } else if shouldUseComplexStaticContextMap(input, start_pos, length, mask, quality, size_hint, num_literal_contexts, literal_context_map) { - } else /* Context map was already set, nothing else to do. */ - { - var end_pos uint = start_pos + length - /* Gather bi-gram data of the UTF8 byte prefixes. To make the analysis of - UTF8 data faster we only examine 64 byte long strides at every 4kB - intervals. */ - - var bigram_prefix_histo = [9]uint32{0} - for ; start_pos+64 <= end_pos; start_pos += 4096 { - var lut = [4]int{0, 0, 1, 2} - var stride_end_pos uint = start_pos + 64 - var prev int = lut[input[start_pos&mask]>>6] * 3 - var pos uint - for pos = start_pos + 1; pos < stride_end_pos; pos++ { - var literal byte = input[pos&mask] - bigram_prefix_histo[prev+lut[literal>>6]]++ - prev = lut[literal>>6] * 3 - } - } - - chooseContextMap(quality, bigram_prefix_histo[0:], num_literal_contexts, literal_context_map) - } -} - -func shouldCompress_encode(data []byte, mask uint, last_flush_pos uint64, bytes uint, num_literals uint, num_commands uint) bool { - /* TODO: find more precise minimal block overhead. */ - if bytes <= 2 { - return false - } - if num_commands < (bytes>>8)+2 { - if float64(num_literals) > 0.99*float64(bytes) { - var literal_histo = [256]uint32{0} - const kSampleRate uint32 = 13 - const kMinEntropy float64 = 7.92 - var bit_cost_threshold float64 = float64(bytes) * kMinEntropy / float64(kSampleRate) - var t uint = uint((uint32(bytes) + kSampleRate - 1) / kSampleRate) - var pos uint32 = uint32(last_flush_pos) - var i uint - for i = 0; i < t; i++ { - literal_histo[data[pos&uint32(mask)]]++ - pos += kSampleRate - } - - if bitsEntropy(literal_histo[:], 256) > bit_cost_threshold { - return false - } - } - } - - return true -} - -/* Chooses the literal context mode for a metablock */ -func chooseContextMode(params *encoderParams, data []byte, pos uint, mask uint, length uint) int { - /* We only do the computation for the option of something else than - CONTEXT_UTF8 for the highest qualities */ - if params.quality >= minQualityForHqBlockSplitting && !isMostlyUTF8(data, pos, mask, length, kMinUTF8Ratio) { - return contextSigned - } - - return contextUTF8 -} - -func writeMetaBlockInternal(data []byte, mask uint, last_flush_pos uint64, bytes uint, is_last bool, literal_context_mode int, params *encoderParams, prev_byte byte, prev_byte2 byte, num_literals uint, commands []command, saved_dist_cache []int, dist_cache []int, storage_ix *uint, storage []byte) { - var wrapped_last_flush_pos uint32 = wrapPosition(last_flush_pos) - var last_bytes uint16 - var last_bytes_bits byte - var literal_context_lut contextLUT = getContextLUT(literal_context_mode) - var block_params encoderParams = *params - - if bytes == 0 { - /* Write the ISLAST and ISEMPTY bits. */ - writeBits(2, 3, storage_ix, storage) - - *storage_ix = (*storage_ix + 7) &^ 7 - return - } - - if !shouldCompress_encode(data, mask, last_flush_pos, bytes, num_literals, uint(len(commands))) { - /* Restore the distance cache, as its last update by - CreateBackwardReferences is now unused. */ - copy(dist_cache, saved_dist_cache[:4]) - - storeUncompressedMetaBlock(is_last, data, uint(wrapped_last_flush_pos), mask, bytes, storage_ix, storage) - return - } - - assert(*storage_ix <= 14) - last_bytes = uint16(storage[1])<<8 | uint16(storage[0]) - last_bytes_bits = byte(*storage_ix) - if params.quality <= maxQualityForStaticEntropyCodes { - storeMetaBlockFast(data, uint(wrapped_last_flush_pos), bytes, mask, is_last, params, commands, storage_ix, storage) - } else if params.quality < minQualityForBlockSplit { - storeMetaBlockTrivial(data, uint(wrapped_last_flush_pos), bytes, mask, is_last, params, commands, storage_ix, storage) - } else { - mb := getMetaBlockSplit() - if params.quality < minQualityForHqBlockSplitting { - var num_literal_contexts uint = 1 - var literal_context_map []uint32 = nil - if !params.disable_literal_context_modeling { - decideOverLiteralContextModeling(data, uint(wrapped_last_flush_pos), bytes, mask, params.quality, params.size_hint, &num_literal_contexts, &literal_context_map) - } - - buildMetaBlockGreedy(data, uint(wrapped_last_flush_pos), mask, prev_byte, prev_byte2, literal_context_lut, num_literal_contexts, literal_context_map, commands, mb) - } else { - buildMetaBlock(data, uint(wrapped_last_flush_pos), mask, &block_params, prev_byte, prev_byte2, commands, literal_context_mode, mb) - } - - if params.quality >= minQualityForOptimizeHistograms { - /* The number of distance symbols effectively used for distance - histograms. It might be less than distance alphabet size - for "Large Window Brotli" (32-bit). */ - var num_effective_dist_codes uint32 = block_params.dist.alphabet_size - if num_effective_dist_codes > numHistogramDistanceSymbols { - num_effective_dist_codes = numHistogramDistanceSymbols - } - - optimizeHistograms(num_effective_dist_codes, mb) - } - - storeMetaBlock(data, uint(wrapped_last_flush_pos), bytes, mask, prev_byte, prev_byte2, is_last, &block_params, literal_context_mode, commands, mb, storage_ix, storage) - freeMetaBlockSplit(mb) - } - - if bytes+4 < *storage_ix>>3 { - /* Restore the distance cache and last byte. */ - copy(dist_cache, saved_dist_cache[:4]) - - storage[0] = byte(last_bytes) - storage[1] = byte(last_bytes >> 8) - *storage_ix = uint(last_bytes_bits) - storeUncompressedMetaBlock(is_last, data, uint(wrapped_last_flush_pos), mask, bytes, storage_ix, storage) - } -} - -func chooseDistanceParams(params *encoderParams) { - var distance_postfix_bits uint32 = 0 - var num_direct_distance_codes uint32 = 0 - - if params.quality >= minQualityForNonzeroDistanceParams { - var ndirect_msb uint32 - if params.mode == modeFont { - distance_postfix_bits = 1 - num_direct_distance_codes = 12 - } else { - distance_postfix_bits = params.dist.distance_postfix_bits - num_direct_distance_codes = params.dist.num_direct_distance_codes - } - - ndirect_msb = (num_direct_distance_codes >> distance_postfix_bits) & 0x0F - if distance_postfix_bits > maxNpostfix || num_direct_distance_codes > maxNdirect || ndirect_msb<>25)), (last_command.dist_prefix_&0x3FF == 0), &last_command.cmd_prefix_) - } -} - -/* - Processes the accumulated input data and writes - the new output meta-block to s.dest, if one has been - created (otherwise the processed input data is buffered internally). - If |is_last| or |force_flush| is true, an output meta-block is - always created. However, until |is_last| is true encoder may retain up - to 7 bits of the last byte of output. To force encoder to dump the remaining - bits use WriteMetadata() to append an empty meta-data block. - Returns false if the size of the input data is larger than - input_block_size(). -*/ -func encodeData(s *Writer, is_last bool, force_flush bool) bool { - var delta uint64 = unprocessedInputSize(s) - var bytes uint32 = uint32(delta) - var wrapped_last_processed_pos uint32 = wrapPosition(s.last_processed_pos_) - var data []byte - var mask uint32 - var literal_context_mode int - - data = s.ringbuffer_.buffer_ - mask = s.ringbuffer_.mask_ - - /* Adding more blocks after "last" block is forbidden. */ - if s.is_last_block_emitted_ { - return false - } - if is_last { - s.is_last_block_emitted_ = true - } - - if delta > uint64(inputBlockSize(s)) { - return false - } - - if s.params.quality == fastTwoPassCompressionQuality { - if s.command_buf_ == nil || cap(s.command_buf_) < int(kCompressFragmentTwoPassBlockSize) { - s.command_buf_ = make([]uint32, kCompressFragmentTwoPassBlockSize) - s.literal_buf_ = make([]byte, kCompressFragmentTwoPassBlockSize) - } else { - s.command_buf_ = s.command_buf_[:kCompressFragmentTwoPassBlockSize] - s.literal_buf_ = s.literal_buf_[:kCompressFragmentTwoPassBlockSize] - } - } - - if s.params.quality == fastOnePassCompressionQuality || s.params.quality == fastTwoPassCompressionQuality { - var storage []byte - var storage_ix uint = uint(s.last_bytes_bits_) - var table_size uint - var table []int - - if delta == 0 && !is_last { - /* We have no new input data and we don't have to finish the stream, so - nothing to do. */ - return true - } - - storage = s.getStorage(int(2*bytes + 503)) - storage[0] = byte(s.last_bytes_) - storage[1] = byte(s.last_bytes_ >> 8) - table = getHashTable(s, s.params.quality, uint(bytes), &table_size) - if s.params.quality == fastOnePassCompressionQuality { - compressFragmentFast(data[wrapped_last_processed_pos&mask:], uint(bytes), is_last, table, table_size, s.cmd_depths_[:], s.cmd_bits_[:], &s.cmd_code_numbits_, s.cmd_code_[:], &storage_ix, storage) - } else { - compressFragmentTwoPass(data[wrapped_last_processed_pos&mask:], uint(bytes), is_last, s.command_buf_, s.literal_buf_, table, table_size, &storage_ix, storage) - } - - s.last_bytes_ = uint16(storage[storage_ix>>3]) - s.last_bytes_bits_ = byte(storage_ix & 7) - updateLastProcessedPos(s) - s.writeOutput(storage[:storage_ix>>3]) - return true - } - { - /* Theoretical max number of commands is 1 per 2 bytes. */ - newsize := len(s.commands) + int(bytes)/2 + 1 - if newsize > cap(s.commands) { - /* Reserve a bit more memory to allow merging with a next block - without reallocation: that would impact speed. */ - newsize += int(bytes/4) + 16 - - new_commands := make([]command, len(s.commands), newsize) - if s.commands != nil { - copy(new_commands, s.commands) - } - - s.commands = new_commands - } - } - - initOrStitchToPreviousBlock(&s.hasher_, data, uint(mask), &s.params, uint(wrapped_last_processed_pos), uint(bytes), is_last) - - literal_context_mode = chooseContextMode(&s.params, data, uint(wrapPosition(s.last_flush_pos_)), uint(mask), uint(s.input_pos_-s.last_flush_pos_)) - - if len(s.commands) != 0 && s.last_insert_len_ == 0 { - extendLastCommand(s, &bytes, &wrapped_last_processed_pos) - } - - if s.params.quality == zopflificationQuality { - assert(s.params.hasher.type_ == 10) - createZopfliBackwardReferences(uint(bytes), uint(wrapped_last_processed_pos), data, uint(mask), &s.params, s.hasher_.(*h10), s.dist_cache_[:], &s.last_insert_len_, &s.commands, &s.num_literals_) - } else if s.params.quality == hqZopflificationQuality { - assert(s.params.hasher.type_ == 10) - createHqZopfliBackwardReferences(uint(bytes), uint(wrapped_last_processed_pos), data, uint(mask), &s.params, s.hasher_, s.dist_cache_[:], &s.last_insert_len_, &s.commands, &s.num_literals_) - } else { - createBackwardReferences(uint(bytes), uint(wrapped_last_processed_pos), data, uint(mask), &s.params, s.hasher_, s.dist_cache_[:], &s.last_insert_len_, &s.commands, &s.num_literals_) - } - { - var max_length uint = maxMetablockSize(&s.params) - var max_literals uint = max_length / 8 - max_commands := int(max_length / 8) - var processed_bytes uint = uint(s.input_pos_ - s.last_flush_pos_) - var next_input_fits_metablock bool = (processed_bytes+inputBlockSize(s) <= max_length) - var should_flush bool = (s.params.quality < minQualityForBlockSplit && s.num_literals_+uint(len(s.commands)) >= maxNumDelayedSymbols) - /* If maximal possible additional block doesn't fit metablock, flush now. */ - /* TODO: Postpone decision until next block arrives? */ - - /* If block splitting is not used, then flush as soon as there is some - amount of commands / literals produced. */ - if !is_last && !force_flush && !should_flush && next_input_fits_metablock && s.num_literals_ < max_literals && len(s.commands) < max_commands { - /* Merge with next input block. Everything will happen later. */ - if updateLastProcessedPos(s) { - hasherReset(s.hasher_) - } - - return true - } - } - - /* Create the last insert-only command. */ - if s.last_insert_len_ > 0 { - s.commands = append(s.commands, makeInsertCommand(s.last_insert_len_)) - s.num_literals_ += s.last_insert_len_ - s.last_insert_len_ = 0 - } - - if !is_last && s.input_pos_ == s.last_flush_pos_ { - /* We have no new input data and we don't have to finish the stream, so - nothing to do. */ - return true - } - - assert(s.input_pos_ >= s.last_flush_pos_) - assert(s.input_pos_ > s.last_flush_pos_ || is_last) - assert(s.input_pos_-s.last_flush_pos_ <= 1<<24) - { - var metablock_size uint32 = uint32(s.input_pos_ - s.last_flush_pos_) - var storage []byte = s.getStorage(int(2*metablock_size + 503)) - var storage_ix uint = uint(s.last_bytes_bits_) - storage[0] = byte(s.last_bytes_) - storage[1] = byte(s.last_bytes_ >> 8) - writeMetaBlockInternal(data, uint(mask), s.last_flush_pos_, uint(metablock_size), is_last, literal_context_mode, &s.params, s.prev_byte_, s.prev_byte2_, s.num_literals_, s.commands, s.saved_dist_cache_[:], s.dist_cache_[:], &storage_ix, storage) - s.last_bytes_ = uint16(storage[storage_ix>>3]) - s.last_bytes_bits_ = byte(storage_ix & 7) - s.last_flush_pos_ = s.input_pos_ - if updateLastProcessedPos(s) { - hasherReset(s.hasher_) - } - - if s.last_flush_pos_ > 0 { - s.prev_byte_ = data[(uint32(s.last_flush_pos_)-1)&mask] - } - - if s.last_flush_pos_ > 1 { - s.prev_byte2_ = data[uint32(s.last_flush_pos_-2)&mask] - } - - s.commands = s.commands[:0] - s.num_literals_ = 0 - - /* Save the state of the distance cache in case we need to restore it for - emitting an uncompressed block. */ - copy(s.saved_dist_cache_[:], s.dist_cache_[:]) - - s.writeOutput(storage[:storage_ix>>3]) - return true - } -} - -/* Dumps remaining output bits and metadata header to |header|. - Returns number of produced bytes. - REQUIRED: |header| should be 8-byte aligned and at least 16 bytes long. - REQUIRED: |block_size| <= (1 << 24). */ -func writeMetadataHeader(s *Writer, block_size uint, header []byte) uint { - storage_ix := uint(s.last_bytes_bits_) - header[0] = byte(s.last_bytes_) - header[1] = byte(s.last_bytes_ >> 8) - s.last_bytes_ = 0 - s.last_bytes_bits_ = 0 - - writeBits(1, 0, &storage_ix, header) - writeBits(2, 3, &storage_ix, header) - writeBits(1, 0, &storage_ix, header) - if block_size == 0 { - writeBits(2, 0, &storage_ix, header) - } else { - var nbits uint32 - if block_size == 1 { - nbits = 0 - } else { - nbits = log2FloorNonZero(uint(uint32(block_size)-1)) + 1 - } - var nbytes uint32 = (nbits + 7) / 8 - writeBits(2, uint64(nbytes), &storage_ix, header) - writeBits(uint(8*nbytes), uint64(block_size)-1, &storage_ix, header) - } - - return (storage_ix + 7) >> 3 -} - -func injectBytePaddingBlock(s *Writer) { - var seal uint32 = uint32(s.last_bytes_) - var seal_bits uint = uint(s.last_bytes_bits_) - s.last_bytes_ = 0 - s.last_bytes_bits_ = 0 - - /* is_last = 0, data_nibbles = 11, reserved = 0, meta_nibbles = 00 */ - seal |= 0x6 << seal_bits - - seal_bits += 6 - - destination := s.tiny_buf_.u8[:] - - destination[0] = byte(seal) - if seal_bits > 8 { - destination[1] = byte(seal >> 8) - } - if seal_bits > 16 { - destination[2] = byte(seal >> 16) - } - s.writeOutput(destination[:(seal_bits+7)>>3]) -} - -func checkFlushComplete(s *Writer) { - if s.stream_state_ == streamFlushRequested && s.err == nil { - s.stream_state_ = streamProcessing - } -} - -func encoderCompressStreamFast(s *Writer, op int, available_in *uint, next_in *[]byte) bool { - var block_size_limit uint = uint(1) << s.params.lgwin - var buf_size uint = brotli_min_size_t(kCompressFragmentTwoPassBlockSize, brotli_min_size_t(*available_in, block_size_limit)) - var command_buf []uint32 = nil - var literal_buf []byte = nil - if s.params.quality != fastOnePassCompressionQuality && s.params.quality != fastTwoPassCompressionQuality { - return false - } - - if s.params.quality == fastTwoPassCompressionQuality { - if s.command_buf_ == nil || cap(s.command_buf_) < int(buf_size) { - s.command_buf_ = make([]uint32, buf_size) - s.literal_buf_ = make([]byte, buf_size) - } else { - s.command_buf_ = s.command_buf_[:buf_size] - s.literal_buf_ = s.literal_buf_[:buf_size] - } - - command_buf = s.command_buf_ - literal_buf = s.literal_buf_ - } - - for { - if s.stream_state_ == streamFlushRequested && s.last_bytes_bits_ != 0 { - injectBytePaddingBlock(s) - continue - } - - /* Compress block only when stream is not - finished, there is no pending flush request, and there is either - additional input or pending operation. */ - if s.stream_state_ == streamProcessing && (*available_in != 0 || op != int(operationProcess)) { - var block_size uint = brotli_min_size_t(block_size_limit, *available_in) - var is_last bool = (*available_in == block_size) && (op == int(operationFinish)) - var force_flush bool = (*available_in == block_size) && (op == int(operationFlush)) - var max_out_size uint = 2*block_size + 503 - var storage []byte = nil - var storage_ix uint = uint(s.last_bytes_bits_) - var table_size uint - var table []int - - if force_flush && block_size == 0 { - s.stream_state_ = streamFlushRequested - continue - } - - storage = s.getStorage(int(max_out_size)) - - storage[0] = byte(s.last_bytes_) - storage[1] = byte(s.last_bytes_ >> 8) - table = getHashTable(s, s.params.quality, block_size, &table_size) - - if s.params.quality == fastOnePassCompressionQuality { - compressFragmentFast(*next_in, block_size, is_last, table, table_size, s.cmd_depths_[:], s.cmd_bits_[:], &s.cmd_code_numbits_, s.cmd_code_[:], &storage_ix, storage) - } else { - compressFragmentTwoPass(*next_in, block_size, is_last, command_buf, literal_buf, table, table_size, &storage_ix, storage) - } - - *next_in = (*next_in)[block_size:] - *available_in -= block_size - var out_bytes uint = storage_ix >> 3 - s.writeOutput(storage[:out_bytes]) - - s.last_bytes_ = uint16(storage[storage_ix>>3]) - s.last_bytes_bits_ = byte(storage_ix & 7) - - if force_flush { - s.stream_state_ = streamFlushRequested - } - if is_last { - s.stream_state_ = streamFinished - } - continue - } - - break - } - - checkFlushComplete(s) - return true -} - -func processMetadata(s *Writer, available_in *uint, next_in *[]byte) bool { - if *available_in > 1<<24 { - return false - } - - /* Switch to metadata block workflow, if required. */ - if s.stream_state_ == streamProcessing { - s.remaining_metadata_bytes_ = uint32(*available_in) - s.stream_state_ = streamMetadataHead - } - - if s.stream_state_ != streamMetadataHead && s.stream_state_ != streamMetadataBody { - return false - } - - for { - if s.stream_state_ == streamFlushRequested && s.last_bytes_bits_ != 0 { - injectBytePaddingBlock(s) - continue - } - - if s.input_pos_ != s.last_flush_pos_ { - var result bool = encodeData(s, false, true) - if !result { - return false - } - continue - } - - if s.stream_state_ == streamMetadataHead { - n := writeMetadataHeader(s, uint(s.remaining_metadata_bytes_), s.tiny_buf_.u8[:]) - s.writeOutput(s.tiny_buf_.u8[:n]) - s.stream_state_ = streamMetadataBody - continue - } else { - /* Exit workflow only when there is no more input and no more output. - Otherwise client may continue producing empty metadata blocks. */ - if s.remaining_metadata_bytes_ == 0 { - s.remaining_metadata_bytes_ = math.MaxUint32 - s.stream_state_ = streamProcessing - break - } - - /* This guarantees progress in "TakeOutput" workflow. */ - var c uint32 = brotli_min_uint32_t(s.remaining_metadata_bytes_, 16) - copy(s.tiny_buf_.u8[:], (*next_in)[:c]) - *next_in = (*next_in)[c:] - *available_in -= uint(c) - s.remaining_metadata_bytes_ -= c - s.writeOutput(s.tiny_buf_.u8[:c]) - - continue - } - } - - return true -} - -func updateSizeHint(s *Writer, available_in uint) { - if s.params.size_hint == 0 { - var delta uint64 = unprocessedInputSize(s) - var tail uint64 = uint64(available_in) - var limit uint32 = 1 << 30 - var total uint32 - if (delta >= uint64(limit)) || (tail >= uint64(limit)) || ((delta + tail) >= uint64(limit)) { - total = limit - } else { - total = uint32(delta + tail) - } - - s.params.size_hint = uint(total) - } -} - -func encoderCompressStream(s *Writer, op int, available_in *uint, next_in *[]byte) bool { - if !ensureInitialized(s) { - return false - } - - /* Unfinished metadata block; check requirements. */ - if s.remaining_metadata_bytes_ != math.MaxUint32 { - if uint32(*available_in) != s.remaining_metadata_bytes_ { - return false - } - if op != int(operationEmitMetadata) { - return false - } - } - - if op == int(operationEmitMetadata) { - updateSizeHint(s, 0) /* First data metablock might be emitted here. */ - return processMetadata(s, available_in, next_in) - } - - if s.stream_state_ == streamMetadataHead || s.stream_state_ == streamMetadataBody { - return false - } - - if s.stream_state_ != streamProcessing && *available_in != 0 { - return false - } - - if s.params.quality == fastOnePassCompressionQuality || s.params.quality == fastTwoPassCompressionQuality { - return encoderCompressStreamFast(s, op, available_in, next_in) - } - - for { - var remaining_block_size uint = remainingInputBlockSize(s) - - if remaining_block_size != 0 && *available_in != 0 { - var copy_input_size uint = brotli_min_size_t(remaining_block_size, *available_in) - copyInputToRingBuffer(s, copy_input_size, *next_in) - *next_in = (*next_in)[copy_input_size:] - *available_in -= copy_input_size - continue - } - - if s.stream_state_ == streamFlushRequested && s.last_bytes_bits_ != 0 { - injectBytePaddingBlock(s) - continue - } - - /* Compress data only when stream is not - finished and there is no pending flush request. */ - if s.stream_state_ == streamProcessing { - if remaining_block_size == 0 || op != int(operationProcess) { - var is_last bool = ((*available_in == 0) && op == int(operationFinish)) - var force_flush bool = ((*available_in == 0) && op == int(operationFlush)) - var result bool - updateSizeHint(s, *available_in) - result = encodeData(s, is_last, force_flush) - if !result { - return false - } - if force_flush { - s.stream_state_ = streamFlushRequested - } - if is_last { - s.stream_state_ = streamFinished - } - continue - } - } - - break - } - - checkFlushComplete(s) - return true -} - -func (w *Writer) writeOutput(data []byte) { - if w.err != nil { - return - } - - _, w.err = w.dst.Write(data) - if w.err == nil { - checkFlushComplete(w) - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/encoder.go b/src/vendor/github.com/andybalholm/brotli/encoder.go deleted file mode 100644 index cd541b35..00000000 --- a/src/vendor/github.com/andybalholm/brotli/encoder.go +++ /dev/null @@ -1,177 +0,0 @@ -package brotli - -import "github.com/andybalholm/brotli/matchfinder" - -// An Encoder implements the matchfinder.Encoder interface, writing in Brotli format. -type Encoder struct { - wroteHeader bool - bw bitWriter - distCache []distanceCode -} - -func (e *Encoder) Reset() { - e.wroteHeader = false - e.bw = bitWriter{} -} - -func (e *Encoder) Encode(dst []byte, src []byte, matches []matchfinder.Match, lastBlock bool) []byte { - e.bw.dst = dst - if !e.wroteHeader { - e.bw.writeBits(4, 15) - e.wroteHeader = true - } - - if len(src) == 0 { - if lastBlock { - e.bw.writeBits(2, 3) // islast + isempty - e.bw.jumpToByteBoundary() - return e.bw.dst - } - return dst - } - - var literalHisto [256]uint32 - var commandHisto [704]uint32 - var distanceHisto [64]uint32 - literalCount := 0 - commandCount := 0 - distanceCount := 0 - - if len(e.distCache) < len(matches) { - e.distCache = make([]distanceCode, len(matches)) - } - - // first pass: build the histograms - pos := 0 - - // d is the ring buffer of the last 4 distances. - d := [4]int{-10, -10, -10, -10} - for i, m := range matches { - if m.Unmatched > 0 { - for _, c := range src[pos : pos+m.Unmatched] { - literalHisto[c]++ - } - literalCount += m.Unmatched - } - - insertCode := getInsertLengthCode(uint(m.Unmatched)) - copyCode := getCopyLengthCode(uint(m.Length)) - if m.Length == 0 { - // If the stream ends with unmatched bytes, we need a dummy copy length. - copyCode = 2 - } - command := combineLengthCodes(insertCode, copyCode, i > 0 && m.Distance == matches[i-1].Distance) - commandHisto[command]++ - commandCount++ - - if command >= 128 && m.Length != 0 { - var distCode distanceCode - switch m.Distance { - case d[3]: - distCode.code = 0 - case d[2]: - distCode.code = 1 - case d[1]: - distCode.code = 2 - case d[0]: - distCode.code = 3 - case d[3] - 1: - distCode.code = 4 - case d[3] + 1: - distCode.code = 5 - case d[3] - 2: - distCode.code = 6 - case d[3] + 2: - distCode.code = 7 - case d[3] - 3: - distCode.code = 8 - case d[3] + 3: - distCode.code = 9 - - // In my testing, codes 10–15 actually reduced the compression ratio. - - default: - distCode = getDistanceCode(m.Distance) - } - e.distCache[i] = distCode - distanceHisto[distCode.code]++ - distanceCount++ - if distCode.code != 0 { - d[0], d[1], d[2], d[3] = d[1], d[2], d[3], m.Distance - } - } - - pos += m.Unmatched + m.Length - } - - storeMetaBlockHeaderBW(uint(len(src)), false, &e.bw) - e.bw.writeBits(13, 0) - - var literalDepths [256]byte - var literalBits [256]uint16 - buildAndStoreHuffmanTreeFastBW(literalHisto[:], uint(literalCount), 8, literalDepths[:], literalBits[:], &e.bw) - - var commandDepths [704]byte - var commandBits [704]uint16 - buildAndStoreHuffmanTreeFastBW(commandHisto[:], uint(commandCount), 10, commandDepths[:], commandBits[:], &e.bw) - - var distanceDepths [64]byte - var distanceBits [64]uint16 - buildAndStoreHuffmanTreeFastBW(distanceHisto[:], uint(distanceCount), 6, distanceDepths[:], distanceBits[:], &e.bw) - - pos = 0 - for i, m := range matches { - insertCode := getInsertLengthCode(uint(m.Unmatched)) - copyCode := getCopyLengthCode(uint(m.Length)) - if m.Length == 0 { - // If the stream ends with unmatched bytes, we need a dummy copy length. - copyCode = 2 - } - command := combineLengthCodes(insertCode, copyCode, i > 0 && m.Distance == matches[i-1].Distance) - e.bw.writeBits(uint(commandDepths[command]), uint64(commandBits[command])) - if kInsExtra[insertCode] > 0 { - e.bw.writeBits(uint(kInsExtra[insertCode]), uint64(m.Unmatched)-uint64(kInsBase[insertCode])) - } - if kCopyExtra[copyCode] > 0 { - e.bw.writeBits(uint(kCopyExtra[copyCode]), uint64(m.Length)-uint64(kCopyBase[copyCode])) - } - - if m.Unmatched > 0 { - for _, c := range src[pos : pos+m.Unmatched] { - e.bw.writeBits(uint(literalDepths[c]), uint64(literalBits[c])) - } - } - - if command >= 128 && m.Length != 0 { - distCode := e.distCache[i] - e.bw.writeBits(uint(distanceDepths[distCode.code]), uint64(distanceBits[distCode.code])) - if distCode.nExtra > 0 { - e.bw.writeBits(distCode.nExtra, distCode.extraBits) - } - } - - pos += m.Unmatched + m.Length - } - - if lastBlock { - e.bw.writeBits(2, 3) // islast + isempty - e.bw.jumpToByteBoundary() - } - return e.bw.dst -} - -type distanceCode struct { - code int - nExtra uint - extraBits uint64 -} - -func getDistanceCode(distance int) distanceCode { - d := distance + 3 - nbits := log2FloorNonZero(uint(d)) - 1 - prefix := (d >> nbits) & 1 - offset := (2 + prefix) << nbits - distcode := int(2*(nbits-1)) + prefix + 16 - extra := d - offset - return distanceCode{distcode, uint(nbits), uint64(extra)} -} diff --git a/src/vendor/github.com/andybalholm/brotli/encoder_dict.go b/src/vendor/github.com/andybalholm/brotli/encoder_dict.go deleted file mode 100644 index 55c051c6..00000000 --- a/src/vendor/github.com/andybalholm/brotli/encoder_dict.go +++ /dev/null @@ -1,22 +0,0 @@ -package brotli - -/* Dictionary data (words and transforms) for 1 possible context */ -type encoderDictionary struct { - words *dictionary - cutoffTransformsCount uint32 - cutoffTransforms uint64 - hash_table []uint16 - buckets []uint16 - dict_words []dictWord -} - -func initEncoderDictionary(dict *encoderDictionary) { - dict.words = getDictionary() - - dict.hash_table = kStaticDictionaryHash[:] - dict.buckets = kStaticDictionaryBuckets[:] - dict.dict_words = kStaticDictionaryWords[:] - - dict.cutoffTransformsCount = kCutoffTransformsCount - dict.cutoffTransforms = kCutoffTransforms -} diff --git a/src/vendor/github.com/andybalholm/brotli/encoder_fast.go b/src/vendor/github.com/andybalholm/brotli/encoder_fast.go deleted file mode 100644 index 36a41737..00000000 --- a/src/vendor/github.com/andybalholm/brotli/encoder_fast.go +++ /dev/null @@ -1,197 +0,0 @@ -package brotli - -import ( - "math" - - "github.com/andybalholm/brotli/matchfinder" -) - -func gaussianProbability(x, mean, stdDev float64) float64 { - return math.Exp(-(x-mean)*(x-mean)/(2*stdDev*stdDev)) / math.Sqrt(2*math.Pi*stdDev*stdDev) -} - -// A FastEncoder implements the matchfinder.Encoder interface, writing in Brotli -// format. It uses a simplified encoding (like level 0 in the reference -// implementation) to save time. -type FastEncoder struct { - wroteHeader bool - bw bitWriter - commandHisto [704]uint32 - distanceHisto [64]uint32 -} - -func (e *FastEncoder) Reset() { - e.wroteHeader = false - e.bw = bitWriter{} -} - -func (e *FastEncoder) Encode(dst []byte, src []byte, matches []matchfinder.Match, lastBlock bool) []byte { - e.bw.dst = dst - if !e.wroteHeader { - e.bw.writeBits(4, 15) - e.wroteHeader = true - - // Fill the histograms with default statistics. - - // For the command codes we're using for insert lengths (insert + 2-byte copy), - // fill the histogram with a Zipf-squared distribution. - for i := range 24 { - e.commandHisto[combineLengthCodes(uint16(i), 0, false)] = uint32(2000 / (i + 1) / (i + 1)) - } - - // For the command codes we're using for copy lengths (0 insert + copy - // (length - 2), with repeat distance), - // fill the histogram with Zipf distribution starting at code 1 (match length 5), - // but a smaller frequency for code 0. - e.commandHisto[combineLengthCodes(0, 0, true)] = 50 - for i := 1; i < 24; i++ { - e.commandHisto[combineLengthCodes(0, uint16(i), i < 16)] = uint32(800 / i) - } - - // Fill in the combined codes for short insert and copy lengths. - for insertCode := range 6 { - copyCode := 2 - e.commandHisto[128+insertCode<<3+copyCode] = uint32(100 / (insertCode + 1) / (insertCode + 1) / copyCode) - for copyCode := 3; copyCode < 8; copyCode++ { - e.commandHisto[128+insertCode<<3+copyCode] = uint32(343 / (insertCode + 1) / (insertCode + 1) / copyCode) - } - } - - // Fill e.distanceHisto with a normal distribution. - e.distanceHisto[0] = 100 - for i := 16; i < 64; i++ { - e.distanceHisto[i] = max(uint32(gaussianProbability(float64(i), 32, 8)*10000), 1) - } - } - - if len(src) == 0 { - if lastBlock { - e.bw.writeBits(2, 3) // islast + isempty - e.bw.jumpToByteBoundary() - return e.bw.dst - } - return dst - } - - var literalHisto [256]uint32 - for _, c := range src { - literalHisto[c]++ - } - - storeMetaBlockHeaderBW(uint(len(src)), false, &e.bw) - e.bw.writeBits(13, 0) - - var literalDepths [256]byte - var literalBits [256]uint16 - buildAndStoreHuffmanTreeFastBW(literalHisto[:], uint(len(src)), 8, literalDepths[:], literalBits[:], &e.bw) - - var commandDepths [704]byte - var commandBits [704]uint16 - commandCount := 0 - for _, n := range e.commandHisto { - commandCount += int(n) - } - buildAndStoreHuffmanTreeFastBW(e.commandHisto[:], uint(commandCount), 10, commandDepths[:], commandBits[:], &e.bw) - - var distanceDepths [64]byte - var distanceBits [64]uint16 - distanceCount := 0 - for _, n := range e.distanceHisto { - distanceCount += int(n) - } - buildAndStoreHuffmanTreeFastBW(e.distanceHisto[:], uint(distanceCount), 6, distanceDepths[:], distanceBits[:], &e.bw) - - // Reset the statistics, starting with a count of 1 for each symbol we might use. - for i := range 24 { - e.commandHisto[combineLengthCodes(uint16(i), 0, false)] = 1 - } - for i := range 24 { - e.commandHisto[combineLengthCodes(0, uint16(i), i < 16)] = 1 - } - for insertCode := range 6 { - for copyCode := 2; copyCode < 8; copyCode++ { - e.commandHisto[128+insertCode<<3+copyCode] = 1 - } - } - e.distanceHisto[0] = 1 - for i := 16; i < 64; i++ { - e.distanceHisto[i] = 1 - } - - pos := 0 - for i, m := range matches { - lengthFinished := false - // Write a command with the appropriate insert length, and a copy length of 2. - if m.Unmatched < 6 { - var command int - if m.Length < 10 && m.Length != 0 { - // We can use a combined insert/copy code with no extra bits. - command = m.Unmatched<<3 + m.Length - 2 + 128 - lengthFinished = true - } else { - command = m.Unmatched<<3 + 128 - } - e.bw.writeBits(uint(commandDepths[command]), uint64(commandBits[command])) - e.commandHisto[command]++ - } else { - insertCode := getInsertLengthCode(uint(m.Unmatched)) - command := combineLengthCodes(insertCode, 0, false) - e.bw.writeBits(uint(commandDepths[command]), uint64(commandBits[command])) - e.bw.writeBits(uint(kInsExtra[insertCode]), uint64(m.Unmatched)-uint64(kInsBase[insertCode])) - e.commandHisto[command]++ - } - - // Write the literals, if any. - if m.Unmatched > 0 { - for _, c := range src[pos : pos+m.Unmatched] { - e.bw.writeBits(uint(literalDepths[c]), uint64(literalBits[c])) - } - } - - if m.Length != 0 { - // Write the distance code. - var distCode distanceCode - if i == 0 || m.Distance != matches[i-1].Distance { - distCode = getDistanceCode(m.Distance) - } - e.bw.writeBits(uint(distanceDepths[distCode.code]), uint64(distanceBits[distCode.code])) - if distCode.nExtra > 0 { - e.bw.writeBits(distCode.nExtra, distCode.extraBits) - } - e.distanceHisto[distCode.code]++ - - // Write a command for the remainder of the match (after the first two bytes - // from before), using the previous distance. - switch { - case lengthFinished: - // We don't need to finish the length. - case m.Length < 12: - command := m.Length - 4 - e.bw.writeBits(uint(commandDepths[command]), uint64(commandBits[command])) - e.commandHisto[command]++ - case m.Length < 72: - copyCode := getCopyLengthCode(uint(m.Length - 2)) - command := combineLengthCodes(0, copyCode, true) - e.bw.writeBits(uint(commandDepths[command]), uint64(commandBits[command])) - e.bw.writeBits(uint(kCopyExtra[copyCode]), uint64(m.Length-2)-uint64(kCopyBase[copyCode])) - e.commandHisto[command]++ - default: - copyCode := getCopyLengthCode(uint(m.Length - 2)) - command := combineLengthCodes(0, copyCode, false) - e.bw.writeBits(uint(commandDepths[command]), uint64(commandBits[command])) - e.bw.writeBits(uint(kCopyExtra[copyCode]), uint64(m.Length-2)-uint64(kCopyBase[copyCode])) - e.bw.writeBits(uint(distanceDepths[0]), uint64(distanceBits[0])) - e.commandHisto[command]++ - e.distanceHisto[0]++ - } - } - - pos += m.Unmatched + m.Length - } - - if lastBlock { - e.bw.writeBits(2, 3) // islast + isempty - e.bw.jumpToByteBoundary() - } - return e.bw.dst -} diff --git a/src/vendor/github.com/andybalholm/brotli/entropy_encode.go b/src/vendor/github.com/andybalholm/brotli/entropy_encode.go deleted file mode 100644 index 3f469a3d..00000000 --- a/src/vendor/github.com/andybalholm/brotli/entropy_encode.go +++ /dev/null @@ -1,592 +0,0 @@ -package brotli - -import "math" - -/* Copyright 2010 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Entropy encoding (Huffman) utilities. */ - -/* A node of a Huffman tree. */ -type huffmanTree struct { - total_count_ uint32 - index_left_ int16 - index_right_or_value_ int16 -} - -func initHuffmanTree(self *huffmanTree, count uint32, left int16, right int16) { - self.total_count_ = count - self.index_left_ = left - self.index_right_or_value_ = right -} - -/* Input size optimized Shell sort. */ -type huffmanTreeComparator func(huffmanTree, huffmanTree) bool - -var sortHuffmanTreeItems_gaps = []uint{132, 57, 23, 10, 4, 1} - -func sortHuffmanTreeItems(items []huffmanTree, n uint, comparator huffmanTreeComparator) { - if n < 13 { - /* Insertion sort. */ - var i uint - for i = 1; i < n; i++ { - var tmp huffmanTree = items[i] - var k uint = i - var j uint = i - 1 - for comparator(tmp, items[j]) { - items[k] = items[j] - k = j - if j == 0 { - break - } - j-- - } - - items[k] = tmp - } - - return - } else { - var g int - if n < 57 { - g = 2 - } else { - g = 0 - } - for ; g < 6; g++ { - var gap uint = sortHuffmanTreeItems_gaps[g] - var i uint - for i = gap; i < n; i++ { - var j uint = i - var tmp huffmanTree = items[i] - for ; j >= gap && comparator(tmp, items[j-gap]); j -= gap { - items[j] = items[j-gap] - } - - items[j] = tmp - } - } - } -} - -/* Returns 1 if assignment of depths succeeded, otherwise 0. */ -func setDepth(p0 int, pool []huffmanTree, depth []byte, max_depth int) bool { - var stack [16]int - var level int = 0 - var p int = p0 - assert(max_depth <= 15) - stack[0] = -1 - for { - if pool[p].index_left_ >= 0 { - level++ - if level > max_depth { - return false - } - stack[level] = int(pool[p].index_right_or_value_) - p = int(pool[p].index_left_) - continue - } else { - depth[pool[p].index_right_or_value_] = byte(level) - } - - for level >= 0 && stack[level] == -1 { - level-- - } - if level < 0 { - return true - } - p = stack[level] - stack[level] = -1 - } -} - -/* Sort the root nodes, least popular first. */ -func sortHuffmanTree(v0 huffmanTree, v1 huffmanTree) bool { - if v0.total_count_ != v1.total_count_ { - return v0.total_count_ < v1.total_count_ - } - - return v0.index_right_or_value_ > v1.index_right_or_value_ -} - -/* This function will create a Huffman tree. - - The catch here is that the tree cannot be arbitrarily deep. - Brotli specifies a maximum depth of 15 bits for "code trees" - and 7 bits for "code length code trees." - - count_limit is the value that is to be faked as the minimum value - and this minimum value is raised until the tree matches the - maximum length requirement. - - This algorithm is not of excellent performance for very long data blocks, - especially when population counts are longer than 2**tree_limit, but - we are not planning to use this with extremely long blocks. - - See http://en.wikipedia.org/wiki/Huffman_coding */ -func createHuffmanTree(data []uint32, length uint, tree_limit int, tree []huffmanTree, depth []byte) { - var count_limit uint32 - var sentinel huffmanTree - initHuffmanTree(&sentinel, math.MaxUint32, -1, -1) - - /* For block sizes below 64 kB, we never need to do a second iteration - of this loop. Probably all of our block sizes will be smaller than - that, so this loop is mostly of academic interest. If we actually - would need this, we would be better off with the Katajainen algorithm. */ - for count_limit = 1; ; count_limit *= 2 { - var n uint = 0 - var i uint - var j uint - var k uint - for i = length; i != 0; { - i-- - if data[i] != 0 { - var count uint32 = brotli_max_uint32_t(data[i], count_limit) - initHuffmanTree(&tree[n], count, -1, int16(i)) - n++ - } - } - - if n == 1 { - depth[tree[0].index_right_or_value_] = 1 /* Only one element. */ - break - } - - sortHuffmanTreeItems(tree, n, huffmanTreeComparator(sortHuffmanTree)) - - /* The nodes are: - [0, n): the sorted leaf nodes that we start with. - [n]: we add a sentinel here. - [n + 1, 2n): new parent nodes are added here, starting from - (n+1). These are naturally in ascending order. - [2n]: we add a sentinel at the end as well. - There will be (2n+1) elements at the end. */ - tree[n] = sentinel - - tree[n+1] = sentinel - - i = 0 /* Points to the next leaf node. */ - j = n + 1 /* Points to the next non-leaf node. */ - for k = n - 1; k != 0; k-- { - var left uint - var right uint - if tree[i].total_count_ <= tree[j].total_count_ { - left = i - i++ - } else { - left = j - j++ - } - - if tree[i].total_count_ <= tree[j].total_count_ { - right = i - i++ - } else { - right = j - j++ - } - { - /* The sentinel node becomes the parent node. */ - var j_end uint = 2*n - k - tree[j_end].total_count_ = tree[left].total_count_ + tree[right].total_count_ - tree[j_end].index_left_ = int16(left) - tree[j_end].index_right_or_value_ = int16(right) - - /* Add back the last sentinel node. */ - tree[j_end+1] = sentinel - } - } - - if setDepth(int(2*n-1), tree[0:], depth, tree_limit) { - /* We need to pack the Huffman tree in tree_limit bits. If this was not - successful, add fake entities to the lowest values and retry. */ - break - } - } -} - -func reverse(v []byte, start uint, end uint) { - end-- - for start < end { - var tmp byte = v[start] - v[start] = v[end] - v[end] = tmp - start++ - end-- - } -} - -func writeHuffmanTreeRepetitions(previous_value byte, value byte, repetitions uint, tree_size *uint, tree []byte, extra_bits_data []byte) { - assert(repetitions > 0) - if previous_value != value { - tree[*tree_size] = value - extra_bits_data[*tree_size] = 0 - (*tree_size)++ - repetitions-- - } - - if repetitions == 7 { - tree[*tree_size] = value - extra_bits_data[*tree_size] = 0 - (*tree_size)++ - repetitions-- - } - - if repetitions < 3 { - var i uint - for i = 0; i < repetitions; i++ { - tree[*tree_size] = value - extra_bits_data[*tree_size] = 0 - (*tree_size)++ - } - } else { - var start uint = *tree_size - repetitions -= 3 - for { - tree[*tree_size] = repeatPreviousCodeLength - extra_bits_data[*tree_size] = byte(repetitions & 0x3) - (*tree_size)++ - repetitions >>= 2 - if repetitions == 0 { - break - } - - repetitions-- - } - - reverse(tree, start, *tree_size) - reverse(extra_bits_data, start, *tree_size) - } -} - -func writeHuffmanTreeRepetitionsZeros(repetitions uint, tree_size *uint, tree []byte, extra_bits_data []byte) { - if repetitions == 11 { - tree[*tree_size] = 0 - extra_bits_data[*tree_size] = 0 - (*tree_size)++ - repetitions-- - } - - if repetitions < 3 { - var i uint - for i = 0; i < repetitions; i++ { - tree[*tree_size] = 0 - extra_bits_data[*tree_size] = 0 - (*tree_size)++ - } - } else { - var start uint = *tree_size - repetitions -= 3 - for { - tree[*tree_size] = repeatZeroCodeLength - extra_bits_data[*tree_size] = byte(repetitions & 0x7) - (*tree_size)++ - repetitions >>= 3 - if repetitions == 0 { - break - } - - repetitions-- - } - - reverse(tree, start, *tree_size) - reverse(extra_bits_data, start, *tree_size) - } -} - -/* Change the population counts in a way that the consequent - Huffman tree compression, especially its RLE-part will be more - likely to compress this data more efficiently. - - length contains the size of the histogram. - counts contains the population counts. - good_for_rle is a buffer of at least length size */ -func optimizeHuffmanCountsForRLE(length uint, counts []uint32, good_for_rle []byte) { - var nonzero_count uint = 0 - var stride uint - var limit uint - var sum uint - var streak_limit uint = 1240 - var i uint - /* Let's make the Huffman code more compatible with RLE encoding. */ - for i = 0; i < length; i++ { - if counts[i] != 0 { - nonzero_count++ - } - } - - if nonzero_count < 16 { - return - } - - for length != 0 && counts[length-1] == 0 { - length-- - } - - if length == 0 { - return /* All zeros. */ - } - - /* Now counts[0..length - 1] does not have trailing zeros. */ - { - var nonzeros uint = 0 - var smallest_nonzero uint32 = 1 << 30 - for i = 0; i < length; i++ { - if counts[i] != 0 { - nonzeros++ - if smallest_nonzero > counts[i] { - smallest_nonzero = counts[i] - } - } - } - - if nonzeros < 5 { - /* Small histogram will model it well. */ - return - } - - if smallest_nonzero < 4 { - var zeros uint = length - nonzeros - if zeros < 6 { - for i = 1; i < length-1; i++ { - if counts[i-1] != 0 && counts[i] == 0 && counts[i+1] != 0 { - counts[i] = 1 - } - } - } - } - - if nonzeros < 28 { - return - } - } - - /* 2) Let's mark all population counts that already can be encoded - with an RLE code. */ - for i := 0; i < int(length); i++ { - good_for_rle[i] = 0 - } - { - var symbol uint32 = counts[0] - /* Let's not spoil any of the existing good RLE codes. - Mark any seq of 0's that is longer as 5 as a good_for_rle. - Mark any seq of non-0's that is longer as 7 as a good_for_rle. */ - - var step uint = 0 - for i = 0; i <= length; i++ { - if i == length || counts[i] != symbol { - if (symbol == 0 && step >= 5) || (symbol != 0 && step >= 7) { - var k uint - for k = 0; k < step; k++ { - good_for_rle[i-k-1] = 1 - } - } - - step = 1 - if i != length { - symbol = counts[i] - } - } else { - step++ - } - } - } - - /* 3) Let's replace those population counts that lead to more RLE codes. - Math here is in 24.8 fixed point representation. */ - stride = 0 - - limit = uint(256*(counts[0]+counts[1]+counts[2])/3 + 420) - sum = 0 - for i = 0; i <= length; i++ { - if i == length || good_for_rle[i] != 0 || (i != 0 && good_for_rle[i-1] != 0) || (256*counts[i]-uint32(limit)+uint32(streak_limit)) >= uint32(2*streak_limit) { - if stride >= 4 || (stride >= 3 && sum == 0) { - var k uint - var count uint = (sum + stride/2) / stride - /* The stride must end, collapse what we have, if we have enough (4). */ - if count == 0 { - count = 1 - } - - if sum == 0 { - /* Don't make an all zeros stride to be upgraded to ones. */ - count = 0 - } - - for k = 0; k < stride; k++ { - /* We don't want to change value at counts[i], - that is already belonging to the next stride. Thus - 1. */ - counts[i-k-1] = uint32(count) - } - } - - stride = 0 - sum = 0 - if i < length-2 { - /* All interesting strides have a count of at least 4, */ - /* at least when non-zeros. */ - limit = uint(256*(counts[i]+counts[i+1]+counts[i+2])/3 + 420) - } else if i < length { - limit = uint(256 * counts[i]) - } else { - limit = 0 - } - } - - stride++ - if i != length { - sum += uint(counts[i]) - if stride >= 4 { - limit = (256*sum + stride/2) / stride - } - - if stride == 4 { - limit += 120 - } - } - } -} - -func decideOverRLEUse(depth []byte, length uint, use_rle_for_non_zero *bool, use_rle_for_zero *bool) { - var total_reps_zero uint = 0 - var total_reps_non_zero uint = 0 - var count_reps_zero uint = 1 - var count_reps_non_zero uint = 1 - var i uint - for i = 0; i < length; { - var value byte = depth[i] - var reps uint = 1 - var k uint - for k = i + 1; k < length && depth[k] == value; k++ { - reps++ - } - - if reps >= 3 && value == 0 { - total_reps_zero += reps - count_reps_zero++ - } - - if reps >= 4 && value != 0 { - total_reps_non_zero += reps - count_reps_non_zero++ - } - - i += reps - } - - *use_rle_for_non_zero = total_reps_non_zero > count_reps_non_zero*2 - *use_rle_for_zero = total_reps_zero > count_reps_zero*2 -} - -/* Write a Huffman tree from bit depths into the bit-stream representation - of a Huffman tree. The generated Huffman tree is to be compressed once - more using a Huffman tree */ -func writeHuffmanTree(depth []byte, length uint, tree_size *uint, tree []byte, extra_bits_data []byte) { - var previous_value byte = initialRepeatedCodeLength - var i uint - var use_rle_for_non_zero bool = false - var use_rle_for_zero bool = false - var new_length uint = length - /* Throw away trailing zeros. */ - for i = 0; i < length; i++ { - if depth[length-i-1] == 0 { - new_length-- - } else { - break - } - } - - /* First gather statistics on if it is a good idea to do RLE. */ - if length > 50 { - /* Find RLE coding for longer codes. - Shorter codes seem not to benefit from RLE. */ - decideOverRLEUse(depth, new_length, &use_rle_for_non_zero, &use_rle_for_zero) - } - - /* Actual RLE coding. */ - for i = 0; i < new_length; { - var value byte = depth[i] - var reps uint = 1 - if (value != 0 && use_rle_for_non_zero) || (value == 0 && use_rle_for_zero) { - var k uint - for k = i + 1; k < new_length && depth[k] == value; k++ { - reps++ - } - } - - if value == 0 { - writeHuffmanTreeRepetitionsZeros(reps, tree_size, tree, extra_bits_data) - } else { - writeHuffmanTreeRepetitions(previous_value, value, reps, tree_size, tree, extra_bits_data) - previous_value = value - } - - i += reps - } -} - -var reverseBits_kLut = [16]uint{ - 0x00, - 0x08, - 0x04, - 0x0C, - 0x02, - 0x0A, - 0x06, - 0x0E, - 0x01, - 0x09, - 0x05, - 0x0D, - 0x03, - 0x0B, - 0x07, - 0x0F, -} - -func reverseBits(num_bits uint, bits uint16) uint16 { - var retval uint = reverseBits_kLut[bits&0x0F] - var i uint - for i = 4; i < num_bits; i += 4 { - retval <<= 4 - bits = uint16(bits >> 4) - retval |= reverseBits_kLut[bits&0x0F] - } - - retval >>= ((0 - num_bits) & 0x03) - return uint16(retval) -} - -/* 0..15 are values for bits */ -const maxHuffmanBits = 16 - -/* Get the actual bit values for a tree of bit depths. */ -func convertBitDepthsToSymbols(depth []byte, len uint, bits []uint16) { - var bl_count = [maxHuffmanBits]uint16{0} - var next_code [maxHuffmanBits]uint16 - var i uint - /* In Brotli, all bit depths are [1..15] - 0 bit depth means that the symbol does not exist. */ - - var code int = 0 - for i = 0; i < len; i++ { - bl_count[depth[i]]++ - } - - bl_count[0] = 0 - next_code[0] = 0 - for i = 1; i < maxHuffmanBits; i++ { - code = (code + int(bl_count[i-1])) << 1 - next_code[i] = uint16(code) - } - - for i = 0; i < len; i++ { - if depth[i] != 0 { - bits[i] = reverseBits(uint(depth[i]), next_code[depth[i]]) - next_code[depth[i]]++ - } - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/entropy_encode_static.go b/src/vendor/github.com/andybalholm/brotli/entropy_encode_static.go deleted file mode 100644 index 294aff4f..00000000 --- a/src/vendor/github.com/andybalholm/brotli/entropy_encode_static.go +++ /dev/null @@ -1,4399 +0,0 @@ -package brotli - -var kCodeLengthDepth = [18]byte{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 0, 4, 4} - -var kStaticCommandCodeDepth = [numCommandSymbols]byte{ - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 9, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, - 11, -} - -var kStaticDistanceCodeDepth = [64]byte{ - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, -} - -var kCodeLengthBits = [18]uint32{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 15, 31, 0, 11, 7} - -func storeStaticCodeLengthCode(storage_ix *uint, storage []byte) { - writeBits(40, 0x0000FF55555554, storage_ix, storage) -} - -func storeStaticCodeLengthCodeBW(bw *bitWriter) { - bw.writeBits(32, 0x55555554) - bw.writeBits(8, 0xFF) -} - -var kZeroRepsBits = [numCommandSymbols]uint64{ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000007, - 0x00000017, - 0x00000027, - 0x00000037, - 0x00000047, - 0x00000057, - 0x00000067, - 0x00000077, - 0x00000770, - 0x00000b87, - 0x00001387, - 0x00001b87, - 0x00002387, - 0x00002b87, - 0x00003387, - 0x00003b87, - 0x00000397, - 0x00000b97, - 0x00001397, - 0x00001b97, - 0x00002397, - 0x00002b97, - 0x00003397, - 0x00003b97, - 0x000003a7, - 0x00000ba7, - 0x000013a7, - 0x00001ba7, - 0x000023a7, - 0x00002ba7, - 0x000033a7, - 0x00003ba7, - 0x000003b7, - 0x00000bb7, - 0x000013b7, - 0x00001bb7, - 0x000023b7, - 0x00002bb7, - 0x000033b7, - 0x00003bb7, - 0x000003c7, - 0x00000bc7, - 0x000013c7, - 0x00001bc7, - 0x000023c7, - 0x00002bc7, - 0x000033c7, - 0x00003bc7, - 0x000003d7, - 0x00000bd7, - 0x000013d7, - 0x00001bd7, - 0x000023d7, - 0x00002bd7, - 0x000033d7, - 0x00003bd7, - 0x000003e7, - 0x00000be7, - 0x000013e7, - 0x00001be7, - 0x000023e7, - 0x00002be7, - 0x000033e7, - 0x00003be7, - 0x000003f7, - 0x00000bf7, - 0x000013f7, - 0x00001bf7, - 0x000023f7, - 0x00002bf7, - 0x000033f7, - 0x00003bf7, - 0x0001c387, - 0x0005c387, - 0x0009c387, - 0x000dc387, - 0x0011c387, - 0x0015c387, - 0x0019c387, - 0x001dc387, - 0x0001cb87, - 0x0005cb87, - 0x0009cb87, - 0x000dcb87, - 0x0011cb87, - 0x0015cb87, - 0x0019cb87, - 0x001dcb87, - 0x0001d387, - 0x0005d387, - 0x0009d387, - 0x000dd387, - 0x0011d387, - 0x0015d387, - 0x0019d387, - 0x001dd387, - 0x0001db87, - 0x0005db87, - 0x0009db87, - 0x000ddb87, - 0x0011db87, - 0x0015db87, - 0x0019db87, - 0x001ddb87, - 0x0001e387, - 0x0005e387, - 0x0009e387, - 0x000de387, - 0x0011e387, - 0x0015e387, - 0x0019e387, - 0x001de387, - 0x0001eb87, - 0x0005eb87, - 0x0009eb87, - 0x000deb87, - 0x0011eb87, - 0x0015eb87, - 0x0019eb87, - 0x001deb87, - 0x0001f387, - 0x0005f387, - 0x0009f387, - 0x000df387, - 0x0011f387, - 0x0015f387, - 0x0019f387, - 0x001df387, - 0x0001fb87, - 0x0005fb87, - 0x0009fb87, - 0x000dfb87, - 0x0011fb87, - 0x0015fb87, - 0x0019fb87, - 0x001dfb87, - 0x0001c397, - 0x0005c397, - 0x0009c397, - 0x000dc397, - 0x0011c397, - 0x0015c397, - 0x0019c397, - 0x001dc397, - 0x0001cb97, - 0x0005cb97, - 0x0009cb97, - 0x000dcb97, - 0x0011cb97, - 0x0015cb97, - 0x0019cb97, - 0x001dcb97, - 0x0001d397, - 0x0005d397, - 0x0009d397, - 0x000dd397, - 0x0011d397, - 0x0015d397, - 0x0019d397, - 0x001dd397, - 0x0001db97, - 0x0005db97, - 0x0009db97, - 0x000ddb97, - 0x0011db97, - 0x0015db97, - 0x0019db97, - 0x001ddb97, - 0x0001e397, - 0x0005e397, - 0x0009e397, - 0x000de397, - 0x0011e397, - 0x0015e397, - 0x0019e397, - 0x001de397, - 0x0001eb97, - 0x0005eb97, - 0x0009eb97, - 0x000deb97, - 0x0011eb97, - 0x0015eb97, - 0x0019eb97, - 0x001deb97, - 0x0001f397, - 0x0005f397, - 0x0009f397, - 0x000df397, - 0x0011f397, - 0x0015f397, - 0x0019f397, - 0x001df397, - 0x0001fb97, - 0x0005fb97, - 0x0009fb97, - 0x000dfb97, - 0x0011fb97, - 0x0015fb97, - 0x0019fb97, - 0x001dfb97, - 0x0001c3a7, - 0x0005c3a7, - 0x0009c3a7, - 0x000dc3a7, - 0x0011c3a7, - 0x0015c3a7, - 0x0019c3a7, - 0x001dc3a7, - 0x0001cba7, - 0x0005cba7, - 0x0009cba7, - 0x000dcba7, - 0x0011cba7, - 0x0015cba7, - 0x0019cba7, - 0x001dcba7, - 0x0001d3a7, - 0x0005d3a7, - 0x0009d3a7, - 0x000dd3a7, - 0x0011d3a7, - 0x0015d3a7, - 0x0019d3a7, - 0x001dd3a7, - 0x0001dba7, - 0x0005dba7, - 0x0009dba7, - 0x000ddba7, - 0x0011dba7, - 0x0015dba7, - 0x0019dba7, - 0x001ddba7, - 0x0001e3a7, - 0x0005e3a7, - 0x0009e3a7, - 0x000de3a7, - 0x0011e3a7, - 0x0015e3a7, - 0x0019e3a7, - 0x001de3a7, - 0x0001eba7, - 0x0005eba7, - 0x0009eba7, - 0x000deba7, - 0x0011eba7, - 0x0015eba7, - 0x0019eba7, - 0x001deba7, - 0x0001f3a7, - 0x0005f3a7, - 0x0009f3a7, - 0x000df3a7, - 0x0011f3a7, - 0x0015f3a7, - 0x0019f3a7, - 0x001df3a7, - 0x0001fba7, - 0x0005fba7, - 0x0009fba7, - 0x000dfba7, - 0x0011fba7, - 0x0015fba7, - 0x0019fba7, - 0x001dfba7, - 0x0001c3b7, - 0x0005c3b7, - 0x0009c3b7, - 0x000dc3b7, - 0x0011c3b7, - 0x0015c3b7, - 0x0019c3b7, - 0x001dc3b7, - 0x0001cbb7, - 0x0005cbb7, - 0x0009cbb7, - 0x000dcbb7, - 0x0011cbb7, - 0x0015cbb7, - 0x0019cbb7, - 0x001dcbb7, - 0x0001d3b7, - 0x0005d3b7, - 0x0009d3b7, - 0x000dd3b7, - 0x0011d3b7, - 0x0015d3b7, - 0x0019d3b7, - 0x001dd3b7, - 0x0001dbb7, - 0x0005dbb7, - 0x0009dbb7, - 0x000ddbb7, - 0x0011dbb7, - 0x0015dbb7, - 0x0019dbb7, - 0x001ddbb7, - 0x0001e3b7, - 0x0005e3b7, - 0x0009e3b7, - 0x000de3b7, - 0x0011e3b7, - 0x0015e3b7, - 0x0019e3b7, - 0x001de3b7, - 0x0001ebb7, - 0x0005ebb7, - 0x0009ebb7, - 0x000debb7, - 0x0011ebb7, - 0x0015ebb7, - 0x0019ebb7, - 0x001debb7, - 0x0001f3b7, - 0x0005f3b7, - 0x0009f3b7, - 0x000df3b7, - 0x0011f3b7, - 0x0015f3b7, - 0x0019f3b7, - 0x001df3b7, - 0x0001fbb7, - 0x0005fbb7, - 0x0009fbb7, - 0x000dfbb7, - 0x0011fbb7, - 0x0015fbb7, - 0x0019fbb7, - 0x001dfbb7, - 0x0001c3c7, - 0x0005c3c7, - 0x0009c3c7, - 0x000dc3c7, - 0x0011c3c7, - 0x0015c3c7, - 0x0019c3c7, - 0x001dc3c7, - 0x0001cbc7, - 0x0005cbc7, - 0x0009cbc7, - 0x000dcbc7, - 0x0011cbc7, - 0x0015cbc7, - 0x0019cbc7, - 0x001dcbc7, - 0x0001d3c7, - 0x0005d3c7, - 0x0009d3c7, - 0x000dd3c7, - 0x0011d3c7, - 0x0015d3c7, - 0x0019d3c7, - 0x001dd3c7, - 0x0001dbc7, - 0x0005dbc7, - 0x0009dbc7, - 0x000ddbc7, - 0x0011dbc7, - 0x0015dbc7, - 0x0019dbc7, - 0x001ddbc7, - 0x0001e3c7, - 0x0005e3c7, - 0x0009e3c7, - 0x000de3c7, - 0x0011e3c7, - 0x0015e3c7, - 0x0019e3c7, - 0x001de3c7, - 0x0001ebc7, - 0x0005ebc7, - 0x0009ebc7, - 0x000debc7, - 0x0011ebc7, - 0x0015ebc7, - 0x0019ebc7, - 0x001debc7, - 0x0001f3c7, - 0x0005f3c7, - 0x0009f3c7, - 0x000df3c7, - 0x0011f3c7, - 0x0015f3c7, - 0x0019f3c7, - 0x001df3c7, - 0x0001fbc7, - 0x0005fbc7, - 0x0009fbc7, - 0x000dfbc7, - 0x0011fbc7, - 0x0015fbc7, - 0x0019fbc7, - 0x001dfbc7, - 0x0001c3d7, - 0x0005c3d7, - 0x0009c3d7, - 0x000dc3d7, - 0x0011c3d7, - 0x0015c3d7, - 0x0019c3d7, - 0x001dc3d7, - 0x0001cbd7, - 0x0005cbd7, - 0x0009cbd7, - 0x000dcbd7, - 0x0011cbd7, - 0x0015cbd7, - 0x0019cbd7, - 0x001dcbd7, - 0x0001d3d7, - 0x0005d3d7, - 0x0009d3d7, - 0x000dd3d7, - 0x0011d3d7, - 0x0015d3d7, - 0x0019d3d7, - 0x001dd3d7, - 0x0001dbd7, - 0x0005dbd7, - 0x0009dbd7, - 0x000ddbd7, - 0x0011dbd7, - 0x0015dbd7, - 0x0019dbd7, - 0x001ddbd7, - 0x0001e3d7, - 0x0005e3d7, - 0x0009e3d7, - 0x000de3d7, - 0x0011e3d7, - 0x0015e3d7, - 0x0019e3d7, - 0x001de3d7, - 0x0001ebd7, - 0x0005ebd7, - 0x0009ebd7, - 0x000debd7, - 0x0011ebd7, - 0x0015ebd7, - 0x0019ebd7, - 0x001debd7, - 0x0001f3d7, - 0x0005f3d7, - 0x0009f3d7, - 0x000df3d7, - 0x0011f3d7, - 0x0015f3d7, - 0x0019f3d7, - 0x001df3d7, - 0x0001fbd7, - 0x0005fbd7, - 0x0009fbd7, - 0x000dfbd7, - 0x0011fbd7, - 0x0015fbd7, - 0x0019fbd7, - 0x001dfbd7, - 0x0001c3e7, - 0x0005c3e7, - 0x0009c3e7, - 0x000dc3e7, - 0x0011c3e7, - 0x0015c3e7, - 0x0019c3e7, - 0x001dc3e7, - 0x0001cbe7, - 0x0005cbe7, - 0x0009cbe7, - 0x000dcbe7, - 0x0011cbe7, - 0x0015cbe7, - 0x0019cbe7, - 0x001dcbe7, - 0x0001d3e7, - 0x0005d3e7, - 0x0009d3e7, - 0x000dd3e7, - 0x0011d3e7, - 0x0015d3e7, - 0x0019d3e7, - 0x001dd3e7, - 0x0001dbe7, - 0x0005dbe7, - 0x0009dbe7, - 0x000ddbe7, - 0x0011dbe7, - 0x0015dbe7, - 0x0019dbe7, - 0x001ddbe7, - 0x0001e3e7, - 0x0005e3e7, - 0x0009e3e7, - 0x000de3e7, - 0x0011e3e7, - 0x0015e3e7, - 0x0019e3e7, - 0x001de3e7, - 0x0001ebe7, - 0x0005ebe7, - 0x0009ebe7, - 0x000debe7, - 0x0011ebe7, - 0x0015ebe7, - 0x0019ebe7, - 0x001debe7, - 0x0001f3e7, - 0x0005f3e7, - 0x0009f3e7, - 0x000df3e7, - 0x0011f3e7, - 0x0015f3e7, - 0x0019f3e7, - 0x001df3e7, - 0x0001fbe7, - 0x0005fbe7, - 0x0009fbe7, - 0x000dfbe7, - 0x0011fbe7, - 0x0015fbe7, - 0x0019fbe7, - 0x001dfbe7, - 0x0001c3f7, - 0x0005c3f7, - 0x0009c3f7, - 0x000dc3f7, - 0x0011c3f7, - 0x0015c3f7, - 0x0019c3f7, - 0x001dc3f7, - 0x0001cbf7, - 0x0005cbf7, - 0x0009cbf7, - 0x000dcbf7, - 0x0011cbf7, - 0x0015cbf7, - 0x0019cbf7, - 0x001dcbf7, - 0x0001d3f7, - 0x0005d3f7, - 0x0009d3f7, - 0x000dd3f7, - 0x0011d3f7, - 0x0015d3f7, - 0x0019d3f7, - 0x001dd3f7, - 0x0001dbf7, - 0x0005dbf7, - 0x0009dbf7, - 0x000ddbf7, - 0x0011dbf7, - 0x0015dbf7, - 0x0019dbf7, - 0x001ddbf7, - 0x0001e3f7, - 0x0005e3f7, - 0x0009e3f7, - 0x000de3f7, - 0x0011e3f7, - 0x0015e3f7, - 0x0019e3f7, - 0x001de3f7, - 0x0001ebf7, - 0x0005ebf7, - 0x0009ebf7, - 0x000debf7, - 0x0011ebf7, - 0x0015ebf7, - 0x0019ebf7, - 0x001debf7, - 0x0001f3f7, - 0x0005f3f7, - 0x0009f3f7, - 0x000df3f7, - 0x0011f3f7, - 0x0015f3f7, - 0x0019f3f7, - 0x001df3f7, - 0x0001fbf7, - 0x0005fbf7, - 0x0009fbf7, - 0x000dfbf7, - 0x0011fbf7, - 0x0015fbf7, - 0x0019fbf7, - 0x001dfbf7, - 0x00e1c387, - 0x02e1c387, - 0x04e1c387, - 0x06e1c387, - 0x08e1c387, - 0x0ae1c387, - 0x0ce1c387, - 0x0ee1c387, - 0x00e5c387, - 0x02e5c387, - 0x04e5c387, - 0x06e5c387, - 0x08e5c387, - 0x0ae5c387, - 0x0ce5c387, - 0x0ee5c387, - 0x00e9c387, - 0x02e9c387, - 0x04e9c387, - 0x06e9c387, - 0x08e9c387, - 0x0ae9c387, - 0x0ce9c387, - 0x0ee9c387, - 0x00edc387, - 0x02edc387, - 0x04edc387, - 0x06edc387, - 0x08edc387, - 0x0aedc387, - 0x0cedc387, - 0x0eedc387, - 0x00f1c387, - 0x02f1c387, - 0x04f1c387, - 0x06f1c387, - 0x08f1c387, - 0x0af1c387, - 0x0cf1c387, - 0x0ef1c387, - 0x00f5c387, - 0x02f5c387, - 0x04f5c387, - 0x06f5c387, - 0x08f5c387, - 0x0af5c387, - 0x0cf5c387, - 0x0ef5c387, - 0x00f9c387, - 0x02f9c387, - 0x04f9c387, - 0x06f9c387, - 0x08f9c387, - 0x0af9c387, - 0x0cf9c387, - 0x0ef9c387, - 0x00fdc387, - 0x02fdc387, - 0x04fdc387, - 0x06fdc387, - 0x08fdc387, - 0x0afdc387, - 0x0cfdc387, - 0x0efdc387, - 0x00e1cb87, - 0x02e1cb87, - 0x04e1cb87, - 0x06e1cb87, - 0x08e1cb87, - 0x0ae1cb87, - 0x0ce1cb87, - 0x0ee1cb87, - 0x00e5cb87, - 0x02e5cb87, - 0x04e5cb87, - 0x06e5cb87, - 0x08e5cb87, - 0x0ae5cb87, - 0x0ce5cb87, - 0x0ee5cb87, - 0x00e9cb87, - 0x02e9cb87, - 0x04e9cb87, - 0x06e9cb87, - 0x08e9cb87, - 0x0ae9cb87, - 0x0ce9cb87, - 0x0ee9cb87, - 0x00edcb87, - 0x02edcb87, - 0x04edcb87, - 0x06edcb87, - 0x08edcb87, - 0x0aedcb87, - 0x0cedcb87, - 0x0eedcb87, - 0x00f1cb87, - 0x02f1cb87, - 0x04f1cb87, - 0x06f1cb87, - 0x08f1cb87, - 0x0af1cb87, - 0x0cf1cb87, - 0x0ef1cb87, - 0x00f5cb87, - 0x02f5cb87, - 0x04f5cb87, - 0x06f5cb87, - 0x08f5cb87, - 0x0af5cb87, - 0x0cf5cb87, - 0x0ef5cb87, - 0x00f9cb87, - 0x02f9cb87, - 0x04f9cb87, - 0x06f9cb87, - 0x08f9cb87, -} - -var kZeroRepsDepth = [numCommandSymbols]uint32{ - 0, - 4, - 8, - 7, - 7, - 7, - 7, - 7, - 7, - 7, - 7, - 11, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 14, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 21, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, - 28, -} - -var kNonZeroRepsBits = [numCommandSymbols]uint64{ - 0x0000000b, - 0x0000001b, - 0x0000002b, - 0x0000003b, - 0x000002cb, - 0x000006cb, - 0x00000acb, - 0x00000ecb, - 0x000002db, - 0x000006db, - 0x00000adb, - 0x00000edb, - 0x000002eb, - 0x000006eb, - 0x00000aeb, - 0x00000eeb, - 0x000002fb, - 0x000006fb, - 0x00000afb, - 0x00000efb, - 0x0000b2cb, - 0x0001b2cb, - 0x0002b2cb, - 0x0003b2cb, - 0x0000b6cb, - 0x0001b6cb, - 0x0002b6cb, - 0x0003b6cb, - 0x0000bacb, - 0x0001bacb, - 0x0002bacb, - 0x0003bacb, - 0x0000becb, - 0x0001becb, - 0x0002becb, - 0x0003becb, - 0x0000b2db, - 0x0001b2db, - 0x0002b2db, - 0x0003b2db, - 0x0000b6db, - 0x0001b6db, - 0x0002b6db, - 0x0003b6db, - 0x0000badb, - 0x0001badb, - 0x0002badb, - 0x0003badb, - 0x0000bedb, - 0x0001bedb, - 0x0002bedb, - 0x0003bedb, - 0x0000b2eb, - 0x0001b2eb, - 0x0002b2eb, - 0x0003b2eb, - 0x0000b6eb, - 0x0001b6eb, - 0x0002b6eb, - 0x0003b6eb, - 0x0000baeb, - 0x0001baeb, - 0x0002baeb, - 0x0003baeb, - 0x0000beeb, - 0x0001beeb, - 0x0002beeb, - 0x0003beeb, - 0x0000b2fb, - 0x0001b2fb, - 0x0002b2fb, - 0x0003b2fb, - 0x0000b6fb, - 0x0001b6fb, - 0x0002b6fb, - 0x0003b6fb, - 0x0000bafb, - 0x0001bafb, - 0x0002bafb, - 0x0003bafb, - 0x0000befb, - 0x0001befb, - 0x0002befb, - 0x0003befb, - 0x002cb2cb, - 0x006cb2cb, - 0x00acb2cb, - 0x00ecb2cb, - 0x002db2cb, - 0x006db2cb, - 0x00adb2cb, - 0x00edb2cb, - 0x002eb2cb, - 0x006eb2cb, - 0x00aeb2cb, - 0x00eeb2cb, - 0x002fb2cb, - 0x006fb2cb, - 0x00afb2cb, - 0x00efb2cb, - 0x002cb6cb, - 0x006cb6cb, - 0x00acb6cb, - 0x00ecb6cb, - 0x002db6cb, - 0x006db6cb, - 0x00adb6cb, - 0x00edb6cb, - 0x002eb6cb, - 0x006eb6cb, - 0x00aeb6cb, - 0x00eeb6cb, - 0x002fb6cb, - 0x006fb6cb, - 0x00afb6cb, - 0x00efb6cb, - 0x002cbacb, - 0x006cbacb, - 0x00acbacb, - 0x00ecbacb, - 0x002dbacb, - 0x006dbacb, - 0x00adbacb, - 0x00edbacb, - 0x002ebacb, - 0x006ebacb, - 0x00aebacb, - 0x00eebacb, - 0x002fbacb, - 0x006fbacb, - 0x00afbacb, - 0x00efbacb, - 0x002cbecb, - 0x006cbecb, - 0x00acbecb, - 0x00ecbecb, - 0x002dbecb, - 0x006dbecb, - 0x00adbecb, - 0x00edbecb, - 0x002ebecb, - 0x006ebecb, - 0x00aebecb, - 0x00eebecb, - 0x002fbecb, - 0x006fbecb, - 0x00afbecb, - 0x00efbecb, - 0x002cb2db, - 0x006cb2db, - 0x00acb2db, - 0x00ecb2db, - 0x002db2db, - 0x006db2db, - 0x00adb2db, - 0x00edb2db, - 0x002eb2db, - 0x006eb2db, - 0x00aeb2db, - 0x00eeb2db, - 0x002fb2db, - 0x006fb2db, - 0x00afb2db, - 0x00efb2db, - 0x002cb6db, - 0x006cb6db, - 0x00acb6db, - 0x00ecb6db, - 0x002db6db, - 0x006db6db, - 0x00adb6db, - 0x00edb6db, - 0x002eb6db, - 0x006eb6db, - 0x00aeb6db, - 0x00eeb6db, - 0x002fb6db, - 0x006fb6db, - 0x00afb6db, - 0x00efb6db, - 0x002cbadb, - 0x006cbadb, - 0x00acbadb, - 0x00ecbadb, - 0x002dbadb, - 0x006dbadb, - 0x00adbadb, - 0x00edbadb, - 0x002ebadb, - 0x006ebadb, - 0x00aebadb, - 0x00eebadb, - 0x002fbadb, - 0x006fbadb, - 0x00afbadb, - 0x00efbadb, - 0x002cbedb, - 0x006cbedb, - 0x00acbedb, - 0x00ecbedb, - 0x002dbedb, - 0x006dbedb, - 0x00adbedb, - 0x00edbedb, - 0x002ebedb, - 0x006ebedb, - 0x00aebedb, - 0x00eebedb, - 0x002fbedb, - 0x006fbedb, - 0x00afbedb, - 0x00efbedb, - 0x002cb2eb, - 0x006cb2eb, - 0x00acb2eb, - 0x00ecb2eb, - 0x002db2eb, - 0x006db2eb, - 0x00adb2eb, - 0x00edb2eb, - 0x002eb2eb, - 0x006eb2eb, - 0x00aeb2eb, - 0x00eeb2eb, - 0x002fb2eb, - 0x006fb2eb, - 0x00afb2eb, - 0x00efb2eb, - 0x002cb6eb, - 0x006cb6eb, - 0x00acb6eb, - 0x00ecb6eb, - 0x002db6eb, - 0x006db6eb, - 0x00adb6eb, - 0x00edb6eb, - 0x002eb6eb, - 0x006eb6eb, - 0x00aeb6eb, - 0x00eeb6eb, - 0x002fb6eb, - 0x006fb6eb, - 0x00afb6eb, - 0x00efb6eb, - 0x002cbaeb, - 0x006cbaeb, - 0x00acbaeb, - 0x00ecbaeb, - 0x002dbaeb, - 0x006dbaeb, - 0x00adbaeb, - 0x00edbaeb, - 0x002ebaeb, - 0x006ebaeb, - 0x00aebaeb, - 0x00eebaeb, - 0x002fbaeb, - 0x006fbaeb, - 0x00afbaeb, - 0x00efbaeb, - 0x002cbeeb, - 0x006cbeeb, - 0x00acbeeb, - 0x00ecbeeb, - 0x002dbeeb, - 0x006dbeeb, - 0x00adbeeb, - 0x00edbeeb, - 0x002ebeeb, - 0x006ebeeb, - 0x00aebeeb, - 0x00eebeeb, - 0x002fbeeb, - 0x006fbeeb, - 0x00afbeeb, - 0x00efbeeb, - 0x002cb2fb, - 0x006cb2fb, - 0x00acb2fb, - 0x00ecb2fb, - 0x002db2fb, - 0x006db2fb, - 0x00adb2fb, - 0x00edb2fb, - 0x002eb2fb, - 0x006eb2fb, - 0x00aeb2fb, - 0x00eeb2fb, - 0x002fb2fb, - 0x006fb2fb, - 0x00afb2fb, - 0x00efb2fb, - 0x002cb6fb, - 0x006cb6fb, - 0x00acb6fb, - 0x00ecb6fb, - 0x002db6fb, - 0x006db6fb, - 0x00adb6fb, - 0x00edb6fb, - 0x002eb6fb, - 0x006eb6fb, - 0x00aeb6fb, - 0x00eeb6fb, - 0x002fb6fb, - 0x006fb6fb, - 0x00afb6fb, - 0x00efb6fb, - 0x002cbafb, - 0x006cbafb, - 0x00acbafb, - 0x00ecbafb, - 0x002dbafb, - 0x006dbafb, - 0x00adbafb, - 0x00edbafb, - 0x002ebafb, - 0x006ebafb, - 0x00aebafb, - 0x00eebafb, - 0x002fbafb, - 0x006fbafb, - 0x00afbafb, - 0x00efbafb, - 0x002cbefb, - 0x006cbefb, - 0x00acbefb, - 0x00ecbefb, - 0x002dbefb, - 0x006dbefb, - 0x00adbefb, - 0x00edbefb, - 0x002ebefb, - 0x006ebefb, - 0x00aebefb, - 0x00eebefb, - 0x002fbefb, - 0x006fbefb, - 0x00afbefb, - 0x00efbefb, - 0x0b2cb2cb, - 0x1b2cb2cb, - 0x2b2cb2cb, - 0x3b2cb2cb, - 0x0b6cb2cb, - 0x1b6cb2cb, - 0x2b6cb2cb, - 0x3b6cb2cb, - 0x0bacb2cb, - 0x1bacb2cb, - 0x2bacb2cb, - 0x3bacb2cb, - 0x0becb2cb, - 0x1becb2cb, - 0x2becb2cb, - 0x3becb2cb, - 0x0b2db2cb, - 0x1b2db2cb, - 0x2b2db2cb, - 0x3b2db2cb, - 0x0b6db2cb, - 0x1b6db2cb, - 0x2b6db2cb, - 0x3b6db2cb, - 0x0badb2cb, - 0x1badb2cb, - 0x2badb2cb, - 0x3badb2cb, - 0x0bedb2cb, - 0x1bedb2cb, - 0x2bedb2cb, - 0x3bedb2cb, - 0x0b2eb2cb, - 0x1b2eb2cb, - 0x2b2eb2cb, - 0x3b2eb2cb, - 0x0b6eb2cb, - 0x1b6eb2cb, - 0x2b6eb2cb, - 0x3b6eb2cb, - 0x0baeb2cb, - 0x1baeb2cb, - 0x2baeb2cb, - 0x3baeb2cb, - 0x0beeb2cb, - 0x1beeb2cb, - 0x2beeb2cb, - 0x3beeb2cb, - 0x0b2fb2cb, - 0x1b2fb2cb, - 0x2b2fb2cb, - 0x3b2fb2cb, - 0x0b6fb2cb, - 0x1b6fb2cb, - 0x2b6fb2cb, - 0x3b6fb2cb, - 0x0bafb2cb, - 0x1bafb2cb, - 0x2bafb2cb, - 0x3bafb2cb, - 0x0befb2cb, - 0x1befb2cb, - 0x2befb2cb, - 0x3befb2cb, - 0x0b2cb6cb, - 0x1b2cb6cb, - 0x2b2cb6cb, - 0x3b2cb6cb, - 0x0b6cb6cb, - 0x1b6cb6cb, - 0x2b6cb6cb, - 0x3b6cb6cb, - 0x0bacb6cb, - 0x1bacb6cb, - 0x2bacb6cb, - 0x3bacb6cb, - 0x0becb6cb, - 0x1becb6cb, - 0x2becb6cb, - 0x3becb6cb, - 0x0b2db6cb, - 0x1b2db6cb, - 0x2b2db6cb, - 0x3b2db6cb, - 0x0b6db6cb, - 0x1b6db6cb, - 0x2b6db6cb, - 0x3b6db6cb, - 0x0badb6cb, - 0x1badb6cb, - 0x2badb6cb, - 0x3badb6cb, - 0x0bedb6cb, - 0x1bedb6cb, - 0x2bedb6cb, - 0x3bedb6cb, - 0x0b2eb6cb, - 0x1b2eb6cb, - 0x2b2eb6cb, - 0x3b2eb6cb, - 0x0b6eb6cb, - 0x1b6eb6cb, - 0x2b6eb6cb, - 0x3b6eb6cb, - 0x0baeb6cb, - 0x1baeb6cb, - 0x2baeb6cb, - 0x3baeb6cb, - 0x0beeb6cb, - 0x1beeb6cb, - 0x2beeb6cb, - 0x3beeb6cb, - 0x0b2fb6cb, - 0x1b2fb6cb, - 0x2b2fb6cb, - 0x3b2fb6cb, - 0x0b6fb6cb, - 0x1b6fb6cb, - 0x2b6fb6cb, - 0x3b6fb6cb, - 0x0bafb6cb, - 0x1bafb6cb, - 0x2bafb6cb, - 0x3bafb6cb, - 0x0befb6cb, - 0x1befb6cb, - 0x2befb6cb, - 0x3befb6cb, - 0x0b2cbacb, - 0x1b2cbacb, - 0x2b2cbacb, - 0x3b2cbacb, - 0x0b6cbacb, - 0x1b6cbacb, - 0x2b6cbacb, - 0x3b6cbacb, - 0x0bacbacb, - 0x1bacbacb, - 0x2bacbacb, - 0x3bacbacb, - 0x0becbacb, - 0x1becbacb, - 0x2becbacb, - 0x3becbacb, - 0x0b2dbacb, - 0x1b2dbacb, - 0x2b2dbacb, - 0x3b2dbacb, - 0x0b6dbacb, - 0x1b6dbacb, - 0x2b6dbacb, - 0x3b6dbacb, - 0x0badbacb, - 0x1badbacb, - 0x2badbacb, - 0x3badbacb, - 0x0bedbacb, - 0x1bedbacb, - 0x2bedbacb, - 0x3bedbacb, - 0x0b2ebacb, - 0x1b2ebacb, - 0x2b2ebacb, - 0x3b2ebacb, - 0x0b6ebacb, - 0x1b6ebacb, - 0x2b6ebacb, - 0x3b6ebacb, - 0x0baebacb, - 0x1baebacb, - 0x2baebacb, - 0x3baebacb, - 0x0beebacb, - 0x1beebacb, - 0x2beebacb, - 0x3beebacb, - 0x0b2fbacb, - 0x1b2fbacb, - 0x2b2fbacb, - 0x3b2fbacb, - 0x0b6fbacb, - 0x1b6fbacb, - 0x2b6fbacb, - 0x3b6fbacb, - 0x0bafbacb, - 0x1bafbacb, - 0x2bafbacb, - 0x3bafbacb, - 0x0befbacb, - 0x1befbacb, - 0x2befbacb, - 0x3befbacb, - 0x0b2cbecb, - 0x1b2cbecb, - 0x2b2cbecb, - 0x3b2cbecb, - 0x0b6cbecb, - 0x1b6cbecb, - 0x2b6cbecb, - 0x3b6cbecb, - 0x0bacbecb, - 0x1bacbecb, - 0x2bacbecb, - 0x3bacbecb, - 0x0becbecb, - 0x1becbecb, - 0x2becbecb, - 0x3becbecb, - 0x0b2dbecb, - 0x1b2dbecb, - 0x2b2dbecb, - 0x3b2dbecb, - 0x0b6dbecb, - 0x1b6dbecb, - 0x2b6dbecb, - 0x3b6dbecb, - 0x0badbecb, - 0x1badbecb, - 0x2badbecb, - 0x3badbecb, - 0x0bedbecb, - 0x1bedbecb, - 0x2bedbecb, - 0x3bedbecb, - 0x0b2ebecb, - 0x1b2ebecb, - 0x2b2ebecb, - 0x3b2ebecb, - 0x0b6ebecb, - 0x1b6ebecb, - 0x2b6ebecb, - 0x3b6ebecb, - 0x0baebecb, - 0x1baebecb, - 0x2baebecb, - 0x3baebecb, - 0x0beebecb, - 0x1beebecb, - 0x2beebecb, - 0x3beebecb, - 0x0b2fbecb, - 0x1b2fbecb, - 0x2b2fbecb, - 0x3b2fbecb, - 0x0b6fbecb, - 0x1b6fbecb, - 0x2b6fbecb, - 0x3b6fbecb, - 0x0bafbecb, - 0x1bafbecb, - 0x2bafbecb, - 0x3bafbecb, - 0x0befbecb, - 0x1befbecb, - 0x2befbecb, - 0x3befbecb, - 0x0b2cb2db, - 0x1b2cb2db, - 0x2b2cb2db, - 0x3b2cb2db, - 0x0b6cb2db, - 0x1b6cb2db, - 0x2b6cb2db, - 0x3b6cb2db, - 0x0bacb2db, - 0x1bacb2db, - 0x2bacb2db, - 0x3bacb2db, - 0x0becb2db, - 0x1becb2db, - 0x2becb2db, - 0x3becb2db, - 0x0b2db2db, - 0x1b2db2db, - 0x2b2db2db, - 0x3b2db2db, - 0x0b6db2db, - 0x1b6db2db, - 0x2b6db2db, - 0x3b6db2db, - 0x0badb2db, - 0x1badb2db, - 0x2badb2db, - 0x3badb2db, - 0x0bedb2db, - 0x1bedb2db, - 0x2bedb2db, - 0x3bedb2db, - 0x0b2eb2db, - 0x1b2eb2db, - 0x2b2eb2db, - 0x3b2eb2db, - 0x0b6eb2db, - 0x1b6eb2db, - 0x2b6eb2db, - 0x3b6eb2db, - 0x0baeb2db, - 0x1baeb2db, - 0x2baeb2db, - 0x3baeb2db, - 0x0beeb2db, - 0x1beeb2db, - 0x2beeb2db, - 0x3beeb2db, - 0x0b2fb2db, - 0x1b2fb2db, - 0x2b2fb2db, - 0x3b2fb2db, - 0x0b6fb2db, - 0x1b6fb2db, - 0x2b6fb2db, - 0x3b6fb2db, - 0x0bafb2db, - 0x1bafb2db, - 0x2bafb2db, - 0x3bafb2db, - 0x0befb2db, - 0x1befb2db, - 0x2befb2db, - 0x3befb2db, - 0x0b2cb6db, - 0x1b2cb6db, - 0x2b2cb6db, - 0x3b2cb6db, - 0x0b6cb6db, - 0x1b6cb6db, - 0x2b6cb6db, - 0x3b6cb6db, - 0x0bacb6db, - 0x1bacb6db, - 0x2bacb6db, - 0x3bacb6db, - 0x0becb6db, - 0x1becb6db, - 0x2becb6db, - 0x3becb6db, - 0x0b2db6db, - 0x1b2db6db, - 0x2b2db6db, - 0x3b2db6db, - 0x0b6db6db, - 0x1b6db6db, - 0x2b6db6db, - 0x3b6db6db, - 0x0badb6db, - 0x1badb6db, - 0x2badb6db, - 0x3badb6db, - 0x0bedb6db, - 0x1bedb6db, - 0x2bedb6db, - 0x3bedb6db, - 0x0b2eb6db, - 0x1b2eb6db, - 0x2b2eb6db, - 0x3b2eb6db, - 0x0b6eb6db, - 0x1b6eb6db, - 0x2b6eb6db, - 0x3b6eb6db, - 0x0baeb6db, - 0x1baeb6db, - 0x2baeb6db, - 0x3baeb6db, -} - -var kNonZeroRepsDepth = [numCommandSymbols]uint32{ - 6, - 6, - 6, - 6, - 12, - 12, - 12, - 12, - 12, - 12, - 12, - 12, - 12, - 12, - 12, - 12, - 12, - 12, - 12, - 12, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 18, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 24, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, - 30, -} - -var kStaticCommandCodeBits = [numCommandSymbols]uint16{ - 0, - 256, - 128, - 384, - 64, - 320, - 192, - 448, - 32, - 288, - 160, - 416, - 96, - 352, - 224, - 480, - 16, - 272, - 144, - 400, - 80, - 336, - 208, - 464, - 48, - 304, - 176, - 432, - 112, - 368, - 240, - 496, - 8, - 264, - 136, - 392, - 72, - 328, - 200, - 456, - 40, - 296, - 168, - 424, - 104, - 360, - 232, - 488, - 24, - 280, - 152, - 408, - 88, - 344, - 216, - 472, - 56, - 312, - 184, - 440, - 120, - 376, - 248, - 504, - 4, - 260, - 132, - 388, - 68, - 324, - 196, - 452, - 36, - 292, - 164, - 420, - 100, - 356, - 228, - 484, - 20, - 276, - 148, - 404, - 84, - 340, - 212, - 468, - 52, - 308, - 180, - 436, - 116, - 372, - 244, - 500, - 12, - 268, - 140, - 396, - 76, - 332, - 204, - 460, - 44, - 300, - 172, - 428, - 108, - 364, - 236, - 492, - 28, - 284, - 156, - 412, - 92, - 348, - 220, - 476, - 60, - 316, - 188, - 444, - 124, - 380, - 252, - 508, - 2, - 258, - 130, - 386, - 66, - 322, - 194, - 450, - 34, - 290, - 162, - 418, - 98, - 354, - 226, - 482, - 18, - 274, - 146, - 402, - 82, - 338, - 210, - 466, - 50, - 306, - 178, - 434, - 114, - 370, - 242, - 498, - 10, - 266, - 138, - 394, - 74, - 330, - 202, - 458, - 42, - 298, - 170, - 426, - 106, - 362, - 234, - 490, - 26, - 282, - 154, - 410, - 90, - 346, - 218, - 474, - 58, - 314, - 186, - 442, - 122, - 378, - 250, - 506, - 6, - 262, - 134, - 390, - 70, - 326, - 198, - 454, - 38, - 294, - 166, - 422, - 102, - 358, - 230, - 486, - 22, - 278, - 150, - 406, - 86, - 342, - 214, - 470, - 54, - 310, - 182, - 438, - 118, - 374, - 246, - 502, - 14, - 270, - 142, - 398, - 78, - 334, - 206, - 462, - 46, - 302, - 174, - 430, - 110, - 366, - 238, - 494, - 30, - 286, - 158, - 414, - 94, - 350, - 222, - 478, - 62, - 318, - 190, - 446, - 126, - 382, - 254, - 510, - 1, - 257, - 129, - 385, - 65, - 321, - 193, - 449, - 33, - 289, - 161, - 417, - 97, - 353, - 225, - 481, - 17, - 273, - 145, - 401, - 81, - 337, - 209, - 465, - 49, - 305, - 177, - 433, - 113, - 369, - 241, - 497, - 9, - 265, - 137, - 393, - 73, - 329, - 201, - 457, - 41, - 297, - 169, - 425, - 105, - 361, - 233, - 489, - 25, - 281, - 153, - 409, - 89, - 345, - 217, - 473, - 57, - 313, - 185, - 441, - 121, - 377, - 249, - 505, - 5, - 261, - 133, - 389, - 69, - 325, - 197, - 453, - 37, - 293, - 165, - 421, - 101, - 357, - 229, - 485, - 21, - 277, - 149, - 405, - 85, - 341, - 213, - 469, - 53, - 309, - 181, - 437, - 117, - 373, - 245, - 501, - 13, - 269, - 141, - 397, - 77, - 333, - 205, - 461, - 45, - 301, - 173, - 429, - 109, - 365, - 237, - 493, - 29, - 285, - 157, - 413, - 93, - 349, - 221, - 477, - 61, - 317, - 189, - 445, - 125, - 381, - 253, - 509, - 3, - 259, - 131, - 387, - 67, - 323, - 195, - 451, - 35, - 291, - 163, - 419, - 99, - 355, - 227, - 483, - 19, - 275, - 147, - 403, - 83, - 339, - 211, - 467, - 51, - 307, - 179, - 435, - 115, - 371, - 243, - 499, - 11, - 267, - 139, - 395, - 75, - 331, - 203, - 459, - 43, - 299, - 171, - 427, - 107, - 363, - 235, - 491, - 27, - 283, - 155, - 411, - 91, - 347, - 219, - 475, - 59, - 315, - 187, - 443, - 123, - 379, - 251, - 507, - 7, - 1031, - 519, - 1543, - 263, - 1287, - 775, - 1799, - 135, - 1159, - 647, - 1671, - 391, - 1415, - 903, - 1927, - 71, - 1095, - 583, - 1607, - 327, - 1351, - 839, - 1863, - 199, - 1223, - 711, - 1735, - 455, - 1479, - 967, - 1991, - 39, - 1063, - 551, - 1575, - 295, - 1319, - 807, - 1831, - 167, - 1191, - 679, - 1703, - 423, - 1447, - 935, - 1959, - 103, - 1127, - 615, - 1639, - 359, - 1383, - 871, - 1895, - 231, - 1255, - 743, - 1767, - 487, - 1511, - 999, - 2023, - 23, - 1047, - 535, - 1559, - 279, - 1303, - 791, - 1815, - 151, - 1175, - 663, - 1687, - 407, - 1431, - 919, - 1943, - 87, - 1111, - 599, - 1623, - 343, - 1367, - 855, - 1879, - 215, - 1239, - 727, - 1751, - 471, - 1495, - 983, - 2007, - 55, - 1079, - 567, - 1591, - 311, - 1335, - 823, - 1847, - 183, - 1207, - 695, - 1719, - 439, - 1463, - 951, - 1975, - 119, - 1143, - 631, - 1655, - 375, - 1399, - 887, - 1911, - 247, - 1271, - 759, - 1783, - 503, - 1527, - 1015, - 2039, - 15, - 1039, - 527, - 1551, - 271, - 1295, - 783, - 1807, - 143, - 1167, - 655, - 1679, - 399, - 1423, - 911, - 1935, - 79, - 1103, - 591, - 1615, - 335, - 1359, - 847, - 1871, - 207, - 1231, - 719, - 1743, - 463, - 1487, - 975, - 1999, - 47, - 1071, - 559, - 1583, - 303, - 1327, - 815, - 1839, - 175, - 1199, - 687, - 1711, - 431, - 1455, - 943, - 1967, - 111, - 1135, - 623, - 1647, - 367, - 1391, - 879, - 1903, - 239, - 1263, - 751, - 1775, - 495, - 1519, - 1007, - 2031, - 31, - 1055, - 543, - 1567, - 287, - 1311, - 799, - 1823, - 159, - 1183, - 671, - 1695, - 415, - 1439, - 927, - 1951, - 95, - 1119, - 607, - 1631, - 351, - 1375, - 863, - 1887, - 223, - 1247, - 735, - 1759, - 479, - 1503, - 991, - 2015, - 63, - 1087, - 575, - 1599, - 319, - 1343, - 831, - 1855, - 191, - 1215, - 703, - 1727, - 447, - 1471, - 959, - 1983, - 127, - 1151, - 639, - 1663, - 383, - 1407, - 895, - 1919, - 255, - 1279, - 767, - 1791, - 511, - 1535, - 1023, - 2047, -} - -func storeStaticCommandHuffmanTree(storage_ix *uint, storage []byte) { - writeBits(56, 0x92624416307003, storage_ix, storage) - writeBits(3, 0x00000000, storage_ix, storage) -} - -var kStaticDistanceCodeBits = [64]uint16{ - 0, - 32, - 16, - 48, - 8, - 40, - 24, - 56, - 4, - 36, - 20, - 52, - 12, - 44, - 28, - 60, - 2, - 34, - 18, - 50, - 10, - 42, - 26, - 58, - 6, - 38, - 22, - 54, - 14, - 46, - 30, - 62, - 1, - 33, - 17, - 49, - 9, - 41, - 25, - 57, - 5, - 37, - 21, - 53, - 13, - 45, - 29, - 61, - 3, - 35, - 19, - 51, - 11, - 43, - 27, - 59, - 7, - 39, - 23, - 55, - 15, - 47, - 31, - 63, -} - -func storeStaticDistanceHuffmanTree(storage_ix *uint, storage []byte) { - writeBits(28, 0x0369DC03, storage_ix, storage) -} diff --git a/src/vendor/github.com/andybalholm/brotli/fast_log.go b/src/vendor/github.com/andybalholm/brotli/fast_log.go deleted file mode 100644 index 9d6607f7..00000000 --- a/src/vendor/github.com/andybalholm/brotli/fast_log.go +++ /dev/null @@ -1,290 +0,0 @@ -package brotli - -import ( - "math" - "math/bits" -) - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Utilities for fast computation of logarithms. */ - -func log2FloorNonZero(n uint) uint32 { - return uint32(bits.Len(n)) - 1 -} - -/* A lookup table for small values of log2(int) to be used in entropy - computation. - - ", ".join(["%.16ff" % x for x in [0.0]+[log2(x) for x in range(1, 256)]]) */ -var kLog2Table = []float32{ - 0.0000000000000000, - 0.0000000000000000, - 1.0000000000000000, - 1.5849625007211563, - 2.0000000000000000, - 2.3219280948873622, - 2.5849625007211561, - 2.8073549220576042, - 3.0000000000000000, - 3.1699250014423126, - 3.3219280948873626, - 3.4594316186372978, - 3.5849625007211565, - 3.7004397181410922, - 3.8073549220576037, - 3.9068905956085187, - 4.0000000000000000, - 4.0874628412503400, - 4.1699250014423122, - 4.2479275134435852, - 4.3219280948873626, - 4.3923174227787607, - 4.4594316186372973, - 4.5235619560570131, - 4.5849625007211570, - 4.6438561897747244, - 4.7004397181410926, - 4.7548875021634691, - 4.8073549220576037, - 4.8579809951275728, - 4.9068905956085187, - 4.9541963103868758, - 5.0000000000000000, - 5.0443941193584534, - 5.0874628412503400, - 5.1292830169449664, - 5.1699250014423122, - 5.2094533656289501, - 5.2479275134435852, - 5.2854022188622487, - 5.3219280948873626, - 5.3575520046180838, - 5.3923174227787607, - 5.4262647547020979, - 5.4594316186372973, - 5.4918530963296748, - 5.5235619560570131, - 5.5545888516776376, - 5.5849625007211570, - 5.6147098441152083, - 5.6438561897747244, - 5.6724253419714961, - 5.7004397181410926, - 5.7279204545631996, - 5.7548875021634691, - 5.7813597135246599, - 5.8073549220576046, - 5.8328900141647422, - 5.8579809951275719, - 5.8826430493618416, - 5.9068905956085187, - 5.9307373375628867, - 5.9541963103868758, - 5.9772799234999168, - 6.0000000000000000, - 6.0223678130284544, - 6.0443941193584534, - 6.0660891904577721, - 6.0874628412503400, - 6.1085244567781700, - 6.1292830169449672, - 6.1497471195046822, - 6.1699250014423122, - 6.1898245588800176, - 6.2094533656289510, - 6.2288186904958804, - 6.2479275134435861, - 6.2667865406949019, - 6.2854022188622487, - 6.3037807481771031, - 6.3219280948873617, - 6.3398500028846252, - 6.3575520046180847, - 6.3750394313469254, - 6.3923174227787598, - 6.4093909361377026, - 6.4262647547020979, - 6.4429434958487288, - 6.4594316186372982, - 6.4757334309663976, - 6.4918530963296748, - 6.5077946401986964, - 6.5235619560570131, - 6.5391588111080319, - 6.5545888516776376, - 6.5698556083309478, - 6.5849625007211561, - 6.5999128421871278, - 6.6147098441152092, - 6.6293566200796095, - 6.6438561897747253, - 6.6582114827517955, - 6.6724253419714952, - 6.6865005271832185, - 6.7004397181410917, - 6.7142455176661224, - 6.7279204545631988, - 6.7414669864011465, - 6.7548875021634691, - 6.7681843247769260, - 6.7813597135246599, - 6.7944158663501062, - 6.8073549220576037, - 6.8201789624151887, - 6.8328900141647422, - 6.8454900509443757, - 6.8579809951275719, - 6.8703647195834048, - 6.8826430493618416, - 6.8948177633079437, - 6.9068905956085187, - 6.9188632372745955, - 6.9307373375628867, - 6.9425145053392399, - 6.9541963103868758, - 6.9657842846620879, - 6.9772799234999168, - 6.9886846867721664, - 7.0000000000000000, - 7.0112272554232540, - 7.0223678130284544, - 7.0334230015374501, - 7.0443941193584534, - 7.0552824355011898, - 7.0660891904577721, - 7.0768155970508317, - 7.0874628412503400, - 7.0980320829605272, - 7.1085244567781700, - 7.1189410727235076, - 7.1292830169449664, - 7.1395513523987937, - 7.1497471195046822, - 7.1598713367783891, - 7.1699250014423130, - 7.1799090900149345, - 7.1898245588800176, - 7.1996723448363644, - 7.2094533656289492, - 7.2191685204621621, - 7.2288186904958804, - 7.2384047393250794, - 7.2479275134435861, - 7.2573878426926521, - 7.2667865406949019, - 7.2761244052742384, - 7.2854022188622487, - 7.2946207488916270, - 7.3037807481771031, - 7.3128829552843557, - 7.3219280948873617, - 7.3309168781146177, - 7.3398500028846243, - 7.3487281542310781, - 7.3575520046180847, - 7.3663222142458151, - 7.3750394313469254, - 7.3837042924740528, - 7.3923174227787607, - 7.4008794362821844, - 7.4093909361377026, - 7.4178525148858991, - 7.4262647547020979, - 7.4346282276367255, - 7.4429434958487288, - 7.4512111118323299, - 7.4594316186372973, - 7.4676055500829976, - 7.4757334309663976, - 7.4838157772642564, - 7.4918530963296748, - 7.4998458870832057, - 7.5077946401986964, - 7.5156998382840436, - 7.5235619560570131, - 7.5313814605163119, - 7.5391588111080319, - 7.5468944598876373, - 7.5545888516776376, - 7.5622424242210728, - 7.5698556083309478, - 7.5774288280357487, - 7.5849625007211561, - 7.5924570372680806, - 7.5999128421871278, - 7.6073303137496113, - 7.6147098441152075, - 7.6220518194563764, - 7.6293566200796095, - 7.6366246205436488, - 7.6438561897747244, - 7.6510516911789290, - 7.6582114827517955, - 7.6653359171851765, - 7.6724253419714952, - 7.6794800995054464, - 7.6865005271832185, - 7.6934869574993252, - 7.7004397181410926, - 7.7073591320808825, - 7.7142455176661224, - 7.7210991887071856, - 7.7279204545631996, - 7.7347096202258392, - 7.7414669864011465, - 7.7481928495894596, - 7.7548875021634691, - 7.7615512324444795, - 7.7681843247769260, - 7.7747870596011737, - 7.7813597135246608, - 7.7879025593914317, - 7.7944158663501062, - 7.8008998999203047, - 7.8073549220576037, - 7.8137811912170374, - 7.8201789624151887, - 7.8265484872909159, - 7.8328900141647422, - 7.8392037880969445, - 7.8454900509443757, - 7.8517490414160571, - 7.8579809951275719, - 7.8641861446542798, - 7.8703647195834048, - 7.8765169465650002, - 7.8826430493618425, - 7.8887432488982601, - 7.8948177633079446, - 7.9008668079807496, - 7.9068905956085187, - 7.9128893362299619, - 7.9188632372745955, - 7.9248125036057813, - 7.9307373375628867, - 7.9366379390025719, - 7.9425145053392399, - 7.9483672315846778, - 7.9541963103868758, - 7.9600019320680806, - 7.9657842846620870, - 7.9715435539507720, - 7.9772799234999168, - 7.9829935746943104, - 7.9886846867721664, - 7.9943534368588578, -} - -/* Faster logarithm for small integers, with the property of log2(0) == 0. */ -func fastLog2(v uint) float64 { - if v < uint(len(kLog2Table)) { - return float64(kLog2Table[v]) - } - - return math.Log2(float64(v)) -} diff --git a/src/vendor/github.com/andybalholm/brotli/find_match_length.go b/src/vendor/github.com/andybalholm/brotli/find_match_length.go deleted file mode 100644 index b46f88e8..00000000 --- a/src/vendor/github.com/andybalholm/brotli/find_match_length.go +++ /dev/null @@ -1,45 +0,0 @@ -package brotli - -import ( - "encoding/binary" - "math/bits" - "runtime" -) - -/* Copyright 2010 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Function to find maximal matching prefixes of strings. */ -func findMatchLengthWithLimit(s1 []byte, s2 []byte, limit uint) uint { - var matched uint = 0 - _, _ = s1[limit-1], s2[limit-1] // bounds check - switch runtime.GOARCH { - case "amd64", "arm64": - // Compare 8 bytes at at time. - for matched+8 <= limit { - w1 := binary.LittleEndian.Uint64(s1[matched:]) - w2 := binary.LittleEndian.Uint64(s2[matched:]) - if w1 != w2 { - return matched + uint(bits.TrailingZeros64(w1^w2)>>3) - } - matched += 8 - } - case "386": - // Compare 4 bytes at at time. - for matched+4 <= limit { - w1 := binary.LittleEndian.Uint32(s1[matched:]) - w2 := binary.LittleEndian.Uint32(s2[matched:]) - if w1 != w2 { - return matched + uint(bits.TrailingZeros32(w1^w2)>>3) - } - matched += 4 - } - } - for matched < limit && s1[matched] == s2[matched] { - matched++ - } - return matched -} diff --git a/src/vendor/github.com/andybalholm/brotli/flate/LICENSE b/src/vendor/github.com/andybalholm/brotli/flate/LICENSE deleted file mode 100644 index 6a66aea5..00000000 --- a/src/vendor/github.com/andybalholm/brotli/flate/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/src/vendor/github.com/andybalholm/brotli/flate/README.md b/src/vendor/github.com/andybalholm/brotli/flate/README.md deleted file mode 100644 index 0603ba1f..00000000 --- a/src/vendor/github.com/andybalholm/brotli/flate/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This package is a flate/gzip compressor that reuses the matchfinder package that I’ve been developing for brotli. -It is copied and adapted from the standard library compress/flate package. diff --git a/src/vendor/github.com/andybalholm/brotli/flate/gzip.go b/src/vendor/github.com/andybalholm/brotli/flate/gzip.go deleted file mode 100644 index 16c62871..00000000 --- a/src/vendor/github.com/andybalholm/brotli/flate/gzip.go +++ /dev/null @@ -1,65 +0,0 @@ -package flate - -import ( - "hash/crc32" - "time" - - "github.com/andybalholm/brotli/matchfinder" -) - -func NewGZIPEncoder() matchfinder.Encoder { - return &gzipEncoder{ - f: NewEncoder(), - } -} - -type gzipEncoder struct { - f matchfinder.Encoder - length uint32 - crc uint32 - wroteHeader bool -} - -func (g *gzipEncoder) Reset() { - g.f.Reset() - g.length = 0 - g.crc = 0 - g.wroteHeader = false -} - -func appendUint32(dst []byte, n uint32) []byte { - return append(dst, - byte(n), - byte(n>>8), - byte(n>>16), - byte(n>>24), - ) -} - -func (g *gzipEncoder) Encode(dst []byte, src []byte, matches []matchfinder.Match, lastBlock bool) []byte { - if !g.wroteHeader { - dst = append(dst, - 0x1f, 0x8b, // magic number - 8, // CM = flate - 0, // FLG - ) - dst = appendUint32(dst, uint32(time.Now().Unix())) - dst = append(dst, - 0, // XFL - 255, // OS (unspecified) - ) - g.wroteHeader = true - } - - dst = g.f.Encode(dst, src, matches, lastBlock) - - g.length += uint32(len(src)) - g.crc = crc32.Update(g.crc, crc32.IEEETable, src) - - if lastBlock { - dst = appendUint32(dst, g.crc) - dst = appendUint32(dst, g.length) - } - - return dst -} diff --git a/src/vendor/github.com/andybalholm/brotli/flate/huffman_bit_writer.go b/src/vendor/github.com/andybalholm/brotli/flate/huffman_bit_writer.go deleted file mode 100644 index c60dfd44..00000000 --- a/src/vendor/github.com/andybalholm/brotli/flate/huffman_bit_writer.go +++ /dev/null @@ -1,517 +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 flate - -import ( - "github.com/andybalholm/brotli/matchfinder" -) - -const ( - // The largest offset code. - offsetCodeCount = 30 - - // The special code used to mark the end of a block. - endBlockMarker = 256 - - // The first length code. - lengthCodesStart = 257 - - // The number of codegen codes. - codegenCodeCount = 19 - badCode = 255 - - maxNumLit = 286 - maxStoreBlockSize = 65535 - baseMatchLength = 3 // The smallest match length per the RFC section 3.2.5 - baseMatchOffset = 1 // The smallest match offset -) - -// The number of extra bits needed by length code X - LENGTH_CODES_START. -var lengthExtraBits = []int8{ - /* 257 */ 0, 0, 0, - /* 260 */ 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, - /* 270 */ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, - /* 280 */ 4, 5, 5, 5, 5, 0, -} - -// The length indicated by length code X - LENGTH_CODES_START. -var lengthBase = []int{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, - 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, - 64, 80, 96, 112, 128, 160, 192, 224, 255, -} - -// offset code word extra bits. -var offsetExtraBits = []int8{ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, -} - -var offsetBase = []int{ - 0x000000, 0x000001, 0x000002, 0x000003, 0x000004, - 0x000006, 0x000008, 0x00000c, 0x000010, 0x000018, - 0x000020, 0x000030, 0x000040, 0x000060, 0x000080, - 0x0000c0, 0x000100, 0x000180, 0x000200, 0x000300, - 0x000400, 0x000600, 0x000800, 0x000c00, 0x001000, - 0x001800, 0x002000, 0x003000, 0x004000, 0x006000, -} - -// The odd order in which the codegen code sizes are written. -var codegenOrder = []uint32{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15} - -type huffmanBitWriter struct { - dst []byte - - // Data waiting to be written is the low nbits of bits. - bits uint64 - nbits uint - codegenFreq [codegenCodeCount]int32 - literalFreq []int32 - offsetFreq []int32 - codegen []uint8 - literalEncoding *huffmanEncoder - offsetEncoding *huffmanEncoder - codegenEncoding *huffmanEncoder -} - -func NewEncoder() matchfinder.Encoder { - return &huffmanBitWriter{ - literalFreq: make([]int32, maxNumLit), - offsetFreq: make([]int32, offsetCodeCount), - codegen: make([]uint8, maxNumLit+offsetCodeCount+1), - literalEncoding: newHuffmanEncoder(maxNumLit), - codegenEncoding: newHuffmanEncoder(codegenCodeCount), - offsetEncoding: newHuffmanEncoder(offsetCodeCount), - } -} - -func (w *huffmanBitWriter) Reset() { - w.bits, w.nbits = 0, 0 -} - -func (w *huffmanBitWriter) flush() { - dst := w.dst - for w.nbits != 0 { - dst = append(dst, byte(w.bits)) - w.bits >>= 8 - if w.nbits > 8 { // Avoid underflow - w.nbits -= 8 - } else { - w.nbits = 0 - } - } - w.bits = 0 - w.dst = dst -} - -func (w *huffmanBitWriter) writeBits(b int32, nb uint) { - w.bits |= uint64(b) << w.nbits - w.nbits += nb - if w.nbits >= 48 { - bits := w.bits - w.bits >>= 48 - w.nbits -= 48 - w.dst = append(w.dst, - byte(bits), - byte(bits>>8), - byte(bits>>16), - byte(bits>>24), - byte(bits>>32), - byte(bits>>40), - ) - } -} - -func (w *huffmanBitWriter) writeBytes(bytes []byte) { - if w.nbits&7 != 0 { - panic("writeBytes with unfinished bits") - } - for w.nbits != 0 { - w.dst = append(w.dst, byte(w.bits)) - w.bits >>= 8 - w.nbits -= 8 - } - w.dst = append(w.dst, bytes...) -} - -// RFC 1951 3.2.7 specifies a special run-length encoding for specifying -// the literal and offset lengths arrays (which are concatenated into a single -// array). This method generates that run-length encoding. -// -// The result is written into the codegen array, and the frequencies -// of each code is written into the codegenFreq array. -// Codes 0-15 are single byte codes. Codes 16-18 are followed by additional -// information. Code badCode is an end marker -// -// numLiterals The number of literals in literalEncoding -// numOffsets The number of offsets in offsetEncoding -// litenc, offenc The literal and offset encoder to use -func (w *huffmanBitWriter) generateCodegen(numLiterals int, numOffsets int, litEnc, offEnc *huffmanEncoder) { - for i := range w.codegenFreq { - w.codegenFreq[i] = 0 - } - // Note that we are using codegen both as a temporary variable for holding - // a copy of the frequencies, and as the place where we put the result. - // This is fine because the output is always shorter than the input used - // so far. - codegen := w.codegen // cache - // Copy the concatenated code sizes to codegen. Put a marker at the end. - cgnl := codegen[:numLiterals] - for i := range cgnl { - cgnl[i] = uint8(litEnc.codes[i].len) - } - - cgnl = codegen[numLiterals : numLiterals+numOffsets] - for i := range cgnl { - cgnl[i] = uint8(offEnc.codes[i].len) - } - codegen[numLiterals+numOffsets] = badCode - - size := codegen[0] - count := 1 - outIndex := 0 - for inIndex := 1; size != badCode; inIndex++ { - // INVARIANT: We have seen "count" copies of size that have not yet - // had output generated for them. - nextSize := codegen[inIndex] - if nextSize == size { - count++ - continue - } - // We need to generate codegen indicating "count" of size. - if size != 0 { - codegen[outIndex] = size - outIndex++ - w.codegenFreq[size]++ - count-- - for count >= 3 { - n := 6 - if n > count { - n = count - } - codegen[outIndex] = 16 - outIndex++ - codegen[outIndex] = uint8(n - 3) - outIndex++ - w.codegenFreq[16]++ - count -= n - } - } else { - for count >= 11 { - n := 138 - if n > count { - n = count - } - codegen[outIndex] = 18 - outIndex++ - codegen[outIndex] = uint8(n - 11) - outIndex++ - w.codegenFreq[18]++ - count -= n - } - if count >= 3 { - // count >= 3 && count <= 10 - codegen[outIndex] = 17 - outIndex++ - codegen[outIndex] = uint8(count - 3) - outIndex++ - w.codegenFreq[17]++ - count = 0 - } - } - count-- - for ; count >= 0; count-- { - codegen[outIndex] = size - outIndex++ - w.codegenFreq[size]++ - } - // Set up invariant for next time through the loop. - size = nextSize - count = 1 - } - // Marker indicating the end of the codegen. - codegen[outIndex] = badCode -} - -// dynamicSize returns the size of dynamically encoded data in bits. -func (w *huffmanBitWriter) dynamicSize(litEnc, offEnc *huffmanEncoder, extraBits int) (size, numCodegens int) { - numCodegens = len(w.codegenFreq) - for numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 { - numCodegens-- - } - header := 3 + 5 + 5 + 4 + (3 * numCodegens) + - w.codegenEncoding.bitLength(w.codegenFreq[:]) + - int(w.codegenFreq[16])*2 + - int(w.codegenFreq[17])*3 + - int(w.codegenFreq[18])*7 - size = header + - litEnc.bitLength(w.literalFreq) + - offEnc.bitLength(w.offsetFreq) + - extraBits - - return size, numCodegens -} - -// fixedSize returns the size of dynamically encoded data in bits. -func (w *huffmanBitWriter) fixedSize(extraBits int) int { - return 3 + - fixedLiteralEncoding.bitLength(w.literalFreq) + - fixedOffsetEncoding.bitLength(w.offsetFreq) + - extraBits -} - -// storedSize calculates the stored size, including header. -// The function returns the size in bits and whether the block -// fits inside a single block. -func (w *huffmanBitWriter) storedSize(in []byte) (int, bool) { - if in == nil { - return 0, false - } - if len(in) <= maxStoreBlockSize { - return (len(in) + 5) * 8, true - } - return 0, false -} - -func (w *huffmanBitWriter) writeCode(c hcode) { - w.bits |= uint64(c.code) << w.nbits - w.nbits += uint(c.len) - if w.nbits >= 48 { - bits := w.bits - w.bits >>= 48 - w.nbits -= 48 - w.dst = append(w.dst, - byte(bits), - byte(bits>>8), - byte(bits>>16), - byte(bits>>24), - byte(bits>>32), - byte(bits>>40), - ) - } -} - -// Write the header of a dynamic Huffman block to the output stream. -// -// numLiterals The number of literals specified in codegen -// numOffsets The number of offsets specified in codegen -// numCodegens The number of codegens used in codegen -func (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffsets int, numCodegens int, isEof bool) { - var firstBits int32 = 4 - if isEof { - firstBits = 5 - } - w.writeBits(firstBits, 3) - w.writeBits(int32(numLiterals-257), 5) - w.writeBits(int32(numOffsets-1), 5) - w.writeBits(int32(numCodegens-4), 4) - - for i := 0; i < numCodegens; i++ { - value := uint(w.codegenEncoding.codes[codegenOrder[i]].len) - w.writeBits(int32(value), 3) - } - - i := 0 - for { - var codeWord int = int(w.codegen[i]) - i++ - if codeWord == badCode { - break - } - w.writeCode(w.codegenEncoding.codes[uint32(codeWord)]) - - switch codeWord { - case 16: - w.writeBits(int32(w.codegen[i]), 2) - i++ - case 17: - w.writeBits(int32(w.codegen[i]), 3) - i++ - case 18: - w.writeBits(int32(w.codegen[i]), 7) - i++ - } - } -} - -func (w *huffmanBitWriter) writeStoredHeader(length int, isEof bool) { - var flag int32 - if isEof { - flag = 1 - } - w.writeBits(flag, 3) - w.flush() - w.writeBits(int32(length), 16) - w.writeBits(int32(^uint16(length)), 16) -} - -func (w *huffmanBitWriter) writeFixedHeader(isEof bool) { - // Indicate that we are a fixed Huffman block - var value int32 = 2 - if isEof { - value = 3 - } - w.writeBits(value, 3) -} - -// writeBlock will write a block of tokens with the smallest encoding. -func (w *huffmanBitWriter) writeBlock(matches []matchfinder.Match, eof bool, input []byte) { - numLiterals, numOffsets := w.makeStatistics(matches, input) - - var extraBits int - storedSize, storable := w.storedSize(input) - if storable { - // We only bother calculating the costs of the extra bits required by - // the length of offset fields (which will be the same for both fixed - // and dynamic encoding), if we need to compare those two encodings - // against stored encoding. - for lengthCode := lengthCodesStart + 8; lengthCode < numLiterals; lengthCode++ { - // First eight length codes have extra size = 0. - extraBits += int(w.literalFreq[lengthCode]) * int(lengthExtraBits[lengthCode-lengthCodesStart]) - } - for offsetCode := 4; offsetCode < numOffsets; offsetCode++ { - // First four offset codes have extra size = 0. - extraBits += int(w.offsetFreq[offsetCode]) * int(offsetExtraBits[offsetCode]) - } - } - - // Figure out smallest code. - // Fixed Huffman baseline. - var literalEncoding = fixedLiteralEncoding - var offsetEncoding = fixedOffsetEncoding - var size = w.fixedSize(extraBits) - - // Dynamic Huffman? - var numCodegens int - - // Generate codegen and codegenFrequencies, which indicates how to encode - // the literalEncoding and the offsetEncoding. - w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding) - w.codegenEncoding.generate(w.codegenFreq[:], 7) - dynamicSize, numCodegens := w.dynamicSize(w.literalEncoding, w.offsetEncoding, extraBits) - - if dynamicSize < size { - size = dynamicSize - literalEncoding = w.literalEncoding - offsetEncoding = w.offsetEncoding - } - - // Stored bytes? - if storable && storedSize < size { - w.writeStoredHeader(len(input), eof) - w.writeBytes(input) - return - } - - // Huffman. - if literalEncoding == fixedLiteralEncoding { - w.writeFixedHeader(eof) - } else { - w.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof) - } - - // Write the tokens. - w.writeTokens(matches, input, literalEncoding.codes, offsetEncoding.codes) - w.writeCode(literalEncoding.codes[endBlockMarker]) -} - -// makeStatistics indexes a slice of tokens, and updates -// literalFreq and offsetFreq, and generates literalEncoding -// and offsetEncoding. -// The number of literal and offset tokens is returned. -func (w *huffmanBitWriter) makeStatistics(matches []matchfinder.Match, input []byte) (numLiterals, numOffsets int) { - for i := range w.literalFreq { - w.literalFreq[i] = 0 - } - for i := range w.offsetFreq { - w.offsetFreq[i] = 0 - } - - pos := 0 - for _, m := range matches { - for _, c := range input[pos : pos+m.Unmatched] { - w.literalFreq[c]++ - } - pos += m.Unmatched - - if m.Length == 0 { - continue - } - w.literalFreq[lengthCodesStart+lengthCode(m.Length)]++ - w.offsetFreq[offsetCode(m.Distance)]++ - pos += m.Length - } - w.literalFreq[endBlockMarker]++ - - // get the number of literals - numLiterals = len(w.literalFreq) - for w.literalFreq[numLiterals-1] == 0 { - numLiterals-- - } - // get the number of offsets - numOffsets = len(w.offsetFreq) - for numOffsets > 0 && w.offsetFreq[numOffsets-1] == 0 { - numOffsets-- - } - if numOffsets == 0 { - // We haven't found a single match. If we want to go with the dynamic encoding, - // we should count at least one offset to be sure that the offset huffman tree could be encoded. - w.offsetFreq[0] = 1 - numOffsets = 1 - } - w.literalEncoding.generate(w.literalFreq, 15) - w.offsetEncoding.generate(w.offsetFreq, 15) - return -} - -// writeTokens writes a slice of tokens to the output. -// codes for literal and offset encoding must be supplied. -func (w *huffmanBitWriter) writeTokens(matches []matchfinder.Match, input []byte, leCodes, oeCodes []hcode) { - pos := 0 - for _, m := range matches { - for _, c := range input[pos : pos+m.Unmatched] { - w.writeCode(leCodes[c]) - } - pos += m.Unmatched - - // Write the length - length := m.Length - if length == 0 { - continue - } - lengthCode := lengthCode(length) - w.writeCode(leCodes[lengthCode+lengthCodesStart]) - extraLengthBits := uint(lengthExtraBits[lengthCode]) - if extraLengthBits > 0 { - extraLength := int32(length - baseMatchLength - lengthBase[lengthCode]) - w.writeBits(extraLength, extraLengthBits) - } - - // Write the offset - offset := m.Distance - offsetCode := offsetCode(offset) - w.writeCode(oeCodes[offsetCode]) - extraOffsetBits := uint(offsetExtraBits[offsetCode]) - if extraOffsetBits > 0 { - extraOffset := int32(offset - baseMatchOffset - offsetBase[offsetCode]) - w.writeBits(extraOffset, extraOffsetBits) - } - pos += m.Length - } -} - -func (w *huffmanBitWriter) Encode(dst []byte, src []byte, matches []matchfinder.Match, lastBlock bool) []byte { - w.dst = dst - - w.writeBlock(matches, lastBlock, src) - if lastBlock { - w.flush() - } - - dst = w.dst - w.dst = nil - return dst -} diff --git a/src/vendor/github.com/andybalholm/brotli/flate/huffman_code.go b/src/vendor/github.com/andybalholm/brotli/flate/huffman_code.go deleted file mode 100644 index 1d73f47d..00000000 --- a/src/vendor/github.com/andybalholm/brotli/flate/huffman_code.go +++ /dev/null @@ -1,346 +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 flate - -import ( - "math" - "math/bits" - "sort" -) - -// hcode is a huffman code with a bit code and bit length. -type hcode struct { - code, len uint16 -} - -type huffmanEncoder struct { - codes []hcode - freqcache []literalNode - bitCount [17]int32 - lns byLiteral // stored to avoid repeated allocation in generate - lfs byFreq // stored to avoid repeated allocation in generate -} - -type literalNode struct { - literal uint16 - freq int32 -} - -// A levelInfo describes the state of the constructed tree for a given depth. -type levelInfo struct { - // Our level. for better printing - level int32 - - // The frequency of the last node at this level - lastFreq int32 - - // The frequency of the next character to add to this level - nextCharFreq int32 - - // The frequency of the next pair (from level below) to add to this level. - // Only valid if the "needed" value of the next lower level is 0. - nextPairFreq int32 - - // The number of chains remaining to generate for this level before moving - // up to the next level - needed int32 -} - -// set sets the code and length of an hcode. -func (h *hcode) set(code uint16, length uint16) { - h.len = length - h.code = code -} - -func maxNode() literalNode { return literalNode{math.MaxUint16, math.MaxInt32} } - -func newHuffmanEncoder(size int) *huffmanEncoder { - return &huffmanEncoder{codes: make([]hcode, size)} -} - -// Generates a HuffmanCode corresponding to the fixed literal table -func generateFixedLiteralEncoding() *huffmanEncoder { - h := newHuffmanEncoder(maxNumLit) - codes := h.codes - var ch uint16 - for ch = 0; ch < maxNumLit; ch++ { - var bits uint16 - var size uint16 - switch { - case ch < 144: - // size 8, 000110000 .. 10111111 - bits = ch + 48 - size = 8 - case ch < 256: - // size 9, 110010000 .. 111111111 - bits = ch + 400 - 144 - size = 9 - case ch < 280: - // size 7, 0000000 .. 0010111 - bits = ch - 256 - size = 7 - default: - // size 8, 11000000 .. 11000111 - bits = ch + 192 - 280 - size = 8 - } - codes[ch] = hcode{code: reverseBits(bits, byte(size)), len: size} - } - return h -} - -func generateFixedOffsetEncoding() *huffmanEncoder { - h := newHuffmanEncoder(30) - codes := h.codes - for ch := range codes { - codes[ch] = hcode{code: reverseBits(uint16(ch), 5), len: 5} - } - return h -} - -var fixedLiteralEncoding *huffmanEncoder = generateFixedLiteralEncoding() -var fixedOffsetEncoding *huffmanEncoder = generateFixedOffsetEncoding() - -func (h *huffmanEncoder) bitLength(freq []int32) int { - var total int - for i, f := range freq { - if f != 0 { - total += int(f) * int(h.codes[i].len) - } - } - return total -} - -const maxBitsLimit = 16 - -// Return the number of literals assigned to each bit size in the Huffman encoding -// -// This method is only called when list.length >= 3 -// The cases of 0, 1, and 2 literals are handled by special case code. -// -// list An array of the literals with non-zero frequencies -// and their associated frequencies. The array is in order of increasing -// frequency, and has as its last element a special element with frequency -// MaxInt32 -// maxBits The maximum number of bits that should be used to encode any literal. -// Must be less than 16. -// return An integer array in which array[i] indicates the number of literals -// that should be encoded in i bits. -func (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) []int32 { - if maxBits >= maxBitsLimit { - panic("flate: maxBits too large") - } - n := int32(len(list)) - list = list[0 : n+1] - list[n] = maxNode() - - // The tree can't have greater depth than n - 1, no matter what. This - // saves a little bit of work in some small cases - if maxBits > n-1 { - maxBits = n - 1 - } - - // Create information about each of the levels. - // A bogus "Level 0" whose sole purpose is so that - // level1.prev.needed==0. This makes level1.nextPairFreq - // be a legitimate value that never gets chosen. - var levels [maxBitsLimit]levelInfo - // leafCounts[i] counts the number of literals at the left - // of ancestors of the rightmost node at level i. - // leafCounts[i][j] is the number of literals at the left - // of the level j ancestor. - var leafCounts [maxBitsLimit][maxBitsLimit]int32 - - for level := int32(1); level <= maxBits; level++ { - // For every level, the first two items are the first two characters. - // We initialize the levels as if we had already figured this out. - levels[level] = levelInfo{ - level: level, - lastFreq: list[1].freq, - nextCharFreq: list[2].freq, - nextPairFreq: list[0].freq + list[1].freq, - } - leafCounts[level][level] = 2 - if level == 1 { - levels[level].nextPairFreq = math.MaxInt32 - } - } - - // We need a total of 2*n - 2 items at top level and have already generated 2. - levels[maxBits].needed = 2*n - 4 - - level := maxBits - for { - l := &levels[level] - if l.nextPairFreq == math.MaxInt32 && l.nextCharFreq == math.MaxInt32 { - // We've run out of both leafs and pairs. - // End all calculations for this level. - // To make sure we never come back to this level or any lower level, - // set nextPairFreq impossibly large. - l.needed = 0 - levels[level+1].nextPairFreq = math.MaxInt32 - level++ - continue - } - - prevFreq := l.lastFreq - if l.nextCharFreq < l.nextPairFreq { - // The next item on this row is a leaf node. - n := leafCounts[level][level] + 1 - l.lastFreq = l.nextCharFreq - // Lower leafCounts are the same of the previous node. - leafCounts[level][level] = n - l.nextCharFreq = list[n].freq - } else { - // The next item on this row is a pair from the previous row. - // nextPairFreq isn't valid until we generate two - // more values in the level below - l.lastFreq = l.nextPairFreq - // Take leaf counts from the lower level, except counts[level] remains the same. - copy(leafCounts[level][:level], leafCounts[level-1][:level]) - levels[l.level-1].needed = 2 - } - - if l.needed--; l.needed == 0 { - // We've done everything we need to do for this level. - // Continue calculating one level up. Fill in nextPairFreq - // of that level with the sum of the two nodes we've just calculated on - // this level. - if l.level == maxBits { - // All done! - break - } - levels[l.level+1].nextPairFreq = prevFreq + l.lastFreq - level++ - } else { - // If we stole from below, move down temporarily to replenish it. - for levels[level-1].needed > 0 { - level-- - } - } - } - - // Somethings is wrong if at the end, the top level is null or hasn't used - // all of the leaves. - if leafCounts[maxBits][maxBits] != n { - panic("leafCounts[maxBits][maxBits] != n") - } - - bitCount := h.bitCount[:maxBits+1] - bits := 1 - counts := &leafCounts[maxBits] - for level := maxBits; level > 0; level-- { - // chain.leafCount gives the number of literals requiring at least "bits" - // bits to encode. - bitCount[bits] = counts[level] - counts[level-1] - bits++ - } - return bitCount -} - -// Look at the leaves and assign them a bit count and an encoding as specified -// in RFC 1951 3.2.2 -func (h *huffmanEncoder) assignEncodingAndSize(bitCount []int32, list []literalNode) { - code := uint16(0) - for n, bits := range bitCount { - code <<= 1 - if n == 0 || bits == 0 { - continue - } - // The literals list[len(list)-bits] .. list[len(list)-bits] - // are encoded using "bits" bits, and get the values - // code, code + 1, .... The code values are - // assigned in literal order (not frequency order). - chunk := list[len(list)-int(bits):] - - h.lns.sort(chunk) - for _, node := range chunk { - h.codes[node.literal] = hcode{code: reverseBits(code, uint8(n)), len: uint16(n)} - code++ - } - list = list[0 : len(list)-int(bits)] - } -} - -// Update this Huffman Code object to be the minimum code for the specified frequency count. -// -// freq An array of frequencies, in which frequency[i] gives the frequency of literal i. -// maxBits The maximum number of bits to use for any literal. -func (h *huffmanEncoder) generate(freq []int32, maxBits int32) { - if h.freqcache == nil { - // Allocate a reusable buffer with the longest possible frequency table. - // Possible lengths are codegenCodeCount, offsetCodeCount and maxNumLit. - // The largest of these is maxNumLit, so we allocate for that case. - h.freqcache = make([]literalNode, maxNumLit+1) - } - list := h.freqcache[:len(freq)+1] - // Number of non-zero literals - count := 0 - // Set list to be the set of all non-zero literals and their frequencies - for i, f := range freq { - if f != 0 { - list[count] = literalNode{uint16(i), f} - count++ - } else { - list[count] = literalNode{} - h.codes[i].len = 0 - } - } - list[len(freq)] = literalNode{} - - list = list[:count] - if count <= 2 { - // Handle the small cases here, because they are awkward for the general case code. With - // two or fewer literals, everything has bit length 1. - for i, node := range list { - // "list" is in order of increasing literal value. - h.codes[node.literal].set(uint16(i), 1) - } - return - } - h.lfs.sort(list) - - // Get the number of literals for each bit count - bitCount := h.bitCounts(list, maxBits) - // And do the assignment - h.assignEncodingAndSize(bitCount, list) -} - -type byLiteral []literalNode - -func (s *byLiteral) sort(a []literalNode) { - *s = byLiteral(a) - sort.Sort(s) -} - -func (s byLiteral) Len() int { return len(s) } - -func (s byLiteral) Less(i, j int) bool { - return s[i].literal < s[j].literal -} - -func (s byLiteral) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -type byFreq []literalNode - -func (s *byFreq) sort(a []literalNode) { - *s = byFreq(a) - sort.Sort(s) -} - -func (s byFreq) Len() int { return len(s) } - -func (s byFreq) Less(i, j int) bool { - if s[i].freq == s[j].freq { - return s[i].literal < s[j].literal - } - return s[i].freq < s[j].freq -} - -func (s byFreq) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -func reverseBits(number uint16, bitLength byte) uint16 { - return bits.Reverse16(number << (16 - bitLength)) -} diff --git a/src/vendor/github.com/andybalholm/brotli/flate/token.go b/src/vendor/github.com/andybalholm/brotli/flate/token.go deleted file mode 100644 index 415b1b5e..00000000 --- a/src/vendor/github.com/andybalholm/brotli/flate/token.go +++ /dev/null @@ -1,80 +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 flate - -import "log" - -// The length code for length X (MIN_MATCH_LENGTH <= X <= MAX_MATCH_LENGTH) -// is lengthCodes[length - MIN_MATCH_LENGTH] -var lengthCodes = [...]uint32{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, - 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, - 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, - 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, - 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, - 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 28, -} - -var offsetCodes = [...]uint32{ - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -} - -func lengthCode(len int) uint32 { - if len > 258 { - panic("match too long") - } - return lengthCodes[len-baseMatchLength] -} - -// Returns the offset code corresponding to a specific offset -func offsetCode(off int) uint32 { - if off > 32768 { - log.Println(off) - panic("match distance too high") - } - off -= baseMatchOffset - if off < len(offsetCodes) { - return offsetCodes[off] - } - if off>>7 < len(offsetCodes) { - return offsetCodes[off>>7] + 14 - } - return offsetCodes[off>>14] + 28 -} diff --git a/src/vendor/github.com/andybalholm/brotli/flate/writer.go b/src/vendor/github.com/andybalholm/brotli/flate/writer.go deleted file mode 100644 index 1e49d489..00000000 --- a/src/vendor/github.com/andybalholm/brotli/flate/writer.go +++ /dev/null @@ -1,66 +0,0 @@ -package flate - -import ( - "io" - - "github.com/andybalholm/brotli/matchfinder" -) - -// NewWriter returns a new matchfinder.Writer that compresses data at the given level, -// in flate encoding. Levels 1–9 are available; levels outside this range will -// be replaced with the closest level available. -func NewWriter(w io.Writer, level int) *matchfinder.Writer { - return newWriter(w, level, NewEncoder()) -} - -// NewGZIPWriter returns a new matchfinder.Writer that compresses data at the given -// level, in gzip encoding. Levels 1–9 are available; levels outside this range -// will be replaced by the closest level available. -func NewGZIPWriter(w io.Writer, level int) *matchfinder.Writer { - return newWriter(w, level, NewGZIPEncoder()) -} - -func newWriter(w io.Writer, level int, e matchfinder.Encoder) *matchfinder.Writer { - var mf matchfinder.MatchFinder - if level < 2 { - mf = &matchfinder.ZFast{MaxDistance: 1 << 15} - } else if level == 2 { - mf = &matchfinder.ZDFast{MaxDistance: 1 << 15} - } else if level == 3 { - mf = &matchfinder.ZM{MaxDistance: 1 << 15} - } else if level == 4 { - mf = &matchfinder.Trio{MaxDistance: 1 << 15} - } else if level < 8 { - chainLen := 32 - switch level { - case 5: - chainLen = 8 - case 6: - chainLen = 16 - } - mf = &matchfinder.M4{ - MaxDistance: 1 << 15, - ChainLength: chainLen, - HashLen: 5, - DistanceBitCost: 66, - } - } else { - chainLen := 32 - hashLen := 5 - if level == 8 { - chainLen = 4 - } - mf = &matchfinder.Pathfinder{ - MaxDistance: 1 << 15, - ChainLength: chainLen, - HashLen: hashLen, - } - } - - return &matchfinder.Writer{ - Dest: w, - MatchFinder: mf, - Encoder: e, - BlockSize: 1 << 16, - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/h10.go b/src/vendor/github.com/andybalholm/brotli/h10.go deleted file mode 100644 index 5662fbbb..00000000 --- a/src/vendor/github.com/andybalholm/brotli/h10.go +++ /dev/null @@ -1,287 +0,0 @@ -package brotli - -import "encoding/binary" - -/* Copyright 2016 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -func (*h10) HashTypeLength() uint { - return 4 -} - -func (*h10) StoreLookahead() uint { - return 128 -} - -func hashBytesH10(data []byte) uint32 { - var h uint32 = binary.LittleEndian.Uint32(data) * kHashMul32 - - /* The higher bits contain more mixture from the multiplication, - so we take our results from there. */ - return h >> (32 - 17) -} - -/* A (forgetful) hash table where each hash bucket contains a binary tree of - sequences whose first 4 bytes share the same hash code. - Each sequence is 128 long and is identified by its starting - position in the input data. The binary tree is sorted by the lexicographic - order of the sequences, and it is also a max-heap with respect to the - starting positions. */ -type h10 struct { - hasherCommon - window_mask_ uint - buckets_ [1 << 17]uint32 - invalid_pos_ uint32 - forest []uint32 -} - -func (h *h10) Initialize(params *encoderParams) { - h.window_mask_ = (1 << params.lgwin) - 1 - h.invalid_pos_ = uint32(0 - h.window_mask_) - var num_nodes uint = uint(1) << params.lgwin - h.forest = make([]uint32, 2*num_nodes) -} - -func (h *h10) Prepare(one_shot bool, input_size uint, data []byte) { - var invalid_pos uint32 = h.invalid_pos_ - var i uint32 - for i = 0; i < 1<<17; i++ { - h.buckets_[i] = invalid_pos - } -} - -func leftChildIndexH10(self *h10, pos uint) uint { - return 2 * (pos & self.window_mask_) -} - -func rightChildIndexH10(self *h10, pos uint) uint { - return 2*(pos&self.window_mask_) + 1 -} - -/* Stores the hash of the next 4 bytes and in a single tree-traversal, the - hash bucket's binary tree is searched for matches and is re-rooted at the - current position. - - If less than 128 data is available, the hash bucket of the - current position is searched for matches, but the state of the hash table - is not changed, since we can not know the final sorting order of the - current (incomplete) sequence. - - This function must be called with increasing cur_ix positions. */ -func storeAndFindMatchesH10(self *h10, data []byte, cur_ix uint, ring_buffer_mask uint, max_length uint, max_backward uint, best_len *uint, matches []backwardMatch) []backwardMatch { - var cur_ix_masked uint = cur_ix & ring_buffer_mask - var max_comp_len uint = brotli_min_size_t(max_length, 128) - var should_reroot_tree bool = (max_length >= 128) - var key uint32 = hashBytesH10(data[cur_ix_masked:]) - var forest []uint32 = self.forest - var prev_ix uint = uint(self.buckets_[key]) - var node_left uint = leftChildIndexH10(self, cur_ix) - var node_right uint = rightChildIndexH10(self, cur_ix) - var best_len_left uint = 0 - var best_len_right uint = 0 - var depth_remaining uint - /* The forest index of the rightmost node of the left subtree of the new - root, updated as we traverse and re-root the tree of the hash bucket. */ - - /* The forest index of the leftmost node of the right subtree of the new - root, updated as we traverse and re-root the tree of the hash bucket. */ - - /* The match length of the rightmost node of the left subtree of the new - root, updated as we traverse and re-root the tree of the hash bucket. */ - - /* The match length of the leftmost node of the right subtree of the new - root, updated as we traverse and re-root the tree of the hash bucket. */ - if should_reroot_tree { - self.buckets_[key] = uint32(cur_ix) - } - - for depth_remaining = 64; ; depth_remaining-- { - var backward uint = cur_ix - prev_ix - var prev_ix_masked uint = prev_ix & ring_buffer_mask - if backward == 0 || backward > max_backward || depth_remaining == 0 { - if should_reroot_tree { - forest[node_left] = self.invalid_pos_ - forest[node_right] = self.invalid_pos_ - } - - break - } - { - var cur_len uint = brotli_min_size_t(best_len_left, best_len_right) - var len uint - assert(cur_len <= 128) - len = cur_len + findMatchLengthWithLimit(data[cur_ix_masked+cur_len:], data[prev_ix_masked+cur_len:], max_length-cur_len) - if matches != nil && len > *best_len { - *best_len = uint(len) - initBackwardMatch(&matches[0], backward, uint(len)) - matches = matches[1:] - } - - if len >= max_comp_len { - if should_reroot_tree { - forest[node_left] = forest[leftChildIndexH10(self, prev_ix)] - forest[node_right] = forest[rightChildIndexH10(self, prev_ix)] - } - - break - } - - if data[cur_ix_masked+len] > data[prev_ix_masked+len] { - best_len_left = uint(len) - if should_reroot_tree { - forest[node_left] = uint32(prev_ix) - } - - node_left = rightChildIndexH10(self, prev_ix) - prev_ix = uint(forest[node_left]) - } else { - best_len_right = uint(len) - if should_reroot_tree { - forest[node_right] = uint32(prev_ix) - } - - node_right = leftChildIndexH10(self, prev_ix) - prev_ix = uint(forest[node_right]) - } - } - } - - return matches -} - -/* Finds all backward matches of &data[cur_ix & ring_buffer_mask] up to the - length of max_length and stores the position cur_ix in the hash table. - - Sets *num_matches to the number of matches found, and stores the found - matches in matches[0] to matches[*num_matches - 1]. The matches will be - sorted by strictly increasing length and (non-strictly) increasing - distance. */ -func findAllMatchesH10(handle *h10, dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, cur_ix uint, max_length uint, max_backward uint, gap uint, params *encoderParams, matches []backwardMatch) uint { - var orig_matches []backwardMatch = matches - var cur_ix_masked uint = cur_ix & ring_buffer_mask - var best_len uint = 1 - var short_match_max_backward uint - if params.quality != hqZopflificationQuality { - short_match_max_backward = 16 - } else { - short_match_max_backward = 64 - } - var stop uint = cur_ix - short_match_max_backward - var dict_matches [maxStaticDictionaryMatchLen + 1]uint32 - var i uint - if cur_ix < short_match_max_backward { - stop = 0 - } - for i = cur_ix - 1; i > stop && best_len <= 2; i-- { - var prev_ix uint = i - var backward uint = cur_ix - prev_ix - if backward > max_backward { - break - } - - prev_ix &= ring_buffer_mask - if data[cur_ix_masked] != data[prev_ix] || data[cur_ix_masked+1] != data[prev_ix+1] { - continue - } - { - var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) - if len > best_len { - best_len = uint(len) - initBackwardMatch(&matches[0], backward, uint(len)) - matches = matches[1:] - } - } - } - - if best_len < max_length { - matches = storeAndFindMatchesH10(handle, data, cur_ix, ring_buffer_mask, max_length, max_backward, &best_len, matches) - } - - for i = 0; i <= maxStaticDictionaryMatchLen; i++ { - dict_matches[i] = kInvalidMatch - } - { - var minlen uint = brotli_max_size_t(4, best_len+1) - if findAllStaticDictionaryMatches(dictionary, data[cur_ix_masked:], minlen, max_length, dict_matches[0:]) { - var maxlen uint = brotli_min_size_t(maxStaticDictionaryMatchLen, max_length) - var l uint - for l = minlen; l <= maxlen; l++ { - var dict_id uint32 = dict_matches[l] - if dict_id < kInvalidMatch { - var distance uint = max_backward + gap + uint(dict_id>>5) + 1 - if distance <= params.dist.max_distance { - initDictionaryBackwardMatch(&matches[0], distance, l, uint(dict_id&31)) - matches = matches[1:] - } - } - } - } - } - - return uint(-cap(matches) + cap(orig_matches)) -} - -/* Stores the hash of the next 4 bytes and re-roots the binary tree at the - current sequence, without returning any matches. - REQUIRES: ix + 128 <= end-of-current-block */ -func (h *h10) Store(data []byte, mask uint, ix uint) { - var max_backward uint = h.window_mask_ - windowGap + 1 - /* Maximum distance is window size - 16, see section 9.1. of the spec. */ - storeAndFindMatchesH10(h, data, ix, mask, 128, max_backward, nil, nil) -} - -func (h *h10) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) { - var i uint = ix_start - var j uint = ix_start - if ix_start+63 <= ix_end { - i = ix_end - 63 - } - - if ix_start+512 <= i { - for ; j < i; j += 8 { - h.Store(data, mask, j) - } - } - - for ; i < ix_end; i++ { - h.Store(data, mask, i) - } -} - -func (h *h10) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint) { - if num_bytes >= h.HashTypeLength()-1 && position >= 128 { - var i_start uint = position - 128 + 1 - var i_end uint = brotli_min_size_t(position, i_start+num_bytes) - /* Store the last `128 - 1` positions in the hasher. - These could not be calculated before, since they require knowledge - of both the previous and the current block. */ - - var i uint - for i = i_start; i < i_end; i++ { - /* Maximum distance is window size - 16, see section 9.1. of the spec. - Furthermore, we have to make sure that we don't look further back - from the start of the next block than the window size, otherwise we - could access already overwritten areas of the ring-buffer. */ - var max_backward uint = h.window_mask_ - brotli_max_size_t(windowGap-1, position-i) - - /* We know that i + 128 <= position + num_bytes, i.e. the - end of the current block and that we have at least - 128 tail in the ring-buffer. */ - storeAndFindMatchesH10(h, ringbuffer, i, ringbuffer_mask, 128, max_backward, nil, nil) - } - } -} - -/* MAX_NUM_MATCHES == 64 + MAX_TREE_SEARCH_DEPTH */ -const maxNumMatchesH10 = 128 - -func (*h10) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { - panic("unimplemented") -} - -func (*h10) PrepareDistanceCache(distance_cache []int) { - panic("unimplemented") -} diff --git a/src/vendor/github.com/andybalholm/brotli/h5.go b/src/vendor/github.com/andybalholm/brotli/h5.go deleted file mode 100644 index f391b73f..00000000 --- a/src/vendor/github.com/andybalholm/brotli/h5.go +++ /dev/null @@ -1,214 +0,0 @@ -package brotli - -import "encoding/binary" - -/* Copyright 2010 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* A (forgetful) hash table to the data seen by the compressor, to - help create backward references to previous data. - - This is a hash map of fixed size (bucket_size_) to a ring buffer of - fixed size (block_size_). The ring buffer contains the last block_size_ - index positions of the given hash key in the compressed data. */ -func (*h5) HashTypeLength() uint { - return 4 -} - -func (*h5) StoreLookahead() uint { - return 4 -} - -/* HashBytes is the function that chooses the bucket to place the address in. */ -func hashBytesH5(data []byte, shift int) uint32 { - var h uint32 = binary.LittleEndian.Uint32(data) * kHashMul32 - - /* The higher bits contain more mixture from the multiplication, - so we take our results from there. */ - return uint32(h >> uint(shift)) -} - -type h5 struct { - hasherCommon - bucket_size_ uint - block_size_ uint - hash_shift_ int - block_mask_ uint32 - num []uint16 - buckets []uint32 -} - -func (h *h5) Initialize(params *encoderParams) { - h.hash_shift_ = 32 - h.params.bucket_bits - h.bucket_size_ = uint(1) << uint(h.params.bucket_bits) - h.block_size_ = uint(1) << uint(h.params.block_bits) - h.block_mask_ = uint32(h.block_size_ - 1) - h.num = make([]uint16, h.bucket_size_) - h.buckets = make([]uint32, h.block_size_*h.bucket_size_) -} - -func (h *h5) Prepare(one_shot bool, input_size uint, data []byte) { - var num []uint16 = h.num - var partial_prepare_threshold uint = h.bucket_size_ >> 6 - /* Partial preparation is 100 times slower (per socket). */ - if one_shot && input_size <= partial_prepare_threshold { - var i uint - for i = 0; i < input_size; i++ { - var key uint32 = hashBytesH5(data[i:], h.hash_shift_) - num[key] = 0 - } - } else { - for i := 0; i < int(h.bucket_size_); i++ { - num[i] = 0 - } - } -} - -/* Look at 4 bytes at &data[ix & mask]. - Compute a hash from these, and store the value of ix at that position. */ -func (h *h5) Store(data []byte, mask uint, ix uint) { - var num []uint16 = h.num - var key uint32 = hashBytesH5(data[ix&mask:], h.hash_shift_) - var minor_ix uint = uint(num[key]) & uint(h.block_mask_) - var offset uint = minor_ix + uint(key<= h.HashTypeLength()-1 && position >= 3 { - /* Prepare the hashes for three last bytes of the last write. - These could not be calculated before, since they require knowledge - of both the previous and the current block. */ - h.Store(ringbuffer, ringbuffer_mask, position-3) - h.Store(ringbuffer, ringbuffer_mask, position-2) - h.Store(ringbuffer, ringbuffer_mask, position-1) - } -} - -func (h *h5) PrepareDistanceCache(distance_cache []int) { - prepareDistanceCache(distance_cache, h.params.num_last_distances_to_check) -} - -/* Find a longest backward match of &data[cur_ix] up to the length of - max_length and stores the position cur_ix in the hash table. - - REQUIRES: PrepareDistanceCacheH5 must be invoked for current distance cache - values; if this method is invoked repeatedly with the same distance - cache values, it is enough to invoke PrepareDistanceCacheH5 once. - - Does not look for matches longer than max_length. - Does not look for matches further away than max_backward. - Writes the best match into |out|. - |out|->score is updated only if a better match is found. */ -func (h *h5) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { - var num []uint16 = h.num - var buckets []uint32 = h.buckets - var cur_ix_masked uint = cur_ix & ring_buffer_mask - var min_score uint = out.score - var best_score uint = out.score - var best_len uint = out.len - var i uint - var bucket []uint32 - /* Don't accept a short copy from far away. */ - out.len = 0 - - out.len_code_delta = 0 - - /* Try last distance first. */ - for i = 0; i < uint(h.params.num_last_distances_to_check); i++ { - var backward uint = uint(distance_cache[i]) - var prev_ix uint = uint(cur_ix - backward) - if prev_ix >= cur_ix { - continue - } - - if backward > max_backward { - continue - } - - prev_ix &= ring_buffer_mask - - if cur_ix_masked+best_len > ring_buffer_mask || prev_ix+best_len > ring_buffer_mask || data[cur_ix_masked+best_len] != data[prev_ix+best_len] { - continue - } - { - var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) - if len >= 3 || (len == 2 && i < 2) { - /* Comparing for >= 2 does not change the semantics, but just saves for - a few unnecessary binary logarithms in backward reference score, - since we are not interested in such short matches. */ - var score uint = backwardReferenceScoreUsingLastDistance(uint(len)) - if best_score < score { - if i != 0 { - score -= backwardReferencePenaltyUsingLastDistance(i) - } - if best_score < score { - best_score = score - best_len = uint(len) - out.len = best_len - out.distance = backward - out.score = best_score - } - } - } - } - } - { - var key uint32 = hashBytesH5(data[cur_ix_masked:], h.hash_shift_) - bucket = buckets[key< h.block_size_ { - down = uint(num[key]) - h.block_size_ - } else { - down = 0 - } - for i = uint(num[key]); i > down; { - var prev_ix uint - i-- - prev_ix = uint(bucket[uint32(i)&h.block_mask_]) - var backward uint = cur_ix - prev_ix - if backward > max_backward { - break - } - - prev_ix &= ring_buffer_mask - if cur_ix_masked+best_len > ring_buffer_mask || prev_ix+best_len > ring_buffer_mask || data[cur_ix_masked+best_len] != data[prev_ix+best_len] { - continue - } - { - var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) - if len >= 4 { - /* Comparing for >= 3 does not change the semantics, but just saves - for a few unnecessary binary logarithms in backward reference - score, since we are not interested in such short matches. */ - var score uint = backwardReferenceScore(uint(len), backward) - if best_score < score { - best_score = score - best_len = uint(len) - out.len = best_len - out.distance = backward - out.score = best_score - } - } - } - } - - bucket[uint32(num[key])&h.block_mask_] = uint32(cur_ix) - num[key]++ - } - - if min_score == out.score { - searchInStaticDictionary(dictionary, h, data[cur_ix_masked:], max_length, max_backward+gap, max_distance, out, false) - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/h6.go b/src/vendor/github.com/andybalholm/brotli/h6.go deleted file mode 100644 index 80bb224a..00000000 --- a/src/vendor/github.com/andybalholm/brotli/h6.go +++ /dev/null @@ -1,216 +0,0 @@ -package brotli - -import "encoding/binary" - -/* Copyright 2010 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* A (forgetful) hash table to the data seen by the compressor, to - help create backward references to previous data. - - This is a hash map of fixed size (bucket_size_) to a ring buffer of - fixed size (block_size_). The ring buffer contains the last block_size_ - index positions of the given hash key in the compressed data. */ -func (*h6) HashTypeLength() uint { - return 8 -} - -func (*h6) StoreLookahead() uint { - return 8 -} - -/* HashBytes is the function that chooses the bucket to place the address in. */ -func hashBytesH6(data []byte, mask uint64, shift int) uint32 { - var h uint64 = (binary.LittleEndian.Uint64(data) & mask) * kHashMul64Long - - /* The higher bits contain more mixture from the multiplication, - so we take our results from there. */ - return uint32(h >> uint(shift)) -} - -type h6 struct { - hasherCommon - bucket_size_ uint - block_size_ uint - hash_shift_ int - hash_mask_ uint64 - block_mask_ uint32 - num []uint16 - buckets []uint32 -} - -func (h *h6) Initialize(params *encoderParams) { - h.hash_shift_ = 64 - h.params.bucket_bits - h.hash_mask_ = (^(uint64(0))) >> uint(64-8*h.params.hash_len) - h.bucket_size_ = uint(1) << uint(h.params.bucket_bits) - h.block_size_ = uint(1) << uint(h.params.block_bits) - h.block_mask_ = uint32(h.block_size_ - 1) - h.num = make([]uint16, h.bucket_size_) - h.buckets = make([]uint32, h.block_size_*h.bucket_size_) -} - -func (h *h6) Prepare(one_shot bool, input_size uint, data []byte) { - var num []uint16 = h.num - var partial_prepare_threshold uint = h.bucket_size_ >> 6 - /* Partial preparation is 100 times slower (per socket). */ - if one_shot && input_size <= partial_prepare_threshold { - var i uint - for i = 0; i < input_size; i++ { - var key uint32 = hashBytesH6(data[i:], h.hash_mask_, h.hash_shift_) - num[key] = 0 - } - } else { - for i := 0; i < int(h.bucket_size_); i++ { - num[i] = 0 - } - } -} - -/* Look at 4 bytes at &data[ix & mask]. - Compute a hash from these, and store the value of ix at that position. */ -func (h *h6) Store(data []byte, mask uint, ix uint) { - var num []uint16 = h.num - var key uint32 = hashBytesH6(data[ix&mask:], h.hash_mask_, h.hash_shift_) - var minor_ix uint = uint(num[key]) & uint(h.block_mask_) - var offset uint = minor_ix + uint(key<= h.HashTypeLength()-1 && position >= 3 { - /* Prepare the hashes for three last bytes of the last write. - These could not be calculated before, since they require knowledge - of both the previous and the current block. */ - h.Store(ringbuffer, ringbuffer_mask, position-3) - h.Store(ringbuffer, ringbuffer_mask, position-2) - h.Store(ringbuffer, ringbuffer_mask, position-1) - } -} - -func (h *h6) PrepareDistanceCache(distance_cache []int) { - prepareDistanceCache(distance_cache, h.params.num_last_distances_to_check) -} - -/* Find a longest backward match of &data[cur_ix] up to the length of - max_length and stores the position cur_ix in the hash table. - - REQUIRES: PrepareDistanceCacheH6 must be invoked for current distance cache - values; if this method is invoked repeatedly with the same distance - cache values, it is enough to invoke PrepareDistanceCacheH6 once. - - Does not look for matches longer than max_length. - Does not look for matches further away than max_backward. - Writes the best match into |out|. - |out|->score is updated only if a better match is found. */ -func (h *h6) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { - var num []uint16 = h.num - var buckets []uint32 = h.buckets - var cur_ix_masked uint = cur_ix & ring_buffer_mask - var min_score uint = out.score - var best_score uint = out.score - var best_len uint = out.len - var i uint - var bucket []uint32 - /* Don't accept a short copy from far away. */ - out.len = 0 - - out.len_code_delta = 0 - - /* Try last distance first. */ - for i = 0; i < uint(h.params.num_last_distances_to_check); i++ { - var backward uint = uint(distance_cache[i]) - var prev_ix uint = uint(cur_ix - backward) - if prev_ix >= cur_ix { - continue - } - - if backward > max_backward { - continue - } - - prev_ix &= ring_buffer_mask - - if cur_ix_masked+best_len > ring_buffer_mask || prev_ix+best_len > ring_buffer_mask || data[cur_ix_masked+best_len] != data[prev_ix+best_len] { - continue - } - { - var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) - if len >= 3 || (len == 2 && i < 2) { - /* Comparing for >= 2 does not change the semantics, but just saves for - a few unnecessary binary logarithms in backward reference score, - since we are not interested in such short matches. */ - var score uint = backwardReferenceScoreUsingLastDistance(uint(len)) - if best_score < score { - if i != 0 { - score -= backwardReferencePenaltyUsingLastDistance(i) - } - if best_score < score { - best_score = score - best_len = uint(len) - out.len = best_len - out.distance = backward - out.score = best_score - } - } - } - } - } - { - var key uint32 = hashBytesH6(data[cur_ix_masked:], h.hash_mask_, h.hash_shift_) - bucket = buckets[key< h.block_size_ { - down = uint(num[key]) - h.block_size_ - } else { - down = 0 - } - for i = uint(num[key]); i > down; { - var prev_ix uint - i-- - prev_ix = uint(bucket[uint32(i)&h.block_mask_]) - var backward uint = cur_ix - prev_ix - if backward > max_backward { - break - } - - prev_ix &= ring_buffer_mask - if cur_ix_masked+best_len > ring_buffer_mask || prev_ix+best_len > ring_buffer_mask || data[cur_ix_masked+best_len] != data[prev_ix+best_len] { - continue - } - { - var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) - if len >= 4 { - /* Comparing for >= 3 does not change the semantics, but just saves - for a few unnecessary binary logarithms in backward reference - score, since we are not interested in such short matches. */ - var score uint = backwardReferenceScore(uint(len), backward) - if best_score < score { - best_score = score - best_len = uint(len) - out.len = best_len - out.distance = backward - out.score = best_score - } - } - } - } - - bucket[uint32(num[key])&h.block_mask_] = uint32(cur_ix) - num[key]++ - } - - if min_score == out.score { - searchInStaticDictionary(dictionary, h, data[cur_ix_masked:], max_length, max_backward+gap, max_distance, out, false) - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/hash.go b/src/vendor/github.com/andybalholm/brotli/hash.go deleted file mode 100644 index 00f812e8..00000000 --- a/src/vendor/github.com/andybalholm/brotli/hash.go +++ /dev/null @@ -1,342 +0,0 @@ -package brotli - -import ( - "encoding/binary" - "fmt" -) - -type hasherCommon struct { - params hasherParams - is_prepared_ bool - dict_num_lookups uint - dict_num_matches uint -} - -func (h *hasherCommon) Common() *hasherCommon { - return h -} - -type hasherHandle interface { - Common() *hasherCommon - Initialize(params *encoderParams) - Prepare(one_shot bool, input_size uint, data []byte) - StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint) - HashTypeLength() uint - StoreLookahead() uint - PrepareDistanceCache(distance_cache []int) - FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) - StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) - Store(data []byte, mask uint, ix uint) -} - -const kCutoffTransformsCount uint32 = 10 - -/* 0, 12, 27, 23, 42, 63, 56, 48, 59, 64 */ -/* 0+0, 4+8, 8+19, 12+11, 16+26, 20+43, 24+32, 28+20, 32+27, 36+28 */ -const kCutoffTransforms uint64 = 0x071B520ADA2D3200 - -type hasherSearchResult struct { - len uint - distance uint - score uint - len_code_delta int -} - -/* kHashMul32 multiplier has these properties: - * The multiplier must be odd. Otherwise we may lose the highest bit. - * No long streaks of ones or zeros. - * There is no effort to ensure that it is a prime, the oddity is enough - for this use. - * The number has been tuned heuristically against compression benchmarks. */ -const kHashMul32 uint32 = 0x1E35A7BD - -const kHashMul64 uint64 = 0x1E35A7BD1E35A7BD - -const kHashMul64Long uint64 = 0x1FE35A7BD3579BD3 - -func hash14(data []byte) uint32 { - var h uint32 = binary.LittleEndian.Uint32(data) * kHashMul32 - - /* The higher bits contain more mixture from the multiplication, - so we take our results from there. */ - return h >> (32 - 14) -} - -func prepareDistanceCache(distance_cache []int, num_distances int) { - if num_distances > 4 { - var last_distance int = distance_cache[0] - distance_cache[4] = last_distance - 1 - distance_cache[5] = last_distance + 1 - distance_cache[6] = last_distance - 2 - distance_cache[7] = last_distance + 2 - distance_cache[8] = last_distance - 3 - distance_cache[9] = last_distance + 3 - if num_distances > 10 { - var next_last_distance int = distance_cache[1] - distance_cache[10] = next_last_distance - 1 - distance_cache[11] = next_last_distance + 1 - distance_cache[12] = next_last_distance - 2 - distance_cache[13] = next_last_distance + 2 - distance_cache[14] = next_last_distance - 3 - distance_cache[15] = next_last_distance + 3 - } - } -} - -const literalByteScore = 135 - -const distanceBitPenalty = 30 - -/* Score must be positive after applying maximal penalty. */ -const scoreBase = (distanceBitPenalty * 8 * 8) - -/* Usually, we always choose the longest backward reference. This function - allows for the exception of that rule. - - If we choose a backward reference that is further away, it will - usually be coded with more bits. We approximate this by assuming - log2(distance). If the distance can be expressed in terms of the - last four distances, we use some heuristic constants to estimate - the bits cost. For the first up to four literals we use the bit - cost of the literals from the literal cost model, after that we - use the average bit cost of the cost model. - - This function is used to sometimes discard a longer backward reference - when it is not much longer and the bit cost for encoding it is more - than the saved literals. - - backward_reference_offset MUST be positive. */ -func backwardReferenceScore(copy_length uint, backward_reference_offset uint) uint { - return scoreBase + literalByteScore*uint(copy_length) - distanceBitPenalty*uint(log2FloorNonZero(backward_reference_offset)) -} - -func backwardReferenceScoreUsingLastDistance(copy_length uint) uint { - return literalByteScore*uint(copy_length) + scoreBase + 15 -} - -func backwardReferencePenaltyUsingLastDistance(distance_short_code uint) uint { - return uint(39) + ((0x1CA10 >> (distance_short_code & 0xE)) & 0xE) -} - -func testStaticDictionaryItem(dictionary *encoderDictionary, item uint, data []byte, max_length uint, max_backward uint, max_distance uint, out *hasherSearchResult) bool { - var len uint - var word_idx uint - var offset uint - var matchlen uint - var backward uint - var score uint - len = item & 0x1F - word_idx = item >> 5 - offset = uint(dictionary.words.offsets_by_length[len]) + len*word_idx - if len > max_length { - return false - } - - matchlen = findMatchLengthWithLimit(data, dictionary.words.data[offset:], uint(len)) - if matchlen+uint(dictionary.cutoffTransformsCount) <= len || matchlen == 0 { - return false - } - { - var cut uint = len - matchlen - var transform_id uint = (cut << 2) + uint((dictionary.cutoffTransforms>>(cut*6))&0x3F) - backward = max_backward + 1 + word_idx + (transform_id << dictionary.words.size_bits_by_length[len]) - } - - if backward > max_distance { - return false - } - - score = backwardReferenceScore(matchlen, backward) - if score < out.score { - return false - } - - out.len = matchlen - out.len_code_delta = int(len) - int(matchlen) - out.distance = backward - out.score = score - return true -} - -func searchInStaticDictionary(dictionary *encoderDictionary, handle hasherHandle, data []byte, max_length uint, max_backward uint, max_distance uint, out *hasherSearchResult, shallow bool) { - var key uint - var i uint - var self *hasherCommon = handle.Common() - if self.dict_num_matches < self.dict_num_lookups>>7 { - return - } - - key = uint(hash14(data) << 1) - for i = 0; ; (func() { i++; key++ })() { - var tmp uint - if shallow { - tmp = 1 - } else { - tmp = 2 - } - if i >= tmp { - break - } - var item uint = uint(dictionary.hash_table[key]) - self.dict_num_lookups++ - if item != 0 { - var item_matches bool = testStaticDictionaryItem(dictionary, item, data, max_length, max_backward, max_distance, out) - if item_matches { - self.dict_num_matches++ - } - } - } -} - -type backwardMatch struct { - distance uint32 - length_and_code uint32 -} - -func initBackwardMatch(self *backwardMatch, dist uint, len uint) { - self.distance = uint32(dist) - self.length_and_code = uint32(len << 5) -} - -func initDictionaryBackwardMatch(self *backwardMatch, dist uint, len uint, len_code uint) { - self.distance = uint32(dist) - var tmp uint - if len == len_code { - tmp = 0 - } else { - tmp = len_code - } - self.length_and_code = uint32(len<<5 | tmp) -} - -func backwardMatchLength(self *backwardMatch) uint { - return uint(self.length_and_code >> 5) -} - -func backwardMatchLengthCode(self *backwardMatch) uint { - var code uint = uint(self.length_and_code) & 31 - if code != 0 { - return code - } else { - return backwardMatchLength(self) - } -} - -func hasherReset(handle hasherHandle) { - if handle == nil { - return - } - handle.Common().is_prepared_ = false -} - -func newHasher(typ int) hasherHandle { - switch typ { - case 2: - return &hashLongestMatchQuickly{ - bucketBits: 16, - bucketSweep: 1, - hashLen: 5, - useDictionary: true, - } - case 3: - return &hashLongestMatchQuickly{ - bucketBits: 16, - bucketSweep: 2, - hashLen: 5, - useDictionary: false, - } - case 4: - return &hashLongestMatchQuickly{ - bucketBits: 17, - bucketSweep: 4, - hashLen: 5, - useDictionary: true, - } - case 5: - return new(h5) - case 6: - return new(h6) - case 10: - return new(h10) - case 35: - return &hashComposite{ - ha: newHasher(3), - hb: &hashRolling{jump: 4}, - } - case 40: - return &hashForgetfulChain{ - bucketBits: 15, - numBanks: 1, - bankBits: 16, - numLastDistancesToCheck: 4, - } - case 41: - return &hashForgetfulChain{ - bucketBits: 15, - numBanks: 1, - bankBits: 16, - numLastDistancesToCheck: 10, - } - case 42: - return &hashForgetfulChain{ - bucketBits: 15, - numBanks: 512, - bankBits: 9, - numLastDistancesToCheck: 16, - } - case 54: - return &hashLongestMatchQuickly{ - bucketBits: 20, - bucketSweep: 4, - hashLen: 7, - useDictionary: false, - } - case 55: - return &hashComposite{ - ha: newHasher(54), - hb: &hashRolling{jump: 4}, - } - case 65: - return &hashComposite{ - ha: newHasher(6), - hb: &hashRolling{jump: 1}, - } - } - - panic(fmt.Sprintf("unknown hasher type: %d", typ)) -} - -func hasherSetup(handle *hasherHandle, params *encoderParams, data []byte, position uint, input_size uint, is_last bool) { - var self hasherHandle = nil - var common *hasherCommon = nil - var one_shot bool = (position == 0 && is_last) - if *handle == nil { - chooseHasher(params, ¶ms.hasher) - self = newHasher(params.hasher.type_) - - *handle = self - common = self.Common() - common.params = params.hasher - self.Initialize(params) - } - - self = *handle - common = self.Common() - if !common.is_prepared_ { - self.Prepare(one_shot, input_size, data) - - if position == 0 { - common.dict_num_lookups = 0 - common.dict_num_matches = 0 - } - - common.is_prepared_ = true - } -} - -func initOrStitchToPreviousBlock(handle *hasherHandle, data []byte, mask uint, params *encoderParams, position uint, input_size uint, is_last bool) { - var self hasherHandle - hasherSetup(handle, params, data, position, input_size, is_last) - self = *handle - self.StitchToPreviousBlock(input_size, position, data, mask) -} diff --git a/src/vendor/github.com/andybalholm/brotli/hash_composite.go b/src/vendor/github.com/andybalholm/brotli/hash_composite.go deleted file mode 100644 index a65fe2e6..00000000 --- a/src/vendor/github.com/andybalholm/brotli/hash_composite.go +++ /dev/null @@ -1,93 +0,0 @@ -package brotli - -/* Copyright 2018 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -func (h *hashComposite) HashTypeLength() uint { - var a uint = h.ha.HashTypeLength() - var b uint = h.hb.HashTypeLength() - if a > b { - return a - } else { - return b - } -} - -func (h *hashComposite) StoreLookahead() uint { - var a uint = h.ha.StoreLookahead() - var b uint = h.hb.StoreLookahead() - if a > b { - return a - } else { - return b - } -} - -/* Composite hasher: This hasher allows to combine two other hashers, HASHER_A - and HASHER_B. */ -type hashComposite struct { - hasherCommon - ha hasherHandle - hb hasherHandle - params *encoderParams -} - -func (h *hashComposite) Initialize(params *encoderParams) { - h.params = params -} - -/* TODO: Initialize of the hashers is defered to Prepare (and params - remembered here) because we don't get the one_shot and input_size params - here that are needed to know the memory size of them. Instead provide - those params to all hashers InitializehashComposite */ -func (h *hashComposite) Prepare(one_shot bool, input_size uint, data []byte) { - if h.ha == nil { - var common_a *hasherCommon - var common_b *hasherCommon - - common_a = h.ha.Common() - common_a.params = h.params.hasher - common_a.is_prepared_ = false - common_a.dict_num_lookups = 0 - common_a.dict_num_matches = 0 - h.ha.Initialize(h.params) - - common_b = h.hb.Common() - common_b.params = h.params.hasher - common_b.is_prepared_ = false - common_b.dict_num_lookups = 0 - common_b.dict_num_matches = 0 - h.hb.Initialize(h.params) - } - - h.ha.Prepare(one_shot, input_size, data) - h.hb.Prepare(one_shot, input_size, data) -} - -func (h *hashComposite) Store(data []byte, mask uint, ix uint) { - h.ha.Store(data, mask, ix) - h.hb.Store(data, mask, ix) -} - -func (h *hashComposite) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) { - h.ha.StoreRange(data, mask, ix_start, ix_end) - h.hb.StoreRange(data, mask, ix_start, ix_end) -} - -func (h *hashComposite) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) { - h.ha.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask) - h.hb.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask) -} - -func (h *hashComposite) PrepareDistanceCache(distance_cache []int) { - h.ha.PrepareDistanceCache(distance_cache) - h.hb.PrepareDistanceCache(distance_cache) -} - -func (h *hashComposite) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { - h.ha.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out) - h.hb.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out) -} diff --git a/src/vendor/github.com/andybalholm/brotli/hash_forgetful_chain.go b/src/vendor/github.com/andybalholm/brotli/hash_forgetful_chain.go deleted file mode 100644 index 306e46d3..00000000 --- a/src/vendor/github.com/andybalholm/brotli/hash_forgetful_chain.go +++ /dev/null @@ -1,252 +0,0 @@ -package brotli - -import "encoding/binary" - -/* Copyright 2016 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -func (*hashForgetfulChain) HashTypeLength() uint { - return 4 -} - -func (*hashForgetfulChain) StoreLookahead() uint { - return 4 -} - -/* HashBytes is the function that chooses the bucket to place the address in.*/ -func (h *hashForgetfulChain) HashBytes(data []byte) uint { - var hash uint32 = binary.LittleEndian.Uint32(data) * kHashMul32 - - /* The higher bits contain more mixture from the multiplication, - so we take our results from there. */ - return uint(hash >> (32 - h.bucketBits)) -} - -type slot struct { - delta uint16 - next uint16 -} - -/* A (forgetful) hash table to the data seen by the compressor, to - help create backward references to previous data. - - Hashes are stored in chains which are bucketed to groups. Group of chains - share a storage "bank". When more than "bank size" chain nodes are added, - oldest nodes are replaced; this way several chains may share a tail. */ -type hashForgetfulChain struct { - hasherCommon - - bucketBits uint - numBanks uint - bankBits uint - numLastDistancesToCheck int - - addr []uint32 - head []uint16 - tiny_hash [65536]byte - banks [][]slot - free_slot_idx []uint16 - max_hops uint -} - -func (h *hashForgetfulChain) Initialize(params *encoderParams) { - var q uint - if params.quality > 6 { - q = 7 - } else { - q = 8 - } - h.max_hops = q << uint(params.quality-4) - - bankSize := 1 << h.bankBits - bucketSize := 1 << h.bucketBits - - h.addr = make([]uint32, bucketSize) - h.head = make([]uint16, bucketSize) - h.banks = make([][]slot, h.numBanks) - for i := range h.banks { - h.banks[i] = make([]slot, bankSize) - } - h.free_slot_idx = make([]uint16, h.numBanks) -} - -func (h *hashForgetfulChain) Prepare(one_shot bool, input_size uint, data []byte) { - var partial_prepare_threshold uint = (1 << h.bucketBits) >> 6 - /* Partial preparation is 100 times slower (per socket). */ - if one_shot && input_size <= partial_prepare_threshold { - var i uint - for i = 0; i < input_size; i++ { - var bucket uint = h.HashBytes(data[i:]) - - /* See InitEmpty comment. */ - h.addr[bucket] = 0xCCCCCCCC - - h.head[bucket] = 0xCCCC - } - } else { - /* Fill |addr| array with 0xCCCCCCCC value. Because of wrapping, position - processed by hasher never reaches 3GB + 64M; this makes all new chains - to be terminated after the first node. */ - for i := range h.addr { - h.addr[i] = 0xCCCCCCCC - } - - for i := range h.head { - h.head[i] = 0 - } - } - - h.tiny_hash = [65536]byte{} - for i := range h.free_slot_idx { - h.free_slot_idx[i] = 0 - } -} - -/* Look at 4 bytes at &data[ix & mask]. Compute a hash from these, and prepend - node to corresponding chain; also update tiny_hash for current position. */ -func (h *hashForgetfulChain) Store(data []byte, mask uint, ix uint) { - var key uint = h.HashBytes(data[ix&mask:]) - var bank uint = key & (h.numBanks - 1) - idx := uint(h.free_slot_idx[bank]) & ((1 << h.bankBits) - 1) - h.free_slot_idx[bank]++ - var delta uint = ix - uint(h.addr[key]) - h.tiny_hash[uint16(ix)] = byte(key) - if delta > 0xFFFF { - delta = 0xFFFF - } - h.banks[bank][idx].delta = uint16(delta) - h.banks[bank][idx].next = h.head[key] - h.addr[key] = uint32(ix) - h.head[key] = uint16(idx) -} - -func (h *hashForgetfulChain) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) { - var i uint - for i = ix_start; i < ix_end; i++ { - h.Store(data, mask, i) - } -} - -func (h *hashForgetfulChain) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) { - if num_bytes >= h.HashTypeLength()-1 && position >= 3 { - /* Prepare the hashes for three last bytes of the last write. - These could not be calculated before, since they require knowledge - of both the previous and the current block. */ - h.Store(ringbuffer, ring_buffer_mask, position-3) - h.Store(ringbuffer, ring_buffer_mask, position-2) - h.Store(ringbuffer, ring_buffer_mask, position-1) - } -} - -func (h *hashForgetfulChain) PrepareDistanceCache(distance_cache []int) { - prepareDistanceCache(distance_cache, h.numLastDistancesToCheck) -} - -/* Find a longest backward match of &data[cur_ix] up to the length of - max_length and stores the position cur_ix in the hash table. - - REQUIRES: PrepareDistanceCachehashForgetfulChain must be invoked for current distance cache - values; if this method is invoked repeatedly with the same distance - cache values, it is enough to invoke PrepareDistanceCachehashForgetfulChain once. - - Does not look for matches longer than max_length. - Does not look for matches further away than max_backward. - Writes the best match into |out|. - |out|->score is updated only if a better match is found. */ -func (h *hashForgetfulChain) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { - var cur_ix_masked uint = cur_ix & ring_buffer_mask - var min_score uint = out.score - var best_score uint = out.score - var best_len uint = out.len - var key uint = h.HashBytes(data[cur_ix_masked:]) - var tiny_hash byte = byte(key) - /* Don't accept a short copy from far away. */ - out.len = 0 - - out.len_code_delta = 0 - - /* Try last distance first. */ - for i := 0; i < h.numLastDistancesToCheck; i++ { - var backward uint = uint(distance_cache[i]) - var prev_ix uint = (cur_ix - backward) - - /* For distance code 0 we want to consider 2-byte matches. */ - if i > 0 && h.tiny_hash[uint16(prev_ix)] != tiny_hash { - continue - } - if prev_ix >= cur_ix || backward > max_backward { - continue - } - - prev_ix &= ring_buffer_mask - { - var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) - if len >= 2 { - var score uint = backwardReferenceScoreUsingLastDistance(uint(len)) - if best_score < score { - if i != 0 { - score -= backwardReferencePenaltyUsingLastDistance(uint(i)) - } - if best_score < score { - best_score = score - best_len = uint(len) - out.len = best_len - out.distance = backward - out.score = best_score - } - } - } - } - } - { - var bank uint = key & (h.numBanks - 1) - var backward uint = 0 - var hops uint = h.max_hops - var delta uint = cur_ix - uint(h.addr[key]) - var slot uint = uint(h.head[key]) - for { - tmp6 := hops - hops-- - if tmp6 == 0 { - break - } - var prev_ix uint - var last uint = slot - backward += delta - if backward > max_backward { - break - } - prev_ix = (cur_ix - backward) & ring_buffer_mask - slot = uint(h.banks[bank][last].next) - delta = uint(h.banks[bank][last].delta) - if cur_ix_masked+best_len > ring_buffer_mask || prev_ix+best_len > ring_buffer_mask || data[cur_ix_masked+best_len] != data[prev_ix+best_len] { - continue - } - { - var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) - if len >= 4 { - /* Comparing for >= 3 does not change the semantics, but just saves - for a few unnecessary binary logarithms in backward reference - score, since we are not interested in such short matches. */ - var score uint = backwardReferenceScore(uint(len), backward) - if best_score < score { - best_score = score - best_len = uint(len) - out.len = best_len - out.distance = backward - out.score = best_score - } - } - } - } - - h.Store(data, ring_buffer_mask, cur_ix) - } - - if out.score == min_score { - searchInStaticDictionary(dictionary, h, data[cur_ix_masked:], max_length, max_backward+gap, max_distance, out, false) - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/hash_longest_match_quickly.go b/src/vendor/github.com/andybalholm/brotli/hash_longest_match_quickly.go deleted file mode 100644 index 9375dc15..00000000 --- a/src/vendor/github.com/andybalholm/brotli/hash_longest_match_quickly.go +++ /dev/null @@ -1,214 +0,0 @@ -package brotli - -import "encoding/binary" - -/* Copyright 2010 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* For BUCKET_SWEEP == 1, enabling the dictionary lookup makes compression - a little faster (0.5% - 1%) and it compresses 0.15% better on small text - and HTML inputs. */ - -func (*hashLongestMatchQuickly) HashTypeLength() uint { - return 8 -} - -func (*hashLongestMatchQuickly) StoreLookahead() uint { - return 8 -} - -/* HashBytes is the function that chooses the bucket to place - the address in. The HashLongestMatch and hashLongestMatchQuickly - classes have separate, different implementations of hashing. */ -func (h *hashLongestMatchQuickly) HashBytes(data []byte) uint32 { - var hash uint64 = ((binary.LittleEndian.Uint64(data) << (64 - 8*h.hashLen)) * kHashMul64) - - /* The higher bits contain more mixture from the multiplication, - so we take our results from there. */ - return uint32(hash >> (64 - h.bucketBits)) -} - -/* A (forgetful) hash table to the data seen by the compressor, to - help create backward references to previous data. - - This is a hash map of fixed size (1 << 16). Starting from the - given index, 1 buckets are used to store values of a key. */ -type hashLongestMatchQuickly struct { - hasherCommon - - bucketBits uint - bucketSweep int - hashLen uint - useDictionary bool - - buckets []uint32 -} - -func (h *hashLongestMatchQuickly) Initialize(params *encoderParams) { - h.buckets = make([]uint32, 1<> 7 - /* Partial preparation is 100 times slower (per socket). */ - if one_shot && input_size <= partial_prepare_threshold { - var i uint - for i = 0; i < input_size; i++ { - var key uint32 = h.HashBytes(data[i:]) - for j := 0; j < h.bucketSweep; j++ { - h.buckets[key+uint32(j)] = 0 - } - } - } else { - /* It is not strictly necessary to fill this buffer here, but - not filling will make the results of the compression stochastic - (but correct). This is because random data would cause the - system to find accidentally good backward references here and there. */ - for i := range h.buckets { - h.buckets[i] = 0 - } - } -} - -/* Look at 5 bytes at &data[ix & mask]. - Compute a hash from these, and store the value somewhere within - [ix .. ix+3]. */ -func (h *hashLongestMatchQuickly) Store(data []byte, mask uint, ix uint) { - var key uint32 = h.HashBytes(data[ix&mask:]) - var off uint32 = uint32(ix>>3) % uint32(h.bucketSweep) - /* Wiggle the value with the bucket sweep range. */ - h.buckets[key+off] = uint32(ix) -} - -func (h *hashLongestMatchQuickly) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) { - var i uint - for i = ix_start; i < ix_end; i++ { - h.Store(data, mask, i) - } -} - -func (h *hashLongestMatchQuickly) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ringbuffer_mask uint) { - if num_bytes >= h.HashTypeLength()-1 && position >= 3 { - /* Prepare the hashes for three last bytes of the last write. - These could not be calculated before, since they require knowledge - of both the previous and the current block. */ - h.Store(ringbuffer, ringbuffer_mask, position-3) - h.Store(ringbuffer, ringbuffer_mask, position-2) - h.Store(ringbuffer, ringbuffer_mask, position-1) - } -} - -func (*hashLongestMatchQuickly) PrepareDistanceCache(distance_cache []int) { -} - -/* Find a longest backward match of &data[cur_ix & ring_buffer_mask] - up to the length of max_length and stores the position cur_ix in the - hash table. - - Does not look for matches longer than max_length. - Does not look for matches further away than max_backward. - Writes the best match into |out|. - |out|->score is updated only if a better match is found. */ -func (h *hashLongestMatchQuickly) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { - var best_len_in uint = out.len - var cur_ix_masked uint = cur_ix & ring_buffer_mask - var key uint32 = h.HashBytes(data[cur_ix_masked:]) - var compare_char int = int(data[cur_ix_masked+best_len_in]) - var min_score uint = out.score - var best_score uint = out.score - var best_len uint = best_len_in - var cached_backward uint = uint(distance_cache[0]) - var prev_ix uint = cur_ix - cached_backward - var bucket []uint32 - out.len_code_delta = 0 - if prev_ix < cur_ix { - prev_ix &= uint(uint32(ring_buffer_mask)) - if compare_char == int(data[prev_ix+best_len]) { - var len uint = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) - if len >= 4 { - var score uint = backwardReferenceScoreUsingLastDistance(uint(len)) - if best_score < score { - best_score = score - best_len = uint(len) - out.len = uint(len) - out.distance = cached_backward - out.score = best_score - compare_char = int(data[cur_ix_masked+best_len]) - if h.bucketSweep == 1 { - h.buckets[key] = uint32(cur_ix) - return - } - } - } - } - } - - if h.bucketSweep == 1 { - var backward uint - var len uint - - /* Only one to look for, don't bother to prepare for a loop. */ - prev_ix = uint(h.buckets[key]) - - h.buckets[key] = uint32(cur_ix) - backward = cur_ix - prev_ix - prev_ix &= uint(uint32(ring_buffer_mask)) - if compare_char != int(data[prev_ix+best_len_in]) { - return - } - - if backward == 0 || backward > max_backward { - return - } - - len = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) - if len >= 4 { - var score uint = backwardReferenceScore(uint(len), backward) - if best_score < score { - out.len = uint(len) - out.distance = backward - out.score = score - return - } - } - } else { - bucket = h.buckets[key:] - var i int - prev_ix = uint(bucket[0]) - bucket = bucket[1:] - for i = 0; i < h.bucketSweep; (func() { i++; tmp3 := bucket; bucket = bucket[1:]; prev_ix = uint(tmp3[0]) })() { - var backward uint = cur_ix - prev_ix - var len uint - prev_ix &= uint(uint32(ring_buffer_mask)) - if compare_char != int(data[prev_ix+best_len]) { - continue - } - - if backward == 0 || backward > max_backward { - continue - } - - len = findMatchLengthWithLimit(data[prev_ix:], data[cur_ix_masked:], max_length) - if len >= 4 { - var score uint = backwardReferenceScore(uint(len), backward) - if best_score < score { - best_score = score - best_len = uint(len) - out.len = best_len - out.distance = backward - out.score = score - compare_char = int(data[cur_ix_masked+best_len]) - } - } - } - } - - if h.useDictionary && min_score == out.score { - searchInStaticDictionary(dictionary, h, data[cur_ix_masked:], max_length, max_backward+gap, max_distance, out, true) - } - - h.buckets[key+uint32((cur_ix>>3)%uint(h.bucketSweep))] = uint32(cur_ix) -} diff --git a/src/vendor/github.com/andybalholm/brotli/hash_rolling.go b/src/vendor/github.com/andybalholm/brotli/hash_rolling.go deleted file mode 100644 index 6630fc07..00000000 --- a/src/vendor/github.com/andybalholm/brotli/hash_rolling.go +++ /dev/null @@ -1,168 +0,0 @@ -package brotli - -/* Copyright 2018 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* NOTE: this hasher does not search in the dictionary. It is used as - backup-hasher, the main hasher already searches in it. */ - -const kRollingHashMul32 uint32 = 69069 - -const kInvalidPosHashRolling uint32 = 0xffffffff - -/* This hasher uses a longer forward length, but returning a higher value here - will hurt compression by the main hasher when combined with a composite - hasher. The hasher tests for forward itself instead. */ -func (*hashRolling) HashTypeLength() uint { - return 4 -} - -func (*hashRolling) StoreLookahead() uint { - return 4 -} - -/* Computes a code from a single byte. A lookup table of 256 values could be - used, but simply adding 1 works about as good. */ -func (*hashRolling) HashByte(b byte) uint32 { - return uint32(b) + 1 -} - -func (h *hashRolling) HashRollingFunctionInitial(state uint32, add byte, factor uint32) uint32 { - return uint32(factor*state + h.HashByte(add)) -} - -func (h *hashRolling) HashRollingFunction(state uint32, add byte, rem byte, factor uint32, factor_remove uint32) uint32 { - return uint32(factor*state + h.HashByte(add) - factor_remove*h.HashByte(rem)) -} - -/* Rolling hash for long distance long string matches. Stores one position - per bucket, bucket key is computed over a long region. */ -type hashRolling struct { - hasherCommon - - jump int - - state uint32 - table []uint32 - next_ix uint - factor uint32 - factor_remove uint32 -} - -func (h *hashRolling) Initialize(params *encoderParams) { - h.state = 0 - h.next_ix = 0 - - h.factor = kRollingHashMul32 - - /* Compute the factor of the oldest byte to remove: factor**steps modulo - 0xffffffff (the multiplications rely on 32-bit overflow) */ - h.factor_remove = 1 - - for i := 0; i < 32; i += h.jump { - h.factor_remove *= h.factor - } - - h.table = make([]uint32, 16777216) - for i := 0; i < 16777216; i++ { - h.table[i] = kInvalidPosHashRolling - } -} - -func (h *hashRolling) Prepare(one_shot bool, input_size uint, data []byte) { - /* Too small size, cannot use this hasher. */ - if input_size < 32 { - return - } - h.state = 0 - for i := 0; i < 32; i += h.jump { - h.state = h.HashRollingFunctionInitial(h.state, data[i], h.factor) - } -} - -func (*hashRolling) Store(data []byte, mask uint, ix uint) { -} - -func (*hashRolling) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) { -} - -func (h *hashRolling) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) { - var position_masked uint - /* In this case we must re-initialize the hasher from scratch from the - current position. */ - - var available uint = num_bytes - if position&uint(h.jump-1) != 0 { - var diff uint = uint(h.jump) - (position & uint(h.jump-1)) - if diff > available { - available = 0 - } else { - available = available - diff - } - position += diff - } - - position_masked = position & ring_buffer_mask - - /* wrapping around ringbuffer not handled. */ - if available > ring_buffer_mask-position_masked { - available = ring_buffer_mask - position_masked - } - - h.Prepare(false, available, ringbuffer[position&ring_buffer_mask:]) - h.next_ix = position -} - -func (*hashRolling) PrepareDistanceCache(distance_cache []int) { -} - -func (h *hashRolling) FindLongestMatch(dictionary *encoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *hasherSearchResult) { - var cur_ix_masked uint = cur_ix & ring_buffer_mask - var pos uint = h.next_ix - - if cur_ix&uint(h.jump-1) != 0 { - return - } - - /* Not enough lookahead */ - if max_length < 32 { - return - } - - for pos = h.next_ix; pos <= cur_ix; pos += uint(h.jump) { - var code uint32 = h.state & ((16777216 * 64) - 1) - var rem byte = data[pos&ring_buffer_mask] - var add byte = data[(pos+32)&ring_buffer_mask] - var found_ix uint = uint(kInvalidPosHashRolling) - - h.state = h.HashRollingFunction(h.state, add, rem, h.factor, h.factor_remove) - - if code < 16777216 { - found_ix = uint(h.table[code]) - h.table[code] = uint32(pos) - if pos == cur_ix && uint32(found_ix) != kInvalidPosHashRolling { - /* The cast to 32-bit makes backward distances up to 4GB work even - if cur_ix is above 4GB, despite using 32-bit values in the table. */ - var backward uint = uint(uint32(cur_ix - found_ix)) - if backward <= max_backward { - var found_ix_masked uint = found_ix & ring_buffer_mask - var len uint = findMatchLengthWithLimit(data[found_ix_masked:], data[cur_ix_masked:], max_length) - if len >= 4 && len > out.len { - var score uint = backwardReferenceScore(uint(len), backward) - if score > out.score { - out.len = uint(len) - out.distance = backward - out.score = score - out.len_code_delta = 0 - } - } - } - } - } - } - - h.next_ix = cur_ix + uint(h.jump) -} diff --git a/src/vendor/github.com/andybalholm/brotli/histogram.go b/src/vendor/github.com/andybalholm/brotli/histogram.go deleted file mode 100644 index 0346622b..00000000 --- a/src/vendor/github.com/andybalholm/brotli/histogram.go +++ /dev/null @@ -1,226 +0,0 @@ -package brotli - -import "math" - -/* The distance symbols effectively used by "Large Window Brotli" (32-bit). */ -const numHistogramDistanceSymbols = 544 - -type histogramLiteral struct { - data_ [numLiteralSymbols]uint32 - total_count_ uint - bit_cost_ float64 -} - -func histogramClearLiteral(self *histogramLiteral) { - self.data_ = [numLiteralSymbols]uint32{} - self.total_count_ = 0 - self.bit_cost_ = math.MaxFloat64 -} - -func clearHistogramsLiteral(array []histogramLiteral, length uint) { - var i uint - for i = 0; i < length; i++ { - histogramClearLiteral(&array[i:][0]) - } -} - -func histogramAddLiteral(self *histogramLiteral, val uint) { - self.data_[val]++ - self.total_count_++ -} - -func histogramAddVectorLiteral(self *histogramLiteral, p []byte, n uint) { - self.total_count_ += n - n += 1 - for { - n-- - if n == 0 { - break - } - self.data_[p[0]]++ - p = p[1:] - } -} - -func histogramAddHistogramLiteral(self *histogramLiteral, v *histogramLiteral) { - var i uint - self.total_count_ += v.total_count_ - for i = 0; i < numLiteralSymbols; i++ { - self.data_[i] += v.data_[i] - } -} - -func histogramDataSizeLiteral() uint { - return numLiteralSymbols -} - -type histogramCommand struct { - data_ [numCommandSymbols]uint32 - total_count_ uint - bit_cost_ float64 -} - -func histogramClearCommand(self *histogramCommand) { - self.data_ = [numCommandSymbols]uint32{} - self.total_count_ = 0 - self.bit_cost_ = math.MaxFloat64 -} - -func clearHistogramsCommand(array []histogramCommand, length uint) { - var i uint - for i = 0; i < length; i++ { - histogramClearCommand(&array[i:][0]) - } -} - -func histogramAddCommand(self *histogramCommand, val uint) { - self.data_[val]++ - self.total_count_++ -} - -func histogramAddVectorCommand(self *histogramCommand, p []uint16, n uint) { - self.total_count_ += n - n += 1 - for { - n-- - if n == 0 { - break - } - self.data_[p[0]]++ - p = p[1:] - } -} - -func histogramAddHistogramCommand(self *histogramCommand, v *histogramCommand) { - var i uint - self.total_count_ += v.total_count_ - for i = 0; i < numCommandSymbols; i++ { - self.data_[i] += v.data_[i] - } -} - -func histogramDataSizeCommand() uint { - return numCommandSymbols -} - -type histogramDistance struct { - data_ [numDistanceSymbols]uint32 - total_count_ uint - bit_cost_ float64 -} - -func histogramClearDistance(self *histogramDistance) { - self.data_ = [numDistanceSymbols]uint32{} - self.total_count_ = 0 - self.bit_cost_ = math.MaxFloat64 -} - -func clearHistogramsDistance(array []histogramDistance, length uint) { - var i uint - for i = 0; i < length; i++ { - histogramClearDistance(&array[i:][0]) - } -} - -func histogramAddDistance(self *histogramDistance, val uint) { - self.data_[val]++ - self.total_count_++ -} - -func histogramAddVectorDistance(self *histogramDistance, p []uint16, n uint) { - self.total_count_ += n - n += 1 - for { - n-- - if n == 0 { - break - } - self.data_[p[0]]++ - p = p[1:] - } -} - -func histogramAddHistogramDistance(self *histogramDistance, v *histogramDistance) { - var i uint - self.total_count_ += v.total_count_ - for i = 0; i < numDistanceSymbols; i++ { - self.data_[i] += v.data_[i] - } -} - -func histogramDataSizeDistance() uint { - return numDistanceSymbols -} - -type blockSplitIterator struct { - split_ *blockSplit - idx_ uint - type_ uint - length_ uint -} - -func initBlockSplitIterator(self *blockSplitIterator, split *blockSplit) { - self.split_ = split - self.idx_ = 0 - self.type_ = 0 - if len(split.lengths) > 0 { - self.length_ = uint(split.lengths[0]) - } else { - self.length_ = 0 - } -} - -func blockSplitIteratorNext(self *blockSplitIterator) { - if self.length_ == 0 { - self.idx_++ - self.type_ = uint(self.split_.types[self.idx_]) - self.length_ = uint(self.split_.lengths[self.idx_]) - } - - self.length_-- -} - -func buildHistogramsWithContext(cmds []command, literal_split *blockSplit, insert_and_copy_split *blockSplit, dist_split *blockSplit, ringbuffer []byte, start_pos uint, mask uint, prev_byte byte, prev_byte2 byte, context_modes []int, literal_histograms []histogramLiteral, insert_and_copy_histograms []histogramCommand, copy_dist_histograms []histogramDistance) { - var pos uint = start_pos - var literal_it blockSplitIterator - var insert_and_copy_it blockSplitIterator - var dist_it blockSplitIterator - - initBlockSplitIterator(&literal_it, literal_split) - initBlockSplitIterator(&insert_and_copy_it, insert_and_copy_split) - initBlockSplitIterator(&dist_it, dist_split) - for i := range cmds { - var cmd *command = &cmds[i] - var j uint - blockSplitIteratorNext(&insert_and_copy_it) - histogramAddCommand(&insert_and_copy_histograms[insert_and_copy_it.type_], uint(cmd.cmd_prefix_)) - - /* TODO: unwrap iterator blocks. */ - for j = uint(cmd.insert_len_); j != 0; j-- { - var context uint - blockSplitIteratorNext(&literal_it) - context = literal_it.type_ - if context_modes != nil { - var lut contextLUT = getContextLUT(context_modes[context]) - context = (context << literalContextBits) + uint(getContext(prev_byte, prev_byte2, lut)) - } - - histogramAddLiteral(&literal_histograms[context], uint(ringbuffer[pos&mask])) - prev_byte2 = prev_byte - prev_byte = ringbuffer[pos&mask] - pos++ - } - - pos += uint(commandCopyLen(cmd)) - if commandCopyLen(cmd) != 0 { - prev_byte2 = ringbuffer[(pos-2)&mask] - prev_byte = ringbuffer[(pos-1)&mask] - if cmd.cmd_prefix_ >= 128 { - var context uint - blockSplitIteratorNext(&dist_it) - context = uint(uint32(dist_it.type_< bestQ && - (spec.Value == "*" || spec.Value == offer) { - bestQ = spec.Q - bestOffer = offer - } - } - } - if bestQ == 0 { - bestOffer = "" - } - return bestOffer -} - -// acceptSpec describes an Accept* header. -type acceptSpec struct { - Value string - Q float64 -} - -// parseAccept parses Accept* headers. -func parseAccept(header http.Header, key string) (specs []acceptSpec) { -loop: - for _, s := range header[key] { - for { - var spec acceptSpec - spec.Value, s = expectTokenSlash(s) - if spec.Value == "" { - continue loop - } - spec.Q = 1.0 - s = skipSpace(s) - if strings.HasPrefix(s, ";") { - s = skipSpace(s[1:]) - if !strings.HasPrefix(s, "q=") { - continue loop - } - spec.Q, s = expectQuality(s[2:]) - if spec.Q < 0.0 { - continue loop - } - } - specs = append(specs, spec) - s = skipSpace(s) - if !strings.HasPrefix(s, ",") { - continue loop - } - s = skipSpace(s[1:]) - } - } - return -} - -func skipSpace(s string) (rest string) { - i := 0 - for ; i < len(s); i++ { - if octetTypes[s[i]]&isSpace == 0 { - break - } - } - return s[i:] -} - -func expectTokenSlash(s string) (token, rest string) { - i := 0 - for ; i < len(s); i++ { - b := s[i] - if (octetTypes[b]&isToken == 0) && b != '/' { - break - } - } - return s[:i], s[i:] -} - -func expectQuality(s string) (q float64, rest string) { - switch { - case len(s) == 0: - return -1, "" - case s[0] == '0': - q = 0 - case s[0] == '1': - q = 1 - default: - return -1, "" - } - s = s[1:] - if !strings.HasPrefix(s, ".") { - return q, s - } - s = s[1:] - i := 0 - n := 0 - d := 1 - for ; i < len(s); i++ { - b := s[i] - if b < '0' || b > '9' { - break - } - n = n*10 + int(b) - '0' - d *= 10 - } - return q + float64(n)/float64(d), s[i:] -} - -// Octet types from RFC 2616. -var octetTypes [256]octetType - -type octetType byte - -const ( - isToken octetType = 1 << iota - isSpace -) - -func init() { - // OCTET = - // CHAR = - // CTL = - // CR = - // LF = - // SP = - // HT = - // <"> = - // CRLF = CR LF - // LWS = [CRLF] 1*( SP | HT ) - // TEXT = - // separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> - // | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT - // token = 1* - // qdtext = > - - for c := 0; c < 256; c++ { - var t octetType - isCtl := c <= 31 || c == 127 - isChar := 0 <= c && c <= 127 - isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) - if strings.ContainsRune(" \t\r\n", rune(c)) { - t |= isSpace - } - if isChar && !isCtl && !isSeparator { - t |= isToken - } - octetTypes[c] = t - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/huffman.go b/src/vendor/github.com/andybalholm/brotli/huffman.go deleted file mode 100644 index 182f3d2a..00000000 --- a/src/vendor/github.com/andybalholm/brotli/huffman.go +++ /dev/null @@ -1,653 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Utilities for building Huffman decoding tables. */ - -const huffmanMaxCodeLength = 15 - -/* Maximum possible Huffman table size for an alphabet size of (index * 32), - max code length 15 and root table bits 8. */ -var kMaxHuffmanTableSize = []uint16{ - 256, - 402, - 436, - 468, - 500, - 534, - 566, - 598, - 630, - 662, - 694, - 726, - 758, - 790, - 822, - 854, - 886, - 920, - 952, - 984, - 1016, - 1048, - 1080, - 1112, - 1144, - 1176, - 1208, - 1240, - 1272, - 1304, - 1336, - 1368, - 1400, - 1432, - 1464, - 1496, - 1528, -} - -/* BROTLI_NUM_BLOCK_LEN_SYMBOLS == 26 */ -const huffmanMaxSize26 = 396 - -/* BROTLI_MAX_BLOCK_TYPE_SYMBOLS == 258 */ -const huffmanMaxSize258 = 632 - -/* BROTLI_MAX_CONTEXT_MAP_SYMBOLS == 272 */ -const huffmanMaxSize272 = 646 - -const huffmanMaxCodeLengthCodeLength = 5 - -/* Do not create this struct directly - use the ConstructHuffmanCode - * constructor below! */ -type huffmanCode struct { - bits byte - value uint16 -} - -func constructHuffmanCode(bits byte, value uint16) huffmanCode { - var h huffmanCode - h.bits = bits - h.value = value - return h -} - -/* Builds Huffman lookup table assuming code lengths are in symbol order. */ - -/* Builds Huffman lookup table assuming code lengths are in symbol order. - Returns size of resulting table. */ - -/* Builds a simple Huffman table. The |num_symbols| parameter is to be - interpreted as follows: 0 means 1 symbol, 1 means 2 symbols, - 2 means 3 symbols, 3 means 4 symbols with lengths [2, 2, 2, 2], - 4 means 4 symbols with lengths [1, 2, 3, 3]. */ - -/* Contains a collection of Huffman trees with the same alphabet size. */ -/* max_symbol is needed due to simple codes since log2(alphabet_size) could be - greater than log2(max_symbol). */ -type huffmanTreeGroup struct { - htrees [][]huffmanCode - codes []huffmanCode - alphabet_size uint16 - max_symbol uint16 - num_htrees uint16 -} - -const reverseBitsMax = 8 - -const reverseBitsBase = 0 - -var kReverseBits = [1 << reverseBitsMax]byte{ - 0x00, - 0x80, - 0x40, - 0xC0, - 0x20, - 0xA0, - 0x60, - 0xE0, - 0x10, - 0x90, - 0x50, - 0xD0, - 0x30, - 0xB0, - 0x70, - 0xF0, - 0x08, - 0x88, - 0x48, - 0xC8, - 0x28, - 0xA8, - 0x68, - 0xE8, - 0x18, - 0x98, - 0x58, - 0xD8, - 0x38, - 0xB8, - 0x78, - 0xF8, - 0x04, - 0x84, - 0x44, - 0xC4, - 0x24, - 0xA4, - 0x64, - 0xE4, - 0x14, - 0x94, - 0x54, - 0xD4, - 0x34, - 0xB4, - 0x74, - 0xF4, - 0x0C, - 0x8C, - 0x4C, - 0xCC, - 0x2C, - 0xAC, - 0x6C, - 0xEC, - 0x1C, - 0x9C, - 0x5C, - 0xDC, - 0x3C, - 0xBC, - 0x7C, - 0xFC, - 0x02, - 0x82, - 0x42, - 0xC2, - 0x22, - 0xA2, - 0x62, - 0xE2, - 0x12, - 0x92, - 0x52, - 0xD2, - 0x32, - 0xB2, - 0x72, - 0xF2, - 0x0A, - 0x8A, - 0x4A, - 0xCA, - 0x2A, - 0xAA, - 0x6A, - 0xEA, - 0x1A, - 0x9A, - 0x5A, - 0xDA, - 0x3A, - 0xBA, - 0x7A, - 0xFA, - 0x06, - 0x86, - 0x46, - 0xC6, - 0x26, - 0xA6, - 0x66, - 0xE6, - 0x16, - 0x96, - 0x56, - 0xD6, - 0x36, - 0xB6, - 0x76, - 0xF6, - 0x0E, - 0x8E, - 0x4E, - 0xCE, - 0x2E, - 0xAE, - 0x6E, - 0xEE, - 0x1E, - 0x9E, - 0x5E, - 0xDE, - 0x3E, - 0xBE, - 0x7E, - 0xFE, - 0x01, - 0x81, - 0x41, - 0xC1, - 0x21, - 0xA1, - 0x61, - 0xE1, - 0x11, - 0x91, - 0x51, - 0xD1, - 0x31, - 0xB1, - 0x71, - 0xF1, - 0x09, - 0x89, - 0x49, - 0xC9, - 0x29, - 0xA9, - 0x69, - 0xE9, - 0x19, - 0x99, - 0x59, - 0xD9, - 0x39, - 0xB9, - 0x79, - 0xF9, - 0x05, - 0x85, - 0x45, - 0xC5, - 0x25, - 0xA5, - 0x65, - 0xE5, - 0x15, - 0x95, - 0x55, - 0xD5, - 0x35, - 0xB5, - 0x75, - 0xF5, - 0x0D, - 0x8D, - 0x4D, - 0xCD, - 0x2D, - 0xAD, - 0x6D, - 0xED, - 0x1D, - 0x9D, - 0x5D, - 0xDD, - 0x3D, - 0xBD, - 0x7D, - 0xFD, - 0x03, - 0x83, - 0x43, - 0xC3, - 0x23, - 0xA3, - 0x63, - 0xE3, - 0x13, - 0x93, - 0x53, - 0xD3, - 0x33, - 0xB3, - 0x73, - 0xF3, - 0x0B, - 0x8B, - 0x4B, - 0xCB, - 0x2B, - 0xAB, - 0x6B, - 0xEB, - 0x1B, - 0x9B, - 0x5B, - 0xDB, - 0x3B, - 0xBB, - 0x7B, - 0xFB, - 0x07, - 0x87, - 0x47, - 0xC7, - 0x27, - 0xA7, - 0x67, - 0xE7, - 0x17, - 0x97, - 0x57, - 0xD7, - 0x37, - 0xB7, - 0x77, - 0xF7, - 0x0F, - 0x8F, - 0x4F, - 0xCF, - 0x2F, - 0xAF, - 0x6F, - 0xEF, - 0x1F, - 0x9F, - 0x5F, - 0xDF, - 0x3F, - 0xBF, - 0x7F, - 0xFF, -} - -const reverseBitsLowest = (uint64(1) << (reverseBitsMax - 1 + reverseBitsBase)) - -/* Returns reverse(num >> BROTLI_REVERSE_BITS_BASE, BROTLI_REVERSE_BITS_MAX), - where reverse(value, len) is the bit-wise reversal of the len least - significant bits of value. */ -func reverseBits8(num uint64) uint64 { - return uint64(kReverseBits[num]) -} - -/* Stores code in table[0], table[step], table[2*step], ..., table[end] */ -/* Assumes that end is an integer multiple of step */ -func replicateValue(table []huffmanCode, step int, end int, code huffmanCode) { - for { - end -= step - table[end] = code - if end <= 0 { - break - } - } -} - -/* Returns the table width of the next 2nd level table. |count| is the histogram - of bit lengths for the remaining symbols, |len| is the code length of the - next processed symbol. */ -func nextTableBitSize(count []uint16, len int, root_bits int) int { - var left int = 1 << uint(len-root_bits) - for len < huffmanMaxCodeLength { - left -= int(count[len]) - if left <= 0 { - break - } - len++ - left <<= 1 - } - - return len - root_bits -} - -func buildCodeLengthsHuffmanTable(table []huffmanCode, code_lengths []byte, count []uint16) { - var code huffmanCode /* current table entry */ /* symbol index in original or sorted table */ /* prefix code */ /* prefix code addend */ /* step size to replicate values in current table */ /* size of current table */ /* symbols sorted by code length */ - var symbol int - var key uint64 - var key_step uint64 - var step int - var table_size int - var sorted [codeLengthCodes]int - var offset [huffmanMaxCodeLengthCodeLength + 1]int - var bits int - var bits_count int - /* offsets in sorted table for each length */ - assert(huffmanMaxCodeLengthCodeLength <= reverseBitsMax) - - /* Generate offsets into sorted symbol table by code length. */ - symbol = -1 - - bits = 1 - var i int - for i = 0; i < huffmanMaxCodeLengthCodeLength; i++ { - symbol += int(count[bits]) - offset[bits] = symbol - bits++ - } - - /* Symbols with code length 0 are placed after all other symbols. */ - offset[0] = codeLengthCodes - 1 - - /* Sort symbols by length, by symbol order within each length. */ - symbol = codeLengthCodes - - for { - var i int - for i = 0; i < 6; i++ { - symbol-- - sorted[offset[code_lengths[symbol]]] = symbol - offset[code_lengths[symbol]]-- - } - if symbol == 0 { - break - } - } - - table_size = 1 << huffmanMaxCodeLengthCodeLength - - /* Special case: all symbols but one have 0 code length. */ - if offset[0] == 0 { - code = constructHuffmanCode(0, uint16(sorted[0])) - for key = 0; key < uint64(table_size); key++ { - table[key] = code - } - - return - } - - /* Fill in table. */ - key = 0 - - key_step = reverseBitsLowest - symbol = 0 - bits = 1 - step = 2 - for { - for bits_count = int(count[bits]); bits_count != 0; bits_count-- { - code = constructHuffmanCode(byte(bits), uint16(sorted[symbol])) - symbol++ - replicateValue(table[reverseBits8(key):], step, table_size, code) - key += key_step - } - - step <<= 1 - key_step >>= 1 - bits++ - if bits > huffmanMaxCodeLengthCodeLength { - break - } - } -} - -func buildHuffmanTable(root_table []huffmanCode, root_bits int, symbol_lists symbolList, count []uint16) uint32 { - var code huffmanCode /* current table entry */ /* next available space in table */ /* current code length */ /* symbol index in original or sorted table */ /* prefix code */ /* prefix code addend */ /* 2nd level table prefix code */ /* 2nd level table prefix code addend */ /* step size to replicate values in current table */ /* key length of current table */ /* size of current table */ /* sum of root table size and 2nd level table sizes */ - var table []huffmanCode - var len int - var symbol int - var key uint64 - var key_step uint64 - var sub_key uint64 - var sub_key_step uint64 - var step int - var table_bits int - var table_size int - var total_size int - var max_length int = -1 - var bits int - var bits_count int - - assert(root_bits <= reverseBitsMax) - assert(huffmanMaxCodeLength-root_bits <= reverseBitsMax) - - for symbolListGet(symbol_lists, max_length) == 0xFFFF { - max_length-- - } - max_length += huffmanMaxCodeLength + 1 - - table = root_table - table_bits = root_bits - table_size = 1 << uint(table_bits) - total_size = table_size - - /* Fill in the root table. Reduce the table size to if possible, - and create the repetitions by memcpy. */ - if table_bits > max_length { - table_bits = max_length - table_size = 1 << uint(table_bits) - } - - key = 0 - key_step = reverseBitsLowest - bits = 1 - step = 2 - for { - symbol = bits - (huffmanMaxCodeLength + 1) - for bits_count = int(count[bits]); bits_count != 0; bits_count-- { - symbol = int(symbolListGet(symbol_lists, symbol)) - code = constructHuffmanCode(byte(bits), uint16(symbol)) - replicateValue(table[reverseBits8(key):], step, table_size, code) - key += key_step - } - - step <<= 1 - key_step >>= 1 - bits++ - if bits > table_bits { - break - } - } - - /* If root_bits != table_bits then replicate to fill the remaining slots. */ - for total_size != table_size { - copy(table[table_size:], table[:uint(table_size)]) - table_size <<= 1 - } - - /* Fill in 2nd level tables and add pointers to root table. */ - key_step = reverseBitsLowest >> uint(root_bits-1) - - sub_key = reverseBitsLowest << 1 - sub_key_step = reverseBitsLowest - len = root_bits + 1 - step = 2 - for ; len <= max_length; len++ { - symbol = len - (huffmanMaxCodeLength + 1) - for ; count[len] != 0; count[len]-- { - if sub_key == reverseBitsLowest<<1 { - table = table[table_size:] - table_bits = nextTableBitSize(count, int(len), root_bits) - table_size = 1 << uint(table_bits) - total_size += table_size - sub_key = reverseBits8(key) - key += key_step - root_table[sub_key] = constructHuffmanCode(byte(table_bits+root_bits), uint16(uint64(uint(-cap(table)+cap(root_table)))-sub_key)) - sub_key = 0 - } - - symbol = int(symbolListGet(symbol_lists, symbol)) - code = constructHuffmanCode(byte(len-root_bits), uint16(symbol)) - replicateValue(table[reverseBits8(sub_key):], step, table_size, code) - sub_key += sub_key_step - } - - step <<= 1 - sub_key_step >>= 1 - } - - return uint32(total_size) -} - -func buildSimpleHuffmanTable(table []huffmanCode, root_bits int, val []uint16, num_symbols uint32) uint32 { - var table_size uint32 = 1 - var goal_size uint32 = 1 << uint(root_bits) - switch num_symbols { - case 0: - table[0] = constructHuffmanCode(0, val[0]) - - case 1: - if val[1] > val[0] { - table[0] = constructHuffmanCode(1, val[0]) - table[1] = constructHuffmanCode(1, val[1]) - } else { - table[0] = constructHuffmanCode(1, val[1]) - table[1] = constructHuffmanCode(1, val[0]) - } - - table_size = 2 - - case 2: - table[0] = constructHuffmanCode(1, val[0]) - table[2] = constructHuffmanCode(1, val[0]) - if val[2] > val[1] { - table[1] = constructHuffmanCode(2, val[1]) - table[3] = constructHuffmanCode(2, val[2]) - } else { - table[1] = constructHuffmanCode(2, val[2]) - table[3] = constructHuffmanCode(2, val[1]) - } - - table_size = 4 - - case 3: - var i int - var k int - for i = 0; i < 3; i++ { - for k = i + 1; k < 4; k++ { - if val[k] < val[i] { - var t uint16 = val[k] - val[k] = val[i] - val[i] = t - } - } - } - - table[0] = constructHuffmanCode(2, val[0]) - table[2] = constructHuffmanCode(2, val[1]) - table[1] = constructHuffmanCode(2, val[2]) - table[3] = constructHuffmanCode(2, val[3]) - table_size = 4 - - case 4: - if val[3] < val[2] { - var t uint16 = val[3] - val[3] = val[2] - val[2] = t - } - - table[0] = constructHuffmanCode(1, val[0]) - table[1] = constructHuffmanCode(2, val[1]) - table[2] = constructHuffmanCode(1, val[0]) - table[3] = constructHuffmanCode(3, val[2]) - table[4] = constructHuffmanCode(1, val[0]) - table[5] = constructHuffmanCode(2, val[1]) - table[6] = constructHuffmanCode(1, val[0]) - table[7] = constructHuffmanCode(3, val[3]) - table_size = 8 - } - - for table_size != goal_size { - copy(table[table_size:], table[:uint(table_size)]) - table_size <<= 1 - } - - return goal_size -} diff --git a/src/vendor/github.com/andybalholm/brotli/literal_cost.go b/src/vendor/github.com/andybalholm/brotli/literal_cost.go deleted file mode 100644 index 5a9ace94..00000000 --- a/src/vendor/github.com/andybalholm/brotli/literal_cost.go +++ /dev/null @@ -1,182 +0,0 @@ -package brotli - -func utf8Position(last uint, c uint, clamp uint) uint { - if c < 128 { - return 0 /* Next one is the 'Byte 1' again. */ - } else if c >= 192 { /* Next one is the 'Byte 2' of utf-8 encoding. */ - return brotli_min_size_t(1, clamp) - } else { - /* Let's decide over the last byte if this ends the sequence. */ - if last < 0xE0 { - return 0 /* Completed two or three byte coding. */ /* Next one is the 'Byte 3' of utf-8 encoding. */ - } else { - return brotli_min_size_t(2, clamp) - } - } -} - -func decideMultiByteStatsLevel(pos uint, len uint, mask uint, data []byte) uint { - var counts = [3]uint{0} /* should be 2, but 1 compresses better. */ - var max_utf8 uint = 1 - var last_c uint = 0 - var i uint - for i = 0; i < len; i++ { - var c uint = uint(data[(pos+i)&mask]) - counts[utf8Position(last_c, c, 2)]++ - last_c = c - } - - if counts[2] < 500 { - max_utf8 = 1 - } - - if counts[1]+counts[2] < 25 { - max_utf8 = 0 - } - - return max_utf8 -} - -func estimateBitCostsForLiteralsUTF8(pos uint, len uint, mask uint, data []byte, cost []float32) { - var max_utf8 uint = decideMultiByteStatsLevel(pos, uint(len), mask, data) - /* Bootstrap histograms. */ - var histogram = [3][256]uint{[256]uint{0}} - var window_half uint = 495 - var in_window uint = brotli_min_size_t(window_half, uint(len)) - var in_window_utf8 = [3]uint{0} - /* max_utf8 is 0 (normal ASCII single byte modeling), - 1 (for 2-byte UTF-8 modeling), or 2 (for 3-byte UTF-8 modeling). */ - - var i uint - { - var last_c uint = 0 - var utf8_pos uint = 0 - for i = 0; i < in_window; i++ { - var c uint = uint(data[(pos+i)&mask]) - histogram[utf8_pos][c]++ - in_window_utf8[utf8_pos]++ - utf8_pos = utf8Position(last_c, c, max_utf8) - last_c = c - } - } - - /* Compute bit costs with sliding window. */ - for i = 0; i < len; i++ { - if i >= window_half { - var c uint - var last_c uint - if i < window_half+1 { - c = 0 - } else { - c = uint(data[(pos+i-window_half-1)&mask]) - } - if i < window_half+2 { - last_c = 0 - } else { - last_c = uint(data[(pos+i-window_half-2)&mask]) - } - /* Remove a byte in the past. */ - - var utf8_pos2 uint = utf8Position(last_c, c, max_utf8) - histogram[utf8_pos2][data[(pos+i-window_half)&mask]]-- - in_window_utf8[utf8_pos2]-- - } - - if i+window_half < len { - var c uint = uint(data[(pos+i+window_half-1)&mask]) - var last_c uint = uint(data[(pos+i+window_half-2)&mask]) - /* Add a byte in the future. */ - - var utf8_pos2 uint = utf8Position(last_c, c, max_utf8) - histogram[utf8_pos2][data[(pos+i+window_half)&mask]]++ - in_window_utf8[utf8_pos2]++ - } - { - var c uint - var last_c uint - if i < 1 { - c = 0 - } else { - c = uint(data[(pos+i-1)&mask]) - } - if i < 2 { - last_c = 0 - } else { - last_c = uint(data[(pos+i-2)&mask]) - } - var utf8_pos uint = utf8Position(last_c, c, max_utf8) - var masked_pos uint = (pos + i) & mask - var histo uint = histogram[utf8_pos][data[masked_pos]] - var lit_cost float64 - if histo == 0 { - histo = 1 - } - - lit_cost = fastLog2(in_window_utf8[utf8_pos]) - fastLog2(histo) - lit_cost += 0.02905 - if lit_cost < 1.0 { - lit_cost *= 0.5 - lit_cost += 0.5 - } - - /* Make the first bytes more expensive -- seems to help, not sure why. - Perhaps because the entropy source is changing its properties - rapidly in the beginning of the file, perhaps because the beginning - of the data is a statistical "anomaly". */ - if i < 2000 { - lit_cost += 0.7 - (float64(2000-i) / 2000.0 * 0.35) - } - - cost[i] = float32(lit_cost) - } - } -} - -func estimateBitCostsForLiterals(pos uint, len uint, mask uint, data []byte, cost []float32) { - if isMostlyUTF8(data, pos, mask, uint(len), kMinUTF8Ratio) { - estimateBitCostsForLiteralsUTF8(pos, uint(len), mask, data, cost) - return - } else { - var histogram = [256]uint{0} - var window_half uint = 2000 - var in_window uint = brotli_min_size_t(window_half, uint(len)) - var i uint - /* Bootstrap histogram. */ - for i = 0; i < in_window; i++ { - histogram[data[(pos+i)&mask]]++ - } - - /* Compute bit costs with sliding window. */ - for i = 0; i < len; i++ { - var histo uint - if i >= window_half { - /* Remove a byte in the past. */ - histogram[data[(pos+i-window_half)&mask]]-- - - in_window-- - } - - if i+window_half < len { - /* Add a byte in the future. */ - histogram[data[(pos+i+window_half)&mask]]++ - - in_window++ - } - - histo = histogram[data[(pos+i)&mask]] - if histo == 0 { - histo = 1 - } - { - var lit_cost float64 = fastLog2(in_window) - fastLog2(histo) - lit_cost += 0.029 - if lit_cost < 1.0 { - lit_cost *= 0.5 - lit_cost += 0.5 - } - - cost[i] = float32(lit_cost) - } - } - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/bargain1.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/bargain1.go deleted file mode 100644 index bdafbd64..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/bargain1.go +++ /dev/null @@ -1,212 +0,0 @@ -package matchfinder - -import ( - "encoding/binary" - "math" - "math/bits" - "slices" -) - -const ( - bargain1TableBits = 18 - bargain1TableSize = 1 << bargain1TableBits -) - -// Bargain1 is a MatchFinder that attempts to find the encoding with the lowest -// "bit cost", using 1 hash length (6). -type Bargain1 struct { - MaxDistance int - - // Skip is whether to look for matches at every other byte instead of every - // byte (to increase speed but decrease compression). - Skip bool - - history []byte - table6 [bargain1TableSize]tableEntry - - // holding onto buffers to reduce allocations: - - arrivals []arrival - matches []Match -} - -func (z *Bargain1) Reset() { - z.table6 = [bargain1TableSize]tableEntry{} - z.history = z.history[:0] -} - -func (z *Bargain1) FindMatches(dst []Match, src []byte) []Match { - if z.MaxDistance == 0 { - z.MaxDistance = 1 << 16 - } - - var histogram [256]uint32 - for _, b := range src { - histogram[b]++ - } - var byteCost [256]float32 - for b, n := range histogram { - cost := max(math.Log2(float64(len(src))/float64(n)), 1) - byteCost[b] = float32(cost) - } - - // Each element in arrivals corresponds to the position just after - // the corresponding byte in src. - arrivals := z.arrivals - if len(arrivals) < len(src) { - arrivals = make([]arrival, len(src)) - z.arrivals = arrivals - } else { - arrivals = arrivals[:len(src)] - for i := range arrivals { - arrivals[i] = arrival{} - } - } - - if len(z.history) > z.MaxDistance*2 { - delta := len(z.history) - z.MaxDistance - copy(z.history, z.history[delta:]) - z.history = z.history[:z.MaxDistance] - - for i := range z.table6 { - v := z.table6[i].offset - v -= int32(delta) - if v < 0 { - z.table6[i] = tableEntry{} - } else { - z.table6[i].offset = v - } - } - } - - historyLen := len(z.history) - z.history = append(z.history, src...) - src = z.history - - addMatch := func(m absoluteMatch, unmatched int, repeat bool) { - var startCost float32 - if m.Start > historyLen { - startCost = arrivals[m.Start-historyLen-1].cost - } - insertCost := float32(bits.Len(uint(unmatched))) - var distanceCost float32 - if !repeat { - distanceCost = float32(bits.Len(uint(m.Start - m.Match))) - } - cost := startCost + baseMatchCost + insertCost + distanceCost - for j := m.End; j >= m.Start+3; j-- { - a := &arrivals[j-historyLen-1] - if a.cost > 0 && a.cost <= cost { - break - } - *a = arrival{ - length: uint32(j - m.Start), - distance: uint32(m.Start - m.Match), - cost: cost, - } - } - } - - var nextOverlapSearch int - - for i := historyLen; i < len(src); i++ { - var arrivedHere arrival - if i > historyLen { - arrivedHere = arrivals[i-historyLen-1] - } - - unmatched := 0 - if arrivedHere.distance == 0 { - unmatched = int(arrivedHere.length) - } - prevDistance := 0 - if unmatched != 0 && i-unmatched > historyLen { - prevDistance = int(arrivals[i-historyLen-1-unmatched].distance) - } - - literalCost := byteCost[src[i]] - nextArrival := &arrivals[i-historyLen] - if nextArrival.cost == 0 || arrivedHere.cost+literalCost < nextArrival.cost { - *nextArrival = arrival{ - cost: arrivedHere.cost + literalCost, - length: uint32(unmatched + 1), - } - } - - if i > len(src)-8 { - // There's no room to check hashes. - continue - } - - cv := binary.LittleEndian.Uint64(src[i:]) - nextHash6 := z.hash6(cv) - candidate6 := z.table6[nextHash6] - - entry := tableEntry{offset: int32(i), val: uint32(cv)} - z.table6[nextHash6] = entry - - // Look for a repeat match, unless there is no previous distance, or a match at - // that distance has already been found. - if prevDistance != 0 && prevDistance != int(arrivals[i-historyLen-1+4].distance) { - repIndex := i - prevDistance - if repIndex >= 0 && binary.LittleEndian.Uint32(src[repIndex:]) == uint32(cv) { - // We have a repeat of the previous match distance. - m := extendMatch2(src, i, repIndex, i) - addMatch(m, unmatched, true) - } - } - - if z.Skip && i%2 != 0 { - continue - } - - nextByteIsUnmatched := arrivals[i-historyLen-1+1].distance == 0 - - if unmatched > 0 || i >= nextOverlapSearch || nextByteIsUnmatched { - if int(candidate6.offset) < i && i-int(candidate6.offset) < z.MaxDistance && uint32(cv) == candidate6.val && - binary.LittleEndian.Uint32(src[candidate6.offset:]) == uint32(cv) { - m := extendMatch2(src, i, int(candidate6.offset), historyLen) - delta := i - m.Start - if delta == 0 { - addMatch(m, unmatched, false) - } else { - // The match was extended backwards. Add it with and without the extra. - addMatch(m, max(unmatched-delta, 0), false) - m.Start += delta - m.Match += delta - addMatch(m, unmatched, false) - } - nextOverlapSearch = max(nextOverlapSearch, m.Start+1, m.End-4) - } - } - } - - // We've found the shortest path; now walk it backward and store the matches. - matches := z.matches[:0] - i := len(arrivals) - 1 - for i >= 0 { - a := arrivals[i] - if a.distance > 0 { - matches = append(matches, Match{ - Length: int(a.length), - Distance: int(a.distance), - }) - i -= int(a.length) - } else { - if len(matches) == 0 { - matches = append(matches, Match{}) - } - matches[len(matches)-1].Unmatched = int(a.length) - i -= int(a.length) - } - } - z.matches = matches - - slices.Reverse(matches) - - return append(dst, matches...) -} - -func (z *Bargain1) hash6(u uint64) uint32 { - return uint32(((u << 16) * 227718039650203) >> (64 - bargain1TableBits)) -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/bargain2.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/bargain2.go deleted file mode 100644 index 020a0003..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/bargain2.go +++ /dev/null @@ -1,248 +0,0 @@ -package matchfinder - -import ( - "encoding/binary" - "math" - "math/bits" - "slices" -) - -const ( - bargain2TableBits = 18 - bargain2TableSize = 1 << bargain2TableBits -) - -// Bargain2 is a MatchFinder that attempts to find the encoding with the lowest -// "bit cost", using 2 hash lengths (5 and 8). -type Bargain2 struct { - MaxDistance int - - // Skip is whether to look for matches at every other byte instead of every - // byte (to increase speed but decrease compression). - Skip bool - - history []byte - table5 [bargain2TableSize]tableEntry - table8 [bargain2TableSize]tableEntry - - // holding onto buffers to reduce allocations: - - arrivals []arrival - matches []Match -} - -func (z *Bargain2) Reset() { - z.table5 = [bargain2TableSize]tableEntry{} - z.table8 = [bargain2TableSize]tableEntry{} - z.history = z.history[:0] -} - -func (z *Bargain2) FindMatches(dst []Match, src []byte) []Match { - if z.MaxDistance == 0 { - z.MaxDistance = 1 << 16 - } - - var histogram [256]uint32 - for _, b := range src { - histogram[b]++ - } - var byteCost [256]float32 - for b, n := range histogram { - cost := max(math.Log2(float64(len(src))/float64(n)), 1) - byteCost[b] = float32(cost) - } - - // Each element in arrivals corresponds to the position just after - // the corresponding byte in src. - arrivals := z.arrivals - if len(arrivals) < len(src) { - arrivals = make([]arrival, len(src)) - z.arrivals = arrivals - } else { - arrivals = arrivals[:len(src)] - for i := range arrivals { - arrivals[i] = arrival{} - } - } - - if len(z.history) > z.MaxDistance*2 { - delta := len(z.history) - z.MaxDistance - copy(z.history, z.history[delta:]) - z.history = z.history[:z.MaxDistance] - - for i := range z.table5 { - v := z.table5[i].offset - v -= int32(delta) - if v < 0 { - z.table5[i] = tableEntry{} - } else { - z.table5[i].offset = v - } - } - for i := range z.table8 { - v := z.table8[i].offset - v -= int32(delta) - if v < 0 { - z.table8[i] = tableEntry{} - } else { - z.table8[i].offset = v - } - } - } - - historyLen := len(z.history) - z.history = append(z.history, src...) - src = z.history - - addMatch := func(m absoluteMatch, unmatched int, repeat bool) { - var startCost float32 - if m.Start > historyLen { - startCost = arrivals[m.Start-historyLen-1].cost - } - insertCost := float32(bits.Len(uint(unmatched))) - var distanceCost float32 - if !repeat { - distanceCost = float32(bits.Len(uint(m.Start - m.Match))) - } - cost := startCost + baseMatchCost + insertCost + distanceCost - for j := m.End; j >= m.Start+3; j-- { - a := &arrivals[j-historyLen-1] - if a.cost > 0 && a.cost <= cost { - break - } - *a = arrival{ - length: uint32(j - m.Start), - distance: uint32(m.Start - m.Match), - cost: cost, - } - } - } - - var nextOverlapSearch int - - for i := historyLen; i < len(src); i++ { - var arrivedHere arrival - if i > historyLen { - arrivedHere = arrivals[i-historyLen-1] - } - - unmatched := 0 - if arrivedHere.distance == 0 { - unmatched = int(arrivedHere.length) - } - prevDistance := 0 - if unmatched != 0 && i-unmatched > historyLen { - prevDistance = int(arrivals[i-historyLen-1-unmatched].distance) - } - - literalCost := byteCost[src[i]] - nextArrival := &arrivals[i-historyLen] - if nextArrival.cost == 0 || arrivedHere.cost+literalCost < nextArrival.cost { - *nextArrival = arrival{ - cost: arrivedHere.cost + literalCost, - length: uint32(unmatched + 1), - } - } - - if i > len(src)-8 { - // There's no room to check hashes. - continue - } - - cv := binary.LittleEndian.Uint64(src[i:]) - nextHash5 := z.hash5(cv) - nextHash8 := z.hash8(cv) - candidate5 := z.table5[nextHash5] - candidate8 := z.table8[nextHash8] - - entry := tableEntry{offset: int32(i), val: uint32(cv)} - z.table5[nextHash5] = entry - z.table8[nextHash8] = entry - - // Look for a repeat match, unless there is no previous distance, or a match at - // that distance has already been found. - if prevDistance != 0 && prevDistance != int(arrivals[i-historyLen-1+4].distance) { - repIndex := i - prevDistance - if repIndex >= 0 && binary.LittleEndian.Uint32(src[repIndex:]) == uint32(cv) { - // We have a repeat of the previous match distance. - m := extendMatch2(src, i, repIndex, i) - addMatch(m, unmatched, true) - } - } - - if z.Skip { - if i%2 != 0 { - continue - } - } - - nextByteIsUnmatched := arrivals[i-historyLen-1+1].distance == 0 - - if unmatched > 0 || i >= nextOverlapSearch || nextByteIsUnmatched { - if int(candidate5.offset) < i && i-int(candidate5.offset) < z.MaxDistance && uint32(cv) == candidate5.val && - binary.LittleEndian.Uint32(src[candidate5.offset:]) == uint32(cv) { - m := extendMatch2(src, i, int(candidate5.offset), historyLen) - delta := i - m.Start - if delta == 0 { - addMatch(m, unmatched, false) - } else { - // The match was extended backwards. Add it with and without the extra. - addMatch(m, max(unmatched-delta, 0), false) - m.Start += delta - m.Match += delta - addMatch(m, unmatched, false) - } - nextOverlapSearch = max(nextOverlapSearch, m.Start+1, m.End-6) - } - - if int(candidate8.offset) < i && i-int(candidate8.offset) < z.MaxDistance && uint32(cv) == candidate8.val && - binary.LittleEndian.Uint32(src[candidate8.offset:]) == uint32(cv) { - m := extendMatch2(src, i, int(candidate8.offset), historyLen) - delta := i - m.Start - if delta == 0 { - addMatch(m, unmatched, false) - } else { - // The match was extended backwards. Add it with and without the extra. - addMatch(m, max(unmatched-delta, 0), false) - m.Start += delta - m.Match += delta - addMatch(m, unmatched, false) - } - nextOverlapSearch = max(nextOverlapSearch, m.Start+1, m.End-6) - } - } - } - - // We've found the shortest path; now walk it backward and store the matches. - matches := z.matches[:0] - i := len(arrivals) - 1 - for i >= 0 { - a := arrivals[i] - if a.distance > 0 { - matches = append(matches, Match{ - Length: int(a.length), - Distance: int(a.distance), - }) - i -= int(a.length) - } else { - if len(matches) == 0 { - matches = append(matches, Match{}) - } - matches[len(matches)-1].Unmatched = int(a.length) - i -= int(a.length) - } - } - z.matches = matches - - slices.Reverse(matches) - - return append(dst, matches...) -} - -func (z *Bargain2) hash5(u uint64) uint32 { - return uint32(((u << 24) * 889523592379) >> (64 - bargain2TableBits)) -} - -func (z *Bargain2) hash8(u uint64) uint32 { - return uint32((u * 0xcf1bbcdcb7a56463) >> (64 - bargain2TableBits)) -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/bargain3.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/bargain3.go deleted file mode 100644 index 24acd1ca..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/bargain3.go +++ /dev/null @@ -1,278 +0,0 @@ -package matchfinder - -import ( - "encoding/binary" - "math" - "math/bits" - "slices" -) - -// Bargain3 is a MatchFinder that attempts to find the encoding with the lowest -// "bit cost", using 3 hash lengths (5, 8, and 12). -type Bargain3 struct { - MaxDistance int - - // Skip is whether to look for matches at every other byte instead of every - // byte (to increase speed but decrease compression). - Skip bool - - history []byte - table5 [1 << 17]tableEntry - table8 [1 << 18]tableEntry - table12 [1 << 19]tableEntry - - // holding onto buffers to reduce allocations: - - arrivals []arrival - matches []Match -} - -func (z *Bargain3) Reset() { - z.table5 = [len(z.table5)]tableEntry{} - z.table8 = [len(z.table8)]tableEntry{} - z.table12 = [len(z.table12)]tableEntry{} - z.history = z.history[:0] -} - -func (z *Bargain3) FindMatches(dst []Match, src []byte) []Match { - if z.MaxDistance == 0 { - z.MaxDistance = 1 << 16 - } - - var histogram [256]uint32 - for _, b := range src { - histogram[b]++ - } - var byteCost [256]float32 - for b, n := range histogram { - cost := max(math.Log2(float64(len(src))/float64(n)), 1) - byteCost[b] = float32(cost) - } - - // Each element in arrivals corresponds to the position just after - // the corresponding byte in src. - arrivals := z.arrivals - if len(arrivals) < len(src) { - arrivals = make([]arrival, len(src)) - z.arrivals = arrivals - } else { - arrivals = arrivals[:len(src)] - for i := range arrivals { - arrivals[i] = arrival{} - } - } - - if len(z.history) > z.MaxDistance*2 { - delta := len(z.history) - z.MaxDistance - copy(z.history, z.history[delta:]) - z.history = z.history[:z.MaxDistance] - - for i := range z.table5 { - v := z.table5[i].offset - v -= int32(delta) - if v < 0 { - z.table5[i] = tableEntry{} - } else { - z.table5[i].offset = v - } - } - for i := range z.table8 { - v := z.table8[i].offset - v -= int32(delta) - if v < 0 { - z.table8[i] = tableEntry{} - } else { - z.table8[i].offset = v - } - } - for i := range z.table12 { - v := z.table12[i].offset - v -= int32(delta) - if v < 0 { - z.table12[i] = tableEntry{} - } else { - z.table12[i].offset = v - } - } - } - - historyLen := len(z.history) - z.history = append(z.history, src...) - src = z.history - - addMatch := func(m absoluteMatch, unmatched int, repeat bool) { - var startCost float32 - if m.Start > historyLen { - startCost = arrivals[m.Start-historyLen-1].cost - } - insertCost := float32(bits.Len(uint(unmatched))) - var distanceCost float32 - if !repeat { - distanceCost = float32(bits.Len(uint(m.Start - m.Match))) - } - cost := startCost + baseMatchCost + insertCost + distanceCost - for j := m.End; j >= m.Start+3; j-- { - a := &arrivals[j-historyLen-1] - if a.cost > 0 && a.cost <= cost { - break - } - *a = arrival{ - length: uint32(j - m.Start), - distance: uint32(m.Start - m.Match), - cost: cost, - } - } - } - - var nextOverlapSearch int - - for i := historyLen; i < len(src); i++ { - var arrivedHere arrival - if i > historyLen { - arrivedHere = arrivals[i-historyLen-1] - } - - unmatched := 0 - if arrivedHere.distance == 0 { - unmatched = int(arrivedHere.length) - } - prevDistance := 0 - if unmatched != 0 && i-unmatched > historyLen { - prevDistance = int(arrivals[i-historyLen-1-unmatched].distance) - } - - literalCost := byteCost[src[i]] - nextArrival := &arrivals[i-historyLen] - if nextArrival.cost == 0 || arrivedHere.cost+literalCost < nextArrival.cost { - *nextArrival = arrival{ - cost: arrivedHere.cost + literalCost, - length: uint32(unmatched + 1), - } - } - - if i > len(src)-12 { - // There's no room to check hashes. - continue - } - - cv := binary.LittleEndian.Uint64(src[i:]) - extra := binary.LittleEndian.Uint32(src[i+8:]) - nextHash5 := z.hash5(cv) - nextHash8 := z.hash8(cv) - nextHash12 := z.hash12(cv, extra) - candidate5 := z.table5[nextHash5] - candidate8 := z.table8[nextHash8] - candidate12 := z.table12[nextHash12] - - entry := tableEntry{offset: int32(i), val: uint32(cv)} - z.table5[nextHash5] = entry - z.table8[nextHash8] = entry - z.table12[nextHash12] = entry - - // Look for a repeat match, unless there is no previous distance, or a match at - // that distance has already been found. - if prevDistance != 0 && prevDistance != int(arrivals[i-historyLen-1+4].distance) { - repIndex := i - prevDistance - if repIndex >= 0 && binary.LittleEndian.Uint32(src[repIndex:]) == uint32(cv) { - // We have a repeat of the previous match distance. - m := extendMatch2(src, i, repIndex, i) - addMatch(m, unmatched, true) - } - } - - if z.Skip { - if i%2 != 0 { - continue - } - } - - nextByteIsUnmatched := arrivals[i-historyLen-1+1].distance == 0 - - if unmatched > 0 || i >= nextOverlapSearch || nextByteIsUnmatched { - if int(candidate5.offset) < i && i-int(candidate5.offset) < z.MaxDistance && uint32(cv) == candidate5.val && - binary.LittleEndian.Uint32(src[candidate5.offset:]) == uint32(cv) { - m := extendMatch2(src, i, int(candidate5.offset), historyLen) - delta := i - m.Start - if delta == 0 { - addMatch(m, unmatched, false) - } else { - // The match was extended backwards. Add it with and without the extra. - addMatch(m, max(unmatched-delta, 0), false) - m.Start += delta - m.Match += delta - addMatch(m, unmatched, false) - } - nextOverlapSearch = max(nextOverlapSearch, m.Start+1, m.End-6) - } - - if int(candidate8.offset) < i && i-int(candidate8.offset) < z.MaxDistance && uint32(cv) == candidate8.val && - binary.LittleEndian.Uint32(src[candidate8.offset:]) == uint32(cv) { - m := extendMatch2(src, i, int(candidate8.offset), historyLen) - delta := i - m.Start - if delta == 0 { - addMatch(m, unmatched, false) - } else { - // The match was extended backwards. Add it with and without the extra. - addMatch(m, max(unmatched-delta, 0), false) - m.Start += delta - m.Match += delta - addMatch(m, unmatched, false) - } - nextOverlapSearch = max(nextOverlapSearch, m.Start+1, m.End-6) - } - - if int(candidate12.offset) < i && i-int(candidate12.offset) < z.MaxDistance && uint32(cv) == candidate12.val && - binary.LittleEndian.Uint32(src[candidate12.offset:]) == uint32(cv) { - m := extendMatch2(src, i, int(candidate12.offset), historyLen) - delta := i - m.Start - if delta == 0 { - addMatch(m, unmatched, false) - } else { - // The match was extended backwards. Add it with and without the extra. - addMatch(m, max(unmatched-delta, 0), false) - m.Start += delta - m.Match += delta - addMatch(m, unmatched, false) - } - nextOverlapSearch = max(nextOverlapSearch, m.Start+1, m.End-6) - } - } - } - - // We've found the shortest path; now walk it backward and store the matches. - matches := z.matches[:0] - i := len(arrivals) - 1 - for i >= 0 { - a := arrivals[i] - if a.distance > 0 { - matches = append(matches, Match{ - Length: int(a.length), - Distance: int(a.distance), - }) - i -= int(a.length) - } else { - if len(matches) == 0 { - matches = append(matches, Match{}) - } - matches[len(matches)-1].Unmatched = int(a.length) - i -= int(a.length) - } - } - z.matches = matches - - slices.Reverse(matches) - - return append(dst, matches...) -} - -func (z *Bargain3) hash5(u uint64) uint32 { - return uint32(((u << 24) * 889523592379) >> (64 - 17)) -} - -func (z *Bargain3) hash8(u uint64) uint32 { - return uint32((u * 0xcf1bbcdcb7a56463) >> (64 - 18)) -} - -func (z *Bargain3) hash12(u uint64, e uint32) uint32 { - return uint32((u*0xcf1bbcdcb7a56463 + uint64(e)*(2654435761<<32)) >> (64 - 19)) -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/emitter.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/emitter.go deleted file mode 100644 index 507d1cae..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/emitter.go +++ /dev/null @@ -1,34 +0,0 @@ -package matchfinder - -// An absoluteMatch is like a Match, but it stores indexes into the byte -// stream instead of lengths. -type absoluteMatch struct { - // Start is the index of the first byte. - Start int - - // End is the index of the byte after the last byte - // (so that End - Start = Length). - End int - - // Match is the index of the previous data that matches - // (Start - Match = Distance). - Match int -} - -// A matchEmitter manages the output of matches for a MatchFinder. -type matchEmitter struct { - // Dst is the destination slice that Matches are added to. - Dst []Match - - // NextEmit is the index of the next byte to emit. - NextEmit int -} - -func (e *matchEmitter) emit(m absoluteMatch) { - e.Dst = append(e.Dst, Match{ - Unmatched: m.Start - e.NextEmit, - Length: m.End - m.Start, - Distance: m.Start - m.Match, - }) - e.NextEmit = m.End -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/m0.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/m0.go deleted file mode 100644 index a37e3b46..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/m0.go +++ /dev/null @@ -1,175 +0,0 @@ -package matchfinder - -import ( - "encoding/binary" -) - -// M0 is an implementation of the MatchFinder interface based -// on the algorithm used by snappy, but modified to be more like the algorithm -// used by compression level 0 of the brotli reference implementation. -// -// It has a maximum block size of 65536 bytes. -type M0 struct { - // Lazy turns on "lazy matching," for higher compression but less speed. - Lazy bool - - MaxDistance int - MaxLength int -} - -func (M0) Reset() {} - -const ( - m0HashLen = 5 - - m0TableBits = 16 - m0TableSize = 1 << m0TableBits - m0Shift = 32 - m0TableBits - // m0TableMask is redundant, but helps the compiler eliminate bounds - // checks. - m0TableMask = m0TableSize - 1 -) - -func (m M0) hash(data uint64) uint64 { - hash := (data << (64 - 8*m0HashLen)) * hashMul64 - return hash >> (64 - m0TableBits) -} - -// FindMatches looks for matches in src, appends them to dst, and returns dst. -// src must not be longer than 65536 bytes. -func (m M0) FindMatches(dst []Match, src []byte) []Match { - const inputMargin = 16 - 1 - const minNonLiteralBlockSize = 1 + 1 + inputMargin - - if len(src) < minNonLiteralBlockSize { - dst = append(dst, Match{ - Unmatched: len(src), - }) - return dst - } - if len(src) > 65536 { - panic("block too long") - } - - var table [m0TableSize]uint16 - - // sLimit is when to stop looking for offset/length copies. The inputMargin - // lets us use a fast path for emitLiteral in the main loop, while we are - // looking for copies. - sLimit := len(src) - inputMargin - - // nextEmit is where in src the next emitLiteral should start from. - nextEmit := 0 - - // The encoded form must start with a literal, as there are no previous - // bytes to copy, so we start looking for hash matches at s == 1. - s := 1 - nextHash := m.hash(binary.LittleEndian.Uint64(src[s:])) - - for { - // Copied from the C++ snappy implementation: - // - // Heuristic match skipping: If 32 bytes are scanned with no matches - // found, start looking only at every other byte. If 32 more bytes are - // scanned (or skipped), look at every third byte, etc.. When a match - // is found, immediately go back to looking at every byte. This is a - // small loss (~5% performance, ~0.1% density) for compressible data - // due to more bookkeeping, but for non-compressible data (such as - // JPEG) it's a huge win since the compressor quickly "realizes" the - // data is incompressible and doesn't bother looking for matches - // everywhere. - // - // The "skip" variable keeps track of how many bytes there are since - // the last match; dividing it by 32 (ie. right-shifting by five) gives - // the number of bytes to move ahead for each iteration. - skip := 32 - - nextS := s - candidate := 0 - for { - s = nextS - bytesBetweenHashLookups := skip >> 5 - nextS = s + bytesBetweenHashLookups - skip += bytesBetweenHashLookups - if nextS > sLimit { - goto emitRemainder - } - candidate = int(table[nextHash&m0TableMask]) - table[nextHash&m0TableMask] = uint16(s) - nextHash = m.hash(binary.LittleEndian.Uint64(src[nextS:])) - if m.MaxDistance != 0 && s-candidate > m.MaxDistance { - continue - } - if binary.LittleEndian.Uint32(src[s:]) == binary.LittleEndian.Uint32(src[candidate:]) { - break - } - } - - // Invariant: we have a 4-byte match at s. - base := s - s = extendMatch(src, candidate+4, s+4) - - origBase := base - if m.Lazy && base+1 < sLimit { - newBase := base + 1 - h := m.hash(binary.LittleEndian.Uint64(src[newBase:])) - newCandidate := int(table[h&m0TableMask]) - table[h&m0TableMask] = uint16(newBase) - okDistance := true - if m.MaxDistance != 0 && newBase-newCandidate > m.MaxDistance { - okDistance = false - } - if okDistance && binary.LittleEndian.Uint32(src[newBase:]) == binary.LittleEndian.Uint32(src[newCandidate:]) { - newS := extendMatch(src, newCandidate+4, newBase+4) - if newS-newBase > s-base+1 { - s = newS - base = newBase - candidate = newCandidate - } - } - } - - if m.MaxLength != 0 && s-base > m.MaxLength { - s = base + m.MaxLength - } - dst = append(dst, Match{ - Unmatched: base - nextEmit, - Length: s - base, - Distance: base - candidate, - }) - nextEmit = s - if s >= sLimit { - goto emitRemainder - } - - if m.Lazy { - // If lazy matching is enabled, we update the hash table for - // every byte in the match. - for i := origBase + 2; i < s-3; i++ { - x := binary.LittleEndian.Uint64(src[i:]) - table[m.hash(x)&m0TableMask] = uint16(i) - } - } else { - // We update the hash table only at base+1 - x := binary.LittleEndian.Uint64(src[base+1:]) - table[m.hash(x)&m0TableMask] = uint16(base + 1) - } - - // We could immediately start working at s now, but to improve - // compression we first update the hash table. - x := binary.LittleEndian.Uint64(src[s-3:]) - table[m.hash(x)&m0TableMask] = uint16(s - 3) - table[m.hash(x>>8)&m0TableMask] = uint16(s - 2) - prevHash := m.hash(x >> 16) - table[prevHash&m0TableMask] = uint16(s - 1) - nextHash = m.hash(x >> 24) - } - -emitRemainder: - if nextEmit < len(src) { - dst = append(dst, Match{ - Unmatched: len(src) - nextEmit, - }) - } - return dst -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/m4.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/m4.go deleted file mode 100644 index a92b92f6..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/m4.go +++ /dev/null @@ -1,339 +0,0 @@ -package matchfinder - -import ( - "bytes" - "encoding/binary" - "math/bits" - "runtime" -) - -// M4 is an implementation of the MatchFinder -// interface that uses a hash table to find matches, -// optional match chains, -// and the advanced parsing technique from -// https://fastcompression.blogspot.com/2011/12/advanced-parsing-strategies.html. -type M4 struct { - // MaxDistance is the maximum distance (in bytes) to look back for - // a match. The default is 65535. - MaxDistance int - - // MinLength is the length of the shortest match to return. - // The default is 4. - MinLength int - - // HashLen is the number of bytes to use to calculate the hashes. - // The maximum is 8 and the default is 6. - HashLen int - - // TableBits is the number of bits in the hash table indexes. - // The default is 17 (128K entries). - TableBits int - - // ChainLength is how many entries to search on the "match chain" of older - // locations with the same hash as the current location. - ChainLength int - - // DistanceBitCost is used when comparing two matches to see - // which is better. The comparison is primarily based on the length - // of the matches, but it can also take the distance into account, - // in terms of the number of bits needed to represent the distance. - // One byte of length is given a score of 256, so 32 (256/8) would - // be a reasonable first guess for the value of one bit. - // (The default is 0, which bases the comparison solely on length.) - DistanceBitCost int - - table []uint32 - chain []uint32 - - history []byte -} - -func (q *M4) Reset() { - for i := range q.table { - q.table[i] = 0 - } - q.history = q.history[:0] - q.chain = q.chain[:0] -} - -func (q *M4) score(m absoluteMatch) int { - return (m.End-m.Start)*256 + (bits.LeadingZeros32(uint32(m.Start-m.Match))-32)*q.DistanceBitCost -} - -func (q *M4) FindMatches(dst []Match, src []byte) []Match { - if q.MaxDistance == 0 { - q.MaxDistance = 65535 - } - if q.MinLength == 0 { - q.MinLength = 4 - } - if q.HashLen == 0 { - q.HashLen = 6 - } - if q.TableBits == 0 { - q.TableBits = 17 - } - if len(q.table) < 1< q.MaxDistance*2 { - // Trim down the history buffer. - delta := len(q.history) - q.MaxDistance - copy(q.history, q.history[delta:]) - q.history = q.history[:q.MaxDistance] - if q.ChainLength > 0 { - copy(q.chain, q.chain[delta:]) - q.chain = q.chain[:q.MaxDistance] - } - - for i, v := range q.table { - newV := int(v) - delta - if newV < 0 { - newV = 0 - } - q.table[i] = uint32(newV) - } - } - - // Append src to the history buffer. - e.NextEmit = len(q.history) - q.history = append(q.history, src...) - if q.ChainLength > 0 { - q.chain = append(q.chain, make([]uint32, len(src))...) - } - src = q.history - - // matches stores the matches that have been found but not emitted, - // in reverse order. (matches[0] is the most recent one.) - var matches [3]absoluteMatch - for i := e.NextEmit; i < len(src)-7; i++ { - if matches[0] != (absoluteMatch{}) && i >= matches[0].End { - // We have found some matches, and we're far enough along that we probably - // won't find overlapping matches, so we might as well emit them. - if matches[1] != (absoluteMatch{}) { - if matches[1].End > matches[0].Start { - matches[1].End = matches[0].Start - } - if matches[1].End-matches[1].Start >= q.MinLength && q.score(matches[1]) > 0 { - e.emit(matches[1]) - } - } - e.emit(matches[0]) - matches = [3]absoluteMatch{} - } - - // Look for a repeat match one byte after the current position. - if matches[0] == (absoluteMatch{}) && len(e.Dst) > 0 { - prevDistance := e.Dst[len(e.Dst)-1].Distance - if binary.LittleEndian.Uint32(src[i+1:]) == binary.LittleEndian.Uint32(src[i+1-prevDistance:]) { - // We have a 4-byte match. - m := extendMatch2(src, i+1, i+1-prevDistance, e.NextEmit+1) - if m.End-m.Start >= q.MinLength { - matches[0] = m - } - } - } - - // Calculate and store the hash. - h := ((binary.LittleEndian.Uint64(src[i:]) & (1<<(8*q.HashLen) - 1)) * hashMul64) >> (64 - q.TableBits) - candidate := int(q.table[h]) - q.table[h] = uint32(i) - if q.ChainLength > 0 && candidate != 0 { - delta := i - candidate - q.chain[i] = uint32(delta) - } - - if i < matches[0].End && i != matches[0].End+2-q.HashLen { - continue - } - if candidate == 0 || i-candidate > q.MaxDistance { - continue - } - - // Look for a match. - var currentMatch absoluteMatch - - if binary.LittleEndian.Uint32(src[candidate:]) == binary.LittleEndian.Uint32(src[i:]) { - m := extendMatch2(src, i, candidate, e.NextEmit) - if m.End-m.Start > q.MinLength && q.score(m) > 0 { - currentMatch = m - } - } - - for j := 0; j < q.ChainLength; j++ { - delta := q.chain[candidate] - if delta == 0 { - break - } - candidate -= int(delta) - if candidate <= 0 || i-candidate > q.MaxDistance { - break - } - if binary.LittleEndian.Uint32(src[candidate:]) == binary.LittleEndian.Uint32(src[i:]) { - m := extendMatch2(src, i, candidate, e.NextEmit) - if m.End-m.Start > q.MinLength && q.score(m) > q.score(currentMatch) { - currentMatch = m - } - } - } - - if currentMatch.End-currentMatch.Start < q.MinLength { - continue - } - - overlapPenalty := 0 - if matches[0] != (absoluteMatch{}) { - overlapPenalty = 275 - if currentMatch.Start <= matches[1].End { - // This match would completely replace the previous match, - // so there is no penalty for overlap. - overlapPenalty = 0 - } - } - - if q.score(currentMatch) <= q.score(matches[0])+overlapPenalty { - continue - } - - matches = [3]absoluteMatch{ - currentMatch, - matches[0], - matches[1], - } - - if matches[2] == (absoluteMatch{}) { - continue - } - - // We have three matches, so it's time to emit one and/or eliminate one. - switch { - case matches[0].Start < matches[2].End: - // The first and third matches overlap; discard the one in between. - matches = [3]absoluteMatch{ - matches[0], - matches[2], - absoluteMatch{}, - } - - case matches[0].Start < matches[2].End+q.MinLength: - // The first and third matches don't overlap, but there's no room for - // another match between them. Emit the first match and discard the second. - e.emit(matches[2]) - matches = [3]absoluteMatch{ - matches[0], - absoluteMatch{}, - absoluteMatch{}, - } - - default: - // Emit the first match, shortening it if necessary to avoid overlap with the second. - if matches[2].End > matches[1].Start { - matches[2].End = matches[1].Start - if q.ChainLength > 0 && matches[2].End-matches[2].Start >= q.MinLength { - // Since the match length was trimmed, we may be able to find a closer match - // to replace it. - pos := matches[2].Start - for { - delta := int(q.chain[pos]) - if delta == 0 { - break - } - pos -= delta - if pos <= matches[2].Match { - break - } - if bytes.Equal(src[matches[2].Start:matches[2].End], src[pos:pos+matches[2].End-matches[2].Start]) { - matches[2].Match = pos - break - } - } - } - } - if matches[2].End-matches[2].Start >= q.MinLength && q.score(matches[2]) > 0 { - e.emit(matches[2]) - } - matches[2] = absoluteMatch{} - } - } - - // We've found all the matches now; emit the remaining ones. - if matches[1] != (absoluteMatch{}) { - if matches[1].End > matches[0].Start { - matches[1].End = matches[0].Start - } - if matches[1].End-matches[1].Start >= q.MinLength && q.score(matches[1]) > 0 { - e.emit(matches[1]) - } - } - if matches[0] != (absoluteMatch{}) { - e.emit(matches[0]) - } - - dst = e.Dst - if e.NextEmit < len(src) { - dst = append(dst, Match{ - Unmatched: len(src) - e.NextEmit, - }) - } - - return dst -} - -const hashMul64 = 0x1E35A7BD1E35A7BD - -// extendMatch returns the largest k such that k <= len(src) and that -// src[i:i+k-j] and src[j:k] have the same contents. -// -// It assumes that: -// -// 0 <= i && i < j && j <= len(src) -func extendMatch(src []byte, i, j int) int { - switch runtime.GOARCH { - case "amd64", "arm64": - // As long as we are 8 or more bytes before the end of src, we can load and - // compare 8 bytes at a time. If those 8 bytes are equal, repeat. - for j+8 < len(src) { - iBytes := binary.LittleEndian.Uint64(src[i:]) - jBytes := binary.LittleEndian.Uint64(src[j:]) - if iBytes != jBytes { - // If those 8 bytes were not equal, XOR the two 8 byte values, and return - // the index of the first byte that differs. The BSF instruction finds the - // least significant 1 bit, the amd64 architecture is little-endian, and - // the shift by 3 converts a bit index to a byte index. - return j + bits.TrailingZeros64(iBytes^jBytes)>>3 - } - i, j = i+8, j+8 - } - case "386": - // On a 32-bit CPU, we do it 4 bytes at a time. - for j+4 < len(src) { - iBytes := binary.LittleEndian.Uint32(src[i:]) - jBytes := binary.LittleEndian.Uint32(src[j:]) - if iBytes != jBytes { - return j + bits.TrailingZeros32(iBytes^jBytes)>>3 - } - i, j = i+4, j+4 - } - } - for ; j < len(src) && src[i] == src[j]; i, j = i+1, j+1 { - } - return j -} - -// Given a 4-byte match at src[start] and src[candidate], extendMatch2 extends it -// upward as far as possible, and downward no farther than to min. -func extendMatch2(src []byte, start, candidate, min int) absoluteMatch { - end := extendMatch(src, candidate+4, start+4) - for start > min && candidate > 0 && src[start-1] == src[candidate-1] { - start-- - candidate-- - } - return absoluteMatch{ - Start: start, - End: end, - Match: candidate, - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/matchfinder.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/matchfinder.go deleted file mode 100644 index f6bcfdb3..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/matchfinder.go +++ /dev/null @@ -1,103 +0,0 @@ -// The matchfinder package defines reusable components for data compression. -// -// Many compression libraries have two main parts: -// - Something that looks for repeated sequences of bytes -// - An encoder for the compressed data format (often an entropy coder) -// -// Although these are logically two separate steps, the implementations are -// usually closely tied together. You can't use flate's matcher with snappy's -// encoder, for example. This package defines interfaces and an intermediate -// representation to allow mixing and matching compression components. -package matchfinder - -import "io" - -// A Match is the basic unit of LZ77 compression. -type Match struct { - Unmatched int // the number of unmatched bytes since the previous match - Length int // the number of bytes in the matched string; it may be 0 at the end of the input - Distance int // how far back in the stream to copy from -} - -// A MatchFinder performs the LZ77 stage of compression, looking for matches. -type MatchFinder interface { - // FindMatches looks for matches in src, appends them to dst, and returns dst. - FindMatches(dst []Match, src []byte) []Match - - // Reset clears any internal state, preparing the MatchFinder to be used with - // a new stream. - Reset() -} - -// An Encoder encodes the data in its final format. -type Encoder interface { - // Encode appends the encoded format of src to dst, using the match - // information from matches. - Encode(dst []byte, src []byte, matches []Match, lastBlock bool) []byte - - // Reset clears any internal state, preparing the Encoder to be used with - // a new stream. - Reset() -} - -// A Writer uses MatchFinder and Encoder to write compressed data to Dest. -type Writer struct { - Dest io.Writer - MatchFinder MatchFinder - Encoder Encoder - - // BlockSize is the number of bytes to compress at a time. If it is zero, - // each Write operation will be treated as one block. - BlockSize int - - err error - inBuf []byte - outBuf []byte - matches []Match -} - -func (w *Writer) Write(p []byte) (n int, err error) { - if w.err != nil { - return 0, w.err - } - - if w.BlockSize == 0 { - return w.writeBlock(p, false) - } - - w.inBuf = append(w.inBuf, p...) - var pos int - for pos = 0; pos+w.BlockSize <= len(w.inBuf) && w.err == nil; pos += w.BlockSize { - w.writeBlock(w.inBuf[pos:pos+w.BlockSize], false) - } - if pos > 0 { - n := copy(w.inBuf, w.inBuf[pos:]) - w.inBuf = w.inBuf[:n] - } - - return len(p), w.err -} - -func (w *Writer) writeBlock(p []byte, lastBlock bool) (n int, err error) { - w.outBuf = w.outBuf[:0] - w.matches = w.MatchFinder.FindMatches(w.matches[:0], p) - w.outBuf = w.Encoder.Encode(w.outBuf, p, w.matches, lastBlock) - _, w.err = w.Dest.Write(w.outBuf) - return len(p), w.err -} - -func (w *Writer) Close() error { - w.writeBlock(w.inBuf, true) - w.inBuf = w.inBuf[:0] - return w.err -} - -func (w *Writer) Reset(newDest io.Writer) { - w.MatchFinder.Reset() - w.Encoder.Reset() - w.err = nil - w.inBuf = w.inBuf[:0] - w.outBuf = w.outBuf[:0] - w.matches = w.matches[:0] - w.Dest = newDest -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/pathfinder.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/pathfinder.go deleted file mode 100644 index 2a12ab9d..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/pathfinder.go +++ /dev/null @@ -1,328 +0,0 @@ -package matchfinder - -import ( - "encoding/binary" - "math" - "math/bits" - "slices" -) - -// Pathfinder is a MatchFinder that uses hash chains to find matches, and a -// shortest-path optimizer to choose which matches to use. -type Pathfinder struct { - // MaxDistance is the maximum distance (in bytes) to look back for - // a match. The default is 65535. - MaxDistance int - - // MinLength is the length of the shortest match to return. - // The default is 4. - MinLength int - - // HashLen is the number of bytes to use to calculate the hashes. - // The maximum is 8 and the default is 6. - HashLen int - - // TableBits is the number of bits in the hash table indexes. - // The default is 17 (128K entries). - TableBits int - - // ChainLength is how many entries to search on the "match chain" of older - // locations with the same hash as the current location. - ChainLength int - - table []uint32 - chain []uint32 - - history []byte - - // holding onto buffers to reduce allocations: - - arrivals []arrival - foundMatches []absoluteMatch - matches []Match -} - -func (q *Pathfinder) Reset() { - for i := range q.table { - q.table[i] = 0 - } - q.history = q.history[:0] - q.chain = q.chain[:0] -} - -// An arrival represents how we got to a certain byte position. -// The cost is the total cost to get there from the beginning of the block. -// If distance > 0, the arrival is with a match. -// If distance == 0, the arrival is with a run of literals. -type arrival struct { - length uint32 - distance uint32 - cost float32 -} - -const ( - baseMatchCost float32 = 4 -) - -func (q *Pathfinder) FindMatches(dst []Match, src []byte) []Match { - if q.MaxDistance == 0 { - q.MaxDistance = 65535 - } - if q.MinLength == 0 { - q.MinLength = 4 - } - if q.HashLen == 0 { - q.HashLen = 6 - } - if q.TableBits == 0 { - q.TableBits = 17 - } - if len(q.table) < 1< q.MaxDistance*2 { - // Trim down the history buffer. - delta := len(q.history) - q.MaxDistance - copy(q.history, q.history[delta:]) - q.history = q.history[:q.MaxDistance] - q.chain = q.chain[:q.MaxDistance] - - for i, v := range q.table { - newV := max(int(v)-delta, 0) - q.table[i] = uint32(newV) - } - } - - // Append src to the history buffer. - historyLen := len(q.history) - q.history = append(q.history, src...) - q.chain = append(q.chain, make([]uint32, len(src))...) - src = q.history - - // Calculate hashes and build the chain. - for i := historyLen; i < len(src)-7; i++ { - h := ((binary.LittleEndian.Uint64(src[i:]) & (1<<(8*q.HashLen) - 1)) * hashMul64) >> (64 - q.TableBits) - candidate := int(q.table[h]) - q.table[h] = uint32(i) - if candidate != 0 { - delta := i - candidate - q.chain[i] = uint32(delta) - } - } - - // Look for matches, and collect them in foundMatches. Later we'll figure out - // which ones to actually use. - foundMatches := q.foundMatches[:0] - var prevMatch absoluteMatch - i := historyLen - for i < len(src)-7 { - delta := q.chain[i] - if delta == 0 { - i++ - continue - } - candidate := i - int(delta) - if candidate <= 0 || i-candidate > q.MaxDistance { - i++ - continue - } - - var currentMatch absoluteMatch - - if i >= prevMatch.End && prevMatch != (absoluteMatch{}) { - // Look for a repeat match at i+1. - prevDistance := prevMatch.Start - prevMatch.Match - if binary.LittleEndian.Uint32(src[i+1:]) == binary.LittleEndian.Uint32(src[i+1-prevDistance:]) { - m := extendMatch2(src, i+1, i+1-prevDistance, i+1) - if m.End-m.Start > q.MinLength { - currentMatch = m - foundMatches = append(foundMatches, m) - } - } - } - - if binary.LittleEndian.Uint32(src[candidate:]) == binary.LittleEndian.Uint32(src[i:]) { - m := extendMatch2(src, i, candidate, max(historyLen, prevMatch.Start)) - if m.End-m.Start > q.MinLength { - currentMatch = m - foundMatches = append(foundMatches, m) - } - } - - for range q.ChainLength { - delta := q.chain[candidate] - if delta == 0 { - break - } - candidate -= int(delta) - if candidate <= 0 || i-candidate > q.MaxDistance { - break - } - if binary.LittleEndian.Uint32(src[candidate:]) == binary.LittleEndian.Uint32(src[i:]) { - m := extendMatch2(src, i, candidate, max(historyLen, prevMatch.Start)) - if m.End-m.Start > q.MinLength && m.End-m.Start > currentMatch.End-currentMatch.Start { - currentMatch = m - foundMatches = append(foundMatches, m) - } - } - } - - if i < prevMatch.End && currentMatch.End-currentMatch.Start <= prevMatch.End-prevMatch.Start { - // We were looking for an overlapping match, but we didn't find one longer - // than the previous match. So we'll go back to sequential search, - // starting right after the previous match. - i = prevMatch.End - continue - } - - if currentMatch == (absoluteMatch{}) { - // No match found. Continue with sequential search. - i++ - continue - } - - // We've found a match; now look for matches overlapping the end of it. - prevMatch = currentMatch - i = currentMatch.End + 2 - q.HashLen - } - - q.foundMatches = foundMatches - - slices.SortFunc(foundMatches, func(a, b absoluteMatch) int { return a.Start - b.Start }) - matchIndex := 0 - var pending absoluteMatch - - for i := historyLen; i < len(src); i++ { - var arrivedHere arrival - if i > historyLen { - arrivedHere = arrivals[i-historyLen-1] - } - - unmatched := 0 - if arrivedHere.distance == 0 { - unmatched = int(arrivedHere.length) - } - prevDistance := 0 - if i-unmatched > historyLen { - prevDistance = int(arrivals[i-historyLen-1-unmatched].distance) - } - - literalCost := byteCost[src[i]] - nextArrival := &arrivals[i-historyLen] - if nextArrival.cost == 0 || arrivedHere.cost+literalCost < nextArrival.cost { - *nextArrival = arrival{ - cost: arrivedHere.cost + literalCost, - length: uint32(unmatched + 1), - } - } - - for matchIndex < len(foundMatches) && foundMatches[matchIndex].Start == i { - m := foundMatches[matchIndex] - matchIndex++ - if m.End > pending.End { - pending = m - } - matchCost := baseMatchCost + float32(bits.Len(uint(unmatched))) - if m.Start-m.Match != prevDistance { - matchCost += float32(bits.Len(uint(m.Start - m.Match))) - } - for j := m.Start + q.MinLength; j <= m.End; j++ { - adjustedCost := matchCost - if j-m.Start < 6 { - // Matches shorter than 6 are comparatively rare, and therefore - // have longer codes. - adjustedCost += float32(6-(j-m.Start)) * 2 - } - a := &arrivals[j-historyLen-1] - if a.cost == 0 || arrivedHere.cost+adjustedCost < a.cost { - *a = arrival{ - length: uint32(j - m.Start), - distance: uint32(m.Start - m.Match), - cost: arrivedHere.cost + adjustedCost, - } - } - } - } - - // If a match from an earlier position extends far enough past the current - // position, try using the tail of it, starting from here. - if unmatched == 0 && pending.Start != i && pending.End >= i+q.MinLength && - !(arrivedHere.length != 0 && arrivedHere.distance == uint32(pending.Start-pending.Match)) { - matchCost := baseMatchCost + float32(bits.Len(uint(pending.Start-pending.Match))) - for j := i + q.MinLength; j <= pending.End; j++ { - adjustedCost := matchCost - if j-i < 6 { - // Matches shorter than 6 are comparatively rare, and therefore - // have longer codes. - adjustedCost += float32(6-(j-i)) * 2 - } - a := &arrivals[j-historyLen-1] - if a.cost == 0 || arrivedHere.cost+adjustedCost < a.cost { - *a = arrival{ - length: uint32(j - i), - distance: uint32(pending.Start - pending.Match), - cost: arrivedHere.cost + adjustedCost, - } - } - } - } - - delta := q.chain[i] - if delta == 0 { - continue - } - candidate := i - int(delta) - if candidate <= 0 || i-candidate > q.MaxDistance { - continue - } - } - - // We've found the shortest path; now walk it backward and store the matches. - matches := q.matches[:0] - i = len(arrivals) - 1 - for i >= 0 { - a := arrivals[i] - if a.distance > 0 { - matches = append(matches, Match{ - Length: int(a.length), - Distance: int(a.distance), - }) - i -= int(a.length) - } else { - if len(matches) == 0 { - matches = append(matches, Match{}) - } - matches[len(matches)-1].Unmatched = int(a.length) - i -= int(a.length) - } - } - q.matches = matches - - slices.Reverse(matches) - - return append(dst, matches...) -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/textencoder.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/textencoder.go deleted file mode 100644 index 75ecc590..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/textencoder.go +++ /dev/null @@ -1,53 +0,0 @@ -package matchfinder - -import "fmt" - -// A TextEncoder is an Encoder that produces a human-readable representation of -// the LZ77 compression. Matches are replaced with symbols. -type TextEncoder struct{} - -func (t TextEncoder) Reset() {} - -func (t TextEncoder) Encode(dst []byte, src []byte, matches []Match, lastBlock bool) []byte { - pos := 0 - for _, m := range matches { - if m.Unmatched > 0 { - dst = append(dst, src[pos:pos+m.Unmatched]...) - pos += m.Unmatched - } - if m.Length > 0 { - dst = append(dst, []byte(fmt.Sprintf("<%d,%d>", m.Length, m.Distance))...) - pos += m.Length - } - } - if pos < len(src) { - dst = append(dst, src[pos:]...) - } - return dst -} - -// A NoMatchFinder implements MatchFinder, but doesn't find any matches. -// It can be used to implement the equivalent of the standard library flate package's -// HuffmanOnly setting. -type NoMatchFinder struct{} - -func (n NoMatchFinder) Reset() {} - -func (n NoMatchFinder) FindMatches(dst []Match, src []byte) []Match { - return append(dst, Match{ - Unmatched: len(src), - }) -} - -// AutoReset wraps a MatchFinder that can return references to data in previous -// blocks, and calls Reset before each block. It is useful for (e.g.) using a -// snappy Encoder with a MatchFinder designed for flate. (Snappy doesn't -// support references between blocks.) -type AutoReset struct { - MatchFinder -} - -func (a AutoReset) FindMatches(dst []Match, src []byte) []Match { - a.Reset() - return a.MatchFinder.FindMatches(dst, src) -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/trio.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/trio.go deleted file mode 100644 index cb33e64a..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/trio.go +++ /dev/null @@ -1,326 +0,0 @@ -package matchfinder - -import "encoding/binary" - -// Trio is a MatchFinder that uses 3 different hash lengths, and -// overlap parsing. -type Trio struct { - MaxDistance int - history []byte - table5 [1 << 16]tableEntry - table8 [1 << 17]tableEntry - table12 [1 << 18]tableEntry -} - -func (z *Trio) Reset() { - z.table5 = [len(z.table5)]tableEntry{} - z.table8 = [len(z.table8)]tableEntry{} - z.table12 = [len(z.table12)]tableEntry{} - z.history = z.history[:0] -} - -func (z *Trio) FindMatches(dst []Match, src []byte) []Match { - if z.MaxDistance == 0 { - z.MaxDistance = 1 << 16 - } - - if len(z.history) > z.MaxDistance*2 { - delta := len(z.history) - z.MaxDistance - copy(z.history, z.history[delta:]) - z.history = z.history[:z.MaxDistance] - - for i := range z.table5 { - v := z.table5[i].offset - v -= int32(delta) - if v < 0 { - z.table5[i] = tableEntry{} - } else { - z.table5[i].offset = v - } - } - for i := range z.table8 { - v := z.table8[i].offset - v -= int32(delta) - if v < 0 { - z.table8[i] = tableEntry{} - } else { - z.table8[i].offset = v - } - } - for i := range z.table12 { - v := z.table12[i].offset - v -= int32(delta) - if v < 0 { - z.table12[i] = tableEntry{} - } else { - z.table12[i].offset = v - } - } - } - - if len(src) < 20 { - return append(dst, Match{ - Unmatched: len(src), - }) - } - - e := matchEmitter{ - Dst: dst, - NextEmit: len(z.history), - } - z.history = append(z.history, src...) - src = z.history - - // matches stores the matches that have been found but not emitted, - // in reverse order. (matches[0] is the most recent one.) - var matches [3]absoluteMatch - - sLimit := int32(len(src)) - 14 - -mainLoop: - for { - // Search for a match, starting after the last match emitted. - s := int32(e.NextEmit) - if s > sLimit { - break mainLoop - } - - // t will contain the match offset when we find one. - var t int32 - var hashLengthFound int - - cv := binary.LittleEndian.Uint64(src[s:]) - extra := binary.LittleEndian.Uint32(src[s+8:]) - - for { - nextHash12 := z.hash12(cv, extra) - nextHash8 := z.hash8(cv) - nextHash5 := z.hash5(cv) - candidate12 := z.table12[nextHash12] - candidate8 := z.table8[nextHash8] - candidate5 := z.table5[nextHash5] - - entry := tableEntry{offset: s, val: uint32(cv)} - z.table12[nextHash12] = entry - z.table8[nextHash8] = entry - z.table5[nextHash5] = entry - - // Look for a repeat match one byte after the current position. - if len(e.Dst) > 0 { - prevDistance := int32(e.Dst[len(e.Dst)-1].Distance) - if prevDistance != 0 { - repIndex := s - prevDistance + 1 - if repIndex >= 0 && binary.LittleEndian.Uint32(src[repIndex:]) == uint32(cv>>8) { - // There is a repeated match at s+2. - s++ - t = repIndex - break - } - } - } - - if candidate12.offset < s && s-candidate12.offset < int32(z.MaxDistance) && uint32(cv) == candidate12.val && - binary.LittleEndian.Uint32(src[candidate12.offset:]) == uint32(cv) { - // There is a 12-byte match at s. - t = candidate12.offset - hashLengthFound = 12 - break - } - if candidate8.offset < s && s-candidate8.offset < int32(z.MaxDistance) && uint32(cv) == candidate8.val && - binary.LittleEndian.Uint32(src[candidate8.offset:]) == uint32(cv) { - t = candidate8.offset - hashLengthFound = 8 - break - } - if candidate5.offset < s && s-candidate5.offset < int32(z.MaxDistance) && uint32(cv) == candidate5.val && - binary.LittleEndian.Uint32(src[candidate5.offset:]) == uint32(cv) { - t = candidate5.offset - hashLengthFound = 5 - break - } - - s += 1 + ((s - int32(e.NextEmit)) >> 7) - if s > sLimit { - break mainLoop - } - cv = binary.LittleEndian.Uint64(src[s:]) - extra = binary.LittleEndian.Uint32(src[s+8:]) - } - - if hashLengthFound != 0 && hashLengthFound < 12 { - // Look for a "lazy" match with a longer hash at s+1. - cv := binary.LittleEndian.Uint64(src[s+1:]) - extra := binary.LittleEndian.Uint32(src[s+9:]) - nextHash12 := z.hash12(cv, extra) - nextHash8 := z.hash8(cv) - candidate12 := z.table12[nextHash12] - candidate8 := z.table8[nextHash8] - coffset12 := s - candidate12.offset + 1 - coffset8 := s - candidate8.offset + 1 - entry := tableEntry{offset: s + 1, val: uint32(cv)} - z.table12[nextHash12] = entry - z.table8[nextHash8] = entry - if candidate12.offset < s+1 && coffset12 < int32(z.MaxDistance) && uint32(cv) == candidate12.val && - binary.LittleEndian.Uint32(src[candidate12.offset:]) == uint32(cv) { - t = candidate12.offset - s++ - } else if hashLengthFound < 8 && candidate8.offset < s+1 && coffset8 < int32(z.MaxDistance) && uint32(cv) == candidate8.val && - binary.LittleEndian.Uint32(src[candidate8.offset:]) == uint32(cv) { - t = candidate8.offset - s++ - } - } - - currentMatch := extendMatch2(src, int(s), int(t), e.NextEmit) - matches[0] = currentMatch - - index0 := s + 1 - - // We have a match in matches[0]. - // Now look for overlapping matches. - - for { - if matches[0].End > int(sLimit) { - break - } - s = int32(max(matches[0].Start+2, matches[0].End-10)) - - // Store some entries that haven't been indexed yet. - for index0 < s-1 { - cv0 := binary.LittleEndian.Uint64(src[index0:]) - extra0 := binary.LittleEndian.Uint32(src[index0+8:]) - te0 := tableEntry{offset: index0, val: uint32(cv0)} - z.table5[z.hash5(cv0)] = te0 - z.table8[z.hash8(cv0)] = te0 - z.table12[z.hash12(cv0, extra0)] = te0 - index0++ - } - - cv = binary.LittleEndian.Uint64(src[s:]) - extra = binary.LittleEndian.Uint32(src[s+8:]) - - nextHash12 := z.hash12(cv, extra) - nextHash8 := z.hash8(cv) - nextHash5 := z.hash5(cv) - candidate12 := z.table12[nextHash12] - candidate8 := z.table8[nextHash8] - - entry := tableEntry{offset: s, val: uint32(cv)} - z.table12[nextHash12] = entry - z.table8[nextHash8] = entry - z.table5[nextHash5] = entry - - t = -1 - if candidate12.offset < s && s-candidate12.offset < int32(z.MaxDistance) && uint32(cv) == candidate12.val && - binary.LittleEndian.Uint32(src[candidate12.offset:]) == uint32(cv) { - // There is a 12-byte match at s. - t = candidate12.offset - } else if candidate8.offset < s && s-candidate8.offset < int32(z.MaxDistance) && uint32(cv) == candidate8.val && - binary.LittleEndian.Uint32(src[candidate8.offset:]) == uint32(cv) { - // There is a long match at s. - t = candidate8.offset - } - - index0 = s + 1 - - if t == -1 { - // No overlapping match was found. - break - } - - newMatch := extendMatch2(src, int(s), int(t), e.NextEmit) - - if newMatch.End-newMatch.Start <= matches[0].End-matches[0].Start { - // The new match isn't longer than the old one, so we break out of the loop - // of looking for overlapping matches. - break - } - - matches = [3]absoluteMatch{ - newMatch, - matches[0], - matches[1], - } - - if matches[2] == (absoluteMatch{}) { - continue - } - - // We have three matches, so it's time to emit one and/or eliminate one. - switch { - case matches[0].Start < matches[2].End: - // The first and third matches overlap; discard the one in between. - matches = [3]absoluteMatch{ - matches[0], - matches[2], - {}, - } - - case matches[0].Start < matches[2].End+4: - // The first and third matches don't overlap, but there's no room for - // another match between them. Emit the first match and discard the second. - e.emit(matches[2]) - matches = [3]absoluteMatch{ - matches[0], - {}, - {}, - } - - default: - // Emit the first match, shortening it if necessary to avoid overlap with the second. - if matches[2].End > matches[1].Start { - matches[2].End = matches[1].Start - } - if matches[2].End-matches[2].Start >= 4 { - e.emit(matches[2]) - } - matches[2] = absoluteMatch{} - } - } - - // Store some entries up to the end of the last match. - for index0 < int32(matches[0].End) && index0 < sLimit { - cv0 := binary.LittleEndian.Uint64(src[index0:]) - extra0 := binary.LittleEndian.Uint32(src[index0+8:]) - te0 := tableEntry{offset: index0, val: uint32(cv0)} - z.table5[z.hash5(cv0)] = te0 - z.table8[z.hash8(cv0)] = te0 - z.table12[z.hash12(cv0, extra0)] = te0 - index0++ - } - - // We're done looking for overlapping matches; emit the ones we have. - - if matches[1] != (absoluteMatch{}) { - if matches[1].End > matches[0].Start { - matches[1].End = matches[0].Start - } - if matches[1].End-matches[1].Start >= 4 { - e.emit(matches[1]) - } - } - e.emit(matches[0]) - matches = [3]absoluteMatch{} - } - - dst = e.Dst - if e.NextEmit < len(src) { - dst = append(dst, Match{ - Unmatched: len(src) - e.NextEmit, - }) - } - - return dst -} - -func (z *Trio) hash5(u uint64) uint32 { - return uint32(((u << 24) * 889523592379) >> (64 - 16)) -} - -func (z *Trio) hash8(u uint64) uint32 { - return uint32((u * 0xcf1bbcdcb7a56463) >> (64 - 17)) -} - -func (z *Trio) hash12(u uint64, e uint32) uint32 { - return uint32((u*0xcf1bbcdcb7a56463 + uint64(e)*(2654435761<<32)) >> (64 - 18)) -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/zdfast.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/zdfast.go deleted file mode 100644 index 6890409b..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/zdfast.go +++ /dev/null @@ -1,258 +0,0 @@ -package matchfinder - -import ( - "encoding/binary" - "math" -) - -const ( - zdfastLongTableBits = 17 - zdfastLongTableSize = 1 << zdfastLongTableBits -) - -// ZDFast is a MatchFinder based on the "Default" setting in -// github.com/klauspost/compress/zstd. -type ZDFast struct { - MaxDistance int - - history []byte - // current is the offset at the start of history - current int32 - table [zfastTableSize]tableEntry - longTable [zdfastLongTableSize]tableEntry -} - -func (z *ZDFast) Reset() { - z.current = 0 - z.table = [zfastTableSize]tableEntry{} - z.longTable = [zdfastLongTableSize]tableEntry{} - z.history = z.history[:0] -} - -func (z *ZDFast) FindMatches(dst []Match, src []byte) []Match { - if z.MaxDistance == 0 { - z.MaxDistance = 1 << 16 - } - - // Protect against overflow of current. - if int(z.current) >= int(math.MaxInt32)-2*z.MaxDistance-len(z.history) { - minOffset := z.current + int32(len(z.history)) - int32(z.MaxDistance) - for i := range z.table { - v := z.table[i].offset - if v < minOffset { - v = 0 - } else { - v = v - z.current + int32(z.MaxDistance) - } - z.table[i].offset = v - } - for i := range z.longTable { - v := z.longTable[i].offset - if v < minOffset { - v = 0 - } else { - v = v - z.current + int32(z.MaxDistance) - } - z.longTable[i].offset = v - } - z.current = int32(z.MaxDistance) - } - - if len(z.history)+len(src) > cap(z.history) { - // history doesn't have enough capacity to hold the new block. - if cap(z.history) == 0 { - historySize := max(2*z.MaxDistance, 1<<20, len(src)) - z.history = make([]byte, 0, historySize) - } else { - // Move down - offset := len(z.history) - z.MaxDistance - copy(z.history[:z.MaxDistance], z.history[offset:]) - z.current += int32(offset) - z.history = z.history[:z.MaxDistance] - } - } - s := int32(len(z.history)) - z.history = append(z.history, src...) - - if len(src) < 16 { - return append(dst, Match{ - Unmatched: len(src), - }) - } - - src = z.history - sLimit := int32(len(src)) - 10 - - const stepSize = 1 - - nextEmit := s - cv := binary.LittleEndian.Uint64(src[s:]) - var offset1, offset2 int32 - -mainLoop: - for { - // t will contain the match offset when we find one. - // When exiting the search loop, we have already checked 4 bytes. - var t int32 - - for { - nextHashL := z.hashLong(cv) - nextHashS := z.hashShort(cv) - candidateL := z.longTable[nextHashL] - candidateS := z.table[nextHashS] - - repIndex := s - offset1 + 1 - - entry := tableEntry{offset: s + z.current, val: uint32(cv)} - z.longTable[nextHashL] = entry - z.table[nextHashS] = entry - - if offset1 != 0 && repIndex >= 0 && binary.LittleEndian.Uint32(src[repIndex:]) == uint32(cv>>8) { - // There is a repeated match at s+1. - end := extendMatch(src, int(repIndex+4), int(s+5)) - start := s + 1 - for repIndex > 0 && start > nextEmit && src[repIndex-1] == src[start-1] { - repIndex-- - start-- - } - - dst = append(dst, Match{ - Unmatched: int(start - nextEmit), - Length: end - int(start), - Distance: int(start - repIndex), - }) - s = int32(end) - nextEmit = s - if s >= sLimit { - break mainLoop - } - cv = binary.LittleEndian.Uint64(src[s:]) - continue - } - - coffsetL := s - (candidateL.offset - z.current) - coffsetS := s - (candidateS.offset - z.current) - if coffsetL < int32(z.MaxDistance) && uint32(cv) == candidateL.val { - t = candidateL.offset - z.current - if binary.LittleEndian.Uint32(src[t:]) == uint32(cv) { - // found a long match (likely at least 8 bytes) - break - } - } - if coffsetS < int32(z.MaxDistance) && uint32(cv) == candidateS.val { - t = candidateS.offset - z.current - if binary.LittleEndian.Uint32(src[t:]) != uint32(cv) { - goto noMatch - } - // Found a regular match. - // See if we can find a long match at s+1 - cv := binary.LittleEndian.Uint64(src[s+1:]) - nextHashL = z.hashLong(cv) - candidateL = z.longTable[nextHashL] - coffsetL = s - (candidateL.offset - z.current) + 1 - z.longTable[nextHashL] = tableEntry{offset: s + 1 + z.current, val: uint32(cv)} - if coffsetL < int32(z.MaxDistance) && uint32(cv) == candidateL.val { - t = candidateL.offset - z.current - if binary.LittleEndian.Uint32(src[t:]) == uint32(cv) { - // We found a long match at s+1, so we'll use that instead - // of the regular match at s. - s++ - break - } - } - - t = candidateS.offset - z.current - break - } - noMatch: - - s += stepSize + ((s - nextEmit) >> 7) - if s > sLimit { - break mainLoop - } - cv = binary.LittleEndian.Uint64(src[s:]) - } - - // A 4-byte match has been found. We'll later see if more than - // 4 bytes. - offset2 = offset1 - offset1 = s - t - - end := extendMatch(src, int(t+4), int(s+4)) - for t > 0 && s > nextEmit && src[t-1] == src[s-1] { - s-- - t-- - } - - dst = append(dst, Match{ - Unmatched: int(s - nextEmit), - Length: end - int(s), - Distance: int(s - t), - }) - prevS := s - s = int32(end) - nextEmit = s - if s >= sLimit { - break mainLoop - } - - // Store some table entries near the start and end of the match. - index0 := prevS + 1 - index1 := s - 2 - cv0 := binary.LittleEndian.Uint64(src[index0:]) - cv1 := binary.LittleEndian.Uint64(src[index1:]) - te0 := tableEntry{offset: index0 + z.current, val: uint32(cv0)} - te1 := tableEntry{offset: index1 + z.current, val: uint32(cv1)} - z.longTable[z.hashLong(cv0)] = te0 - z.longTable[z.hashLong(cv1)] = te1 - cv0 >>= 8 - cv1 >>= 8 - te0.offset++ - te1.offset++ - te0.val = uint32(cv0) - te1.val = uint32(cv1) - z.table[z.hashShort(cv0)] = te0 - z.table[z.hashShort(cv1)] = te1 - - cv = binary.LittleEndian.Uint64(src[s:]) - - // Check offset 2 - if o2 := s - offset2; offset2 != 0 && binary.LittleEndian.Uint32(src[o2:]) == uint32(cv) { - end := extendMatch(src, int(o2+4), int(s+4)) - - // Store the hashes, since we have them. - nextHashS := z.hashShort(cv) - nextHashL := z.hashLong(cv) - entry := tableEntry{offset: s + z.current, val: uint32(cv)} - z.table[nextHashS] = entry - z.longTable[nextHashL] = entry - dst = append(dst, Match{ - Length: end - int(s), - Distance: int(offset2), - }) - s = int32(end) - nextEmit = s - offset1, offset2 = offset2, offset1 - if s >= sLimit { - break mainLoop - } - cv = binary.LittleEndian.Uint64(src[s:]) - } - } - - if int(nextEmit) < len(src) { - dst = append(dst, Match{ - Unmatched: len(src) - int(nextEmit), - }) - } - - return dst -} - -func (z *ZDFast) hashShort(u uint64) uint32 { - return uint32(((u << 24) * 889523592379) >> (64 - zfastTableBits)) -} - -func (z *ZDFast) hashLong(u uint64) uint32 { - return uint32((u * 0xcf1bbcdcb7a56463) >> (64 - zdfastLongTableBits)) -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/zfast.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/zfast.go deleted file mode 100644 index 6f2ad8d0..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/zfast.go +++ /dev/null @@ -1,206 +0,0 @@ -package matchfinder - -import ( - "encoding/binary" - "math" -) - -type tableEntry struct { - val uint32 - offset int32 -} - -const ( - zfastTableBits = 15 - zfastTableSize = 1 << zfastTableBits - zfastHashLen = 6 - - prime6Bytes = 227718039650203 -) - -// ZFast is a MatchFinder based on the "Fastest" setting in -// github.com/klauspost/compress/zstd. -type ZFast struct { - MaxDistance int - - history []byte - // current is the offset at the start of history - current int32 - table [zfastTableSize]tableEntry -} - -func (z *ZFast) Reset() { - z.current = 0 - z.table = [zfastTableSize]tableEntry{} - z.history = z.history[:0] -} - -func (z *ZFast) FindMatches(dst []Match, src []byte) []Match { - if z.MaxDistance == 0 { - z.MaxDistance = 1 << 16 - } - - // Protect against overflow of current. - if int(z.current) >= int(math.MaxInt32)-2*z.MaxDistance-len(z.history) { - minOffset := z.current + int32(len(z.history)) - int32(z.MaxDistance) - for i := range z.table { - v := z.table[i].offset - if v < minOffset { - v = 0 - } else { - v = v - z.current + int32(z.MaxDistance) - } - z.table[i].offset = v - } - z.current = int32(z.MaxDistance) - } - - if len(z.history)+len(src) > cap(z.history) { - // history doesn't have enough capacity to hold the new block. - if cap(z.history) == 0 { - historySize := max(2*z.MaxDistance, 1<<20, len(src)) - z.history = make([]byte, 0, historySize) - } else { - // Move down - offset := len(z.history) - z.MaxDistance - copy(z.history[:z.MaxDistance], z.history[offset:]) - z.current += int32(offset) - z.history = z.history[:z.MaxDistance] - } - } - s := int32(len(z.history)) - z.history = append(z.history, src...) - - if len(src) < 10 { - return append(dst, Match{ - Unmatched: len(src), - }) - } - - src = z.history - sLimit := int32(len(src)) - 8 - - const stepSize = 2 - - nextEmit := s - cv := binary.LittleEndian.Uint64(src[s:]) - var offset1, offset2 int32 - -mainLoop: - for { - // t will contain the match offset when we find one. - // When exiting the search loop, we have already checked 4 bytes. - var t int32 - - for { - nextHash := z.hash(cv) - nextHash2 := z.hash(cv >> 8) - candidate := z.table[nextHash] - candidate2 := z.table[nextHash2] - repIndex := s - offset1 + 2 - - z.table[nextHash] = tableEntry{offset: s + z.current, val: uint32(cv)} - z.table[nextHash2] = tableEntry{offset: s + z.current + 1, val: uint32(cv >> 8)} - - if offset1 != 0 && repIndex >= 0 && binary.LittleEndian.Uint32(src[repIndex:]) == uint32(cv>>16) { - // There is a repeated match at s+2. - end := extendMatch(src, int(repIndex+4), int(s+6)) - start := s + 2 - for repIndex > 0 && start > nextEmit && src[repIndex-1] == src[start-1] { - repIndex-- - start-- - } - dst = append(dst, Match{ - Unmatched: int(start - nextEmit), - Length: end - int(start), - Distance: int(start - repIndex), - }) - s = int32(end) - nextEmit = s - if s >= sLimit { - break mainLoop - } - cv = binary.LittleEndian.Uint64(src[s:]) - continue - } - - coffset0 := s - (candidate.offset - z.current) - coffset1 := s - (candidate2.offset - z.current) + 1 - if coffset0 < int32(z.MaxDistance) && uint32(cv) == candidate.val { - t = candidate.offset - z.current - if binary.LittleEndian.Uint32(src[t:]) == uint32(cv) { - // found a regular match - break - } - } - if coffset1 < int32(z.MaxDistance) && uint32(cv>>8) == candidate2.val { - t = candidate2.offset - z.current - if binary.LittleEndian.Uint32(src[t:]) == uint32(cv>>8) { - s++ - break - } - } - - s += stepSize + ((s - nextEmit) >> 5) - if s > sLimit { - break mainLoop - } - cv = binary.LittleEndian.Uint64(src[s:]) - } - - // A 4-byte match has been found. We'll later see if more than - // 4 bytes. - offset2 = offset1 - offset1 = s - t - - end := extendMatch(src, int(t+4), int(s+4)) - for t > 0 && s > nextEmit && src[t-1] == src[s-1] { - s-- - t-- - } - - dst = append(dst, Match{ - Unmatched: int(s - nextEmit), - Length: end - int(s), - Distance: int(s - t), - }) - s = int32(end) - nextEmit = s - if s >= sLimit { - break mainLoop - } - cv = binary.LittleEndian.Uint64(src[s:]) - - // Check offset 2 - if o2 := s - offset2; offset2 != 0 && binary.LittleEndian.Uint32(src[o2:]) == uint32(cv) { - end := extendMatch(src, int(o2+4), int(s+4)) - - // Store the hash, since we have it. - nextHash := z.hash(cv) - z.table[nextHash] = tableEntry{offset: s + z.current, val: uint32(cv)} - dst = append(dst, Match{ - Length: end - int(s), - Distance: int(offset2), - }) - s = int32(end) - nextEmit = s - offset1, offset2 = offset2, offset1 - if s >= sLimit { - break mainLoop - } - cv = binary.LittleEndian.Uint64(src[s:]) - } - } - - if int(nextEmit) < len(src) { - dst = append(dst, Match{ - Unmatched: len(src) - int(nextEmit), - }) - } - - return dst -} - -func (z *ZFast) hash(u uint64) uint32 { - return uint32(((u << 16) * prime6Bytes) >> (64 - zfastTableBits)) -} diff --git a/src/vendor/github.com/andybalholm/brotli/matchfinder/zm.go b/src/vendor/github.com/andybalholm/brotli/matchfinder/zm.go deleted file mode 100644 index 59a920c3..00000000 --- a/src/vendor/github.com/andybalholm/brotli/matchfinder/zm.go +++ /dev/null @@ -1,301 +0,0 @@ -package matchfinder - -import "encoding/binary" - -const ( - zmTableBits = 15 - zmTableSize = 1 << zmTableBits - zmLongTableBits = 17 - zmLongTableSize = 1 << zmLongTableBits -) - -// ZM is a MatchFinder that combines the cache tables of ZDFast with the -// overlap-based parsing of M4. -type ZM struct { - MaxDistance int - history []byte - table [zmTableSize]tableEntry - longTable [zmLongTableSize]tableEntry -} - -func (z *ZM) Reset() { - z.table = [zmTableSize]tableEntry{} - z.longTable = [zmLongTableSize]tableEntry{} - z.history = z.history[:0] -} - -func (z *ZM) FindMatches(dst []Match, src []byte) []Match { - if z.MaxDistance == 0 { - z.MaxDistance = 1 << 16 - } - - if len(z.history) > z.MaxDistance*2 { - delta := len(z.history) - z.MaxDistance - copy(z.history, z.history[delta:]) - z.history = z.history[:z.MaxDistance] - - for i := range z.table { - v := z.table[i].offset - v -= int32(delta) - if v < 0 { - z.table[i] = tableEntry{} - } else { - z.table[i].offset = v - } - } - for i := range z.longTable { - v := z.longTable[i].offset - v -= int32(delta) - if v < 0 { - z.longTable[i] = tableEntry{} - } else { - z.longTable[i].offset = v - } - } - } - - if len(src) < 16 { - return append(dst, Match{ - Unmatched: len(src), - }) - } - - e := matchEmitter{ - Dst: dst, - NextEmit: len(z.history), - } - z.history = append(z.history, src...) - src = z.history - - // matches stores the matches that have been found but not emitted, - // in reverse order. (matches[0] is the most recent one.) - var matches [3]absoluteMatch - - sLimit := int32(len(src)) - 10 - -mainLoop: - for { - // Search for a match, starting after the last match emitted. - s := int32(e.NextEmit) - if s > sLimit { - break mainLoop - } - - // t will contain the match offset when we find one. - var t int32 - - cv := binary.LittleEndian.Uint64(src[s:]) - - for { - nextHashL := z.hashLong(cv) - nextHashS := z.hashShort(cv) - candidateL := z.longTable[nextHashL] - candidateS := z.table[nextHashS] - - entry := tableEntry{offset: s, val: uint32(cv)} - z.longTable[nextHashL] = entry - z.table[nextHashS] = entry - - // Look for a repeat match one byte after the current position. - if len(e.Dst) > 0 { - prevDistance := int32(e.Dst[len(e.Dst)-1].Distance) - if prevDistance != 0 { - repIndex := s - prevDistance + 1 - if repIndex >= 0 && binary.LittleEndian.Uint32(src[repIndex:]) == uint32(cv>>8) { - // There is a repeated match at s+2. - s++ - t = repIndex - break - } - } - } - - if candidateL.offset < s && s-candidateL.offset < int32(z.MaxDistance) && uint32(cv) == candidateL.val && - binary.LittleEndian.Uint32(src[candidateL.offset:]) == uint32(cv) { - // There is a long match at s. - t = candidateL.offset - break - } - if candidateS.offset < s && s-candidateS.offset < int32(z.MaxDistance) && uint32(cv) == candidateS.val && - binary.LittleEndian.Uint32(src[candidateS.offset:]) == uint32(cv) { - // There is a regular match at s. - // See if we can find a long match at s+1. - cv := binary.LittleEndian.Uint64(src[s+1:]) - nextHashL = z.hashLong(cv) - candidateL = z.longTable[nextHashL] - coffsetL := s - candidateL.offset + 1 - z.longTable[nextHashL] = tableEntry{offset: s + 1, val: uint32(cv)} - if candidateL.offset < s+1 && coffsetL < int32(z.MaxDistance) && uint32(cv) == candidateL.val && - binary.LittleEndian.Uint32(src[candidateL.offset:]) == uint32(cv) { - // We found a long match at s+1, so we'll use that instead - // of the regular match at s. - t = candidateL.offset - s++ - break - } - - t = candidateS.offset - break - } - - s += 1 + ((s - int32(e.NextEmit)) >> 7) - if s > sLimit { - break mainLoop - } - cv = binary.LittleEndian.Uint64(src[s:]) - } - - currentMatch := extendMatch2(src, int(s), int(t), e.NextEmit) - matches[0] = currentMatch - - // Store some table entries after s. - index0 := s + 1 - cv0 := binary.LittleEndian.Uint64(src[index0:]) - te0 := tableEntry{offset: index0, val: uint32(cv0)} - z.longTable[z.hashLong(cv0)] = te0 - cv0 >>= 8 - te0.offset++ - te0.val = uint32(cv0) - z.table[z.hashShort(cv0)] = te0 - - // We have a match in matches[0]. - // Now look for overlapping matches. - - for { - if matches[0].End > int(sLimit) { - break - } - s = int32(max(matches[0].Start+2, matches[0].End-6)) - cv = binary.LittleEndian.Uint64(src[s:]) - - nextHashL := z.hashLong(cv) - nextHashS := z.hashShort(cv) - candidateL := z.longTable[nextHashL] - candidateS := z.table[nextHashS] - - entry := tableEntry{offset: s, val: uint32(cv)} - z.longTable[nextHashL] = entry - z.table[nextHashS] = entry - - t = -1 - if candidateL.offset < s && s-candidateL.offset < int32(z.MaxDistance) && uint32(cv) == candidateL.val && - binary.LittleEndian.Uint32(src[candidateL.offset:]) == uint32(cv) { - // There is a long match at s. - t = candidateL.offset - } else if candidateS.offset < s && s-candidateS.offset < int32(z.MaxDistance) && uint32(cv) == candidateS.val && - binary.LittleEndian.Uint32(src[candidateS.offset:]) == uint32(cv) { - // There is a regular match at s. - t = candidateS.offset - // See if we can find a long match at s+1. - cv := binary.LittleEndian.Uint64(src[s+1:]) - nextHashL = z.hashLong(cv) - candidateL = z.longTable[nextHashL] - coffsetL := s - candidateL.offset + 1 - z.longTable[nextHashL] = tableEntry{offset: s + 1, val: uint32(cv)} - if candidateL.offset < s+1 && coffsetL < int32(z.MaxDistance) && uint32(cv) == candidateL.val && - binary.LittleEndian.Uint32(src[candidateL.offset:]) == uint32(cv) { - // We found a long match at s+1, so we'll use that instead - // of the regular match at s. - t = candidateL.offset - s++ - } - } - - if t == -1 { - // No overlapping match was found. - break - } - - newMatch := extendMatch2(src, int(s), int(t), e.NextEmit) - - if newMatch.End-newMatch.Start <= matches[0].End-matches[0].Start { - // The new match isn't longer than the old one, so we break out of the loop - // of looking for overlapping matches. - break - } - - matches = [3]absoluteMatch{ - newMatch, - matches[0], - matches[1], - } - - if matches[2] == (absoluteMatch{}) { - continue - } - - // We have three matches, so it's time to emit one and/or eliminate one. - switch { - case matches[0].Start < matches[2].End: - // The first and third matches overlap; discard the one in between. - matches = [3]absoluteMatch{ - matches[0], - matches[2], - {}, - } - - case matches[0].Start < matches[2].End+4: - // The first and third matches don't overlap, but there's no room for - // another match between them. Emit the first match and discard the second. - e.emit(matches[2]) - matches = [3]absoluteMatch{ - matches[0], - {}, - {}, - } - - default: - // Emit the first match, shortening it if necessary to avoid overlap with the second. - if matches[2].End > matches[1].Start { - matches[2].End = matches[1].Start - } - if matches[2].End-matches[2].Start >= 4 { - e.emit(matches[2]) - } - matches[2] = absoluteMatch{} - } - } - - // Store some table entries at the end of the last match. - index1 := int32(matches[0].End - 2) - if index1 < sLimit { - cv1 := binary.LittleEndian.Uint64(src[index1:]) - te1 := tableEntry{offset: index1, val: uint32(cv1)} - z.longTable[z.hashLong(cv1)] = te1 - cv1 >>= 8 - te1.offset++ - te1.val = uint32(cv1) - z.table[z.hashShort(cv1)] = te1 - } - - // We're done looking for overlapping matches; emit the ones we have. - - if matches[1] != (absoluteMatch{}) { - if matches[1].End > matches[0].Start { - matches[1].End = matches[0].Start - } - if matches[1].End-matches[1].Start >= 4 { - e.emit(matches[1]) - } - } - e.emit(matches[0]) - matches = [3]absoluteMatch{} - } - - dst = e.Dst - if e.NextEmit < len(src) { - dst = append(dst, Match{ - Unmatched: len(src) - e.NextEmit, - }) - } - - return dst -} - -func (z *ZM) hashShort(u uint64) uint32 { - return uint32(((u << 24) * 889523592379) >> (64 - zmTableBits)) -} - -func (z *ZM) hashLong(u uint64) uint32 { - return uint32((u * 0xcf1bbcdcb7a56463) >> (64 - zmLongTableBits)) -} diff --git a/src/vendor/github.com/andybalholm/brotli/memory.go b/src/vendor/github.com/andybalholm/brotli/memory.go deleted file mode 100644 index a07c7050..00000000 --- a/src/vendor/github.com/andybalholm/brotli/memory.go +++ /dev/null @@ -1,66 +0,0 @@ -package brotli - -/* Copyright 2016 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* -Dynamically grows array capacity to at least the requested size -T: data type -A: array -C: capacity -R: requested size -*/ -func brotli_ensure_capacity_uint8_t(a *[]byte, c *uint, r uint) { - if *c < r { - var new_size uint = *c - if new_size == 0 { - new_size = r - } - - for new_size < r { - new_size *= 2 - } - - if cap(*a) < int(new_size) { - var new_array []byte = make([]byte, new_size) - if *c != 0 { - copy(new_array, (*a)[:*c]) - } - - *a = new_array - } else { - *a = (*a)[:new_size] - } - - *c = new_size - } -} - -func brotli_ensure_capacity_uint32_t(a *[]uint32, c *uint, r uint) { - var new_array []uint32 - if *c < r { - var new_size uint = *c - if new_size == 0 { - new_size = r - } - - for new_size < r { - new_size *= 2 - } - - if cap(*a) < int(new_size) { - new_array = make([]uint32, new_size) - if *c != 0 { - copy(new_array, (*a)[:*c]) - } - - *a = new_array - } else { - *a = (*a)[:new_size] - } - *c = new_size - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/metablock.go b/src/vendor/github.com/andybalholm/brotli/metablock.go deleted file mode 100644 index 3014df8c..00000000 --- a/src/vendor/github.com/andybalholm/brotli/metablock.go +++ /dev/null @@ -1,574 +0,0 @@ -package brotli - -import ( - "sync" -) - -/* Copyright 2014 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Algorithms for distributing the literals and commands of a metablock between - block types and contexts. */ - -type metaBlockSplit struct { - literal_split blockSplit - command_split blockSplit - distance_split blockSplit - literal_context_map []uint32 - literal_context_map_size uint - distance_context_map []uint32 - distance_context_map_size uint - literal_histograms []histogramLiteral - literal_histograms_size uint - command_histograms []histogramCommand - command_histograms_size uint - distance_histograms []histogramDistance - distance_histograms_size uint -} - -var metaBlockPool sync.Pool - -func getMetaBlockSplit() *metaBlockSplit { - mb, _ := metaBlockPool.Get().(*metaBlockSplit) - - if mb == nil { - mb = &metaBlockSplit{} - } else { - initBlockSplit(&mb.literal_split) - initBlockSplit(&mb.command_split) - initBlockSplit(&mb.distance_split) - mb.literal_context_map = mb.literal_context_map[:0] - mb.literal_context_map_size = 0 - mb.distance_context_map = mb.distance_context_map[:0] - mb.distance_context_map_size = 0 - mb.literal_histograms = mb.literal_histograms[:0] - mb.command_histograms = mb.command_histograms[:0] - mb.distance_histograms = mb.distance_histograms[:0] - } - return mb -} - -func freeMetaBlockSplit(mb *metaBlockSplit) { - metaBlockPool.Put(mb) -} - -func initDistanceParams(params *encoderParams, npostfix uint32, ndirect uint32) { - var dist_params *distanceParams = ¶ms.dist - var alphabet_size uint32 - var max_distance uint32 - - dist_params.distance_postfix_bits = npostfix - dist_params.num_direct_distance_codes = ndirect - - alphabet_size = uint32(distanceAlphabetSize(uint(npostfix), uint(ndirect), maxDistanceBits)) - max_distance = ndirect + (1 << (maxDistanceBits + npostfix + 2)) - (1 << (npostfix + 2)) - - if params.large_window { - var bound = [maxNpostfix + 1]uint32{0, 4, 12, 28} - var postfix uint32 = 1 << npostfix - alphabet_size = uint32(distanceAlphabetSize(uint(npostfix), uint(ndirect), largeMaxDistanceBits)) - - /* The maximum distance is set so that no distance symbol used can encode - a distance larger than BROTLI_MAX_ALLOWED_DISTANCE with all - its extra bits set. */ - if ndirect < bound[npostfix] { - max_distance = maxAllowedDistance - (bound[npostfix] - ndirect) - } else if ndirect >= bound[npostfix]+postfix { - max_distance = (3 << 29) - 4 + (ndirect - bound[npostfix]) - } else { - max_distance = maxAllowedDistance - } - } - - dist_params.alphabet_size = alphabet_size - dist_params.max_distance = uint(max_distance) -} - -func recomputeDistancePrefixes(cmds []command, orig_params *distanceParams, new_params *distanceParams) { - if orig_params.distance_postfix_bits == new_params.distance_postfix_bits && orig_params.num_direct_distance_codes == new_params.num_direct_distance_codes { - return - } - - for i := range cmds { - var cmd *command = &cmds[i] - if commandCopyLen(cmd) != 0 && cmd.cmd_prefix_ >= 128 { - prefixEncodeCopyDistance(uint(commandRestoreDistanceCode(cmd, orig_params)), uint(new_params.num_direct_distance_codes), uint(new_params.distance_postfix_bits), &cmd.dist_prefix_, &cmd.dist_extra_) - } - } -} - -func computeDistanceCost(cmds []command, orig_params *distanceParams, new_params *distanceParams, cost *float64) bool { - var equal_params bool = false - var dist_prefix uint16 - var dist_extra uint32 - var extra_bits float64 = 0.0 - var histo histogramDistance - histogramClearDistance(&histo) - - if orig_params.distance_postfix_bits == new_params.distance_postfix_bits && orig_params.num_direct_distance_codes == new_params.num_direct_distance_codes { - equal_params = true - } - - for i := range cmds { - cmd := &cmds[i] - if commandCopyLen(cmd) != 0 && cmd.cmd_prefix_ >= 128 { - if equal_params { - dist_prefix = cmd.dist_prefix_ - } else { - var distance uint32 = commandRestoreDistanceCode(cmd, orig_params) - if distance > uint32(new_params.max_distance) { - return false - } - - prefixEncodeCopyDistance(uint(distance), uint(new_params.num_direct_distance_codes), uint(new_params.distance_postfix_bits), &dist_prefix, &dist_extra) - } - - histogramAddDistance(&histo, uint(dist_prefix)&0x3FF) - extra_bits += float64(dist_prefix >> 10) - } - } - - *cost = populationCostDistance(&histo) + extra_bits - return true -} - -var buildMetaBlock_kMaxNumberOfHistograms uint = 256 - -func buildMetaBlock(ringbuffer []byte, pos uint, mask uint, params *encoderParams, prev_byte byte, prev_byte2 byte, cmds []command, literal_context_mode int, mb *metaBlockSplit) { - var distance_histograms []histogramDistance - var literal_histograms []histogramLiteral - var literal_context_modes []int = nil - var literal_histograms_size uint - var distance_histograms_size uint - var i uint - var literal_context_multiplier uint = 1 - var npostfix uint32 - var ndirect_msb uint32 = 0 - var check_orig bool = true - var best_dist_cost float64 = 1e99 - var orig_params encoderParams = *params - /* Histogram ids need to fit in one byte. */ - - var new_params encoderParams = *params - - for npostfix = 0; npostfix <= maxNpostfix; npostfix++ { - for ; ndirect_msb < 16; ndirect_msb++ { - var ndirect uint32 = ndirect_msb << npostfix - var skip bool - var dist_cost float64 - initDistanceParams(&new_params, npostfix, ndirect) - if npostfix == orig_params.dist.distance_postfix_bits && ndirect == orig_params.dist.num_direct_distance_codes { - check_orig = false - } - - skip = !computeDistanceCost(cmds, &orig_params.dist, &new_params.dist, &dist_cost) - if skip || (dist_cost > best_dist_cost) { - break - } - - best_dist_cost = dist_cost - params.dist = new_params.dist - } - - if ndirect_msb > 0 { - ndirect_msb-- - } - ndirect_msb /= 2 - } - - if check_orig { - var dist_cost float64 - computeDistanceCost(cmds, &orig_params.dist, &orig_params.dist, &dist_cost) - if dist_cost < best_dist_cost { - /* NB: currently unused; uncomment when more param tuning is added. */ - /* best_dist_cost = dist_cost; */ - params.dist = orig_params.dist - } - } - - recomputeDistancePrefixes(cmds, &orig_params.dist, ¶ms.dist) - - splitBlock(cmds, ringbuffer, pos, mask, params, &mb.literal_split, &mb.command_split, &mb.distance_split) - - if !params.disable_literal_context_modeling { - literal_context_multiplier = 1 << literalContextBits - literal_context_modes = make([]int, (mb.literal_split.num_types)) - for i = 0; i < mb.literal_split.num_types; i++ { - literal_context_modes[i] = literal_context_mode - } - } - - literal_histograms_size = mb.literal_split.num_types * literal_context_multiplier - literal_histograms = make([]histogramLiteral, literal_histograms_size) - clearHistogramsLiteral(literal_histograms, literal_histograms_size) - - distance_histograms_size = mb.distance_split.num_types << distanceContextBits - distance_histograms = make([]histogramDistance, distance_histograms_size) - clearHistogramsDistance(distance_histograms, distance_histograms_size) - - mb.command_histograms_size = mb.command_split.num_types - if cap(mb.command_histograms) < int(mb.command_histograms_size) { - mb.command_histograms = make([]histogramCommand, (mb.command_histograms_size)) - } else { - mb.command_histograms = mb.command_histograms[:mb.command_histograms_size] - } - clearHistogramsCommand(mb.command_histograms, mb.command_histograms_size) - - buildHistogramsWithContext(cmds, &mb.literal_split, &mb.command_split, &mb.distance_split, ringbuffer, pos, mask, prev_byte, prev_byte2, literal_context_modes, literal_histograms, mb.command_histograms, distance_histograms) - literal_context_modes = nil - - mb.literal_context_map_size = mb.literal_split.num_types << literalContextBits - if cap(mb.literal_context_map) < int(mb.literal_context_map_size) { - mb.literal_context_map = make([]uint32, (mb.literal_context_map_size)) - } else { - mb.literal_context_map = mb.literal_context_map[:mb.literal_context_map_size] - } - - mb.literal_histograms_size = mb.literal_context_map_size - if cap(mb.literal_histograms) < int(mb.literal_histograms_size) { - mb.literal_histograms = make([]histogramLiteral, (mb.literal_histograms_size)) - } else { - mb.literal_histograms = mb.literal_histograms[:mb.literal_histograms_size] - } - - clusterHistogramsLiteral(literal_histograms, literal_histograms_size, buildMetaBlock_kMaxNumberOfHistograms, mb.literal_histograms, &mb.literal_histograms_size, mb.literal_context_map) - literal_histograms = nil - - if params.disable_literal_context_modeling { - /* Distribute assignment to all contexts. */ - for i = mb.literal_split.num_types; i != 0; { - var j uint = 0 - i-- - for ; j < 1< 0 { - var entropy [maxStaticContexts]float64 - var combined_histo []histogramLiteral = make([]histogramLiteral, (2 * num_contexts)) - var combined_entropy [2 * maxStaticContexts]float64 - var diff = [2]float64{0.0} - /* Try merging the set of histograms for the current block type with the - respective set of histograms for the last and second last block types. - Decide over the split based on the total reduction of entropy across - all contexts. */ - - var i uint - for i = 0; i < num_contexts; i++ { - var curr_histo_ix uint = self.curr_histogram_ix_ + i - var j uint - entropy[i] = bitsEntropy(histograms[curr_histo_ix].data_[:], self.alphabet_size_) - for j = 0; j < 2; j++ { - var jx uint = j*num_contexts + i - var last_histogram_ix uint = self.last_histogram_ix_[j] + i - combined_histo[jx] = histograms[curr_histo_ix] - histogramAddHistogramLiteral(&combined_histo[jx], &histograms[last_histogram_ix]) - combined_entropy[jx] = bitsEntropy(combined_histo[jx].data_[0:], self.alphabet_size_) - diff[j] += combined_entropy[jx] - entropy[i] - last_entropy[jx] - } - } - - if split.num_types < self.max_block_types_ && diff[0] > self.split_threshold_ && diff[1] > self.split_threshold_ { - /* Create new block. */ - split.lengths[self.num_blocks_] = uint32(self.block_size_) - - split.types[self.num_blocks_] = byte(split.num_types) - self.last_histogram_ix_[1] = self.last_histogram_ix_[0] - self.last_histogram_ix_[0] = split.num_types * num_contexts - for i = 0; i < num_contexts; i++ { - last_entropy[num_contexts+i] = last_entropy[i] - last_entropy[i] = entropy[i] - } - - self.num_blocks_++ - split.num_types++ - self.curr_histogram_ix_ += num_contexts - if self.curr_histogram_ix_ < *self.histograms_size_ { - clearHistogramsLiteral(self.histograms_[self.curr_histogram_ix_:], self.num_contexts_) - } - - self.block_size_ = 0 - self.merge_last_count_ = 0 - self.target_block_size_ = self.min_block_size_ - } else if diff[1] < diff[0]-20.0 { - split.lengths[self.num_blocks_] = uint32(self.block_size_) - split.types[self.num_blocks_] = split.types[self.num_blocks_-2] - /* Combine this block with second last block. */ - - var tmp uint = self.last_histogram_ix_[0] - self.last_histogram_ix_[0] = self.last_histogram_ix_[1] - self.last_histogram_ix_[1] = tmp - for i = 0; i < num_contexts; i++ { - histograms[self.last_histogram_ix_[0]+i] = combined_histo[num_contexts+i] - last_entropy[num_contexts+i] = last_entropy[i] - last_entropy[i] = combined_entropy[num_contexts+i] - histogramClearLiteral(&histograms[self.curr_histogram_ix_+i]) - } - - self.num_blocks_++ - self.block_size_ = 0 - self.merge_last_count_ = 0 - self.target_block_size_ = self.min_block_size_ - } else { - /* Combine this block with last block. */ - split.lengths[self.num_blocks_-1] += uint32(self.block_size_) - - for i = 0; i < num_contexts; i++ { - histograms[self.last_histogram_ix_[0]+i] = combined_histo[i] - last_entropy[i] = combined_entropy[i] - if split.num_types == 1 { - last_entropy[num_contexts+i] = last_entropy[i] - } - - histogramClearLiteral(&histograms[self.curr_histogram_ix_+i]) - } - - self.block_size_ = 0 - self.merge_last_count_++ - if self.merge_last_count_ > 1 { - self.target_block_size_ += self.min_block_size_ - } - } - - combined_histo = nil - } - - if is_final { - *self.histograms_size_ = split.num_types * num_contexts - split.num_blocks = self.num_blocks_ - } -} - -/* Adds the next symbol to the current block type and context. When the - current block reaches the target size, decides on merging the block. */ -func contextBlockSplitterAddSymbol(self *contextBlockSplitter, symbol uint, context uint) { - histogramAddLiteral(&self.histograms_[self.curr_histogram_ix_+context], symbol) - self.block_size_++ - if self.block_size_ == self.target_block_size_ { - contextBlockSplitterFinishBlock(self, false) /* is_final = */ - } -} - -func mapStaticContexts(num_contexts uint, static_context_map []uint32, mb *metaBlockSplit) { - var i uint - mb.literal_context_map_size = mb.literal_split.num_types << literalContextBits - if cap(mb.literal_context_map) < int(mb.literal_context_map_size) { - mb.literal_context_map = make([]uint32, (mb.literal_context_map_size)) - } else { - mb.literal_context_map = mb.literal_context_map[:mb.literal_context_map_size] - } - - for i = 0; i < mb.literal_split.num_types; i++ { - var offset uint32 = uint32(i * num_contexts) - var j uint - for j = 0; j < 1<= 128 { - blockSplitterAddSymbolDistance(&dist_blocks, uint(cmd.dist_prefix_)&0x3FF) - } - } - } - - if num_contexts == 1 { - blockSplitterFinishBlockLiteral(&lit_blocks.plain, true) /* is_final = */ - } else { - contextBlockSplitterFinishBlock(&lit_blocks.ctx, true) /* is_final = */ - } - - blockSplitterFinishBlockCommand(&cmd_blocks, true) /* is_final = */ - blockSplitterFinishBlockDistance(&dist_blocks, true) /* is_final = */ - - if num_contexts > 1 { - mapStaticContexts(num_contexts, static_context_map, mb) - } -} - -func buildMetaBlockGreedy(ringbuffer []byte, pos uint, mask uint, prev_byte byte, prev_byte2 byte, literal_context_lut contextLUT, num_contexts uint, static_context_map []uint32, commands []command, mb *metaBlockSplit) { - if num_contexts == 1 { - buildMetaBlockGreedyInternal(ringbuffer, pos, mask, prev_byte, prev_byte2, literal_context_lut, 1, nil, commands, mb) - } else { - buildMetaBlockGreedyInternal(ringbuffer, pos, mask, prev_byte, prev_byte2, literal_context_lut, num_contexts, static_context_map, commands, mb) - } -} - -func optimizeHistograms(num_distance_codes uint32, mb *metaBlockSplit) { - var good_for_rle [numCommandSymbols]byte - var i uint - for i = 0; i < mb.literal_histograms_size; i++ { - optimizeHuffmanCountsForRLE(256, mb.literal_histograms[i].data_[:], good_for_rle[:]) - } - - for i = 0; i < mb.command_histograms_size; i++ { - optimizeHuffmanCountsForRLE(numCommandSymbols, mb.command_histograms[i].data_[:], good_for_rle[:]) - } - - for i = 0; i < mb.distance_histograms_size; i++ { - optimizeHuffmanCountsForRLE(uint(num_distance_codes), mb.distance_histograms[i].data_[:], good_for_rle[:]) - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/metablock_command.go b/src/vendor/github.com/andybalholm/brotli/metablock_command.go deleted file mode 100644 index 46459723..00000000 --- a/src/vendor/github.com/andybalholm/brotli/metablock_command.go +++ /dev/null @@ -1,165 +0,0 @@ -package brotli - -/* Copyright 2015 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Greedy block splitter for one block category (literal, command or distance). - */ -type blockSplitterCommand struct { - alphabet_size_ uint - min_block_size_ uint - split_threshold_ float64 - num_blocks_ uint - split_ *blockSplit - histograms_ []histogramCommand - histograms_size_ *uint - target_block_size_ uint - block_size_ uint - curr_histogram_ix_ uint - last_histogram_ix_ [2]uint - last_entropy_ [2]float64 - merge_last_count_ uint -} - -func initBlockSplitterCommand(self *blockSplitterCommand, alphabet_size uint, min_block_size uint, split_threshold float64, num_symbols uint, split *blockSplit, histograms *[]histogramCommand, histograms_size *uint) { - var max_num_blocks uint = num_symbols/min_block_size + 1 - var max_num_types uint = brotli_min_size_t(max_num_blocks, maxNumberOfBlockTypes+1) - /* We have to allocate one more histogram than the maximum number of block - types for the current histogram when the meta-block is too big. */ - self.alphabet_size_ = alphabet_size - - self.min_block_size_ = min_block_size - self.split_threshold_ = split_threshold - self.num_blocks_ = 0 - self.split_ = split - self.histograms_size_ = histograms_size - self.target_block_size_ = min_block_size - self.block_size_ = 0 - self.curr_histogram_ix_ = 0 - self.merge_last_count_ = 0 - brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, max_num_blocks) - brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, max_num_blocks) - self.split_.num_blocks = max_num_blocks - *histograms_size = max_num_types - if cap(*histograms) < int(*histograms_size) { - *histograms = make([]histogramCommand, (*histograms_size)) - } else { - *histograms = (*histograms)[:*histograms_size] - } - self.histograms_ = *histograms - - /* Clear only current histogram. */ - histogramClearCommand(&self.histograms_[0]) - - self.last_histogram_ix_[1] = 0 - self.last_histogram_ix_[0] = self.last_histogram_ix_[1] -} - -/* Does either of three things: - (1) emits the current block with a new block type; - (2) emits the current block with the type of the second last block; - (3) merges the current block with the last block. */ -func blockSplitterFinishBlockCommand(self *blockSplitterCommand, is_final bool) { - var split *blockSplit = self.split_ - var last_entropy []float64 = self.last_entropy_[:] - var histograms []histogramCommand = self.histograms_ - self.block_size_ = brotli_max_size_t(self.block_size_, self.min_block_size_) - if self.num_blocks_ == 0 { - /* Create first block. */ - split.lengths[0] = uint32(self.block_size_) - - split.types[0] = 0 - last_entropy[0] = bitsEntropy(histograms[0].data_[:], self.alphabet_size_) - last_entropy[1] = last_entropy[0] - self.num_blocks_++ - split.num_types++ - self.curr_histogram_ix_++ - if self.curr_histogram_ix_ < *self.histograms_size_ { - histogramClearCommand(&histograms[self.curr_histogram_ix_]) - } - self.block_size_ = 0 - } else if self.block_size_ > 0 { - var entropy float64 = bitsEntropy(histograms[self.curr_histogram_ix_].data_[:], self.alphabet_size_) - var combined_histo [2]histogramCommand - var combined_entropy [2]float64 - var diff [2]float64 - var j uint - for j = 0; j < 2; j++ { - var last_histogram_ix uint = self.last_histogram_ix_[j] - combined_histo[j] = histograms[self.curr_histogram_ix_] - histogramAddHistogramCommand(&combined_histo[j], &histograms[last_histogram_ix]) - combined_entropy[j] = bitsEntropy(combined_histo[j].data_[0:], self.alphabet_size_) - diff[j] = combined_entropy[j] - entropy - last_entropy[j] - } - - if split.num_types < maxNumberOfBlockTypes && diff[0] > self.split_threshold_ && diff[1] > self.split_threshold_ { - /* Create new block. */ - split.lengths[self.num_blocks_] = uint32(self.block_size_) - - split.types[self.num_blocks_] = byte(split.num_types) - self.last_histogram_ix_[1] = self.last_histogram_ix_[0] - self.last_histogram_ix_[0] = uint(byte(split.num_types)) - last_entropy[1] = last_entropy[0] - last_entropy[0] = entropy - self.num_blocks_++ - split.num_types++ - self.curr_histogram_ix_++ - if self.curr_histogram_ix_ < *self.histograms_size_ { - histogramClearCommand(&histograms[self.curr_histogram_ix_]) - } - self.block_size_ = 0 - self.merge_last_count_ = 0 - self.target_block_size_ = self.min_block_size_ - } else if diff[1] < diff[0]-20.0 { - split.lengths[self.num_blocks_] = uint32(self.block_size_) - split.types[self.num_blocks_] = split.types[self.num_blocks_-2] - /* Combine this block with second last block. */ - - var tmp uint = self.last_histogram_ix_[0] - self.last_histogram_ix_[0] = self.last_histogram_ix_[1] - self.last_histogram_ix_[1] = tmp - histograms[self.last_histogram_ix_[0]] = combined_histo[1] - last_entropy[1] = last_entropy[0] - last_entropy[0] = combined_entropy[1] - self.num_blocks_++ - self.block_size_ = 0 - histogramClearCommand(&histograms[self.curr_histogram_ix_]) - self.merge_last_count_ = 0 - self.target_block_size_ = self.min_block_size_ - } else { - /* Combine this block with last block. */ - split.lengths[self.num_blocks_-1] += uint32(self.block_size_) - - histograms[self.last_histogram_ix_[0]] = combined_histo[0] - last_entropy[0] = combined_entropy[0] - if split.num_types == 1 { - last_entropy[1] = last_entropy[0] - } - - self.block_size_ = 0 - histogramClearCommand(&histograms[self.curr_histogram_ix_]) - self.merge_last_count_++ - if self.merge_last_count_ > 1 { - self.target_block_size_ += self.min_block_size_ - } - } - } - - if is_final { - *self.histograms_size_ = split.num_types - split.num_blocks = self.num_blocks_ - } -} - -/* Adds the next symbol to the current histogram. When the current histogram - reaches the target size, decides on merging the block. */ -func blockSplitterAddSymbolCommand(self *blockSplitterCommand, symbol uint) { - histogramAddCommand(&self.histograms_[self.curr_histogram_ix_], symbol) - self.block_size_++ - if self.block_size_ == self.target_block_size_ { - blockSplitterFinishBlockCommand(self, false) /* is_final = */ - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/metablock_distance.go b/src/vendor/github.com/andybalholm/brotli/metablock_distance.go deleted file mode 100644 index 90837294..00000000 --- a/src/vendor/github.com/andybalholm/brotli/metablock_distance.go +++ /dev/null @@ -1,165 +0,0 @@ -package brotli - -/* Copyright 2015 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Greedy block splitter for one block category (literal, command or distance). - */ -type blockSplitterDistance struct { - alphabet_size_ uint - min_block_size_ uint - split_threshold_ float64 - num_blocks_ uint - split_ *blockSplit - histograms_ []histogramDistance - histograms_size_ *uint - target_block_size_ uint - block_size_ uint - curr_histogram_ix_ uint - last_histogram_ix_ [2]uint - last_entropy_ [2]float64 - merge_last_count_ uint -} - -func initBlockSplitterDistance(self *blockSplitterDistance, alphabet_size uint, min_block_size uint, split_threshold float64, num_symbols uint, split *blockSplit, histograms *[]histogramDistance, histograms_size *uint) { - var max_num_blocks uint = num_symbols/min_block_size + 1 - var max_num_types uint = brotli_min_size_t(max_num_blocks, maxNumberOfBlockTypes+1) - /* We have to allocate one more histogram than the maximum number of block - types for the current histogram when the meta-block is too big. */ - self.alphabet_size_ = alphabet_size - - self.min_block_size_ = min_block_size - self.split_threshold_ = split_threshold - self.num_blocks_ = 0 - self.split_ = split - self.histograms_size_ = histograms_size - self.target_block_size_ = min_block_size - self.block_size_ = 0 - self.curr_histogram_ix_ = 0 - self.merge_last_count_ = 0 - brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, max_num_blocks) - brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, max_num_blocks) - self.split_.num_blocks = max_num_blocks - *histograms_size = max_num_types - if cap(*histograms) < int(*histograms_size) { - *histograms = make([]histogramDistance, *histograms_size) - } else { - *histograms = (*histograms)[:*histograms_size] - } - self.histograms_ = *histograms - - /* Clear only current histogram. */ - histogramClearDistance(&self.histograms_[0]) - - self.last_histogram_ix_[1] = 0 - self.last_histogram_ix_[0] = self.last_histogram_ix_[1] -} - -/* Does either of three things: - (1) emits the current block with a new block type; - (2) emits the current block with the type of the second last block; - (3) merges the current block with the last block. */ -func blockSplitterFinishBlockDistance(self *blockSplitterDistance, is_final bool) { - var split *blockSplit = self.split_ - var last_entropy []float64 = self.last_entropy_[:] - var histograms []histogramDistance = self.histograms_ - self.block_size_ = brotli_max_size_t(self.block_size_, self.min_block_size_) - if self.num_blocks_ == 0 { - /* Create first block. */ - split.lengths[0] = uint32(self.block_size_) - - split.types[0] = 0 - last_entropy[0] = bitsEntropy(histograms[0].data_[:], self.alphabet_size_) - last_entropy[1] = last_entropy[0] - self.num_blocks_++ - split.num_types++ - self.curr_histogram_ix_++ - if self.curr_histogram_ix_ < *self.histograms_size_ { - histogramClearDistance(&histograms[self.curr_histogram_ix_]) - } - self.block_size_ = 0 - } else if self.block_size_ > 0 { - var entropy float64 = bitsEntropy(histograms[self.curr_histogram_ix_].data_[:], self.alphabet_size_) - var combined_histo [2]histogramDistance - var combined_entropy [2]float64 - var diff [2]float64 - var j uint - for j = 0; j < 2; j++ { - var last_histogram_ix uint = self.last_histogram_ix_[j] - combined_histo[j] = histograms[self.curr_histogram_ix_] - histogramAddHistogramDistance(&combined_histo[j], &histograms[last_histogram_ix]) - combined_entropy[j] = bitsEntropy(combined_histo[j].data_[0:], self.alphabet_size_) - diff[j] = combined_entropy[j] - entropy - last_entropy[j] - } - - if split.num_types < maxNumberOfBlockTypes && diff[0] > self.split_threshold_ && diff[1] > self.split_threshold_ { - /* Create new block. */ - split.lengths[self.num_blocks_] = uint32(self.block_size_) - - split.types[self.num_blocks_] = byte(split.num_types) - self.last_histogram_ix_[1] = self.last_histogram_ix_[0] - self.last_histogram_ix_[0] = uint(byte(split.num_types)) - last_entropy[1] = last_entropy[0] - last_entropy[0] = entropy - self.num_blocks_++ - split.num_types++ - self.curr_histogram_ix_++ - if self.curr_histogram_ix_ < *self.histograms_size_ { - histogramClearDistance(&histograms[self.curr_histogram_ix_]) - } - self.block_size_ = 0 - self.merge_last_count_ = 0 - self.target_block_size_ = self.min_block_size_ - } else if diff[1] < diff[0]-20.0 { - split.lengths[self.num_blocks_] = uint32(self.block_size_) - split.types[self.num_blocks_] = split.types[self.num_blocks_-2] - /* Combine this block with second last block. */ - - var tmp uint = self.last_histogram_ix_[0] - self.last_histogram_ix_[0] = self.last_histogram_ix_[1] - self.last_histogram_ix_[1] = tmp - histograms[self.last_histogram_ix_[0]] = combined_histo[1] - last_entropy[1] = last_entropy[0] - last_entropy[0] = combined_entropy[1] - self.num_blocks_++ - self.block_size_ = 0 - histogramClearDistance(&histograms[self.curr_histogram_ix_]) - self.merge_last_count_ = 0 - self.target_block_size_ = self.min_block_size_ - } else { - /* Combine this block with last block. */ - split.lengths[self.num_blocks_-1] += uint32(self.block_size_) - - histograms[self.last_histogram_ix_[0]] = combined_histo[0] - last_entropy[0] = combined_entropy[0] - if split.num_types == 1 { - last_entropy[1] = last_entropy[0] - } - - self.block_size_ = 0 - histogramClearDistance(&histograms[self.curr_histogram_ix_]) - self.merge_last_count_++ - if self.merge_last_count_ > 1 { - self.target_block_size_ += self.min_block_size_ - } - } - } - - if is_final { - *self.histograms_size_ = split.num_types - split.num_blocks = self.num_blocks_ - } -} - -/* Adds the next symbol to the current histogram. When the current histogram - reaches the target size, decides on merging the block. */ -func blockSplitterAddSymbolDistance(self *blockSplitterDistance, symbol uint) { - histogramAddDistance(&self.histograms_[self.curr_histogram_ix_], symbol) - self.block_size_++ - if self.block_size_ == self.target_block_size_ { - blockSplitterFinishBlockDistance(self, false) /* is_final = */ - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/metablock_literal.go b/src/vendor/github.com/andybalholm/brotli/metablock_literal.go deleted file mode 100644 index 1c8b235b..00000000 --- a/src/vendor/github.com/andybalholm/brotli/metablock_literal.go +++ /dev/null @@ -1,165 +0,0 @@ -package brotli - -/* Copyright 2015 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Greedy block splitter for one block category (literal, command or distance). - */ -type blockSplitterLiteral struct { - alphabet_size_ uint - min_block_size_ uint - split_threshold_ float64 - num_blocks_ uint - split_ *blockSplit - histograms_ []histogramLiteral - histograms_size_ *uint - target_block_size_ uint - block_size_ uint - curr_histogram_ix_ uint - last_histogram_ix_ [2]uint - last_entropy_ [2]float64 - merge_last_count_ uint -} - -func initBlockSplitterLiteral(self *blockSplitterLiteral, alphabet_size uint, min_block_size uint, split_threshold float64, num_symbols uint, split *blockSplit, histograms *[]histogramLiteral, histograms_size *uint) { - var max_num_blocks uint = num_symbols/min_block_size + 1 - var max_num_types uint = brotli_min_size_t(max_num_blocks, maxNumberOfBlockTypes+1) - /* We have to allocate one more histogram than the maximum number of block - types for the current histogram when the meta-block is too big. */ - self.alphabet_size_ = alphabet_size - - self.min_block_size_ = min_block_size - self.split_threshold_ = split_threshold - self.num_blocks_ = 0 - self.split_ = split - self.histograms_size_ = histograms_size - self.target_block_size_ = min_block_size - self.block_size_ = 0 - self.curr_histogram_ix_ = 0 - self.merge_last_count_ = 0 - brotli_ensure_capacity_uint8_t(&split.types, &split.types_alloc_size, max_num_blocks) - brotli_ensure_capacity_uint32_t(&split.lengths, &split.lengths_alloc_size, max_num_blocks) - self.split_.num_blocks = max_num_blocks - *histograms_size = max_num_types - if cap(*histograms) < int(*histograms_size) { - *histograms = make([]histogramLiteral, *histograms_size) - } else { - *histograms = (*histograms)[:*histograms_size] - } - self.histograms_ = *histograms - - /* Clear only current histogram. */ - histogramClearLiteral(&self.histograms_[0]) - - self.last_histogram_ix_[1] = 0 - self.last_histogram_ix_[0] = self.last_histogram_ix_[1] -} - -/* Does either of three things: - (1) emits the current block with a new block type; - (2) emits the current block with the type of the second last block; - (3) merges the current block with the last block. */ -func blockSplitterFinishBlockLiteral(self *blockSplitterLiteral, is_final bool) { - var split *blockSplit = self.split_ - var last_entropy []float64 = self.last_entropy_[:] - var histograms []histogramLiteral = self.histograms_ - self.block_size_ = brotli_max_size_t(self.block_size_, self.min_block_size_) - if self.num_blocks_ == 0 { - /* Create first block. */ - split.lengths[0] = uint32(self.block_size_) - - split.types[0] = 0 - last_entropy[0] = bitsEntropy(histograms[0].data_[:], self.alphabet_size_) - last_entropy[1] = last_entropy[0] - self.num_blocks_++ - split.num_types++ - self.curr_histogram_ix_++ - if self.curr_histogram_ix_ < *self.histograms_size_ { - histogramClearLiteral(&histograms[self.curr_histogram_ix_]) - } - self.block_size_ = 0 - } else if self.block_size_ > 0 { - var entropy float64 = bitsEntropy(histograms[self.curr_histogram_ix_].data_[:], self.alphabet_size_) - var combined_histo [2]histogramLiteral - var combined_entropy [2]float64 - var diff [2]float64 - var j uint - for j = 0; j < 2; j++ { - var last_histogram_ix uint = self.last_histogram_ix_[j] - combined_histo[j] = histograms[self.curr_histogram_ix_] - histogramAddHistogramLiteral(&combined_histo[j], &histograms[last_histogram_ix]) - combined_entropy[j] = bitsEntropy(combined_histo[j].data_[0:], self.alphabet_size_) - diff[j] = combined_entropy[j] - entropy - last_entropy[j] - } - - if split.num_types < maxNumberOfBlockTypes && diff[0] > self.split_threshold_ && diff[1] > self.split_threshold_ { - /* Create new block. */ - split.lengths[self.num_blocks_] = uint32(self.block_size_) - - split.types[self.num_blocks_] = byte(split.num_types) - self.last_histogram_ix_[1] = self.last_histogram_ix_[0] - self.last_histogram_ix_[0] = uint(byte(split.num_types)) - last_entropy[1] = last_entropy[0] - last_entropy[0] = entropy - self.num_blocks_++ - split.num_types++ - self.curr_histogram_ix_++ - if self.curr_histogram_ix_ < *self.histograms_size_ { - histogramClearLiteral(&histograms[self.curr_histogram_ix_]) - } - self.block_size_ = 0 - self.merge_last_count_ = 0 - self.target_block_size_ = self.min_block_size_ - } else if diff[1] < diff[0]-20.0 { - split.lengths[self.num_blocks_] = uint32(self.block_size_) - split.types[self.num_blocks_] = split.types[self.num_blocks_-2] - /* Combine this block with second last block. */ - - var tmp uint = self.last_histogram_ix_[0] - self.last_histogram_ix_[0] = self.last_histogram_ix_[1] - self.last_histogram_ix_[1] = tmp - histograms[self.last_histogram_ix_[0]] = combined_histo[1] - last_entropy[1] = last_entropy[0] - last_entropy[0] = combined_entropy[1] - self.num_blocks_++ - self.block_size_ = 0 - histogramClearLiteral(&histograms[self.curr_histogram_ix_]) - self.merge_last_count_ = 0 - self.target_block_size_ = self.min_block_size_ - } else { - /* Combine this block with last block. */ - split.lengths[self.num_blocks_-1] += uint32(self.block_size_) - - histograms[self.last_histogram_ix_[0]] = combined_histo[0] - last_entropy[0] = combined_entropy[0] - if split.num_types == 1 { - last_entropy[1] = last_entropy[0] - } - - self.block_size_ = 0 - histogramClearLiteral(&histograms[self.curr_histogram_ix_]) - self.merge_last_count_++ - if self.merge_last_count_ > 1 { - self.target_block_size_ += self.min_block_size_ - } - } - } - - if is_final { - *self.histograms_size_ = split.num_types - split.num_blocks = self.num_blocks_ - } -} - -/* Adds the next symbol to the current histogram. When the current histogram - reaches the target size, decides on merging the block. */ -func blockSplitterAddSymbolLiteral(self *blockSplitterLiteral, symbol uint) { - histogramAddLiteral(&self.histograms_[self.curr_histogram_ix_], symbol) - self.block_size_++ - if self.block_size_ == self.target_block_size_ { - blockSplitterFinishBlockLiteral(self, false) /* is_final = */ - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/params.go b/src/vendor/github.com/andybalholm/brotli/params.go deleted file mode 100644 index 0a4c6875..00000000 --- a/src/vendor/github.com/andybalholm/brotli/params.go +++ /dev/null @@ -1,37 +0,0 @@ -package brotli - -/* Copyright 2017 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Parameters for the Brotli encoder with chosen quality levels. */ -type hasherParams struct { - type_ int - bucket_bits int - block_bits int - hash_len int - num_last_distances_to_check int -} - -type distanceParams struct { - distance_postfix_bits uint32 - num_direct_distance_codes uint32 - alphabet_size uint32 - max_distance uint -} - -/* Encoding parameters */ -type encoderParams struct { - mode int - quality int - lgwin uint - lgblock int - size_hint uint - disable_literal_context_modeling bool - large_window bool - hasher hasherParams - dist distanceParams - dictionary encoderDictionary -} diff --git a/src/vendor/github.com/andybalholm/brotli/platform.go b/src/vendor/github.com/andybalholm/brotli/platform.go deleted file mode 100644 index 4ebfb152..00000000 --- a/src/vendor/github.com/andybalholm/brotli/platform.go +++ /dev/null @@ -1,103 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -func brotli_min_double(a float64, b float64) float64 { - if a < b { - return a - } else { - return b - } -} - -func brotli_max_double(a float64, b float64) float64 { - if a > b { - return a - } else { - return b - } -} - -func brotli_min_float(a float32, b float32) float32 { - if a < b { - return a - } else { - return b - } -} - -func brotli_max_float(a float32, b float32) float32 { - if a > b { - return a - } else { - return b - } -} - -func brotli_min_int(a int, b int) int { - if a < b { - return a - } else { - return b - } -} - -func brotli_max_int(a int, b int) int { - if a > b { - return a - } else { - return b - } -} - -func brotli_min_size_t(a uint, b uint) uint { - if a < b { - return a - } else { - return b - } -} - -func brotli_max_size_t(a uint, b uint) uint { - if a > b { - return a - } else { - return b - } -} - -func brotli_min_uint32_t(a uint32, b uint32) uint32 { - if a < b { - return a - } else { - return b - } -} - -func brotli_max_uint32_t(a uint32, b uint32) uint32 { - if a > b { - return a - } else { - return b - } -} - -func brotli_min_uint8_t(a byte, b byte) byte { - if a < b { - return a - } else { - return b - } -} - -func brotli_max_uint8_t(a byte, b byte) byte { - if a > b { - return a - } else { - return b - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/prefix.go b/src/vendor/github.com/andybalholm/brotli/prefix.go deleted file mode 100644 index 484df0d6..00000000 --- a/src/vendor/github.com/andybalholm/brotli/prefix.go +++ /dev/null @@ -1,30 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Functions for encoding of integers into prefix codes the amount of extra - bits, and the actual values of the extra bits. */ - -/* Here distance_code is an intermediate code, i.e. one of the special codes or - the actual distance increased by BROTLI_NUM_DISTANCE_SHORT_CODES - 1. */ -func prefixEncodeCopyDistance(distance_code uint, num_direct_codes uint, postfix_bits uint, code *uint16, extra_bits *uint32) { - if distance_code < numDistanceShortCodes+num_direct_codes { - *code = uint16(distance_code) - *extra_bits = 0 - return - } else { - var dist uint = (uint(1) << (postfix_bits + 2)) + (distance_code - numDistanceShortCodes - num_direct_codes) - var bucket uint = uint(log2FloorNonZero(dist) - 1) - var postfix_mask uint = (1 << postfix_bits) - 1 - var postfix uint = dist & postfix_mask - var prefix uint = (dist >> bucket) & 1 - var offset uint = (2 + prefix) << bucket - var nbits uint = bucket - postfix_bits - *code = uint16(nbits<<10 | (numDistanceShortCodes + num_direct_codes + ((2*(nbits-1) + prefix) << postfix_bits) + postfix)) - *extra_bits = uint32((dist - offset) >> postfix_bits) - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/prefix_dec.go b/src/vendor/github.com/andybalholm/brotli/prefix_dec.go deleted file mode 100644 index 183f0d53..00000000 --- a/src/vendor/github.com/andybalholm/brotli/prefix_dec.go +++ /dev/null @@ -1,723 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -type cmdLutElement struct { - insert_len_extra_bits byte - copy_len_extra_bits byte - distance_code int8 - context byte - insert_len_offset uint16 - copy_len_offset uint16 -} - -var kCmdLut = [numCommandSymbols]cmdLutElement{ - cmdLutElement{0x00, 0x00, 0, 0x00, 0x0000, 0x0002}, - cmdLutElement{0x00, 0x00, 0, 0x01, 0x0000, 0x0003}, - cmdLutElement{0x00, 0x00, 0, 0x02, 0x0000, 0x0004}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0000, 0x0005}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0000, 0x0006}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0000, 0x0007}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0000, 0x0008}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0000, 0x0009}, - cmdLutElement{0x00, 0x00, 0, 0x00, 0x0001, 0x0002}, - cmdLutElement{0x00, 0x00, 0, 0x01, 0x0001, 0x0003}, - cmdLutElement{0x00, 0x00, 0, 0x02, 0x0001, 0x0004}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0001, 0x0005}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0001, 0x0006}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0001, 0x0007}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0001, 0x0008}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0001, 0x0009}, - cmdLutElement{0x00, 0x00, 0, 0x00, 0x0002, 0x0002}, - cmdLutElement{0x00, 0x00, 0, 0x01, 0x0002, 0x0003}, - cmdLutElement{0x00, 0x00, 0, 0x02, 0x0002, 0x0004}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0002, 0x0005}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0002, 0x0006}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0002, 0x0007}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0002, 0x0008}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0002, 0x0009}, - cmdLutElement{0x00, 0x00, 0, 0x00, 0x0003, 0x0002}, - cmdLutElement{0x00, 0x00, 0, 0x01, 0x0003, 0x0003}, - cmdLutElement{0x00, 0x00, 0, 0x02, 0x0003, 0x0004}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0003, 0x0005}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0003, 0x0006}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0003, 0x0007}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0003, 0x0008}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0003, 0x0009}, - cmdLutElement{0x00, 0x00, 0, 0x00, 0x0004, 0x0002}, - cmdLutElement{0x00, 0x00, 0, 0x01, 0x0004, 0x0003}, - cmdLutElement{0x00, 0x00, 0, 0x02, 0x0004, 0x0004}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0004, 0x0005}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0004, 0x0006}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0004, 0x0007}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0004, 0x0008}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0004, 0x0009}, - cmdLutElement{0x00, 0x00, 0, 0x00, 0x0005, 0x0002}, - cmdLutElement{0x00, 0x00, 0, 0x01, 0x0005, 0x0003}, - cmdLutElement{0x00, 0x00, 0, 0x02, 0x0005, 0x0004}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0005, 0x0005}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0005, 0x0006}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0005, 0x0007}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0005, 0x0008}, - cmdLutElement{0x00, 0x00, 0, 0x03, 0x0005, 0x0009}, - cmdLutElement{0x01, 0x00, 0, 0x00, 0x0006, 0x0002}, - cmdLutElement{0x01, 0x00, 0, 0x01, 0x0006, 0x0003}, - cmdLutElement{0x01, 0x00, 0, 0x02, 0x0006, 0x0004}, - cmdLutElement{0x01, 0x00, 0, 0x03, 0x0006, 0x0005}, - cmdLutElement{0x01, 0x00, 0, 0x03, 0x0006, 0x0006}, - cmdLutElement{0x01, 0x00, 0, 0x03, 0x0006, 0x0007}, - cmdLutElement{0x01, 0x00, 0, 0x03, 0x0006, 0x0008}, - cmdLutElement{0x01, 0x00, 0, 0x03, 0x0006, 0x0009}, - cmdLutElement{0x01, 0x00, 0, 0x00, 0x0008, 0x0002}, - cmdLutElement{0x01, 0x00, 0, 0x01, 0x0008, 0x0003}, - cmdLutElement{0x01, 0x00, 0, 0x02, 0x0008, 0x0004}, - cmdLutElement{0x01, 0x00, 0, 0x03, 0x0008, 0x0005}, - cmdLutElement{0x01, 0x00, 0, 0x03, 0x0008, 0x0006}, - cmdLutElement{0x01, 0x00, 0, 0x03, 0x0008, 0x0007}, - cmdLutElement{0x01, 0x00, 0, 0x03, 0x0008, 0x0008}, - cmdLutElement{0x01, 0x00, 0, 0x03, 0x0008, 0x0009}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0000, 0x000a}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0000, 0x000c}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0000, 0x000e}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0000, 0x0012}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0000, 0x0016}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0000, 0x001e}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0000, 0x0026}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0000, 0x0036}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0001, 0x000a}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0001, 0x000c}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0001, 0x000e}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0001, 0x0012}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0001, 0x0016}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0001, 0x001e}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0001, 0x0026}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0001, 0x0036}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0002, 0x000a}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0002, 0x000c}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0002, 0x000e}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0002, 0x0012}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0002, 0x0016}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0002, 0x001e}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0002, 0x0026}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0002, 0x0036}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0003, 0x000a}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0003, 0x000c}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0003, 0x000e}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0003, 0x0012}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0003, 0x0016}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0003, 0x001e}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0003, 0x0026}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0003, 0x0036}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0004, 0x000a}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0004, 0x000c}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0004, 0x000e}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0004, 0x0012}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0004, 0x0016}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0004, 0x001e}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0004, 0x0026}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0004, 0x0036}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0005, 0x000a}, - cmdLutElement{0x00, 0x01, 0, 0x03, 0x0005, 0x000c}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0005, 0x000e}, - cmdLutElement{0x00, 0x02, 0, 0x03, 0x0005, 0x0012}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0005, 0x0016}, - cmdLutElement{0x00, 0x03, 0, 0x03, 0x0005, 0x001e}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0005, 0x0026}, - cmdLutElement{0x00, 0x04, 0, 0x03, 0x0005, 0x0036}, - cmdLutElement{0x01, 0x01, 0, 0x03, 0x0006, 0x000a}, - cmdLutElement{0x01, 0x01, 0, 0x03, 0x0006, 0x000c}, - cmdLutElement{0x01, 0x02, 0, 0x03, 0x0006, 0x000e}, - cmdLutElement{0x01, 0x02, 0, 0x03, 0x0006, 0x0012}, - cmdLutElement{0x01, 0x03, 0, 0x03, 0x0006, 0x0016}, - cmdLutElement{0x01, 0x03, 0, 0x03, 0x0006, 0x001e}, - cmdLutElement{0x01, 0x04, 0, 0x03, 0x0006, 0x0026}, - cmdLutElement{0x01, 0x04, 0, 0x03, 0x0006, 0x0036}, - cmdLutElement{0x01, 0x01, 0, 0x03, 0x0008, 0x000a}, - cmdLutElement{0x01, 0x01, 0, 0x03, 0x0008, 0x000c}, - cmdLutElement{0x01, 0x02, 0, 0x03, 0x0008, 0x000e}, - cmdLutElement{0x01, 0x02, 0, 0x03, 0x0008, 0x0012}, - cmdLutElement{0x01, 0x03, 0, 0x03, 0x0008, 0x0016}, - cmdLutElement{0x01, 0x03, 0, 0x03, 0x0008, 0x001e}, - cmdLutElement{0x01, 0x04, 0, 0x03, 0x0008, 0x0026}, - cmdLutElement{0x01, 0x04, 0, 0x03, 0x0008, 0x0036}, - cmdLutElement{0x00, 0x00, -1, 0x00, 0x0000, 0x0002}, - cmdLutElement{0x00, 0x00, -1, 0x01, 0x0000, 0x0003}, - cmdLutElement{0x00, 0x00, -1, 0x02, 0x0000, 0x0004}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0000, 0x0005}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0000, 0x0006}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0000, 0x0007}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0000, 0x0008}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0000, 0x0009}, - cmdLutElement{0x00, 0x00, -1, 0x00, 0x0001, 0x0002}, - cmdLutElement{0x00, 0x00, -1, 0x01, 0x0001, 0x0003}, - cmdLutElement{0x00, 0x00, -1, 0x02, 0x0001, 0x0004}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0001, 0x0005}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0001, 0x0006}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0001, 0x0007}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0001, 0x0008}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0001, 0x0009}, - cmdLutElement{0x00, 0x00, -1, 0x00, 0x0002, 0x0002}, - cmdLutElement{0x00, 0x00, -1, 0x01, 0x0002, 0x0003}, - cmdLutElement{0x00, 0x00, -1, 0x02, 0x0002, 0x0004}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0002, 0x0005}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0002, 0x0006}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0002, 0x0007}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0002, 0x0008}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0002, 0x0009}, - cmdLutElement{0x00, 0x00, -1, 0x00, 0x0003, 0x0002}, - cmdLutElement{0x00, 0x00, -1, 0x01, 0x0003, 0x0003}, - cmdLutElement{0x00, 0x00, -1, 0x02, 0x0003, 0x0004}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0003, 0x0005}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0003, 0x0006}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0003, 0x0007}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0003, 0x0008}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0003, 0x0009}, - cmdLutElement{0x00, 0x00, -1, 0x00, 0x0004, 0x0002}, - cmdLutElement{0x00, 0x00, -1, 0x01, 0x0004, 0x0003}, - cmdLutElement{0x00, 0x00, -1, 0x02, 0x0004, 0x0004}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0004, 0x0005}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0004, 0x0006}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0004, 0x0007}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0004, 0x0008}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0004, 0x0009}, - cmdLutElement{0x00, 0x00, -1, 0x00, 0x0005, 0x0002}, - cmdLutElement{0x00, 0x00, -1, 0x01, 0x0005, 0x0003}, - cmdLutElement{0x00, 0x00, -1, 0x02, 0x0005, 0x0004}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0005, 0x0005}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0005, 0x0006}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0005, 0x0007}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0005, 0x0008}, - cmdLutElement{0x00, 0x00, -1, 0x03, 0x0005, 0x0009}, - cmdLutElement{0x01, 0x00, -1, 0x00, 0x0006, 0x0002}, - cmdLutElement{0x01, 0x00, -1, 0x01, 0x0006, 0x0003}, - cmdLutElement{0x01, 0x00, -1, 0x02, 0x0006, 0x0004}, - cmdLutElement{0x01, 0x00, -1, 0x03, 0x0006, 0x0005}, - cmdLutElement{0x01, 0x00, -1, 0x03, 0x0006, 0x0006}, - cmdLutElement{0x01, 0x00, -1, 0x03, 0x0006, 0x0007}, - cmdLutElement{0x01, 0x00, -1, 0x03, 0x0006, 0x0008}, - cmdLutElement{0x01, 0x00, -1, 0x03, 0x0006, 0x0009}, - cmdLutElement{0x01, 0x00, -1, 0x00, 0x0008, 0x0002}, - cmdLutElement{0x01, 0x00, -1, 0x01, 0x0008, 0x0003}, - cmdLutElement{0x01, 0x00, -1, 0x02, 0x0008, 0x0004}, - cmdLutElement{0x01, 0x00, -1, 0x03, 0x0008, 0x0005}, - cmdLutElement{0x01, 0x00, -1, 0x03, 0x0008, 0x0006}, - cmdLutElement{0x01, 0x00, -1, 0x03, 0x0008, 0x0007}, - cmdLutElement{0x01, 0x00, -1, 0x03, 0x0008, 0x0008}, - cmdLutElement{0x01, 0x00, -1, 0x03, 0x0008, 0x0009}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0000, 0x000a}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0000, 0x000c}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0000, 0x000e}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0000, 0x0012}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0000, 0x0016}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0000, 0x001e}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0000, 0x0026}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0000, 0x0036}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0001, 0x000a}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0001, 0x000c}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0001, 0x000e}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0001, 0x0012}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0001, 0x0016}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0001, 0x001e}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0001, 0x0026}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0001, 0x0036}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0002, 0x000a}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0002, 0x000c}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0002, 0x000e}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0002, 0x0012}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0002, 0x0016}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0002, 0x001e}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0002, 0x0026}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0002, 0x0036}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0003, 0x000a}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0003, 0x000c}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0003, 0x000e}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0003, 0x0012}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0003, 0x0016}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0003, 0x001e}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0003, 0x0026}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0003, 0x0036}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0004, 0x000a}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0004, 0x000c}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0004, 0x000e}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0004, 0x0012}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0004, 0x0016}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0004, 0x001e}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0004, 0x0026}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0004, 0x0036}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0005, 0x000a}, - cmdLutElement{0x00, 0x01, -1, 0x03, 0x0005, 0x000c}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0005, 0x000e}, - cmdLutElement{0x00, 0x02, -1, 0x03, 0x0005, 0x0012}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0005, 0x0016}, - cmdLutElement{0x00, 0x03, -1, 0x03, 0x0005, 0x001e}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0005, 0x0026}, - cmdLutElement{0x00, 0x04, -1, 0x03, 0x0005, 0x0036}, - cmdLutElement{0x01, 0x01, -1, 0x03, 0x0006, 0x000a}, - cmdLutElement{0x01, 0x01, -1, 0x03, 0x0006, 0x000c}, - cmdLutElement{0x01, 0x02, -1, 0x03, 0x0006, 0x000e}, - cmdLutElement{0x01, 0x02, -1, 0x03, 0x0006, 0x0012}, - cmdLutElement{0x01, 0x03, -1, 0x03, 0x0006, 0x0016}, - cmdLutElement{0x01, 0x03, -1, 0x03, 0x0006, 0x001e}, - cmdLutElement{0x01, 0x04, -1, 0x03, 0x0006, 0x0026}, - cmdLutElement{0x01, 0x04, -1, 0x03, 0x0006, 0x0036}, - cmdLutElement{0x01, 0x01, -1, 0x03, 0x0008, 0x000a}, - cmdLutElement{0x01, 0x01, -1, 0x03, 0x0008, 0x000c}, - cmdLutElement{0x01, 0x02, -1, 0x03, 0x0008, 0x000e}, - cmdLutElement{0x01, 0x02, -1, 0x03, 0x0008, 0x0012}, - cmdLutElement{0x01, 0x03, -1, 0x03, 0x0008, 0x0016}, - cmdLutElement{0x01, 0x03, -1, 0x03, 0x0008, 0x001e}, - cmdLutElement{0x01, 0x04, -1, 0x03, 0x0008, 0x0026}, - cmdLutElement{0x01, 0x04, -1, 0x03, 0x0008, 0x0036}, - cmdLutElement{0x02, 0x00, -1, 0x00, 0x000a, 0x0002}, - cmdLutElement{0x02, 0x00, -1, 0x01, 0x000a, 0x0003}, - cmdLutElement{0x02, 0x00, -1, 0x02, 0x000a, 0x0004}, - cmdLutElement{0x02, 0x00, -1, 0x03, 0x000a, 0x0005}, - cmdLutElement{0x02, 0x00, -1, 0x03, 0x000a, 0x0006}, - cmdLutElement{0x02, 0x00, -1, 0x03, 0x000a, 0x0007}, - cmdLutElement{0x02, 0x00, -1, 0x03, 0x000a, 0x0008}, - cmdLutElement{0x02, 0x00, -1, 0x03, 0x000a, 0x0009}, - cmdLutElement{0x02, 0x00, -1, 0x00, 0x000e, 0x0002}, - cmdLutElement{0x02, 0x00, -1, 0x01, 0x000e, 0x0003}, - cmdLutElement{0x02, 0x00, -1, 0x02, 0x000e, 0x0004}, - cmdLutElement{0x02, 0x00, -1, 0x03, 0x000e, 0x0005}, - cmdLutElement{0x02, 0x00, -1, 0x03, 0x000e, 0x0006}, - cmdLutElement{0x02, 0x00, -1, 0x03, 0x000e, 0x0007}, - cmdLutElement{0x02, 0x00, -1, 0x03, 0x000e, 0x0008}, - cmdLutElement{0x02, 0x00, -1, 0x03, 0x000e, 0x0009}, - cmdLutElement{0x03, 0x00, -1, 0x00, 0x0012, 0x0002}, - cmdLutElement{0x03, 0x00, -1, 0x01, 0x0012, 0x0003}, - cmdLutElement{0x03, 0x00, -1, 0x02, 0x0012, 0x0004}, - cmdLutElement{0x03, 0x00, -1, 0x03, 0x0012, 0x0005}, - cmdLutElement{0x03, 0x00, -1, 0x03, 0x0012, 0x0006}, - cmdLutElement{0x03, 0x00, -1, 0x03, 0x0012, 0x0007}, - cmdLutElement{0x03, 0x00, -1, 0x03, 0x0012, 0x0008}, - cmdLutElement{0x03, 0x00, -1, 0x03, 0x0012, 0x0009}, - cmdLutElement{0x03, 0x00, -1, 0x00, 0x001a, 0x0002}, - cmdLutElement{0x03, 0x00, -1, 0x01, 0x001a, 0x0003}, - cmdLutElement{0x03, 0x00, -1, 0x02, 0x001a, 0x0004}, - cmdLutElement{0x03, 0x00, -1, 0x03, 0x001a, 0x0005}, - cmdLutElement{0x03, 0x00, -1, 0x03, 0x001a, 0x0006}, - cmdLutElement{0x03, 0x00, -1, 0x03, 0x001a, 0x0007}, - cmdLutElement{0x03, 0x00, -1, 0x03, 0x001a, 0x0008}, - cmdLutElement{0x03, 0x00, -1, 0x03, 0x001a, 0x0009}, - cmdLutElement{0x04, 0x00, -1, 0x00, 0x0022, 0x0002}, - cmdLutElement{0x04, 0x00, -1, 0x01, 0x0022, 0x0003}, - cmdLutElement{0x04, 0x00, -1, 0x02, 0x0022, 0x0004}, - cmdLutElement{0x04, 0x00, -1, 0x03, 0x0022, 0x0005}, - cmdLutElement{0x04, 0x00, -1, 0x03, 0x0022, 0x0006}, - cmdLutElement{0x04, 0x00, -1, 0x03, 0x0022, 0x0007}, - cmdLutElement{0x04, 0x00, -1, 0x03, 0x0022, 0x0008}, - cmdLutElement{0x04, 0x00, -1, 0x03, 0x0022, 0x0009}, - cmdLutElement{0x04, 0x00, -1, 0x00, 0x0032, 0x0002}, - cmdLutElement{0x04, 0x00, -1, 0x01, 0x0032, 0x0003}, - cmdLutElement{0x04, 0x00, -1, 0x02, 0x0032, 0x0004}, - cmdLutElement{0x04, 0x00, -1, 0x03, 0x0032, 0x0005}, - cmdLutElement{0x04, 0x00, -1, 0x03, 0x0032, 0x0006}, - cmdLutElement{0x04, 0x00, -1, 0x03, 0x0032, 0x0007}, - cmdLutElement{0x04, 0x00, -1, 0x03, 0x0032, 0x0008}, - cmdLutElement{0x04, 0x00, -1, 0x03, 0x0032, 0x0009}, - cmdLutElement{0x05, 0x00, -1, 0x00, 0x0042, 0x0002}, - cmdLutElement{0x05, 0x00, -1, 0x01, 0x0042, 0x0003}, - cmdLutElement{0x05, 0x00, -1, 0x02, 0x0042, 0x0004}, - cmdLutElement{0x05, 0x00, -1, 0x03, 0x0042, 0x0005}, - cmdLutElement{0x05, 0x00, -1, 0x03, 0x0042, 0x0006}, - cmdLutElement{0x05, 0x00, -1, 0x03, 0x0042, 0x0007}, - cmdLutElement{0x05, 0x00, -1, 0x03, 0x0042, 0x0008}, - cmdLutElement{0x05, 0x00, -1, 0x03, 0x0042, 0x0009}, - cmdLutElement{0x05, 0x00, -1, 0x00, 0x0062, 0x0002}, - cmdLutElement{0x05, 0x00, -1, 0x01, 0x0062, 0x0003}, - cmdLutElement{0x05, 0x00, -1, 0x02, 0x0062, 0x0004}, - cmdLutElement{0x05, 0x00, -1, 0x03, 0x0062, 0x0005}, - cmdLutElement{0x05, 0x00, -1, 0x03, 0x0062, 0x0006}, - cmdLutElement{0x05, 0x00, -1, 0x03, 0x0062, 0x0007}, - cmdLutElement{0x05, 0x00, -1, 0x03, 0x0062, 0x0008}, - cmdLutElement{0x05, 0x00, -1, 0x03, 0x0062, 0x0009}, - cmdLutElement{0x02, 0x01, -1, 0x03, 0x000a, 0x000a}, - cmdLutElement{0x02, 0x01, -1, 0x03, 0x000a, 0x000c}, - cmdLutElement{0x02, 0x02, -1, 0x03, 0x000a, 0x000e}, - cmdLutElement{0x02, 0x02, -1, 0x03, 0x000a, 0x0012}, - cmdLutElement{0x02, 0x03, -1, 0x03, 0x000a, 0x0016}, - cmdLutElement{0x02, 0x03, -1, 0x03, 0x000a, 0x001e}, - cmdLutElement{0x02, 0x04, -1, 0x03, 0x000a, 0x0026}, - cmdLutElement{0x02, 0x04, -1, 0x03, 0x000a, 0x0036}, - cmdLutElement{0x02, 0x01, -1, 0x03, 0x000e, 0x000a}, - cmdLutElement{0x02, 0x01, -1, 0x03, 0x000e, 0x000c}, - cmdLutElement{0x02, 0x02, -1, 0x03, 0x000e, 0x000e}, - cmdLutElement{0x02, 0x02, -1, 0x03, 0x000e, 0x0012}, - cmdLutElement{0x02, 0x03, -1, 0x03, 0x000e, 0x0016}, - cmdLutElement{0x02, 0x03, -1, 0x03, 0x000e, 0x001e}, - cmdLutElement{0x02, 0x04, -1, 0x03, 0x000e, 0x0026}, - cmdLutElement{0x02, 0x04, -1, 0x03, 0x000e, 0x0036}, - cmdLutElement{0x03, 0x01, -1, 0x03, 0x0012, 0x000a}, - cmdLutElement{0x03, 0x01, -1, 0x03, 0x0012, 0x000c}, - cmdLutElement{0x03, 0x02, -1, 0x03, 0x0012, 0x000e}, - cmdLutElement{0x03, 0x02, -1, 0x03, 0x0012, 0x0012}, - cmdLutElement{0x03, 0x03, -1, 0x03, 0x0012, 0x0016}, - cmdLutElement{0x03, 0x03, -1, 0x03, 0x0012, 0x001e}, - cmdLutElement{0x03, 0x04, -1, 0x03, 0x0012, 0x0026}, - cmdLutElement{0x03, 0x04, -1, 0x03, 0x0012, 0x0036}, - cmdLutElement{0x03, 0x01, -1, 0x03, 0x001a, 0x000a}, - cmdLutElement{0x03, 0x01, -1, 0x03, 0x001a, 0x000c}, - cmdLutElement{0x03, 0x02, -1, 0x03, 0x001a, 0x000e}, - cmdLutElement{0x03, 0x02, -1, 0x03, 0x001a, 0x0012}, - cmdLutElement{0x03, 0x03, -1, 0x03, 0x001a, 0x0016}, - cmdLutElement{0x03, 0x03, -1, 0x03, 0x001a, 0x001e}, - cmdLutElement{0x03, 0x04, -1, 0x03, 0x001a, 0x0026}, - cmdLutElement{0x03, 0x04, -1, 0x03, 0x001a, 0x0036}, - cmdLutElement{0x04, 0x01, -1, 0x03, 0x0022, 0x000a}, - cmdLutElement{0x04, 0x01, -1, 0x03, 0x0022, 0x000c}, - cmdLutElement{0x04, 0x02, -1, 0x03, 0x0022, 0x000e}, - cmdLutElement{0x04, 0x02, -1, 0x03, 0x0022, 0x0012}, - cmdLutElement{0x04, 0x03, -1, 0x03, 0x0022, 0x0016}, - cmdLutElement{0x04, 0x03, -1, 0x03, 0x0022, 0x001e}, - cmdLutElement{0x04, 0x04, -1, 0x03, 0x0022, 0x0026}, - cmdLutElement{0x04, 0x04, -1, 0x03, 0x0022, 0x0036}, - cmdLutElement{0x04, 0x01, -1, 0x03, 0x0032, 0x000a}, - cmdLutElement{0x04, 0x01, -1, 0x03, 0x0032, 0x000c}, - cmdLutElement{0x04, 0x02, -1, 0x03, 0x0032, 0x000e}, - cmdLutElement{0x04, 0x02, -1, 0x03, 0x0032, 0x0012}, - cmdLutElement{0x04, 0x03, -1, 0x03, 0x0032, 0x0016}, - cmdLutElement{0x04, 0x03, -1, 0x03, 0x0032, 0x001e}, - cmdLutElement{0x04, 0x04, -1, 0x03, 0x0032, 0x0026}, - cmdLutElement{0x04, 0x04, -1, 0x03, 0x0032, 0x0036}, - cmdLutElement{0x05, 0x01, -1, 0x03, 0x0042, 0x000a}, - cmdLutElement{0x05, 0x01, -1, 0x03, 0x0042, 0x000c}, - cmdLutElement{0x05, 0x02, -1, 0x03, 0x0042, 0x000e}, - cmdLutElement{0x05, 0x02, -1, 0x03, 0x0042, 0x0012}, - cmdLutElement{0x05, 0x03, -1, 0x03, 0x0042, 0x0016}, - cmdLutElement{0x05, 0x03, -1, 0x03, 0x0042, 0x001e}, - cmdLutElement{0x05, 0x04, -1, 0x03, 0x0042, 0x0026}, - cmdLutElement{0x05, 0x04, -1, 0x03, 0x0042, 0x0036}, - cmdLutElement{0x05, 0x01, -1, 0x03, 0x0062, 0x000a}, - cmdLutElement{0x05, 0x01, -1, 0x03, 0x0062, 0x000c}, - cmdLutElement{0x05, 0x02, -1, 0x03, 0x0062, 0x000e}, - cmdLutElement{0x05, 0x02, -1, 0x03, 0x0062, 0x0012}, - cmdLutElement{0x05, 0x03, -1, 0x03, 0x0062, 0x0016}, - cmdLutElement{0x05, 0x03, -1, 0x03, 0x0062, 0x001e}, - cmdLutElement{0x05, 0x04, -1, 0x03, 0x0062, 0x0026}, - cmdLutElement{0x05, 0x04, -1, 0x03, 0x0062, 0x0036}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0000, 0x0046}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0000, 0x0066}, - cmdLutElement{0x00, 0x06, -1, 0x03, 0x0000, 0x0086}, - cmdLutElement{0x00, 0x07, -1, 0x03, 0x0000, 0x00c6}, - cmdLutElement{0x00, 0x08, -1, 0x03, 0x0000, 0x0146}, - cmdLutElement{0x00, 0x09, -1, 0x03, 0x0000, 0x0246}, - cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0000, 0x0446}, - cmdLutElement{0x00, 0x18, -1, 0x03, 0x0000, 0x0846}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0001, 0x0046}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0001, 0x0066}, - cmdLutElement{0x00, 0x06, -1, 0x03, 0x0001, 0x0086}, - cmdLutElement{0x00, 0x07, -1, 0x03, 0x0001, 0x00c6}, - cmdLutElement{0x00, 0x08, -1, 0x03, 0x0001, 0x0146}, - cmdLutElement{0x00, 0x09, -1, 0x03, 0x0001, 0x0246}, - cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0001, 0x0446}, - cmdLutElement{0x00, 0x18, -1, 0x03, 0x0001, 0x0846}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0002, 0x0046}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0002, 0x0066}, - cmdLutElement{0x00, 0x06, -1, 0x03, 0x0002, 0x0086}, - cmdLutElement{0x00, 0x07, -1, 0x03, 0x0002, 0x00c6}, - cmdLutElement{0x00, 0x08, -1, 0x03, 0x0002, 0x0146}, - cmdLutElement{0x00, 0x09, -1, 0x03, 0x0002, 0x0246}, - cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0002, 0x0446}, - cmdLutElement{0x00, 0x18, -1, 0x03, 0x0002, 0x0846}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0003, 0x0046}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0003, 0x0066}, - cmdLutElement{0x00, 0x06, -1, 0x03, 0x0003, 0x0086}, - cmdLutElement{0x00, 0x07, -1, 0x03, 0x0003, 0x00c6}, - cmdLutElement{0x00, 0x08, -1, 0x03, 0x0003, 0x0146}, - cmdLutElement{0x00, 0x09, -1, 0x03, 0x0003, 0x0246}, - cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0003, 0x0446}, - cmdLutElement{0x00, 0x18, -1, 0x03, 0x0003, 0x0846}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0004, 0x0046}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0004, 0x0066}, - cmdLutElement{0x00, 0x06, -1, 0x03, 0x0004, 0x0086}, - cmdLutElement{0x00, 0x07, -1, 0x03, 0x0004, 0x00c6}, - cmdLutElement{0x00, 0x08, -1, 0x03, 0x0004, 0x0146}, - cmdLutElement{0x00, 0x09, -1, 0x03, 0x0004, 0x0246}, - cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0004, 0x0446}, - cmdLutElement{0x00, 0x18, -1, 0x03, 0x0004, 0x0846}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0005, 0x0046}, - cmdLutElement{0x00, 0x05, -1, 0x03, 0x0005, 0x0066}, - cmdLutElement{0x00, 0x06, -1, 0x03, 0x0005, 0x0086}, - cmdLutElement{0x00, 0x07, -1, 0x03, 0x0005, 0x00c6}, - cmdLutElement{0x00, 0x08, -1, 0x03, 0x0005, 0x0146}, - cmdLutElement{0x00, 0x09, -1, 0x03, 0x0005, 0x0246}, - cmdLutElement{0x00, 0x0a, -1, 0x03, 0x0005, 0x0446}, - cmdLutElement{0x00, 0x18, -1, 0x03, 0x0005, 0x0846}, - cmdLutElement{0x01, 0x05, -1, 0x03, 0x0006, 0x0046}, - cmdLutElement{0x01, 0x05, -1, 0x03, 0x0006, 0x0066}, - cmdLutElement{0x01, 0x06, -1, 0x03, 0x0006, 0x0086}, - cmdLutElement{0x01, 0x07, -1, 0x03, 0x0006, 0x00c6}, - cmdLutElement{0x01, 0x08, -1, 0x03, 0x0006, 0x0146}, - cmdLutElement{0x01, 0x09, -1, 0x03, 0x0006, 0x0246}, - cmdLutElement{0x01, 0x0a, -1, 0x03, 0x0006, 0x0446}, - cmdLutElement{0x01, 0x18, -1, 0x03, 0x0006, 0x0846}, - cmdLutElement{0x01, 0x05, -1, 0x03, 0x0008, 0x0046}, - cmdLutElement{0x01, 0x05, -1, 0x03, 0x0008, 0x0066}, - cmdLutElement{0x01, 0x06, -1, 0x03, 0x0008, 0x0086}, - cmdLutElement{0x01, 0x07, -1, 0x03, 0x0008, 0x00c6}, - cmdLutElement{0x01, 0x08, -1, 0x03, 0x0008, 0x0146}, - cmdLutElement{0x01, 0x09, -1, 0x03, 0x0008, 0x0246}, - cmdLutElement{0x01, 0x0a, -1, 0x03, 0x0008, 0x0446}, - cmdLutElement{0x01, 0x18, -1, 0x03, 0x0008, 0x0846}, - cmdLutElement{0x06, 0x00, -1, 0x00, 0x0082, 0x0002}, - cmdLutElement{0x06, 0x00, -1, 0x01, 0x0082, 0x0003}, - cmdLutElement{0x06, 0x00, -1, 0x02, 0x0082, 0x0004}, - cmdLutElement{0x06, 0x00, -1, 0x03, 0x0082, 0x0005}, - cmdLutElement{0x06, 0x00, -1, 0x03, 0x0082, 0x0006}, - cmdLutElement{0x06, 0x00, -1, 0x03, 0x0082, 0x0007}, - cmdLutElement{0x06, 0x00, -1, 0x03, 0x0082, 0x0008}, - cmdLutElement{0x06, 0x00, -1, 0x03, 0x0082, 0x0009}, - cmdLutElement{0x07, 0x00, -1, 0x00, 0x00c2, 0x0002}, - cmdLutElement{0x07, 0x00, -1, 0x01, 0x00c2, 0x0003}, - cmdLutElement{0x07, 0x00, -1, 0x02, 0x00c2, 0x0004}, - cmdLutElement{0x07, 0x00, -1, 0x03, 0x00c2, 0x0005}, - cmdLutElement{0x07, 0x00, -1, 0x03, 0x00c2, 0x0006}, - cmdLutElement{0x07, 0x00, -1, 0x03, 0x00c2, 0x0007}, - cmdLutElement{0x07, 0x00, -1, 0x03, 0x00c2, 0x0008}, - cmdLutElement{0x07, 0x00, -1, 0x03, 0x00c2, 0x0009}, - cmdLutElement{0x08, 0x00, -1, 0x00, 0x0142, 0x0002}, - cmdLutElement{0x08, 0x00, -1, 0x01, 0x0142, 0x0003}, - cmdLutElement{0x08, 0x00, -1, 0x02, 0x0142, 0x0004}, - cmdLutElement{0x08, 0x00, -1, 0x03, 0x0142, 0x0005}, - cmdLutElement{0x08, 0x00, -1, 0x03, 0x0142, 0x0006}, - cmdLutElement{0x08, 0x00, -1, 0x03, 0x0142, 0x0007}, - cmdLutElement{0x08, 0x00, -1, 0x03, 0x0142, 0x0008}, - cmdLutElement{0x08, 0x00, -1, 0x03, 0x0142, 0x0009}, - cmdLutElement{0x09, 0x00, -1, 0x00, 0x0242, 0x0002}, - cmdLutElement{0x09, 0x00, -1, 0x01, 0x0242, 0x0003}, - cmdLutElement{0x09, 0x00, -1, 0x02, 0x0242, 0x0004}, - cmdLutElement{0x09, 0x00, -1, 0x03, 0x0242, 0x0005}, - cmdLutElement{0x09, 0x00, -1, 0x03, 0x0242, 0x0006}, - cmdLutElement{0x09, 0x00, -1, 0x03, 0x0242, 0x0007}, - cmdLutElement{0x09, 0x00, -1, 0x03, 0x0242, 0x0008}, - cmdLutElement{0x09, 0x00, -1, 0x03, 0x0242, 0x0009}, - cmdLutElement{0x0a, 0x00, -1, 0x00, 0x0442, 0x0002}, - cmdLutElement{0x0a, 0x00, -1, 0x01, 0x0442, 0x0003}, - cmdLutElement{0x0a, 0x00, -1, 0x02, 0x0442, 0x0004}, - cmdLutElement{0x0a, 0x00, -1, 0x03, 0x0442, 0x0005}, - cmdLutElement{0x0a, 0x00, -1, 0x03, 0x0442, 0x0006}, - cmdLutElement{0x0a, 0x00, -1, 0x03, 0x0442, 0x0007}, - cmdLutElement{0x0a, 0x00, -1, 0x03, 0x0442, 0x0008}, - cmdLutElement{0x0a, 0x00, -1, 0x03, 0x0442, 0x0009}, - cmdLutElement{0x0c, 0x00, -1, 0x00, 0x0842, 0x0002}, - cmdLutElement{0x0c, 0x00, -1, 0x01, 0x0842, 0x0003}, - cmdLutElement{0x0c, 0x00, -1, 0x02, 0x0842, 0x0004}, - cmdLutElement{0x0c, 0x00, -1, 0x03, 0x0842, 0x0005}, - cmdLutElement{0x0c, 0x00, -1, 0x03, 0x0842, 0x0006}, - cmdLutElement{0x0c, 0x00, -1, 0x03, 0x0842, 0x0007}, - cmdLutElement{0x0c, 0x00, -1, 0x03, 0x0842, 0x0008}, - cmdLutElement{0x0c, 0x00, -1, 0x03, 0x0842, 0x0009}, - cmdLutElement{0x0e, 0x00, -1, 0x00, 0x1842, 0x0002}, - cmdLutElement{0x0e, 0x00, -1, 0x01, 0x1842, 0x0003}, - cmdLutElement{0x0e, 0x00, -1, 0x02, 0x1842, 0x0004}, - cmdLutElement{0x0e, 0x00, -1, 0x03, 0x1842, 0x0005}, - cmdLutElement{0x0e, 0x00, -1, 0x03, 0x1842, 0x0006}, - cmdLutElement{0x0e, 0x00, -1, 0x03, 0x1842, 0x0007}, - cmdLutElement{0x0e, 0x00, -1, 0x03, 0x1842, 0x0008}, - cmdLutElement{0x0e, 0x00, -1, 0x03, 0x1842, 0x0009}, - cmdLutElement{0x18, 0x00, -1, 0x00, 0x5842, 0x0002}, - cmdLutElement{0x18, 0x00, -1, 0x01, 0x5842, 0x0003}, - cmdLutElement{0x18, 0x00, -1, 0x02, 0x5842, 0x0004}, - cmdLutElement{0x18, 0x00, -1, 0x03, 0x5842, 0x0005}, - cmdLutElement{0x18, 0x00, -1, 0x03, 0x5842, 0x0006}, - cmdLutElement{0x18, 0x00, -1, 0x03, 0x5842, 0x0007}, - cmdLutElement{0x18, 0x00, -1, 0x03, 0x5842, 0x0008}, - cmdLutElement{0x18, 0x00, -1, 0x03, 0x5842, 0x0009}, - cmdLutElement{0x02, 0x05, -1, 0x03, 0x000a, 0x0046}, - cmdLutElement{0x02, 0x05, -1, 0x03, 0x000a, 0x0066}, - cmdLutElement{0x02, 0x06, -1, 0x03, 0x000a, 0x0086}, - cmdLutElement{0x02, 0x07, -1, 0x03, 0x000a, 0x00c6}, - cmdLutElement{0x02, 0x08, -1, 0x03, 0x000a, 0x0146}, - cmdLutElement{0x02, 0x09, -1, 0x03, 0x000a, 0x0246}, - cmdLutElement{0x02, 0x0a, -1, 0x03, 0x000a, 0x0446}, - cmdLutElement{0x02, 0x18, -1, 0x03, 0x000a, 0x0846}, - cmdLutElement{0x02, 0x05, -1, 0x03, 0x000e, 0x0046}, - cmdLutElement{0x02, 0x05, -1, 0x03, 0x000e, 0x0066}, - cmdLutElement{0x02, 0x06, -1, 0x03, 0x000e, 0x0086}, - cmdLutElement{0x02, 0x07, -1, 0x03, 0x000e, 0x00c6}, - cmdLutElement{0x02, 0x08, -1, 0x03, 0x000e, 0x0146}, - cmdLutElement{0x02, 0x09, -1, 0x03, 0x000e, 0x0246}, - cmdLutElement{0x02, 0x0a, -1, 0x03, 0x000e, 0x0446}, - cmdLutElement{0x02, 0x18, -1, 0x03, 0x000e, 0x0846}, - cmdLutElement{0x03, 0x05, -1, 0x03, 0x0012, 0x0046}, - cmdLutElement{0x03, 0x05, -1, 0x03, 0x0012, 0x0066}, - cmdLutElement{0x03, 0x06, -1, 0x03, 0x0012, 0x0086}, - cmdLutElement{0x03, 0x07, -1, 0x03, 0x0012, 0x00c6}, - cmdLutElement{0x03, 0x08, -1, 0x03, 0x0012, 0x0146}, - cmdLutElement{0x03, 0x09, -1, 0x03, 0x0012, 0x0246}, - cmdLutElement{0x03, 0x0a, -1, 0x03, 0x0012, 0x0446}, - cmdLutElement{0x03, 0x18, -1, 0x03, 0x0012, 0x0846}, - cmdLutElement{0x03, 0x05, -1, 0x03, 0x001a, 0x0046}, - cmdLutElement{0x03, 0x05, -1, 0x03, 0x001a, 0x0066}, - cmdLutElement{0x03, 0x06, -1, 0x03, 0x001a, 0x0086}, - cmdLutElement{0x03, 0x07, -1, 0x03, 0x001a, 0x00c6}, - cmdLutElement{0x03, 0x08, -1, 0x03, 0x001a, 0x0146}, - cmdLutElement{0x03, 0x09, -1, 0x03, 0x001a, 0x0246}, - cmdLutElement{0x03, 0x0a, -1, 0x03, 0x001a, 0x0446}, - cmdLutElement{0x03, 0x18, -1, 0x03, 0x001a, 0x0846}, - cmdLutElement{0x04, 0x05, -1, 0x03, 0x0022, 0x0046}, - cmdLutElement{0x04, 0x05, -1, 0x03, 0x0022, 0x0066}, - cmdLutElement{0x04, 0x06, -1, 0x03, 0x0022, 0x0086}, - cmdLutElement{0x04, 0x07, -1, 0x03, 0x0022, 0x00c6}, - cmdLutElement{0x04, 0x08, -1, 0x03, 0x0022, 0x0146}, - cmdLutElement{0x04, 0x09, -1, 0x03, 0x0022, 0x0246}, - cmdLutElement{0x04, 0x0a, -1, 0x03, 0x0022, 0x0446}, - cmdLutElement{0x04, 0x18, -1, 0x03, 0x0022, 0x0846}, - cmdLutElement{0x04, 0x05, -1, 0x03, 0x0032, 0x0046}, - cmdLutElement{0x04, 0x05, -1, 0x03, 0x0032, 0x0066}, - cmdLutElement{0x04, 0x06, -1, 0x03, 0x0032, 0x0086}, - cmdLutElement{0x04, 0x07, -1, 0x03, 0x0032, 0x00c6}, - cmdLutElement{0x04, 0x08, -1, 0x03, 0x0032, 0x0146}, - cmdLutElement{0x04, 0x09, -1, 0x03, 0x0032, 0x0246}, - cmdLutElement{0x04, 0x0a, -1, 0x03, 0x0032, 0x0446}, - cmdLutElement{0x04, 0x18, -1, 0x03, 0x0032, 0x0846}, - cmdLutElement{0x05, 0x05, -1, 0x03, 0x0042, 0x0046}, - cmdLutElement{0x05, 0x05, -1, 0x03, 0x0042, 0x0066}, - cmdLutElement{0x05, 0x06, -1, 0x03, 0x0042, 0x0086}, - cmdLutElement{0x05, 0x07, -1, 0x03, 0x0042, 0x00c6}, - cmdLutElement{0x05, 0x08, -1, 0x03, 0x0042, 0x0146}, - cmdLutElement{0x05, 0x09, -1, 0x03, 0x0042, 0x0246}, - cmdLutElement{0x05, 0x0a, -1, 0x03, 0x0042, 0x0446}, - cmdLutElement{0x05, 0x18, -1, 0x03, 0x0042, 0x0846}, - cmdLutElement{0x05, 0x05, -1, 0x03, 0x0062, 0x0046}, - cmdLutElement{0x05, 0x05, -1, 0x03, 0x0062, 0x0066}, - cmdLutElement{0x05, 0x06, -1, 0x03, 0x0062, 0x0086}, - cmdLutElement{0x05, 0x07, -1, 0x03, 0x0062, 0x00c6}, - cmdLutElement{0x05, 0x08, -1, 0x03, 0x0062, 0x0146}, - cmdLutElement{0x05, 0x09, -1, 0x03, 0x0062, 0x0246}, - cmdLutElement{0x05, 0x0a, -1, 0x03, 0x0062, 0x0446}, - cmdLutElement{0x05, 0x18, -1, 0x03, 0x0062, 0x0846}, - cmdLutElement{0x06, 0x01, -1, 0x03, 0x0082, 0x000a}, - cmdLutElement{0x06, 0x01, -1, 0x03, 0x0082, 0x000c}, - cmdLutElement{0x06, 0x02, -1, 0x03, 0x0082, 0x000e}, - cmdLutElement{0x06, 0x02, -1, 0x03, 0x0082, 0x0012}, - cmdLutElement{0x06, 0x03, -1, 0x03, 0x0082, 0x0016}, - cmdLutElement{0x06, 0x03, -1, 0x03, 0x0082, 0x001e}, - cmdLutElement{0x06, 0x04, -1, 0x03, 0x0082, 0x0026}, - cmdLutElement{0x06, 0x04, -1, 0x03, 0x0082, 0x0036}, - cmdLutElement{0x07, 0x01, -1, 0x03, 0x00c2, 0x000a}, - cmdLutElement{0x07, 0x01, -1, 0x03, 0x00c2, 0x000c}, - cmdLutElement{0x07, 0x02, -1, 0x03, 0x00c2, 0x000e}, - cmdLutElement{0x07, 0x02, -1, 0x03, 0x00c2, 0x0012}, - cmdLutElement{0x07, 0x03, -1, 0x03, 0x00c2, 0x0016}, - cmdLutElement{0x07, 0x03, -1, 0x03, 0x00c2, 0x001e}, - cmdLutElement{0x07, 0x04, -1, 0x03, 0x00c2, 0x0026}, - cmdLutElement{0x07, 0x04, -1, 0x03, 0x00c2, 0x0036}, - cmdLutElement{0x08, 0x01, -1, 0x03, 0x0142, 0x000a}, - cmdLutElement{0x08, 0x01, -1, 0x03, 0x0142, 0x000c}, - cmdLutElement{0x08, 0x02, -1, 0x03, 0x0142, 0x000e}, - cmdLutElement{0x08, 0x02, -1, 0x03, 0x0142, 0x0012}, - cmdLutElement{0x08, 0x03, -1, 0x03, 0x0142, 0x0016}, - cmdLutElement{0x08, 0x03, -1, 0x03, 0x0142, 0x001e}, - cmdLutElement{0x08, 0x04, -1, 0x03, 0x0142, 0x0026}, - cmdLutElement{0x08, 0x04, -1, 0x03, 0x0142, 0x0036}, - cmdLutElement{0x09, 0x01, -1, 0x03, 0x0242, 0x000a}, - cmdLutElement{0x09, 0x01, -1, 0x03, 0x0242, 0x000c}, - cmdLutElement{0x09, 0x02, -1, 0x03, 0x0242, 0x000e}, - cmdLutElement{0x09, 0x02, -1, 0x03, 0x0242, 0x0012}, - cmdLutElement{0x09, 0x03, -1, 0x03, 0x0242, 0x0016}, - cmdLutElement{0x09, 0x03, -1, 0x03, 0x0242, 0x001e}, - cmdLutElement{0x09, 0x04, -1, 0x03, 0x0242, 0x0026}, - cmdLutElement{0x09, 0x04, -1, 0x03, 0x0242, 0x0036}, - cmdLutElement{0x0a, 0x01, -1, 0x03, 0x0442, 0x000a}, - cmdLutElement{0x0a, 0x01, -1, 0x03, 0x0442, 0x000c}, - cmdLutElement{0x0a, 0x02, -1, 0x03, 0x0442, 0x000e}, - cmdLutElement{0x0a, 0x02, -1, 0x03, 0x0442, 0x0012}, - cmdLutElement{0x0a, 0x03, -1, 0x03, 0x0442, 0x0016}, - cmdLutElement{0x0a, 0x03, -1, 0x03, 0x0442, 0x001e}, - cmdLutElement{0x0a, 0x04, -1, 0x03, 0x0442, 0x0026}, - cmdLutElement{0x0a, 0x04, -1, 0x03, 0x0442, 0x0036}, - cmdLutElement{0x0c, 0x01, -1, 0x03, 0x0842, 0x000a}, - cmdLutElement{0x0c, 0x01, -1, 0x03, 0x0842, 0x000c}, - cmdLutElement{0x0c, 0x02, -1, 0x03, 0x0842, 0x000e}, - cmdLutElement{0x0c, 0x02, -1, 0x03, 0x0842, 0x0012}, - cmdLutElement{0x0c, 0x03, -1, 0x03, 0x0842, 0x0016}, - cmdLutElement{0x0c, 0x03, -1, 0x03, 0x0842, 0x001e}, - cmdLutElement{0x0c, 0x04, -1, 0x03, 0x0842, 0x0026}, - cmdLutElement{0x0c, 0x04, -1, 0x03, 0x0842, 0x0036}, - cmdLutElement{0x0e, 0x01, -1, 0x03, 0x1842, 0x000a}, - cmdLutElement{0x0e, 0x01, -1, 0x03, 0x1842, 0x000c}, - cmdLutElement{0x0e, 0x02, -1, 0x03, 0x1842, 0x000e}, - cmdLutElement{0x0e, 0x02, -1, 0x03, 0x1842, 0x0012}, - cmdLutElement{0x0e, 0x03, -1, 0x03, 0x1842, 0x0016}, - cmdLutElement{0x0e, 0x03, -1, 0x03, 0x1842, 0x001e}, - cmdLutElement{0x0e, 0x04, -1, 0x03, 0x1842, 0x0026}, - cmdLutElement{0x0e, 0x04, -1, 0x03, 0x1842, 0x0036}, - cmdLutElement{0x18, 0x01, -1, 0x03, 0x5842, 0x000a}, - cmdLutElement{0x18, 0x01, -1, 0x03, 0x5842, 0x000c}, - cmdLutElement{0x18, 0x02, -1, 0x03, 0x5842, 0x000e}, - cmdLutElement{0x18, 0x02, -1, 0x03, 0x5842, 0x0012}, - cmdLutElement{0x18, 0x03, -1, 0x03, 0x5842, 0x0016}, - cmdLutElement{0x18, 0x03, -1, 0x03, 0x5842, 0x001e}, - cmdLutElement{0x18, 0x04, -1, 0x03, 0x5842, 0x0026}, - cmdLutElement{0x18, 0x04, -1, 0x03, 0x5842, 0x0036}, - cmdLutElement{0x06, 0x05, -1, 0x03, 0x0082, 0x0046}, - cmdLutElement{0x06, 0x05, -1, 0x03, 0x0082, 0x0066}, - cmdLutElement{0x06, 0x06, -1, 0x03, 0x0082, 0x0086}, - cmdLutElement{0x06, 0x07, -1, 0x03, 0x0082, 0x00c6}, - cmdLutElement{0x06, 0x08, -1, 0x03, 0x0082, 0x0146}, - cmdLutElement{0x06, 0x09, -1, 0x03, 0x0082, 0x0246}, - cmdLutElement{0x06, 0x0a, -1, 0x03, 0x0082, 0x0446}, - cmdLutElement{0x06, 0x18, -1, 0x03, 0x0082, 0x0846}, - cmdLutElement{0x07, 0x05, -1, 0x03, 0x00c2, 0x0046}, - cmdLutElement{0x07, 0x05, -1, 0x03, 0x00c2, 0x0066}, - cmdLutElement{0x07, 0x06, -1, 0x03, 0x00c2, 0x0086}, - cmdLutElement{0x07, 0x07, -1, 0x03, 0x00c2, 0x00c6}, - cmdLutElement{0x07, 0x08, -1, 0x03, 0x00c2, 0x0146}, - cmdLutElement{0x07, 0x09, -1, 0x03, 0x00c2, 0x0246}, - cmdLutElement{0x07, 0x0a, -1, 0x03, 0x00c2, 0x0446}, - cmdLutElement{0x07, 0x18, -1, 0x03, 0x00c2, 0x0846}, - cmdLutElement{0x08, 0x05, -1, 0x03, 0x0142, 0x0046}, - cmdLutElement{0x08, 0x05, -1, 0x03, 0x0142, 0x0066}, - cmdLutElement{0x08, 0x06, -1, 0x03, 0x0142, 0x0086}, - cmdLutElement{0x08, 0x07, -1, 0x03, 0x0142, 0x00c6}, - cmdLutElement{0x08, 0x08, -1, 0x03, 0x0142, 0x0146}, - cmdLutElement{0x08, 0x09, -1, 0x03, 0x0142, 0x0246}, - cmdLutElement{0x08, 0x0a, -1, 0x03, 0x0142, 0x0446}, - cmdLutElement{0x08, 0x18, -1, 0x03, 0x0142, 0x0846}, - cmdLutElement{0x09, 0x05, -1, 0x03, 0x0242, 0x0046}, - cmdLutElement{0x09, 0x05, -1, 0x03, 0x0242, 0x0066}, - cmdLutElement{0x09, 0x06, -1, 0x03, 0x0242, 0x0086}, - cmdLutElement{0x09, 0x07, -1, 0x03, 0x0242, 0x00c6}, - cmdLutElement{0x09, 0x08, -1, 0x03, 0x0242, 0x0146}, - cmdLutElement{0x09, 0x09, -1, 0x03, 0x0242, 0x0246}, - cmdLutElement{0x09, 0x0a, -1, 0x03, 0x0242, 0x0446}, - cmdLutElement{0x09, 0x18, -1, 0x03, 0x0242, 0x0846}, - cmdLutElement{0x0a, 0x05, -1, 0x03, 0x0442, 0x0046}, - cmdLutElement{0x0a, 0x05, -1, 0x03, 0x0442, 0x0066}, - cmdLutElement{0x0a, 0x06, -1, 0x03, 0x0442, 0x0086}, - cmdLutElement{0x0a, 0x07, -1, 0x03, 0x0442, 0x00c6}, - cmdLutElement{0x0a, 0x08, -1, 0x03, 0x0442, 0x0146}, - cmdLutElement{0x0a, 0x09, -1, 0x03, 0x0442, 0x0246}, - cmdLutElement{0x0a, 0x0a, -1, 0x03, 0x0442, 0x0446}, - cmdLutElement{0x0a, 0x18, -1, 0x03, 0x0442, 0x0846}, - cmdLutElement{0x0c, 0x05, -1, 0x03, 0x0842, 0x0046}, - cmdLutElement{0x0c, 0x05, -1, 0x03, 0x0842, 0x0066}, - cmdLutElement{0x0c, 0x06, -1, 0x03, 0x0842, 0x0086}, - cmdLutElement{0x0c, 0x07, -1, 0x03, 0x0842, 0x00c6}, - cmdLutElement{0x0c, 0x08, -1, 0x03, 0x0842, 0x0146}, - cmdLutElement{0x0c, 0x09, -1, 0x03, 0x0842, 0x0246}, - cmdLutElement{0x0c, 0x0a, -1, 0x03, 0x0842, 0x0446}, - cmdLutElement{0x0c, 0x18, -1, 0x03, 0x0842, 0x0846}, - cmdLutElement{0x0e, 0x05, -1, 0x03, 0x1842, 0x0046}, - cmdLutElement{0x0e, 0x05, -1, 0x03, 0x1842, 0x0066}, - cmdLutElement{0x0e, 0x06, -1, 0x03, 0x1842, 0x0086}, - cmdLutElement{0x0e, 0x07, -1, 0x03, 0x1842, 0x00c6}, - cmdLutElement{0x0e, 0x08, -1, 0x03, 0x1842, 0x0146}, - cmdLutElement{0x0e, 0x09, -1, 0x03, 0x1842, 0x0246}, - cmdLutElement{0x0e, 0x0a, -1, 0x03, 0x1842, 0x0446}, - cmdLutElement{0x0e, 0x18, -1, 0x03, 0x1842, 0x0846}, - cmdLutElement{0x18, 0x05, -1, 0x03, 0x5842, 0x0046}, - cmdLutElement{0x18, 0x05, -1, 0x03, 0x5842, 0x0066}, - cmdLutElement{0x18, 0x06, -1, 0x03, 0x5842, 0x0086}, - cmdLutElement{0x18, 0x07, -1, 0x03, 0x5842, 0x00c6}, - cmdLutElement{0x18, 0x08, -1, 0x03, 0x5842, 0x0146}, - cmdLutElement{0x18, 0x09, -1, 0x03, 0x5842, 0x0246}, - cmdLutElement{0x18, 0x0a, -1, 0x03, 0x5842, 0x0446}, - cmdLutElement{0x18, 0x18, -1, 0x03, 0x5842, 0x0846}, -} diff --git a/src/vendor/github.com/andybalholm/brotli/quality.go b/src/vendor/github.com/andybalholm/brotli/quality.go deleted file mode 100644 index 49709a38..00000000 --- a/src/vendor/github.com/andybalholm/brotli/quality.go +++ /dev/null @@ -1,196 +0,0 @@ -package brotli - -const fastOnePassCompressionQuality = 0 - -const fastTwoPassCompressionQuality = 1 - -const zopflificationQuality = 10 - -const hqZopflificationQuality = 11 - -const maxQualityForStaticEntropyCodes = 2 - -const minQualityForBlockSplit = 4 - -const minQualityForNonzeroDistanceParams = 4 - -const minQualityForOptimizeHistograms = 4 - -const minQualityForExtensiveReferenceSearch = 5 - -const minQualityForContextModeling = 5 - -const minQualityForHqContextModeling = 7 - -const minQualityForHqBlockSplitting = 10 - -/* For quality below MIN_QUALITY_FOR_BLOCK_SPLIT there is no block splitting, - so we buffer at most this much literals and commands. */ -const maxNumDelayedSymbols = 0x2FFF - -/* Returns hash-table size for quality levels 0 and 1. */ -func maxHashTableSize(quality int) uint { - if quality == fastOnePassCompressionQuality { - return 1 << 15 - } else { - return 1 << 17 - } -} - -/* The maximum length for which the zopflification uses distinct distances. */ -const maxZopfliLenQuality10 = 150 - -const maxZopfliLenQuality11 = 325 - -/* Do not thoroughly search when a long copy is found. */ -const longCopyQuickStep = 16384 - -func maxZopfliLen(params *encoderParams) uint { - if params.quality <= 10 { - return maxZopfliLenQuality10 - } else { - return maxZopfliLenQuality11 - } -} - -/* Number of best candidates to evaluate to expand Zopfli chain. */ -func maxZopfliCandidates(params *encoderParams) uint { - if params.quality <= 10 { - return 1 - } else { - return 5 - } -} - -func sanitizeParams(params *encoderParams) { - params.quality = brotli_min_int(maxQuality, brotli_max_int(minQuality, params.quality)) - if params.quality <= maxQualityForStaticEntropyCodes { - params.large_window = false - } - - if params.lgwin < minWindowBits { - params.lgwin = minWindowBits - } else { - var max_lgwin int - if params.large_window { - max_lgwin = largeMaxWindowBits - } else { - max_lgwin = maxWindowBits - } - if params.lgwin > uint(max_lgwin) { - params.lgwin = uint(max_lgwin) - } - } -} - -/* Returns optimized lg_block value. */ -func computeLgBlock(params *encoderParams) int { - var lgblock int = params.lgblock - if params.quality == fastOnePassCompressionQuality || params.quality == fastTwoPassCompressionQuality { - lgblock = int(params.lgwin) - } else if params.quality < minQualityForBlockSplit { - lgblock = 14 - } else if lgblock == 0 { - lgblock = 16 - if params.quality >= 9 && params.lgwin > uint(lgblock) { - lgblock = brotli_min_int(18, int(params.lgwin)) - } - } else { - lgblock = brotli_min_int(maxInputBlockBits, brotli_max_int(minInputBlockBits, lgblock)) - } - - return lgblock -} - -/* Returns log2 of the size of main ring buffer area. - Allocate at least lgwin + 1 bits for the ring buffer so that the newly - added block fits there completely and we still get lgwin bits and at least - read_block_size_bits + 1 bits because the copy tail length needs to be - smaller than ring-buffer size. */ -func computeRbBits(params *encoderParams) int { - return 1 + brotli_max_int(int(params.lgwin), params.lgblock) -} - -func maxMetablockSize(params *encoderParams) uint { - var bits int = brotli_min_int(computeRbBits(params), maxInputBlockBits) - return uint(1) << uint(bits) -} - -/* When searching for backward references and have not seen matches for a long - time, we can skip some match lookups. Unsuccessful match lookups are very - expensive and this kind of a heuristic speeds up compression quite a lot. - At first 8 byte strides are taken and every second byte is put to hasher. - After 4x more literals stride by 16 bytes, every put 4-th byte to hasher. - Applied only to qualities 2 to 9. */ -func literalSpreeLengthForSparseSearch(params *encoderParams) uint { - if params.quality < 9 { - return 64 - } else { - return 512 - } -} - -func chooseHasher(params *encoderParams, hparams *hasherParams) { - if params.quality > 9 { - hparams.type_ = 10 - } else if params.quality == 4 && params.size_hint >= 1<<20 { - hparams.type_ = 54 - } else if params.quality < 5 { - hparams.type_ = params.quality - } else if params.lgwin <= 16 { - if params.quality < 7 { - hparams.type_ = 40 - } else if params.quality < 9 { - hparams.type_ = 41 - } else { - hparams.type_ = 42 - } - } else if params.size_hint >= 1<<20 && params.lgwin >= 19 { - hparams.type_ = 6 - hparams.block_bits = params.quality - 1 - hparams.bucket_bits = 15 - hparams.hash_len = 5 - if params.quality < 7 { - hparams.num_last_distances_to_check = 4 - } else if params.quality < 9 { - hparams.num_last_distances_to_check = 10 - } else { - hparams.num_last_distances_to_check = 16 - } - } else { - hparams.type_ = 5 - hparams.block_bits = params.quality - 1 - if params.quality < 7 { - hparams.bucket_bits = 14 - } else { - hparams.bucket_bits = 15 - } - if params.quality < 7 { - hparams.num_last_distances_to_check = 4 - } else if params.quality < 9 { - hparams.num_last_distances_to_check = 10 - } else { - hparams.num_last_distances_to_check = 16 - } - } - - if params.lgwin > 24 { - /* Different hashers for large window brotli: not for qualities <= 2, - these are too fast for large window. Not for qualities >= 10: their - hasher already works well with large window. So the changes are: - H3 --> H35: for quality 3. - H54 --> H55: for quality 4 with size hint > 1MB - H6 --> H65: for qualities 5, 6, 7, 8, 9. */ - if hparams.type_ == 3 { - hparams.type_ = 35 - } - - if hparams.type_ == 54 { - hparams.type_ = 55 - } - - if hparams.type_ == 6 { - hparams.type_ = 65 - } - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/reader.go b/src/vendor/github.com/andybalholm/brotli/reader.go deleted file mode 100644 index d652f4a1..00000000 --- a/src/vendor/github.com/andybalholm/brotli/reader.go +++ /dev/null @@ -1,126 +0,0 @@ -package brotli - -import ( - "errors" - "io" -) - -type decodeError int - -func (err decodeError) Error() string { - return "brotli: " + string(decoderErrorString(int(err))) -} - -var errExcessiveInput = errors.New("brotli: excessive input") -var errInvalidState = errors.New("brotli: invalid state") - -// readBufSize is a "good" buffer size that avoids excessive round-trips -// between C and Go but doesn't waste too much memory on buffering. -// It is arbitrarily chosen to be equal to the constant used in io.Copy. -const readBufSize = 32 * 1024 - -// NewReader creates a new Reader reading the given reader. -func NewReader(src io.Reader) *Reader { - r := new(Reader) - r.Reset(src) - return r -} - -// Reset discards the Reader's state and makes it equivalent to the result of -// its original state from NewReader, but reading from src instead. -// This permits reusing a Reader rather than allocating a new one. -// Error is always nil -func (r *Reader) Reset(src io.Reader) error { - if r.error_code < 0 { - // There was an unrecoverable error, leaving the Reader's state - // undefined. Clear out everything but the buffers. - *r = Reader{ - buf: r.buf, - block_type_trees: r.block_type_trees, - literal_hgroup: huffmanTreeGroup{ - htrees: r.literal_hgroup.htrees, - codes: r.literal_hgroup.codes, - }, - distance_hgroup: huffmanTreeGroup{ - htrees: r.distance_hgroup.htrees, - codes: r.distance_hgroup.codes, - }, - insert_copy_hgroup: huffmanTreeGroup{ - htrees: r.insert_copy_hgroup.htrees, - codes: r.insert_copy_hgroup.codes, - }, - } - } - - decoderStateInit(r) - r.src = src - if r.buf == nil { - r.buf = make([]byte, readBufSize) - } - return nil -} - -func (r *Reader) Read(p []byte) (n int, err error) { - if !decoderHasMoreOutput(r) && len(r.in) == 0 { - m, readErr := r.src.Read(r.buf) - if m == 0 { - if readErr == io.EOF && r.state != stateDone { - readErr = io.ErrUnexpectedEOF - } - // If readErr is `nil`, we just proxy underlying stream behavior. - return 0, readErr - } - r.in = r.buf[:m] - } - - if len(p) == 0 { - return 0, nil - } - - for { - var written uint - in_len := uint(len(r.in)) - out_len := uint(len(p)) - in_remaining := in_len - out_remaining := out_len - result := decoderDecompressStream(r, &in_remaining, &r.in, &out_remaining, &p) - written = out_len - out_remaining - n = int(written) - - switch result { - case decoderResultSuccess: - if len(r.in) > 0 { - return n, errExcessiveInput - } - return n, nil - case decoderResultError: - return n, decodeError(decoderGetErrorCode(r)) - case decoderResultNeedsMoreOutput: - if n == 0 { - return 0, io.ErrShortBuffer - } - return n, nil - case decoderNeedsMoreInput: - } - - if len(r.in) != 0 { - return 0, errInvalidState - } - - // Calling r.src.Read may block. Don't block if we have data to return. - if n > 0 { - return n, nil - } - - // Top off the buffer. - encN, err := r.src.Read(r.buf) - if encN == 0 { - // Not enough data to complete decoding. - if err == io.EOF { - return 0, io.ErrUnexpectedEOF - } - return 0, err - } - r.in = r.buf[:encN] - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/ringbuffer.go b/src/vendor/github.com/andybalholm/brotli/ringbuffer.go deleted file mode 100644 index 1c8f86fe..00000000 --- a/src/vendor/github.com/andybalholm/brotli/ringbuffer.go +++ /dev/null @@ -1,134 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* A ringBuffer(window_bits, tail_bits) contains `1 << window_bits' bytes of - data in a circular manner: writing a byte writes it to: - `position() % (1 << window_bits)'. - For convenience, the ringBuffer array contains another copy of the - first `1 << tail_bits' bytes: - buffer_[i] == buffer_[i + (1 << window_bits)], if i < (1 << tail_bits), - and another copy of the last two bytes: - buffer_[-1] == buffer_[(1 << window_bits) - 1] and - buffer_[-2] == buffer_[(1 << window_bits) - 2]. */ -type ringBuffer struct { - size_ uint32 - mask_ uint32 - tail_size_ uint32 - total_size_ uint32 - cur_size_ uint32 - pos_ uint32 - data_ []byte - buffer_ []byte -} - -func ringBufferInit(rb *ringBuffer) { - rb.pos_ = 0 -} - -func ringBufferSetup(params *encoderParams, rb *ringBuffer) { - var window_bits int = computeRbBits(params) - var tail_bits int = params.lgblock - *(*uint32)(&rb.size_) = 1 << uint(window_bits) - *(*uint32)(&rb.mask_) = (1 << uint(window_bits)) - 1 - *(*uint32)(&rb.tail_size_) = 1 << uint(tail_bits) - *(*uint32)(&rb.total_size_) = rb.size_ + rb.tail_size_ -} - -const kSlackForEightByteHashingEverywhere uint = 7 - -/* Allocates or re-allocates data_ to the given length + plus some slack - region before and after. Fills the slack regions with zeros. */ -func ringBufferInitBuffer(buflen uint32, rb *ringBuffer) { - var new_data []byte - var i uint - size := 2 + int(buflen) + int(kSlackForEightByteHashingEverywhere) - if cap(rb.data_) < size { - new_data = make([]byte, size) - } else { - new_data = rb.data_[:size] - } - if rb.data_ != nil { - copy(new_data, rb.data_[:2+rb.cur_size_+uint32(kSlackForEightByteHashingEverywhere)]) - } - - rb.data_ = new_data - rb.cur_size_ = buflen - rb.buffer_ = rb.data_[2:] - rb.data_[1] = 0 - rb.data_[0] = rb.data_[1] - for i = 0; i < kSlackForEightByteHashingEverywhere; i++ { - rb.buffer_[rb.cur_size_+uint32(i)] = 0 - } -} - -func ringBufferWriteTail(bytes []byte, n uint, rb *ringBuffer) { - var masked_pos uint = uint(rb.pos_ & rb.mask_) - if uint32(masked_pos) < rb.tail_size_ { - /* Just fill the tail buffer with the beginning data. */ - var p uint = uint(rb.size_ + uint32(masked_pos)) - copy(rb.buffer_[p:], bytes[:brotli_min_size_t(n, uint(rb.tail_size_-uint32(masked_pos)))]) - } -} - -/* Push bytes into the ring buffer. */ -func ringBufferWrite(bytes []byte, n uint, rb *ringBuffer) { - if rb.pos_ == 0 && uint32(n) < rb.tail_size_ { - /* Special case for the first write: to process the first block, we don't - need to allocate the whole ring-buffer and we don't need the tail - either. However, we do this memory usage optimization only if the - first write is less than the tail size, which is also the input block - size, otherwise it is likely that other blocks will follow and we - will need to reallocate to the full size anyway. */ - rb.pos_ = uint32(n) - - ringBufferInitBuffer(rb.pos_, rb) - copy(rb.buffer_, bytes[:n]) - return - } - - if rb.cur_size_ < rb.total_size_ { - /* Lazily allocate the full buffer. */ - ringBufferInitBuffer(rb.total_size_, rb) - - /* Initialize the last two bytes to zero, so that we don't have to worry - later when we copy the last two bytes to the first two positions. */ - rb.buffer_[rb.size_-2] = 0 - - rb.buffer_[rb.size_-1] = 0 - } - { - var masked_pos uint = uint(rb.pos_ & rb.mask_) - - /* The length of the writes is limited so that we do not need to worry - about a write */ - ringBufferWriteTail(bytes, n, rb) - - if uint32(masked_pos+n) <= rb.size_ { - /* A single write fits. */ - copy(rb.buffer_[masked_pos:], bytes[:n]) - } else { - /* Split into two writes. - Copy into the end of the buffer, including the tail buffer. */ - copy(rb.buffer_[masked_pos:], bytes[:brotli_min_size_t(n, uint(rb.total_size_-uint32(masked_pos)))]) - - /* Copy into the beginning of the buffer */ - copy(rb.buffer_, bytes[rb.size_-uint32(masked_pos):][:uint32(n)-(rb.size_-uint32(masked_pos))]) - } - } - { - var not_first_lap bool = rb.pos_&(1<<31) != 0 - var rb_pos_mask uint32 = (1 << 31) - 1 - rb.data_[0] = rb.buffer_[rb.size_-2] - rb.data_[1] = rb.buffer_[rb.size_-1] - rb.pos_ = (rb.pos_ & rb_pos_mask) + uint32(uint32(n)&rb_pos_mask) - if not_first_lap { - /* Wrap, but preserve not-a-first-lap feature. */ - rb.pos_ |= 1 << 31 - } - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/state.go b/src/vendor/github.com/andybalholm/brotli/state.go deleted file mode 100644 index da26da44..00000000 --- a/src/vendor/github.com/andybalholm/brotli/state.go +++ /dev/null @@ -1,313 +0,0 @@ -package brotli - -import "io" - -/* Copyright 2015 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Brotli state for partial streaming decoding. */ -const ( - stateUninited = iota - stateLargeWindowBits - stateInitialize - stateMetablockBegin - stateMetablockHeader - stateMetablockHeader2 - stateContextModes - stateCommandBegin - stateCommandInner - stateCommandPostDecodeLiterals - stateCommandPostWrapCopy - stateUncompressed - stateMetadata - stateCommandInnerWrite - stateMetablockDone - stateCommandPostWrite1 - stateCommandPostWrite2 - stateHuffmanCode0 - stateHuffmanCode1 - stateHuffmanCode2 - stateHuffmanCode3 - stateContextMap1 - stateContextMap2 - stateTreeGroup - stateDone -) - -const ( - stateMetablockHeaderNone = iota - stateMetablockHeaderEmpty - stateMetablockHeaderNibbles - stateMetablockHeaderSize - stateMetablockHeaderUncompressed - stateMetablockHeaderReserved - stateMetablockHeaderBytes - stateMetablockHeaderMetadata -) - -const ( - stateUncompressedNone = iota - stateUncompressedWrite -) - -const ( - stateTreeGroupNone = iota - stateTreeGroupLoop -) - -const ( - stateContextMapNone = iota - stateContextMapReadPrefix - stateContextMapHuffman - stateContextMapDecode - stateContextMapTransform -) - -const ( - stateHuffmanNone = iota - stateHuffmanSimpleSize - stateHuffmanSimpleRead - stateHuffmanSimpleBuild - stateHuffmanComplex - stateHuffmanLengthSymbols -) - -const ( - stateDecodeUint8None = iota - stateDecodeUint8Short - stateDecodeUint8Long -) - -const ( - stateReadBlockLengthNone = iota - stateReadBlockLengthSuffix -) - -type Reader struct { - src io.Reader - buf []byte // scratch space for reading from src - in []byte // current chunk to decode; usually aliases buf - - state int - loop_counter int - br bitReader - buffer struct { - u64 uint64 - u8 [8]byte - } - buffer_length uint32 - pos int - max_backward_distance int - max_distance int - ringbuffer_size int - ringbuffer_mask int - dist_rb_idx int - dist_rb [4]int - error_code int - sub_loop_counter uint32 - ringbuffer []byte - ringbuffer_end []byte - htree_command []huffmanCode - context_lookup []byte - context_map_slice []byte - dist_context_map_slice []byte - literal_hgroup huffmanTreeGroup - insert_copy_hgroup huffmanTreeGroup - distance_hgroup huffmanTreeGroup - block_type_trees []huffmanCode - block_len_trees []huffmanCode - trivial_literal_context int - distance_context int - meta_block_remaining_len int - block_length_index uint32 - block_length [3]uint32 - num_block_types [3]uint32 - block_type_rb [6]uint32 - distance_postfix_bits uint32 - num_direct_distance_codes uint32 - distance_postfix_mask int - num_dist_htrees uint32 - dist_context_map []byte - literal_htree []huffmanCode - dist_htree_index byte - repeat_code_len uint32 - prev_code_len uint32 - copy_length int - distance_code int - rb_roundtrips uint - partial_pos_out uint - symbol uint32 - repeat uint32 - space uint32 - table [32]huffmanCode - symbol_lists symbolList - symbols_lists_array [huffmanMaxCodeLength + 1 + numCommandSymbols]uint16 - next_symbol [32]int - code_length_code_lengths [codeLengthCodes]byte - code_length_histo [16]uint16 - htree_index int - next []huffmanCode - context_index uint32 - max_run_length_prefix uint32 - code uint32 - context_map_table [huffmanMaxSize272]huffmanCode - substate_metablock_header int - substate_tree_group int - substate_context_map int - substate_uncompressed int - substate_huffman int - substate_decode_uint8 int - substate_read_block_length int - is_last_metablock uint - is_uncompressed uint - is_metadata uint - should_wrap_ringbuffer uint - canny_ringbuffer_allocation uint - large_window bool - size_nibbles uint - window_bits uint32 - new_ringbuffer_size int - num_literal_htrees uint32 - context_map []byte - context_modes []byte - dictionary *dictionary - transforms *transforms - trivial_literal_contexts [8]uint32 -} - -func decoderStateInit(s *Reader) bool { - s.error_code = 0 /* BROTLI_DECODER_NO_ERROR */ - - initBitReader(&s.br) - s.state = stateUninited - s.large_window = false - s.substate_metablock_header = stateMetablockHeaderNone - s.substate_tree_group = stateTreeGroupNone - s.substate_context_map = stateContextMapNone - s.substate_uncompressed = stateUncompressedNone - s.substate_huffman = stateHuffmanNone - s.substate_decode_uint8 = stateDecodeUint8None - s.substate_read_block_length = stateReadBlockLengthNone - - s.buffer_length = 0 - s.loop_counter = 0 - s.pos = 0 - s.rb_roundtrips = 0 - s.partial_pos_out = 0 - - clear(s.block_type_trees) - s.block_len_trees = nil - s.ringbuffer_size = 0 - s.new_ringbuffer_size = 0 - s.ringbuffer_mask = 0 - - s.context_map = nil - s.context_modes = nil - s.dist_context_map = nil - s.context_map_slice = nil - s.dist_context_map_slice = nil - - s.sub_loop_counter = 0 - - cleanupCodes(s) - cleanupHTrees(s) - - s.is_last_metablock = 0 - s.is_uncompressed = 0 - s.is_metadata = 0 - s.should_wrap_ringbuffer = 0 - s.canny_ringbuffer_allocation = 1 - - s.window_bits = 0 - s.max_distance = 0 - s.dist_rb[0] = 16 - s.dist_rb[1] = 15 - s.dist_rb[2] = 11 - s.dist_rb[3] = 4 - s.dist_rb_idx = 0 - - s.symbol_lists.storage = s.symbols_lists_array[:] - s.symbol_lists.offset = huffmanMaxCodeLength + 1 - - s.dictionary = getDictionary() - s.transforms = getTransforms() - - return true -} - -func decoderStateMetablockBegin(s *Reader) { - s.meta_block_remaining_len = 0 - s.block_length[0] = 1 << 24 - s.block_length[1] = 1 << 24 - s.block_length[2] = 1 << 24 - s.num_block_types[0] = 1 - s.num_block_types[1] = 1 - s.num_block_types[2] = 1 - s.block_type_rb[0] = 1 - s.block_type_rb[1] = 0 - s.block_type_rb[2] = 1 - s.block_type_rb[3] = 0 - s.block_type_rb[4] = 1 - s.block_type_rb[5] = 0 - s.context_map = nil - s.context_modes = nil - s.dist_context_map = nil - s.context_map_slice = nil - s.literal_htree = nil - s.dist_context_map_slice = nil - s.dist_htree_index = 0 - s.context_lookup = nil - - cleanupCodes(s) - cleanupHTrees(s) -} - -func decoderStateCleanupAfterMetablock(s *Reader) { - s.context_modes = nil - s.context_map = nil - s.dist_context_map = nil - cleanupHTrees(s) -} - -func decoderHuffmanTreeGroupInit(group *huffmanTreeGroup, alphabet_size uint32, max_symbol uint32, ntrees uint32) { - var max_table_size uint = uint(kMaxHuffmanTableSize[(alphabet_size+31)>>5]) - group.alphabet_size = uint16(alphabet_size) - group.max_symbol = uint16(max_symbol) - group.num_htrees = uint16(ntrees) - - makeCodesBuffer(group, uint(ntrees)*max_table_size) - makeTreesBuffer(group, ntrees) -} - -func makeTreesBuffer(group *huffmanTreeGroup, treesLen uint32) { - if cap(group.htrees) < int(treesLen) { - group.htrees = make([][]huffmanCode, treesLen) - return - } - - group.htrees = group.htrees[:treesLen] -} - -func makeCodesBuffer(group *huffmanTreeGroup, codesLen uint) { - if cap(group.codes) < int(codesLen) { - group.codes = make([]huffmanCode, codesLen) - return - } - - group.codes = group.codes[:codesLen] -} - -func cleanupCodes(s *Reader) { - clear(s.literal_hgroup.codes) - clear(s.insert_copy_hgroup.codes) - clear(s.distance_hgroup.codes) -} - -func cleanupHTrees(s *Reader) { - clear(s.literal_hgroup.htrees) - clear(s.insert_copy_hgroup.htrees) - clear(s.distance_hgroup.htrees) -} diff --git a/src/vendor/github.com/andybalholm/brotli/static_dict.go b/src/vendor/github.com/andybalholm/brotli/static_dict.go deleted file mode 100644 index bc05566d..00000000 --- a/src/vendor/github.com/andybalholm/brotli/static_dict.go +++ /dev/null @@ -1,662 +0,0 @@ -package brotli - -import "encoding/binary" - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Class to model the static dictionary. */ - -const maxStaticDictionaryMatchLen = 37 - -const kInvalidMatch uint32 = 0xFFFFFFF - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ -func hash(data []byte) uint32 { - var h uint32 = binary.LittleEndian.Uint32(data) * kDictHashMul32 - - /* The higher bits contain more mixture from the multiplication, - so we take our results from there. */ - return h >> uint(32-kDictNumBits) -} - -func addMatch(distance uint, len uint, len_code uint, matches []uint32) { - var match uint32 = uint32((distance << 5) + len_code) - matches[len] = brotli_min_uint32_t(matches[len], match) -} - -func dictMatchLength(dict *dictionary, data []byte, id uint, len uint, maxlen uint) uint { - var offset uint = uint(dict.offsets_by_length[len]) + len*id - return findMatchLengthWithLimit(dict.data[offset:], data, brotli_min_size_t(uint(len), maxlen)) -} - -func isMatch(d *dictionary, w dictWord, data []byte, max_length uint) bool { - if uint(w.len) > max_length { - return false - } else { - var offset uint = uint(d.offsets_by_length[w.len]) + uint(w.len)*uint(w.idx) - var dict []byte = d.data[offset:] - if w.transform == 0 { - /* Match against base dictionary word. */ - return findMatchLengthWithLimit(dict, data, uint(w.len)) == uint(w.len) - } else if w.transform == 10 { - /* Match against uppercase first transform. - Note that there are only ASCII uppercase words in the lookup table. */ - return dict[0] >= 'a' && dict[0] <= 'z' && (dict[0]^32) == data[0] && findMatchLengthWithLimit(dict[1:], data[1:], uint(w.len)-1) == uint(w.len-1) - } else { - /* Match against uppercase all transform. - Note that there are only ASCII uppercase words in the lookup table. */ - var i uint - for i = 0; i < uint(w.len); i++ { - if dict[i] >= 'a' && dict[i] <= 'z' { - if (dict[i] ^ 32) != data[i] { - return false - } - } else { - if dict[i] != data[i] { - return false - } - } - } - - return true - } - } -} - -func findAllStaticDictionaryMatches(dict *encoderDictionary, data []byte, min_length uint, max_length uint, matches []uint32) bool { - var has_found_match bool = false - { - var offset uint = uint(dict.buckets[hash(data)]) - var end bool = offset == 0 - for !end { - w := dict.dict_words[offset] - offset++ - var l uint = uint(w.len) & 0x1F - var n uint = uint(1) << dict.words.size_bits_by_length[l] - var id uint = uint(w.idx) - end = !(w.len&0x80 == 0) - w.len = byte(l) - if w.transform == 0 { - var matchlen uint = dictMatchLength(dict.words, data, id, l, max_length) - var s []byte - var minlen uint - var maxlen uint - var len uint - - /* Transform "" + BROTLI_TRANSFORM_IDENTITY + "" */ - if matchlen == l { - addMatch(id, l, l, matches) - has_found_match = true - } - - /* Transforms "" + BROTLI_TRANSFORM_OMIT_LAST_1 + "" and - "" + BROTLI_TRANSFORM_OMIT_LAST_1 + "ing " */ - if matchlen >= l-1 { - addMatch(id+12*n, l-1, l, matches) - if l+2 < max_length && data[l-1] == 'i' && data[l] == 'n' && data[l+1] == 'g' && data[l+2] == ' ' { - addMatch(id+49*n, l+3, l, matches) - } - - has_found_match = true - } - - /* Transform "" + BROTLI_TRANSFORM_OMIT_LAST_# + "" (# = 2 .. 9) */ - minlen = min_length - - if l > 9 { - minlen = brotli_max_size_t(minlen, l-9) - } - maxlen = brotli_min_size_t(matchlen, l-2) - for len = minlen; len <= maxlen; len++ { - var cut uint = l - len - var transform_id uint = (cut << 2) + uint((dict.cutoffTransforms>>(cut*6))&0x3F) - addMatch(id+transform_id*n, uint(len), l, matches) - has_found_match = true - } - - if matchlen < l || l+6 >= max_length { - continue - } - - s = data[l:] - - /* Transforms "" + BROTLI_TRANSFORM_IDENTITY + */ - if s[0] == ' ' { - addMatch(id+n, l+1, l, matches) - if s[1] == 'a' { - if s[2] == ' ' { - addMatch(id+28*n, l+3, l, matches) - } else if s[2] == 's' { - if s[3] == ' ' { - addMatch(id+46*n, l+4, l, matches) - } - } else if s[2] == 't' { - if s[3] == ' ' { - addMatch(id+60*n, l+4, l, matches) - } - } else if s[2] == 'n' { - if s[3] == 'd' && s[4] == ' ' { - addMatch(id+10*n, l+5, l, matches) - } - } - } else if s[1] == 'b' { - if s[2] == 'y' && s[3] == ' ' { - addMatch(id+38*n, l+4, l, matches) - } - } else if s[1] == 'i' { - if s[2] == 'n' { - if s[3] == ' ' { - addMatch(id+16*n, l+4, l, matches) - } - } else if s[2] == 's' { - if s[3] == ' ' { - addMatch(id+47*n, l+4, l, matches) - } - } - } else if s[1] == 'f' { - if s[2] == 'o' { - if s[3] == 'r' && s[4] == ' ' { - addMatch(id+25*n, l+5, l, matches) - } - } else if s[2] == 'r' { - if s[3] == 'o' && s[4] == 'm' && s[5] == ' ' { - addMatch(id+37*n, l+6, l, matches) - } - } - } else if s[1] == 'o' { - if s[2] == 'f' { - if s[3] == ' ' { - addMatch(id+8*n, l+4, l, matches) - } - } else if s[2] == 'n' { - if s[3] == ' ' { - addMatch(id+45*n, l+4, l, matches) - } - } - } else if s[1] == 'n' { - if s[2] == 'o' && s[3] == 't' && s[4] == ' ' { - addMatch(id+80*n, l+5, l, matches) - } - } else if s[1] == 't' { - if s[2] == 'h' { - if s[3] == 'e' { - if s[4] == ' ' { - addMatch(id+5*n, l+5, l, matches) - } - } else if s[3] == 'a' { - if s[4] == 't' && s[5] == ' ' { - addMatch(id+29*n, l+6, l, matches) - } - } - } else if s[2] == 'o' { - if s[3] == ' ' { - addMatch(id+17*n, l+4, l, matches) - } - } - } else if s[1] == 'w' { - if s[2] == 'i' && s[3] == 't' && s[4] == 'h' && s[5] == ' ' { - addMatch(id+35*n, l+6, l, matches) - } - } - } else if s[0] == '"' { - addMatch(id+19*n, l+1, l, matches) - if s[1] == '>' { - addMatch(id+21*n, l+2, l, matches) - } - } else if s[0] == '.' { - addMatch(id+20*n, l+1, l, matches) - if s[1] == ' ' { - addMatch(id+31*n, l+2, l, matches) - if s[2] == 'T' && s[3] == 'h' { - if s[4] == 'e' { - if s[5] == ' ' { - addMatch(id+43*n, l+6, l, matches) - } - } else if s[4] == 'i' { - if s[5] == 's' && s[6] == ' ' { - addMatch(id+75*n, l+7, l, matches) - } - } - } - } - } else if s[0] == ',' { - addMatch(id+76*n, l+1, l, matches) - if s[1] == ' ' { - addMatch(id+14*n, l+2, l, matches) - } - } else if s[0] == '\n' { - addMatch(id+22*n, l+1, l, matches) - if s[1] == '\t' { - addMatch(id+50*n, l+2, l, matches) - } - } else if s[0] == ']' { - addMatch(id+24*n, l+1, l, matches) - } else if s[0] == '\'' { - addMatch(id+36*n, l+1, l, matches) - } else if s[0] == ':' { - addMatch(id+51*n, l+1, l, matches) - } else if s[0] == '(' { - addMatch(id+57*n, l+1, l, matches) - } else if s[0] == '=' { - if s[1] == '"' { - addMatch(id+70*n, l+2, l, matches) - } else if s[1] == '\'' { - addMatch(id+86*n, l+2, l, matches) - } - } else if s[0] == 'a' { - if s[1] == 'l' && s[2] == ' ' { - addMatch(id+84*n, l+3, l, matches) - } - } else if s[0] == 'e' { - if s[1] == 'd' { - if s[2] == ' ' { - addMatch(id+53*n, l+3, l, matches) - } - } else if s[1] == 'r' { - if s[2] == ' ' { - addMatch(id+82*n, l+3, l, matches) - } - } else if s[1] == 's' { - if s[2] == 't' && s[3] == ' ' { - addMatch(id+95*n, l+4, l, matches) - } - } - } else if s[0] == 'f' { - if s[1] == 'u' && s[2] == 'l' && s[3] == ' ' { - addMatch(id+90*n, l+4, l, matches) - } - } else if s[0] == 'i' { - if s[1] == 'v' { - if s[2] == 'e' && s[3] == ' ' { - addMatch(id+92*n, l+4, l, matches) - } - } else if s[1] == 'z' { - if s[2] == 'e' && s[3] == ' ' { - addMatch(id+100*n, l+4, l, matches) - } - } - } else if s[0] == 'l' { - if s[1] == 'e' { - if s[2] == 's' && s[3] == 's' && s[4] == ' ' { - addMatch(id+93*n, l+5, l, matches) - } - } else if s[1] == 'y' { - if s[2] == ' ' { - addMatch(id+61*n, l+3, l, matches) - } - } - } else if s[0] == 'o' { - if s[1] == 'u' && s[2] == 's' && s[3] == ' ' { - addMatch(id+106*n, l+4, l, matches) - } - } - } else { - var is_all_caps bool = (w.transform != transformUppercaseFirst) - /* Set is_all_caps=0 for BROTLI_TRANSFORM_UPPERCASE_FIRST and - is_all_caps=1 otherwise (BROTLI_TRANSFORM_UPPERCASE_ALL) - transform. */ - - var s []byte - if !isMatch(dict.words, w, data, max_length) { - continue - } - - /* Transform "" + kUppercase{First,All} + "" */ - var tmp int - if is_all_caps { - tmp = 44 - } else { - tmp = 9 - } - addMatch(id+uint(tmp)*n, l, l, matches) - - has_found_match = true - if l+1 >= max_length { - continue - } - - /* Transforms "" + kUppercase{First,All} + */ - s = data[l:] - - if s[0] == ' ' { - var tmp int - if is_all_caps { - tmp = 68 - } else { - tmp = 4 - } - addMatch(id+uint(tmp)*n, l+1, l, matches) - } else if s[0] == '"' { - var tmp int - if is_all_caps { - tmp = 87 - } else { - tmp = 66 - } - addMatch(id+uint(tmp)*n, l+1, l, matches) - if s[1] == '>' { - var tmp int - if is_all_caps { - tmp = 97 - } else { - tmp = 69 - } - addMatch(id+uint(tmp)*n, l+2, l, matches) - } - } else if s[0] == '.' { - var tmp int - if is_all_caps { - tmp = 101 - } else { - tmp = 79 - } - addMatch(id+uint(tmp)*n, l+1, l, matches) - if s[1] == ' ' { - var tmp int - if is_all_caps { - tmp = 114 - } else { - tmp = 88 - } - addMatch(id+uint(tmp)*n, l+2, l, matches) - } - } else if s[0] == ',' { - var tmp int - if is_all_caps { - tmp = 112 - } else { - tmp = 99 - } - addMatch(id+uint(tmp)*n, l+1, l, matches) - if s[1] == ' ' { - var tmp int - if is_all_caps { - tmp = 107 - } else { - tmp = 58 - } - addMatch(id+uint(tmp)*n, l+2, l, matches) - } - } else if s[0] == '\'' { - var tmp int - if is_all_caps { - tmp = 94 - } else { - tmp = 74 - } - addMatch(id+uint(tmp)*n, l+1, l, matches) - } else if s[0] == '(' { - var tmp int - if is_all_caps { - tmp = 113 - } else { - tmp = 78 - } - addMatch(id+uint(tmp)*n, l+1, l, matches) - } else if s[0] == '=' { - if s[1] == '"' { - var tmp int - if is_all_caps { - tmp = 105 - } else { - tmp = 104 - } - addMatch(id+uint(tmp)*n, l+2, l, matches) - } else if s[1] == '\'' { - var tmp int - if is_all_caps { - tmp = 116 - } else { - tmp = 108 - } - addMatch(id+uint(tmp)*n, l+2, l, matches) - } - } - } - } - } - - /* Transforms with prefixes " " and "." */ - if max_length >= 5 && (data[0] == ' ' || data[0] == '.') { - var is_space bool = (data[0] == ' ') - var offset uint = uint(dict.buckets[hash(data[1:])]) - var end bool = offset == 0 - for !end { - w := dict.dict_words[offset] - offset++ - var l uint = uint(w.len) & 0x1F - var n uint = uint(1) << dict.words.size_bits_by_length[l] - var id uint = uint(w.idx) - end = !(w.len&0x80 == 0) - w.len = byte(l) - if w.transform == 0 { - var s []byte - if !isMatch(dict.words, w, data[1:], max_length-1) { - continue - } - - /* Transforms " " + BROTLI_TRANSFORM_IDENTITY + "" and - "." + BROTLI_TRANSFORM_IDENTITY + "" */ - var tmp int - if is_space { - tmp = 6 - } else { - tmp = 32 - } - addMatch(id+uint(tmp)*n, l+1, l, matches) - - has_found_match = true - if l+2 >= max_length { - continue - } - - /* Transforms " " + BROTLI_TRANSFORM_IDENTITY + and - "." + BROTLI_TRANSFORM_IDENTITY + - */ - s = data[l+1:] - - if s[0] == ' ' { - var tmp int - if is_space { - tmp = 2 - } else { - tmp = 77 - } - addMatch(id+uint(tmp)*n, l+2, l, matches) - } else if s[0] == '(' { - var tmp int - if is_space { - tmp = 89 - } else { - tmp = 67 - } - addMatch(id+uint(tmp)*n, l+2, l, matches) - } else if is_space { - if s[0] == ',' { - addMatch(id+103*n, l+2, l, matches) - if s[1] == ' ' { - addMatch(id+33*n, l+3, l, matches) - } - } else if s[0] == '.' { - addMatch(id+71*n, l+2, l, matches) - if s[1] == ' ' { - addMatch(id+52*n, l+3, l, matches) - } - } else if s[0] == '=' { - if s[1] == '"' { - addMatch(id+81*n, l+3, l, matches) - } else if s[1] == '\'' { - addMatch(id+98*n, l+3, l, matches) - } - } - } - } else if is_space { - var is_all_caps bool = (w.transform != transformUppercaseFirst) - /* Set is_all_caps=0 for BROTLI_TRANSFORM_UPPERCASE_FIRST and - is_all_caps=1 otherwise (BROTLI_TRANSFORM_UPPERCASE_ALL) - transform. */ - - var s []byte - if !isMatch(dict.words, w, data[1:], max_length-1) { - continue - } - - /* Transforms " " + kUppercase{First,All} + "" */ - var tmp int - if is_all_caps { - tmp = 85 - } else { - tmp = 30 - } - addMatch(id+uint(tmp)*n, l+1, l, matches) - - has_found_match = true - if l+2 >= max_length { - continue - } - - /* Transforms " " + kUppercase{First,All} + */ - s = data[l+1:] - - if s[0] == ' ' { - var tmp int - if is_all_caps { - tmp = 83 - } else { - tmp = 15 - } - addMatch(id+uint(tmp)*n, l+2, l, matches) - } else if s[0] == ',' { - if !is_all_caps { - addMatch(id+109*n, l+2, l, matches) - } - - if s[1] == ' ' { - var tmp int - if is_all_caps { - tmp = 111 - } else { - tmp = 65 - } - addMatch(id+uint(tmp)*n, l+3, l, matches) - } - } else if s[0] == '.' { - var tmp int - if is_all_caps { - tmp = 115 - } else { - tmp = 96 - } - addMatch(id+uint(tmp)*n, l+2, l, matches) - if s[1] == ' ' { - var tmp int - if is_all_caps { - tmp = 117 - } else { - tmp = 91 - } - addMatch(id+uint(tmp)*n, l+3, l, matches) - } - } else if s[0] == '=' { - if s[1] == '"' { - var tmp int - if is_all_caps { - tmp = 110 - } else { - tmp = 118 - } - addMatch(id+uint(tmp)*n, l+3, l, matches) - } else if s[1] == '\'' { - var tmp int - if is_all_caps { - tmp = 119 - } else { - tmp = 120 - } - addMatch(id+uint(tmp)*n, l+3, l, matches) - } - } - } - } - } - - if max_length >= 6 { - /* Transforms with prefixes "e ", "s ", ", " and "\xC2\xA0" */ - if (data[1] == ' ' && (data[0] == 'e' || data[0] == 's' || data[0] == ',')) || (data[0] == 0xC2 && data[1] == 0xA0) { - var offset uint = uint(dict.buckets[hash(data[2:])]) - var end bool = offset == 0 - for !end { - w := dict.dict_words[offset] - offset++ - var l uint = uint(w.len) & 0x1F - var n uint = uint(1) << dict.words.size_bits_by_length[l] - var id uint = uint(w.idx) - end = !(w.len&0x80 == 0) - w.len = byte(l) - if w.transform == 0 && isMatch(dict.words, w, data[2:], max_length-2) { - if data[0] == 0xC2 { - addMatch(id+102*n, l+2, l, matches) - has_found_match = true - } else if l+2 < max_length && data[l+2] == ' ' { - var t uint = 13 - if data[0] == 'e' { - t = 18 - } else if data[0] == 's' { - t = 7 - } - addMatch(id+t*n, l+3, l, matches) - has_found_match = true - } - } - } - } - } - - if max_length >= 9 { - /* Transforms with prefixes " the " and ".com/" */ - if (data[0] == ' ' && data[1] == 't' && data[2] == 'h' && data[3] == 'e' && data[4] == ' ') || (data[0] == '.' && data[1] == 'c' && data[2] == 'o' && data[3] == 'm' && data[4] == '/') { - var offset uint = uint(dict.buckets[hash(data[5:])]) - var end bool = offset == 0 - for !end { - w := dict.dict_words[offset] - offset++ - var l uint = uint(w.len) & 0x1F - var n uint = uint(1) << dict.words.size_bits_by_length[l] - var id uint = uint(w.idx) - end = !(w.len&0x80 == 0) - w.len = byte(l) - if w.transform == 0 && isMatch(dict.words, w, data[5:], max_length-5) { - var tmp int - if data[0] == ' ' { - tmp = 41 - } else { - tmp = 72 - } - addMatch(id+uint(tmp)*n, l+5, l, matches) - has_found_match = true - if l+5 < max_length { - var s []byte = data[l+5:] - if data[0] == ' ' { - if l+8 < max_length && s[0] == ' ' && s[1] == 'o' && s[2] == 'f' && s[3] == ' ' { - addMatch(id+62*n, l+9, l, matches) - if l+12 < max_length && s[4] == 't' && s[5] == 'h' && s[6] == 'e' && s[7] == ' ' { - addMatch(id+73*n, l+13, l, matches) - } - } - } - } - } - } - } - } - - return has_found_match -} diff --git a/src/vendor/github.com/andybalholm/brotli/static_dict_lut.go b/src/vendor/github.com/andybalholm/brotli/static_dict_lut.go deleted file mode 100644 index b33963e9..00000000 --- a/src/vendor/github.com/andybalholm/brotli/static_dict_lut.go +++ /dev/null @@ -1,75094 +0,0 @@ -package brotli - -/* Copyright 2017 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Lookup table for static dictionary and transforms. */ - -type dictWord struct { - len byte - transform byte - idx uint16 -} - -const kDictNumBits int = 15 - -const kDictHashMul32 uint32 = 0x1E35A7BD - -var kStaticDictionaryBuckets = [32768]uint16{ - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3, - 6, - 0, - 0, - 0, - 0, - 0, - 20, - 0, - 0, - 0, - 21, - 0, - 22, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23, - 0, - 0, - 25, - 0, - 29, - 0, - 53, - 0, - 0, - 0, - 0, - 0, - 0, - 55, - 0, - 0, - 0, - 0, - 0, - 0, - 61, - 76, - 0, - 0, - 0, - 94, - 0, - 0, - 0, - 0, - 0, - 0, - 96, - 0, - 97, - 0, - 98, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 99, - 101, - 106, - 108, - 0, - 0, - 0, - 0, - 0, - 110, - 0, - 111, - 112, - 0, - 113, - 118, - 124, - 0, - 0, - 0, - 0, - 0, - 125, - 128, - 0, - 0, - 0, - 0, - 129, - 0, - 0, - 131, - 0, - 0, - 0, - 0, - 0, - 0, - 132, - 0, - 0, - 135, - 0, - 0, - 0, - 137, - 0, - 0, - 0, - 0, - 0, - 138, - 139, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 142, - 143, - 144, - 0, - 0, - 0, - 0, - 0, - 145, - 0, - 0, - 0, - 146, - 149, - 151, - 152, - 0, - 0, - 153, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 154, - 0, - 0, - 0, - 0, - 0, - 0, - 155, - 0, - 0, - 0, - 0, - 160, - 182, - 0, - 0, - 0, - 0, - 0, - 0, - 183, - 0, - 0, - 0, - 188, - 189, - 0, - 0, - 192, - 0, - 0, - 0, - 0, - 0, - 0, - 194, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 197, - 202, - 209, - 0, - 0, - 210, - 0, - 224, - 0, - 0, - 0, - 225, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 231, - 0, - 0, - 0, - 232, - 0, - 240, - 0, - 0, - 242, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 244, - 0, - 0, - 0, - 246, - 0, - 0, - 249, - 251, - 253, - 0, - 0, - 0, - 0, - 0, - 258, - 0, - 0, - 261, - 263, - 0, - 0, - 0, - 267, - 0, - 0, - 268, - 0, - 269, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 271, - 0, - 0, - 0, - 0, - 0, - 0, - 272, - 0, - 273, - 0, - 277, - 0, - 278, - 286, - 0, - 0, - 0, - 0, - 287, - 0, - 289, - 290, - 291, - 0, - 0, - 0, - 295, - 0, - 0, - 296, - 297, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 298, - 0, - 0, - 0, - 299, - 0, - 0, - 305, - 0, - 324, - 0, - 0, - 0, - 0, - 0, - 327, - 0, - 328, - 329, - 0, - 0, - 0, - 0, - 336, - 0, - 0, - 340, - 0, - 341, - 342, - 343, - 0, - 0, - 346, - 0, - 348, - 0, - 0, - 0, - 0, - 0, - 0, - 349, - 351, - 0, - 0, - 355, - 0, - 363, - 0, - 364, - 0, - 368, - 369, - 0, - 370, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 372, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 373, - 0, - 375, - 0, - 0, - 0, - 0, - 376, - 377, - 0, - 0, - 394, - 395, - 396, - 0, - 0, - 398, - 0, - 0, - 0, - 0, - 400, - 0, - 0, - 408, - 0, - 0, - 0, - 0, - 420, - 0, - 0, - 0, - 0, - 0, - 0, - 421, - 0, - 0, - 422, - 423, - 0, - 0, - 429, - 435, - 436, - 442, - 0, - 0, - 443, - 0, - 444, - 445, - 453, - 456, - 0, - 457, - 0, - 0, - 0, - 0, - 0, - 458, - 0, - 0, - 0, - 459, - 0, - 0, - 0, - 460, - 0, - 462, - 463, - 465, - 0, - 0, - 0, - 0, - 0, - 0, - 466, - 469, - 0, - 0, - 0, - 0, - 0, - 0, - 470, - 0, - 0, - 0, - 474, - 0, - 476, - 0, - 0, - 0, - 0, - 483, - 0, - 485, - 0, - 0, - 0, - 486, - 0, - 0, - 488, - 491, - 492, - 0, - 0, - 497, - 499, - 500, - 0, - 501, - 0, - 0, - 0, - 505, - 0, - 0, - 506, - 0, - 0, - 0, - 507, - 0, - 0, - 0, - 509, - 0, - 0, - 0, - 0, - 511, - 512, - 519, - 0, - 0, - 0, - 0, - 0, - 0, - 529, - 530, - 0, - 0, - 0, - 534, - 0, - 0, - 0, - 0, - 543, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 553, - 0, - 0, - 0, - 0, - 557, - 560, - 0, - 0, - 0, - 0, - 0, - 0, - 561, - 0, - 564, - 0, - 0, - 0, - 0, - 0, - 0, - 565, - 566, - 0, - 575, - 0, - 619, - 0, - 620, - 0, - 0, - 623, - 624, - 0, - 0, - 0, - 625, - 0, - 0, - 626, - 627, - 0, - 0, - 628, - 0, - 0, - 0, - 0, - 630, - 0, - 631, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 641, - 0, - 0, - 0, - 0, - 643, - 656, - 668, - 0, - 0, - 0, - 673, - 0, - 0, - 0, - 674, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 682, - 0, - 687, - 0, - 690, - 0, - 693, - 699, - 700, - 0, - 0, - 0, - 0, - 0, - 0, - 704, - 705, - 0, - 0, - 0, - 0, - 707, - 710, - 0, - 711, - 0, - 0, - 0, - 0, - 726, - 0, - 0, - 729, - 0, - 0, - 0, - 730, - 731, - 0, - 0, - 0, - 0, - 0, - 752, - 0, - 0, - 0, - 762, - 0, - 763, - 0, - 0, - 767, - 0, - 0, - 0, - 770, - 774, - 0, - 0, - 775, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 776, - 0, - 0, - 0, - 777, - 783, - 0, - 0, - 0, - 785, - 788, - 0, - 0, - 0, - 0, - 790, - 0, - 0, - 0, - 793, - 0, - 0, - 0, - 0, - 794, - 0, - 0, - 804, - 819, - 821, - 0, - 827, - 0, - 0, - 0, - 834, - 0, - 0, - 835, - 0, - 0, - 0, - 841, - 0, - 844, - 0, - 850, - 851, - 859, - 0, - 860, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 874, - 0, - 876, - 0, - 877, - 890, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 893, - 894, - 898, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 899, - 0, - 0, - 0, - 900, - 904, - 906, - 0, - 0, - 0, - 907, - 0, - 908, - 909, - 0, - 910, - 0, - 0, - 0, - 0, - 911, - 0, - 0, - 0, - 0, - 0, - 916, - 0, - 0, - 0, - 922, - 925, - 0, - 930, - 0, - 934, - 0, - 0, - 0, - 0, - 0, - 943, - 0, - 0, - 944, - 0, - 953, - 954, - 0, - 0, - 0, - 0, - 0, - 0, - 955, - 0, - 962, - 963, - 0, - 0, - 976, - 0, - 0, - 977, - 978, - 979, - 980, - 0, - 981, - 0, - 0, - 0, - 0, - 984, - 0, - 0, - 985, - 0, - 0, - 987, - 989, - 991, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 992, - 0, - 0, - 0, - 993, - 0, - 0, - 0, - 0, - 0, - 0, - 996, - 0, - 0, - 0, - 1000, - 0, - 0, - 0, - 0, - 0, - 1002, - 0, - 0, - 0, - 0, - 1005, - 1007, - 0, - 0, - 0, - 1009, - 0, - 0, - 0, - 1010, - 0, - 0, - 0, - 0, - 0, - 0, - 1011, - 0, - 1012, - 0, - 0, - 0, - 0, - 1014, - 1016, - 0, - 0, - 0, - 1020, - 0, - 1021, - 0, - 0, - 0, - 0, - 1022, - 0, - 0, - 0, - 1024, - 0, - 0, - 0, - 0, - 0, - 0, - 1025, - 0, - 0, - 1026, - 1027, - 0, - 0, - 0, - 0, - 0, - 1031, - 0, - 1033, - 0, - 0, - 0, - 0, - 1034, - 0, - 0, - 0, - 1037, - 1040, - 0, - 0, - 0, - 1042, - 1043, - 0, - 0, - 1053, - 0, - 1054, - 0, - 0, - 1057, - 0, - 0, - 0, - 1058, - 0, - 0, - 1060, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1061, - 0, - 0, - 1062, - 0, - 0, - 0, - 0, - 1063, - 0, - 0, - 0, - 0, - 1064, - 0, - 0, - 0, - 0, - 0, - 1065, - 0, - 0, - 0, - 0, - 1066, - 1067, - 0, - 0, - 0, - 1069, - 1070, - 1072, - 0, - 0, - 0, - 0, - 0, - 0, - 1073, - 0, - 1075, - 0, - 0, - 0, - 0, - 0, - 0, - 1080, - 1084, - 0, - 0, - 0, - 0, - 1088, - 0, - 0, - 0, - 0, - 0, - 0, - 1094, - 0, - 1095, - 0, - 1107, - 0, - 0, - 0, - 1112, - 1114, - 0, - 1119, - 0, - 1122, - 0, - 0, - 1126, - 0, - 1129, - 0, - 1130, - 0, - 0, - 0, - 0, - 0, - 1132, - 0, - 0, - 0, - 0, - 0, - 0, - 1144, - 0, - 0, - 1145, - 1146, - 0, - 1148, - 1149, - 0, - 0, - 1150, - 1151, - 0, - 0, - 0, - 0, - 1152, - 0, - 1153, - 0, - 0, - 0, - 0, - 0, - 1154, - 0, - 1163, - 0, - 0, - 0, - 1164, - 0, - 0, - 0, - 0, - 0, - 1165, - 0, - 1167, - 0, - 1170, - 0, - 0, - 0, - 0, - 0, - 1171, - 1172, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1173, - 1175, - 1177, - 0, - 1186, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1195, - 0, - 0, - 1221, - 0, - 0, - 1224, - 0, - 0, - 1227, - 0, - 0, - 0, - 0, - 0, - 1228, - 1229, - 0, - 0, - 1230, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1231, - 0, - 0, - 0, - 1233, - 0, - 0, - 1243, - 1244, - 1246, - 1248, - 0, - 0, - 0, - 0, - 1254, - 1255, - 1258, - 1259, - 0, - 0, - 0, - 1260, - 0, - 0, - 1261, - 0, - 0, - 0, - 1262, - 1264, - 0, - 0, - 1265, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1266, - 0, - 1267, - 0, - 0, - 0, - 0, - 1273, - 1274, - 1276, - 1289, - 0, - 0, - 1291, - 1292, - 1293, - 0, - 0, - 1294, - 1295, - 1296, - 0, - 0, - 0, - 0, - 1302, - 0, - 1304, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1311, - 1312, - 0, - 1314, - 0, - 1316, - 1320, - 1321, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1322, - 1323, - 1324, - 0, - 1335, - 0, - 1336, - 0, - 0, - 0, - 0, - 1341, - 1342, - 0, - 1346, - 0, - 1357, - 0, - 0, - 0, - 1358, - 1360, - 0, - 0, - 0, - 0, - 0, - 0, - 1361, - 0, - 0, - 0, - 1362, - 1365, - 0, - 1366, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1379, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1386, - 0, - 1388, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1395, - 0, - 0, - 0, - 0, - 1403, - 0, - 1405, - 0, - 0, - 1407, - 0, - 0, - 0, - 0, - 0, - 1408, - 1409, - 0, - 1410, - 0, - 0, - 0, - 1412, - 1413, - 1416, - 0, - 0, - 1429, - 1451, - 0, - 0, - 1454, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1455, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1456, - 0, - 0, - 0, - 0, - 1459, - 1460, - 1461, - 1475, - 0, - 0, - 0, - 0, - 0, - 0, - 1477, - 0, - 1480, - 0, - 1481, - 0, - 0, - 1486, - 0, - 0, - 1495, - 0, - 0, - 0, - 1496, - 0, - 0, - 1498, - 1499, - 1501, - 1520, - 1521, - 0, - 0, - 0, - 1526, - 0, - 0, - 0, - 0, - 1528, - 1529, - 0, - 1533, - 1536, - 0, - 0, - 0, - 1537, - 1538, - 1549, - 0, - 1550, - 1558, - 1559, - 1572, - 0, - 1573, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1575, - 0, - 0, - 0, - 0, - 0, - 1579, - 0, - 1599, - 0, - 1603, - 0, - 1604, - 0, - 1605, - 0, - 0, - 0, - 0, - 0, - 1608, - 1610, - 0, - 0, - 0, - 0, - 1611, - 0, - 1615, - 0, - 1616, - 1618, - 0, - 1619, - 0, - 0, - 1622, - 0, - 0, - 0, - 0, - 1634, - 0, - 0, - 0, - 1635, - 0, - 0, - 0, - 1641, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1643, - 0, - 0, - 0, - 1650, - 0, - 0, - 1652, - 0, - 0, - 0, - 0, - 0, - 1653, - 0, - 0, - 0, - 1654, - 0, - 0, - 0, - 0, - 1655, - 0, - 1662, - 0, - 0, - 1663, - 1664, - 0, - 0, - 1668, - 0, - 0, - 1669, - 1670, - 0, - 1672, - 1673, - 0, - 0, - 0, - 0, - 0, - 1674, - 0, - 0, - 0, - 1675, - 1676, - 1680, - 0, - 1682, - 0, - 0, - 1687, - 0, - 0, - 0, - 0, - 0, - 1704, - 0, - 0, - 1705, - 0, - 0, - 1721, - 0, - 0, - 0, - 0, - 1734, - 1735, - 0, - 0, - 0, - 0, - 1737, - 0, - 0, - 0, - 0, - 1739, - 0, - 0, - 1740, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1741, - 1743, - 0, - 0, - 0, - 0, - 1745, - 0, - 0, - 0, - 1749, - 0, - 0, - 0, - 1751, - 0, - 0, - 0, - 0, - 0, - 0, - 1760, - 0, - 0, - 0, - 0, - 1765, - 0, - 0, - 0, - 0, - 0, - 1784, - 0, - 1785, - 1787, - 0, - 0, - 0, - 0, - 1788, - 1789, - 0, - 0, - 0, - 0, - 1790, - 1791, - 1793, - 0, - 1798, - 1799, - 0, - 0, - 0, - 0, - 1801, - 0, - 1803, - 1805, - 0, - 0, - 0, - 1806, - 1811, - 0, - 1812, - 1814, - 0, - 1821, - 0, - 0, - 0, - 0, - 0, - 1822, - 1833, - 0, - 0, - 0, - 0, - 0, - 0, - 1848, - 0, - 0, - 0, - 0, - 0, - 0, - 1857, - 0, - 0, - 0, - 1859, - 0, - 0, - 0, - 0, - 1861, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1866, - 0, - 1921, - 1925, - 0, - 0, - 0, - 1929, - 1930, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1931, - 0, - 0, - 0, - 0, - 1932, - 0, - 0, - 0, - 1934, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1946, - 0, - 0, - 1948, - 0, - 0, - 0, - 0, - 1950, - 0, - 1957, - 0, - 1958, - 0, - 0, - 0, - 0, - 0, - 1965, - 1967, - 0, - 0, - 0, - 0, - 1968, - 0, - 1969, - 0, - 1971, - 1972, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1973, - 0, - 0, - 0, - 0, - 1975, - 0, - 0, - 0, - 0, - 1976, - 1979, - 0, - 1982, - 0, - 0, - 0, - 0, - 1984, - 1988, - 0, - 0, - 0, - 0, - 1990, - 2004, - 2008, - 0, - 0, - 0, - 2012, - 2013, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2015, - 0, - 2016, - 2017, - 0, - 0, - 0, - 0, - 2021, - 0, - 0, - 2025, - 0, - 0, - 0, - 0, - 0, - 2029, - 2036, - 2040, - 0, - 2042, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2043, - 0, - 0, - 0, - 0, - 0, - 2045, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2046, - 2047, - 0, - 2048, - 2049, - 0, - 2059, - 0, - 0, - 2063, - 0, - 2064, - 2065, - 0, - 0, - 2066, - 0, - 0, - 0, - 0, - 0, - 0, - 2069, - 0, - 0, - 0, - 0, - 2070, - 0, - 2071, - 0, - 2072, - 0, - 0, - 0, - 0, - 2080, - 2082, - 2083, - 0, - 0, - 0, - 0, - 0, - 2085, - 0, - 2086, - 2088, - 2089, - 2105, - 0, - 0, - 0, - 0, - 2107, - 0, - 0, - 2116, - 2117, - 0, - 2120, - 0, - 0, - 2122, - 0, - 0, - 0, - 0, - 0, - 2123, - 0, - 0, - 2125, - 2127, - 2128, - 0, - 0, - 0, - 2130, - 0, - 0, - 0, - 2137, - 2139, - 2140, - 2141, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2144, - 2145, - 0, - 0, - 2146, - 2149, - 0, - 0, - 0, - 0, - 2150, - 0, - 0, - 2151, - 2158, - 0, - 2159, - 0, - 2160, - 0, - 0, - 0, - 0, - 0, - 0, - 2161, - 2162, - 0, - 0, - 2194, - 2202, - 0, - 0, - 0, - 0, - 0, - 0, - 2205, - 2217, - 0, - 2220, - 0, - 2221, - 0, - 2222, - 2224, - 0, - 0, - 0, - 0, - 2237, - 0, - 0, - 0, - 0, - 0, - 2238, - 0, - 2239, - 2241, - 0, - 0, - 2242, - 0, - 0, - 0, - 0, - 0, - 2243, - 0, - 0, - 0, - 0, - 0, - 0, - 2252, - 0, - 0, - 2253, - 0, - 0, - 0, - 2257, - 2258, - 0, - 0, - 0, - 2260, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2262, - 0, - 2264, - 0, - 0, - 0, - 0, - 0, - 2269, - 2270, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2271, - 0, - 2273, - 0, - 0, - 0, - 0, - 2277, - 0, - 0, - 0, - 0, - 2278, - 0, - 0, - 0, - 0, - 2279, - 0, - 2280, - 0, - 2283, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2287, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2289, - 2290, - 0, - 0, - 0, - 0, - 2291, - 0, - 2292, - 0, - 0, - 0, - 2293, - 2295, - 2296, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2298, - 0, - 0, - 0, - 0, - 0, - 2303, - 0, - 2305, - 0, - 0, - 2306, - 0, - 2307, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2313, - 2314, - 2315, - 2316, - 0, - 0, - 2318, - 0, - 2319, - 0, - 2322, - 0, - 0, - 2323, - 0, - 2324, - 0, - 2326, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2335, - 0, - 2336, - 2338, - 2339, - 0, - 2340, - 0, - 0, - 0, - 2355, - 0, - 2375, - 0, - 2382, - 2386, - 0, - 2387, - 0, - 0, - 2394, - 0, - 0, - 0, - 0, - 2395, - 0, - 2397, - 0, - 0, - 0, - 0, - 0, - 2398, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2399, - 2402, - 2404, - 2408, - 2411, - 0, - 0, - 0, - 2413, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2415, - 0, - 0, - 2416, - 2417, - 2419, - 0, - 2420, - 0, - 0, - 0, - 0, - 0, - 2425, - 0, - 0, - 0, - 2426, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2427, - 2428, - 0, - 2429, - 0, - 0, - 2430, - 2434, - 0, - 2436, - 0, - 0, - 0, - 0, - 0, - 0, - 2441, - 2442, - 0, - 2445, - 0, - 0, - 2446, - 2457, - 0, - 2459, - 0, - 0, - 2462, - 0, - 2464, - 0, - 2477, - 0, - 2478, - 2486, - 0, - 0, - 0, - 2491, - 0, - 0, - 2493, - 0, - 0, - 2494, - 0, - 2495, - 0, - 2513, - 2523, - 0, - 0, - 0, - 0, - 2524, - 0, - 0, - 0, - 0, - 0, - 0, - 2528, - 2529, - 2530, - 0, - 0, - 2531, - 0, - 2533, - 0, - 0, - 2534, - 2535, - 0, - 2536, - 2537, - 0, - 2538, - 0, - 2539, - 2540, - 0, - 0, - 0, - 2545, - 2546, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2548, - 0, - 0, - 2549, - 0, - 2550, - 2555, - 0, - 0, - 0, - 0, - 0, - 2557, - 0, - 2560, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2561, - 0, - 2576, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2577, - 2578, - 0, - 0, - 0, - 2579, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2580, - 0, - 0, - 0, - 0, - 2581, - 0, - 0, - 0, - 0, - 2583, - 0, - 2584, - 0, - 2588, - 2590, - 0, - 0, - 0, - 2591, - 0, - 0, - 0, - 0, - 2593, - 2594, - 0, - 2595, - 0, - 2601, - 2602, - 0, - 0, - 2603, - 0, - 2605, - 0, - 0, - 0, - 2606, - 2607, - 2611, - 0, - 2615, - 0, - 0, - 0, - 2617, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2619, - 0, - 0, - 2620, - 0, - 0, - 0, - 2621, - 0, - 2623, - 0, - 2625, - 0, - 0, - 2628, - 2629, - 0, - 0, - 2635, - 2636, - 2637, - 0, - 0, - 2639, - 0, - 0, - 0, - 2642, - 0, - 0, - 0, - 0, - 2643, - 0, - 2644, - 0, - 2649, - 0, - 0, - 0, - 0, - 0, - 0, - 2655, - 2656, - 0, - 0, - 2657, - 0, - 0, - 0, - 0, - 0, - 2658, - 0, - 0, - 0, - 0, - 0, - 2659, - 0, - 0, - 0, - 0, - 2664, - 2685, - 0, - 2687, - 0, - 2688, - 0, - 0, - 2689, - 0, - 0, - 2694, - 0, - 2695, - 0, - 0, - 2698, - 0, - 2701, - 2706, - 0, - 0, - 0, - 2707, - 0, - 2709, - 2710, - 2711, - 0, - 0, - 0, - 2720, - 2730, - 2735, - 0, - 0, - 0, - 0, - 2738, - 2740, - 0, - 0, - 0, - 0, - 2747, - 0, - 0, - 0, - 0, - 0, - 0, - 2748, - 0, - 0, - 2749, - 0, - 0, - 0, - 0, - 0, - 2750, - 0, - 0, - 2752, - 2754, - 0, - 0, - 0, - 0, - 0, - 2758, - 0, - 0, - 0, - 0, - 2762, - 0, - 0, - 0, - 0, - 2763, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2764, - 2767, - 0, - 0, - 0, - 0, - 2768, - 0, - 0, - 2770, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2771, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2772, - 0, - 0, - 0, - 0, - 0, - 2773, - 2776, - 0, - 0, - 2783, - 0, - 0, - 2784, - 0, - 2789, - 0, - 2790, - 0, - 0, - 0, - 2792, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2793, - 2795, - 0, - 0, - 0, - 0, - 0, - 0, - 2796, - 0, - 0, - 0, - 0, - 0, - 0, - 2797, - 2799, - 0, - 0, - 0, - 0, - 2803, - 0, - 0, - 0, - 0, - 2806, - 0, - 2807, - 2808, - 2817, - 2819, - 0, - 0, - 0, - 0, - 0, - 2821, - 0, - 0, - 0, - 0, - 2822, - 2823, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2824, - 0, - 0, - 2828, - 0, - 2834, - 0, - 0, - 0, - 0, - 0, - 0, - 2836, - 0, - 2838, - 0, - 0, - 2839, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2841, - 0, - 0, - 0, - 2842, - 0, - 0, - 0, - 0, - 0, - 2843, - 2844, - 0, - 0, - 0, - 0, - 2846, - 0, - 0, - 2847, - 0, - 2849, - 0, - 2853, - 0, - 0, - 0, - 0, - 0, - 2857, - 0, - 0, - 0, - 0, - 2858, - 0, - 2859, - 0, - 0, - 2860, - 0, - 2862, - 2868, - 0, - 0, - 0, - 0, - 2875, - 0, - 2876, - 0, - 0, - 2877, - 2878, - 2884, - 2889, - 2890, - 0, - 0, - 2891, - 0, - 0, - 2892, - 0, - 0, - 0, - 2906, - 2912, - 0, - 2913, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2916, - 0, - 2934, - 0, - 0, - 0, - 0, - 0, - 2935, - 0, - 0, - 0, - 0, - 2939, - 0, - 2940, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2941, - 0, - 0, - 0, - 2946, - 0, - 2949, - 0, - 0, - 2950, - 2954, - 2955, - 0, - 0, - 0, - 2959, - 2961, - 0, - 0, - 2962, - 0, - 2963, - 0, - 0, - 0, - 0, - 0, - 0, - 2964, - 2965, - 2966, - 2967, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2969, - 0, - 0, - 0, - 0, - 0, - 2970, - 2975, - 0, - 2982, - 2983, - 2984, - 0, - 0, - 0, - 0, - 0, - 2989, - 0, - 0, - 2990, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2991, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2998, - 0, - 3000, - 3001, - 0, - 0, - 3002, - 0, - 0, - 0, - 3003, - 0, - 0, - 3012, - 0, - 0, - 3022, - 0, - 0, - 3024, - 0, - 0, - 3025, - 3027, - 0, - 0, - 0, - 3030, - 0, - 0, - 0, - 0, - 3034, - 3035, - 0, - 0, - 3036, - 0, - 3039, - 0, - 3049, - 0, - 0, - 3050, - 0, - 0, - 0, - 0, - 0, - 0, - 3051, - 0, - 3053, - 0, - 0, - 0, - 0, - 3057, - 0, - 3058, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3063, - 0, - 0, - 3073, - 3074, - 3078, - 3079, - 0, - 3080, - 3086, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3087, - 0, - 3092, - 0, - 3095, - 0, - 3099, - 0, - 0, - 0, - 3100, - 0, - 3101, - 3102, - 0, - 3122, - 0, - 0, - 0, - 3124, - 0, - 3125, - 0, - 0, - 0, - 0, - 0, - 0, - 3132, - 3134, - 0, - 0, - 3136, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3147, - 0, - 0, - 3149, - 0, - 0, - 0, - 0, - 0, - 3150, - 3151, - 3152, - 0, - 0, - 0, - 0, - 3158, - 0, - 0, - 3160, - 0, - 0, - 3161, - 0, - 0, - 3162, - 0, - 3163, - 3166, - 3168, - 0, - 0, - 3169, - 3170, - 0, - 0, - 3171, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3182, - 0, - 3184, - 0, - 0, - 3188, - 0, - 0, - 3194, - 0, - 0, - 0, - 0, - 0, - 0, - 3204, - 0, - 0, - 0, - 0, - 3209, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3216, - 3217, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3219, - 0, - 0, - 3220, - 3222, - 0, - 3223, - 0, - 0, - 0, - 0, - 3224, - 0, - 3225, - 3226, - 0, - 3228, - 3233, - 0, - 3239, - 3241, - 3242, - 0, - 0, - 3251, - 3252, - 3253, - 3255, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3260, - 0, - 0, - 3261, - 0, - 0, - 0, - 3267, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3271, - 0, - 0, - 0, - 3278, - 0, - 3282, - 0, - 0, - 0, - 3284, - 0, - 0, - 0, - 3285, - 3286, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3287, - 3292, - 0, - 0, - 0, - 0, - 3294, - 3296, - 0, - 0, - 3299, - 3300, - 3301, - 0, - 3302, - 0, - 0, - 0, - 0, - 0, - 3304, - 3306, - 0, - 0, - 0, - 0, - 0, - 0, - 3308, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3311, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3312, - 3314, - 3315, - 0, - 3318, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3319, - 0, - 0, - 0, - 0, - 0, - 3321, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3322, - 0, - 0, - 3324, - 3325, - 0, - 0, - 3326, - 0, - 0, - 3328, - 3329, - 3331, - 0, - 0, - 3335, - 0, - 0, - 3337, - 0, - 3338, - 0, - 0, - 0, - 0, - 3343, - 3347, - 0, - 0, - 0, - 3348, - 0, - 0, - 3351, - 0, - 0, - 0, - 0, - 0, - 0, - 3354, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3355, - 0, - 0, - 3365, - 3366, - 3367, - 0, - 0, - 0, - 0, - 0, - 0, - 3368, - 3369, - 0, - 3370, - 0, - 0, - 3373, - 0, - 0, - 3376, - 0, - 0, - 3377, - 0, - 3379, - 3387, - 0, - 0, - 0, - 0, - 0, - 3390, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3402, - 0, - 3403, - 3436, - 3437, - 3439, - 0, - 0, - 3441, - 0, - 0, - 0, - 3442, - 0, - 0, - 3449, - 0, - 0, - 0, - 3450, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3451, - 0, - 0, - 3452, - 0, - 3453, - 3456, - 0, - 3457, - 0, - 0, - 3458, - 0, - 3459, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3460, - 0, - 0, - 3469, - 3470, - 0, - 0, - 3475, - 0, - 0, - 0, - 3480, - 3487, - 3489, - 0, - 3490, - 0, - 0, - 3491, - 3499, - 0, - 3500, - 0, - 0, - 3501, - 0, - 0, - 0, - 3502, - 0, - 3514, - 0, - 0, - 0, - 3516, - 3517, - 0, - 0, - 0, - 3518, - 0, - 0, - 0, - 0, - 3520, - 3521, - 3522, - 0, - 0, - 3526, - 3530, - 0, - 0, - 0, - 0, - 3531, - 0, - 0, - 0, - 0, - 3536, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3539, - 3541, - 0, - 0, - 3542, - 3544, - 0, - 3547, - 3548, - 0, - 0, - 3550, - 0, - 3553, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3554, - 0, - 3555, - 0, - 3558, - 0, - 3559, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3563, - 0, - 3581, - 0, - 0, - 0, - 3599, - 0, - 0, - 0, - 3600, - 0, - 3601, - 0, - 3602, - 3603, - 0, - 0, - 3606, - 3608, - 0, - 3610, - 3611, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3612, - 3616, - 3619, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3624, - 3628, - 0, - 3629, - 3634, - 3635, - 0, - 0, - 0, - 0, - 0, - 0, - 3636, - 0, - 3637, - 0, - 0, - 3638, - 3651, - 0, - 0, - 0, - 0, - 0, - 0, - 3652, - 3653, - 0, - 0, - 0, - 0, - 3656, - 3657, - 0, - 0, - 0, - 0, - 0, - 3658, - 0, - 0, - 0, - 0, - 3659, - 0, - 3661, - 3663, - 3664, - 0, - 3665, - 0, - 3692, - 0, - 0, - 0, - 3694, - 3696, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3698, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3700, - 0, - 0, - 3701, - 0, - 0, - 0, - 3708, - 3709, - 0, - 0, - 0, - 3711, - 3712, - 0, - 0, - 0, - 0, - 0, - 3723, - 0, - 3724, - 3725, - 0, - 0, - 3726, - 0, - 0, - 0, - 0, - 0, - 0, - 3728, - 3729, - 0, - 3734, - 3735, - 3737, - 0, - 0, - 0, - 3743, - 0, - 3745, - 0, - 0, - 3746, - 0, - 0, - 3747, - 3748, - 0, - 3757, - 0, - 3759, - 3766, - 3767, - 0, - 3768, - 0, - 0, - 0, - 0, - 3769, - 0, - 0, - 3771, - 0, - 3774, - 0, - 0, - 0, - 0, - 0, - 0, - 3775, - 0, - 0, - 0, - 0, - 0, - 0, - 3776, - 0, - 3777, - 3786, - 0, - 3788, - 3789, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3791, - 0, - 3811, - 0, - 0, - 0, - 0, - 0, - 3814, - 3815, - 3816, - 3820, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3821, - 0, - 0, - 3825, - 0, - 0, - 0, - 0, - 3835, - 0, - 0, - 3848, - 3849, - 0, - 0, - 0, - 0, - 3850, - 3851, - 3853, - 0, - 0, - 0, - 0, - 3859, - 0, - 3860, - 3862, - 0, - 0, - 0, - 0, - 0, - 3863, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3873, - 0, - 3874, - 0, - 3875, - 3886, - 0, - 3887, - 0, - 0, - 0, - 0, - 3892, - 3913, - 0, - 3914, - 0, - 0, - 0, - 3925, - 3931, - 0, - 0, - 0, - 0, - 3934, - 3941, - 3942, - 0, - 0, - 0, - 0, - 3943, - 0, - 0, - 0, - 3944, - 0, - 0, - 0, - 0, - 0, - 3945, - 0, - 3947, - 0, - 0, - 0, - 3956, - 3957, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3958, - 0, - 3959, - 3965, - 0, - 0, - 0, - 0, - 3966, - 0, - 0, - 0, - 3967, - 0, - 0, - 0, - 3968, - 3974, - 0, - 0, - 0, - 0, - 0, - 3975, - 3977, - 3978, - 0, - 0, - 0, - 0, - 3980, - 0, - 3985, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3986, - 4011, - 0, - 0, - 4017, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4018, - 0, - 0, - 0, - 0, - 4019, - 0, - 4023, - 0, - 0, - 0, - 4027, - 4028, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4031, - 4034, - 0, - 0, - 4035, - 4037, - 4039, - 4040, - 0, - 0, - 0, - 0, - 0, - 4059, - 0, - 4060, - 4061, - 0, - 4062, - 4063, - 4066, - 0, - 0, - 4072, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4088, - 0, - 0, - 0, - 0, - 0, - 4091, - 0, - 0, - 0, - 0, - 4094, - 4095, - 0, - 0, - 4096, - 0, - 0, - 0, - 0, - 0, - 4098, - 4099, - 0, - 0, - 0, - 4101, - 0, - 4104, - 0, - 0, - 0, - 4105, - 4108, - 0, - 4113, - 0, - 0, - 4115, - 4116, - 0, - 4126, - 0, - 0, - 4127, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4128, - 4132, - 4133, - 0, - 4134, - 0, - 0, - 0, - 4137, - 0, - 0, - 4141, - 0, - 0, - 0, - 0, - 4144, - 4146, - 4147, - 0, - 0, - 0, - 0, - 4148, - 0, - 0, - 4311, - 0, - 0, - 0, - 4314, - 4329, - 0, - 4331, - 4332, - 0, - 4333, - 0, - 4334, - 0, - 0, - 0, - 4335, - 0, - 4336, - 0, - 0, - 0, - 4337, - 0, - 0, - 0, - 4342, - 4345, - 4346, - 4350, - 0, - 4351, - 4352, - 0, - 4354, - 4355, - 0, - 0, - 4364, - 0, - 0, - 0, - 0, - 4369, - 0, - 0, - 0, - 4373, - 0, - 4374, - 0, - 0, - 0, - 0, - 4377, - 0, - 0, - 0, - 0, - 4378, - 0, - 0, - 0, - 4380, - 0, - 0, - 0, - 4381, - 4382, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4384, - 0, - 0, - 0, - 0, - 4385, - 0, - 0, - 0, - 4386, - 0, - 0, - 0, - 4391, - 4398, - 0, - 0, - 0, - 0, - 4407, - 4409, - 0, - 0, - 0, - 0, - 4410, - 0, - 0, - 4411, - 0, - 4414, - 4415, - 4418, - 0, - 4427, - 4428, - 4430, - 0, - 4431, - 0, - 4448, - 0, - 0, - 0, - 0, - 0, - 4449, - 0, - 0, - 0, - 4451, - 4452, - 0, - 4453, - 4454, - 0, - 4456, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4459, - 0, - 4463, - 0, - 0, - 0, - 0, - 0, - 4466, - 0, - 4467, - 0, - 4469, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4470, - 4471, - 0, - 4473, - 0, - 0, - 4475, - 0, - 0, - 0, - 0, - 4477, - 4478, - 0, - 0, - 0, - 4479, - 4481, - 0, - 4482, - 0, - 4484, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4486, - 0, - 0, - 4488, - 0, - 0, - 4497, - 0, - 4508, - 0, - 0, - 4510, - 4511, - 0, - 4520, - 4523, - 0, - 4524, - 0, - 4525, - 0, - 4527, - 0, - 0, - 4528, - 0, - 0, - 0, - 0, - 4530, - 0, - 4531, - 0, - 0, - 4532, - 0, - 0, - 0, - 4533, - 0, - 0, - 0, - 0, - 0, - 4535, - 0, - 0, - 0, - 4536, - 0, - 0, - 0, - 0, - 0, - 4541, - 4543, - 4544, - 4545, - 4547, - 0, - 4548, - 0, - 0, - 0, - 0, - 4550, - 4551, - 0, - 4553, - 0, - 0, - 0, - 0, - 4562, - 0, - 0, - 4571, - 0, - 0, - 0, - 4574, - 0, - 0, - 0, - 4575, - 0, - 4576, - 0, - 4577, - 0, - 0, - 0, - 4581, - 0, - 0, - 0, - 0, - 0, - 4582, - 0, - 0, - 4586, - 0, - 0, - 0, - 4588, - 0, - 0, - 4597, - 0, - 4598, - 0, - 0, - 0, - 0, - 4616, - 4617, - 0, - 4618, - 0, - 0, - 0, - 0, - 4619, - 0, - 4620, - 0, - 0, - 4621, - 0, - 4624, - 0, - 0, - 0, - 0, - 0, - 4625, - 0, - 0, - 0, - 0, - 4657, - 0, - 4659, - 0, - 4667, - 0, - 0, - 0, - 4668, - 4670, - 0, - 4672, - 0, - 0, - 0, - 0, - 0, - 4673, - 4676, - 0, - 0, - 0, - 0, - 4687, - 0, - 0, - 0, - 0, - 4697, - 0, - 0, - 0, - 0, - 4699, - 0, - 4701, - 0, - 0, - 0, - 0, - 4702, - 0, - 0, - 4706, - 0, - 0, - 4713, - 0, - 0, - 0, - 4714, - 4715, - 4716, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4717, - 0, - 0, - 4720, - 0, - 4721, - 4729, - 4735, - 0, - 0, - 0, - 4737, - 0, - 0, - 0, - 4739, - 0, - 0, - 0, - 4740, - 0, - 0, - 0, - 4741, - 0, - 0, - 0, - 0, - 0, - 4742, - 0, - 4745, - 4746, - 4747, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4748, - 0, - 0, - 0, - 4749, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4751, - 4786, - 0, - 4787, - 0, - 4788, - 4796, - 0, - 0, - 4797, - 4798, - 0, - 4799, - 4806, - 4807, - 0, - 0, - 0, - 0, - 4809, - 4810, - 0, - 0, - 0, - 0, - 0, - 0, - 4811, - 0, - 0, - 0, - 0, - 0, - 4812, - 0, - 4813, - 0, - 0, - 4815, - 0, - 4821, - 4822, - 0, - 0, - 0, - 0, - 4823, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4824, - 0, - 0, - 0, - 0, - 4826, - 0, - 0, - 0, - 4828, - 0, - 4829, - 0, - 0, - 0, - 4843, - 0, - 0, - 4847, - 0, - 4853, - 4855, - 4858, - 0, - 0, - 0, - 0, - 0, - 4859, - 0, - 4864, - 0, - 0, - 4879, - 0, - 0, - 0, - 0, - 4880, - 0, - 0, - 0, - 0, - 4881, - 0, - 4882, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4883, - 0, - 0, - 0, - 0, - 4884, - 0, - 0, - 0, - 0, - 0, - 4886, - 4887, - 4888, - 4894, - 4896, - 0, - 4902, - 0, - 0, - 4905, - 0, - 0, - 4915, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4916, - 4917, - 4919, - 4921, - 0, - 0, - 0, - 0, - 0, - 4926, - 0, - 0, - 0, - 0, - 4927, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 4929, - 0, - 4930, - 4931, - 0, - 4938, - 0, - 4952, - 0, - 4953, - 4957, - 4960, - 4964, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5019, - 5020, - 5022, - 0, - 0, - 0, - 0, - 0, - 5023, - 0, - 0, - 0, - 5024, - 0, - 0, - 0, - 5025, - 0, - 0, - 0, - 0, - 5028, - 0, - 0, - 0, - 0, - 5029, - 5030, - 5031, - 0, - 5033, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5034, - 5035, - 0, - 5036, - 0, - 0, - 5037, - 0, - 0, - 0, - 0, - 5038, - 0, - 0, - 5039, - 0, - 0, - 0, - 5041, - 5042, - 0, - 0, - 0, - 0, - 5044, - 5049, - 5054, - 0, - 5055, - 0, - 5057, - 0, - 0, - 0, - 5060, - 0, - 0, - 0, - 0, - 0, - 5063, - 0, - 5064, - 5065, - 0, - 5067, - 0, - 0, - 0, - 5068, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5076, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5077, - 0, - 0, - 5078, - 5080, - 0, - 0, - 5083, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5085, - 0, - 0, - 0, - 0, - 0, - 0, - 5098, - 5099, - 5101, - 5105, - 5107, - 0, - 5108, - 0, - 5109, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5110, - 0, - 0, - 0, - 0, - 0, - 5117, - 5118, - 0, - 5121, - 0, - 5122, - 0, - 0, - 5130, - 0, - 0, - 0, - 5137, - 0, - 0, - 0, - 5148, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5151, - 5154, - 0, - 0, - 0, - 5155, - 0, - 0, - 5156, - 5159, - 5161, - 0, - 0, - 0, - 0, - 5162, - 0, - 0, - 0, - 0, - 5163, - 5164, - 0, - 5166, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5167, - 0, - 0, - 0, - 5172, - 0, - 0, - 0, - 0, - 0, - 0, - 5178, - 5179, - 0, - 0, - 5190, - 0, - 0, - 5191, - 5192, - 5194, - 0, - 0, - 5198, - 5201, - 0, - 0, - 0, - 0, - 0, - 5203, - 0, - 5206, - 5209, - 0, - 0, - 0, - 0, - 0, - 0, - 5213, - 0, - 5214, - 5216, - 0, - 0, - 0, - 0, - 0, - 5217, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5218, - 5219, - 0, - 5231, - 0, - 0, - 5244, - 5249, - 0, - 5254, - 0, - 5255, - 0, - 0, - 5257, - 0, - 0, - 0, - 0, - 0, - 5258, - 0, - 5260, - 5270, - 0, - 5277, - 0, - 0, - 0, - 0, - 0, - 0, - 5280, - 5281, - 5282, - 5283, - 0, - 0, - 0, - 0, - 0, - 5284, - 0, - 5285, - 0, - 0, - 0, - 0, - 0, - 5287, - 5288, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5289, - 5291, - 0, - 0, - 5294, - 0, - 0, - 5295, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5304, - 0, - 0, - 5306, - 5307, - 5308, - 0, - 5309, - 0, - 0, - 5310, - 0, - 0, - 0, - 0, - 5311, - 5312, - 0, - 5313, - 0, - 0, - 0, - 0, - 0, - 5316, - 0, - 0, - 0, - 5317, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5325, - 0, - 0, - 0, - 0, - 0, - 0, - 5326, - 0, - 5327, - 5329, - 0, - 5332, - 0, - 0, - 0, - 0, - 5338, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5340, - 0, - 0, - 5341, - 0, - 0, - 0, - 5342, - 0, - 5343, - 5344, - 0, - 0, - 5345, - 0, - 0, - 0, - 0, - 0, - 0, - 5347, - 5348, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5349, - 0, - 5350, - 0, - 5354, - 0, - 0, - 0, - 0, - 5358, - 0, - 0, - 5359, - 0, - 0, - 5361, - 0, - 0, - 5365, - 0, - 5367, - 0, - 5373, - 0, - 0, - 0, - 5379, - 0, - 0, - 0, - 5380, - 0, - 0, - 0, - 5382, - 0, - 5384, - 0, - 0, - 0, - 0, - 0, - 0, - 5385, - 0, - 0, - 0, - 0, - 5387, - 0, - 0, - 0, - 0, - 0, - 0, - 5388, - 5390, - 5393, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5396, - 0, - 0, - 0, - 0, - 5397, - 5402, - 0, - 0, - 0, - 0, - 0, - 5403, - 0, - 0, - 0, - 5404, - 5405, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5406, - 0, - 0, - 0, - 0, - 5410, - 0, - 0, - 5411, - 0, - 5415, - 0, - 0, - 0, - 0, - 5416, - 5434, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5438, - 0, - 5440, - 0, - 0, - 0, - 0, - 0, - 0, - 5441, - 5442, - 0, - 0, - 0, - 5443, - 5444, - 5447, - 0, - 0, - 5448, - 5449, - 5451, - 0, - 0, - 0, - 5456, - 5457, - 0, - 0, - 0, - 5459, - 0, - 0, - 0, - 5461, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5464, - 0, - 5466, - 0, - 0, - 5467, - 0, - 5470, - 0, - 0, - 5473, - 0, - 0, - 5474, - 0, - 0, - 5476, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5477, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5484, - 0, - 0, - 5485, - 5486, - 0, - 0, - 0, - 0, - 0, - 5488, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5489, - 0, - 0, - 0, - 0, - 0, - 5507, - 0, - 0, - 0, - 5510, - 0, - 5511, - 0, - 0, - 5512, - 0, - 0, - 0, - 5513, - 0, - 5515, - 0, - 0, - 5516, - 5517, - 0, - 5518, - 0, - 0, - 5522, - 0, - 0, - 0, - 0, - 0, - 5534, - 5535, - 0, - 0, - 5536, - 0, - 5538, - 0, - 0, - 5543, - 0, - 5544, - 0, - 0, - 5545, - 0, - 5547, - 0, - 5557, - 0, - 0, - 5558, - 0, - 5560, - 5567, - 0, - 0, - 0, - 0, - 5568, - 0, - 0, - 0, - 5571, - 5573, - 0, - 5574, - 0, - 5575, - 0, - 0, - 0, - 0, - 5577, - 0, - 0, - 5598, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5600, - 5609, - 0, - 0, - 0, - 0, - 5610, - 0, - 0, - 5612, - 0, - 5624, - 0, - 5625, - 0, - 0, - 0, - 5629, - 0, - 5641, - 0, - 5642, - 5643, - 0, - 0, - 0, - 0, - 0, - 0, - 5651, - 0, - 0, - 0, - 5652, - 5653, - 0, - 5661, - 5662, - 5678, - 0, - 5679, - 0, - 0, - 0, - 0, - 5685, - 5686, - 0, - 0, - 0, - 0, - 0, - 5690, - 5692, - 0, - 5703, - 0, - 0, - 0, - 0, - 0, - 5706, - 0, - 0, - 0, - 0, - 5707, - 0, - 0, - 0, - 0, - 0, - 0, - 5708, - 0, - 0, - 5709, - 0, - 5710, - 0, - 0, - 0, - 5712, - 0, - 5733, - 0, - 5734, - 5735, - 0, - 0, - 5744, - 5751, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5752, - 0, - 5754, - 0, - 0, - 0, - 0, - 0, - 0, - 5757, - 5758, - 0, - 5760, - 5761, - 0, - 0, - 0, - 0, - 5763, - 5764, - 5765, - 0, - 5766, - 0, - 5767, - 5768, - 0, - 5770, - 0, - 0, - 0, - 0, - 5776, - 5780, - 0, - 0, - 0, - 0, - 5782, - 0, - 0, - 0, - 0, - 5784, - 0, - 0, - 5788, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5797, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5799, - 0, - 0, - 5801, - 0, - 0, - 0, - 5811, - 0, - 0, - 0, - 0, - 0, - 0, - 5816, - 0, - 0, - 5827, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5830, - 5831, - 0, - 0, - 5832, - 0, - 0, - 5833, - 0, - 5835, - 5844, - 5845, - 0, - 5846, - 0, - 0, - 0, - 0, - 0, - 5850, - 0, - 0, - 0, - 0, - 0, - 5852, - 0, - 5855, - 5857, - 0, - 0, - 5859, - 0, - 5861, - 0, - 0, - 5863, - 0, - 5865, - 0, - 0, - 0, - 5873, - 5875, - 0, - 0, - 0, - 5877, - 0, - 5879, - 0, - 0, - 0, - 5888, - 0, - 0, - 5889, - 5891, - 0, - 5894, - 0, - 0, - 0, - 0, - 0, - 0, - 5895, - 0, - 5897, - 0, - 0, - 0, - 0, - 0, - 0, - 5907, - 0, - 5911, - 0, - 0, - 5912, - 0, - 5913, - 5922, - 5924, - 0, - 5927, - 5928, - 0, - 0, - 0, - 0, - 5929, - 5930, - 0, - 5933, - 0, - 0, - 0, - 0, - 5949, - 0, - 0, - 5951, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 5953, - 0, - 0, - 5954, - 0, - 5959, - 5960, - 5961, - 0, - 5964, - 0, - 0, - 0, - 5976, - 5978, - 5987, - 5990, - 0, - 0, - 0, - 0, - 0, - 5991, - 0, - 5992, - 0, - 0, - 0, - 5994, - 5995, - 0, - 0, - 5996, - 0, - 0, - 6001, - 6003, - 0, - 0, - 0, - 0, - 6007, - 0, - 0, - 0, - 0, - 0, - 6008, - 0, - 0, - 6009, - 0, - 6010, - 0, - 0, - 0, - 6011, - 6015, - 0, - 6017, - 0, - 6019, - 0, - 6023, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6025, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6026, - 0, - 6030, - 0, - 0, - 6032, - 0, - 0, - 0, - 6033, - 6038, - 6040, - 0, - 0, - 0, - 6041, - 6045, - 0, - 0, - 6046, - 0, - 0, - 6053, - 0, - 0, - 6054, - 0, - 6055, - 0, - 0, - 0, - 0, - 0, - 0, - 6057, - 0, - 6063, - 0, - 0, - 0, - 6064, - 0, - 6066, - 6071, - 6072, - 0, - 0, - 0, - 0, - 0, - 0, - 6075, - 6076, - 0, - 0, - 6077, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6078, - 6079, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6080, - 0, - 6083, - 0, - 0, - 0, - 0, - 0, - 6084, - 0, - 0, - 6088, - 0, - 6089, - 0, - 0, - 6093, - 6105, - 0, - 0, - 6107, - 0, - 6110, - 0, - 0, - 0, - 6111, - 6125, - 6126, - 0, - 0, - 0, - 6129, - 0, - 0, - 0, - 0, - 6130, - 0, - 0, - 0, - 6131, - 6134, - 0, - 0, - 0, - 0, - 0, - 0, - 6142, - 0, - 0, - 0, - 0, - 0, - 6144, - 0, - 0, - 6146, - 6151, - 6153, - 0, - 6156, - 0, - 6163, - 0, - 6180, - 6181, - 0, - 0, - 0, - 0, - 0, - 6182, - 0, - 0, - 0, - 0, - 6184, - 6195, - 0, - 0, - 6206, - 0, - 6208, - 0, - 0, - 6212, - 6213, - 6214, - 0, - 6215, - 0, - 0, - 0, - 6228, - 0, - 0, - 0, - 6234, - 0, - 0, - 0, - 0, - 0, - 0, - 6235, - 6240, - 0, - 6242, - 6243, - 6244, - 0, - 6250, - 6255, - 0, - 0, - 0, - 0, - 0, - 6257, - 0, - 0, - 0, - 6258, - 6278, - 0, - 6284, - 0, - 0, - 0, - 6285, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6286, - 0, - 0, - 0, - 6320, - 0, - 0, - 6322, - 6332, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6334, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6335, - 0, - 0, - 6337, - 0, - 6338, - 0, - 6339, - 6340, - 0, - 0, - 6356, - 6357, - 6369, - 0, - 0, - 0, - 6370, - 6371, - 6372, - 0, - 6373, - 0, - 0, - 0, - 0, - 0, - 6376, - 0, - 0, - 0, - 0, - 0, - 6382, - 6383, - 6384, - 0, - 0, - 0, - 0, - 6386, - 0, - 6389, - 6397, - 6400, - 6411, - 0, - 6414, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6415, - 6416, - 0, - 0, - 0, - 0, - 0, - 0, - 6417, - 0, - 0, - 0, - 0, - 6418, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6420, - 0, - 6421, - 6423, - 6425, - 0, - 6429, - 6430, - 0, - 6433, - 6438, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6439, - 6440, - 0, - 0, - 6441, - 0, - 0, - 6444, - 0, - 0, - 0, - 0, - 6446, - 0, - 0, - 0, - 0, - 6447, - 6448, - 0, - 0, - 6450, - 0, - 0, - 0, - 6454, - 0, - 0, - 6455, - 0, - 6461, - 0, - 0, - 0, - 0, - 0, - 0, - 6462, - 0, - 0, - 6463, - 0, - 6464, - 0, - 6465, - 6467, - 0, - 0, - 0, - 6468, - 0, - 6479, - 6480, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6481, - 0, - 0, - 6485, - 6487, - 0, - 0, - 0, - 0, - 0, - 0, - 6493, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6494, - 6495, - 6496, - 0, - 0, - 0, - 0, - 0, - 6498, - 0, - 0, - 0, - 6507, - 6508, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6511, - 6512, - 0, - 0, - 0, - 0, - 6513, - 0, - 0, - 0, - 6514, - 0, - 0, - 0, - 0, - 0, - 6516, - 0, - 0, - 6517, - 6518, - 0, - 0, - 0, - 6519, - 6520, - 6521, - 0, - 6523, - 0, - 0, - 0, - 0, - 6524, - 6528, - 0, - 6530, - 0, - 0, - 6532, - 0, - 6578, - 0, - 0, - 0, - 6583, - 0, - 6584, - 0, - 0, - 0, - 6587, - 0, - 0, - 0, - 6590, - 0, - 6591, - 0, - 0, - 0, - 0, - 0, - 6592, - 0, - 0, - 0, - 0, - 6593, - 6594, - 0, - 0, - 0, - 0, - 0, - 6599, - 6600, - 0, - 0, - 6601, - 6602, - 6604, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6608, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6610, - 6611, - 0, - 6615, - 0, - 6616, - 6618, - 6620, - 0, - 6637, - 0, - 0, - 0, - 0, - 6639, - 0, - 0, - 0, - 0, - 6641, - 0, - 6642, - 0, - 0, - 0, - 6647, - 0, - 6660, - 6663, - 0, - 6664, - 0, - 6666, - 6669, - 0, - 6675, - 6676, - 6677, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6678, - 0, - 0, - 0, - 6679, - 0, - 6680, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6693, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6704, - 6705, - 6706, - 0, - 0, - 6711, - 6713, - 0, - 0, - 0, - 0, - 0, - 6716, - 0, - 0, - 0, - 6717, - 0, - 6719, - 6724, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6725, - 6726, - 0, - 0, - 0, - 0, - 0, - 6728, - 6729, - 6735, - 0, - 6737, - 6742, - 0, - 0, - 6743, - 6750, - 0, - 6751, - 0, - 0, - 6752, - 6753, - 0, - 0, - 0, - 0, - 0, - 0, - 6754, - 0, - 0, - 0, - 0, - 0, - 6756, - 0, - 0, - 0, - 0, - 0, - 0, - 6763, - 0, - 0, - 6764, - 6765, - 0, - 0, - 0, - 6770, - 0, - 0, - 0, - 6776, - 6780, - 0, - 6781, - 0, - 0, - 0, - 6783, - 0, - 6784, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6785, - 0, - 0, - 0, - 6792, - 0, - 0, - 0, - 6793, - 0, - 0, - 6802, - 0, - 0, - 0, - 0, - 0, - 6803, - 0, - 0, - 0, - 6804, - 0, - 0, - 0, - 6812, - 0, - 0, - 6823, - 0, - 6824, - 6839, - 0, - 0, - 0, - 0, - 6852, - 0, - 0, - 6854, - 0, - 6856, - 6857, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6867, - 0, - 6868, - 6870, - 6872, - 0, - 0, - 0, - 6873, - 6874, - 0, - 0, - 0, - 0, - 0, - 6875, - 0, - 0, - 6877, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6878, - 0, - 0, - 0, - 6879, - 0, - 6880, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6887, - 0, - 6888, - 6891, - 6893, - 0, - 6895, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6899, - 0, - 0, - 0, - 0, - 6901, - 0, - 0, - 0, - 0, - 6910, - 0, - 6911, - 0, - 0, - 6912, - 0, - 0, - 6913, - 6914, - 0, - 0, - 0, - 6915, - 0, - 0, - 0, - 6916, - 6919, - 0, - 0, - 0, - 0, - 0, - 0, - 6924, - 0, - 6925, - 0, - 0, - 0, - 6926, - 6927, - 6928, - 0, - 6929, - 0, - 6930, - 0, - 0, - 6931, - 6935, - 0, - 6936, - 0, - 0, - 0, - 0, - 6939, - 6940, - 6941, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6942, - 6948, - 6949, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6952, - 6954, - 6963, - 6965, - 6966, - 0, - 0, - 6967, - 6968, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6969, - 0, - 0, - 6970, - 6979, - 0, - 0, - 6980, - 0, - 0, - 6983, - 0, - 0, - 0, - 0, - 0, - 6984, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6988, - 6990, - 6992, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 6995, - 0, - 0, - 0, - 7012, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7019, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7021, - 0, - 0, - 7022, - 7023, - 7028, - 0, - 7030, - 7033, - 0, - 0, - 0, - 0, - 0, - 0, - 7038, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7039, - 0, - 0, - 0, - 0, - 0, - 7046, - 0, - 7047, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7048, - 7052, - 0, - 0, - 0, - 0, - 0, - 7054, - 0, - 7060, - 0, - 0, - 0, - 0, - 7061, - 0, - 7065, - 0, - 0, - 0, - 0, - 7067, - 7069, - 0, - 7070, - 7071, - 7072, - 0, - 0, - 7078, - 0, - 7080, - 7081, - 0, - 7083, - 0, - 0, - 0, - 7084, - 7087, - 7088, - 0, - 0, - 7090, - 0, - 7093, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7107, - 0, - 0, - 7108, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7110, - 0, - 7114, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7115, - 0, - 7116, - 0, - 0, - 0, - 0, - 0, - 7117, - 0, - 0, - 7118, - 0, - 0, - 7124, - 0, - 7125, - 0, - 0, - 7126, - 0, - 0, - 0, - 0, - 7128, - 0, - 0, - 0, - 0, - 0, - 7129, - 0, - 7130, - 0, - 7132, - 7133, - 0, - 0, - 7134, - 0, - 0, - 7139, - 0, - 7148, - 7150, - 0, - 0, - 0, - 0, - 7152, - 0, - 0, - 0, - 7153, - 7156, - 7157, - 0, - 0, - 0, - 0, - 0, - 7158, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7163, - 7165, - 7169, - 0, - 7171, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7172, - 0, - 7173, - 7181, - 0, - 0, - 0, - 0, - 0, - 7182, - 7185, - 0, - 0, - 0, - 0, - 7187, - 0, - 7201, - 7204, - 0, - 0, - 0, - 0, - 0, - 7206, - 7207, - 0, - 0, - 0, - 0, - 7211, - 7216, - 0, - 7218, - 0, - 0, - 0, - 0, - 7226, - 7228, - 7230, - 7232, - 7233, - 7235, - 7237, - 0, - 0, - 0, - 0, - 7238, - 7241, - 0, - 7242, - 0, - 0, - 7247, - 0, - 0, - 0, - 7266, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7289, - 0, - 0, - 7290, - 7291, - 0, - 0, - 7292, - 0, - 7297, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7300, - 0, - 7301, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7302, - 0, - 0, - 0, - 0, - 7305, - 0, - 0, - 0, - 0, - 7307, - 0, - 7308, - 0, - 7310, - 0, - 7335, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7337, - 0, - 7343, - 7347, - 0, - 0, - 0, - 0, - 0, - 7348, - 0, - 7349, - 7350, - 7352, - 7354, - 0, - 0, - 0, - 0, - 7357, - 0, - 7358, - 7366, - 0, - 7367, - 7368, - 0, - 0, - 7373, - 0, - 0, - 0, - 7374, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7376, - 0, - 0, - 0, - 7377, - 0, - 0, - 0, - 0, - 0, - 7378, - 0, - 7379, - 7380, - 0, - 0, - 0, - 0, - 0, - 7383, - 0, - 0, - 7386, - 0, - 0, - 0, - 0, - 7398, - 0, - 0, - 0, - 7399, - 7400, - 0, - 7401, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7402, - 0, - 0, - 0, - 0, - 0, - 7405, - 0, - 0, - 0, - 0, - 0, - 7406, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7421, - 7427, - 7429, - 0, - 0, - 0, - 7435, - 0, - 0, - 7436, - 0, - 0, - 0, - 7437, - 0, - 0, - 0, - 0, - 0, - 0, - 7438, - 7443, - 0, - 7446, - 0, - 7448, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7456, - 0, - 0, - 0, - 0, - 0, - 7457, - 0, - 0, - 7461, - 0, - 0, - 0, - 0, - 0, - 7462, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7463, - 7466, - 7472, - 0, - 7476, - 0, - 0, - 7490, - 0, - 7491, - 0, - 0, - 7493, - 0, - 0, - 0, - 7498, - 7499, - 0, - 0, - 7508, - 0, - 0, - 0, - 0, - 0, - 7512, - 0, - 0, - 0, - 7513, - 7514, - 7516, - 0, - 0, - 0, - 0, - 7518, - 0, - 0, - 7519, - 7521, - 7522, - 0, - 0, - 0, - 7526, - 0, - 0, - 7529, - 0, - 0, - 7531, - 0, - 7536, - 0, - 7538, - 0, - 7539, - 0, - 0, - 7541, - 7542, - 7546, - 0, - 0, - 0, - 0, - 0, - 7547, - 0, - 7548, - 0, - 0, - 0, - 0, - 0, - 7550, - 0, - 0, - 7552, - 7553, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7554, - 7563, - 0, - 7573, - 0, - 0, - 0, - 0, - 0, - 0, - 7574, - 7576, - 0, - 7578, - 7581, - 7583, - 0, - 0, - 0, - 7584, - 0, - 7587, - 0, - 0, - 0, - 0, - 0, - 7589, - 0, - 0, - 0, - 7594, - 0, - 0, - 7595, - 0, - 0, - 7600, - 7602, - 7610, - 0, - 0, - 0, - 0, - 0, - 7612, - 0, - 7613, - 7614, - 0, - 0, - 7615, - 0, - 0, - 7616, - 0, - 7620, - 0, - 7621, - 7622, - 0, - 7623, - 0, - 0, - 0, - 0, - 7626, - 0, - 0, - 0, - 0, - 7627, - 7629, - 7631, - 0, - 0, - 7633, - 0, - 0, - 0, - 0, - 0, - 7639, - 0, - 7640, - 7642, - 0, - 0, - 7643, - 0, - 0, - 0, - 0, - 7644, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7645, - 0, - 0, - 0, - 0, - 0, - 7661, - 7662, - 7663, - 7665, - 0, - 7666, - 0, - 7667, - 0, - 7684, - 7688, - 7690, - 0, - 7691, - 0, - 0, - 0, - 0, - 0, - 0, - 7692, - 0, - 0, - 7700, - 0, - 7707, - 0, - 7708, - 0, - 7709, - 0, - 7721, - 0, - 0, - 0, - 7722, - 0, - 7724, - 0, - 0, - 0, - 0, - 0, - 0, - 7729, - 7731, - 0, - 7732, - 0, - 7733, - 7735, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7739, - 0, - 0, - 7741, - 7745, - 0, - 7748, - 0, - 0, - 0, - 7751, - 0, - 0, - 0, - 7752, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7753, - 0, - 0, - 7756, - 0, - 7757, - 0, - 7759, - 0, - 7760, - 0, - 0, - 0, - 0, - 7761, - 7768, - 0, - 0, - 7769, - 0, - 0, - 7770, - 0, - 0, - 7771, - 0, - 0, - 7772, - 0, - 0, - 7773, - 0, - 0, - 0, - 0, - 0, - 7778, - 7783, - 0, - 0, - 0, - 0, - 0, - 7784, - 7785, - 0, - 7790, - 0, - 0, - 0, - 0, - 7792, - 0, - 7798, - 0, - 0, - 0, - 0, - 0, - 7799, - 0, - 7810, - 0, - 0, - 7813, - 0, - 7814, - 0, - 7816, - 0, - 7818, - 7824, - 7825, - 7826, - 0, - 7828, - 7830, - 0, - 0, - 0, - 7840, - 0, - 7842, - 0, - 7843, - 0, - 0, - 0, - 0, - 7844, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7846, - 0, - 0, - 0, - 0, - 0, - 7856, - 7857, - 7858, - 7862, - 0, - 7865, - 0, - 0, - 7866, - 0, - 0, - 7913, - 0, - 0, - 0, - 0, - 7914, - 0, - 0, - 7915, - 7917, - 7918, - 7919, - 0, - 7920, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7921, - 7922, - 0, - 7924, - 0, - 0, - 7925, - 0, - 0, - 7927, - 0, - 7930, - 7935, - 0, - 0, - 7937, - 0, - 0, - 0, - 0, - 0, - 0, - 7939, - 0, - 7940, - 0, - 0, - 0, - 0, - 0, - 7941, - 0, - 0, - 0, - 0, - 7945, - 0, - 0, - 0, - 0, - 7949, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7950, - 0, - 7953, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7968, - 0, - 0, - 0, - 0, - 7969, - 7972, - 7992, - 0, - 7993, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 7994, - 0, - 0, - 0, - 0, - 8007, - 8008, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8010, - 0, - 0, - 0, - 8012, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8018, - 0, - 8028, - 8029, - 0, - 0, - 8030, - 0, - 0, - 8032, - 8033, - 0, - 0, - 8034, - 8036, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8037, - 0, - 0, - 0, - 8043, - 8052, - 8059, - 8060, - 0, - 0, - 8061, - 0, - 0, - 0, - 8062, - 0, - 8063, - 0, - 8064, - 0, - 8066, - 8068, - 0, - 0, - 0, - 8080, - 8081, - 0, - 8089, - 0, - 0, - 0, - 0, - 0, - 8092, - 0, - 0, - 0, - 0, - 0, - 0, - 8093, - 8110, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8111, - 0, - 0, - 0, - 0, - 0, - 8112, - 8115, - 0, - 8117, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8120, - 8121, - 8122, - 8128, - 8129, - 8130, - 8131, - 0, - 0, - 8139, - 0, - 0, - 8144, - 0, - 0, - 0, - 0, - 8145, - 8146, - 8153, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8154, - 0, - 8157, - 8160, - 8162, - 0, - 8164, - 8165, - 0, - 0, - 0, - 0, - 8166, - 8167, - 0, - 0, - 8179, - 0, - 0, - 0, - 8185, - 0, - 0, - 0, - 8186, - 0, - 0, - 8187, - 0, - 0, - 0, - 8188, - 0, - 0, - 0, - 0, - 0, - 8204, - 0, - 0, - 0, - 0, - 8210, - 0, - 0, - 0, - 0, - 0, - 8213, - 0, - 8214, - 0, - 0, - 8215, - 0, - 0, - 0, - 0, - 0, - 0, - 8218, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8219, - 0, - 8221, - 0, - 0, - 8222, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8225, - 0, - 0, - 0, - 8233, - 0, - 0, - 8242, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8247, - 0, - 8248, - 8252, - 0, - 8256, - 8257, - 0, - 0, - 8261, - 0, - 8264, - 8265, - 0, - 0, - 0, - 0, - 8267, - 0, - 0, - 0, - 8269, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8270, - 0, - 0, - 0, - 8278, - 0, - 8279, - 8283, - 0, - 0, - 8285, - 8286, - 8289, - 8292, - 0, - 0, - 0, - 0, - 8293, - 8295, - 8299, - 8300, - 8301, - 0, - 0, - 0, - 0, - 0, - 0, - 8304, - 8307, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8321, - 0, - 0, - 0, - 8322, - 8323, - 8325, - 8326, - 8327, - 0, - 0, - 8332, - 8338, - 0, - 0, - 8340, - 0, - 0, - 0, - 0, - 0, - 8350, - 0, - 0, - 8351, - 0, - 8354, - 8355, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8360, - 8372, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8377, - 0, - 0, - 0, - 0, - 8380, - 0, - 0, - 0, - 8383, - 0, - 8384, - 0, - 0, - 0, - 0, - 8386, - 8392, - 0, - 0, - 8394, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8396, - 8397, - 0, - 8398, - 0, - 8399, - 0, - 0, - 0, - 0, - 0, - 8400, - 0, - 8401, - 8410, - 8411, - 0, - 8412, - 8413, - 8422, - 0, - 0, - 0, - 0, - 8423, - 0, - 0, - 0, - 0, - 8424, - 0, - 0, - 8425, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8441, - 8442, - 0, - 0, - 0, - 0, - 0, - 0, - 8443, - 0, - 0, - 8444, - 0, - 8447, - 0, - 0, - 0, - 0, - 8451, - 0, - 8458, - 0, - 8462, - 0, - 0, - 8468, - 0, - 8469, - 0, - 0, - 0, - 8470, - 0, - 8473, - 8479, - 8480, - 0, - 0, - 0, - 0, - 8481, - 8483, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8484, - 0, - 0, - 8490, - 0, - 0, - 0, - 0, - 0, - 0, - 8491, - 8493, - 8494, - 0, - 8528, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8530, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8534, - 8538, - 8540, - 0, - 0, - 8541, - 0, - 0, - 8545, - 0, - 8557, - 0, - 0, - 8569, - 8570, - 0, - 0, - 8571, - 8574, - 8575, - 8579, - 0, - 8583, - 0, - 0, - 0, - 0, - 8591, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8606, - 0, - 8607, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8608, - 0, - 0, - 8609, - 0, - 0, - 0, - 8610, - 0, - 0, - 0, - 8611, - 0, - 0, - 8613, - 8617, - 8621, - 0, - 0, - 8622, - 0, - 8623, - 0, - 8624, - 8625, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8637, - 8638, - 8639, - 8650, - 0, - 0, - 0, - 0, - 8652, - 8654, - 8655, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8656, - 0, - 0, - 0, - 0, - 0, - 8657, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8658, - 0, - 0, - 8659, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8660, - 0, - 0, - 0, - 0, - 0, - 0, - 8661, - 8663, - 8664, - 0, - 0, - 0, - 0, - 8665, - 0, - 8669, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8671, - 8674, - 0, - 8684, - 0, - 8686, - 0, - 0, - 0, - 8689, - 0, - 0, - 0, - 8690, - 0, - 8706, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8710, - 0, - 8711, - 8713, - 8714, - 8724, - 8727, - 8728, - 8733, - 8736, - 0, - 8737, - 8739, - 0, - 0, - 0, - 0, - 8742, - 8743, - 8745, - 8754, - 0, - 0, - 0, - 0, - 8756, - 0, - 0, - 0, - 0, - 0, - 0, - 8757, - 8760, - 0, - 0, - 0, - 0, - 0, - 8762, - 8763, - 8764, - 0, - 8766, - 8769, - 8770, - 8773, - 0, - 8774, - 0, - 8779, - 0, - 0, - 0, - 0, - 8780, - 0, - 0, - 8781, - 0, - 0, - 8783, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8784, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8785, - 0, - 0, - 0, - 0, - 8786, - 0, - 0, - 0, - 0, - 8788, - 8790, - 0, - 0, - 0, - 8803, - 0, - 8813, - 8814, - 0, - 0, - 0, - 0, - 0, - 8815, - 8816, - 0, - 0, - 0, - 0, - 8818, - 0, - 0, - 0, - 0, - 8822, - 8828, - 8829, - 0, - 8831, - 0, - 0, - 0, - 0, - 8833, - 0, - 0, - 0, - 8834, - 0, - 0, - 0, - 8835, - 0, - 8836, - 0, - 0, - 0, - 8837, - 0, - 0, - 0, - 0, - 0, - 0, - 8838, - 8839, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8840, - 0, - 0, - 0, - 8841, - 0, - 8842, - 0, - 0, - 0, - 8846, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8847, - 0, - 8848, - 0, - 0, - 8864, - 0, - 0, - 8866, - 0, - 0, - 8870, - 8872, - 0, - 0, - 8873, - 8874, - 0, - 0, - 0, - 0, - 0, - 0, - 8875, - 0, - 8876, - 0, - 0, - 0, - 0, - 8896, - 8900, - 0, - 0, - 0, - 0, - 8901, - 0, - 0, - 0, - 0, - 0, - 8904, - 0, - 8907, - 0, - 0, - 0, - 0, - 8911, - 8912, - 8913, - 0, - 0, - 0, - 8914, - 0, - 8915, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8916, - 0, - 0, - 0, - 8929, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8930, - 0, - 8932, - 0, - 8943, - 0, - 0, - 0, - 8945, - 8947, - 0, - 0, - 0, - 0, - 8949, - 0, - 8950, - 0, - 8954, - 8957, - 0, - 0, - 8970, - 0, - 0, - 0, - 0, - 8971, - 0, - 8996, - 0, - 0, - 0, - 0, - 8997, - 9000, - 0, - 0, - 0, - 0, - 9001, - 9002, - 0, - 9004, - 9009, - 9024, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9027, - 9082, - 0, - 0, - 9083, - 9089, - 0, - 0, - 0, - 0, - 0, - 0, - 9090, - 0, - 0, - 0, - 9092, - 0, - 0, - 9093, - 0, - 9095, - 0, - 0, - 9096, - 9097, - 9101, - 9102, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9112, - 0, - 0, - 0, - 0, - 0, - 0, - 9114, - 0, - 0, - 9120, - 0, - 9121, - 9122, - 0, - 0, - 0, - 9123, - 9124, - 0, - 0, - 9125, - 0, - 0, - 9126, - 0, - 9127, - 0, - 0, - 9129, - 9131, - 0, - 0, - 0, - 9132, - 0, - 0, - 9136, - 0, - 9144, - 0, - 0, - 9148, - 0, - 0, - 0, - 0, - 0, - 0, - 9149, - 0, - 9152, - 9163, - 0, - 0, - 9165, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9166, - 0, - 9169, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9170, - 0, - 0, - 0, - 0, - 9172, - 0, - 9174, - 9175, - 9176, - 0, - 9177, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9186, - 0, - 9187, - 0, - 0, - 0, - 9188, - 9189, - 0, - 0, - 9190, - 0, - 0, - 0, - 0, - 9191, - 0, - 0, - 0, - 9193, - 0, - 0, - 0, - 0, - 9197, - 9198, - 0, - 0, - 0, - 9208, - 9211, - 0, - 0, - 0, - 0, - 9216, - 9217, - 0, - 9220, - 0, - 0, - 0, - 0, - 9221, - 9222, - 9223, - 0, - 9224, - 9225, - 0, - 0, - 9227, - 0, - 9228, - 9229, - 0, - 0, - 9230, - 0, - 9232, - 0, - 9233, - 0, - 0, - 0, - 0, - 0, - 9234, - 9235, - 0, - 0, - 9237, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9238, - 9240, - 0, - 0, - 9241, - 0, - 0, - 0, - 0, - 9244, - 0, - 0, - 0, - 0, - 9247, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9248, - 0, - 0, - 0, - 9249, - 0, - 0, - 0, - 0, - 0, - 9250, - 0, - 0, - 0, - 0, - 9251, - 0, - 0, - 9252, - 9255, - 0, - 0, - 0, - 9256, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9257, - 0, - 0, - 9258, - 0, - 0, - 0, - 0, - 0, - 0, - 9259, - 0, - 0, - 0, - 0, - 0, - 9262, - 9263, - 0, - 0, - 9265, - 9266, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9268, - 9271, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9273, - 0, - 0, - 0, - 9276, - 9277, - 9279, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9280, - 0, - 0, - 9293, - 0, - 0, - 0, - 0, - 0, - 9297, - 9301, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9308, - 9309, - 9313, - 9321, - 9322, - 0, - 9326, - 9327, - 0, - 0, - 9477, - 0, - 9479, - 0, - 0, - 0, - 0, - 9482, - 0, - 0, - 0, - 9483, - 0, - 9484, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9485, - 0, - 0, - 9486, - 0, - 0, - 0, - 9489, - 0, - 0, - 0, - 0, - 9490, - 9491, - 0, - 0, - 0, - 0, - 9493, - 0, - 9495, - 9496, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9500, - 0, - 9502, - 0, - 0, - 0, - 0, - 0, - 9504, - 9507, - 0, - 9509, - 0, - 9511, - 0, - 0, - 9513, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9515, - 0, - 0, - 0, - 0, - 0, - 0, - 9516, - 9517, - 0, - 0, - 0, - 0, - 9532, - 0, - 0, - 9533, - 0, - 0, - 9538, - 0, - 9539, - 9540, - 0, - 0, - 0, - 0, - 9541, - 0, - 0, - 0, - 9542, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9544, - 9545, - 0, - 9546, - 0, - 0, - 0, - 0, - 0, - 0, - 9547, - 9548, - 0, - 0, - 0, - 9550, - 0, - 9557, - 0, - 9558, - 0, - 9561, - 0, - 9563, - 9570, - 0, - 9572, - 9574, - 9575, - 0, - 0, - 0, - 9577, - 9592, - 0, - 0, - 9596, - 0, - 0, - 0, - 9598, - 0, - 9600, - 0, - 9601, - 0, - 0, - 0, - 0, - 0, - 0, - 9608, - 0, - 9638, - 9639, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9641, - 0, - 0, - 9643, - 9644, - 9645, - 9646, - 0, - 0, - 0, - 9648, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9650, - 9654, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9655, - 0, - 0, - 0, - 0, - 0, - 9656, - 0, - 9657, - 0, - 0, - 0, - 0, - 9658, - 0, - 0, - 9659, - 0, - 0, - 9664, - 0, - 0, - 9665, - 0, - 9667, - 9669, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9671, - 0, - 9673, - 9681, - 0, - 0, - 0, - 0, - 9682, - 9683, - 9684, - 0, - 0, - 0, - 0, - 9686, - 9698, - 0, - 0, - 9700, - 9701, - 9702, - 0, - 9703, - 9717, - 0, - 0, - 0, - 0, - 9718, - 0, - 9726, - 0, - 0, - 0, - 0, - 9727, - 0, - 0, - 0, - 9728, - 0, - 9742, - 0, - 9744, - 0, - 0, - 0, - 9750, - 0, - 9754, - 9755, - 0, - 0, - 0, - 0, - 0, - 9756, - 0, - 9757, - 9768, - 0, - 9769, - 0, - 0, - 0, - 9770, - 9771, - 0, - 9773, - 0, - 9774, - 0, - 9775, - 0, - 0, - 0, - 9776, - 9777, - 9784, - 0, - 0, - 0, - 9786, - 0, - 9789, - 0, - 0, - 0, - 0, - 9793, - 9794, - 0, - 0, - 0, - 9808, - 0, - 0, - 0, - 0, - 0, - 9811, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9812, - 0, - 9820, - 0, - 9823, - 0, - 9828, - 0, - 0, - 0, - 0, - 9830, - 0, - 0, - 9833, - 9836, - 0, - 0, - 0, - 9840, - 0, - 0, - 0, - 9841, - 0, - 0, - 9842, - 0, - 9845, - 0, - 0, - 0, - 9847, - 9848, - 0, - 0, - 9855, - 0, - 0, - 0, - 0, - 0, - 0, - 9856, - 9863, - 9865, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9866, - 9867, - 9868, - 9873, - 9875, - 0, - 0, - 0, - 0, - 0, - 0, - 9880, - 0, - 9886, - 0, - 0, - 0, - 9887, - 0, - 0, - 9891, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9906, - 9907, - 9908, - 0, - 0, - 0, - 9909, - 0, - 0, - 0, - 0, - 0, - 0, - 9910, - 0, - 0, - 0, - 0, - 9913, - 0, - 0, - 0, - 0, - 9914, - 0, - 0, - 0, - 0, - 0, - 9922, - 0, - 0, - 0, - 0, - 9923, - 9925, - 0, - 0, - 0, - 0, - 0, - 0, - 9930, - 0, - 0, - 0, - 9931, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9932, - 0, - 9939, - 0, - 0, - 9940, - 9962, - 9966, - 0, - 9969, - 9970, - 0, - 0, - 9974, - 0, - 9979, - 9981, - 9982, - 0, - 0, - 0, - 9985, - 0, - 0, - 0, - 0, - 0, - 0, - 9987, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 9988, - 9993, - 0, - 0, - 9994, - 0, - 0, - 0, - 9997, - 0, - 10004, - 0, - 0, - 0, - 0, - 0, - 10007, - 10019, - 10020, - 10022, - 0, - 0, - 0, - 10031, - 0, - 0, - 0, - 0, - 0, - 10032, - 0, - 0, - 10034, - 0, - 10036, - 0, - 0, - 0, - 0, - 10038, - 0, - 10039, - 10040, - 10041, - 10042, - 0, - 0, - 0, - 0, - 0, - 10043, - 0, - 0, - 0, - 0, - 0, - 10045, - 10054, - 0, - 0, - 0, - 0, - 10055, - 0, - 0, - 10057, - 10058, - 0, - 0, - 0, - 0, - 0, - 0, - 10059, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10060, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10063, - 0, - 10066, - 0, - 0, - 0, - 10070, - 0, - 10072, - 0, - 0, - 10076, - 10077, - 0, - 0, - 10084, - 0, - 10087, - 10090, - 10091, - 0, - 0, - 0, - 10094, - 10097, - 0, - 0, - 0, - 0, - 0, - 0, - 10098, - 0, - 0, - 0, - 0, - 0, - 0, - 10103, - 0, - 10104, - 0, - 10108, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10120, - 0, - 0, - 0, - 10122, - 0, - 0, - 10125, - 0, - 0, - 0, - 0, - 10127, - 10128, - 0, - 0, - 10134, - 0, - 10135, - 10136, - 0, - 10137, - 0, - 0, - 10147, - 0, - 10149, - 10150, - 0, - 0, - 10156, - 0, - 10158, - 10159, - 10160, - 10168, - 0, - 0, - 10171, - 0, - 10173, - 0, - 0, - 0, - 10176, - 0, - 0, - 0, - 0, - 10177, - 0, - 0, - 0, - 0, - 10178, - 0, - 0, - 0, - 0, - 10194, - 0, - 10202, - 0, - 0, - 10203, - 10204, - 0, - 10205, - 10206, - 0, - 10207, - 0, - 0, - 0, - 0, - 10209, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10213, - 0, - 0, - 0, - 0, - 0, - 0, - 10217, - 0, - 10229, - 0, - 10230, - 10231, - 0, - 0, - 10232, - 0, - 0, - 10237, - 10238, - 10244, - 0, - 0, - 0, - 0, - 0, - 10250, - 0, - 10252, - 0, - 0, - 0, - 0, - 0, - 0, - 10255, - 0, - 0, - 10257, - 0, - 0, - 0, - 0, - 0, - 0, - 10258, - 0, - 10259, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10260, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10284, - 10288, - 10289, - 0, - 0, - 0, - 10290, - 0, - 10296, - 0, - 0, - 0, - 0, - 0, - 10297, - 0, - 0, - 0, - 0, - 0, - 0, - 10298, - 0, - 0, - 0, - 0, - 10299, - 10303, - 0, - 0, - 0, - 0, - 0, - 10306, - 0, - 0, - 0, - 10307, - 0, - 10308, - 0, - 0, - 0, - 0, - 10311, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10315, - 10317, - 0, - 0, - 0, - 10318, - 10319, - 0, - 10321, - 0, - 10326, - 0, - 10328, - 0, - 0, - 0, - 0, - 10329, - 0, - 0, - 10331, - 0, - 10332, - 0, - 0, - 0, - 0, - 0, - 0, - 10334, - 0, - 0, - 10335, - 10338, - 0, - 0, - 0, - 0, - 0, - 10339, - 10349, - 0, - 0, - 0, - 0, - 0, - 0, - 10351, - 0, - 10353, - 0, - 0, - 0, - 0, - 0, - 0, - 10362, - 0, - 10368, - 0, - 10369, - 0, - 0, - 0, - 10372, - 10373, - 0, - 0, - 0, - 0, - 0, - 10374, - 0, - 0, - 0, - 10375, - 0, - 10376, - 0, - 0, - 10386, - 10388, - 10390, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10391, - 0, - 0, - 10392, - 10394, - 0, - 0, - 10396, - 0, - 10397, - 0, - 10403, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10404, - 0, - 10405, - 10410, - 0, - 0, - 10411, - 0, - 10412, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10421, - 10422, - 10423, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10425, - 0, - 0, - 10427, - 0, - 0, - 10430, - 0, - 0, - 0, - 0, - 0, - 10432, - 0, - 10433, - 10434, - 0, - 0, - 0, - 0, - 10436, - 10437, - 0, - 10438, - 0, - 10439, - 0, - 10444, - 10446, - 0, - 0, - 0, - 0, - 0, - 10448, - 0, - 0, - 0, - 0, - 0, - 10449, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10451, - 0, - 10453, - 0, - 0, - 0, - 10454, - 10457, - 0, - 0, - 10459, - 0, - 10469, - 0, - 0, - 0, - 0, - 0, - 10472, - 10481, - 0, - 0, - 0, - 0, - 0, - 10482, - 10483, - 0, - 10492, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10499, - 0, - 0, - 0, - 10502, - 0, - 0, - 10510, - 0, - 10521, - 10524, - 0, - 0, - 10525, - 10526, - 10528, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10530, - 0, - 0, - 0, - 0, - 10533, - 0, - 10534, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10535, - 10536, - 0, - 0, - 10544, - 0, - 10553, - 10556, - 0, - 10557, - 10559, - 0, - 0, - 0, - 0, - 0, - 10562, - 10563, - 10564, - 0, - 10565, - 0, - 0, - 0, - 10566, - 0, - 10567, - 0, - 0, - 0, - 0, - 10575, - 0, - 0, - 10576, - 0, - 10578, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10585, - 10586, - 10587, - 10589, - 0, - 10590, - 0, - 0, - 10594, - 0, - 0, - 0, - 0, - 0, - 10598, - 0, - 0, - 10601, - 0, - 0, - 0, - 10602, - 0, - 10603, - 0, - 10604, - 0, - 10605, - 0, - 0, - 10607, - 0, - 10626, - 0, - 10627, - 0, - 0, - 0, - 0, - 0, - 10629, - 10630, - 10631, - 0, - 0, - 0, - 10646, - 0, - 0, - 0, - 10647, - 0, - 10650, - 0, - 10651, - 0, - 0, - 0, - 10652, - 10653, - 10655, - 0, - 10658, - 0, - 0, - 10659, - 0, - 10667, - 0, - 0, - 0, - 0, - 10669, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10670, - 0, - 0, - 0, - 10671, - 0, - 0, - 0, - 0, - 10672, - 10673, - 0, - 10674, - 0, - 0, - 0, - 10676, - 0, - 0, - 0, - 0, - 0, - 0, - 10678, - 0, - 10682, - 0, - 0, - 10692, - 0, - 10697, - 0, - 0, - 0, - 0, - 10698, - 0, - 0, - 0, - 10700, - 0, - 0, - 0, - 0, - 0, - 10703, - 0, - 10704, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10705, - 0, - 10715, - 10718, - 10720, - 0, - 0, - 10722, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10723, - 0, - 0, - 0, - 0, - 10726, - 0, - 0, - 0, - 0, - 0, - 10727, - 10730, - 10743, - 0, - 0, - 0, - 0, - 0, - 0, - 10744, - 0, - 0, - 10745, - 0, - 0, - 0, - 0, - 0, - 0, - 10748, - 0, - 0, - 0, - 0, - 10750, - 0, - 0, - 10752, - 10753, - 0, - 0, - 0, - 10756, - 0, - 0, - 0, - 0, - 0, - 0, - 10758, - 0, - 0, - 0, - 10759, - 0, - 10769, - 0, - 0, - 10772, - 0, - 0, - 0, - 0, - 0, - 0, - 10773, - 0, - 0, - 0, - 10777, - 0, - 0, - 10779, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10780, - 10784, - 0, - 0, - 0, - 10789, - 0, - 0, - 0, - 10791, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10795, - 0, - 0, - 10796, - 0, - 10808, - 0, - 10809, - 0, - 0, - 0, - 10810, - 0, - 0, - 0, - 10812, - 0, - 0, - 10814, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10815, - 0, - 0, - 0, - 0, - 10816, - 10817, - 0, - 0, - 0, - 0, - 10819, - 0, - 10820, - 0, - 0, - 0, - 0, - 10821, - 10822, - 10823, - 0, - 10826, - 10849, - 0, - 0, - 0, - 0, - 10850, - 0, - 0, - 10852, - 0, - 10853, - 0, - 0, - 10856, - 0, - 0, - 10857, - 10858, - 10859, - 10860, - 0, - 0, - 0, - 0, - 0, - 0, - 10863, - 0, - 10866, - 10867, - 10872, - 10890, - 0, - 0, - 10891, - 10892, - 0, - 0, - 0, - 0, - 0, - 10893, - 0, - 0, - 0, - 10896, - 10899, - 0, - 0, - 10900, - 10902, - 0, - 0, - 0, - 0, - 0, - 10903, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10905, - 0, - 10906, - 0, - 0, - 0, - 0, - 10908, - 10911, - 0, - 10912, - 0, - 0, - 10916, - 0, - 0, - 0, - 0, - 0, - 10917, - 0, - 10918, - 0, - 0, - 0, - 10923, - 0, - 0, - 0, - 0, - 0, - 10924, - 0, - 0, - 10928, - 10929, - 0, - 0, - 10930, - 0, - 0, - 0, - 10932, - 0, - 0, - 0, - 0, - 10939, - 0, - 0, - 10945, - 0, - 0, - 0, - 10947, - 0, - 0, - 10948, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10958, - 0, - 10960, - 10962, - 0, - 0, - 10964, - 0, - 0, - 0, - 10966, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 10967, - 0, - 0, - 0, - 10968, - 0, - 0, - 0, - 10973, - 0, - 0, - 0, - 0, - 0, - 10975, - 0, - 0, - 0, - 10976, - 10978, - 0, - 0, - 10982, - 10984, - 10987, - 0, - 0, - 10988, - 0, - 10989, - 0, - 0, - 10991, - 0, - 0, - 0, - 0, - 10992, - 0, - 0, - 0, - 10993, - 0, - 10995, - 0, - 0, - 0, - 10996, - 10997, - 0, - 0, - 0, - 10998, - 0, - 10999, - 0, - 11001, - 0, - 0, - 0, - 0, - 0, - 0, - 11010, - 11012, - 0, - 11013, - 11016, - 11017, - 0, - 0, - 11019, - 11020, - 11021, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11022, - 0, - 0, - 11023, - 11029, - 0, - 0, - 0, - 0, - 11031, - 0, - 0, - 0, - 11034, - 0, - 0, - 0, - 0, - 11055, - 0, - 0, - 0, - 0, - 0, - 11056, - 11060, - 0, - 0, - 0, - 0, - 0, - 0, - 11061, - 0, - 0, - 11064, - 11065, - 0, - 11066, - 0, - 11069, - 0, - 11085, - 0, - 0, - 0, - 0, - 0, - 11086, - 0, - 0, - 0, - 11088, - 0, - 0, - 0, - 11094, - 0, - 0, - 0, - 11095, - 11096, - 0, - 0, - 0, - 0, - 0, - 0, - 11097, - 11098, - 0, - 0, - 0, - 0, - 0, - 0, - 11099, - 0, - 0, - 11102, - 11108, - 0, - 0, - 0, - 11109, - 0, - 11114, - 11119, - 0, - 11131, - 0, - 0, - 0, - 11142, - 0, - 0, - 11143, - 0, - 11146, - 0, - 11147, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11148, - 0, - 11149, - 11152, - 11153, - 11154, - 0, - 11156, - 0, - 11157, - 0, - 0, - 0, - 11158, - 0, - 0, - 11159, - 11160, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11163, - 0, - 0, - 11164, - 11166, - 0, - 0, - 0, - 11172, - 11174, - 0, - 0, - 0, - 11176, - 0, - 0, - 0, - 0, - 0, - 11182, - 11183, - 0, - 0, - 0, - 11184, - 11187, - 0, - 0, - 11188, - 11189, - 0, - 0, - 0, - 0, - 0, - 0, - 11194, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11200, - 11202, - 0, - 0, - 0, - 0, - 0, - 0, - 11203, - 0, - 11204, - 0, - 0, - 0, - 0, - 0, - 11205, - 0, - 0, - 0, - 11206, - 0, - 11207, - 0, - 0, - 11209, - 0, - 11211, - 0, - 11214, - 0, - 0, - 11231, - 0, - 0, - 0, - 11293, - 11295, - 0, - 0, - 11296, - 11297, - 11302, - 0, - 0, - 0, - 11307, - 0, - 0, - 0, - 0, - 11309, - 11310, - 0, - 11311, - 0, - 0, - 0, - 11313, - 0, - 11314, - 0, - 0, - 0, - 0, - 11334, - 0, - 11338, - 0, - 0, - 0, - 11339, - 0, - 0, - 0, - 0, - 0, - 11340, - 0, - 11341, - 11342, - 0, - 11344, - 0, - 11345, - 0, - 0, - 0, - 11348, - 11349, - 0, - 0, - 11350, - 0, - 0, - 0, - 11355, - 0, - 0, - 0, - 0, - 0, - 0, - 11356, - 0, - 11357, - 11370, - 0, - 0, - 11371, - 0, - 11374, - 11376, - 0, - 0, - 0, - 11377, - 0, - 0, - 11378, - 11383, - 0, - 11386, - 11399, - 0, - 11400, - 11406, - 0, - 0, - 0, - 11408, - 0, - 0, - 11409, - 11412, - 0, - 0, - 0, - 0, - 11417, - 0, - 0, - 0, - 11418, - 0, - 11421, - 0, - 11426, - 11429, - 0, - 0, - 0, - 0, - 0, - 11430, - 0, - 11437, - 0, - 11438, - 0, - 0, - 0, - 0, - 0, - 11440, - 11453, - 0, - 0, - 0, - 0, - 0, - 0, - 11454, - 0, - 0, - 0, - 0, - 11455, - 0, - 0, - 11456, - 11460, - 11461, - 11463, - 0, - 11469, - 0, - 11473, - 0, - 0, - 0, - 0, - 11474, - 0, - 0, - 0, - 11475, - 0, - 11476, - 11477, - 11480, - 0, - 0, - 0, - 0, - 11481, - 0, - 0, - 11484, - 0, - 0, - 11487, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11497, - 0, - 0, - 11502, - 0, - 11509, - 0, - 0, - 11510, - 11511, - 11513, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11515, - 0, - 0, - 0, - 0, - 11516, - 0, - 11520, - 11521, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11529, - 11530, - 11531, - 11534, - 0, - 0, - 11543, - 0, - 0, - 0, - 0, - 0, - 11547, - 0, - 11548, - 0, - 0, - 0, - 0, - 0, - 11552, - 11556, - 0, - 11557, - 0, - 0, - 11559, - 0, - 11560, - 0, - 0, - 0, - 0, - 0, - 0, - 11561, - 0, - 0, - 11563, - 11564, - 0, - 11565, - 0, - 0, - 0, - 0, - 11567, - 0, - 0, - 0, - 11569, - 0, - 11574, - 0, - 11575, - 0, - 0, - 0, - 11577, - 0, - 11578, - 0, - 0, - 0, - 11580, - 11581, - 0, - 0, - 0, - 11582, - 11584, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11587, - 0, - 11588, - 11591, - 0, - 11595, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11596, - 0, - 11597, - 0, - 0, - 0, - 0, - 11598, - 11601, - 0, - 0, - 0, - 11602, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11603, - 11604, - 0, - 11606, - 0, - 0, - 11608, - 0, - 0, - 0, - 0, - 11610, - 0, - 0, - 11611, - 0, - 0, - 0, - 0, - 11613, - 0, - 11622, - 0, - 0, - 0, - 11623, - 0, - 0, - 0, - 0, - 11625, - 0, - 0, - 11626, - 11627, - 11628, - 11630, - 0, - 0, - 0, - 0, - 0, - 0, - 11639, - 0, - 0, - 11646, - 0, - 11648, - 11649, - 0, - 11650, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11651, - 0, - 0, - 11652, - 11653, - 11656, - 0, - 0, - 11677, - 11679, - 0, - 0, - 0, - 0, - 11680, - 0, - 0, - 11681, - 0, - 11685, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11688, - 0, - 0, - 0, - 11716, - 0, - 11719, - 0, - 0, - 0, - 0, - 0, - 11721, - 0, - 0, - 11724, - 11743, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11745, - 11748, - 11750, - 0, - 0, - 0, - 0, - 0, - 11751, - 0, - 0, - 0, - 11752, - 11754, - 0, - 11755, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11759, - 0, - 0, - 0, - 0, - 0, - 0, - 11760, - 0, - 0, - 0, - 11761, - 0, - 0, - 0, - 0, - 0, - 0, - 11766, - 11767, - 0, - 11772, - 11773, - 0, - 11774, - 0, - 0, - 11775, - 0, - 11777, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11778, - 11780, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11783, - 0, - 11784, - 0, - 0, - 0, - 11785, - 0, - 0, - 0, - 11786, - 0, - 0, - 0, - 0, - 11788, - 0, - 0, - 11789, - 11791, - 11792, - 0, - 0, - 0, - 0, - 11795, - 11834, - 11835, - 11836, - 0, - 0, - 11837, - 0, - 0, - 0, - 11838, - 0, - 0, - 11846, - 11851, - 0, - 11852, - 0, - 11869, - 0, - 0, - 0, - 11871, - 0, - 0, - 0, - 11872, - 11874, - 0, - 0, - 0, - 0, - 0, - 0, - 11875, - 0, - 11876, - 11877, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11883, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11884, - 0, - 11885, - 0, - 11886, - 0, - 0, - 11887, - 0, - 11894, - 11895, - 11897, - 11909, - 11910, - 0, - 11912, - 11918, - 0, - 0, - 11920, - 0, - 11922, - 11924, - 11927, - 11928, - 0, - 0, - 0, - 0, - 11929, - 0, - 11934, - 0, - 0, - 0, - 0, - 0, - 11941, - 11943, - 11944, - 0, - 11945, - 0, - 0, - 0, - 0, - 11948, - 11949, - 0, - 0, - 0, - 0, - 11953, - 0, - 11954, - 0, - 11955, - 0, - 11956, - 0, - 0, - 0, - 0, - 0, - 11957, - 0, - 0, - 11959, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 11961, - 0, - 0, - 0, - 0, - 0, - 11978, - 0, - 0, - 0, - 11979, - 11980, - 11986, - 11987, - 0, - 11992, - 0, - 0, - 0, - 0, - 0, - 11993, - 0, - 0, - 0, - 11994, - 0, - 11999, - 12004, - 12005, - 12006, - 0, - 0, - 0, - 0, - 0, - 12011, - 0, - 0, - 12012, - 12014, - 0, - 0, - 12015, - 0, - 0, - 12019, - 12028, - 0, - 0, - 12029, - 0, - 0, - 12032, - 12033, - 0, - 0, - 0, - 0, - 12034, - 0, - 12041, - 12043, - 0, - 0, - 12044, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12046, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12054, - 12055, - 0, - 12056, - 0, - 0, - 0, - 12060, - 12064, - 0, - 0, - 0, - 0, - 0, - 12065, - 12067, - 12068, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12074, - 0, - 0, - 0, - 12075, - 12076, - 0, - 0, - 0, - 12079, - 0, - 12081, - 12086, - 12087, - 0, - 0, - 12088, - 0, - 0, - 0, - 0, - 12089, - 0, - 12092, - 0, - 0, - 0, - 0, - 12097, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12098, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12102, - 12103, - 12104, - 12111, - 0, - 0, - 12114, - 12116, - 0, - 0, - 0, - 12118, - 0, - 0, - 0, - 12119, - 12120, - 12128, - 0, - 0, - 0, - 0, - 12130, - 0, - 0, - 0, - 0, - 0, - 0, - 12131, - 0, - 0, - 0, - 12132, - 12134, - 0, - 0, - 0, - 0, - 12137, - 0, - 12139, - 0, - 12141, - 0, - 0, - 12142, - 0, - 0, - 0, - 12144, - 0, - 0, - 0, - 0, - 0, - 12145, - 0, - 12148, - 0, - 12153, - 0, - 0, - 0, - 0, - 12154, - 12171, - 12173, - 0, - 0, - 0, - 12175, - 0, - 0, - 0, - 0, - 12178, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12183, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12184, - 0, - 0, - 0, - 12186, - 0, - 0, - 0, - 0, - 0, - 12187, - 12188, - 0, - 0, - 12189, - 0, - 12196, - 0, - 12197, - 0, - 0, - 12198, - 0, - 12201, - 0, - 0, - 0, - 0, - 12203, - 0, - 12209, - 0, - 0, - 0, - 0, - 12210, - 12211, - 12212, - 12213, - 0, - 12217, - 12218, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12222, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12223, - 0, - 0, - 12229, - 0, - 0, - 0, - 0, - 12233, - 0, - 0, - 0, - 0, - 12234, - 0, - 0, - 12236, - 12242, - 0, - 0, - 0, - 12243, - 0, - 0, - 0, - 12244, - 12253, - 0, - 12254, - 12256, - 0, - 12257, - 0, - 0, - 12275, - 0, - 0, - 0, - 0, - 0, - 12277, - 0, - 0, - 0, - 0, - 0, - 12278, - 0, - 12289, - 0, - 0, - 12290, - 0, - 12292, - 12293, - 0, - 0, - 12294, - 0, - 12295, - 0, - 0, - 12296, - 0, - 12297, - 0, - 12298, - 0, - 0, - 0, - 0, - 12301, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12309, - 0, - 12338, - 12340, - 0, - 0, - 0, - 0, - 12341, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12342, - 12343, - 0, - 12344, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12345, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12346, - 0, - 0, - 0, - 0, - 12348, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12350, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12351, - 0, - 12355, - 12356, - 12357, - 0, - 0, - 12367, - 12370, - 12371, - 0, - 0, - 0, - 0, - 0, - 12372, - 12376, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12379, - 0, - 12382, - 0, - 12383, - 0, - 0, - 12384, - 0, - 0, - 0, - 0, - 12393, - 0, - 0, - 12394, - 0, - 0, - 0, - 0, - 12398, - 12403, - 0, - 0, - 12404, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12410, - 0, - 0, - 0, - 12411, - 0, - 0, - 0, - 12412, - 0, - 0, - 0, - 0, - 12420, - 0, - 12421, - 0, - 0, - 0, - 0, - 0, - 12423, - 0, - 12425, - 12429, - 0, - 0, - 0, - 12431, - 12432, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12434, - 0, - 0, - 0, - 0, - 0, - 12435, - 12436, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12437, - 0, - 0, - 0, - 0, - 0, - 12438, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12445, - 0, - 0, - 0, - 12450, - 12451, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12452, - 12475, - 0, - 0, - 12493, - 12494, - 0, - 0, - 0, - 12495, - 0, - 0, - 0, - 0, - 12496, - 12502, - 12509, - 0, - 0, - 0, - 0, - 12510, - 0, - 12512, - 12513, - 0, - 0, - 0, - 0, - 12514, - 0, - 0, - 0, - 12515, - 0, - 12520, - 0, - 0, - 0, - 12524, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12527, - 0, - 0, - 0, - 12528, - 0, - 0, - 0, - 12529, - 0, - 0, - 0, - 0, - 0, - 12530, - 0, - 12535, - 0, - 0, - 12536, - 0, - 12538, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12540, - 0, - 12548, - 0, - 0, - 0, - 0, - 0, - 12550, - 0, - 0, - 0, - 12551, - 12552, - 0, - 0, - 0, - 12554, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12555, - 0, - 0, - 12562, - 0, - 12565, - 0, - 12566, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12569, - 0, - 0, - 0, - 12571, - 12574, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12577, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12578, - 12579, - 12603, - 0, - 12608, - 0, - 0, - 12611, - 0, - 12612, - 0, - 12615, - 0, - 12625, - 0, - 0, - 0, - 0, - 12627, - 12646, - 0, - 12648, - 0, - 0, - 12657, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12670, - 0, - 0, - 12671, - 0, - 12673, - 12677, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12679, - 0, - 12681, - 0, - 12682, - 12693, - 0, - 12694, - 0, - 12697, - 0, - 12701, - 0, - 0, - 0, - 12703, - 12704, - 0, - 0, - 0, - 0, - 12707, - 12737, - 0, - 0, - 12739, - 0, - 0, - 12740, - 0, - 0, - 12742, - 12743, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12745, - 0, - 12746, - 12747, - 0, - 12748, - 0, - 0, - 12759, - 12767, - 0, - 0, - 0, - 0, - 12773, - 0, - 12774, - 12778, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12779, - 0, - 0, - 0, - 0, - 0, - 12780, - 12793, - 0, - 12824, - 0, - 12825, - 0, - 12836, - 0, - 0, - 0, - 0, - 12839, - 0, - 12842, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12843, - 12845, - 0, - 12846, - 0, - 0, - 0, - 0, - 12847, - 0, - 0, - 12850, - 12852, - 12853, - 0, - 0, - 0, - 12854, - 0, - 0, - 0, - 12855, - 0, - 12856, - 0, - 12858, - 0, - 0, - 12859, - 0, - 12862, - 0, - 12863, - 0, - 0, - 12866, - 0, - 12869, - 12872, - 12873, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12875, - 0, - 12877, - 0, - 0, - 12878, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12884, - 12885, - 12888, - 0, - 12889, - 0, - 0, - 0, - 0, - 12893, - 0, - 0, - 0, - 12895, - 12896, - 12898, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12902, - 0, - 12909, - 12910, - 0, - 12926, - 0, - 12928, - 0, - 0, - 0, - 12929, - 0, - 12930, - 0, - 0, - 0, - 0, - 12931, - 0, - 12932, - 12933, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12934, - 0, - 12942, - 0, - 0, - 0, - 0, - 12944, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12946, - 0, - 0, - 12948, - 0, - 0, - 12949, - 0, - 0, - 0, - 0, - 12950, - 0, - 0, - 0, - 0, - 12951, - 0, - 12952, - 0, - 12953, - 0, - 0, - 0, - 12954, - 12958, - 12959, - 0, - 0, - 0, - 0, - 0, - 12960, - 12964, - 0, - 0, - 0, - 0, - 0, - 12966, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 12970, - 0, - 12971, - 0, - 0, - 0, - 0, - 0, - 0, - 12972, - 0, - 0, - 12982, - 0, - 0, - 0, - 12984, - 12985, - 0, - 12986, - 12996, - 12997, - 13001, - 13002, - 0, - 0, - 0, - 0, - 13004, - 0, - 0, - 13005, - 0, - 0, - 13007, - 13009, - 0, - 13017, - 0, - 0, - 0, - 13020, - 0, - 13021, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13022, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13024, - 13027, - 0, - 0, - 0, - 0, - 0, - 13028, - 0, - 0, - 13029, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13032, - 0, - 13037, - 0, - 0, - 0, - 0, - 0, - 0, - 13040, - 0, - 0, - 13041, - 0, - 0, - 0, - 13043, - 13044, - 13046, - 0, - 0, - 0, - 0, - 13047, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13049, - 13054, - 0, - 13056, - 0, - 0, - 13060, - 13061, - 0, - 0, - 0, - 0, - 0, - 13067, - 0, - 0, - 13068, - 0, - 13071, - 0, - 0, - 0, - 0, - 0, - 13077, - 13078, - 0, - 0, - 0, - 0, - 0, - 13079, - 13080, - 13081, - 0, - 13082, - 0, - 0, - 0, - 13085, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13086, - 0, - 13087, - 13088, - 0, - 0, - 0, - 0, - 0, - 13094, - 0, - 13099, - 0, - 13100, - 0, - 0, - 0, - 13101, - 0, - 13125, - 13126, - 13128, - 13129, - 0, - 0, - 13130, - 0, - 13131, - 0, - 0, - 0, - 0, - 0, - 0, - 13134, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13150, - 0, - 13168, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13169, - 0, - 0, - 13170, - 0, - 0, - 0, - 0, - 13174, - 0, - 0, - 0, - 13176, - 0, - 0, - 0, - 0, - 0, - 13177, - 0, - 13178, - 13183, - 13187, - 0, - 0, - 0, - 13189, - 0, - 0, - 13190, - 0, - 0, - 13191, - 0, - 0, - 13206, - 0, - 0, - 0, - 13207, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13212, - 0, - 0, - 13219, - 13232, - 0, - 0, - 0, - 13241, - 0, - 13249, - 13253, - 0, - 0, - 0, - 0, - 0, - 13255, - 13259, - 0, - 13260, - 13261, - 0, - 13262, - 0, - 13272, - 0, - 0, - 0, - 0, - 13276, - 0, - 0, - 0, - 0, - 13277, - 13299, - 0, - 0, - 13301, - 13302, - 0, - 0, - 13303, - 0, - 0, - 13305, - 0, - 13310, - 0, - 0, - 0, - 13311, - 0, - 0, - 0, - 0, - 13325, - 0, - 13328, - 0, - 0, - 0, - 13329, - 0, - 0, - 0, - 0, - 0, - 0, - 13330, - 0, - 0, - 13331, - 0, - 13335, - 0, - 0, - 13342, - 0, - 0, - 0, - 0, - 0, - 13343, - 0, - 13354, - 0, - 13362, - 0, - 13366, - 13367, - 13369, - 0, - 0, - 13371, - 13372, - 0, - 13373, - 13374, - 0, - 13376, - 0, - 13380, - 13381, - 13386, - 0, - 13387, - 13388, - 0, - 13389, - 13391, - 13395, - 0, - 0, - 0, - 0, - 0, - 13401, - 13409, - 0, - 13410, - 0, - 0, - 0, - 0, - 13420, - 0, - 0, - 0, - 0, - 0, - 13422, - 0, - 0, - 0, - 0, - 13423, - 0, - 0, - 0, - 0, - 13425, - 0, - 0, - 0, - 0, - 0, - 13427, - 0, - 0, - 0, - 13428, - 0, - 0, - 13430, - 13438, - 0, - 13439, - 0, - 13445, - 0, - 13448, - 13449, - 0, - 0, - 0, - 0, - 0, - 0, - 13451, - 0, - 13457, - 0, - 0, - 0, - 0, - 13458, - 13459, - 0, - 13460, - 0, - 0, - 0, - 0, - 13464, - 13465, - 13466, - 13470, - 0, - 13471, - 13472, - 13474, - 13475, - 0, - 13476, - 0, - 0, - 13478, - 13479, - 0, - 13481, - 0, - 0, - 0, - 0, - 13487, - 0, - 13490, - 0, - 13493, - 0, - 0, - 13494, - 0, - 0, - 13495, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13496, - 13497, - 0, - 13500, - 0, - 0, - 13516, - 13522, - 0, - 0, - 13525, - 13528, - 0, - 0, - 0, - 13530, - 13535, - 0, - 13537, - 13539, - 0, - 13540, - 0, - 13543, - 0, - 13544, - 0, - 0, - 0, - 0, - 0, - 0, - 13545, - 0, - 0, - 0, - 0, - 0, - 0, - 13547, - 0, - 0, - 0, - 13549, - 13555, - 0, - 0, - 0, - 13556, - 13557, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13558, - 0, - 13563, - 0, - 0, - 0, - 0, - 13564, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13566, - 0, - 0, - 0, - 0, - 0, - 0, - 13569, - 0, - 0, - 13571, - 0, - 0, - 0, - 0, - 13573, - 0, - 0, - 0, - 0, - 0, - 0, - 13578, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13581, - 0, - 13586, - 0, - 13595, - 0, - 13600, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13601, - 13603, - 0, - 13604, - 13605, - 13606, - 13607, - 0, - 0, - 13617, - 13618, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13623, - 0, - 13625, - 13627, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13629, - 0, - 0, - 0, - 13634, - 0, - 0, - 0, - 13638, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13654, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13656, - 0, - 13659, - 0, - 0, - 13660, - 0, - 0, - 13662, - 0, - 0, - 0, - 13663, - 0, - 13664, - 0, - 0, - 0, - 0, - 0, - 13668, - 0, - 13669, - 13671, - 0, - 0, - 13672, - 0, - 0, - 0, - 0, - 0, - 0, - 13675, - 13685, - 0, - 13686, - 0, - 0, - 0, - 13687, - 0, - 0, - 0, - 13692, - 13694, - 13697, - 0, - 0, - 0, - 13702, - 0, - 0, - 0, - 0, - 0, - 13705, - 0, - 0, - 0, - 0, - 13707, - 0, - 0, - 0, - 13714, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13715, - 0, - 13716, - 13717, - 0, - 0, - 13719, - 13724, - 13730, - 13731, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13732, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13734, - 0, - 13736, - 0, - 0, - 13737, - 13738, - 13747, - 0, - 13751, - 0, - 0, - 13752, - 0, - 0, - 0, - 13753, - 0, - 13757, - 0, - 0, - 13762, - 13763, - 0, - 13764, - 13765, - 0, - 13766, - 0, - 0, - 13767, - 0, - 0, - 0, - 13768, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13769, - 0, - 0, - 13772, - 0, - 13775, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13776, - 13778, - 13787, - 0, - 0, - 0, - 13797, - 0, - 13798, - 0, - 13801, - 0, - 13804, - 13806, - 0, - 0, - 0, - 0, - 13816, - 13817, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13834, - 0, - 13836, - 0, - 0, - 13838, - 0, - 0, - 13839, - 0, - 13840, - 0, - 0, - 0, - 0, - 13842, - 0, - 0, - 0, - 0, - 0, - 0, - 13843, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13845, - 0, - 0, - 0, - 0, - 0, - 13858, - 0, - 0, - 13860, - 0, - 0, - 13861, - 0, - 0, - 13862, - 13863, - 0, - 13868, - 0, - 13869, - 13870, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13872, - 0, - 0, - 0, - 0, - 13873, - 13878, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13886, - 0, - 13888, - 13889, - 13890, - 0, - 0, - 13891, - 13894, - 0, - 13897, - 13899, - 13900, - 13904, - 0, - 0, - 13906, - 0, - 0, - 0, - 13909, - 0, - 0, - 0, - 13910, - 0, - 0, - 0, - 13911, - 0, - 0, - 0, - 0, - 0, - 13912, - 13917, - 0, - 0, - 0, - 0, - 13918, - 0, - 13919, - 0, - 0, - 13920, - 0, - 0, - 0, - 13921, - 0, - 0, - 13922, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13924, - 0, - 13927, - 0, - 0, - 0, - 0, - 0, - 13932, - 0, - 13933, - 0, - 13934, - 0, - 0, - 13935, - 0, - 13944, - 0, - 0, - 0, - 13954, - 0, - 0, - 13955, - 0, - 0, - 0, - 0, - 13956, - 0, - 13957, - 0, - 13967, - 13969, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 13970, - 13990, - 0, - 13991, - 13994, - 0, - 13995, - 0, - 0, - 0, - 0, - 13996, - 0, - 0, - 13999, - 0, - 0, - 0, - 14018, - 0, - 14019, - 0, - 14021, - 0, - 0, - 0, - 0, - 0, - 0, - 14041, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14043, - 0, - 0, - 0, - 0, - 14046, - 0, - 0, - 0, - 14048, - 14049, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14051, - 0, - 0, - 14052, - 14056, - 0, - 14063, - 0, - 14064, - 14066, - 0, - 0, - 14067, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14068, - 0, - 0, - 0, - 14072, - 0, - 14074, - 14075, - 0, - 14076, - 14079, - 14085, - 14086, - 14087, - 14093, - 0, - 0, - 0, - 0, - 14095, - 0, - 0, - 0, - 0, - 0, - 0, - 14096, - 14097, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14098, - 0, - 14102, - 0, - 0, - 0, - 0, - 0, - 14103, - 0, - 0, - 0, - 14104, - 0, - 0, - 14105, - 0, - 0, - 0, - 14107, - 14108, - 0, - 0, - 14109, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14117, - 0, - 0, - 0, - 0, - 14118, - 0, - 0, - 0, - 0, - 14119, - 0, - 0, - 14120, - 0, - 0, - 14121, - 0, - 14122, - 14127, - 0, - 14128, - 14136, - 0, - 0, - 14138, - 0, - 14140, - 0, - 0, - 0, - 14141, - 14142, - 0, - 0, - 0, - 0, - 14146, - 0, - 0, - 14149, - 0, - 14151, - 0, - 0, - 0, - 14152, - 0, - 0, - 14153, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14154, - 0, - 14156, - 14157, - 0, - 0, - 14159, - 0, - 14161, - 0, - 0, - 0, - 0, - 14162, - 0, - 0, - 0, - 0, - 0, - 0, - 14163, - 0, - 0, - 14173, - 0, - 0, - 0, - 0, - 0, - 0, - 14174, - 0, - 0, - 14176, - 0, - 0, - 14178, - 0, - 0, - 14179, - 14181, - 0, - 0, - 14182, - 14185, - 14187, - 0, - 14190, - 0, - 0, - 14197, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14198, - 0, - 0, - 0, - 0, - 0, - 0, - 14199, - 14200, - 0, - 0, - 0, - 14204, - 0, - 0, - 14208, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14231, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14234, - 0, - 0, - 14235, - 0, - 0, - 0, - 14240, - 14241, - 0, - 0, - 0, - 14246, - 0, - 0, - 0, - 14247, - 0, - 14250, - 0, - 0, - 14251, - 0, - 0, - 14254, - 0, - 0, - 14256, - 0, - 0, - 0, - 14260, - 0, - 14261, - 0, - 0, - 0, - 0, - 14262, - 14267, - 14269, - 0, - 0, - 14277, - 0, - 0, - 14278, - 0, - 14279, - 14282, - 0, - 0, - 0, - 14283, - 0, - 0, - 0, - 14284, - 14285, - 0, - 0, - 0, - 0, - 14286, - 0, - 0, - 0, - 14288, - 0, - 0, - 0, - 14289, - 0, - 14290, - 0, - 14293, - 14301, - 14302, - 14304, - 14305, - 0, - 14307, - 0, - 14308, - 14309, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14311, - 14312, - 0, - 0, - 14317, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14318, - 0, - 0, - 0, - 0, - 14320, - 0, - 0, - 0, - 0, - 14321, - 14322, - 0, - 0, - 0, - 0, - 0, - 14326, - 14329, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14330, - 14331, - 0, - 0, - 0, - 0, - 14332, - 0, - 0, - 0, - 14333, - 0, - 0, - 14337, - 14340, - 0, - 14341, - 0, - 0, - 14342, - 0, - 14345, - 14346, - 0, - 0, - 14347, - 0, - 14362, - 0, - 0, - 0, - 0, - 0, - 14364, - 14365, - 14371, - 0, - 14373, - 0, - 0, - 14374, - 0, - 14379, - 0, - 14400, - 0, - 0, - 0, - 0, - 0, - 14401, - 0, - 0, - 14405, - 0, - 14406, - 0, - 14408, - 14409, - 0, - 0, - 0, - 14417, - 0, - 0, - 14424, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14430, - 0, - 0, - 0, - 14431, - 0, - 0, - 14435, - 0, - 14440, - 0, - 0, - 0, - 0, - 0, - 0, - 14442, - 0, - 0, - 14443, - 0, - 0, - 0, - 0, - 0, - 14446, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14454, - 0, - 14457, - 0, - 14460, - 0, - 0, - 14466, - 0, - 0, - 0, - 0, - 0, - 14467, - 0, - 0, - 0, - 0, - 0, - 0, - 14469, - 0, - 14477, - 0, - 0, - 0, - 0, - 0, - 0, - 14478, - 14482, - 0, - 0, - 0, - 14483, - 0, - 0, - 0, - 14485, - 14486, - 0, - 0, - 0, - 14487, - 14488, - 14489, - 14492, - 14493, - 14494, - 14495, - 14496, - 14497, - 0, - 14499, - 0, - 14501, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14502, - 0, - 14507, - 14512, - 14513, - 14514, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14515, - 14526, - 14530, - 0, - 14537, - 0, - 14544, - 0, - 14547, - 0, - 0, - 14548, - 14550, - 14551, - 0, - 0, - 14552, - 0, - 0, - 0, - 14553, - 0, - 14554, - 0, - 0, - 0, - 0, - 14556, - 14564, - 0, - 0, - 14565, - 14566, - 0, - 0, - 0, - 0, - 0, - 0, - 14568, - 0, - 0, - 14569, - 0, - 0, - 0, - 14571, - 14576, - 0, - 0, - 14577, - 14578, - 14579, - 0, - 0, - 14580, - 0, - 0, - 0, - 0, - 14582, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14583, - 0, - 0, - 0, - 0, - 0, - 14587, - 0, - 14588, - 0, - 0, - 14600, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14601, - 0, - 0, - 14604, - 14605, - 14611, - 0, - 14613, - 0, - 0, - 0, - 0, - 14615, - 0, - 0, - 0, - 0, - 0, - 0, - 14627, - 0, - 14628, - 0, - 0, - 0, - 0, - 14631, - 0, - 14633, - 14634, - 0, - 0, - 0, - 0, - 14635, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14636, - 0, - 0, - 14639, - 14642, - 0, - 0, - 0, - 0, - 14644, - 0, - 0, - 0, - 0, - 14645, - 14646, - 0, - 14653, - 0, - 0, - 14654, - 0, - 14658, - 0, - 14661, - 0, - 0, - 0, - 14665, - 0, - 0, - 0, - 14668, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14669, - 0, - 0, - 14670, - 0, - 0, - 0, - 14680, - 0, - 0, - 14681, - 0, - 0, - 0, - 0, - 0, - 14682, - 14683, - 0, - 0, - 0, - 0, - 14686, - 0, - 0, - 0, - 0, - 14687, - 14697, - 0, - 0, - 0, - 0, - 14699, - 14705, - 14711, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14712, - 0, - 0, - 0, - 14713, - 0, - 0, - 0, - 0, - 14719, - 0, - 14720, - 14721, - 14726, - 0, - 0, - 0, - 14728, - 14729, - 0, - 0, - 0, - 0, - 14731, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14733, - 14736, - 14737, - 0, - 0, - 14740, - 14742, - 0, - 0, - 0, - 14744, - 14753, - 0, - 0, - 0, - 0, - 14755, - 14758, - 14760, - 0, - 0, - 0, - 0, - 0, - 14761, - 14762, - 14765, - 14771, - 0, - 14772, - 0, - 14773, - 14774, - 0, - 0, - 14775, - 0, - 0, - 14776, - 0, - 0, - 0, - 0, - 14777, - 0, - 14779, - 0, - 0, - 14782, - 0, - 0, - 14785, - 14786, - 14788, - 0, - 0, - 0, - 0, - 0, - 14795, - 0, - 0, - 0, - 0, - 0, - 0, - 14798, - 0, - 14803, - 14804, - 14806, - 0, - 0, - 0, - 14809, - 0, - 0, - 0, - 0, - 0, - 0, - 14810, - 0, - 0, - 0, - 0, - 14811, - 0, - 14812, - 0, - 0, - 0, - 0, - 0, - 14815, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14816, - 0, - 14818, - 0, - 0, - 0, - 0, - 0, - 0, - 14819, - 0, - 14820, - 0, - 14823, - 0, - 0, - 0, - 14824, - 0, - 0, - 14826, - 14827, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14830, - 0, - 0, - 0, - 0, - 0, - 14833, - 0, - 14845, - 0, - 0, - 0, - 0, - 0, - 14846, - 0, - 0, - 14847, - 14871, - 0, - 14873, - 0, - 14876, - 0, - 14877, - 14878, - 14880, - 0, - 0, - 0, - 0, - 0, - 14881, - 0, - 14882, - 14894, - 0, - 0, - 0, - 0, - 14895, - 0, - 14907, - 0, - 14908, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14911, - 0, - 0, - 0, - 0, - 14920, - 0, - 0, - 14931, - 0, - 14932, - 14934, - 14935, - 0, - 0, - 14936, - 0, - 14945, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14947, - 0, - 0, - 14948, - 14949, - 14951, - 0, - 0, - 14952, - 0, - 0, - 0, - 14964, - 14973, - 0, - 0, - 14990, - 0, - 0, - 0, - 0, - 14995, - 0, - 0, - 14998, - 15001, - 0, - 0, - 15002, - 15020, - 0, - 0, - 0, - 0, - 0, - 0, - 15021, - 0, - 15022, - 0, - 0, - 0, - 0, - 15023, - 0, - 0, - 15025, - 15029, - 15033, - 0, - 0, - 0, - 15034, - 0, - 0, - 0, - 15035, - 0, - 0, - 0, - 0, - 0, - 15043, - 15044, - 0, - 0, - 0, - 15045, - 15046, - 15048, - 15050, - 0, - 15065, - 0, - 0, - 0, - 0, - 15066, - 0, - 0, - 15075, - 15082, - 15084, - 0, - 0, - 15085, - 15086, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15088, - 0, - 0, - 0, - 15089, - 0, - 0, - 0, - 0, - 15094, - 0, - 15096, - 0, - 15097, - 0, - 15100, - 0, - 0, - 15102, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15105, - 0, - 0, - 15106, - 0, - 15109, - 15113, - 0, - 0, - 0, - 15115, - 0, - 15118, - 0, - 0, - 0, - 0, - 0, - 0, - 15119, - 0, - 0, - 15120, - 0, - 0, - 0, - 0, - 0, - 15123, - 15129, - 0, - 0, - 0, - 15130, - 0, - 15131, - 0, - 0, - 15134, - 0, - 15135, - 0, - 0, - 0, - 15137, - 15138, - 0, - 0, - 0, - 0, - 0, - 0, - 15139, - 0, - 0, - 0, - 0, - 0, - 15140, - 0, - 0, - 15154, - 15162, - 0, - 15169, - 15170, - 0, - 15175, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15177, - 0, - 15178, - 15179, - 0, - 0, - 0, - 0, - 0, - 15183, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15185, - 15187, - 0, - 15194, - 15195, - 15196, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15204, - 0, - 0, - 0, - 0, - 15206, - 0, - 0, - 0, - 0, - 0, - 15207, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15213, - 0, - 15214, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15232, - 0, - 0, - 0, - 0, - 15234, - 0, - 15238, - 15240, - 0, - 15248, - 0, - 0, - 0, - 0, - 15250, - 15251, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15252, - 0, - 0, - 0, - 15255, - 15262, - 15266, - 0, - 0, - 0, - 15267, - 0, - 0, - 0, - 15277, - 15279, - 0, - 0, - 0, - 15280, - 15281, - 15282, - 0, - 0, - 0, - 0, - 0, - 15285, - 0, - 0, - 0, - 0, - 15289, - 0, - 0, - 15291, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15296, - 15297, - 0, - 0, - 15304, - 0, - 0, - 0, - 0, - 15306, - 0, - 0, - 0, - 0, - 0, - 0, - 15307, - 15308, - 0, - 15309, - 0, - 0, - 15311, - 0, - 0, - 15312, - 15313, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15314, - 15317, - 0, - 0, - 0, - 15318, - 15319, - 0, - 0, - 0, - 0, - 15320, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15321, - 0, - 0, - 0, - 0, - 0, - 15324, - 0, - 15325, - 15326, - 0, - 15330, - 0, - 0, - 0, - 0, - 15334, - 0, - 15335, - 0, - 15341, - 0, - 0, - 15342, - 0, - 0, - 15343, - 15344, - 0, - 0, - 0, - 0, - 15345, - 0, - 0, - 0, - 0, - 15347, - 0, - 0, - 15348, - 15349, - 15350, - 0, - 15356, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15357, - 0, - 15358, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15359, - 15360, - 15364, - 0, - 15380, - 0, - 0, - 0, - 0, - 0, - 15392, - 0, - 0, - 15393, - 0, - 15395, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15396, - 0, - 0, - 15397, - 15398, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15399, - 0, - 15400, - 0, - 0, - 0, - 15402, - 0, - 15405, - 15410, - 0, - 0, - 0, - 0, - 15411, - 0, - 0, - 0, - 15412, - 0, - 15416, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15428, - 0, - 15435, - 0, - 0, - 15438, - 0, - 0, - 0, - 0, - 15439, - 0, - 0, - 0, - 15440, - 0, - 0, - 0, - 15441, - 15449, - 15451, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15452, - 0, - 0, - 15455, - 0, - 0, - 0, - 15456, - 0, - 0, - 15458, - 0, - 15460, - 15461, - 0, - 0, - 0, - 0, - 0, - 15462, - 15464, - 0, - 15465, - 0, - 0, - 15466, - 0, - 0, - 15467, - 0, - 0, - 0, - 0, - 0, - 15468, - 0, - 0, - 0, - 0, - 15481, - 0, - 0, - 15484, - 0, - 15485, - 15486, - 0, - 0, - 0, - 15487, - 0, - 0, - 0, - 0, - 0, - 15488, - 0, - 15492, - 15498, - 0, - 0, - 0, - 15499, - 0, - 0, - 0, - 15500, - 0, - 15501, - 0, - 0, - 15512, - 0, - 15522, - 0, - 0, - 0, - 15524, - 0, - 15525, - 15526, - 0, - 0, - 15527, - 0, - 0, - 15545, - 15546, - 0, - 15548, - 15552, - 0, - 15553, - 0, - 0, - 0, - 15554, - 0, - 15555, - 0, - 15557, - 15565, - 15573, - 15577, - 15578, - 0, - 15582, - 0, - 15583, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15586, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15588, - 0, - 0, - 0, - 0, - 0, - 15589, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15593, - 15594, - 0, - 0, - 0, - 0, - 15595, - 0, - 0, - 0, - 0, - 0, - 0, - 15596, - 0, - 0, - 0, - 15597, - 0, - 0, - 0, - 0, - 15600, - 0, - 0, - 15601, - 0, - 0, - 0, - 0, - 15602, - 15603, - 0, - 0, - 0, - 0, - 0, - 0, - 15604, - 0, - 15609, - 0, - 0, - 15612, - 0, - 0, - 15613, - 0, - 0, - 15615, - 15617, - 15618, - 0, - 0, - 15620, - 0, - 15636, - 15637, - 0, - 0, - 15649, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15650, - 0, - 0, - 15651, - 0, - 0, - 0, - 15656, - 0, - 15658, - 0, - 0, - 0, - 15664, - 0, - 0, - 15665, - 0, - 0, - 15668, - 0, - 0, - 0, - 0, - 0, - 15669, - 0, - 0, - 15674, - 0, - 0, - 15675, - 0, - 0, - 0, - 0, - 15676, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15677, - 0, - 0, - 0, - 0, - 15678, - 0, - 0, - 0, - 0, - 0, - 15679, - 0, - 0, - 15681, - 0, - 15686, - 0, - 0, - 0, - 0, - 15687, - 0, - 15688, - 0, - 0, - 15690, - 0, - 0, - 0, - 15697, - 0, - 15699, - 15700, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15701, - 0, - 15702, - 15703, - 0, - 15704, - 0, - 15705, - 0, - 15707, - 0, - 15709, - 0, - 15712, - 15716, - 0, - 15717, - 0, - 15718, - 15720, - 0, - 0, - 0, - 0, - 0, - 15724, - 0, - 0, - 0, - 15725, - 0, - 15726, - 0, - 0, - 0, - 15740, - 0, - 15745, - 15746, - 0, - 0, - 15747, - 0, - 15748, - 0, - 0, - 0, - 0, - 0, - 15749, - 0, - 0, - 0, - 15752, - 0, - 15753, - 0, - 0, - 0, - 0, - 0, - 0, - 15759, - 0, - 0, - 0, - 15765, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15767, - 0, - 0, - 0, - 15771, - 0, - 0, - 15784, - 0, - 0, - 0, - 0, - 15785, - 15790, - 15791, - 0, - 0, - 15792, - 0, - 0, - 0, - 15807, - 0, - 15811, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15818, - 0, - 0, - 0, - 15819, - 0, - 0, - 0, - 0, - 15821, - 0, - 0, - 0, - 0, - 0, - 15822, - 15824, - 0, - 0, - 15827, - 0, - 0, - 15829, - 15831, - 0, - 15832, - 0, - 0, - 15833, - 0, - 15835, - 15838, - 15839, - 15843, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15844, - 0, - 0, - 0, - 0, - 15845, - 15851, - 15856, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15858, - 15860, - 0, - 15861, - 0, - 0, - 0, - 15864, - 0, - 0, - 0, - 0, - 15865, - 0, - 0, - 0, - 0, - 0, - 0, - 15866, - 0, - 15872, - 0, - 0, - 15876, - 0, - 0, - 0, - 0, - 15877, - 15878, - 15883, - 15885, - 0, - 0, - 15888, - 0, - 0, - 0, - 0, - 0, - 15889, - 15890, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15892, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15893, - 0, - 0, - 15894, - 0, - 0, - 0, - 15895, - 0, - 15896, - 15897, - 0, - 15898, - 15901, - 15902, - 0, - 15911, - 15915, - 0, - 15916, - 0, - 15924, - 15935, - 0, - 15937, - 0, - 0, - 0, - 0, - 0, - 15950, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15958, - 0, - 0, - 0, - 15961, - 0, - 0, - 15966, - 0, - 15967, - 0, - 0, - 15977, - 0, - 0, - 15978, - 0, - 0, - 15981, - 15982, - 15983, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 15986, - 0, - 0, - 0, - 15990, - 0, - 15991, - 15995, - 15998, - 0, - 15999, - 0, - 16000, - 0, - 0, - 0, - 0, - 16008, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16009, - 16011, - 0, - 16013, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16014, - 0, - 0, - 16015, - 16023, - 16024, - 16025, - 0, - 0, - 16026, - 0, - 16030, - 0, - 16032, - 0, - 16033, - 0, - 0, - 0, - 0, - 0, - 0, - 16035, - 16036, - 16037, - 0, - 0, - 0, - 0, - 0, - 16039, - 0, - 0, - 0, - 0, - 16041, - 0, - 0, - 0, - 0, - 0, - 16043, - 16044, - 0, - 0, - 16047, - 0, - 0, - 0, - 16048, - 0, - 0, - 16049, - 16050, - 16052, - 0, - 0, - 0, - 0, - 0, - 16055, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16056, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16058, - 16060, - 16061, - 0, - 0, - 16063, - 0, - 0, - 16064, - 0, - 0, - 0, - 16067, - 16068, - 0, - 0, - 16069, - 16078, - 0, - 0, - 0, - 16079, - 0, - 0, - 0, - 16080, - 0, - 16081, - 0, - 0, - 0, - 16088, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16089, - 16093, - 0, - 16097, - 0, - 16103, - 0, - 16104, - 16105, - 0, - 0, - 16256, - 0, - 0, - 16259, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16260, - 16261, - 0, - 0, - 16262, - 0, - 0, - 16263, - 0, - 16268, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16269, - 0, - 0, - 16270, - 16273, - 0, - 16274, - 0, - 0, - 0, - 0, - 16275, - 16276, - 16277, - 16280, - 0, - 0, - 0, - 16281, - 16284, - 0, - 0, - 0, - 16286, - 0, - 16289, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16290, - 0, - 0, - 0, - 0, - 16291, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16292, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16293, - 16295, - 16297, - 0, - 16302, - 0, - 16304, - 0, - 16305, - 0, - 16306, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16307, - 16308, - 16312, - 0, - 0, - 0, - 0, - 0, - 0, - 16313, - 16315, - 0, - 16318, - 0, - 0, - 0, - 16321, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16326, - 16333, - 16336, - 0, - 0, - 0, - 0, - 16337, - 16340, - 0, - 0, - 0, - 0, - 0, - 16345, - 0, - 0, - 16346, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16347, - 0, - 0, - 16348, - 0, - 0, - 0, - 0, - 16349, - 0, - 0, - 0, - 16350, - 0, - 16357, - 0, - 0, - 0, - 0, - 16359, - 16360, - 0, - 0, - 0, - 0, - 16362, - 16363, - 16364, - 16365, - 0, - 0, - 16366, - 0, - 0, - 0, - 0, - 16367, - 16368, - 0, - 16369, - 16374, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16376, - 0, - 0, - 0, - 0, - 16378, - 16379, - 0, - 16380, - 0, - 0, - 0, - 16381, - 16383, - 0, - 0, - 0, - 0, - 0, - 16390, - 0, - 0, - 0, - 16399, - 0, - 16402, - 16404, - 16406, - 16407, - 0, - 0, - 0, - 16409, - 16411, - 0, - 0, - 0, - 0, - 16412, - 0, - 16413, - 16415, - 16423, - 0, - 0, - 0, - 0, - 0, - 16424, - 0, - 0, - 0, - 16428, - 16434, - 16435, - 16449, - 0, - 16450, - 16451, - 0, - 0, - 0, - 16453, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16454, - 0, - 0, - 16456, - 16458, - 0, - 0, - 16459, - 0, - 0, - 16460, - 0, - 0, - 0, - 0, - 16462, - 0, - 16463, - 0, - 0, - 16466, - 0, - 0, - 0, - 0, - 0, - 16479, - 0, - 0, - 16480, - 0, - 16481, - 16484, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16485, - 0, - 0, - 0, - 0, - 0, - 0, - 16489, - 0, - 0, - 0, - 0, - 0, - 16491, - 0, - 0, - 16498, - 0, - 0, - 16503, - 0, - 16505, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16506, - 0, - 0, - 0, - 16508, - 16509, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16511, - 16513, - 0, - 0, - 0, - 16516, - 0, - 16517, - 0, - 16519, - 0, - 16529, - 0, - 0, - 16531, - 0, - 0, - 0, - 0, - 0, - 0, - 16534, - 0, - 0, - 16541, - 16542, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16543, - 16547, - 16548, - 0, - 0, - 0, - 16551, - 0, - 16552, - 0, - 0, - 0, - 16553, - 0, - 0, - 16558, - 0, - 0, - 16562, - 16565, - 0, - 0, - 0, - 16570, - 0, - 0, - 0, - 16573, - 16585, - 0, - 0, - 0, - 16586, - 16587, - 16595, - 0, - 16596, - 0, - 16598, - 0, - 0, - 0, - 16600, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16601, - 0, - 0, - 0, - 0, - 16603, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16604, - 16612, - 0, - 0, - 0, - 0, - 16613, - 0, - 16618, - 0, - 0, - 0, - 16640, - 0, - 0, - 16641, - 0, - 0, - 0, - 0, - 0, - 0, - 16645, - 0, - 0, - 0, - 0, - 16646, - 0, - 0, - 0, - 0, - 0, - 0, - 16651, - 0, - 0, - 0, - 0, - 16653, - 16654, - 0, - 0, - 0, - 16655, - 0, - 0, - 16656, - 16667, - 0, - 0, - 0, - 0, - 16671, - 0, - 16672, - 0, - 0, - 0, - 16673, - 0, - 0, - 0, - 0, - 0, - 16676, - 0, - 16686, - 0, - 0, - 0, - 0, - 16689, - 0, - 16690, - 0, - 16692, - 0, - 16693, - 0, - 16694, - 0, - 16696, - 0, - 0, - 0, - 16705, - 0, - 0, - 0, - 0, - 0, - 0, - 16707, - 0, - 0, - 0, - 16709, - 0, - 0, - 0, - 0, - 16711, - 0, - 16712, - 16713, - 0, - 0, - 0, - 16715, - 0, - 0, - 0, - 0, - 16716, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16718, - 16724, - 0, - 0, - 16726, - 16727, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16728, - 0, - 16729, - 0, - 0, - 16730, - 0, - 0, - 0, - 0, - 0, - 16731, - 0, - 0, - 0, - 16732, - 0, - 0, - 0, - 0, - 16734, - 16738, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16743, - 0, - 0, - 16745, - 0, - 0, - 0, - 0, - 0, - 16749, - 0, - 16752, - 0, - 0, - 0, - 0, - 16756, - 0, - 0, - 16758, - 0, - 16759, - 0, - 0, - 0, - 0, - 0, - 16760, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16762, - 0, - 16769, - 0, - 16770, - 0, - 16772, - 0, - 0, - 0, - 16777, - 16780, - 0, - 0, - 0, - 0, - 0, - 0, - 16781, - 0, - 0, - 16782, - 0, - 16784, - 0, - 0, - 16785, - 16787, - 16792, - 0, - 0, - 16794, - 0, - 0, - 0, - 16798, - 0, - 0, - 16809, - 0, - 0, - 16814, - 16816, - 16817, - 0, - 16819, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16820, - 0, - 0, - 16836, - 16839, - 0, - 0, - 16841, - 16851, - 16857, - 0, - 0, - 16858, - 16859, - 0, - 0, - 16860, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16862, - 0, - 16863, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16864, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16876, - 0, - 16881, - 16882, - 0, - 16885, - 16886, - 0, - 16887, - 0, - 0, - 0, - 16889, - 16891, - 0, - 0, - 0, - 0, - 0, - 16894, - 16895, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16897, - 0, - 16898, - 0, - 0, - 0, - 0, - 0, - 16913, - 0, - 0, - 16924, - 16925, - 16926, - 0, - 0, - 16927, - 0, - 0, - 0, - 16937, - 16938, - 0, - 0, - 0, - 16940, - 16941, - 0, - 0, - 0, - 16942, - 16945, - 0, - 16946, - 16949, - 16950, - 0, - 0, - 0, - 16952, - 16955, - 0, - 0, - 0, - 16965, - 0, - 16969, - 0, - 0, - 16975, - 0, - 0, - 16976, - 0, - 0, - 0, - 0, - 16978, - 0, - 0, - 16981, - 0, - 16983, - 16989, - 0, - 0, - 0, - 0, - 16990, - 0, - 0, - 16991, - 0, - 0, - 0, - 16993, - 0, - 16994, - 16996, - 17000, - 0, - 0, - 0, - 0, - 0, - 17002, - 17004, - 0, - 17006, - 0, - 0, - 17007, - 0, - 0, - 0, - 0, - 17008, - 17013, - 17014, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17021, - 0, - 17031, - 0, - 0, - 0, - 0, - 0, - 17033, - 17036, - 0, - 17038, - 0, - 0, - 17039, - 0, - 17045, - 0, - 0, - 17046, - 17047, - 0, - 0, - 0, - 0, - 17048, - 0, - 17049, - 17050, - 0, - 17051, - 17053, - 0, - 17054, - 0, - 17055, - 0, - 0, - 0, - 0, - 0, - 17063, - 0, - 0, - 17064, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17065, - 0, - 0, - 17068, - 0, - 0, - 0, - 0, - 0, - 17072, - 0, - 0, - 0, - 0, - 0, - 0, - 17073, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17074, - 0, - 17080, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17081, - 17083, - 17084, - 0, - 0, - 0, - 17085, - 0, - 0, - 0, - 0, - 17092, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17093, - 0, - 17095, - 17102, - 0, - 0, - 0, - 0, - 0, - 0, - 17103, - 0, - 0, - 17105, - 0, - 17107, - 0, - 0, - 0, - 0, - 17114, - 0, - 0, - 0, - 0, - 0, - 17115, - 17125, - 17127, - 0, - 0, - 17128, - 0, - 0, - 0, - 17129, - 17130, - 0, - 17131, - 0, - 0, - 0, - 0, - 0, - 17132, - 17135, - 17145, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17146, - 0, - 17147, - 0, - 17148, - 0, - 0, - 0, - 0, - 0, - 0, - 17149, - 17150, - 0, - 17151, - 17153, - 0, - 17155, - 0, - 0, - 0, - 0, - 17163, - 17171, - 0, - 17174, - 0, - 0, - 0, - 0, - 17179, - 0, - 0, - 17182, - 17185, - 0, - 0, - 0, - 0, - 0, - 17186, - 0, - 0, - 17188, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17189, - 17191, - 0, - 17194, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17195, - 17196, - 17203, - 17204, - 0, - 0, - 17205, - 17217, - 0, - 0, - 0, - 0, - 0, - 17218, - 0, - 0, - 0, - 0, - 17219, - 0, - 17220, - 0, - 17221, - 0, - 0, - 17230, - 0, - 0, - 0, - 0, - 0, - 17236, - 0, - 17238, - 17239, - 0, - 0, - 0, - 17241, - 17244, - 0, - 0, - 17245, - 0, - 17248, - 0, - 0, - 17251, - 0, - 17252, - 0, - 0, - 17264, - 0, - 17266, - 0, - 0, - 0, - 17268, - 0, - 0, - 0, - 0, - 17271, - 17272, - 0, - 17273, - 0, - 17295, - 0, - 17302, - 0, - 17305, - 0, - 0, - 0, - 17306, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17308, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17309, - 0, - 17310, - 17313, - 0, - 0, - 0, - 0, - 17314, - 17315, - 0, - 17317, - 0, - 0, - 0, - 0, - 17318, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17320, - 0, - 0, - 0, - 0, - 0, - 0, - 17334, - 0, - 17344, - 17348, - 0, - 0, - 0, - 17350, - 17351, - 0, - 0, - 17353, - 0, - 0, - 17354, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17355, - 0, - 0, - 0, - 0, - 0, - 0, - 17356, - 17357, - 0, - 0, - 17359, - 0, - 0, - 0, - 17371, - 0, - 17372, - 0, - 0, - 0, - 17393, - 0, - 0, - 0, - 0, - 17394, - 0, - 0, - 0, - 0, - 0, - 17395, - 0, - 0, - 17399, - 0, - 0, - 0, - 17401, - 17417, - 0, - 17418, - 0, - 17419, - 0, - 0, - 0, - 0, - 0, - 17422, - 17423, - 0, - 0, - 0, - 0, - 0, - 17424, - 0, - 0, - 0, - 0, - 0, - 17428, - 17429, - 17433, - 0, - 0, - 0, - 17437, - 0, - 0, - 17441, - 0, - 0, - 17442, - 0, - 0, - 17453, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17454, - 17456, - 17462, - 0, - 0, - 17466, - 0, - 0, - 17468, - 0, - 0, - 17469, - 0, - 0, - 0, - 0, - 17470, - 0, - 17475, - 0, - 0, - 0, - 0, - 0, - 17479, - 0, - 0, - 0, - 17483, - 17484, - 0, - 17485, - 0, - 17486, - 0, - 17491, - 17492, - 0, - 0, - 17493, - 0, - 17494, - 17495, - 0, - 0, - 0, - 17496, - 0, - 0, - 0, - 17497, - 0, - 0, - 0, - 17502, - 0, - 0, - 0, - 0, - 0, - 17503, - 0, - 17505, - 0, - 17507, - 0, - 0, - 0, - 17512, - 17513, - 17514, - 0, - 0, - 17515, - 0, - 0, - 0, - 17519, - 0, - 0, - 0, - 17522, - 0, - 0, - 17523, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17527, - 0, - 0, - 0, - 17528, - 0, - 0, - 0, - 17534, - 0, - 0, - 0, - 0, - 17536, - 0, - 0, - 0, - 17539, - 0, - 17540, - 17543, - 17549, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17556, - 0, - 0, - 17558, - 0, - 17559, - 0, - 0, - 17560, - 0, - 0, - 0, - 17563, - 0, - 0, - 0, - 0, - 0, - 0, - 17564, - 0, - 0, - 17565, - 17566, - 0, - 17567, - 0, - 0, - 0, - 0, - 0, - 0, - 17569, - 17570, - 0, - 17575, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17581, - 0, - 0, - 0, - 17582, - 17583, - 0, - 17586, - 0, - 0, - 17587, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17588, - 0, - 0, - 0, - 0, - 17596, - 17597, - 0, - 0, - 17598, - 17600, - 0, - 0, - 0, - 0, - 0, - 0, - 17601, - 0, - 0, - 0, - 17604, - 0, - 0, - 17605, - 0, - 0, - 17607, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17612, - 0, - 0, - 17618, - 0, - 17621, - 17622, - 0, - 0, - 0, - 0, - 17623, - 0, - 0, - 17624, - 0, - 0, - 17630, - 0, - 0, - 17631, - 17633, - 17634, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17635, - 0, - 0, - 17636, - 0, - 0, - 17637, - 0, - 17638, - 0, - 17640, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17641, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17643, - 0, - 0, - 0, - 0, - 17645, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17646, - 17662, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17663, - 17664, - 0, - 17665, - 17666, - 0, - 0, - 0, - 17669, - 17671, - 17673, - 0, - 17679, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17684, - 0, - 0, - 0, - 17686, - 0, - 17714, - 0, - 0, - 17720, - 17722, - 17726, - 0, - 0, - 17728, - 0, - 0, - 17729, - 0, - 0, - 0, - 17732, - 0, - 17733, - 0, - 17734, - 0, - 0, - 0, - 17735, - 0, - 0, - 0, - 0, - 17737, - 0, - 0, - 0, - 0, - 17739, - 0, - 0, - 0, - 17741, - 17742, - 0, - 0, - 0, - 0, - 17743, - 17744, - 17745, - 0, - 0, - 0, - 17749, - 0, - 17750, - 17751, - 17752, - 17754, - 17761, - 17762, - 0, - 17763, - 0, - 17766, - 0, - 17772, - 0, - 0, - 0, - 0, - 0, - 17775, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17776, - 0, - 0, - 17777, - 0, - 0, - 17778, - 17779, - 0, - 17782, - 17783, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17784, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17821, - 0, - 0, - 0, - 17822, - 0, - 0, - 0, - 17823, - 17825, - 0, - 0, - 0, - 0, - 0, - 17826, - 17831, - 17832, - 17833, - 0, - 0, - 17845, - 0, - 0, - 0, - 17846, - 0, - 0, - 0, - 17848, - 17850, - 17854, - 0, - 17855, - 0, - 0, - 17859, - 0, - 0, - 0, - 0, - 0, - 0, - 17860, - 17861, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 17870, - 17871, - 0, - 0, - 0, - 0, - 0, - 0, - 17872, - 0, - 0, - 0, - 17879, - 0, - 0, - 0, - 17881, - 17883, - 0, - 17884, - 0, - 17885, - 0, - 0, - 17886, - 0, - 0, - 17887, - 17891, - 17953, - 0, - 0, - 0, - 0, - 17954, - 0, - 0, - 17955, - 0, - 17968, - 0, - 0, - 17972, - 0, - 0, - 0, - 0, - 0, - 17974, - 0, - 0, - 0, - 0, - 17976, - 17978, - 0, - 0, - 17983, - 0, - 0, - 0, - 0, - 18003, - 0, - 0, - 0, - 0, - 0, - 18007, - 0, - 0, - 0, - 0, - 0, - 18009, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18010, - 0, - 0, - 0, - 0, - 0, - 0, - 18012, - 0, - 0, - 18014, - 0, - 0, - 0, - 18015, - 0, - 0, - 0, - 18016, - 0, - 18017, - 0, - 0, - 0, - 18030, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18031, - 0, - 0, - 18036, - 18037, - 18038, - 0, - 0, - 18049, - 18056, - 0, - 18057, - 18058, - 0, - 18059, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18062, - 0, - 0, - 0, - 0, - 18064, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18067, - 0, - 0, - 0, - 18068, - 0, - 0, - 18075, - 0, - 0, - 18078, - 18093, - 18094, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18097, - 0, - 0, - 0, - 0, - 0, - 18098, - 18100, - 0, - 0, - 0, - 18108, - 0, - 18111, - 0, - 0, - 18112, - 0, - 18113, - 0, - 0, - 18115, - 18116, - 0, - 18118, - 0, - 0, - 0, - 0, - 18121, - 0, - 0, - 0, - 0, - 18123, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18124, - 0, - 0, - 0, - 0, - 18125, - 18126, - 0, - 18127, - 0, - 0, - 18128, - 18135, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18150, - 0, - 0, - 0, - 0, - 0, - 18151, - 18152, - 0, - 0, - 18156, - 18164, - 0, - 18166, - 18171, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18172, - 18183, - 0, - 18184, - 0, - 0, - 0, - 0, - 18185, - 0, - 18187, - 0, - 0, - 0, - 0, - 0, - 18188, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18189, - 0, - 0, - 18190, - 0, - 0, - 18191, - 18192, - 0, - 0, - 18194, - 18195, - 18196, - 0, - 0, - 0, - 18197, - 0, - 18203, - 0, - 18204, - 0, - 0, - 0, - 0, - 18205, - 0, - 0, - 0, - 18207, - 18208, - 0, - 0, - 18214, - 0, - 0, - 0, - 18215, - 18216, - 0, - 0, - 0, - 18220, - 0, - 0, - 18222, - 0, - 0, - 0, - 0, - 0, - 18223, - 0, - 18225, - 18231, - 0, - 18234, - 0, - 18235, - 0, - 0, - 0, - 0, - 18240, - 0, - 0, - 18241, - 18242, - 0, - 0, - 0, - 0, - 0, - 18243, - 18251, - 0, - 18253, - 0, - 18254, - 0, - 0, - 0, - 18266, - 0, - 0, - 0, - 0, - 0, - 0, - 18269, - 18270, - 18271, - 18273, - 18281, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18282, - 0, - 18283, - 0, - 18284, - 0, - 0, - 0, - 0, - 0, - 0, - 18285, - 0, - 18287, - 18289, - 0, - 0, - 18290, - 0, - 0, - 0, - 0, - 18308, - 0, - 0, - 0, - 18310, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18311, - 0, - 18312, - 18313, - 0, - 18315, - 0, - 0, - 18316, - 18320, - 0, - 18331, - 0, - 18332, - 0, - 18336, - 0, - 0, - 0, - 0, - 18337, - 0, - 18340, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18341, - 0, - 18344, - 18345, - 0, - 18346, - 0, - 0, - 0, - 0, - 0, - 18348, - 0, - 18351, - 0, - 0, - 18356, - 0, - 0, - 0, - 0, - 0, - 0, - 18357, - 0, - 0, - 0, - 0, - 0, - 18367, - 0, - 0, - 0, - 18368, - 0, - 18369, - 0, - 18370, - 18371, - 0, - 0, - 0, - 18437, - 18444, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18445, - 18450, - 0, - 0, - 0, - 0, - 18451, - 0, - 18452, - 0, - 0, - 0, - 18453, - 0, - 0, - 0, - 0, - 0, - 18455, - 0, - 0, - 0, - 18456, - 0, - 18457, - 0, - 18460, - 0, - 0, - 18461, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18466, - 0, - 0, - 18467, - 0, - 0, - 0, - 0, - 18473, - 0, - 0, - 0, - 18476, - 0, - 18477, - 0, - 0, - 0, - 18478, - 18479, - 18480, - 0, - 0, - 0, - 18485, - 0, - 0, - 0, - 18486, - 0, - 0, - 0, - 0, - 0, - 0, - 18488, - 18490, - 0, - 0, - 0, - 0, - 0, - 0, - 18491, - 0, - 0, - 0, - 0, - 0, - 18495, - 0, - 0, - 18496, - 0, - 0, - 0, - 0, - 0, - 0, - 18505, - 0, - 18521, - 0, - 18522, - 18523, - 0, - 0, - 0, - 18525, - 18526, - 0, - 0, - 0, - 0, - 0, - 18527, - 0, - 0, - 0, - 0, - 18532, - 18533, - 0, - 18534, - 0, - 0, - 0, - 0, - 0, - 0, - 18535, - 18537, - 0, - 18538, - 0, - 0, - 0, - 0, - 0, - 0, - 18540, - 18541, - 18542, - 18543, - 0, - 18546, - 0, - 0, - 0, - 0, - 18553, - 18556, - 0, - 0, - 18558, - 0, - 0, - 18569, - 18571, - 0, - 0, - 0, - 18572, - 0, - 18574, - 0, - 0, - 0, - 0, - 18586, - 0, - 0, - 0, - 0, - 0, - 18588, - 0, - 0, - 18589, - 0, - 0, - 0, - 0, - 0, - 0, - 18590, - 0, - 18592, - 0, - 0, - 0, - 0, - 18594, - 0, - 0, - 0, - 18596, - 0, - 0, - 18597, - 18598, - 0, - 0, - 18601, - 0, - 0, - 0, - 0, - 18602, - 0, - 0, - 0, - 18603, - 18604, - 0, - 18605, - 0, - 0, - 0, - 0, - 18608, - 0, - 0, - 18611, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18612, - 0, - 18616, - 0, - 0, - 18617, - 18619, - 0, - 0, - 0, - 18628, - 0, - 0, - 0, - 18629, - 0, - 0, - 18630, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18631, - 0, - 18632, - 0, - 0, - 18635, - 18637, - 0, - 0, - 0, - 0, - 0, - 0, - 18641, - 18643, - 18648, - 0, - 18652, - 0, - 0, - 18653, - 0, - 18655, - 18656, - 0, - 0, - 0, - 18657, - 0, - 0, - 18666, - 18674, - 0, - 0, - 0, - 0, - 18677, - 18684, - 18685, - 0, - 0, - 18686, - 0, - 0, - 18690, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18695, - 18696, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18697, - 0, - 0, - 18700, - 0, - 0, - 0, - 0, - 0, - 0, - 18702, - 0, - 18708, - 0, - 0, - 18709, - 0, - 18710, - 0, - 0, - 18711, - 0, - 18714, - 0, - 0, - 18718, - 0, - 0, - 0, - 0, - 0, - 0, - 18719, - 0, - 0, - 18722, - 0, - 18726, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18731, - 0, - 0, - 0, - 0, - 0, - 18739, - 18741, - 0, - 0, - 18742, - 0, - 18743, - 18744, - 18746, - 18748, - 0, - 18752, - 18753, - 0, - 0, - 18754, - 18763, - 0, - 18765, - 0, - 0, - 0, - 18766, - 0, - 0, - 0, - 18769, - 0, - 0, - 0, - 0, - 0, - 18773, - 18778, - 18779, - 18781, - 0, - 0, - 18784, - 18787, - 0, - 18788, - 0, - 18793, - 0, - 0, - 0, - 0, - 0, - 0, - 18795, - 0, - 0, - 18800, - 0, - 0, - 0, - 0, - 0, - 18801, - 18804, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18806, - 0, - 0, - 0, - 18811, - 18815, - 18816, - 0, - 0, - 0, - 0, - 18825, - 0, - 0, - 18827, - 18829, - 0, - 0, - 18830, - 0, - 0, - 0, - 0, - 18831, - 0, - 0, - 18832, - 0, - 0, - 0, - 0, - 18833, - 0, - 18840, - 0, - 18841, - 0, - 18842, - 0, - 0, - 0, - 0, - 18843, - 0, - 18844, - 0, - 0, - 0, - 0, - 0, - 0, - 18845, - 18846, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18848, - 0, - 0, - 0, - 18853, - 18860, - 0, - 0, - 18862, - 18866, - 0, - 0, - 18867, - 18869, - 0, - 0, - 18874, - 18881, - 18891, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18892, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18895, - 0, - 18896, - 0, - 0, - 0, - 18900, - 0, - 0, - 0, - 18901, - 0, - 18902, - 18915, - 18916, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18919, - 0, - 0, - 0, - 0, - 0, - 18920, - 0, - 0, - 0, - 18921, - 18929, - 0, - 0, - 0, - 0, - 18930, - 0, - 0, - 0, - 0, - 0, - 0, - 18932, - 0, - 0, - 0, - 0, - 18934, - 18942, - 0, - 0, - 0, - 18951, - 18957, - 0, - 0, - 0, - 0, - 18958, - 0, - 0, - 0, - 0, - 18959, - 18960, - 0, - 0, - 18961, - 0, - 0, - 18962, - 0, - 0, - 0, - 0, - 18963, - 18964, - 0, - 0, - 0, - 18965, - 0, - 18967, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18968, - 0, - 18969, - 0, - 18970, - 18973, - 18976, - 0, - 0, - 0, - 0, - 0, - 0, - 18977, - 0, - 0, - 0, - 18981, - 0, - 0, - 0, - 18990, - 0, - 18998, - 0, - 0, - 0, - 0, - 0, - 18999, - 19003, - 0, - 0, - 19005, - 0, - 0, - 0, - 19006, - 0, - 0, - 0, - 0, - 0, - 0, - 19008, - 19011, - 0, - 0, - 19018, - 0, - 0, - 19019, - 0, - 19024, - 0, - 19031, - 19032, - 0, - 19039, - 0, - 19041, - 19050, - 0, - 0, - 0, - 19051, - 19055, - 19056, - 0, - 19059, - 19063, - 19064, - 0, - 0, - 19088, - 0, - 0, - 0, - 19093, - 19094, - 0, - 0, - 0, - 0, - 19095, - 0, - 19096, - 0, - 0, - 0, - 19097, - 0, - 0, - 19098, - 0, - 19099, - 19100, - 0, - 0, - 19103, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19111, - 0, - 0, - 0, - 0, - 0, - 0, - 19112, - 0, - 0, - 0, - 19116, - 19117, - 0, - 19121, - 19122, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19123, - 19124, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19125, - 19126, - 0, - 19128, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19129, - 19130, - 19131, - 19132, - 0, - 0, - 19146, - 0, - 0, - 19147, - 19156, - 19158, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19182, - 19185, - 0, - 0, - 19187, - 0, - 0, - 0, - 19193, - 0, - 0, - 0, - 0, - 0, - 19194, - 0, - 19197, - 0, - 0, - 0, - 0, - 19198, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19202, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19203, - 0, - 19205, - 19210, - 0, - 0, - 0, - 19213, - 0, - 19218, - 0, - 0, - 0, - 19223, - 19229, - 0, - 0, - 19230, - 0, - 0, - 19231, - 19232, - 19233, - 19239, - 0, - 0, - 0, - 0, - 0, - 19240, - 0, - 19248, - 19249, - 0, - 0, - 0, - 0, - 19254, - 0, - 19256, - 19258, - 19259, - 0, - 0, - 19261, - 0, - 19266, - 0, - 0, - 0, - 19272, - 0, - 19278, - 19281, - 19282, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19283, - 0, - 0, - 19284, - 0, - 0, - 19285, - 19287, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19288, - 19291, - 0, - 19292, - 0, - 0, - 0, - 0, - 19297, - 0, - 19298, - 0, - 0, - 0, - 0, - 19302, - 19303, - 0, - 0, - 0, - 0, - 19304, - 19305, - 0, - 0, - 0, - 0, - 19314, - 0, - 0, - 19315, - 0, - 0, - 19321, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19322, - 0, - 19333, - 0, - 19334, - 19335, - 0, - 19336, - 19337, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19346, - 0, - 0, - 19353, - 0, - 19354, - 19362, - 0, - 19366, - 19367, - 0, - 0, - 19369, - 0, - 19375, - 0, - 19377, - 19380, - 19388, - 0, - 0, - 0, - 0, - 0, - 19389, - 19390, - 0, - 0, - 0, - 0, - 19392, - 0, - 0, - 0, - 0, - 0, - 19402, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19412, - 0, - 0, - 19413, - 19422, - 0, - 19424, - 0, - 0, - 0, - 19425, - 0, - 0, - 0, - 19428, - 0, - 0, - 0, - 0, - 19431, - 0, - 0, - 0, - 0, - 0, - 19432, - 0, - 0, - 0, - 0, - 0, - 19448, - 19459, - 0, - 0, - 19461, - 0, - 19462, - 19463, - 0, - 19467, - 19474, - 19482, - 0, - 0, - 0, - 0, - 19494, - 0, - 0, - 0, - 0, - 19501, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19502, - 19504, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19505, - 0, - 0, - 0, - 0, - 19506, - 19507, - 0, - 0, - 0, - 19508, - 0, - 0, - 19511, - 0, - 0, - 19514, - 0, - 19515, - 0, - 19516, - 0, - 19518, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19530, - 0, - 19537, - 19538, - 0, - 19543, - 19546, - 0, - 19547, - 19551, - 0, - 0, - 0, - 0, - 0, - 0, - 19552, - 19553, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19555, - 0, - 0, - 19556, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19560, - 19561, - 0, - 0, - 19562, - 0, - 0, - 0, - 0, - 0, - 0, - 19565, - 19567, - 0, - 19568, - 0, - 0, - 0, - 19569, - 19570, - 0, - 19578, - 0, - 0, - 0, - 0, - 19580, - 0, - 0, - 0, - 0, - 19581, - 19584, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19585, - 19586, - 0, - 0, - 0, - 19587, - 19588, - 0, - 19589, - 0, - 0, - 0, - 0, - 0, - 0, - 19592, - 19593, - 19599, - 0, - 19600, - 0, - 0, - 19604, - 0, - 0, - 19605, - 0, - 19606, - 19608, - 19610, - 0, - 19613, - 19614, - 0, - 0, - 0, - 0, - 0, - 0, - 19616, - 19617, - 0, - 0, - 19618, - 0, - 0, - 19619, - 0, - 0, - 0, - 19620, - 19621, - 19631, - 0, - 0, - 19632, - 19634, - 19636, - 0, - 19643, - 0, - 0, - 19644, - 19658, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19659, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19675, - 19677, - 0, - 0, - 0, - 0, - 19679, - 0, - 19683, - 0, - 19684, - 0, - 0, - 0, - 0, - 0, - 0, - 19687, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19688, - 19689, - 19692, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19695, - 19697, - 0, - 0, - 0, - 0, - 0, - 19698, - 19699, - 0, - 0, - 19700, - 0, - 19702, - 0, - 0, - 19703, - 0, - 0, - 0, - 0, - 0, - 0, - 19704, - 19708, - 0, - 19710, - 0, - 19713, - 0, - 0, - 0, - 19715, - 0, - 0, - 0, - 0, - 19718, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19720, - 0, - 19722, - 0, - 0, - 19725, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19730, - 0, - 0, - 0, - 0, - 0, - 19731, - 0, - 19734, - 19735, - 19739, - 0, - 0, - 19740, - 0, - 19741, - 0, - 0, - 0, - 19746, - 0, - 0, - 19747, - 0, - 19771, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19772, - 19775, - 0, - 0, - 0, - 0, - 0, - 0, - 19778, - 0, - 0, - 0, - 0, - 0, - 19779, - 0, - 0, - 19780, - 19790, - 0, - 19791, - 0, - 0, - 19792, - 0, - 0, - 0, - 19793, - 0, - 0, - 19796, - 19797, - 0, - 0, - 0, - 19799, - 0, - 0, - 0, - 19801, - 0, - 0, - 0, - 0, - 19803, - 0, - 19804, - 0, - 19805, - 0, - 0, - 19807, - 0, - 0, - 0, - 19808, - 0, - 0, - 0, - 0, - 0, - 0, - 19809, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19816, - 0, - 19821, - 0, - 19822, - 19830, - 19831, - 0, - 0, - 0, - 19833, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19838, - 0, - 0, - 0, - 0, - 19839, - 0, - 0, - 19843, - 0, - 0, - 0, - 0, - 19845, - 0, - 0, - 0, - 0, - 19847, - 0, - 0, - 19848, - 0, - 19849, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19851, - 0, - 0, - 0, - 19854, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19864, - 0, - 19865, - 0, - 19866, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19868, - 0, - 0, - 19870, - 0, - 0, - 19871, - 0, - 0, - 19872, - 19873, - 19875, - 0, - 19880, - 19882, - 19884, - 0, - 0, - 19885, - 19886, - 19888, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19890, - 19892, - 19893, - 0, - 0, - 19894, - 0, - 0, - 0, - 19895, - 0, - 19896, - 19902, - 0, - 0, - 19903, - 0, - 0, - 19905, - 0, - 0, - 0, - 19906, - 0, - 19908, - 0, - 19909, - 19911, - 0, - 0, - 0, - 19913, - 19920, - 0, - 19938, - 19939, - 19940, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 19942, - 0, - 19943, - 0, - 19945, - 0, - 0, - 0, - 19951, - 19952, - 19954, - 19960, - 0, - 19965, - 0, - 19971, - 0, - 0, - 0, - 0, - 0, - 19975, - 0, - 19976, - 0, - 19990, - 0, - 0, - 19991, - 0, - 19993, - 0, - 19995, - 0, - 0, - 0, - 19998, - 19999, - 20001, - 0, - 20003, - 20005, - 0, - 20011, - 20012, - 0, - 0, - 0, - 0, - 0, - 0, - 20014, - 0, - 20020, - 0, - 0, - 0, - 0, - 20021, - 0, - 0, - 0, - 0, - 0, - 20023, - 20024, - 0, - 0, - 0, - 0, - 0, - 20025, - 0, - 0, - 20027, - 0, - 0, - 20029, - 0, - 0, - 20032, - 0, - 0, - 0, - 0, - 20044, - 20045, - 0, - 20048, - 20049, - 0, - 0, - 20050, - 0, - 20052, - 0, - 0, - 20054, - 20057, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20059, - 0, - 0, - 20061, - 0, - 20062, - 0, - 20064, - 0, - 0, - 20066, - 0, - 0, - 20067, - 0, - 0, - 0, - 0, - 20069, - 0, - 0, - 0, - 0, - 0, - 0, - 20070, - 20071, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20072, - 0, - 0, - 20073, - 20074, - 0, - 0, - 0, - 0, - 0, - 20075, - 0, - 20078, - 0, - 0, - 0, - 0, - 20080, - 0, - 20081, - 0, - 0, - 0, - 0, - 0, - 0, - 20095, - 0, - 20098, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20107, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20112, - 0, - 0, - 0, - 20113, - 20114, - 0, - 0, - 0, - 20115, - 20123, - 20124, - 0, - 0, - 0, - 20131, - 20133, - 20134, - 0, - 0, - 0, - 0, - 20136, - 0, - 0, - 20137, - 20138, - 20150, - 0, - 20152, - 0, - 0, - 0, - 20153, - 0, - 0, - 20154, - 0, - 0, - 0, - 20158, - 0, - 20163, - 0, - 0, - 20164, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20166, - 0, - 20168, - 0, - 20170, - 0, - 20175, - 0, - 0, - 20178, - 0, - 0, - 0, - 0, - 20223, - 0, - 0, - 0, - 0, - 20224, - 0, - 20226, - 0, - 0, - 20230, - 0, - 20231, - 0, - 0, - 0, - 0, - 20232, - 0, - 0, - 20233, - 20234, - 0, - 20244, - 0, - 20247, - 0, - 0, - 0, - 0, - 0, - 0, - 20249, - 0, - 0, - 0, - 20250, - 0, - 0, - 0, - 0, - 20251, - 0, - 20253, - 0, - 20254, - 0, - 0, - 0, - 0, - 20256, - 0, - 0, - 20264, - 0, - 0, - 0, - 0, - 20266, - 0, - 0, - 0, - 20278, - 0, - 0, - 20279, - 20282, - 0, - 0, - 0, - 0, - 0, - 20283, - 0, - 20284, - 0, - 20285, - 0, - 20287, - 20290, - 0, - 0, - 0, - 0, - 20292, - 0, - 0, - 0, - 0, - 20293, - 20297, - 0, - 0, - 0, - 0, - 0, - 0, - 20299, - 0, - 20300, - 20303, - 0, - 0, - 0, - 0, - 0, - 0, - 20307, - 0, - 0, - 20308, - 0, - 20309, - 0, - 20310, - 0, - 0, - 0, - 0, - 0, - 0, - 20312, - 0, - 0, - 0, - 20314, - 0, - 0, - 0, - 0, - 20315, - 20316, - 0, - 20322, - 0, - 0, - 0, - 0, - 0, - 0, - 20339, - 0, - 0, - 0, - 20342, - 0, - 0, - 0, - 0, - 20352, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20362, - 0, - 0, - 20365, - 0, - 20375, - 20377, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20378, - 20379, - 0, - 20380, - 0, - 0, - 20381, - 0, - 20382, - 0, - 20383, - 0, - 20388, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20390, - 20392, - 20393, - 0, - 0, - 20395, - 0, - 0, - 0, - 0, - 0, - 20396, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20398, - 20415, - 0, - 0, - 0, - 20417, - 0, - 0, - 20420, - 0, - 0, - 20426, - 20428, - 0, - 20431, - 0, - 0, - 20432, - 0, - 20433, - 20434, - 20435, - 0, - 0, - 0, - 0, - 20440, - 0, - 0, - 0, - 0, - 0, - 20442, - 0, - 20443, - 0, - 20446, - 0, - 0, - 0, - 0, - 20448, - 0, - 20451, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20452, - 20453, - 0, - 0, - 20454, - 0, - 0, - 0, - 0, - 0, - 0, - 20457, - 0, - 20458, - 0, - 0, - 0, - 20465, - 0, - 0, - 0, - 0, - 0, - 20469, - 0, - 0, - 0, - 20473, - 0, - 20476, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20477, - 0, - 0, - 20485, - 0, - 0, - 20486, - 0, - 0, - 20487, - 0, - 20496, - 0, - 20497, - 0, - 0, - 20498, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20499, - 20500, - 0, - 20501, - 0, - 0, - 0, - 0, - 0, - 20520, - 20527, - 0, - 20529, - 0, - 0, - 0, - 0, - 20539, - 0, - 0, - 20540, - 0, - 0, - 0, - 20543, - 0, - 0, - 0, - 20546, - 0, - 0, - 0, - 0, - 0, - 20548, - 0, - 0, - 20563, - 0, - 0, - 20564, - 0, - 20566, - 0, - 0, - 0, - 0, - 0, - 20589, - 0, - 0, - 0, - 0, - 20590, - 0, - 0, - 20593, - 20594, - 0, - 0, - 0, - 0, - 20595, - 0, - 20597, - 20598, - 0, - 0, - 0, - 20618, - 20620, - 0, - 0, - 0, - 0, - 20621, - 0, - 0, - 0, - 0, - 20627, - 0, - 0, - 0, - 0, - 0, - 20628, - 0, - 0, - 0, - 20629, - 0, - 20630, - 0, - 0, - 20639, - 0, - 0, - 0, - 0, - 0, - 20707, - 0, - 0, - 20709, - 0, - 0, - 0, - 20713, - 20714, - 0, - 0, - 0, - 0, - 0, - 20724, - 20725, - 0, - 0, - 0, - 0, - 20726, - 20728, - 20729, - 0, - 20733, - 0, - 20734, - 0, - 20735, - 20736, - 0, - 20737, - 0, - 0, - 20744, - 0, - 20745, - 0, - 20748, - 0, - 0, - 20749, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20750, - 0, - 0, - 0, - 0, - 20754, - 0, - 0, - 0, - 20761, - 0, - 0, - 20763, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20766, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20767, - 0, - 0, - 0, - 0, - 20768, - 0, - 20769, - 20777, - 0, - 0, - 0, - 0, - 0, - 0, - 20785, - 0, - 0, - 0, - 20786, - 20795, - 20801, - 0, - 20802, - 0, - 20807, - 0, - 0, - 20808, - 0, - 0, - 20810, - 0, - 0, - 20811, - 0, - 20812, - 0, - 0, - 0, - 0, - 0, - 20813, - 0, - 0, - 20818, - 20820, - 20821, - 0, - 0, - 0, - 20822, - 0, - 20823, - 0, - 0, - 0, - 20826, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20829, - 20830, - 20831, - 0, - 20832, - 20836, - 0, - 0, - 20839, - 0, - 0, - 20840, - 20842, - 0, - 20843, - 0, - 20844, - 0, - 20854, - 0, - 0, - 0, - 20855, - 0, - 0, - 0, - 0, - 20856, - 0, - 0, - 0, - 20869, - 0, - 0, - 20871, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20873, - 0, - 0, - 0, - 0, - 0, - 20876, - 0, - 0, - 0, - 0, - 0, - 20880, - 0, - 0, - 20882, - 0, - 0, - 0, - 0, - 20883, - 20884, - 0, - 0, - 20890, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 20891, - 0, - 0, - 0, - 0, - 0, - 20905, - 0, - 20906, - 20910, - 0, - 0, - 20912, - 20915, - 0, - 0, - 0, - 0, - 0, - 20916, - 0, - 20917, - 0, - 20919, - 20920, - 20922, - 0, - 20927, - 0, - 20928, - 20929, - 20930, - 0, - 0, - 20935, - 0, - 0, - 20939, - 0, - 0, - 20941, - 0, - 0, - 0, - 20943, - 0, - 0, - 0, - 20946, - 20947, - 0, - 0, - 0, - 0, - 0, - 20950, - 0, - 20954, - 0, - 0, - 20955, - 20964, - 0, - 0, - 20967, - 0, - 0, - 0, - 0, - 0, - 20973, - 20975, - 0, - 0, - 0, - 20984, - 0, - 20987, - 20988, - 0, - 0, - 0, - 0, - 0, - 20989, - 0, - 0, - 0, - 20995, - 0, - 20998, - 0, - 20999, - 0, - 0, - 0, - 0, - 21000, - 21001, - 0, - 0, - 0, - 0, - 21008, - 0, - 21010, - 0, - 21016, - 0, - 0, - 0, - 21017, - 21018, - 0, - 0, - 0, - 0, - 0, - 21021, - 21026, - 21027, - 21028, - 0, - 0, - 21029, - 0, - 0, - 0, - 0, - 0, - 21030, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21031, - 21032, - 0, - 0, - 0, - 0, - 0, - 21037, - 0, - 0, - 21038, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21039, - 0, - 21041, - 0, - 21046, - 21047, - 0, - 0, - 0, - 21049, - 21053, - 0, - 0, - 21057, - 21064, - 21065, - 0, - 0, - 21066, - 21067, - 0, - 0, - 0, - 21069, - 0, - 0, - 0, - 21071, - 21072, - 0, - 0, - 21073, - 0, - 21074, - 0, - 0, - 21078, - 0, - 0, - 0, - 0, - 21079, - 0, - 0, - 21080, - 21081, - 0, - 0, - 21086, - 21087, - 0, - 21089, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21091, - 0, - 21093, - 0, - 21094, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21095, - 0, - 0, - 0, - 0, - 0, - 21096, - 0, - 21098, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21099, - 0, - 0, - 21100, - 21101, - 21102, - 0, - 0, - 0, - 0, - 0, - 21103, - 0, - 21104, - 0, - 0, - 0, - 0, - 0, - 21105, - 21108, - 21109, - 0, - 0, - 21112, - 21113, - 0, - 0, - 0, - 0, - 0, - 0, - 21115, - 21122, - 21123, - 0, - 0, - 0, - 0, - 0, - 21125, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21129, - 21131, - 0, - 0, - 21134, - 0, - 0, - 0, - 21137, - 21142, - 0, - 21143, - 0, - 0, - 21144, - 0, - 21145, - 21146, - 0, - 21152, - 21154, - 21155, - 21156, - 0, - 0, - 0, - 21160, - 0, - 0, - 0, - 0, - 0, - 0, - 21161, - 0, - 21164, - 0, - 21166, - 0, - 0, - 0, - 0, - 21170, - 0, - 0, - 0, - 0, - 21171, - 0, - 0, - 21172, - 0, - 21174, - 0, - 21175, - 0, - 0, - 0, - 0, - 0, - 21176, - 21179, - 21188, - 0, - 0, - 0, - 21189, - 0, - 0, - 21190, - 0, - 0, - 0, - 21192, - 0, - 0, - 21193, - 0, - 0, - 0, - 21198, - 0, - 21212, - 0, - 0, - 21213, - 0, - 0, - 0, - 0, - 0, - 0, - 21215, - 21216, - 0, - 0, - 21223, - 21225, - 0, - 21226, - 0, - 0, - 0, - 0, - 21227, - 21228, - 0, - 0, - 21229, - 0, - 0, - 0, - 0, - 21230, - 21236, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21237, - 0, - 0, - 21238, - 21239, - 0, - 0, - 0, - 0, - 21256, - 0, - 0, - 0, - 0, - 0, - 21257, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21259, - 0, - 0, - 0, - 21263, - 0, - 21272, - 0, - 21274, - 0, - 21282, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21283, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21294, - 0, - 0, - 21297, - 0, - 0, - 0, - 0, - 21298, - 0, - 0, - 0, - 21299, - 0, - 21300, - 21302, - 0, - 21316, - 0, - 21318, - 21322, - 21323, - 0, - 21324, - 0, - 21326, - 0, - 0, - 0, - 21327, - 21328, - 0, - 0, - 0, - 21352, - 0, - 0, - 21354, - 21361, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21362, - 0, - 0, - 0, - 21363, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21366, - 0, - 0, - 21367, - 21372, - 21374, - 0, - 0, - 0, - 21375, - 21377, - 0, - 21378, - 0, - 0, - 0, - 21380, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21381, - 0, - 0, - 0, - 0, - 0, - 0, - 21382, - 0, - 21383, - 0, - 0, - 21384, - 0, - 0, - 21385, - 0, - 0, - 0, - 0, - 21389, - 21390, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21397, - 21398, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21399, - 0, - 21400, - 0, - 0, - 0, - 0, - 21402, - 0, - 0, - 0, - 21403, - 21404, - 0, - 21405, - 21406, - 0, - 0, - 0, - 21407, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21408, - 0, - 0, - 0, - 0, - 21409, - 0, - 21421, - 0, - 21422, - 0, - 0, - 0, - 21425, - 21428, - 0, - 0, - 0, - 0, - 21429, - 0, - 0, - 0, - 0, - 0, - 21433, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21434, - 0, - 21443, - 0, - 21444, - 21449, - 0, - 21452, - 0, - 21453, - 21454, - 0, - 0, - 0, - 21457, - 0, - 0, - 21458, - 0, - 0, - 0, - 21460, - 21461, - 0, - 0, - 21464, - 0, - 0, - 0, - 21473, - 21478, - 0, - 0, - 21479, - 0, - 0, - 21481, - 21483, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21484, - 0, - 0, - 21485, - 21486, - 0, - 0, - 21488, - 0, - 0, - 0, - 0, - 0, - 0, - 21523, - 0, - 0, - 21525, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21526, - 0, - 0, - 0, - 0, - 0, - 0, - 21529, - 21530, - 0, - 0, - 21531, - 0, - 0, - 21533, - 0, - 0, - 21539, - 21564, - 0, - 21567, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21575, - 0, - 0, - 0, - 0, - 21577, - 0, - 0, - 0, - 0, - 0, - 21591, - 0, - 0, - 21604, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21605, - 0, - 21606, - 0, - 0, - 21617, - 21618, - 21619, - 21620, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21623, - 0, - 0, - 0, - 0, - 21631, - 0, - 21635, - 0, - 0, - 0, - 0, - 21639, - 21646, - 21653, - 21662, - 0, - 0, - 21663, - 21664, - 0, - 21666, - 0, - 0, - 21667, - 0, - 21670, - 21672, - 21673, - 0, - 21674, - 21683, - 0, - 0, - 0, - 0, - 0, - 21684, - 0, - 21694, - 0, - 0, - 0, - 0, - 21695, - 21700, - 0, - 21703, - 0, - 21704, - 0, - 0, - 21709, - 0, - 0, - 0, - 21710, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21711, - 0, - 0, - 0, - 21712, - 0, - 21717, - 0, - 21730, - 0, - 0, - 0, - 21731, - 21733, - 0, - 0, - 0, - 0, - 21737, - 21741, - 21742, - 0, - 21747, - 0, - 0, - 0, - 21749, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21750, - 0, - 0, - 0, - 0, - 0, - 21752, - 0, - 0, - 0, - 0, - 21753, - 0, - 0, - 0, - 0, - 0, - 0, - 21755, - 21756, - 0, - 21757, - 0, - 0, - 0, - 0, - 0, - 0, - 21760, - 0, - 0, - 21763, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21764, - 0, - 0, - 21766, - 0, - 0, - 21767, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21773, - 0, - 21774, - 0, - 0, - 21775, - 0, - 0, - 0, - 0, - 21776, - 0, - 0, - 21777, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21780, - 21787, - 21788, - 21791, - 0, - 0, - 0, - 21797, - 0, - 0, - 0, - 0, - 0, - 21805, - 0, - 0, - 0, - 0, - 21806, - 0, - 21807, - 21809, - 0, - 21810, - 21811, - 0, - 21817, - 21819, - 21820, - 0, - 21823, - 0, - 21824, - 0, - 0, - 21825, - 0, - 0, - 21826, - 21832, - 0, - 0, - 0, - 0, - 0, - 21833, - 21848, - 21849, - 0, - 0, - 21867, - 21870, - 21871, - 21873, - 0, - 0, - 0, - 21874, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21875, - 0, - 21878, - 0, - 0, - 0, - 21879, - 0, - 21881, - 21886, - 0, - 0, - 0, - 0, - 21887, - 0, - 0, - 21888, - 21894, - 21895, - 21897, - 0, - 21901, - 0, - 21904, - 0, - 0, - 21906, - 0, - 0, - 0, - 21909, - 21910, - 21911, - 0, - 0, - 21912, - 0, - 0, - 21913, - 21914, - 21915, - 0, - 21919, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21921, - 0, - 0, - 21922, - 21933, - 21939, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21944, - 0, - 0, - 0, - 0, - 0, - 21945, - 0, - 21947, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21949, - 0, - 0, - 0, - 21950, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21951, - 0, - 21952, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21954, - 21957, - 0, - 0, - 0, - 0, - 21958, - 0, - 21959, - 0, - 0, - 0, - 0, - 0, - 0, - 21962, - 21963, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 21964, - 21965, - 0, - 0, - 21969, - 21970, - 0, - 0, - 0, - 21974, - 0, - 0, - 21980, - 21981, - 0, - 21982, - 0, - 0, - 0, - 0, - 0, - 21985, - 0, - 21988, - 0, - 21992, - 0, - 21999, - 0, - 0, - 0, - 0, - 0, - 0, - 22001, - 0, - 22002, - 0, - 0, - 0, - 0, - 0, - 0, - 22003, - 0, - 0, - 0, - 0, - 0, - 22004, - 0, - 0, - 0, - 22008, - 0, - 22009, - 22015, - 0, - 0, - 22016, - 0, - 0, - 0, - 22017, - 22019, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22020, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22021, - 22037, - 0, - 22039, - 0, - 0, - 0, - 22040, - 0, - 0, - 0, - 22048, - 22049, - 0, - 0, - 22053, - 22055, - 22056, - 22059, - 0, - 0, - 22060, - 22061, - 0, - 0, - 22064, - 0, - 0, - 0, - 0, - 22066, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22073, - 0, - 0, - 0, - 22074, - 22075, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22076, - 0, - 0, - 0, - 0, - 22077, - 22084, - 22099, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22104, - 0, - 0, - 22107, - 0, - 22108, - 0, - 22109, - 0, - 22110, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22111, - 22119, - 0, - 22120, - 22122, - 0, - 0, - 0, - 0, - 22125, - 0, - 0, - 0, - 22128, - 22129, - 0, - 0, - 0, - 0, - 0, - 0, - 22141, - 0, - 0, - 0, - 22142, - 0, - 0, - 22144, - 22146, - 0, - 22148, - 22149, - 22151, - 22154, - 0, - 0, - 0, - 22162, - 0, - 0, - 0, - 0, - 22164, - 22177, - 0, - 0, - 0, - 0, - 22179, - 0, - 22182, - 22183, - 0, - 0, - 22184, - 22188, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22190, - 0, - 22194, - 22201, - 0, - 0, - 22208, - 0, - 22209, - 0, - 22212, - 0, - 0, - 22215, - 0, - 22223, - 22231, - 0, - 0, - 22232, - 0, - 22234, - 0, - 0, - 22235, - 22236, - 0, - 22237, - 0, - 22240, - 0, - 0, - 0, - 0, - 0, - 22241, - 0, - 0, - 0, - 22242, - 22246, - 22247, - 0, - 0, - 0, - 22259, - 22268, - 0, - 22269, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22270, - 0, - 0, - 0, - 0, - 22271, - 0, - 22272, - 0, - 22277, - 0, - 0, - 0, - 0, - 0, - 22278, - 22280, - 22283, - 22286, - 0, - 0, - 22287, - 22289, - 0, - 0, - 22290, - 0, - 22293, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22295, - 0, - 22301, - 22302, - 0, - 0, - 0, - 22305, - 0, - 22308, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22315, - 0, - 0, - 0, - 22317, - 0, - 22334, - 0, - 0, - 0, - 22335, - 0, - 0, - 0, - 0, - 0, - 22336, - 0, - 22338, - 22344, - 0, - 22347, - 22349, - 0, - 22350, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22357, - 0, - 0, - 0, - 0, - 0, - 22358, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22359, - 22360, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22361, - 22366, - 0, - 0, - 22369, - 0, - 22370, - 22373, - 0, - 0, - 0, - 0, - 0, - 22375, - 0, - 22377, - 0, - 0, - 0, - 0, - 0, - 22378, - 0, - 0, - 0, - 0, - 22381, - 0, - 0, - 0, - 0, - 22382, - 0, - 22383, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22391, - 0, - 0, - 22392, - 22395, - 22396, - 22402, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22405, - 0, - 0, - 22406, - 0, - 0, - 22408, - 0, - 0, - 22409, - 22410, - 0, - 0, - 0, - 0, - 0, - 0, - 22424, - 0, - 0, - 0, - 0, - 22426, - 0, - 0, - 0, - 22427, - 0, - 22428, - 0, - 22432, - 0, - 22435, - 22442, - 22443, - 0, - 0, - 0, - 0, - 22444, - 0, - 0, - 0, - 0, - 0, - 22446, - 0, - 22454, - 0, - 22455, - 0, - 0, - 0, - 22465, - 0, - 22470, - 0, - 22471, - 0, - 0, - 0, - 0, - 22472, - 22473, - 0, - 22487, - 0, - 0, - 0, - 22488, - 0, - 0, - 0, - 0, - 22489, - 0, - 0, - 22499, - 0, - 0, - 0, - 0, - 0, - 0, - 22514, - 0, - 0, - 22515, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22516, - 0, - 0, - 0, - 22517, - 22520, - 0, - 0, - 0, - 22534, - 0, - 0, - 22535, - 0, - 0, - 22536, - 0, - 22540, - 22553, - 0, - 22555, - 0, - 0, - 0, - 0, - 22561, - 0, - 0, - 22562, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22566, - 0, - 0, - 0, - 0, - 22567, - 22568, - 0, - 0, - 22575, - 0, - 22579, - 0, - 22582, - 22583, - 22585, - 0, - 0, - 0, - 0, - 0, - 22586, - 0, - 0, - 22587, - 0, - 0, - 22590, - 0, - 0, - 0, - 0, - 0, - 22591, - 0, - 22592, - 0, - 0, - 0, - 0, - 0, - 22593, - 0, - 22602, - 0, - 0, - 22604, - 0, - 0, - 22609, - 0, - 0, - 22618, - 0, - 0, - 0, - 0, - 0, - 0, - 22619, - 0, - 22624, - 22625, - 0, - 0, - 22638, - 0, - 0, - 0, - 0, - 0, - 22639, - 0, - 0, - 22640, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22644, - 0, - 22645, - 22647, - 0, - 0, - 0, - 0, - 22652, - 22653, - 0, - 0, - 0, - 22654, - 0, - 22655, - 0, - 0, - 0, - 22656, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22673, - 22675, - 22676, - 0, - 0, - 22678, - 22679, - 0, - 22691, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22693, - 0, - 0, - 22696, - 0, - 22699, - 22707, - 22708, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22718, - 0, - 22719, - 0, - 0, - 0, - 0, - 22723, - 0, - 0, - 0, - 22724, - 22725, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22726, - 22728, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22729, - 0, - 0, - 22731, - 0, - 0, - 0, - 0, - 22732, - 22735, - 22736, - 0, - 0, - 0, - 0, - 22739, - 0, - 22749, - 0, - 0, - 22751, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22758, - 0, - 0, - 0, - 0, - 0, - 22760, - 0, - 0, - 0, - 0, - 0, - 22764, - 22765, - 22766, - 0, - 22768, - 0, - 0, - 0, - 0, - 0, - 22769, - 22770, - 0, - 0, - 0, - 0, - 0, - 0, - 22771, - 0, - 0, - 22772, - 22775, - 0, - 22776, - 22777, - 22780, - 0, - 0, - 22782, - 22784, - 0, - 22787, - 0, - 22789, - 22796, - 0, - 0, - 0, - 0, - 0, - 22798, - 0, - 0, - 0, - 0, - 0, - 0, - 22802, - 0, - 22803, - 22804, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22805, - 0, - 0, - 22810, - 22811, - 22814, - 22816, - 0, - 22825, - 22826, - 0, - 22831, - 22833, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22834, - 0, - 22836, - 22838, - 0, - 22839, - 0, - 0, - 0, - 0, - 0, - 22840, - 0, - 22847, - 0, - 0, - 0, - 0, - 0, - 22856, - 22857, - 0, - 22858, - 22859, - 0, - 0, - 22862, - 0, - 0, - 22864, - 0, - 0, - 0, - 0, - 22865, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22866, - 0, - 22867, - 22868, - 0, - 0, - 0, - 0, - 22869, - 0, - 22871, - 0, - 22872, - 0, - 22873, - 22881, - 22882, - 22884, - 22885, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22886, - 22887, - 0, - 22894, - 0, - 22895, - 0, - 0, - 0, - 22900, - 0, - 22901, - 0, - 0, - 0, - 0, - 22904, - 0, - 0, - 0, - 0, - 22905, - 22907, - 0, - 0, - 0, - 22915, - 22917, - 0, - 0, - 22918, - 0, - 0, - 0, - 22920, - 0, - 0, - 0, - 22929, - 22930, - 0, - 0, - 0, - 22941, - 22942, - 0, - 0, - 0, - 22943, - 0, - 0, - 0, - 22944, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22946, - 0, - 22947, - 0, - 0, - 22954, - 0, - 22956, - 0, - 0, - 22962, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22963, - 0, - 0, - 22964, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 22965, - 0, - 22968, - 0, - 0, - 0, - 22969, - 0, - 0, - 0, - 0, - 0, - 22970, - 0, - 22971, - 0, - 0, - 0, - 0, - 0, - 22978, - 0, - 0, - 22979, - 0, - 22987, - 0, - 0, - 22989, - 0, - 0, - 0, - 0, - 0, - 0, - 22990, - 0, - 23005, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23006, - 23007, - 23008, - 0, - 0, - 23023, - 23024, - 23029, - 0, - 0, - 0, - 0, - 23030, - 0, - 0, - 0, - 0, - 0, - 23032, - 0, - 0, - 0, - 0, - 0, - 23035, - 0, - 0, - 0, - 0, - 23038, - 0, - 0, - 0, - 23048, - 0, - 23049, - 23052, - 23053, - 23060, - 23061, - 0, - 23063, - 0, - 0, - 0, - 0, - 23067, - 23068, - 0, - 0, - 0, - 23069, - 23073, - 0, - 0, - 0, - 23127, - 0, - 23128, - 0, - 0, - 0, - 0, - 0, - 23129, - 0, - 23138, - 23141, - 0, - 23149, - 0, - 0, - 23150, - 0, - 0, - 0, - 23152, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23154, - 0, - 0, - 0, - 0, - 23157, - 23159, - 23160, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23180, - 0, - 0, - 0, - 0, - 23181, - 0, - 0, - 23188, - 0, - 23189, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23195, - 0, - 0, - 23196, - 23199, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23202, - 0, - 23204, - 0, - 23207, - 0, - 23209, - 23210, - 0, - 0, - 0, - 0, - 0, - 0, - 23227, - 23229, - 0, - 0, - 23230, - 23234, - 23238, - 0, - 0, - 0, - 23245, - 23246, - 23248, - 0, - 0, - 0, - 0, - 23249, - 23254, - 0, - 0, - 0, - 23265, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23268, - 0, - 23276, - 0, - 0, - 0, - 0, - 23277, - 0, - 23297, - 0, - 23298, - 0, - 0, - 0, - 0, - 23299, - 0, - 23302, - 0, - 0, - 23303, - 23312, - 0, - 0, - 23314, - 0, - 23320, - 0, - 0, - 0, - 0, - 23324, - 0, - 23325, - 0, - 23328, - 0, - 23334, - 0, - 0, - 0, - 23337, - 0, - 0, - 0, - 0, - 23343, - 23344, - 23346, - 0, - 23348, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23353, - 0, - 0, - 0, - 0, - 23355, - 0, - 23356, - 23358, - 0, - 0, - 0, - 23359, - 23360, - 0, - 23361, - 0, - 23367, - 0, - 23369, - 0, - 0, - 23373, - 0, - 23378, - 23379, - 0, - 23382, - 23383, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23387, - 0, - 0, - 0, - 0, - 0, - 0, - 23388, - 23390, - 0, - 0, - 23393, - 23398, - 0, - 0, - 0, - 23399, - 0, - 0, - 0, - 23400, - 0, - 0, - 0, - 0, - 23401, - 0, - 0, - 0, - 23415, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23416, - 0, - 23422, - 0, - 23443, - 23444, - 0, - 0, - 0, - 0, - 23448, - 0, - 23454, - 0, - 0, - 0, - 0, - 0, - 0, - 23456, - 0, - 0, - 23458, - 23464, - 0, - 0, - 0, - 0, - 0, - 0, - 23465, - 0, - 0, - 0, - 23470, - 23471, - 0, - 0, - 23472, - 0, - 0, - 0, - 23473, - 23496, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23497, - 0, - 23499, - 0, - 0, - 23502, - 0, - 0, - 23503, - 0, - 0, - 23513, - 0, - 0, - 23515, - 0, - 0, - 0, - 23517, - 0, - 0, - 0, - 0, - 23518, - 23519, - 23521, - 23524, - 0, - 23525, - 23528, - 23539, - 0, - 0, - 0, - 0, - 0, - 23541, - 0, - 0, - 23544, - 0, - 0, - 23556, - 0, - 0, - 23557, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23559, - 0, - 23560, - 0, - 0, - 23561, - 0, - 0, - 23566, - 0, - 0, - 0, - 0, - 0, - 23568, - 23569, - 23570, - 0, - 0, - 0, - 0, - 23571, - 0, - 23574, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23575, - 0, - 23579, - 0, - 0, - 23581, - 0, - 0, - 0, - 0, - 0, - 0, - 23587, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23596, - 23598, - 0, - 0, - 0, - 0, - 23602, - 23606, - 0, - 0, - 23607, - 0, - 23608, - 0, - 0, - 0, - 23614, - 23616, - 0, - 0, - 0, - 0, - 0, - 23618, - 0, - 0, - 23619, - 0, - 0, - 0, - 0, - 23621, - 23626, - 0, - 23627, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23629, - 0, - 23630, - 0, - 0, - 0, - 0, - 23634, - 0, - 23636, - 0, - 0, - 0, - 0, - 0, - 0, - 23638, - 0, - 0, - 0, - 0, - 23640, - 23667, - 0, - 23669, - 0, - 0, - 0, - 23681, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23682, - 0, - 23683, - 0, - 0, - 0, - 0, - 0, - 23684, - 0, - 0, - 0, - 23685, - 23689, - 0, - 23693, - 23694, - 23700, - 0, - 23702, - 0, - 23709, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23712, - 0, - 0, - 0, - 0, - 0, - 23714, - 0, - 0, - 23715, - 0, - 0, - 0, - 0, - 23718, - 0, - 0, - 23720, - 0, - 0, - 0, - 0, - 23722, - 0, - 0, - 0, - 23726, - 23729, - 0, - 23741, - 23746, - 0, - 23748, - 0, - 0, - 0, - 0, - 23749, - 0, - 0, - 0, - 0, - 0, - 23750, - 0, - 0, - 0, - 0, - 23751, - 0, - 23753, - 0, - 0, - 0, - 0, - 23757, - 23765, - 0, - 0, - 0, - 23770, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23771, - 0, - 23772, - 23781, - 0, - 0, - 23796, - 0, - 0, - 0, - 0, - 23798, - 0, - 23799, - 0, - 0, - 0, - 23802, - 0, - 0, - 23806, - 0, - 23807, - 0, - 0, - 23808, - 0, - 23809, - 0, - 23819, - 0, - 0, - 0, - 23821, - 0, - 23827, - 0, - 0, - 0, - 23829, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23830, - 0, - 0, - 0, - 0, - 0, - 0, - 23832, - 23833, - 23834, - 23835, - 0, - 0, - 0, - 0, - 23837, - 23838, - 0, - 0, - 0, - 0, - 0, - 23846, - 0, - 0, - 0, - 0, - 0, - 0, - 23847, - 0, - 0, - 0, - 0, - 0, - 23879, - 23881, - 0, - 0, - 23882, - 23883, - 23895, - 0, - 23899, - 0, - 0, - 0, - 0, - 23901, - 0, - 0, - 0, - 0, - 0, - 0, - 23902, - 0, - 0, - 0, - 0, - 0, - 23903, - 23905, - 0, - 23906, - 0, - 23907, - 23918, - 23919, - 23920, - 0, - 23922, - 0, - 23924, - 0, - 23927, - 0, - 23934, - 0, - 23937, - 23941, - 0, - 23942, - 23946, - 0, - 0, - 0, - 0, - 0, - 23955, - 23956, - 23958, - 0, - 0, - 0, - 0, - 0, - 0, - 23959, - 0, - 23962, - 23965, - 0, - 23966, - 0, - 0, - 0, - 0, - 23967, - 23968, - 0, - 0, - 23973, - 0, - 0, - 23974, - 0, - 0, - 0, - 0, - 23975, - 0, - 23976, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23977, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23980, - 0, - 0, - 23984, - 0, - 23985, - 0, - 0, - 23987, - 0, - 0, - 23988, - 23990, - 23991, - 0, - 0, - 0, - 0, - 0, - 0, - 23992, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23994, - 0, - 0, - 0, - 23998, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 23999, - 0, - 0, - 24003, - 0, - 24004, - 0, - 24006, - 0, - 0, - 0, - 24007, - 0, - 0, - 24008, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24009, - 0, - 0, - 24010, - 0, - 0, - 24011, - 0, - 0, - 24013, - 24014, - 0, - 0, - 24015, - 24016, - 24027, - 0, - 24028, - 24029, - 0, - 24030, - 0, - 0, - 0, - 0, - 0, - 24033, - 24034, - 0, - 24035, - 0, - 0, - 24036, - 0, - 0, - 24044, - 0, - 24048, - 24049, - 24063, - 24067, - 0, - 24068, - 24070, - 0, - 0, - 24071, - 24078, - 24087, - 0, - 24090, - 0, - 0, - 0, - 24095, - 0, - 24098, - 24101, - 24104, - 24106, - 0, - 24107, - 0, - 0, - 0, - 24108, - 0, - 0, - 0, - 0, - 24110, - 24111, - 0, - 24113, - 0, - 0, - 24115, - 24120, - 0, - 0, - 0, - 0, - 0, - 0, - 24124, - 0, - 24125, - 0, - 24126, - 0, - 24127, - 0, - 0, - 0, - 0, - 0, - 24135, - 0, - 0, - 24136, - 0, - 24137, - 24142, - 0, - 0, - 0, - 24146, - 0, - 0, - 24147, - 24149, - 24154, - 0, - 24163, - 0, - 0, - 0, - 24165, - 24166, - 24167, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24169, - 24170, - 24175, - 0, - 0, - 0, - 24178, - 0, - 0, - 24179, - 0, - 0, - 24181, - 0, - 24184, - 24197, - 0, - 24201, - 24204, - 0, - 0, - 0, - 0, - 0, - 0, - 24206, - 24212, - 24220, - 0, - 0, - 0, - 24224, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24226, - 0, - 24234, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24235, - 0, - 24236, - 0, - 0, - 0, - 0, - 0, - 24239, - 24240, - 24241, - 0, - 0, - 24248, - 0, - 0, - 24249, - 0, - 24251, - 0, - 0, - 0, - 0, - 0, - 0, - 24253, - 0, - 24268, - 0, - 0, - 0, - 24269, - 0, - 24271, - 24272, - 0, - 0, - 0, - 0, - 24273, - 0, - 0, - 24274, - 0, - 0, - 24279, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24280, - 0, - 24293, - 24294, - 0, - 0, - 0, - 0, - 0, - 0, - 24296, - 0, - 0, - 24323, - 0, - 0, - 0, - 24329, - 24330, - 24331, - 24339, - 0, - 24351, - 0, - 0, - 24369, - 24370, - 0, - 0, - 0, - 24371, - 0, - 0, - 0, - 0, - 24372, - 24373, - 24374, - 0, - 0, - 0, - 0, - 0, - 24378, - 0, - 0, - 0, - 0, - 24379, - 0, - 24381, - 0, - 24383, - 24389, - 0, - 24390, - 0, - 0, - 24394, - 24395, - 24400, - 0, - 0, - 0, - 24401, - 24402, - 0, - 24406, - 0, - 0, - 0, - 24411, - 0, - 0, - 0, - 24415, - 0, - 24416, - 0, - 0, - 0, - 0, - 0, - 24417, - 0, - 24419, - 0, - 24422, - 0, - 24423, - 24428, - 0, - 24435, - 0, - 0, - 0, - 24439, - 0, - 0, - 0, - 24440, - 24442, - 24446, - 0, - 0, - 0, - 24447, - 24448, - 24449, - 24452, - 0, - 0, - 0, - 0, - 24453, - 24457, - 0, - 0, - 24458, - 24459, - 24460, - 0, - 24465, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24470, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24471, - 0, - 24473, - 24474, - 24475, - 24476, - 0, - 24478, - 0, - 0, - 0, - 0, - 24480, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24481, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24482, - 24485, - 0, - 0, - 0, - 0, - 24486, - 0, - 0, - 0, - 24488, - 0, - 0, - 0, - 24494, - 0, - 0, - 0, - 0, - 24497, - 0, - 0, - 24498, - 0, - 0, - 0, - 24499, - 24506, - 0, - 0, - 0, - 24507, - 0, - 0, - 24511, - 0, - 0, - 24513, - 24514, - 0, - 0, - 0, - 0, - 0, - 24517, - 0, - 24518, - 0, - 24520, - 0, - 24521, - 24524, - 24525, - 0, - 0, - 0, - 0, - 0, - 24527, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24528, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24537, - 24539, - 0, - 24540, - 0, - 0, - 0, - 24548, - 0, - 0, - 0, - 0, - 0, - 24549, - 24550, - 0, - 0, - 0, - 24553, - 24554, - 0, - 24555, - 0, - 24556, - 0, - 24558, - 0, - 0, - 0, - 0, - 0, - 24560, - 0, - 0, - 0, - 24561, - 0, - 0, - 0, - 0, - 0, - 24562, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24567, - 0, - 0, - 0, - 0, - 0, - 24569, - 0, - 0, - 0, - 24574, - 0, - 24575, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24577, - 24581, - 0, - 24584, - 0, - 0, - 0, - 0, - 0, - 24585, - 0, - 0, - 0, - 0, - 0, - 24586, - 0, - 0, - 24587, - 0, - 24588, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24590, - 24591, - 0, - 0, - 0, - 0, - 24592, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24594, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24596, - 24597, - 0, - 0, - 0, - 0, - 24602, - 24603, - 0, - 0, - 0, - 0, - 24604, - 0, - 0, - 24605, - 0, - 24610, - 0, - 0, - 24611, - 0, - 0, - 0, - 0, - 24612, - 24615, - 24616, - 24624, - 0, - 0, - 0, - 24627, - 0, - 24638, - 24639, - 0, - 0, - 0, - 0, - 24640, - 0, - 0, - 0, - 24655, - 24656, - 24657, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24662, - 0, - 24663, - 24664, - 0, - 0, - 0, - 0, - 0, - 24665, - 0, - 0, - 0, - 0, - 24667, - 0, - 0, - 0, - 0, - 0, - 0, - 24668, - 24669, - 0, - 24670, - 24674, - 0, - 0, - 0, - 24675, - 0, - 24678, - 0, - 0, - 24679, - 0, - 0, - 0, - 24681, - 0, - 24683, - 0, - 0, - 0, - 0, - 24684, - 0, - 24685, - 0, - 0, - 24686, - 0, - 0, - 24688, - 24689, - 0, - 0, - 0, - 0, - 24690, - 24691, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24697, - 0, - 24698, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24709, - 0, - 0, - 0, - 0, - 0, - 24710, - 0, - 24712, - 0, - 0, - 0, - 0, - 0, - 0, - 24713, - 24714, - 0, - 24715, - 0, - 24716, - 24718, - 0, - 24719, - 0, - 0, - 0, - 0, - 24720, - 0, - 0, - 24725, - 0, - 0, - 24738, - 0, - 24749, - 24750, - 0, - 0, - 0, - 24752, - 0, - 0, - 0, - 24753, - 0, - 0, - 0, - 24758, - 0, - 0, - 0, - 0, - 0, - 24762, - 0, - 24763, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24764, - 0, - 0, - 0, - 0, - 0, - 24765, - 24767, - 24768, - 0, - 24772, - 0, - 0, - 0, - 0, - 24773, - 0, - 0, - 0, - 0, - 24777, - 0, - 0, - 0, - 0, - 0, - 24785, - 0, - 24786, - 24788, - 0, - 0, - 0, - 24789, - 0, - 0, - 0, - 0, - 24794, - 24798, - 0, - 24799, - 24800, - 0, - 0, - 0, - 24803, - 0, - 24804, - 24806, - 0, - 24807, - 0, - 0, - 0, - 24810, - 0, - 0, - 0, - 0, - 0, - 0, - 24827, - 24828, - 0, - 24835, - 0, - 0, - 0, - 0, - 0, - 0, - 24836, - 0, - 0, - 0, - 0, - 0, - 24839, - 0, - 24843, - 24844, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24847, - 0, - 0, - 24848, - 0, - 0, - 0, - 0, - 0, - 0, - 24849, - 0, - 24850, - 24851, - 0, - 0, - 0, - 24852, - 0, - 24853, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24854, - 0, - 24855, - 0, - 0, - 24868, - 0, - 0, - 0, - 24883, - 0, - 0, - 0, - 24884, - 0, - 24895, - 24897, - 0, - 0, - 0, - 0, - 0, - 24899, - 0, - 0, - 0, - 0, - 0, - 24900, - 0, - 24913, - 0, - 0, - 0, - 0, - 0, - 0, - 24914, - 0, - 0, - 24917, - 24930, - 24931, - 0, - 0, - 0, - 24932, - 0, - 0, - 24939, - 0, - 0, - 24942, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24945, - 24950, - 0, - 24951, - 0, - 0, - 24953, - 0, - 0, - 0, - 24954, - 0, - 24959, - 0, - 0, - 0, - 24961, - 0, - 0, - 24962, - 0, - 24964, - 24968, - 24970, - 24972, - 0, - 0, - 0, - 0, - 0, - 24976, - 0, - 0, - 0, - 24977, - 0, - 24982, - 0, - 0, - 24983, - 0, - 0, - 24984, - 0, - 0, - 0, - 24993, - 0, - 0, - 0, - 24994, - 0, - 0, - 25001, - 0, - 0, - 0, - 25003, - 0, - 0, - 25018, - 0, - 0, - 25023, - 0, - 0, - 0, - 25034, - 0, - 0, - 25035, - 25036, - 0, - 25037, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25039, - 0, - 0, - 0, - 0, - 0, - 25040, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25042, - 0, - 0, - 25043, - 25045, - 0, - 0, - 0, - 0, - 0, - 0, - 25049, - 0, - 0, - 25051, - 0, - 25052, - 25053, - 0, - 0, - 25054, - 0, - 0, - 0, - 25055, - 0, - 0, - 0, - 0, - 25057, - 25059, - 0, - 0, - 25060, - 25064, - 0, - 25065, - 25069, - 25070, - 0, - 0, - 0, - 0, - 25072, - 0, - 25073, - 0, - 25090, - 0, - 0, - 25092, - 25093, - 25101, - 0, - 0, - 0, - 0, - 0, - 0, - 25105, - 25108, - 0, - 0, - 25113, - 0, - 0, - 25115, - 25116, - 0, - 0, - 0, - 0, - 0, - 0, - 25117, - 0, - 0, - 0, - 25120, - 25121, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25125, - 0, - 0, - 0, - 25126, - 0, - 25130, - 25134, - 0, - 25139, - 0, - 25143, - 0, - 0, - 0, - 25151, - 0, - 25161, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25163, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25174, - 0, - 25175, - 0, - 25207, - 0, - 0, - 0, - 25209, - 0, - 0, - 0, - 0, - 25213, - 0, - 25219, - 0, - 25223, - 0, - 25225, - 0, - 0, - 0, - 25227, - 0, - 0, - 0, - 25228, - 0, - 0, - 0, - 25229, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25231, - 25233, - 0, - 0, - 0, - 0, - 25237, - 25239, - 0, - 0, - 0, - 25243, - 0, - 0, - 0, - 25252, - 0, - 25257, - 25258, - 0, - 0, - 0, - 0, - 25260, - 25265, - 0, - 25268, - 0, - 0, - 25273, - 25324, - 0, - 25325, - 0, - 25326, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25327, - 0, - 0, - 0, - 0, - 0, - 25328, - 0, - 0, - 0, - 0, - 0, - 0, - 25332, - 0, - 0, - 0, - 25333, - 0, - 0, - 0, - 25336, - 25337, - 25338, - 0, - 0, - 25343, - 0, - 25350, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25352, - 0, - 25354, - 0, - 25375, - 0, - 25379, - 0, - 0, - 0, - 0, - 25384, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25386, - 0, - 25388, - 0, - 25390, - 0, - 0, - 25399, - 0, - 0, - 25401, - 0, - 0, - 0, - 25402, - 0, - 0, - 0, - 25407, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25413, - 25415, - 0, - 0, - 25417, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25419, - 0, - 0, - 0, - 25421, - 0, - 0, - 0, - 25424, - 0, - 0, - 0, - 0, - 25433, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25435, - 0, - 0, - 0, - 0, - 0, - 0, - 25436, - 0, - 0, - 0, - 25437, - 0, - 0, - 25440, - 0, - 0, - 0, - 0, - 0, - 0, - 25442, - 0, - 0, - 25443, - 0, - 25446, - 0, - 0, - 25449, - 0, - 0, - 0, - 25450, - 0, - 0, - 0, - 0, - 25452, - 0, - 25453, - 25454, - 25455, - 0, - 0, - 0, - 25456, - 0, - 25457, - 0, - 0, - 0, - 25459, - 0, - 25461, - 0, - 25468, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25469, - 0, - 0, - 0, - 0, - 0, - 25471, - 0, - 0, - 0, - 0, - 0, - 25474, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25475, - 0, - 0, - 0, - 0, - 25477, - 0, - 0, - 0, - 0, - 25483, - 0, - 0, - 0, - 0, - 0, - 25484, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25485, - 0, - 25497, - 0, - 0, - 25498, - 0, - 25504, - 0, - 25510, - 0, - 25512, - 0, - 0, - 25513, - 25514, - 0, - 0, - 0, - 0, - 0, - 0, - 25517, - 25518, - 25519, - 0, - 25520, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25521, - 0, - 25522, - 25527, - 25534, - 0, - 25536, - 0, - 25537, - 0, - 0, - 25548, - 25550, - 0, - 0, - 25551, - 0, - 25552, - 0, - 0, - 0, - 0, - 0, - 25554, - 0, - 25555, - 0, - 25556, - 25557, - 25568, - 0, - 0, - 0, - 25570, - 25571, - 0, - 0, - 0, - 0, - 0, - 0, - 25574, - 0, - 0, - 0, - 0, - 25579, - 0, - 0, - 0, - 25581, - 0, - 0, - 0, - 25582, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25588, - 0, - 0, - 0, - 0, - 25589, - 0, - 0, - 0, - 0, - 25590, - 0, - 25591, - 25592, - 25593, - 0, - 25594, - 0, - 0, - 0, - 25596, - 0, - 25597, - 25615, - 0, - 0, - 0, - 0, - 0, - 25618, - 0, - 0, - 0, - 0, - 25619, - 25623, - 0, - 0, - 25629, - 0, - 0, - 25631, - 0, - 0, - 0, - 25635, - 25636, - 0, - 0, - 25649, - 0, - 0, - 0, - 0, - 25654, - 0, - 0, - 0, - 25661, - 25663, - 0, - 0, - 25671, - 0, - 0, - 25678, - 25698, - 0, - 25699, - 25702, - 25703, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25704, - 0, - 0, - 0, - 0, - 0, - 25706, - 0, - 0, - 25710, - 0, - 25711, - 0, - 25712, - 0, - 25715, - 25716, - 25717, - 0, - 0, - 25718, - 25728, - 25732, - 0, - 0, - 0, - 25734, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25737, - 0, - 0, - 25739, - 0, - 0, - 0, - 25740, - 0, - 25741, - 25745, - 0, - 25746, - 0, - 25748, - 25772, - 25778, - 0, - 0, - 0, - 0, - 0, - 25780, - 0, - 0, - 0, - 0, - 25781, - 0, - 25782, - 25784, - 25785, - 0, - 0, - 0, - 25789, - 0, - 0, - 0, - 0, - 0, - 0, - 25797, - 25801, - 0, - 0, - 0, - 25808, - 25809, - 0, - 0, - 25811, - 25814, - 25815, - 0, - 0, - 25817, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25820, - 0, - 0, - 0, - 0, - 25832, - 25833, - 0, - 0, - 0, - 25846, - 0, - 0, - 0, - 25847, - 25848, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25849, - 25850, - 0, - 0, - 25851, - 0, - 0, - 25852, - 0, - 25862, - 0, - 0, - 0, - 25863, - 25865, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25867, - 25868, - 0, - 25869, - 25874, - 0, - 25875, - 0, - 25876, - 25877, - 0, - 0, - 0, - 0, - 25878, - 25902, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25903, - 25904, - 25905, - 0, - 0, - 0, - 25908, - 25909, - 0, - 0, - 0, - 0, - 25910, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25912, - 0, - 25913, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25914, - 0, - 0, - 25916, - 0, - 0, - 0, - 0, - 0, - 25917, - 25927, - 0, - 0, - 0, - 0, - 25928, - 0, - 0, - 25930, - 0, - 0, - 0, - 25933, - 0, - 0, - 25938, - 25942, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25945, - 0, - 25950, - 0, - 25956, - 0, - 0, - 25961, - 25962, - 0, - 0, - 25963, - 0, - 25964, - 25965, - 25966, - 0, - 0, - 0, - 0, - 0, - 25967, - 0, - 0, - 0, - 0, - 25968, - 0, - 0, - 0, - 25969, - 25971, - 0, - 0, - 0, - 0, - 0, - 25973, - 25975, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25978, - 0, - 25981, - 0, - 0, - 0, - 25982, - 0, - 0, - 0, - 25984, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 25993, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26002, - 0, - 0, - 0, - 26005, - 0, - 0, - 0, - 26006, - 26007, - 0, - 0, - 26014, - 26015, - 26016, - 0, - 0, - 0, - 0, - 0, - 0, - 26017, - 26018, - 26020, - 0, - 26022, - 26023, - 0, - 0, - 0, - 26024, - 26028, - 0, - 26029, - 26033, - 26034, - 26044, - 0, - 0, - 0, - 0, - 0, - 26046, - 0, - 0, - 26047, - 0, - 0, - 26049, - 0, - 26050, - 0, - 26051, - 0, - 0, - 0, - 0, - 0, - 26053, - 0, - 0, - 0, - 0, - 26054, - 26059, - 0, - 0, - 0, - 0, - 0, - 0, - 26060, - 0, - 26066, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26067, - 0, - 26069, - 0, - 0, - 26071, - 0, - 0, - 0, - 26073, - 0, - 26074, - 26077, - 0, - 0, - 0, - 0, - 26078, - 0, - 0, - 0, - 26079, - 0, - 26090, - 0, - 0, - 26094, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26095, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26096, - 26101, - 0, - 26107, - 26122, - 0, - 26124, - 0, - 0, - 26125, - 0, - 0, - 0, - 0, - 0, - 0, - 26136, - 26141, - 26155, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26164, - 26166, - 0, - 0, - 0, - 26167, - 0, - 26170, - 26171, - 0, - 0, - 26172, - 0, - 0, - 26174, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26175, - 0, - 0, - 0, - 26176, - 26177, - 0, - 26321, - 26322, - 0, - 26323, - 0, - 0, - 26324, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26325, - 0, - 26331, - 0, - 0, - 0, - 0, - 0, - 0, - 26335, - 0, - 0, - 0, - 26350, - 0, - 0, - 0, - 26379, - 0, - 0, - 26382, - 26383, - 26385, - 0, - 0, - 26392, - 26406, - 0, - 0, - 0, - 0, - 26411, - 0, - 0, - 0, - 0, - 0, - 26412, - 0, - 0, - 26420, - 0, - 0, - 26423, - 0, - 26424, - 26426, - 26432, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26435, - 0, - 26436, - 0, - 0, - 0, - 0, - 0, - 26441, - 0, - 26444, - 0, - 0, - 0, - 26446, - 0, - 0, - 0, - 0, - 26447, - 0, - 0, - 0, - 0, - 26449, - 0, - 26450, - 26452, - 0, - 26453, - 26454, - 0, - 0, - 0, - 26455, - 0, - 0, - 0, - 26456, - 0, - 0, - 26458, - 0, - 0, - 26460, - 0, - 26463, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26464, - 26470, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26473, - 0, - 0, - 26474, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26475, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26477, - 0, - 26485, - 0, - 0, - 26486, - 0, - 26487, - 0, - 0, - 26488, - 26493, - 26494, - 0, - 0, - 26495, - 0, - 26497, - 26504, - 26506, - 0, - 0, - 0, - 0, - 0, - 26507, - 0, - 0, - 0, - 0, - 0, - 26509, - 0, - 0, - 26510, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26512, - 0, - 26513, - 26515, - 0, - 0, - 0, - 26518, - 0, - 0, - 0, - 26519, - 0, - 26524, - 26526, - 0, - 0, - 0, - 26527, - 0, - 26532, - 0, - 26533, - 26537, - 26558, - 0, - 0, - 0, - 26559, - 0, - 0, - 0, - 26571, - 0, - 0, - 26573, - 0, - 26588, - 0, - 26593, - 0, - 0, - 0, - 0, - 0, - 0, - 26603, - 0, - 26604, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26606, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26607, - 26609, - 26611, - 26614, - 0, - 0, - 0, - 26616, - 26620, - 0, - 26621, - 0, - 0, - 0, - 0, - 0, - 26627, - 0, - 26629, - 0, - 0, - 26630, - 0, - 0, - 26632, - 26643, - 0, - 0, - 0, - 26644, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26646, - 26647, - 0, - 0, - 0, - 26650, - 0, - 0, - 26656, - 0, - 0, - 0, - 0, - 26663, - 26670, - 26671, - 0, - 0, - 0, - 26685, - 26686, - 26687, - 0, - 26689, - 0, - 0, - 0, - 0, - 26744, - 0, - 26745, - 0, - 26747, - 26748, - 0, - 26749, - 26750, - 26751, - 0, - 0, - 0, - 0, - 26752, - 26755, - 0, - 0, - 0, - 26756, - 26769, - 0, - 0, - 0, - 26774, - 0, - 0, - 0, - 0, - 0, - 26775, - 0, - 26777, - 26778, - 0, - 26786, - 0, - 0, - 0, - 26787, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26788, - 0, - 0, - 26789, - 0, - 0, - 0, - 0, - 0, - 26791, - 0, - 26792, - 26793, - 0, - 0, - 0, - 26794, - 0, - 26797, - 26798, - 0, - 0, - 0, - 26800, - 0, - 0, - 26803, - 0, - 26804, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26805, - 0, - 0, - 26808, - 0, - 0, - 26809, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26812, - 0, - 26825, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26826, - 0, - 0, - 26827, - 26829, - 26834, - 0, - 0, - 0, - 0, - 26835, - 0, - 0, - 26849, - 0, - 26851, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26852, - 0, - 26853, - 26857, - 0, - 26858, - 0, - 26859, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26876, - 0, - 26878, - 26882, - 26883, - 0, - 0, - 0, - 0, - 26890, - 26894, - 0, - 0, - 0, - 0, - 26895, - 26896, - 0, - 0, - 0, - 0, - 0, - 26900, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26911, - 26913, - 26914, - 26915, - 26916, - 26919, - 0, - 0, - 0, - 26921, - 26922, - 0, - 0, - 26925, - 0, - 0, - 0, - 26928, - 0, - 0, - 26929, - 26930, - 0, - 0, - 0, - 26931, - 0, - 26932, - 0, - 0, - 0, - 0, - 0, - 26933, - 0, - 0, - 0, - 0, - 0, - 0, - 26937, - 0, - 0, - 26943, - 0, - 0, - 26944, - 0, - 0, - 0, - 26946, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26956, - 0, - 26958, - 0, - 0, - 26963, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 26965, - 0, - 26969, - 26970, - 26972, - 0, - 0, - 0, - 0, - 0, - 26973, - 0, - 26974, - 0, - 26978, - 0, - 26980, - 0, - 0, - 0, - 0, - 0, - 0, - 26982, - 0, - 26986, - 26987, - 0, - 26990, - 0, - 0, - 0, - 0, - 27003, - 27006, - 0, - 0, - 27007, - 27010, - 27012, - 27013, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27014, - 27015, - 27018, - 0, - 27019, - 0, - 0, - 0, - 0, - 0, - 27025, - 0, - 0, - 0, - 27026, - 0, - 0, - 0, - 0, - 27029, - 27030, - 27031, - 27034, - 0, - 0, - 27036, - 27037, - 0, - 0, - 0, - 27038, - 27042, - 0, - 0, - 0, - 27044, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27045, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27046, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27047, - 27049, - 0, - 27050, - 0, - 0, - 0, - 27051, - 27052, - 0, - 27055, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27056, - 27058, - 27059, - 0, - 27061, - 0, - 27064, - 0, - 0, - 0, - 0, - 0, - 27069, - 0, - 0, - 27070, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27072, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27076, - 0, - 0, - 0, - 0, - 0, - 27078, - 0, - 27079, - 0, - 0, - 0, - 27081, - 0, - 0, - 0, - 0, - 0, - 0, - 27082, - 0, - 27083, - 27086, - 0, - 0, - 0, - 0, - 27087, - 0, - 0, - 0, - 0, - 0, - 27088, - 27090, - 0, - 27094, - 0, - 0, - 27095, - 0, - 27099, - 27102, - 0, - 0, - 0, - 27103, - 0, - 0, - 0, - 0, - 27105, - 0, - 0, - 0, - 27106, - 0, - 0, - 0, - 0, - 0, - 0, - 27107, - 0, - 0, - 0, - 0, - 27108, - 27117, - 0, - 0, - 0, - 0, - 27118, - 0, - 0, - 27124, - 0, - 27126, - 0, - 0, - 27130, - 27131, - 0, - 0, - 0, - 0, - 0, - 0, - 27147, - 0, - 0, - 0, - 0, - 27148, - 27149, - 0, - 0, - 0, - 0, - 27150, - 27151, - 0, - 27152, - 0, - 27159, - 0, - 0, - 0, - 27164, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27175, - 0, - 27189, - 0, - 0, - 27191, - 0, - 27193, - 0, - 27195, - 0, - 27198, - 0, - 0, - 0, - 0, - 0, - 27200, - 0, - 0, - 0, - 0, - 27202, - 0, - 0, - 0, - 0, - 27203, - 0, - 0, - 27204, - 0, - 0, - 27206, - 0, - 27207, - 0, - 0, - 0, - 0, - 27209, - 0, - 0, - 0, - 27213, - 0, - 0, - 27216, - 27219, - 27220, - 27222, - 27223, - 0, - 27224, - 0, - 27225, - 27226, - 0, - 0, - 27233, - 0, - 0, - 0, - 0, - 27235, - 0, - 27237, - 0, - 27238, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27239, - 0, - 27242, - 27243, - 0, - 27250, - 0, - 0, - 0, - 27251, - 0, - 27253, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27254, - 27255, - 27258, - 0, - 0, - 0, - 27259, - 0, - 0, - 0, - 0, - 0, - 0, - 27267, - 0, - 27276, - 27278, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27296, - 27297, - 27301, - 0, - 0, - 0, - 0, - 0, - 0, - 27302, - 0, - 0, - 0, - 0, - 0, - 0, - 27312, - 27313, - 0, - 0, - 0, - 0, - 0, - 27318, - 0, - 27320, - 0, - 27329, - 0, - 27330, - 27331, - 0, - 27332, - 0, - 0, - 0, - 0, - 27340, - 0, - 0, - 0, - 27348, - 0, - 0, - 0, - 0, - 0, - 0, - 27350, - 0, - 27351, - 0, - 0, - 0, - 0, - 27355, - 0, - 0, - 27358, - 27359, - 27361, - 0, - 0, - 0, - 27365, - 0, - 27367, - 0, - 27376, - 27378, - 0, - 0, - 27379, - 0, - 0, - 0, - 0, - 0, - 0, - 27396, - 0, - 27397, - 27404, - 0, - 0, - 0, - 0, - 0, - 27408, - 0, - 0, - 0, - 0, - 27453, - 0, - 0, - 0, - 27456, - 0, - 0, - 0, - 27458, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27459, - 0, - 0, - 0, - 27460, - 0, - 0, - 27461, - 0, - 27465, - 27467, - 0, - 0, - 27469, - 0, - 27470, - 0, - 27471, - 0, - 27477, - 27482, - 0, - 0, - 0, - 0, - 0, - 0, - 27484, - 0, - 0, - 0, - 0, - 0, - 0, - 27485, - 0, - 0, - 0, - 0, - 0, - 27493, - 0, - 27494, - 27502, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27511, - 27532, - 0, - 0, - 0, - 27533, - 27545, - 0, - 0, - 0, - 27546, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27547, - 0, - 0, - 27549, - 27550, - 0, - 27551, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27555, - 0, - 0, - 27571, - 0, - 27573, - 27574, - 27575, - 27577, - 0, - 27578, - 0, - 0, - 27579, - 27585, - 0, - 0, - 0, - 0, - 0, - 27586, - 0, - 0, - 27588, - 27589, - 0, - 0, - 0, - 0, - 27596, - 0, - 0, - 27600, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27608, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27610, - 0, - 0, - 0, - 27618, - 0, - 0, - 27620, - 0, - 0, - 0, - 27631, - 0, - 0, - 27632, - 27634, - 0, - 27636, - 27638, - 0, - 0, - 0, - 27643, - 0, - 27644, - 27649, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27651, - 27660, - 0, - 27661, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27662, - 0, - 0, - 27664, - 0, - 27665, - 0, - 0, - 0, - 27669, - 0, - 27671, - 0, - 0, - 0, - 27673, - 27674, - 0, - 0, - 0, - 27682, - 0, - 0, - 0, - 27711, - 0, - 27712, - 27713, - 27719, - 27720, - 0, - 0, - 27728, - 0, - 27729, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27731, - 0, - 0, - 27732, - 0, - 27733, - 0, - 27738, - 0, - 0, - 0, - 27742, - 0, - 0, - 0, - 27743, - 27744, - 0, - 0, - 0, - 0, - 0, - 0, - 27745, - 27746, - 0, - 0, - 0, - 27747, - 27748, - 27751, - 27752, - 0, - 0, - 0, - 27768, - 27770, - 0, - 0, - 0, - 27774, - 27775, - 0, - 27776, - 27777, - 0, - 0, - 27781, - 0, - 27784, - 0, - 27786, - 0, - 0, - 27791, - 0, - 27792, - 27793, - 27804, - 0, - 27812, - 27813, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27814, - 0, - 27825, - 0, - 27827, - 0, - 0, - 0, - 0, - 27828, - 27861, - 27862, - 0, - 0, - 0, - 27864, - 0, - 0, - 0, - 27865, - 27884, - 0, - 27889, - 0, - 0, - 0, - 0, - 0, - 27890, - 0, - 27891, - 0, - 0, - 0, - 27892, - 0, - 0, - 0, - 0, - 0, - 27897, - 27898, - 0, - 0, - 27899, - 0, - 0, - 0, - 27901, - 27905, - 0, - 0, - 27920, - 0, - 0, - 27921, - 0, - 27922, - 0, - 0, - 0, - 27931, - 27934, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27941, - 0, - 27942, - 0, - 27945, - 0, - 27947, - 27954, - 0, - 0, - 0, - 0, - 27960, - 27963, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27964, - 27965, - 0, - 0, - 0, - 27967, - 0, - 27969, - 27975, - 0, - 27976, - 27977, - 0, - 27981, - 0, - 27983, - 28051, - 28052, - 0, - 0, - 0, - 0, - 0, - 28056, - 0, - 0, - 0, - 0, - 0, - 0, - 28058, - 28059, - 0, - 0, - 28061, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28063, - 0, - 0, - 0, - 0, - 0, - 0, - 28066, - 0, - 0, - 0, - 0, - 0, - 0, - 28069, - 28070, - 28072, - 0, - 28073, - 0, - 0, - 28074, - 0, - 0, - 0, - 0, - 28075, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28078, - 0, - 0, - 0, - 0, - 28085, - 0, - 0, - 0, - 0, - 28086, - 0, - 0, - 0, - 0, - 0, - 0, - 28088, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28090, - 0, - 28097, - 28114, - 28115, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28116, - 0, - 0, - 0, - 0, - 0, - 28118, - 0, - 28129, - 0, - 28131, - 0, - 0, - 28135, - 0, - 0, - 0, - 28140, - 28141, - 0, - 0, - 0, - 28146, - 0, - 0, - 0, - 0, - 28152, - 0, - 0, - 0, - 0, - 28155, - 28157, - 28161, - 0, - 0, - 0, - 0, - 28166, - 0, - 28167, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28172, - 0, - 0, - 0, - 0, - 0, - 0, - 28173, - 0, - 0, - 28175, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28178, - 28188, - 0, - 28190, - 0, - 0, - 0, - 0, - 0, - 28191, - 0, - 28193, - 28206, - 0, - 0, - 28207, - 28209, - 0, - 28211, - 0, - 28213, - 0, - 0, - 0, - 28215, - 28216, - 28217, - 0, - 28222, - 0, - 28223, - 28225, - 0, - 0, - 0, - 28226, - 0, - 28227, - 28229, - 28232, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28235, - 0, - 28241, - 0, - 0, - 28242, - 0, - 0, - 0, - 0, - 28243, - 0, - 0, - 0, - 28245, - 0, - 0, - 0, - 28248, - 28250, - 0, - 28251, - 28252, - 0, - 0, - 0, - 0, - 0, - 0, - 28253, - 0, - 0, - 28254, - 28255, - 0, - 0, - 28256, - 0, - 0, - 28258, - 0, - 0, - 0, - 0, - 0, - 28259, - 0, - 0, - 28260, - 0, - 0, - 28261, - 0, - 0, - 0, - 0, - 28262, - 28263, - 0, - 0, - 28264, - 0, - 0, - 0, - 28266, - 0, - 28268, - 28269, - 0, - 28270, - 28272, - 28274, - 0, - 28277, - 28278, - 0, - 0, - 0, - 28279, - 0, - 28280, - 28281, - 28283, - 0, - 28292, - 0, - 28294, - 0, - 28297, - 0, - 0, - 0, - 0, - 28299, - 0, - 0, - 0, - 0, - 0, - 28300, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28301, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28302, - 28303, - 0, - 0, - 0, - 0, - 28304, - 0, - 0, - 28305, - 0, - 28312, - 0, - 28313, - 28314, - 0, - 0, - 0, - 0, - 0, - 0, - 28315, - 0, - 0, - 0, - 28320, - 28321, - 0, - 0, - 28328, - 0, - 0, - 0, - 28329, - 28338, - 0, - 28339, - 0, - 0, - 28344, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28347, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28348, - 0, - 0, - 0, - 0, - 0, - 28411, - 0, - 28412, - 28413, - 0, - 28416, - 0, - 0, - 0, - 28420, - 0, - 0, - 0, - 0, - 0, - 28421, - 0, - 0, - 0, - 0, - 28423, - 0, - 0, - 0, - 28424, - 0, - 0, - 28428, - 0, - 0, - 0, - 0, - 0, - 28429, - 0, - 0, - 0, - 28431, - 28434, - 0, - 28458, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28464, - 0, - 0, - 0, - 0, - 28465, - 0, - 28467, - 0, - 0, - 0, - 0, - 0, - 0, - 28471, - 0, - 0, - 0, - 0, - 28474, - 0, - 28480, - 0, - 28481, - 0, - 0, - 28485, - 0, - 0, - 0, - 0, - 28486, - 28488, - 0, - 0, - 28489, - 0, - 0, - 0, - 0, - 28492, - 0, - 0, - 0, - 28495, - 0, - 28497, - 0, - 28499, - 0, - 0, - 0, - 0, - 28500, - 0, - 0, - 28502, - 28503, - 0, - 0, - 0, - 28508, - 0, - 0, - 0, - 28510, - 0, - 0, - 28512, - 28513, - 28514, - 28521, - 0, - 28526, - 0, - 28527, - 28528, - 0, - 0, - 0, - 0, - 28529, - 0, - 0, - 28532, - 0, - 0, - 28537, - 28538, - 0, - 0, - 0, - 28539, - 0, - 28548, - 0, - 28553, - 28554, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28560, - 28563, - 0, - 0, - 28564, - 0, - 0, - 0, - 0, - 28565, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28566, - 28568, - 0, - 0, - 0, - 0, - 0, - 0, - 28569, - 0, - 0, - 0, - 28570, - 0, - 28572, - 28573, - 0, - 0, - 0, - 0, - 28575, - 0, - 0, - 0, - 0, - 28576, - 28581, - 28588, - 0, - 0, - 28589, - 0, - 0, - 0, - 28590, - 28595, - 0, - 28598, - 0, - 0, - 28601, - 0, - 0, - 28605, - 0, - 0, - 0, - 0, - 28614, - 28615, - 28619, - 0, - 0, - 0, - 0, - 0, - 0, - 28620, - 0, - 28626, - 0, - 0, - 28628, - 0, - 28631, - 0, - 28632, - 0, - 0, - 0, - 0, - 0, - 0, - 28635, - 0, - 0, - 0, - 28637, - 28638, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28639, - 0, - 28643, - 0, - 0, - 28652, - 0, - 0, - 0, - 28662, - 0, - 28670, - 28671, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28672, - 28673, - 28675, - 28676, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28691, - 0, - 0, - 0, - 28695, - 0, - 0, - 0, - 28696, - 0, - 28697, - 28698, - 0, - 28705, - 0, - 28707, - 28708, - 28710, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28711, - 28728, - 0, - 0, - 0, - 28736, - 0, - 0, - 0, - 28737, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28738, - 0, - 28739, - 0, - 28741, - 0, - 0, - 28742, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28745, - 0, - 0, - 0, - 0, - 0, - 0, - 28749, - 28750, - 28752, - 28754, - 28756, - 0, - 28757, - 0, - 0, - 0, - 0, - 28759, - 28760, - 0, - 0, - 0, - 0, - 0, - 0, - 28762, - 0, - 0, - 0, - 28764, - 0, - 0, - 0, - 0, - 0, - 0, - 28766, - 0, - 28767, - 28768, - 0, - 0, - 0, - 0, - 28769, - 28770, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28771, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28772, - 0, - 28773, - 0, - 28782, - 0, - 0, - 0, - 0, - 0, - 0, - 28784, - 0, - 28785, - 0, - 28786, - 0, - 0, - 0, - 28787, - 0, - 0, - 0, - 28797, - 0, - 0, - 0, - 0, - 0, - 0, - 28799, - 0, - 0, - 28801, - 0, - 0, - 0, - 0, - 28802, - 0, - 28805, - 0, - 0, - 28806, - 0, - 0, - 28807, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28808, - 0, - 0, - 0, - 0, - 0, - 28810, - 28812, - 0, - 0, - 28816, - 28819, - 0, - 0, - 28821, - 0, - 28826, - 0, - 0, - 0, - 28842, - 28852, - 0, - 0, - 28853, - 0, - 28854, - 28855, - 0, - 0, - 0, - 28857, - 0, - 0, - 0, - 28858, - 0, - 28867, - 28868, - 28869, - 0, - 0, - 0, - 28874, - 28880, - 28882, - 28890, - 28892, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28895, - 0, - 0, - 0, - 28898, - 28899, - 0, - 0, - 0, - 28900, - 0, - 0, - 28904, - 0, - 28906, - 0, - 0, - 0, - 0, - 28907, - 0, - 0, - 0, - 0, - 0, - 0, - 28908, - 0, - 0, - 0, - 28910, - 0, - 28914, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28915, - 28916, - 28919, - 0, - 0, - 28920, - 0, - 28921, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28924, - 0, - 0, - 0, - 0, - 28926, - 28929, - 0, - 0, - 0, - 28930, - 0, - 28936, - 0, - 28939, - 0, - 0, - 0, - 0, - 28942, - 0, - 0, - 0, - 0, - 0, - 0, - 28956, - 0, - 0, - 0, - 28966, - 0, - 0, - 0, - 0, - 28967, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28968, - 0, - 28971, - 0, - 28975, - 28976, - 0, - 28982, - 28983, - 0, - 0, - 28984, - 28989, - 28996, - 28997, - 28998, - 0, - 0, - 0, - 0, - 0, - 0, - 28999, - 0, - 0, - 0, - 0, - 0, - 29000, - 0, - 29001, - 0, - 0, - 0, - 29009, - 0, - 0, - 29011, - 0, - 0, - 29021, - 0, - 0, - 0, - 0, - 29024, - 0, - 29025, - 0, - 0, - 0, - 0, - 0, - 29026, - 0, - 0, - 0, - 29036, - 0, - 0, - 0, - 29037, - 0, - 0, - 0, - 0, - 29038, - 0, - 29045, - 0, - 29047, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29051, - 0, - 0, - 0, - 29054, - 29056, - 29062, - 0, - 29070, - 29082, - 0, - 0, - 0, - 29083, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29084, - 0, - 0, - 0, - 0, - 29085, - 29088, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29090, - 29097, - 0, - 0, - 0, - 29103, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29105, - 0, - 0, - 0, - 0, - 0, - 29107, - 0, - 29109, - 0, - 0, - 0, - 29115, - 0, - 0, - 29120, - 0, - 0, - 29138, - 29140, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29152, - 0, - 29160, - 29174, - 0, - 29176, - 0, - 0, - 29180, - 0, - 29181, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29228, - 0, - 0, - 29229, - 0, - 0, - 29230, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29234, - 0, - 0, - 0, - 29241, - 0, - 29245, - 0, - 29248, - 0, - 29250, - 29256, - 29280, - 0, - 29282, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29285, - 0, - 0, - 29286, - 29291, - 29292, - 0, - 0, - 0, - 0, - 29294, - 0, - 29295, - 0, - 0, - 0, - 0, - 0, - 29296, - 29297, - 29298, - 29300, - 0, - 29302, - 0, - 0, - 29304, - 29307, - 0, - 29312, - 0, - 0, - 0, - 29322, - 0, - 0, - 29323, - 0, - 0, - 29324, - 29326, - 29328, - 0, - 29335, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29338, - 29339, - 0, - 0, - 0, - 0, - 0, - 29341, - 29343, - 0, - 0, - 0, - 0, - 29344, - 0, - 0, - 0, - 0, - 0, - 29345, - 0, - 0, - 0, - 0, - 29346, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29347, - 29348, - 29349, - 0, - 0, - 29354, - 0, - 0, - 29355, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29357, - 0, - 0, - 0, - 0, - 29364, - 0, - 29365, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29366, - 0, - 0, - 29368, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29378, - 0, - 29381, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29386, - 0, - 0, - 0, - 0, - 0, - 0, - 29389, - 0, - 0, - 0, - 29390, - 0, - 0, - 29391, - 29397, - 0, - 29398, - 29412, - 29414, - 29418, - 29419, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29420, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29423, - 0, - 0, - 0, - 29435, - 0, - 0, - 0, - 29437, - 0, - 0, - 29439, - 0, - 29441, - 0, - 0, - 0, - 0, - 29443, - 0, - 29446, - 29450, - 29452, - 0, - 0, - 0, - 0, - 0, - 29456, - 0, - 0, - 0, - 0, - 0, - 29461, - 0, - 0, - 0, - 29464, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29468, - 0, - 29473, - 0, - 0, - 0, - 29486, - 0, - 0, - 0, - 29490, - 0, - 0, - 0, - 29491, - 29492, - 0, - 0, - 29497, - 0, - 0, - 0, - 29498, - 0, - 29499, - 0, - 29502, - 29505, - 0, - 29509, - 0, - 0, - 0, - 29510, - 0, - 0, - 0, - 29512, - 0, - 0, - 0, - 29516, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29518, - 0, - 29519, - 0, - 0, - 0, - 0, - 0, - 29520, - 29521, - 29529, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29530, - 0, - 0, - 29531, - 29538, - 0, - 29540, - 0, - 0, - 0, - 29542, - 0, - 29543, - 29544, - 29547, - 0, - 0, - 29548, - 0, - 0, - 0, - 29549, - 0, - 0, - 0, - 29550, - 0, - 0, - 29552, - 0, - 0, - 0, - 0, - 29558, - 29561, - 0, - 29562, - 29564, - 0, - 0, - 29565, - 0, - 0, - 29566, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29578, - 29584, - 29586, - 29591, - 0, - 0, - 0, - 0, - 29593, - 29594, - 0, - 0, - 29597, - 0, - 0, - 29613, - 0, - 29614, - 0, - 29615, - 0, - 0, - 0, - 0, - 29616, - 29617, - 0, - 0, - 29625, - 0, - 0, - 0, - 29632, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29633, - 0, - 0, - 0, - 0, - 0, - 29634, - 29635, - 29637, - 0, - 29638, - 0, - 29641, - 29643, - 0, - 0, - 0, - 0, - 0, - 0, - 29644, - 0, - 29645, - 0, - 29649, - 0, - 0, - 0, - 29650, - 0, - 29653, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29656, - 29659, - 0, - 0, - 29660, - 0, - 0, - 0, - 29661, - 0, - 0, - 0, - 0, - 0, - 29664, - 0, - 0, - 0, - 29671, - 29673, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29675, - 0, - 29677, - 29679, - 0, - 0, - 29684, - 0, - 0, - 0, - 0, - 0, - 29685, - 0, - 0, - 0, - 29687, - 0, - 0, - 0, - 29688, - 0, - 29689, - 29690, - 29700, - 0, - 29701, - 0, - 0, - 0, - 29702, - 0, - 29706, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29720, - 0, - 29721, - 0, - 29727, - 0, - 29733, - 29734, - 0, - 29750, - 29761, - 0, - 29763, - 0, - 0, - 0, - 0, - 0, - 29764, - 0, - 0, - 29765, - 0, - 0, - 0, - 29771, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29772, - 0, - 0, - 0, - 29773, - 29774, - 29775, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29822, - 0, - 0, - 0, - 29824, - 0, - 29825, - 0, - 0, - 0, - 0, - 0, - 29827, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29829, - 0, - 29832, - 29834, - 0, - 0, - 29835, - 0, - 0, - 29837, - 29838, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29843, - 0, - 0, - 0, - 0, - 29844, - 29845, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29849, - 0, - 0, - 29869, - 29872, - 29890, - 29905, - 0, - 0, - 0, - 0, - 0, - 29907, - 29921, - 0, - 29922, - 0, - 0, - 29923, - 29926, - 29944, - 29946, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29947, - 29948, - 0, - 0, - 0, - 29951, - 0, - 0, - 0, - 0, - 0, - 29953, - 0, - 0, - 29956, - 0, - 29957, - 0, - 0, - 29962, - 0, - 0, - 0, - 0, - 29971, - 0, - 0, - 0, - 29972, - 0, - 0, - 0, - 0, - 0, - 29978, - 0, - 29979, - 29992, - 30007, - 30008, - 30010, - 0, - 0, - 0, - 30013, - 0, - 0, - 0, - 0, - 30014, - 30016, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30017, - 0, - 0, - 0, - 0, - 0, - 30023, - 30031, - 0, - 0, - 30033, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30034, - 0, - 30038, - 0, - 30039, - 0, - 30040, - 0, - 0, - 0, - 0, - 0, - 0, - 30067, - 30068, - 0, - 0, - 0, - 30069, - 0, - 30072, - 0, - 0, - 0, - 30073, - 0, - 0, - 0, - 0, - 30075, - 0, - 0, - 0, - 0, - 0, - 0, - 30079, - 0, - 0, - 30080, - 0, - 0, - 0, - 0, - 0, - 30082, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30084, - 30090, - 0, - 0, - 30091, - 0, - 0, - 0, - 0, - 30098, - 30118, - 0, - 30119, - 0, - 30121, - 30130, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30131, - 30132, - 30133, - 0, - 0, - 0, - 0, - 0, - 0, - 30135, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30136, - 0, - 0, - 30137, - 30138, - 0, - 0, - 0, - 30139, - 30146, - 0, - 0, - 0, - 0, - 0, - 30147, - 0, - 0, - 30148, - 30151, - 0, - 0, - 0, - 30168, - 0, - 30172, - 30173, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30180, - 30181, - 0, - 30192, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30194, - 30196, - 0, - 0, - 30199, - 0, - 0, - 30202, - 0, - 0, - 0, - 0, - 30203, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30213, - 0, - 0, - 0, - 30216, - 0, - 0, - 30217, - 0, - 0, - 0, - 30218, - 0, - 0, - 0, - 0, - 30219, - 0, - 30220, - 0, - 30222, - 30227, - 0, - 0, - 0, - 0, - 0, - 30231, - 0, - 0, - 30233, - 30235, - 0, - 0, - 0, - 0, - 30238, - 0, - 30240, - 30243, - 30245, - 0, - 30250, - 30252, - 0, - 0, - 0, - 30269, - 0, - 0, - 30271, - 30272, - 0, - 0, - 0, - 30278, - 30280, - 0, - 0, - 30282, - 0, - 30284, - 0, - 30294, - 0, - 0, - 0, - 0, - 30295, - 30296, - 0, - 0, - 0, - 0, - 0, - 30298, - 30299, - 30302, - 30304, - 30306, - 0, - 0, - 0, - 0, - 0, - 0, - 30316, - 30317, - 0, - 0, - 0, - 30318, - 0, - 0, - 0, - 30319, - 0, - 30320, - 30322, - 30326, - 0, - 0, - 0, - 0, - 0, - 30327, - 0, - 30332, - 30348, - 30349, - 0, - 0, - 30356, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30357, - 0, - 30358, - 0, - 30359, - 30360, - 0, - 0, - 30365, - 30366, - 30378, - 0, - 0, - 0, - 0, - 30379, - 0, - 0, - 30381, - 0, - 30385, - 0, - 30388, - 30397, - 0, - 0, - 0, - 30401, - 0, - 0, - 0, - 0, - 30403, - 0, - 0, - 0, - 0, - 0, - 30404, - 0, - 0, - 30405, - 0, - 30406, - 30408, - 0, - 30409, - 0, - 30410, - 0, - 0, - 0, - 30417, - 0, - 0, - 30418, - 30419, - 0, - 30420, - 0, - 30424, - 0, - 0, - 0, - 30427, - 30430, - 30432, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30433, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30436, - 0, - 30437, - 30438, - 0, - 30441, - 30442, - 0, - 0, - 0, - 30445, - 0, - 0, - 0, - 0, - 30452, - 30456, - 30457, - 0, - 0, - 0, - 30458, - 0, - 30464, - 0, - 0, - 0, - 0, - 0, - 0, - 30467, - 0, - 30469, - 0, - 0, - 0, - 0, - 0, - 30477, - 0, - 0, - 30484, - 0, - 0, - 0, - 0, - 0, - 30485, - 0, - 0, - 0, - 0, - 0, - 30486, - 30487, - 30497, - 30498, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30505, - 0, - 30508, - 0, - 0, - 0, - 30509, - 30510, - 0, - 30514, - 30516, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30523, - 0, - 30524, - 0, - 30525, - 0, - 0, - 0, - 0, - 30537, - 0, - 0, - 30538, - 0, - 0, - 0, - 0, - 0, - 30553, - 0, - 0, - 30555, - 30556, - 30558, - 30559, - 30560, - 0, - 0, - 30561, - 0, - 30562, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30563, - 30570, - 30571, - 0, - 30586, - 30587, - 0, - 0, - 30590, - 0, - 0, - 30594, - 0, - 0, - 0, - 0, - 30611, - 30612, - 30623, - 30634, - 0, - 0, - 30636, - 30640, - 30655, - 30656, - 0, - 30657, - 0, - 0, - 30658, - 30669, - 0, - 30670, - 0, - 30676, - 30678, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30679, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30695, - 0, - 0, - 30698, - 0, - 0, - 0, - 0, - 30700, - 0, - 0, - 0, - 0, - 30701, - 0, - 30702, - 30703, - 0, - 0, - 0, - 0, - 30707, - 0, - 0, - 0, - 30709, - 0, - 0, - 30710, - 30719, - 30729, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30731, - 0, - 0, - 30733, - 0, - 0, - 0, - 30734, - 0, - 0, - 0, - 0, - 0, - 30736, - 30737, - 0, - 0, - 0, - 30740, - 0, - 0, - 0, - 30743, - 0, - 30746, - 0, - 30747, - 30748, - 0, - 0, - 30751, - 30752, - 30753, - 0, - 0, - 0, - 30754, - 0, - 0, - 30760, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30763, - 0, - 30764, - 0, - 0, - 30766, - 0, - 30769, - 30770, - 30771, - 30774, - 30777, - 0, - 0, - 30779, - 30780, - 30781, - 0, - 0, - 0, - 0, - 30790, - 0, - 0, - 0, - 30792, - 0, - 0, - 0, - 0, - 30810, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30812, - 30819, - 0, - 0, - 30823, - 30824, - 0, - 30825, - 0, - 30827, - 0, - 0, - 0, - 0, - 0, - 0, - 30828, - 0, - 0, - 30830, - 0, - 0, - 0, - 30834, - 0, - 30835, - 0, - 30837, - 30838, - 0, - 30845, - 0, - 0, - 0, - 0, - 0, - 30846, - 30847, - 0, - 0, - 30849, - 0, - 30851, - 0, - 0, - 0, - 0, - 0, - 30852, - 30858, - 0, - 0, - 30859, - 0, - 30865, - 0, - 0, - 30866, - 0, - 0, - 30868, - 0, - 0, - 30869, - 0, - 0, - 0, - 30881, - 30883, - 0, - 0, - 0, - 0, - 0, - 30889, - 0, - 30891, - 0, - 0, - 0, - 0, - 30894, - 0, - 30895, - 0, - 30897, - 0, - 30898, - 0, - 0, - 0, - 30904, - 30906, - 0, - 30909, - 0, - 0, - 0, - 0, - 0, - 0, - 30910, - 0, - 0, - 0, - 30915, - 30933, - 30942, - 0, - 0, - 0, - 0, - 30943, - 0, - 0, - 30945, - 0, - 0, - 0, - 0, - 0, - 0, - 30946, - 0, - 0, - 30947, - 0, - 0, - 30955, - 30956, - 0, - 0, - 30960, - 0, - 0, - 30961, - 30962, - 30966, - 0, - 0, - 30969, - 30974, - 0, - 0, - 0, - 30976, - 0, - 0, - 30977, - 0, - 30978, - 30982, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 30994, - 30995, - 30998, - 0, - 31000, - 0, - 0, - 31001, - 0, - 0, - 31003, - 31005, - 0, - 0, - 31006, - 31011, - 0, - 0, - 31014, - 0, - 31016, - 0, - 0, - 0, - 0, - 31018, - 0, - 0, - 31020, - 31023, - 31024, - 31025, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31027, - 31028, - 31029, - 0, - 0, - 0, - 0, - 0, - 0, - 31032, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31036, - 31037, - 31038, - 0, - 0, - 0, - 31041, - 31043, - 31045, - 0, - 31047, - 0, - 0, - 0, - 31048, - 0, - 31049, - 0, - 0, - 0, - 31053, - 31054, - 31055, - 0, - 0, - 31063, - 0, - 0, - 0, - 0, - 0, - 31066, - 0, - 31068, - 31071, - 0, - 0, - 0, - 31072, - 31073, - 0, - 0, - 0, - 0, - 31075, - 0, - 0, - 31076, - 0, - 0, - 0, - 31077, - 31079, - 0, - 31080, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31087, - 0, - 31142, - 0, - 31144, - 0, - 0, - 31145, - 31146, - 31147, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31149, - 0, - 31151, - 31152, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31162, - 31171, - 31174, - 31175, - 0, - 0, - 0, - 31176, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31179, - 0, - 0, - 0, - 31186, - 0, - 0, - 0, - 31192, - 31195, - 0, - 0, - 31196, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31198, - 0, - 0, - 0, - 0, - 0, - 31199, - 0, - 0, - 0, - 31205, - 0, - 0, - 0, - 0, - 31211, - 31215, - 0, - 0, - 0, - 0, - 31231, - 0, - 31232, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31233, - 31236, - 31253, - 0, - 31254, - 0, - 0, - 0, - 0, - 0, - 0, - 31255, - 0, - 0, - 31257, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31258, - 31259, - 0, - 0, - 31260, - 0, - 31261, - 0, - 0, - 0, - 0, - 0, - 31262, - 31263, - 0, - 0, - 31264, - 0, - 31266, - 0, - 31267, - 0, - 0, - 0, - 0, - 0, - 31281, - 0, - 31282, - 0, - 31284, - 0, - 0, - 31285, - 31287, - 31288, - 0, - 0, - 31290, - 0, - 0, - 0, - 31292, - 31295, - 0, - 31299, - 0, - 31300, - 0, - 0, - 0, - 0, - 0, - 31302, - 0, - 0, - 0, - 0, - 31303, - 0, - 0, - 0, - 0, - 0, - 0, - 31304, - 0, - 0, - 0, - 0, - 0, - 31305, - 31308, - 31309, - 31315, - 0, - 31317, - 0, - 0, - 0, - 0, - 0, - 31323, - 0, - 31324, - 0, - 0, - 0, - 0, - 0, - 31325, - 31327, - 0, - 0, - 31331, - 0, - 0, - 0, - 0, - 0, - 31333, - 0, - 0, - 0, - 0, - 0, - 31336, - 0, - 0, - 31337, - 0, - 0, - 0, - 0, - 0, - 0, - 31338, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31339, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31342, - 0, - 0, - 0, - 0, - 31345, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31347, - 0, - 0, - 0, - 0, - 0, - 0, - 31348, - 0, - 0, - 31350, - 31351, - 0, - 31352, - 0, - 0, - 31354, - 0, - 0, - 0, - 0, - 31355, - 0, - 0, - 31356, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31363, - 0, - 31372, - 0, - 0, - 31373, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31376, - 0, - 31388, - 0, - 31389, - 0, - 31392, - 0, - 31401, - 0, - 31405, - 31407, - 31408, - 0, - 31409, - 0, - 0, - 0, - 0, - 0, - 0, - 31413, - 31415, - 0, - 0, - 0, - 31416, - 31418, - 0, - 0, - 0, - 0, - 0, - 0, - 31422, - 31423, - 0, - 0, - 31424, - 0, - 31425, - 31432, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31433, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31434, - 0, - 0, - 0, - 0, - 0, - 0, - 31435, - 0, - 0, - 0, - 0, - 31438, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31442, - 0, - 31444, - 0, - 31448, - 0, - 0, - 31451, - 0, - 0, - 0, - 0, - 31452, - 0, - 31461, - 31465, - 0, - 0, - 31466, - 0, - 0, - 31467, - 0, - 0, - 31468, - 0, - 0, - 0, - 31469, - 31473, - 0, - 31476, - 0, - 0, - 0, - 0, - 31489, - 31490, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31492, - 31493, - 31494, - 0, - 0, - 0, - 0, - 31501, - 31504, - 31505, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31509, - 0, - 0, - 0, - 0, - 31510, - 0, - 0, - 31511, - 0, - 0, - 31513, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31514, - 0, - 31522, - 31536, - 31539, - 31540, - 0, - 31541, - 0, - 0, - 0, - 0, - 0, - 0, - 31546, - 31553, - 31559, - 0, - 0, - 0, - 31560, - 31561, - 31562, - 0, - 0, - 31564, - 31567, - 0, - 31569, - 0, - 0, - 0, - 31570, - 0, - 0, - 0, - 0, - 31571, - 0, - 0, - 0, - 0, - 0, - 0, - 31572, - 31574, - 31580, - 31581, - 0, - 0, - 31582, - 31584, - 31585, - 31586, - 31595, - 0, - 31596, - 0, - 0, - 0, - 0, - 31597, - 0, - 31599, - 0, - 31600, - 31601, - 0, - 0, - 31603, - 31604, - 0, - 0, - 31608, - 31610, - 0, - 0, - 0, - 31611, - 0, - 31615, - 0, - 0, - 0, - 0, - 31616, - 0, - 0, - 0, - 0, - 0, - 0, - 31617, - 0, - 0, - 0, - 0, - 0, - 31618, - 0, - 0, - 0, - 0, - 0, - 0, - 31621, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31622, - 31625, - 0, - 0, - 0, - 0, - 31627, - 0, - 31641, - 0, - 0, - 31642, - 0, - 0, - 31643, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31644, - 0, - 31646, - 0, - 0, - 0, - 0, - 31648, - 0, - 0, - 0, - 31652, - 0, - 0, - 0, - 31657, - 0, - 0, - 31676, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 31689, - 31691, - 31692, - 0, - 31694, - 0, - 0, - 0, - 31696, - 0, - 31702, - 0, - 31703, - 0, -} - -var kStaticDictionaryWords = [31705]dictWord{ - dictWord{0, 0, 0}, - dictWord{8, 0, 1002}, - dictWord{136, 0, 1015}, - dictWord{4, 0, 683}, - dictWord{4, 10, 325}, - dictWord{138, 10, 125}, - dictWord{7, 11, 572}, - dictWord{ - 9, - 11, - 592, - }, - dictWord{11, 11, 680}, - dictWord{11, 11, 842}, - dictWord{11, 11, 924}, - dictWord{12, 11, 356}, - dictWord{12, 11, 550}, - dictWord{13, 11, 317}, - dictWord{13, 11, 370}, - dictWord{13, 11, 469}, - dictWord{13, 11, 471}, - dictWord{14, 11, 397}, - dictWord{18, 11, 69}, - dictWord{146, 11, 145}, - dictWord{ - 134, - 0, - 1265, - }, - dictWord{136, 11, 534}, - dictWord{134, 0, 1431}, - dictWord{11, 0, 138}, - dictWord{140, 0, 40}, - dictWord{4, 0, 155}, - dictWord{7, 0, 1689}, - dictWord{ - 4, - 10, - 718, - }, - dictWord{135, 10, 1216}, - dictWord{4, 0, 245}, - dictWord{5, 0, 151}, - dictWord{5, 0, 741}, - dictWord{6, 0, 1147}, - dictWord{7, 0, 498}, - dictWord{7, 0, 870}, - dictWord{7, 0, 1542}, - dictWord{12, 0, 213}, - dictWord{14, 0, 36}, - dictWord{14, 0, 391}, - dictWord{17, 0, 111}, - dictWord{18, 0, 6}, - dictWord{18, 0, 46}, - dictWord{ - 18, - 0, - 151, - }, - dictWord{19, 0, 36}, - dictWord{20, 0, 32}, - dictWord{20, 0, 56}, - dictWord{20, 0, 69}, - dictWord{20, 0, 102}, - dictWord{21, 0, 4}, - dictWord{22, 0, 8}, - dictWord{ - 22, - 0, - 10, - }, - dictWord{22, 0, 14}, - dictWord{150, 0, 31}, - dictWord{4, 0, 624}, - dictWord{135, 0, 1752}, - dictWord{5, 10, 124}, - dictWord{5, 10, 144}, - dictWord{6, 10, 548}, - dictWord{7, 10, 15}, - dictWord{7, 10, 153}, - dictWord{137, 10, 629}, - dictWord{6, 0, 503}, - dictWord{9, 0, 586}, - dictWord{13, 0, 468}, - dictWord{14, 0, 66}, - dictWord{ - 16, - 0, - 58, - }, - dictWord{7, 10, 1531}, - dictWord{8, 10, 416}, - dictWord{9, 10, 275}, - dictWord{10, 10, 100}, - dictWord{11, 10, 658}, - dictWord{11, 10, 979}, - dictWord{ - 12, - 10, - 86, - }, - dictWord{14, 10, 207}, - dictWord{15, 10, 20}, - dictWord{143, 10, 25}, - dictWord{5, 0, 603}, - dictWord{7, 0, 1212}, - dictWord{9, 0, 565}, - dictWord{ - 14, - 0, - 301, - }, - dictWord{5, 10, 915}, - dictWord{6, 10, 1783}, - dictWord{7, 10, 211}, - dictWord{7, 10, 1353}, - dictWord{9, 10, 83}, - dictWord{10, 10, 376}, - dictWord{ - 10, - 10, - 431, - }, - dictWord{11, 10, 543}, - dictWord{12, 10, 664}, - dictWord{13, 10, 280}, - dictWord{13, 10, 428}, - dictWord{14, 10, 128}, - dictWord{17, 10, 52}, - dictWord{ - 145, - 10, - 81, - }, - dictWord{4, 0, 492}, - dictWord{133, 0, 451}, - dictWord{135, 0, 835}, - dictWord{141, 0, 70}, - dictWord{132, 0, 539}, - dictWord{7, 11, 748}, - dictWord{ - 139, - 11, - 700, - }, - dictWord{7, 11, 1517}, - dictWord{11, 11, 597}, - dictWord{14, 11, 76}, - dictWord{14, 11, 335}, - dictWord{148, 11, 33}, - dictWord{6, 0, 113}, - dictWord{135, 0, 436}, - dictWord{4, 10, 338}, - dictWord{133, 10, 400}, - dictWord{136, 0, 718}, - dictWord{133, 11, 127}, - dictWord{133, 11, 418}, - dictWord{ - 6, - 0, - 1505, - }, - dictWord{7, 0, 520}, - dictWord{6, 11, 198}, - dictWord{11, 10, 892}, - dictWord{140, 11, 83}, - dictWord{4, 10, 221}, - dictWord{5, 10, 659}, - dictWord{ - 5, - 10, - 989, - }, - dictWord{7, 10, 697}, - dictWord{7, 10, 1211}, - dictWord{138, 10, 284}, - dictWord{135, 0, 1070}, - dictWord{5, 11, 276}, - dictWord{6, 11, 55}, - dictWord{ - 135, - 11, - 1369, - }, - dictWord{134, 0, 1515}, - dictWord{6, 11, 1752}, - dictWord{136, 11, 726}, - dictWord{138, 10, 507}, - dictWord{15, 0, 78}, - dictWord{4, 10, 188}, - dictWord{135, 10, 805}, - dictWord{5, 10, 884}, - dictWord{139, 10, 991}, - dictWord{133, 11, 764}, - dictWord{134, 10, 1653}, - dictWord{6, 11, 309}, - dictWord{ - 7, - 11, - 331, - }, - dictWord{138, 11, 550}, - dictWord{135, 11, 1861}, - dictWord{132, 11, 348}, - dictWord{135, 11, 986}, - dictWord{135, 11, 1573}, - dictWord{ - 12, - 0, - 610, - }, - dictWord{13, 0, 431}, - dictWord{144, 0, 59}, - dictWord{9, 11, 799}, - dictWord{140, 10, 166}, - dictWord{134, 0, 1530}, - dictWord{132, 0, 750}, - dictWord{132, 0, 307}, - dictWord{133, 0, 964}, - dictWord{6, 11, 194}, - dictWord{7, 11, 133}, - dictWord{10, 11, 493}, - dictWord{10, 11, 570}, - dictWord{139, 11, 664}, - dictWord{5, 11, 24}, - dictWord{5, 11, 569}, - dictWord{6, 11, 3}, - dictWord{6, 11, 119}, - dictWord{6, 11, 143}, - dictWord{6, 11, 440}, - dictWord{7, 11, 295}, - dictWord{ - 7, - 11, - 599, - }, - dictWord{7, 11, 1686}, - dictWord{7, 11, 1854}, - dictWord{8, 11, 424}, - dictWord{9, 11, 43}, - dictWord{9, 11, 584}, - dictWord{9, 11, 760}, - dictWord{ - 10, - 11, - 148, - }, - dictWord{10, 11, 328}, - dictWord{11, 11, 159}, - dictWord{11, 11, 253}, - dictWord{11, 11, 506}, - dictWord{12, 11, 487}, - dictWord{12, 11, 531}, - dictWord{144, 11, 33}, - dictWord{136, 10, 760}, - dictWord{5, 11, 14}, - dictWord{5, 11, 892}, - dictWord{6, 11, 283}, - dictWord{7, 11, 234}, - dictWord{136, 11, 537}, - dictWord{135, 11, 1251}, - dictWord{4, 11, 126}, - dictWord{8, 11, 635}, - dictWord{147, 11, 34}, - dictWord{4, 11, 316}, - dictWord{135, 11, 1561}, - dictWord{ - 6, - 0, - 999, - }, - dictWord{6, 0, 1310}, - dictWord{137, 11, 861}, - dictWord{4, 11, 64}, - dictWord{5, 11, 352}, - dictWord{5, 11, 720}, - dictWord{6, 11, 368}, - dictWord{ - 139, - 11, - 359, - }, - dictWord{4, 0, 75}, - dictWord{5, 0, 180}, - dictWord{6, 0, 500}, - dictWord{7, 0, 58}, - dictWord{7, 0, 710}, - dictWord{10, 0, 645}, - dictWord{136, 10, 770}, - dictWord{133, 0, 649}, - dictWord{6, 0, 276}, - dictWord{7, 0, 282}, - dictWord{7, 0, 879}, - dictWord{7, 0, 924}, - dictWord{8, 0, 459}, - dictWord{9, 0, 599}, - dictWord{9, 0, 754}, - dictWord{11, 0, 574}, - dictWord{12, 0, 128}, - dictWord{12, 0, 494}, - dictWord{13, 0, 52}, - dictWord{13, 0, 301}, - dictWord{15, 0, 30}, - dictWord{143, 0, 132}, - dictWord{132, 0, 200}, - dictWord{4, 10, 89}, - dictWord{5, 10, 489}, - dictWord{6, 10, 315}, - dictWord{7, 10, 553}, - dictWord{7, 10, 1745}, - dictWord{138, 10, 243}, - dictWord{135, 11, 1050}, - dictWord{7, 0, 1621}, - dictWord{6, 10, 1658}, - dictWord{9, 10, 3}, - dictWord{10, 10, 154}, - dictWord{11, 10, 641}, - dictWord{13, 10, 85}, - dictWord{13, 10, 201}, - dictWord{141, 10, 346}, - dictWord{6, 11, 175}, - dictWord{137, 11, 289}, - dictWord{5, 11, 432}, - dictWord{133, 11, 913}, - dictWord{ - 6, - 0, - 225, - }, - dictWord{137, 0, 211}, - dictWord{7, 0, 718}, - dictWord{8, 0, 687}, - dictWord{139, 0, 374}, - dictWord{4, 10, 166}, - dictWord{133, 10, 505}, - dictWord{ - 9, - 0, - 110, - }, - dictWord{134, 10, 1670}, - dictWord{8, 0, 58}, - dictWord{9, 0, 724}, - dictWord{11, 0, 809}, - dictWord{13, 0, 113}, - dictWord{145, 0, 72}, - dictWord{6, 0, 345}, - dictWord{7, 0, 1247}, - dictWord{144, 11, 82}, - dictWord{5, 11, 931}, - dictWord{134, 11, 1698}, - dictWord{8, 0, 767}, - dictWord{8, 0, 803}, - dictWord{9, 0, 301}, - dictWord{137, 0, 903}, - dictWord{139, 0, 203}, - dictWord{134, 0, 1154}, - dictWord{7, 0, 1949}, - dictWord{136, 0, 674}, - dictWord{134, 0, 259}, - dictWord{ - 135, - 0, - 1275, - }, - dictWord{5, 11, 774}, - dictWord{6, 11, 1637}, - dictWord{6, 11, 1686}, - dictWord{134, 11, 1751}, - dictWord{134, 0, 1231}, - dictWord{7, 10, 445}, - dictWord{8, 10, 307}, - dictWord{8, 10, 704}, - dictWord{10, 10, 41}, - dictWord{10, 10, 439}, - dictWord{11, 10, 237}, - dictWord{11, 10, 622}, - dictWord{140, 10, 201}, - dictWord{136, 0, 254}, - dictWord{6, 11, 260}, - dictWord{135, 11, 1484}, - dictWord{139, 0, 277}, - dictWord{135, 10, 1977}, - dictWord{4, 10, 189}, - dictWord{ - 5, - 10, - 713, - }, - dictWord{6, 11, 573}, - dictWord{136, 10, 57}, - dictWord{138, 10, 371}, - dictWord{132, 10, 552}, - dictWord{134, 11, 344}, - dictWord{133, 0, 248}, - dictWord{9, 0, 800}, - dictWord{10, 0, 693}, - dictWord{11, 0, 482}, - dictWord{11, 0, 734}, - dictWord{11, 0, 789}, - dictWord{134, 11, 240}, - dictWord{4, 0, 116}, - dictWord{ - 5, - 0, - 95, - }, - dictWord{5, 0, 445}, - dictWord{7, 0, 1688}, - dictWord{8, 0, 29}, - dictWord{9, 0, 272}, - dictWord{11, 0, 509}, - dictWord{11, 0, 915}, - dictWord{4, 11, 292}, - dictWord{4, 11, 736}, - dictWord{5, 11, 871}, - dictWord{6, 11, 171}, - dictWord{6, 11, 1689}, - dictWord{7, 11, 1324}, - dictWord{7, 11, 1944}, - dictWord{9, 11, 415}, - dictWord{9, 11, 580}, - dictWord{14, 11, 230}, - dictWord{146, 11, 68}, - dictWord{7, 0, 490}, - dictWord{13, 0, 100}, - dictWord{143, 0, 75}, - dictWord{135, 0, 1641}, - dictWord{133, 0, 543}, - dictWord{7, 11, 209}, - dictWord{8, 11, 661}, - dictWord{10, 11, 42}, - dictWord{11, 11, 58}, - dictWord{12, 11, 58}, - dictWord{12, 11, 118}, - dictWord{141, 11, 32}, - dictWord{5, 0, 181}, - dictWord{8, 0, 41}, - dictWord{6, 11, 63}, - dictWord{135, 11, 920}, - dictWord{133, 0, 657}, - dictWord{133, 11, 793}, - dictWord{138, 0, 709}, - dictWord{7, 0, 25}, - dictWord{8, 0, 202}, - dictWord{138, 0, 536}, - dictWord{5, 11, 665}, - dictWord{135, 10, 1788}, - dictWord{145, 10, 49}, - dictWord{9, 0, 423}, - dictWord{140, 0, 89}, - dictWord{5, 11, 67}, - dictWord{6, 11, 62}, - dictWord{6, 11, 374}, - dictWord{135, 11, 1391}, - dictWord{8, 0, 113}, - dictWord{ - 9, - 0, - 877, - }, - dictWord{10, 0, 554}, - dictWord{11, 0, 83}, - dictWord{12, 0, 136}, - dictWord{19, 0, 109}, - dictWord{9, 11, 790}, - dictWord{140, 11, 47}, - dictWord{ - 138, - 10, - 661, - }, - dictWord{4, 0, 963}, - dictWord{10, 0, 927}, - dictWord{14, 0, 442}, - dictWord{135, 10, 1945}, - dictWord{133, 0, 976}, - dictWord{132, 0, 206}, - dictWord{ - 4, - 11, - 391, - }, - dictWord{135, 11, 1169}, - dictWord{134, 0, 2002}, - dictWord{6, 0, 696}, - dictWord{134, 0, 1008}, - dictWord{134, 0, 1170}, - dictWord{132, 11, 271}, - dictWord{7, 0, 13}, - dictWord{8, 0, 226}, - dictWord{10, 0, 537}, - dictWord{11, 0, 570}, - dictWord{11, 0, 605}, - dictWord{11, 0, 799}, - dictWord{11, 0, 804}, - dictWord{ - 12, - 0, - 85, - }, - dictWord{12, 0, 516}, - dictWord{12, 0, 623}, - dictWord{13, 0, 112}, - dictWord{13, 0, 361}, - dictWord{14, 0, 77}, - dictWord{14, 0, 78}, - dictWord{17, 0, 28}, - dictWord{19, 0, 110}, - dictWord{140, 11, 314}, - dictWord{132, 0, 769}, - dictWord{134, 0, 1544}, - dictWord{4, 0, 551}, - dictWord{137, 0, 678}, - dictWord{5, 10, 84}, - dictWord{134, 10, 163}, - dictWord{9, 0, 57}, - dictWord{9, 0, 459}, - dictWord{10, 0, 425}, - dictWord{11, 0, 119}, - dictWord{12, 0, 184}, - dictWord{12, 0, 371}, - dictWord{ - 13, - 0, - 358, - }, - dictWord{145, 0, 51}, - dictWord{5, 0, 188}, - dictWord{5, 0, 814}, - dictWord{8, 0, 10}, - dictWord{9, 0, 421}, - dictWord{9, 0, 729}, - dictWord{10, 0, 609}, - dictWord{11, 0, 689}, - dictWord{4, 11, 253}, - dictWord{5, 10, 410}, - dictWord{5, 11, 544}, - dictWord{7, 11, 300}, - dictWord{137, 11, 340}, - dictWord{134, 0, 624}, - dictWord{138, 11, 321}, - dictWord{135, 0, 1941}, - dictWord{18, 0, 130}, - dictWord{5, 10, 322}, - dictWord{8, 10, 186}, - dictWord{9, 10, 262}, - dictWord{10, 10, 187}, - dictWord{142, 10, 208}, - dictWord{5, 11, 53}, - dictWord{5, 11, 541}, - dictWord{6, 11, 94}, - dictWord{6, 11, 499}, - dictWord{7, 11, 230}, - dictWord{139, 11, 321}, - dictWord{133, 10, 227}, - dictWord{4, 0, 378}, - dictWord{4, 11, 920}, - dictWord{5, 11, 25}, - dictWord{5, 11, 790}, - dictWord{6, 11, 457}, - dictWord{135, 11, 853}, - dictWord{137, 0, 269}, - dictWord{132, 0, 528}, - dictWord{134, 0, 1146}, - dictWord{7, 10, 1395}, - dictWord{8, 10, 486}, - dictWord{9, 10, 236}, - dictWord{9, 10, 878}, - dictWord{10, 10, 218}, - dictWord{11, 10, 95}, - dictWord{19, 10, 17}, - dictWord{147, 10, 31}, - dictWord{7, 10, 2043}, - dictWord{8, 10, 672}, - dictWord{ - 141, - 10, - 448, - }, - dictWord{134, 0, 1105}, - dictWord{134, 0, 1616}, - dictWord{134, 11, 1765}, - dictWord{140, 11, 163}, - dictWord{5, 10, 412}, - dictWord{133, 11, 822}, - dictWord{132, 11, 634}, - dictWord{6, 0, 656}, - dictWord{134, 11, 1730}, - dictWord{134, 0, 1940}, - dictWord{5, 0, 104}, - dictWord{6, 0, 173}, - dictWord{ - 135, - 0, - 1631, - }, - dictWord{136, 10, 562}, - dictWord{6, 11, 36}, - dictWord{7, 11, 658}, - dictWord{8, 11, 454}, - dictWord{147, 11, 86}, - dictWord{5, 0, 457}, - dictWord{ - 134, - 10, - 1771, - }, - dictWord{7, 0, 810}, - dictWord{8, 0, 138}, - dictWord{8, 0, 342}, - dictWord{9, 0, 84}, - dictWord{10, 0, 193}, - dictWord{11, 0, 883}, - dictWord{140, 0, 359}, - dictWord{9, 0, 620}, - dictWord{135, 10, 1190}, - dictWord{137, 10, 132}, - dictWord{7, 11, 975}, - dictWord{137, 11, 789}, - dictWord{6, 0, 95}, - dictWord{6, 0, 1934}, - dictWord{136, 0, 967}, - dictWord{141, 11, 335}, - dictWord{6, 0, 406}, - dictWord{10, 0, 409}, - dictWord{10, 0, 447}, - dictWord{11, 0, 44}, - dictWord{140, 0, 100}, - dictWord{4, 10, 317}, - dictWord{135, 10, 1279}, - dictWord{132, 0, 477}, - dictWord{134, 0, 1268}, - dictWord{6, 0, 1941}, - dictWord{8, 0, 944}, - dictWord{5, 10, 63}, - dictWord{133, 10, 509}, - dictWord{132, 0, 629}, - dictWord{132, 11, 104}, - dictWord{4, 0, 246}, - dictWord{133, 0, 375}, - dictWord{6, 0, 1636}, - dictWord{ - 132, - 10, - 288, - }, - dictWord{135, 11, 1614}, - dictWord{9, 0, 49}, - dictWord{10, 0, 774}, - dictWord{8, 10, 89}, - dictWord{8, 10, 620}, - dictWord{11, 10, 628}, - dictWord{ - 12, - 10, - 322, - }, - dictWord{143, 10, 124}, - dictWord{4, 0, 282}, - dictWord{7, 0, 1034}, - dictWord{11, 0, 398}, - dictWord{11, 0, 634}, - dictWord{12, 0, 1}, - dictWord{12, 0, 79}, - dictWord{12, 0, 544}, - dictWord{14, 0, 237}, - dictWord{17, 0, 10}, - dictWord{146, 0, 20}, - dictWord{132, 0, 824}, - dictWord{7, 11, 45}, - dictWord{9, 11, 542}, - dictWord{ - 9, - 11, - 566, - }, - dictWord{138, 11, 728}, - dictWord{5, 0, 118}, - dictWord{5, 0, 499}, - dictWord{6, 0, 476}, - dictWord{6, 0, 665}, - dictWord{6, 0, 1176}, - dictWord{ - 6, - 0, - 1196, - }, - dictWord{7, 0, 600}, - dictWord{7, 0, 888}, - dictWord{135, 0, 1096}, - dictWord{7, 0, 296}, - dictWord{7, 0, 596}, - dictWord{8, 0, 560}, - dictWord{8, 0, 586}, - dictWord{9, 0, 612}, - dictWord{11, 0, 304}, - dictWord{12, 0, 46}, - dictWord{13, 0, 89}, - dictWord{14, 0, 112}, - dictWord{145, 0, 122}, - dictWord{5, 0, 894}, - dictWord{ - 6, - 0, - 1772, - }, - dictWord{9, 0, 1009}, - dictWord{138, 10, 120}, - dictWord{5, 11, 533}, - dictWord{7, 11, 755}, - dictWord{138, 11, 780}, - dictWord{151, 10, 1}, - dictWord{ - 6, - 0, - 1474, - }, - dictWord{7, 11, 87}, - dictWord{142, 11, 288}, - dictWord{139, 0, 366}, - dictWord{137, 10, 461}, - dictWord{7, 11, 988}, - dictWord{7, 11, 1939}, - dictWord{ - 9, - 11, - 64, - }, - dictWord{9, 11, 502}, - dictWord{12, 11, 7}, - dictWord{12, 11, 34}, - dictWord{13, 11, 12}, - dictWord{13, 11, 234}, - dictWord{147, 11, 77}, - dictWord{ - 7, - 0, - 1599, - }, - dictWord{7, 0, 1723}, - dictWord{8, 0, 79}, - dictWord{8, 0, 106}, - dictWord{8, 0, 190}, - dictWord{8, 0, 302}, - dictWord{8, 0, 383}, - dictWord{8, 0, 713}, - dictWord{ - 9, - 0, - 119, - }, - dictWord{9, 0, 233}, - dictWord{9, 0, 419}, - dictWord{9, 0, 471}, - dictWord{10, 0, 181}, - dictWord{10, 0, 406}, - dictWord{11, 0, 57}, - dictWord{11, 0, 85}, - dictWord{11, 0, 120}, - dictWord{11, 0, 177}, - dictWord{11, 0, 296}, - dictWord{11, 0, 382}, - dictWord{11, 0, 454}, - dictWord{11, 0, 758}, - dictWord{11, 0, 999}, - dictWord{ - 12, - 0, - 27, - }, - dictWord{12, 0, 98}, - dictWord{12, 0, 131}, - dictWord{12, 0, 245}, - dictWord{12, 0, 312}, - dictWord{12, 0, 446}, - dictWord{12, 0, 454}, - dictWord{13, 0, 25}, - dictWord{13, 0, 98}, - dictWord{13, 0, 426}, - dictWord{13, 0, 508}, - dictWord{14, 0, 70}, - dictWord{14, 0, 163}, - dictWord{14, 0, 272}, - dictWord{14, 0, 277}, - dictWord{ - 14, - 0, - 370, - }, - dictWord{15, 0, 95}, - dictWord{15, 0, 138}, - dictWord{15, 0, 167}, - dictWord{17, 0, 38}, - dictWord{148, 0, 96}, - dictWord{135, 10, 1346}, - dictWord{ - 10, - 0, - 200, - }, - dictWord{19, 0, 2}, - dictWord{151, 0, 22}, - dictWord{135, 11, 141}, - dictWord{134, 10, 85}, - dictWord{134, 0, 1759}, - dictWord{138, 0, 372}, - dictWord{ - 145, - 0, - 16, - }, - dictWord{8, 0, 943}, - dictWord{132, 11, 619}, - dictWord{139, 11, 88}, - dictWord{5, 11, 246}, - dictWord{8, 11, 189}, - dictWord{9, 11, 355}, - dictWord{ - 9, - 11, - 512, - }, - dictWord{10, 11, 124}, - dictWord{10, 11, 453}, - dictWord{11, 11, 143}, - dictWord{11, 11, 416}, - dictWord{11, 11, 859}, - dictWord{141, 11, 341}, - dictWord{ - 5, - 0, - 258, - }, - dictWord{134, 0, 719}, - dictWord{6, 0, 1798}, - dictWord{6, 0, 1839}, - dictWord{8, 0, 900}, - dictWord{10, 0, 874}, - dictWord{10, 0, 886}, - dictWord{ - 12, - 0, - 698, - }, - dictWord{12, 0, 732}, - dictWord{12, 0, 770}, - dictWord{16, 0, 106}, - dictWord{18, 0, 163}, - dictWord{18, 0, 170}, - dictWord{18, 0, 171}, - dictWord{152, 0, 20}, - dictWord{9, 0, 707}, - dictWord{11, 0, 326}, - dictWord{11, 0, 339}, - dictWord{12, 0, 423}, - dictWord{12, 0, 502}, - dictWord{20, 0, 62}, - dictWord{9, 11, 707}, - dictWord{ - 11, - 11, - 326, - }, - dictWord{11, 11, 339}, - dictWord{12, 11, 423}, - dictWord{12, 11, 502}, - dictWord{148, 11, 62}, - dictWord{5, 0, 30}, - dictWord{7, 0, 495}, - dictWord{ - 8, - 0, - 134, - }, - dictWord{9, 0, 788}, - dictWord{140, 0, 438}, - dictWord{133, 11, 678}, - dictWord{5, 10, 279}, - dictWord{6, 10, 235}, - dictWord{7, 10, 468}, - dictWord{ - 8, - 10, - 446, - }, - dictWord{9, 10, 637}, - dictWord{10, 10, 717}, - dictWord{11, 10, 738}, - dictWord{140, 10, 514}, - dictWord{5, 11, 35}, - dictWord{6, 11, 287}, - dictWord{ - 7, - 11, - 862, - }, - dictWord{7, 11, 1886}, - dictWord{138, 11, 179}, - dictWord{7, 0, 1948}, - dictWord{7, 0, 2004}, - dictWord{132, 11, 517}, - dictWord{5, 10, 17}, - dictWord{ - 6, - 10, - 371, - }, - dictWord{137, 10, 528}, - dictWord{4, 0, 115}, - dictWord{5, 0, 669}, - dictWord{6, 0, 407}, - dictWord{8, 0, 311}, - dictWord{11, 0, 10}, - dictWord{141, 0, 5}, - dictWord{137, 0, 381}, - dictWord{5, 0, 50}, - dictWord{6, 0, 439}, - dictWord{7, 0, 780}, - dictWord{135, 0, 1040}, - dictWord{136, 11, 667}, - dictWord{11, 11, 403}, - dictWord{146, 11, 83}, - dictWord{5, 0, 1}, - dictWord{6, 0, 81}, - dictWord{138, 0, 520}, - dictWord{134, 0, 738}, - dictWord{5, 0, 482}, - dictWord{8, 0, 98}, - dictWord{9, 0, 172}, - dictWord{10, 0, 360}, - dictWord{10, 0, 700}, - dictWord{10, 0, 822}, - dictWord{11, 0, 302}, - dictWord{11, 0, 778}, - dictWord{12, 0, 50}, - dictWord{12, 0, 127}, - dictWord{ - 12, - 0, - 396, - }, - dictWord{13, 0, 62}, - dictWord{13, 0, 328}, - dictWord{14, 0, 122}, - dictWord{147, 0, 72}, - dictWord{9, 11, 157}, - dictWord{10, 11, 131}, - dictWord{ - 140, - 11, - 72, - }, - dictWord{135, 11, 714}, - dictWord{135, 11, 539}, - dictWord{5, 0, 2}, - dictWord{6, 0, 512}, - dictWord{7, 0, 797}, - dictWord{7, 0, 1494}, - dictWord{8, 0, 253}, - dictWord{8, 0, 589}, - dictWord{9, 0, 77}, - dictWord{10, 0, 1}, - dictWord{10, 0, 129}, - dictWord{10, 0, 225}, - dictWord{11, 0, 118}, - dictWord{11, 0, 226}, - dictWord{ - 11, - 0, - 251, - }, - dictWord{11, 0, 430}, - dictWord{11, 0, 701}, - dictWord{11, 0, 974}, - dictWord{11, 0, 982}, - dictWord{12, 0, 64}, - dictWord{12, 0, 260}, - dictWord{12, 0, 488}, - dictWord{140, 0, 690}, - dictWord{5, 11, 394}, - dictWord{7, 11, 367}, - dictWord{7, 11, 487}, - dictWord{7, 11, 857}, - dictWord{7, 11, 1713}, - dictWord{8, 11, 246}, - dictWord{9, 11, 537}, - dictWord{10, 11, 165}, - dictWord{12, 11, 219}, - dictWord{140, 11, 561}, - dictWord{136, 0, 557}, - dictWord{5, 10, 779}, - dictWord{5, 10, 807}, - dictWord{6, 10, 1655}, - dictWord{134, 10, 1676}, - dictWord{4, 10, 196}, - dictWord{5, 10, 558}, - dictWord{133, 10, 949}, - dictWord{11, 11, 827}, - dictWord{ - 12, - 11, - 56, - }, - dictWord{14, 11, 34}, - dictWord{143, 11, 148}, - dictWord{137, 0, 347}, - dictWord{133, 0, 572}, - dictWord{134, 0, 832}, - dictWord{4, 0, 12}, - dictWord{ - 7, - 0, - 504, - }, - dictWord{7, 0, 522}, - dictWord{7, 0, 809}, - dictWord{8, 0, 797}, - dictWord{141, 0, 88}, - dictWord{4, 10, 752}, - dictWord{133, 11, 449}, - dictWord{7, 11, 86}, - dictWord{8, 11, 103}, - dictWord{145, 11, 69}, - dictWord{7, 11, 2028}, - dictWord{138, 11, 641}, - dictWord{5, 0, 528}, - dictWord{6, 11, 1}, - dictWord{142, 11, 2}, - dictWord{134, 0, 861}, - dictWord{10, 0, 294}, - dictWord{4, 10, 227}, - dictWord{5, 10, 159}, - dictWord{5, 10, 409}, - dictWord{7, 10, 80}, - dictWord{10, 10, 479}, - dictWord{ - 12, - 10, - 418, - }, - dictWord{14, 10, 50}, - dictWord{14, 10, 249}, - dictWord{142, 10, 295}, - dictWord{7, 10, 1470}, - dictWord{8, 10, 66}, - dictWord{8, 10, 137}, - dictWord{ - 8, - 10, - 761, - }, - dictWord{9, 10, 638}, - dictWord{11, 10, 80}, - dictWord{11, 10, 212}, - dictWord{11, 10, 368}, - dictWord{11, 10, 418}, - dictWord{12, 10, 8}, - dictWord{ - 13, - 10, - 15, - }, - dictWord{16, 10, 61}, - dictWord{17, 10, 59}, - dictWord{19, 10, 28}, - dictWord{148, 10, 84}, - dictWord{20, 0, 109}, - dictWord{135, 11, 1148}, - dictWord{ - 6, - 11, - 277, - }, - dictWord{7, 11, 1274}, - dictWord{7, 11, 1386}, - dictWord{7, 11, 1392}, - dictWord{12, 11, 129}, - dictWord{146, 11, 87}, - dictWord{6, 11, 187}, - dictWord{7, 11, 39}, - dictWord{7, 11, 1203}, - dictWord{8, 11, 380}, - dictWord{8, 11, 542}, - dictWord{14, 11, 117}, - dictWord{149, 11, 28}, - dictWord{134, 0, 1187}, - dictWord{5, 0, 266}, - dictWord{9, 0, 290}, - dictWord{9, 0, 364}, - dictWord{10, 0, 293}, - dictWord{11, 0, 606}, - dictWord{142, 0, 45}, - dictWord{6, 11, 297}, - dictWord{ - 7, - 11, - 793, - }, - dictWord{139, 11, 938}, - dictWord{4, 0, 50}, - dictWord{6, 0, 594}, - dictWord{9, 0, 121}, - dictWord{10, 0, 49}, - dictWord{10, 0, 412}, - dictWord{139, 0, 834}, - dictWord{136, 0, 748}, - dictWord{7, 11, 464}, - dictWord{8, 11, 438}, - dictWord{11, 11, 105}, - dictWord{11, 11, 363}, - dictWord{12, 11, 231}, - dictWord{ - 14, - 11, - 386, - }, - dictWord{15, 11, 102}, - dictWord{148, 11, 75}, - dictWord{132, 0, 466}, - dictWord{13, 0, 399}, - dictWord{14, 0, 337}, - dictWord{6, 10, 38}, - dictWord{ - 7, - 10, - 1220, - }, - dictWord{8, 10, 185}, - dictWord{8, 10, 256}, - dictWord{9, 10, 22}, - dictWord{9, 10, 331}, - dictWord{10, 10, 738}, - dictWord{11, 10, 205}, - dictWord{ - 11, - 10, - 540, - }, - dictWord{11, 10, 746}, - dictWord{13, 10, 465}, - dictWord{142, 10, 194}, - dictWord{9, 0, 378}, - dictWord{141, 0, 162}, - dictWord{137, 0, 519}, - dictWord{ - 4, - 10, - 159, - }, - dictWord{6, 10, 115}, - dictWord{7, 10, 252}, - dictWord{7, 10, 257}, - dictWord{7, 10, 1928}, - dictWord{8, 10, 69}, - dictWord{9, 10, 384}, - dictWord{ - 10, - 10, - 91, - }, - dictWord{10, 10, 615}, - dictWord{12, 10, 375}, - dictWord{14, 10, 235}, - dictWord{18, 10, 117}, - dictWord{147, 10, 123}, - dictWord{5, 11, 604}, - dictWord{ - 5, - 10, - 911, - }, - dictWord{136, 10, 278}, - dictWord{132, 0, 667}, - dictWord{8, 0, 351}, - dictWord{9, 0, 322}, - dictWord{4, 10, 151}, - dictWord{135, 10, 1567}, - dictWord{134, 0, 902}, - dictWord{133, 10, 990}, - dictWord{12, 0, 180}, - dictWord{5, 10, 194}, - dictWord{7, 10, 1662}, - dictWord{137, 10, 90}, - dictWord{4, 0, 869}, - dictWord{134, 0, 1996}, - dictWord{134, 0, 813}, - dictWord{133, 10, 425}, - dictWord{137, 11, 761}, - dictWord{132, 0, 260}, - dictWord{133, 10, 971}, - dictWord{ - 5, - 11, - 20, - }, - dictWord{6, 11, 298}, - dictWord{7, 11, 659}, - dictWord{7, 11, 1366}, - dictWord{137, 11, 219}, - dictWord{4, 0, 39}, - dictWord{5, 0, 36}, - dictWord{ - 7, - 0, - 1843, - }, - dictWord{8, 0, 407}, - dictWord{11, 0, 144}, - dictWord{140, 0, 523}, - dictWord{4, 0, 510}, - dictWord{10, 0, 587}, - dictWord{139, 10, 752}, - dictWord{7, 0, 29}, - dictWord{7, 0, 66}, - dictWord{7, 0, 1980}, - dictWord{10, 0, 487}, - dictWord{138, 0, 809}, - dictWord{13, 0, 260}, - dictWord{14, 0, 82}, - dictWord{18, 0, 63}, - dictWord{ - 137, - 10, - 662, - }, - dictWord{5, 10, 72}, - dictWord{6, 10, 264}, - dictWord{7, 10, 21}, - dictWord{7, 10, 46}, - dictWord{7, 10, 2013}, - dictWord{8, 10, 215}, - dictWord{ - 8, - 10, - 513, - }, - dictWord{10, 10, 266}, - dictWord{139, 10, 22}, - dictWord{134, 0, 570}, - dictWord{6, 0, 565}, - dictWord{7, 0, 1667}, - dictWord{4, 11, 439}, - dictWord{ - 10, - 10, - 95, - }, - dictWord{11, 10, 603}, - dictWord{12, 11, 242}, - dictWord{13, 10, 443}, - dictWord{14, 10, 160}, - dictWord{143, 10, 4}, - dictWord{134, 0, 1464}, - dictWord{ - 134, - 10, - 431, - }, - dictWord{9, 0, 372}, - dictWord{15, 0, 2}, - dictWord{19, 0, 10}, - dictWord{19, 0, 18}, - dictWord{5, 10, 874}, - dictWord{6, 10, 1677}, - dictWord{143, 10, 0}, - dictWord{132, 0, 787}, - dictWord{6, 0, 380}, - dictWord{12, 0, 399}, - dictWord{21, 0, 19}, - dictWord{7, 10, 939}, - dictWord{7, 10, 1172}, - dictWord{7, 10, 1671}, - dictWord{9, 10, 540}, - dictWord{10, 10, 696}, - dictWord{11, 10, 265}, - dictWord{11, 10, 732}, - dictWord{11, 10, 928}, - dictWord{11, 10, 937}, - dictWord{ - 141, - 10, - 438, - }, - dictWord{137, 0, 200}, - dictWord{132, 11, 233}, - dictWord{132, 0, 516}, - dictWord{134, 11, 577}, - dictWord{132, 0, 844}, - dictWord{11, 0, 887}, - dictWord{14, 0, 365}, - dictWord{142, 0, 375}, - dictWord{132, 11, 482}, - dictWord{8, 0, 821}, - dictWord{140, 0, 44}, - dictWord{7, 0, 1655}, - dictWord{136, 0, 305}, - dictWord{5, 10, 682}, - dictWord{135, 10, 1887}, - dictWord{135, 11, 346}, - dictWord{132, 10, 696}, - dictWord{4, 0, 10}, - dictWord{7, 0, 917}, - dictWord{139, 0, 786}, - dictWord{5, 11, 795}, - dictWord{6, 11, 1741}, - dictWord{8, 11, 417}, - dictWord{137, 11, 782}, - dictWord{4, 0, 1016}, - dictWord{134, 0, 2031}, - dictWord{5, 0, 684}, - dictWord{4, 10, 726}, - dictWord{133, 10, 630}, - dictWord{6, 0, 1021}, - dictWord{134, 0, 1480}, - dictWord{8, 10, 802}, - dictWord{136, 10, 838}, - dictWord{ - 134, - 0, - 27, - }, - dictWord{134, 0, 395}, - dictWord{135, 11, 622}, - dictWord{7, 11, 625}, - dictWord{135, 11, 1750}, - dictWord{4, 11, 203}, - dictWord{135, 11, 1936}, - dictWord{6, 10, 118}, - dictWord{7, 10, 215}, - dictWord{7, 10, 1521}, - dictWord{140, 10, 11}, - dictWord{132, 0, 813}, - dictWord{136, 0, 511}, - dictWord{7, 10, 615}, - dictWord{138, 10, 251}, - dictWord{135, 10, 1044}, - dictWord{145, 0, 56}, - dictWord{133, 10, 225}, - dictWord{6, 0, 342}, - dictWord{6, 0, 496}, - dictWord{8, 0, 275}, - dictWord{137, 0, 206}, - dictWord{4, 0, 909}, - dictWord{133, 0, 940}, - dictWord{132, 0, 891}, - dictWord{7, 11, 311}, - dictWord{9, 11, 308}, - dictWord{ - 140, - 11, - 255, - }, - dictWord{4, 10, 370}, - dictWord{5, 10, 756}, - dictWord{135, 10, 1326}, - dictWord{4, 0, 687}, - dictWord{134, 0, 1596}, - dictWord{134, 0, 1342}, - dictWord{ - 6, - 10, - 1662, - }, - dictWord{7, 10, 48}, - dictWord{8, 10, 771}, - dictWord{10, 10, 116}, - dictWord{13, 10, 104}, - dictWord{14, 10, 105}, - dictWord{14, 10, 184}, - dictWord{15, 10, 168}, - dictWord{19, 10, 92}, - dictWord{148, 10, 68}, - dictWord{138, 10, 209}, - dictWord{4, 11, 400}, - dictWord{5, 11, 267}, - dictWord{135, 11, 232}, - dictWord{151, 11, 12}, - dictWord{6, 0, 41}, - dictWord{141, 0, 160}, - dictWord{141, 11, 314}, - dictWord{134, 0, 1718}, - dictWord{136, 0, 778}, - dictWord{ - 142, - 11, - 261, - }, - dictWord{134, 0, 1610}, - dictWord{133, 0, 115}, - dictWord{132, 0, 294}, - dictWord{14, 0, 314}, - dictWord{132, 10, 120}, - dictWord{132, 0, 983}, - dictWord{5, 0, 193}, - dictWord{140, 0, 178}, - dictWord{138, 10, 429}, - dictWord{5, 10, 820}, - dictWord{135, 10, 931}, - dictWord{6, 0, 994}, - dictWord{6, 0, 1051}, - dictWord{6, 0, 1439}, - dictWord{7, 0, 174}, - dictWord{133, 11, 732}, - dictWord{4, 11, 100}, - dictWord{7, 11, 679}, - dictWord{8, 11, 313}, - dictWord{138, 10, 199}, - dictWord{6, 10, 151}, - dictWord{6, 10, 1675}, - dictWord{7, 10, 383}, - dictWord{151, 10, 10}, - dictWord{6, 0, 1796}, - dictWord{8, 0, 848}, - dictWord{8, 0, 867}, - dictWord{ - 8, - 0, - 907, - }, - dictWord{10, 0, 855}, - dictWord{140, 0, 703}, - dictWord{140, 0, 221}, - dictWord{4, 0, 122}, - dictWord{5, 0, 796}, - dictWord{5, 0, 952}, - dictWord{6, 0, 1660}, - dictWord{6, 0, 1671}, - dictWord{8, 0, 567}, - dictWord{9, 0, 687}, - dictWord{9, 0, 742}, - dictWord{10, 0, 686}, - dictWord{11, 0, 682}, - dictWord{11, 0, 909}, - dictWord{ - 140, - 0, - 281, - }, - dictWord{5, 11, 362}, - dictWord{5, 11, 443}, - dictWord{6, 11, 318}, - dictWord{7, 11, 1019}, - dictWord{139, 11, 623}, - dictWord{5, 11, 463}, - dictWord{136, 11, 296}, - dictWord{11, 0, 583}, - dictWord{13, 0, 262}, - dictWord{6, 10, 1624}, - dictWord{12, 10, 422}, - dictWord{142, 10, 360}, - dictWord{5, 0, 179}, - dictWord{7, 0, 1095}, - dictWord{135, 0, 1213}, - dictWord{4, 10, 43}, - dictWord{4, 11, 454}, - dictWord{5, 10, 344}, - dictWord{133, 10, 357}, - dictWord{4, 0, 66}, - dictWord{7, 0, 722}, - dictWord{135, 0, 904}, - dictWord{134, 0, 773}, - dictWord{7, 0, 352}, - dictWord{133, 10, 888}, - dictWord{5, 11, 48}, - dictWord{5, 11, 404}, - dictWord{ - 6, - 11, - 557, - }, - dictWord{7, 11, 458}, - dictWord{8, 11, 597}, - dictWord{10, 11, 455}, - dictWord{10, 11, 606}, - dictWord{11, 11, 49}, - dictWord{11, 11, 548}, - dictWord{ - 12, - 11, - 476, - }, - dictWord{13, 11, 18}, - dictWord{141, 11, 450}, - dictWord{134, 11, 418}, - dictWord{132, 10, 711}, - dictWord{5, 11, 442}, - dictWord{ - 135, - 11, - 1984, - }, - dictWord{141, 0, 35}, - dictWord{137, 0, 152}, - dictWord{134, 0, 1197}, - dictWord{135, 11, 1093}, - dictWord{137, 11, 203}, - dictWord{137, 10, 440}, - dictWord{10, 0, 592}, - dictWord{10, 0, 753}, - dictWord{12, 0, 317}, - dictWord{12, 0, 355}, - dictWord{12, 0, 465}, - dictWord{12, 0, 469}, - dictWord{12, 0, 560}, - dictWord{12, 0, 578}, - dictWord{141, 0, 243}, - dictWord{133, 0, 564}, - dictWord{134, 0, 797}, - dictWord{5, 10, 958}, - dictWord{133, 10, 987}, - dictWord{5, 11, 55}, - dictWord{7, 11, 376}, - dictWord{140, 11, 161}, - dictWord{133, 11, 450}, - dictWord{134, 0, 556}, - dictWord{134, 0, 819}, - dictWord{11, 10, 276}, - dictWord{ - 142, - 10, - 293, - }, - dictWord{7, 0, 544}, - dictWord{138, 0, 61}, - dictWord{8, 0, 719}, - dictWord{4, 10, 65}, - dictWord{5, 10, 479}, - dictWord{5, 10, 1004}, - dictWord{7, 10, 1913}, - dictWord{8, 10, 317}, - dictWord{9, 10, 302}, - dictWord{10, 10, 612}, - dictWord{141, 10, 22}, - dictWord{4, 0, 5}, - dictWord{5, 0, 498}, - dictWord{8, 0, 637}, - dictWord{ - 9, - 0, - 521, - }, - dictWord{4, 11, 213}, - dictWord{4, 10, 261}, - dictWord{7, 11, 223}, - dictWord{7, 10, 510}, - dictWord{136, 11, 80}, - dictWord{5, 0, 927}, - dictWord{7, 0, 101}, - dictWord{4, 10, 291}, - dictWord{7, 11, 381}, - dictWord{7, 11, 806}, - dictWord{7, 11, 820}, - dictWord{8, 11, 354}, - dictWord{8, 11, 437}, - dictWord{8, 11, 787}, - dictWord{9, 10, 515}, - dictWord{9, 11, 657}, - dictWord{10, 11, 58}, - dictWord{10, 11, 339}, - dictWord{10, 11, 749}, - dictWord{11, 11, 914}, - dictWord{12, 10, 152}, - dictWord{12, 11, 162}, - dictWord{12, 10, 443}, - dictWord{13, 11, 75}, - dictWord{13, 10, 392}, - dictWord{14, 11, 106}, - dictWord{14, 11, 198}, - dictWord{ - 14, - 11, - 320, - }, - dictWord{14, 10, 357}, - dictWord{14, 11, 413}, - dictWord{146, 11, 43}, - dictWord{6, 0, 1153}, - dictWord{7, 0, 1441}, - dictWord{136, 11, 747}, - dictWord{ - 4, - 0, - 893, - }, - dictWord{5, 0, 780}, - dictWord{133, 0, 893}, - dictWord{138, 11, 654}, - dictWord{133, 11, 692}, - dictWord{133, 0, 238}, - dictWord{134, 11, 191}, - dictWord{4, 10, 130}, - dictWord{135, 10, 843}, - dictWord{6, 0, 1296}, - dictWord{5, 10, 42}, - dictWord{5, 10, 879}, - dictWord{7, 10, 245}, - dictWord{7, 10, 324}, - dictWord{ - 7, - 10, - 1532, - }, - dictWord{11, 10, 463}, - dictWord{11, 10, 472}, - dictWord{13, 10, 363}, - dictWord{144, 10, 52}, - dictWord{134, 0, 1729}, - dictWord{6, 0, 1999}, - dictWord{136, 0, 969}, - dictWord{4, 10, 134}, - dictWord{133, 10, 372}, - dictWord{4, 0, 60}, - dictWord{7, 0, 941}, - dictWord{7, 0, 1800}, - dictWord{8, 0, 314}, - dictWord{ - 9, - 0, - 700, - }, - dictWord{139, 0, 487}, - dictWord{134, 0, 1144}, - dictWord{6, 11, 162}, - dictWord{7, 11, 1960}, - dictWord{136, 11, 831}, - dictWord{132, 11, 706}, - dictWord{135, 0, 1147}, - dictWord{138, 11, 426}, - dictWord{138, 11, 89}, - dictWord{7, 0, 1853}, - dictWord{138, 0, 437}, - dictWord{136, 0, 419}, - dictWord{ - 135, - 10, - 1634, - }, - dictWord{133, 0, 828}, - dictWord{5, 0, 806}, - dictWord{7, 0, 176}, - dictWord{7, 0, 178}, - dictWord{7, 0, 1240}, - dictWord{7, 0, 1976}, - dictWord{ - 132, - 10, - 644, - }, - dictWord{135, 11, 1877}, - dictWord{5, 11, 420}, - dictWord{135, 11, 1449}, - dictWord{4, 0, 51}, - dictWord{5, 0, 39}, - dictWord{6, 0, 4}, - dictWord{7, 0, 591}, - dictWord{7, 0, 849}, - dictWord{7, 0, 951}, - dictWord{7, 0, 1613}, - dictWord{7, 0, 1760}, - dictWord{7, 0, 1988}, - dictWord{9, 0, 434}, - dictWord{10, 0, 754}, - dictWord{ - 11, - 0, - 25, - }, - dictWord{139, 0, 37}, - dictWord{10, 11, 57}, - dictWord{138, 11, 277}, - dictWord{135, 10, 540}, - dictWord{132, 11, 204}, - dictWord{135, 0, 159}, - dictWord{139, 11, 231}, - dictWord{133, 0, 902}, - dictWord{7, 0, 928}, - dictWord{7, 11, 366}, - dictWord{9, 11, 287}, - dictWord{12, 11, 199}, - dictWord{12, 11, 556}, - dictWord{140, 11, 577}, - dictWord{6, 10, 623}, - dictWord{136, 10, 789}, - dictWord{4, 10, 908}, - dictWord{5, 10, 359}, - dictWord{5, 10, 508}, - dictWord{6, 10, 1723}, - dictWord{7, 10, 343}, - dictWord{7, 10, 1996}, - dictWord{135, 10, 2026}, - dictWord{134, 0, 270}, - dictWord{4, 10, 341}, - dictWord{135, 10, 480}, - dictWord{ - 5, - 11, - 356, - }, - dictWord{135, 11, 224}, - dictWord{11, 11, 588}, - dictWord{11, 11, 864}, - dictWord{11, 11, 968}, - dictWord{143, 11, 160}, - dictWord{132, 0, 556}, - dictWord{137, 0, 801}, - dictWord{132, 0, 416}, - dictWord{142, 0, 372}, - dictWord{5, 0, 152}, - dictWord{5, 0, 197}, - dictWord{7, 0, 340}, - dictWord{7, 0, 867}, - dictWord{ - 10, - 0, - 548, - }, - dictWord{10, 0, 581}, - dictWord{11, 0, 6}, - dictWord{12, 0, 3}, - dictWord{12, 0, 19}, - dictWord{14, 0, 110}, - dictWord{142, 0, 289}, - dictWord{139, 0, 369}, - dictWord{7, 11, 630}, - dictWord{9, 11, 567}, - dictWord{11, 11, 150}, - dictWord{11, 11, 444}, - dictWord{141, 11, 119}, - dictWord{134, 11, 539}, - dictWord{ - 7, - 10, - 1995, - }, - dictWord{8, 10, 299}, - dictWord{11, 10, 890}, - dictWord{140, 10, 674}, - dictWord{7, 0, 34}, - dictWord{7, 0, 190}, - dictWord{8, 0, 28}, - dictWord{8, 0, 141}, - dictWord{8, 0, 444}, - dictWord{8, 0, 811}, - dictWord{9, 0, 468}, - dictWord{11, 0, 334}, - dictWord{12, 0, 24}, - dictWord{12, 0, 386}, - dictWord{140, 0, 576}, - dictWord{ - 133, - 0, - 757, - }, - dictWord{7, 0, 1553}, - dictWord{136, 0, 898}, - dictWord{133, 0, 721}, - dictWord{136, 0, 1012}, - dictWord{4, 0, 789}, - dictWord{5, 0, 647}, - dictWord{ - 135, - 0, - 1102, - }, - dictWord{132, 0, 898}, - dictWord{10, 0, 183}, - dictWord{4, 10, 238}, - dictWord{5, 10, 503}, - dictWord{6, 10, 179}, - dictWord{7, 10, 2003}, - dictWord{ - 8, - 10, - 381, - }, - dictWord{8, 10, 473}, - dictWord{9, 10, 149}, - dictWord{10, 10, 788}, - dictWord{15, 10, 45}, - dictWord{15, 10, 86}, - dictWord{20, 10, 110}, - dictWord{ - 150, - 10, - 57, - }, - dictWord{9, 0, 136}, - dictWord{19, 0, 107}, - dictWord{4, 10, 121}, - dictWord{5, 10, 156}, - dictWord{5, 10, 349}, - dictWord{10, 10, 605}, - dictWord{ - 142, - 10, - 342, - }, - dictWord{4, 11, 235}, - dictWord{135, 11, 255}, - dictWord{4, 11, 194}, - dictWord{5, 11, 584}, - dictWord{6, 11, 384}, - dictWord{7, 11, 583}, - dictWord{ - 10, - 11, - 761, - }, - dictWord{11, 11, 760}, - dictWord{139, 11, 851}, - dictWord{6, 10, 80}, - dictWord{6, 10, 1694}, - dictWord{7, 10, 173}, - dictWord{7, 10, 1974}, - dictWord{ - 9, - 10, - 547, - }, - dictWord{10, 10, 730}, - dictWord{14, 10, 18}, - dictWord{150, 10, 39}, - dictWord{4, 10, 923}, - dictWord{134, 10, 1711}, - dictWord{5, 0, 277}, - dictWord{141, 0, 247}, - dictWord{132, 0, 435}, - dictWord{133, 11, 562}, - dictWord{134, 0, 1311}, - dictWord{5, 11, 191}, - dictWord{137, 11, 271}, - dictWord{ - 132, - 10, - 595, - }, - dictWord{7, 11, 1537}, - dictWord{14, 11, 96}, - dictWord{143, 11, 73}, - dictWord{5, 0, 437}, - dictWord{7, 0, 502}, - dictWord{7, 0, 519}, - dictWord{7, 0, 1122}, - dictWord{7, 0, 1751}, - dictWord{14, 0, 211}, - dictWord{6, 10, 459}, - dictWord{7, 10, 1753}, - dictWord{7, 10, 1805}, - dictWord{8, 10, 658}, - dictWord{9, 10, 1}, - dictWord{11, 10, 959}, - dictWord{141, 10, 446}, - dictWord{6, 0, 814}, - dictWord{4, 11, 470}, - dictWord{5, 11, 473}, - dictWord{6, 11, 153}, - dictWord{7, 11, 1503}, - dictWord{7, 11, 1923}, - dictWord{10, 11, 701}, - dictWord{11, 11, 132}, - dictWord{11, 11, 168}, - dictWord{11, 11, 227}, - dictWord{11, 11, 320}, - dictWord{ - 11, - 11, - 436, - }, - dictWord{11, 11, 525}, - dictWord{11, 11, 855}, - dictWord{12, 11, 41}, - dictWord{12, 11, 286}, - dictWord{13, 11, 103}, - dictWord{13, 11, 284}, - dictWord{ - 14, - 11, - 255, - }, - dictWord{14, 11, 262}, - dictWord{15, 11, 117}, - dictWord{143, 11, 127}, - dictWord{5, 0, 265}, - dictWord{6, 0, 212}, - dictWord{135, 0, 28}, - dictWord{ - 138, - 0, - 750, - }, - dictWord{133, 11, 327}, - dictWord{6, 11, 552}, - dictWord{7, 11, 1754}, - dictWord{137, 11, 604}, - dictWord{134, 0, 2012}, - dictWord{132, 0, 702}, - dictWord{5, 11, 80}, - dictWord{6, 11, 405}, - dictWord{7, 11, 403}, - dictWord{7, 11, 1502}, - dictWord{7, 11, 1626}, - dictWord{8, 11, 456}, - dictWord{9, 11, 487}, - dictWord{9, 11, 853}, - dictWord{9, 11, 889}, - dictWord{10, 11, 309}, - dictWord{11, 11, 721}, - dictWord{11, 11, 994}, - dictWord{12, 11, 430}, - dictWord{ - 141, - 11, - 165, - }, - dictWord{5, 0, 808}, - dictWord{135, 0, 2045}, - dictWord{5, 0, 166}, - dictWord{8, 0, 739}, - dictWord{140, 0, 511}, - dictWord{134, 10, 490}, - dictWord{ - 4, - 11, - 453, - }, - dictWord{5, 11, 887}, - dictWord{6, 11, 535}, - dictWord{8, 11, 6}, - dictWord{136, 11, 543}, - dictWord{4, 0, 119}, - dictWord{5, 0, 170}, - dictWord{5, 0, 447}, - dictWord{7, 0, 1708}, - dictWord{7, 0, 1889}, - dictWord{9, 0, 357}, - dictWord{9, 0, 719}, - dictWord{12, 0, 486}, - dictWord{140, 0, 596}, - dictWord{137, 0, 500}, - dictWord{ - 7, - 10, - 250, - }, - dictWord{136, 10, 507}, - dictWord{132, 10, 158}, - dictWord{6, 0, 809}, - dictWord{134, 0, 1500}, - dictWord{9, 0, 327}, - dictWord{11, 0, 350}, - dictWord{11, 0, 831}, - dictWord{13, 0, 352}, - dictWord{4, 10, 140}, - dictWord{7, 10, 362}, - dictWord{8, 10, 209}, - dictWord{9, 10, 10}, - dictWord{9, 10, 503}, - dictWord{ - 9, - 10, - 614, - }, - dictWord{10, 10, 689}, - dictWord{11, 10, 327}, - dictWord{11, 10, 725}, - dictWord{12, 10, 252}, - dictWord{12, 10, 583}, - dictWord{13, 10, 192}, - dictWord{14, 10, 269}, - dictWord{14, 10, 356}, - dictWord{148, 10, 50}, - dictWord{135, 11, 741}, - dictWord{4, 0, 450}, - dictWord{7, 0, 1158}, - dictWord{19, 10, 1}, - dictWord{19, 10, 26}, - dictWord{150, 10, 9}, - dictWord{6, 0, 597}, - dictWord{135, 0, 1318}, - dictWord{134, 0, 1602}, - dictWord{6, 10, 228}, - dictWord{7, 10, 1341}, - dictWord{9, 10, 408}, - dictWord{138, 10, 343}, - dictWord{7, 0, 1375}, - dictWord{7, 0, 1466}, - dictWord{138, 0, 331}, - dictWord{132, 0, 754}, - dictWord{ - 132, - 10, - 557, - }, - dictWord{5, 11, 101}, - dictWord{6, 11, 88}, - dictWord{6, 11, 543}, - dictWord{7, 11, 1677}, - dictWord{9, 11, 100}, - dictWord{10, 11, 677}, - dictWord{ - 14, - 11, - 169, - }, - dictWord{14, 11, 302}, - dictWord{14, 11, 313}, - dictWord{15, 11, 48}, - dictWord{143, 11, 84}, - dictWord{134, 0, 1368}, - dictWord{4, 11, 310}, - dictWord{ - 9, - 11, - 795, - }, - dictWord{10, 11, 733}, - dictWord{11, 11, 451}, - dictWord{12, 11, 249}, - dictWord{14, 11, 115}, - dictWord{14, 11, 286}, - dictWord{143, 11, 100}, - dictWord{132, 10, 548}, - dictWord{10, 0, 557}, - dictWord{7, 10, 197}, - dictWord{8, 10, 142}, - dictWord{8, 10, 325}, - dictWord{9, 10, 150}, - dictWord{9, 10, 596}, - dictWord{10, 10, 353}, - dictWord{11, 10, 74}, - dictWord{11, 10, 315}, - dictWord{12, 10, 662}, - dictWord{12, 10, 681}, - dictWord{14, 10, 423}, - dictWord{ - 143, - 10, - 141, - }, - dictWord{133, 11, 587}, - dictWord{5, 0, 850}, - dictWord{136, 0, 799}, - dictWord{10, 0, 908}, - dictWord{12, 0, 701}, - dictWord{12, 0, 757}, - dictWord{ - 142, - 0, - 466, - }, - dictWord{4, 0, 62}, - dictWord{5, 0, 275}, - dictWord{18, 0, 19}, - dictWord{6, 10, 399}, - dictWord{6, 10, 579}, - dictWord{7, 10, 692}, - dictWord{7, 10, 846}, - dictWord{ - 7, - 10, - 1015, - }, - dictWord{7, 10, 1799}, - dictWord{8, 10, 403}, - dictWord{9, 10, 394}, - dictWord{10, 10, 133}, - dictWord{12, 10, 4}, - dictWord{12, 10, 297}, - dictWord{12, 10, 452}, - dictWord{16, 10, 81}, - dictWord{18, 10, 25}, - dictWord{21, 10, 14}, - dictWord{22, 10, 12}, - dictWord{151, 10, 18}, - dictWord{12, 0, 459}, - dictWord{ - 7, - 10, - 1546, - }, - dictWord{11, 10, 299}, - dictWord{142, 10, 407}, - dictWord{132, 10, 177}, - dictWord{132, 11, 498}, - dictWord{7, 11, 217}, - dictWord{ - 8, - 11, - 140, - }, - dictWord{138, 11, 610}, - dictWord{5, 10, 411}, - dictWord{135, 10, 653}, - dictWord{134, 0, 1802}, - dictWord{7, 10, 439}, - dictWord{10, 10, 727}, - dictWord{11, 10, 260}, - dictWord{139, 10, 684}, - dictWord{133, 11, 905}, - dictWord{11, 11, 580}, - dictWord{142, 11, 201}, - dictWord{134, 0, 1397}, - dictWord{ - 5, - 10, - 208, - }, - dictWord{7, 10, 753}, - dictWord{135, 10, 1528}, - dictWord{7, 0, 238}, - dictWord{7, 0, 2033}, - dictWord{8, 0, 120}, - dictWord{8, 0, 188}, - dictWord{8, 0, 659}, - dictWord{9, 0, 598}, - dictWord{10, 0, 466}, - dictWord{12, 0, 342}, - dictWord{12, 0, 588}, - dictWord{13, 0, 503}, - dictWord{14, 0, 246}, - dictWord{143, 0, 92}, - dictWord{135, 11, 1041}, - dictWord{4, 11, 456}, - dictWord{7, 11, 105}, - dictWord{7, 11, 358}, - dictWord{7, 11, 1637}, - dictWord{8, 11, 643}, - dictWord{139, 11, 483}, - dictWord{6, 0, 1318}, - dictWord{134, 0, 1324}, - dictWord{4, 0, 201}, - dictWord{7, 0, 1744}, - dictWord{8, 0, 602}, - dictWord{11, 0, 247}, - dictWord{11, 0, 826}, - dictWord{17, 0, 65}, - dictWord{133, 10, 242}, - dictWord{8, 0, 164}, - dictWord{146, 0, 62}, - dictWord{133, 10, 953}, - dictWord{139, 10, 802}, - dictWord{133, 0, 615}, - dictWord{7, 11, 1566}, - dictWord{8, 11, 269}, - dictWord{9, 11, 212}, - dictWord{9, 11, 718}, - dictWord{14, 11, 15}, - dictWord{14, 11, 132}, - dictWord{142, 11, 227}, - dictWord{133, 10, 290}, - dictWord{132, 10, 380}, - dictWord{5, 10, 52}, - dictWord{7, 10, 277}, - dictWord{9, 10, 368}, - dictWord{139, 10, 791}, - dictWord{ - 135, - 0, - 1243, - }, - dictWord{133, 11, 539}, - dictWord{11, 11, 919}, - dictWord{141, 11, 409}, - dictWord{136, 0, 968}, - dictWord{133, 11, 470}, - dictWord{134, 0, 882}, - dictWord{132, 0, 907}, - dictWord{5, 0, 100}, - dictWord{10, 0, 329}, - dictWord{12, 0, 416}, - dictWord{149, 0, 29}, - dictWord{10, 10, 138}, - dictWord{139, 10, 476}, - dictWord{5, 10, 725}, - dictWord{5, 10, 727}, - dictWord{6, 11, 91}, - dictWord{7, 11, 435}, - dictWord{135, 10, 1811}, - dictWord{4, 11, 16}, - dictWord{5, 11, 316}, - dictWord{5, 11, 842}, - dictWord{6, 11, 370}, - dictWord{6, 11, 1778}, - dictWord{8, 11, 166}, - dictWord{11, 11, 812}, - dictWord{12, 11, 206}, - dictWord{12, 11, 351}, - dictWord{14, 11, 418}, - dictWord{16, 11, 15}, - dictWord{16, 11, 34}, - dictWord{18, 11, 3}, - dictWord{19, 11, 3}, - dictWord{19, 11, 7}, - dictWord{20, 11, 4}, - dictWord{ - 149, - 11, - 21, - }, - dictWord{132, 0, 176}, - dictWord{5, 0, 636}, - dictWord{5, 0, 998}, - dictWord{7, 0, 9}, - dictWord{7, 0, 1508}, - dictWord{8, 0, 26}, - dictWord{9, 0, 317}, - dictWord{ - 9, - 0, - 358, - }, - dictWord{10, 0, 210}, - dictWord{10, 0, 292}, - dictWord{10, 0, 533}, - dictWord{11, 0, 555}, - dictWord{12, 0, 526}, - dictWord{12, 0, 607}, - dictWord{ - 13, - 0, - 263, - }, - dictWord{13, 0, 459}, - dictWord{142, 0, 271}, - dictWord{6, 0, 256}, - dictWord{8, 0, 265}, - dictWord{4, 10, 38}, - dictWord{7, 10, 307}, - dictWord{7, 10, 999}, - dictWord{7, 10, 1481}, - dictWord{7, 10, 1732}, - dictWord{7, 10, 1738}, - dictWord{9, 10, 414}, - dictWord{11, 10, 316}, - dictWord{12, 10, 52}, - dictWord{13, 10, 420}, - dictWord{147, 10, 100}, - dictWord{135, 10, 1296}, - dictWord{4, 11, 611}, - dictWord{133, 11, 606}, - dictWord{4, 0, 643}, - dictWord{142, 11, 21}, - dictWord{ - 133, - 11, - 715, - }, - dictWord{133, 10, 723}, - dictWord{6, 0, 610}, - dictWord{135, 11, 597}, - dictWord{10, 0, 127}, - dictWord{141, 0, 27}, - dictWord{6, 0, 1995}, - dictWord{ - 6, - 0, - 2001, - }, - dictWord{8, 0, 119}, - dictWord{136, 0, 973}, - dictWord{4, 11, 149}, - dictWord{138, 11, 368}, - dictWord{12, 0, 522}, - dictWord{4, 11, 154}, - dictWord{ - 5, - 10, - 109, - }, - dictWord{6, 10, 1784}, - dictWord{7, 11, 1134}, - dictWord{7, 10, 1895}, - dictWord{8, 11, 105}, - dictWord{12, 10, 296}, - dictWord{140, 10, 302}, - dictWord{4, 11, 31}, - dictWord{6, 11, 429}, - dictWord{7, 11, 962}, - dictWord{9, 11, 458}, - dictWord{139, 11, 691}, - dictWord{10, 0, 553}, - dictWord{11, 0, 876}, - dictWord{13, 0, 193}, - dictWord{13, 0, 423}, - dictWord{14, 0, 166}, - dictWord{19, 0, 84}, - dictWord{4, 11, 312}, - dictWord{5, 10, 216}, - dictWord{7, 10, 1879}, - dictWord{ - 9, - 10, - 141, - }, - dictWord{9, 10, 270}, - dictWord{9, 10, 679}, - dictWord{10, 10, 159}, - dictWord{11, 10, 197}, - dictWord{12, 10, 538}, - dictWord{12, 10, 559}, - dictWord{14, 10, 144}, - dictWord{14, 10, 167}, - dictWord{143, 10, 67}, - dictWord{134, 0, 1582}, - dictWord{7, 0, 1578}, - dictWord{135, 11, 1578}, - dictWord{ - 137, - 10, - 81, - }, - dictWord{132, 11, 236}, - dictWord{134, 10, 391}, - dictWord{134, 0, 795}, - dictWord{7, 10, 322}, - dictWord{136, 10, 249}, - dictWord{5, 11, 836}, - dictWord{ - 5, - 11, - 857, - }, - dictWord{6, 11, 1680}, - dictWord{7, 11, 59}, - dictWord{147, 11, 53}, - dictWord{135, 0, 432}, - dictWord{10, 11, 68}, - dictWord{139, 11, 494}, - dictWord{4, 11, 81}, - dictWord{139, 11, 867}, - dictWord{7, 0, 126}, - dictWord{136, 0, 84}, - dictWord{142, 11, 280}, - dictWord{5, 11, 282}, - dictWord{8, 11, 650}, - dictWord{ - 9, - 11, - 295, - }, - dictWord{9, 11, 907}, - dictWord{138, 11, 443}, - dictWord{136, 0, 790}, - dictWord{5, 10, 632}, - dictWord{138, 10, 526}, - dictWord{6, 0, 64}, - dictWord{12, 0, 377}, - dictWord{13, 0, 309}, - dictWord{14, 0, 141}, - dictWord{14, 0, 429}, - dictWord{14, 11, 141}, - dictWord{142, 11, 429}, - dictWord{134, 0, 1529}, - dictWord{6, 0, 321}, - dictWord{7, 0, 1857}, - dictWord{9, 0, 530}, - dictWord{19, 0, 99}, - dictWord{7, 10, 948}, - dictWord{7, 10, 1042}, - dictWord{8, 10, 235}, - dictWord{ - 8, - 10, - 461, - }, - dictWord{9, 10, 453}, - dictWord{10, 10, 354}, - dictWord{145, 10, 77}, - dictWord{7, 0, 1104}, - dictWord{11, 0, 269}, - dictWord{11, 0, 539}, - dictWord{ - 11, - 0, - 627, - }, - dictWord{11, 0, 706}, - dictWord{11, 0, 975}, - dictWord{12, 0, 248}, - dictWord{12, 0, 434}, - dictWord{12, 0, 600}, - dictWord{12, 0, 622}, - dictWord{ - 13, - 0, - 297, - }, - dictWord{13, 0, 485}, - dictWord{14, 0, 69}, - dictWord{14, 0, 409}, - dictWord{143, 0, 108}, - dictWord{4, 10, 362}, - dictWord{7, 10, 52}, - dictWord{7, 10, 303}, - dictWord{10, 11, 70}, - dictWord{12, 11, 26}, - dictWord{14, 11, 17}, - dictWord{14, 11, 178}, - dictWord{15, 11, 34}, - dictWord{149, 11, 12}, - dictWord{11, 0, 977}, - dictWord{141, 0, 507}, - dictWord{9, 0, 34}, - dictWord{139, 0, 484}, - dictWord{5, 10, 196}, - dictWord{6, 10, 486}, - dictWord{7, 10, 212}, - dictWord{8, 10, 309}, - dictWord{136, 10, 346}, - dictWord{6, 0, 1700}, - dictWord{7, 0, 26}, - dictWord{7, 0, 293}, - dictWord{7, 0, 382}, - dictWord{7, 0, 1026}, - dictWord{7, 0, 1087}, - dictWord{ - 7, - 0, - 2027, - }, - dictWord{8, 0, 24}, - dictWord{8, 0, 114}, - dictWord{8, 0, 252}, - dictWord{8, 0, 727}, - dictWord{8, 0, 729}, - dictWord{9, 0, 30}, - dictWord{9, 0, 199}, - dictWord{ - 9, - 0, - 231, - }, - dictWord{9, 0, 251}, - dictWord{9, 0, 334}, - dictWord{9, 0, 361}, - dictWord{9, 0, 712}, - dictWord{10, 0, 55}, - dictWord{10, 0, 60}, - dictWord{10, 0, 232}, - dictWord{ - 10, - 0, - 332, - }, - dictWord{10, 0, 384}, - dictWord{10, 0, 396}, - dictWord{10, 0, 504}, - dictWord{10, 0, 542}, - dictWord{10, 0, 652}, - dictWord{11, 0, 20}, - dictWord{11, 0, 48}, - dictWord{11, 0, 207}, - dictWord{11, 0, 291}, - dictWord{11, 0, 298}, - dictWord{11, 0, 342}, - dictWord{11, 0, 365}, - dictWord{11, 0, 394}, - dictWord{11, 0, 620}, - dictWord{11, 0, 705}, - dictWord{11, 0, 1017}, - dictWord{12, 0, 123}, - dictWord{12, 0, 340}, - dictWord{12, 0, 406}, - dictWord{12, 0, 643}, - dictWord{13, 0, 61}, - dictWord{ - 13, - 0, - 269, - }, - dictWord{13, 0, 311}, - dictWord{13, 0, 319}, - dictWord{13, 0, 486}, - dictWord{14, 0, 234}, - dictWord{15, 0, 62}, - dictWord{15, 0, 85}, - dictWord{16, 0, 71}, - dictWord{18, 0, 119}, - dictWord{20, 0, 105}, - dictWord{135, 10, 1912}, - dictWord{4, 11, 71}, - dictWord{5, 11, 376}, - dictWord{7, 11, 119}, - dictWord{138, 11, 665}, - dictWord{10, 0, 918}, - dictWord{10, 0, 926}, - dictWord{4, 10, 686}, - dictWord{136, 11, 55}, - dictWord{138, 10, 625}, - dictWord{136, 10, 706}, - dictWord{ - 132, - 11, - 479, - }, - dictWord{4, 10, 30}, - dictWord{133, 10, 43}, - dictWord{6, 0, 379}, - dictWord{7, 0, 270}, - dictWord{8, 0, 176}, - dictWord{8, 0, 183}, - dictWord{9, 0, 432}, - dictWord{ - 9, - 0, - 661, - }, - dictWord{12, 0, 247}, - dictWord{12, 0, 617}, - dictWord{18, 0, 125}, - dictWord{7, 11, 607}, - dictWord{8, 11, 99}, - dictWord{152, 11, 4}, - dictWord{ - 5, - 0, - 792, - }, - dictWord{133, 0, 900}, - dictWord{4, 11, 612}, - dictWord{133, 11, 561}, - dictWord{4, 11, 41}, - dictWord{4, 10, 220}, - dictWord{5, 11, 74}, - dictWord{ - 7, - 10, - 1535, - }, - dictWord{7, 11, 1627}, - dictWord{11, 11, 871}, - dictWord{140, 11, 619}, - dictWord{135, 0, 1920}, - dictWord{7, 11, 94}, - dictWord{11, 11, 329}, - dictWord{11, 11, 965}, - dictWord{12, 11, 241}, - dictWord{14, 11, 354}, - dictWord{15, 11, 22}, - dictWord{148, 11, 63}, - dictWord{9, 11, 209}, - dictWord{137, 11, 300}, - dictWord{134, 0, 771}, - dictWord{135, 0, 1979}, - dictWord{4, 0, 901}, - dictWord{133, 0, 776}, - dictWord{142, 0, 254}, - dictWord{133, 11, 98}, - dictWord{ - 9, - 11, - 16, - }, - dictWord{141, 11, 386}, - dictWord{133, 11, 984}, - dictWord{4, 11, 182}, - dictWord{6, 11, 205}, - dictWord{135, 11, 220}, - dictWord{7, 10, 1725}, - dictWord{ - 7, - 10, - 1774, - }, - dictWord{138, 10, 393}, - dictWord{5, 10, 263}, - dictWord{134, 10, 414}, - dictWord{4, 11, 42}, - dictWord{9, 11, 205}, - dictWord{9, 11, 786}, - dictWord{138, 11, 659}, - dictWord{14, 0, 140}, - dictWord{148, 0, 41}, - dictWord{8, 0, 440}, - dictWord{10, 0, 359}, - dictWord{6, 10, 178}, - dictWord{6, 11, 289}, - dictWord{ - 6, - 10, - 1750, - }, - dictWord{7, 11, 1670}, - dictWord{9, 10, 690}, - dictWord{10, 10, 155}, - dictWord{10, 10, 373}, - dictWord{11, 10, 698}, - dictWord{12, 11, 57}, - dictWord{13, 10, 155}, - dictWord{20, 10, 93}, - dictWord{151, 11, 4}, - dictWord{4, 0, 37}, - dictWord{5, 0, 334}, - dictWord{7, 0, 1253}, - dictWord{151, 11, 25}, - dictWord{ - 4, - 0, - 508, - }, - dictWord{4, 11, 635}, - dictWord{5, 10, 97}, - dictWord{137, 10, 393}, - dictWord{139, 11, 533}, - dictWord{4, 0, 640}, - dictWord{133, 0, 513}, - dictWord{ - 134, - 10, - 1639, - }, - dictWord{132, 11, 371}, - dictWord{4, 11, 272}, - dictWord{7, 11, 836}, - dictWord{7, 11, 1651}, - dictWord{145, 11, 89}, - dictWord{5, 11, 825}, - dictWord{6, 11, 444}, - dictWord{6, 11, 1640}, - dictWord{136, 11, 308}, - dictWord{4, 10, 191}, - dictWord{7, 10, 934}, - dictWord{8, 10, 647}, - dictWord{145, 10, 97}, - dictWord{12, 0, 246}, - dictWord{15, 0, 162}, - dictWord{19, 0, 64}, - dictWord{20, 0, 8}, - dictWord{20, 0, 95}, - dictWord{22, 0, 24}, - dictWord{152, 0, 17}, - dictWord{4, 0, 533}, - dictWord{5, 10, 165}, - dictWord{9, 10, 346}, - dictWord{138, 10, 655}, - dictWord{5, 11, 737}, - dictWord{139, 10, 885}, - dictWord{133, 10, 877}, - dictWord{ - 8, - 10, - 128, - }, - dictWord{139, 10, 179}, - dictWord{137, 11, 307}, - dictWord{140, 0, 752}, - dictWord{133, 0, 920}, - dictWord{135, 0, 1048}, - dictWord{5, 0, 153}, - dictWord{ - 6, - 0, - 580, - }, - dictWord{6, 10, 1663}, - dictWord{7, 10, 132}, - dictWord{7, 10, 1154}, - dictWord{7, 10, 1415}, - dictWord{7, 10, 1507}, - dictWord{12, 10, 493}, - dictWord{15, 10, 105}, - dictWord{151, 10, 15}, - dictWord{5, 10, 459}, - dictWord{7, 10, 1073}, - dictWord{8, 10, 241}, - dictWord{136, 10, 334}, - dictWord{138, 0, 391}, - dictWord{135, 0, 1952}, - dictWord{133, 11, 525}, - dictWord{8, 11, 641}, - dictWord{11, 11, 388}, - dictWord{140, 11, 580}, - dictWord{142, 0, 126}, - dictWord{ - 134, - 0, - 640, - }, - dictWord{132, 0, 483}, - dictWord{7, 0, 1616}, - dictWord{9, 0, 69}, - dictWord{6, 10, 324}, - dictWord{6, 10, 520}, - dictWord{7, 10, 338}, - dictWord{ - 7, - 10, - 1729, - }, - dictWord{8, 10, 228}, - dictWord{139, 10, 750}, - dictWord{5, 11, 493}, - dictWord{134, 11, 528}, - dictWord{135, 0, 734}, - dictWord{4, 11, 174}, - dictWord{135, 11, 911}, - dictWord{138, 0, 480}, - dictWord{9, 0, 495}, - dictWord{146, 0, 104}, - dictWord{135, 10, 705}, - dictWord{9, 0, 472}, - dictWord{4, 10, 73}, - dictWord{6, 10, 612}, - dictWord{7, 10, 927}, - dictWord{7, 10, 1330}, - dictWord{7, 10, 1822}, - dictWord{8, 10, 217}, - dictWord{9, 10, 765}, - dictWord{9, 10, 766}, - dictWord{10, 10, 408}, - dictWord{11, 10, 51}, - dictWord{11, 10, 793}, - dictWord{12, 10, 266}, - dictWord{15, 10, 158}, - dictWord{20, 10, 89}, - dictWord{150, 10, 32}, - dictWord{7, 11, 548}, - dictWord{137, 11, 58}, - dictWord{4, 11, 32}, - dictWord{5, 11, 215}, - dictWord{6, 11, 269}, - dictWord{7, 11, 1782}, - dictWord{7, 11, 1892}, - dictWord{10, 11, 16}, - dictWord{11, 11, 822}, - dictWord{11, 11, 954}, - dictWord{141, 11, 481}, - dictWord{132, 0, 874}, - dictWord{9, 0, 229}, - dictWord{5, 10, 389}, - dictWord{136, 10, 636}, - dictWord{7, 11, 1749}, - dictWord{136, 11, 477}, - dictWord{134, 0, 948}, - dictWord{5, 11, 308}, - dictWord{135, 11, 1088}, - dictWord{ - 4, - 0, - 748, - }, - dictWord{139, 0, 1009}, - dictWord{136, 10, 21}, - dictWord{6, 0, 555}, - dictWord{135, 0, 485}, - dictWord{5, 11, 126}, - dictWord{8, 11, 297}, - dictWord{ - 9, - 11, - 366, - }, - dictWord{9, 11, 445}, - dictWord{12, 11, 53}, - dictWord{12, 11, 374}, - dictWord{141, 11, 492}, - dictWord{7, 11, 1551}, - dictWord{139, 11, 361}, - dictWord{136, 0, 193}, - dictWord{136, 0, 472}, - dictWord{8, 0, 653}, - dictWord{13, 0, 93}, - dictWord{147, 0, 14}, - dictWord{132, 0, 984}, - dictWord{132, 11, 175}, - dictWord{5, 0, 172}, - dictWord{6, 0, 1971}, - dictWord{132, 11, 685}, - dictWord{149, 11, 8}, - dictWord{133, 11, 797}, - dictWord{13, 0, 83}, - dictWord{5, 10, 189}, - dictWord{ - 7, - 10, - 442, - }, - dictWord{7, 10, 443}, - dictWord{8, 10, 281}, - dictWord{12, 10, 174}, - dictWord{141, 10, 261}, - dictWord{134, 0, 1568}, - dictWord{133, 11, 565}, - dictWord{139, 0, 384}, - dictWord{133, 0, 260}, - dictWord{7, 0, 758}, - dictWord{7, 0, 880}, - dictWord{7, 0, 1359}, - dictWord{9, 0, 164}, - dictWord{9, 0, 167}, - dictWord{ - 10, - 0, - 156, - }, - dictWord{10, 0, 588}, - dictWord{12, 0, 101}, - dictWord{14, 0, 48}, - dictWord{15, 0, 70}, - dictWord{6, 10, 2}, - dictWord{7, 10, 1262}, - dictWord{ - 7, - 10, - 1737, - }, - dictWord{8, 10, 22}, - dictWord{8, 10, 270}, - dictWord{8, 10, 612}, - dictWord{9, 10, 312}, - dictWord{9, 10, 436}, - dictWord{10, 10, 311}, - dictWord{ - 10, - 10, - 623, - }, - dictWord{11, 10, 72}, - dictWord{11, 10, 330}, - dictWord{11, 10, 455}, - dictWord{12, 10, 321}, - dictWord{12, 10, 504}, - dictWord{12, 10, 530}, - dictWord{ - 12, - 10, - 543, - }, - dictWord{13, 10, 17}, - dictWord{13, 10, 156}, - dictWord{13, 10, 334}, - dictWord{17, 10, 60}, - dictWord{148, 10, 64}, - dictWord{4, 11, 252}, - dictWord{ - 7, - 11, - 1068, - }, - dictWord{10, 11, 434}, - dictWord{11, 11, 228}, - dictWord{11, 11, 426}, - dictWord{13, 11, 231}, - dictWord{18, 11, 106}, - dictWord{148, 11, 87}, - dictWord{7, 10, 354}, - dictWord{10, 10, 410}, - dictWord{139, 10, 815}, - dictWord{6, 0, 367}, - dictWord{7, 10, 670}, - dictWord{7, 10, 1327}, - dictWord{8, 10, 411}, - dictWord{8, 10, 435}, - dictWord{9, 10, 653}, - dictWord{9, 10, 740}, - dictWord{10, 10, 385}, - dictWord{11, 10, 222}, - dictWord{11, 10, 324}, - dictWord{11, 10, 829}, - dictWord{140, 10, 611}, - dictWord{7, 0, 1174}, - dictWord{6, 10, 166}, - dictWord{135, 10, 374}, - dictWord{146, 0, 121}, - dictWord{132, 0, 828}, - dictWord{ - 5, - 11, - 231, - }, - dictWord{138, 11, 509}, - dictWord{7, 11, 601}, - dictWord{9, 11, 277}, - dictWord{9, 11, 674}, - dictWord{10, 11, 178}, - dictWord{10, 11, 257}, - dictWord{ - 10, - 11, - 418, - }, - dictWord{11, 11, 531}, - dictWord{11, 11, 544}, - dictWord{11, 11, 585}, - dictWord{12, 11, 113}, - dictWord{12, 11, 475}, - dictWord{13, 11, 99}, - dictWord{142, 11, 428}, - dictWord{134, 0, 1541}, - dictWord{135, 11, 1779}, - dictWord{5, 0, 343}, - dictWord{134, 10, 398}, - dictWord{135, 10, 50}, - dictWord{ - 135, - 11, - 1683, - }, - dictWord{4, 0, 440}, - dictWord{7, 0, 57}, - dictWord{8, 0, 167}, - dictWord{8, 0, 375}, - dictWord{9, 0, 82}, - dictWord{9, 0, 561}, - dictWord{9, 0, 744}, - dictWord{ - 10, - 0, - 620, - }, - dictWord{137, 11, 744}, - dictWord{134, 0, 926}, - dictWord{6, 10, 517}, - dictWord{7, 10, 1159}, - dictWord{10, 10, 621}, - dictWord{139, 10, 192}, - dictWord{137, 0, 827}, - dictWord{8, 0, 194}, - dictWord{136, 0, 756}, - dictWord{10, 10, 223}, - dictWord{139, 10, 645}, - dictWord{7, 10, 64}, - dictWord{ - 136, - 10, - 245, - }, - dictWord{4, 11, 399}, - dictWord{5, 11, 119}, - dictWord{5, 11, 494}, - dictWord{7, 11, 751}, - dictWord{137, 11, 556}, - dictWord{132, 0, 808}, - dictWord{ - 135, - 0, - 22, - }, - dictWord{7, 10, 1763}, - dictWord{140, 10, 310}, - dictWord{5, 0, 639}, - dictWord{7, 0, 1249}, - dictWord{11, 0, 896}, - dictWord{134, 11, 584}, - dictWord{ - 134, - 0, - 1614, - }, - dictWord{135, 0, 860}, - dictWord{135, 11, 1121}, - dictWord{5, 10, 129}, - dictWord{6, 10, 61}, - dictWord{135, 10, 947}, - dictWord{4, 0, 102}, - dictWord{ - 7, - 0, - 815, - }, - dictWord{7, 0, 1699}, - dictWord{139, 0, 964}, - dictWord{13, 10, 505}, - dictWord{141, 10, 506}, - dictWord{139, 10, 1000}, - dictWord{ - 132, - 11, - 679, - }, - dictWord{132, 0, 899}, - dictWord{132, 0, 569}, - dictWord{5, 11, 694}, - dictWord{137, 11, 714}, - dictWord{136, 0, 795}, - dictWord{6, 0, 2045}, - dictWord{ - 139, - 11, - 7, - }, - dictWord{6, 0, 52}, - dictWord{9, 0, 104}, - dictWord{9, 0, 559}, - dictWord{12, 0, 308}, - dictWord{147, 0, 87}, - dictWord{4, 0, 301}, - dictWord{132, 0, 604}, - dictWord{133, 10, 637}, - dictWord{136, 0, 779}, - dictWord{5, 11, 143}, - dictWord{5, 11, 769}, - dictWord{6, 11, 1760}, - dictWord{7, 11, 682}, - dictWord{7, 11, 1992}, - dictWord{136, 11, 736}, - dictWord{137, 10, 590}, - dictWord{147, 0, 32}, - dictWord{137, 11, 527}, - dictWord{5, 10, 280}, - dictWord{135, 10, 1226}, - dictWord{134, 0, 494}, - dictWord{6, 0, 677}, - dictWord{6, 0, 682}, - dictWord{134, 0, 1044}, - dictWord{133, 10, 281}, - dictWord{135, 10, 1064}, - dictWord{7, 0, 508}, - dictWord{133, 11, 860}, - dictWord{6, 11, 422}, - dictWord{7, 11, 0}, - dictWord{7, 11, 1544}, - dictWord{9, 11, 577}, - dictWord{11, 11, 990}, - dictWord{12, 11, 141}, - dictWord{12, 11, 453}, - dictWord{13, 11, 47}, - dictWord{141, 11, 266}, - dictWord{134, 0, 1014}, - dictWord{5, 11, 515}, - dictWord{137, 11, 131}, - dictWord{ - 134, - 0, - 957, - }, - dictWord{132, 11, 646}, - dictWord{6, 0, 310}, - dictWord{7, 0, 1849}, - dictWord{8, 0, 72}, - dictWord{8, 0, 272}, - dictWord{8, 0, 431}, - dictWord{9, 0, 12}, - dictWord{ - 9, - 0, - 376, - }, - dictWord{10, 0, 563}, - dictWord{10, 0, 630}, - dictWord{10, 0, 796}, - dictWord{10, 0, 810}, - dictWord{11, 0, 367}, - dictWord{11, 0, 599}, - dictWord{ - 11, - 0, - 686, - }, - dictWord{140, 0, 672}, - dictWord{7, 0, 570}, - dictWord{4, 11, 396}, - dictWord{7, 10, 120}, - dictWord{7, 11, 728}, - dictWord{8, 10, 489}, - dictWord{9, 11, 117}, - dictWord{9, 10, 319}, - dictWord{10, 10, 820}, - dictWord{11, 10, 1004}, - dictWord{12, 10, 379}, - dictWord{12, 10, 679}, - dictWord{13, 10, 117}, - dictWord{ - 13, - 11, - 202, - }, - dictWord{13, 10, 412}, - dictWord{14, 10, 25}, - dictWord{15, 10, 52}, - dictWord{15, 10, 161}, - dictWord{16, 10, 47}, - dictWord{20, 11, 51}, - dictWord{ - 149, - 10, - 2, - }, - dictWord{6, 11, 121}, - dictWord{6, 11, 124}, - dictWord{6, 11, 357}, - dictWord{7, 11, 1138}, - dictWord{7, 11, 1295}, - dictWord{8, 11, 162}, - dictWord{ - 139, - 11, - 655, - }, - dictWord{8, 0, 449}, - dictWord{4, 10, 937}, - dictWord{5, 10, 801}, - dictWord{136, 11, 449}, - dictWord{139, 11, 958}, - dictWord{6, 0, 181}, - dictWord{ - 7, - 0, - 537, - }, - dictWord{8, 0, 64}, - dictWord{9, 0, 127}, - dictWord{10, 0, 496}, - dictWord{12, 0, 510}, - dictWord{141, 0, 384}, - dictWord{138, 11, 253}, - dictWord{4, 0, 244}, - dictWord{135, 0, 233}, - dictWord{133, 11, 237}, - dictWord{132, 10, 365}, - dictWord{6, 0, 1650}, - dictWord{10, 0, 702}, - dictWord{139, 0, 245}, - dictWord{ - 5, - 10, - 7, - }, - dictWord{139, 10, 774}, - dictWord{13, 0, 463}, - dictWord{20, 0, 49}, - dictWord{13, 11, 463}, - dictWord{148, 11, 49}, - dictWord{4, 10, 734}, - dictWord{ - 5, - 10, - 662, - }, - dictWord{134, 10, 430}, - dictWord{4, 10, 746}, - dictWord{135, 10, 1090}, - dictWord{5, 10, 360}, - dictWord{136, 10, 237}, - dictWord{137, 0, 338}, - dictWord{143, 11, 10}, - dictWord{7, 11, 571}, - dictWord{138, 11, 366}, - dictWord{134, 0, 1279}, - dictWord{9, 11, 513}, - dictWord{10, 11, 22}, - dictWord{10, 11, 39}, - dictWord{12, 11, 122}, - dictWord{140, 11, 187}, - dictWord{133, 0, 896}, - dictWord{146, 0, 178}, - dictWord{134, 0, 695}, - dictWord{137, 0, 808}, - dictWord{ - 134, - 11, - 587, - }, - dictWord{7, 11, 107}, - dictWord{7, 11, 838}, - dictWord{8, 11, 550}, - dictWord{138, 11, 401}, - dictWord{7, 0, 1117}, - dictWord{136, 0, 539}, - dictWord{ - 4, - 10, - 277, - }, - dictWord{5, 10, 608}, - dictWord{6, 10, 493}, - dictWord{7, 10, 457}, - dictWord{140, 10, 384}, - dictWord{133, 11, 768}, - dictWord{12, 0, 257}, - dictWord{ - 7, - 10, - 27, - }, - dictWord{135, 10, 316}, - dictWord{140, 0, 1003}, - dictWord{4, 0, 207}, - dictWord{5, 0, 586}, - dictWord{5, 0, 676}, - dictWord{6, 0, 448}, - dictWord{ - 8, - 0, - 244, - }, - dictWord{11, 0, 1}, - dictWord{13, 0, 3}, - dictWord{16, 0, 54}, - dictWord{17, 0, 4}, - dictWord{18, 0, 13}, - dictWord{133, 10, 552}, - dictWord{4, 10, 401}, - dictWord{ - 137, - 10, - 264, - }, - dictWord{5, 0, 516}, - dictWord{7, 0, 1883}, - dictWord{135, 11, 1883}, - dictWord{12, 0, 960}, - dictWord{132, 11, 894}, - dictWord{5, 0, 4}, - dictWord{ - 5, - 0, - 810, - }, - dictWord{6, 0, 13}, - dictWord{6, 0, 538}, - dictWord{6, 0, 1690}, - dictWord{6, 0, 1726}, - dictWord{7, 0, 499}, - dictWord{7, 0, 1819}, - dictWord{8, 0, 148}, - dictWord{ - 8, - 0, - 696, - }, - dictWord{8, 0, 791}, - dictWord{12, 0, 125}, - dictWord{143, 0, 9}, - dictWord{135, 0, 1268}, - dictWord{11, 0, 30}, - dictWord{14, 0, 315}, - dictWord{ - 9, - 10, - 543, - }, - dictWord{10, 10, 524}, - dictWord{12, 10, 524}, - dictWord{16, 10, 18}, - dictWord{20, 10, 26}, - dictWord{148, 10, 65}, - dictWord{6, 0, 748}, - dictWord{ - 4, - 10, - 205, - }, - dictWord{5, 10, 623}, - dictWord{7, 10, 104}, - dictWord{136, 10, 519}, - dictWord{11, 0, 542}, - dictWord{139, 0, 852}, - dictWord{140, 0, 6}, - dictWord{ - 132, - 0, - 848, - }, - dictWord{7, 0, 1385}, - dictWord{11, 0, 582}, - dictWord{11, 0, 650}, - dictWord{11, 0, 901}, - dictWord{11, 0, 949}, - dictWord{12, 0, 232}, - dictWord{12, 0, 236}, - dictWord{13, 0, 413}, - dictWord{13, 0, 501}, - dictWord{18, 0, 116}, - dictWord{7, 10, 579}, - dictWord{9, 10, 41}, - dictWord{9, 10, 244}, - dictWord{9, 10, 669}, - dictWord{10, 10, 5}, - dictWord{11, 10, 861}, - dictWord{11, 10, 951}, - dictWord{139, 10, 980}, - dictWord{4, 0, 945}, - dictWord{6, 0, 1811}, - dictWord{6, 0, 1845}, - dictWord{ - 6, - 0, - 1853, - }, - dictWord{6, 0, 1858}, - dictWord{8, 0, 862}, - dictWord{12, 0, 782}, - dictWord{12, 0, 788}, - dictWord{18, 0, 160}, - dictWord{148, 0, 117}, - dictWord{ - 132, - 10, - 717, - }, - dictWord{4, 0, 925}, - dictWord{5, 0, 803}, - dictWord{8, 0, 698}, - dictWord{138, 0, 828}, - dictWord{134, 0, 1416}, - dictWord{132, 0, 610}, - dictWord{ - 139, - 0, - 992, - }, - dictWord{6, 0, 878}, - dictWord{134, 0, 1477}, - dictWord{135, 0, 1847}, - dictWord{138, 11, 531}, - dictWord{137, 11, 539}, - dictWord{134, 11, 272}, - dictWord{133, 0, 383}, - dictWord{134, 0, 1404}, - dictWord{132, 10, 489}, - dictWord{4, 11, 9}, - dictWord{5, 11, 128}, - dictWord{7, 11, 368}, - dictWord{ - 11, - 11, - 480, - }, - dictWord{148, 11, 3}, - dictWord{136, 0, 986}, - dictWord{9, 0, 660}, - dictWord{138, 0, 347}, - dictWord{135, 10, 892}, - dictWord{136, 11, 682}, - dictWord{ - 7, - 0, - 572, - }, - dictWord{9, 0, 592}, - dictWord{11, 0, 680}, - dictWord{12, 0, 356}, - dictWord{140, 0, 550}, - dictWord{7, 0, 1411}, - dictWord{138, 11, 527}, - dictWord{ - 4, - 11, - 2, - }, - dictWord{7, 11, 545}, - dictWord{135, 11, 894}, - dictWord{137, 10, 473}, - dictWord{11, 0, 64}, - dictWord{7, 11, 481}, - dictWord{7, 10, 819}, - dictWord{9, 10, 26}, - dictWord{9, 10, 392}, - dictWord{9, 11, 792}, - dictWord{10, 10, 152}, - dictWord{10, 10, 226}, - dictWord{12, 10, 276}, - dictWord{12, 10, 426}, - dictWord{ - 12, - 10, - 589, - }, - dictWord{13, 10, 460}, - dictWord{15, 10, 97}, - dictWord{19, 10, 48}, - dictWord{148, 10, 104}, - dictWord{135, 10, 51}, - dictWord{136, 11, 445}, - dictWord{136, 11, 646}, - dictWord{135, 0, 606}, - dictWord{132, 10, 674}, - dictWord{6, 0, 1829}, - dictWord{134, 0, 1830}, - dictWord{132, 10, 770}, - dictWord{ - 5, - 10, - 79, - }, - dictWord{7, 10, 1027}, - dictWord{7, 10, 1477}, - dictWord{139, 10, 52}, - dictWord{5, 11, 530}, - dictWord{142, 11, 113}, - dictWord{134, 10, 1666}, - dictWord{ - 7, - 0, - 748, - }, - dictWord{139, 0, 700}, - dictWord{134, 10, 195}, - dictWord{133, 10, 789}, - dictWord{9, 0, 87}, - dictWord{10, 0, 365}, - dictWord{4, 10, 251}, - dictWord{ - 4, - 10, - 688, - }, - dictWord{7, 10, 513}, - dictWord{135, 10, 1284}, - dictWord{136, 11, 111}, - dictWord{133, 0, 127}, - dictWord{6, 0, 198}, - dictWord{140, 0, 83}, - dictWord{133, 11, 556}, - dictWord{133, 10, 889}, - dictWord{4, 10, 160}, - dictWord{5, 10, 330}, - dictWord{7, 10, 1434}, - dictWord{136, 10, 174}, - dictWord{5, 0, 276}, - dictWord{6, 0, 55}, - dictWord{7, 0, 1369}, - dictWord{138, 0, 864}, - dictWord{8, 11, 16}, - dictWord{140, 11, 568}, - dictWord{6, 0, 1752}, - dictWord{136, 0, 726}, - dictWord{135, 0, 1066}, - dictWord{133, 0, 764}, - dictWord{6, 11, 186}, - dictWord{137, 11, 426}, - dictWord{11, 0, 683}, - dictWord{139, 11, 683}, - dictWord{ - 6, - 0, - 309, - }, - dictWord{7, 0, 331}, - dictWord{138, 0, 550}, - dictWord{133, 10, 374}, - dictWord{6, 0, 1212}, - dictWord{6, 0, 1852}, - dictWord{7, 0, 1062}, - dictWord{ - 8, - 0, - 874, - }, - dictWord{8, 0, 882}, - dictWord{138, 0, 936}, - dictWord{132, 11, 585}, - dictWord{134, 0, 1364}, - dictWord{7, 0, 986}, - dictWord{133, 10, 731}, - dictWord{ - 6, - 0, - 723, - }, - dictWord{6, 0, 1408}, - dictWord{138, 0, 381}, - dictWord{135, 0, 1573}, - dictWord{134, 0, 1025}, - dictWord{4, 10, 626}, - dictWord{5, 10, 642}, - dictWord{ - 6, - 10, - 425, - }, - dictWord{10, 10, 202}, - dictWord{139, 10, 141}, - dictWord{4, 11, 93}, - dictWord{5, 11, 252}, - dictWord{6, 11, 229}, - dictWord{7, 11, 291}, - dictWord{ - 9, - 11, - 550, - }, - dictWord{139, 11, 644}, - dictWord{137, 11, 749}, - dictWord{137, 11, 162}, - dictWord{132, 11, 381}, - dictWord{135, 0, 1559}, - dictWord{ - 6, - 0, - 194, - }, - dictWord{7, 0, 133}, - dictWord{10, 0, 493}, - dictWord{10, 0, 570}, - dictWord{139, 0, 664}, - dictWord{5, 0, 24}, - dictWord{5, 0, 569}, - dictWord{6, 0, 3}, - dictWord{ - 6, - 0, - 119, - }, - dictWord{6, 0, 143}, - dictWord{6, 0, 440}, - dictWord{7, 0, 295}, - dictWord{7, 0, 599}, - dictWord{7, 0, 1686}, - dictWord{7, 0, 1854}, - dictWord{8, 0, 424}, - dictWord{ - 9, - 0, - 43, - }, - dictWord{9, 0, 584}, - dictWord{9, 0, 760}, - dictWord{10, 0, 148}, - dictWord{10, 0, 328}, - dictWord{11, 0, 159}, - dictWord{11, 0, 253}, - dictWord{11, 0, 506}, - dictWord{12, 0, 487}, - dictWord{140, 0, 531}, - dictWord{6, 0, 661}, - dictWord{134, 0, 1517}, - dictWord{136, 10, 835}, - dictWord{151, 10, 17}, - dictWord{5, 0, 14}, - dictWord{5, 0, 892}, - dictWord{6, 0, 283}, - dictWord{7, 0, 234}, - dictWord{136, 0, 537}, - dictWord{139, 0, 541}, - dictWord{4, 0, 126}, - dictWord{8, 0, 635}, - dictWord{ - 147, - 0, - 34, - }, - dictWord{4, 0, 316}, - dictWord{4, 0, 495}, - dictWord{135, 0, 1561}, - dictWord{4, 11, 187}, - dictWord{5, 11, 184}, - dictWord{5, 11, 690}, - dictWord{ - 7, - 11, - 1869, - }, - dictWord{138, 11, 756}, - dictWord{139, 11, 783}, - dictWord{4, 0, 998}, - dictWord{137, 0, 861}, - dictWord{136, 0, 1009}, - dictWord{139, 11, 292}, - dictWord{5, 11, 21}, - dictWord{6, 11, 77}, - dictWord{6, 11, 157}, - dictWord{7, 11, 974}, - dictWord{7, 11, 1301}, - dictWord{7, 11, 1339}, - dictWord{7, 11, 1490}, - dictWord{ - 7, - 11, - 1873, - }, - dictWord{137, 11, 628}, - dictWord{7, 11, 1283}, - dictWord{9, 11, 227}, - dictWord{9, 11, 499}, - dictWord{10, 11, 341}, - dictWord{11, 11, 325}, - dictWord{11, 11, 408}, - dictWord{14, 11, 180}, - dictWord{15, 11, 144}, - dictWord{18, 11, 47}, - dictWord{147, 11, 49}, - dictWord{4, 0, 64}, - dictWord{5, 0, 352}, - dictWord{5, 0, 720}, - dictWord{6, 0, 368}, - dictWord{139, 0, 359}, - dictWord{5, 10, 384}, - dictWord{8, 10, 455}, - dictWord{140, 10, 48}, - dictWord{5, 10, 264}, - dictWord{ - 134, - 10, - 184, - }, - dictWord{7, 0, 1577}, - dictWord{10, 0, 304}, - dictWord{10, 0, 549}, - dictWord{12, 0, 365}, - dictWord{13, 0, 220}, - dictWord{13, 0, 240}, - dictWord{ - 142, - 0, - 33, - }, - dictWord{134, 0, 1107}, - dictWord{134, 0, 929}, - dictWord{135, 0, 1142}, - dictWord{6, 0, 175}, - dictWord{137, 0, 289}, - dictWord{5, 0, 432}, - dictWord{ - 133, - 0, - 913, - }, - dictWord{6, 0, 279}, - dictWord{7, 0, 219}, - dictWord{5, 10, 633}, - dictWord{135, 10, 1323}, - dictWord{7, 0, 785}, - dictWord{7, 10, 359}, - dictWord{ - 8, - 10, - 243, - }, - dictWord{140, 10, 175}, - dictWord{139, 0, 595}, - dictWord{132, 10, 105}, - dictWord{8, 11, 398}, - dictWord{9, 11, 681}, - dictWord{139, 11, 632}, - dictWord{140, 0, 80}, - dictWord{5, 0, 931}, - dictWord{134, 0, 1698}, - dictWord{142, 11, 241}, - dictWord{134, 11, 20}, - dictWord{134, 0, 1323}, - dictWord{11, 0, 526}, - dictWord{11, 0, 939}, - dictWord{141, 0, 290}, - dictWord{5, 0, 774}, - dictWord{6, 0, 780}, - dictWord{6, 0, 1637}, - dictWord{6, 0, 1686}, - dictWord{6, 0, 1751}, - dictWord{ - 8, - 0, - 559, - }, - dictWord{141, 0, 109}, - dictWord{141, 0, 127}, - dictWord{7, 0, 1167}, - dictWord{11, 0, 934}, - dictWord{13, 0, 391}, - dictWord{17, 0, 76}, - dictWord{ - 135, - 11, - 709, - }, - dictWord{135, 0, 963}, - dictWord{6, 0, 260}, - dictWord{135, 0, 1484}, - dictWord{134, 0, 573}, - dictWord{4, 10, 758}, - dictWord{139, 11, 941}, - dictWord{135, 10, 1649}, - dictWord{145, 11, 36}, - dictWord{4, 0, 292}, - dictWord{137, 0, 580}, - dictWord{4, 0, 736}, - dictWord{5, 0, 871}, - dictWord{6, 0, 1689}, - dictWord{135, 0, 1944}, - dictWord{7, 11, 945}, - dictWord{11, 11, 713}, - dictWord{139, 11, 744}, - dictWord{134, 0, 1164}, - dictWord{135, 11, 937}, - dictWord{ - 6, - 0, - 1922, - }, - dictWord{9, 0, 982}, - dictWord{15, 0, 173}, - dictWord{15, 0, 178}, - dictWord{15, 0, 200}, - dictWord{18, 0, 189}, - dictWord{18, 0, 207}, - dictWord{21, 0, 47}, - dictWord{135, 11, 1652}, - dictWord{7, 0, 1695}, - dictWord{139, 10, 128}, - dictWord{6, 0, 63}, - dictWord{135, 0, 920}, - dictWord{133, 0, 793}, - dictWord{ - 143, - 11, - 134, - }, - dictWord{133, 10, 918}, - dictWord{5, 0, 67}, - dictWord{6, 0, 62}, - dictWord{6, 0, 374}, - dictWord{135, 0, 1391}, - dictWord{9, 0, 790}, - dictWord{12, 0, 47}, - dictWord{4, 11, 579}, - dictWord{5, 11, 226}, - dictWord{5, 11, 323}, - dictWord{135, 11, 960}, - dictWord{10, 11, 784}, - dictWord{141, 11, 191}, - dictWord{4, 0, 391}, - dictWord{135, 0, 1169}, - dictWord{137, 0, 443}, - dictWord{13, 11, 232}, - dictWord{146, 11, 35}, - dictWord{132, 10, 340}, - dictWord{132, 0, 271}, - dictWord{ - 137, - 11, - 313, - }, - dictWord{5, 11, 973}, - dictWord{137, 11, 659}, - dictWord{134, 0, 1140}, - dictWord{6, 11, 135}, - dictWord{135, 11, 1176}, - dictWord{4, 0, 253}, - dictWord{5, 0, 544}, - dictWord{7, 0, 300}, - dictWord{137, 0, 340}, - dictWord{7, 0, 897}, - dictWord{5, 10, 985}, - dictWord{7, 10, 509}, - dictWord{145, 10, 96}, - dictWord{ - 138, - 11, - 735, - }, - dictWord{135, 10, 1919}, - dictWord{138, 0, 890}, - dictWord{5, 0, 818}, - dictWord{134, 0, 1122}, - dictWord{5, 0, 53}, - dictWord{5, 0, 541}, - dictWord{ - 6, - 0, - 94, - }, - dictWord{6, 0, 499}, - dictWord{7, 0, 230}, - dictWord{139, 0, 321}, - dictWord{4, 0, 920}, - dictWord{5, 0, 25}, - dictWord{5, 0, 790}, - dictWord{6, 0, 457}, - dictWord{ - 7, - 0, - 853, - }, - dictWord{8, 0, 788}, - dictWord{142, 11, 31}, - dictWord{132, 10, 247}, - dictWord{135, 11, 314}, - dictWord{132, 0, 468}, - dictWord{7, 0, 243}, - dictWord{ - 6, - 10, - 337, - }, - dictWord{7, 10, 494}, - dictWord{8, 10, 27}, - dictWord{8, 10, 599}, - dictWord{138, 10, 153}, - dictWord{4, 10, 184}, - dictWord{5, 10, 390}, - dictWord{ - 7, - 10, - 618, - }, - dictWord{7, 10, 1456}, - dictWord{139, 10, 710}, - dictWord{134, 0, 870}, - dictWord{134, 0, 1238}, - dictWord{134, 0, 1765}, - dictWord{10, 0, 853}, - dictWord{10, 0, 943}, - dictWord{14, 0, 437}, - dictWord{14, 0, 439}, - dictWord{14, 0, 443}, - dictWord{14, 0, 446}, - dictWord{14, 0, 452}, - dictWord{14, 0, 469}, - dictWord{ - 14, - 0, - 471, - }, - dictWord{14, 0, 473}, - dictWord{16, 0, 93}, - dictWord{16, 0, 102}, - dictWord{16, 0, 110}, - dictWord{148, 0, 121}, - dictWord{4, 0, 605}, - dictWord{ - 7, - 0, - 518, - }, - dictWord{7, 0, 1282}, - dictWord{7, 0, 1918}, - dictWord{10, 0, 180}, - dictWord{139, 0, 218}, - dictWord{133, 0, 822}, - dictWord{4, 0, 634}, - dictWord{ - 11, - 0, - 916, - }, - dictWord{142, 0, 419}, - dictWord{6, 11, 281}, - dictWord{7, 11, 6}, - dictWord{8, 11, 282}, - dictWord{8, 11, 480}, - dictWord{8, 11, 499}, - dictWord{9, 11, 198}, - dictWord{10, 11, 143}, - dictWord{10, 11, 169}, - dictWord{10, 11, 211}, - dictWord{10, 11, 417}, - dictWord{10, 11, 574}, - dictWord{11, 11, 147}, - dictWord{ - 11, - 11, - 395, - }, - dictWord{12, 11, 75}, - dictWord{12, 11, 407}, - dictWord{12, 11, 608}, - dictWord{13, 11, 500}, - dictWord{142, 11, 251}, - dictWord{134, 0, 898}, - dictWord{ - 6, - 0, - 36, - }, - dictWord{7, 0, 658}, - dictWord{8, 0, 454}, - dictWord{150, 11, 48}, - dictWord{133, 11, 674}, - dictWord{135, 11, 1776}, - dictWord{4, 11, 419}, - dictWord{ - 10, - 10, - 227, - }, - dictWord{11, 10, 497}, - dictWord{11, 10, 709}, - dictWord{140, 10, 415}, - dictWord{6, 10, 360}, - dictWord{7, 10, 1664}, - dictWord{136, 10, 478}, - dictWord{137, 0, 806}, - dictWord{12, 11, 508}, - dictWord{14, 11, 102}, - dictWord{14, 11, 226}, - dictWord{144, 11, 57}, - dictWord{135, 11, 1123}, - dictWord{ - 4, - 11, - 138, - }, - dictWord{7, 11, 1012}, - dictWord{7, 11, 1280}, - dictWord{137, 11, 76}, - dictWord{5, 11, 29}, - dictWord{140, 11, 638}, - dictWord{136, 10, 699}, - dictWord{134, 0, 1326}, - dictWord{132, 0, 104}, - dictWord{135, 11, 735}, - dictWord{132, 10, 739}, - dictWord{134, 0, 1331}, - dictWord{7, 0, 260}, - dictWord{ - 135, - 11, - 260, - }, - dictWord{135, 11, 1063}, - dictWord{7, 0, 45}, - dictWord{9, 0, 542}, - dictWord{9, 0, 566}, - dictWord{10, 0, 728}, - dictWord{137, 10, 869}, - dictWord{ - 4, - 10, - 67, - }, - dictWord{5, 10, 422}, - dictWord{7, 10, 1037}, - dictWord{7, 10, 1289}, - dictWord{7, 10, 1555}, - dictWord{9, 10, 741}, - dictWord{145, 10, 108}, - dictWord{ - 139, - 0, - 263, - }, - dictWord{134, 0, 1516}, - dictWord{14, 0, 146}, - dictWord{15, 0, 42}, - dictWord{16, 0, 23}, - dictWord{17, 0, 86}, - dictWord{146, 0, 17}, - dictWord{ - 138, - 0, - 468, - }, - dictWord{136, 0, 1005}, - dictWord{4, 11, 17}, - dictWord{5, 11, 23}, - dictWord{7, 11, 995}, - dictWord{11, 11, 383}, - dictWord{11, 11, 437}, - dictWord{ - 12, - 11, - 460, - }, - dictWord{140, 11, 532}, - dictWord{7, 0, 87}, - dictWord{142, 0, 288}, - dictWord{138, 10, 96}, - dictWord{135, 11, 626}, - dictWord{144, 10, 26}, - dictWord{ - 7, - 0, - 988, - }, - dictWord{7, 0, 1939}, - dictWord{9, 0, 64}, - dictWord{9, 0, 502}, - dictWord{12, 0, 22}, - dictWord{12, 0, 34}, - dictWord{13, 0, 12}, - dictWord{13, 0, 234}, - dictWord{147, 0, 77}, - dictWord{13, 0, 133}, - dictWord{8, 10, 203}, - dictWord{11, 10, 823}, - dictWord{11, 10, 846}, - dictWord{12, 10, 482}, - dictWord{13, 10, 277}, - dictWord{13, 10, 302}, - dictWord{13, 10, 464}, - dictWord{14, 10, 205}, - dictWord{142, 10, 221}, - dictWord{4, 10, 449}, - dictWord{133, 10, 718}, - dictWord{ - 135, - 0, - 141, - }, - dictWord{6, 0, 1842}, - dictWord{136, 0, 872}, - dictWord{8, 11, 70}, - dictWord{12, 11, 171}, - dictWord{141, 11, 272}, - dictWord{4, 10, 355}, - dictWord{ - 6, - 10, - 311, - }, - dictWord{9, 10, 256}, - dictWord{138, 10, 404}, - dictWord{132, 0, 619}, - dictWord{137, 0, 261}, - dictWord{10, 11, 233}, - dictWord{10, 10, 758}, - dictWord{139, 11, 76}, - dictWord{5, 0, 246}, - dictWord{8, 0, 189}, - dictWord{9, 0, 355}, - dictWord{9, 0, 512}, - dictWord{10, 0, 124}, - dictWord{10, 0, 453}, - dictWord{ - 11, - 0, - 143, - }, - dictWord{11, 0, 416}, - dictWord{11, 0, 859}, - dictWord{141, 0, 341}, - dictWord{134, 11, 442}, - dictWord{133, 10, 827}, - dictWord{5, 10, 64}, - dictWord{ - 140, - 10, - 581, - }, - dictWord{4, 10, 442}, - dictWord{7, 10, 1047}, - dictWord{7, 10, 1352}, - dictWord{135, 10, 1643}, - dictWord{134, 11, 1709}, - dictWord{5, 0, 678}, - dictWord{6, 0, 305}, - dictWord{7, 0, 775}, - dictWord{7, 0, 1065}, - dictWord{133, 10, 977}, - dictWord{11, 11, 69}, - dictWord{12, 11, 105}, - dictWord{12, 11, 117}, - dictWord{13, 11, 213}, - dictWord{14, 11, 13}, - dictWord{14, 11, 62}, - dictWord{14, 11, 177}, - dictWord{14, 11, 421}, - dictWord{15, 11, 19}, - dictWord{146, 11, 141}, - dictWord{137, 11, 309}, - dictWord{5, 0, 35}, - dictWord{7, 0, 862}, - dictWord{7, 0, 1886}, - dictWord{138, 0, 179}, - dictWord{136, 0, 285}, - dictWord{132, 0, 517}, - dictWord{7, 11, 976}, - dictWord{9, 11, 146}, - dictWord{10, 11, 206}, - dictWord{10, 11, 596}, - dictWord{13, 11, 218}, - dictWord{142, 11, 153}, - dictWord{ - 132, - 10, - 254, - }, - dictWord{6, 0, 214}, - dictWord{12, 0, 540}, - dictWord{4, 10, 275}, - dictWord{7, 10, 1219}, - dictWord{140, 10, 376}, - dictWord{8, 0, 667}, - dictWord{ - 11, - 0, - 403, - }, - dictWord{146, 0, 83}, - dictWord{12, 0, 74}, - dictWord{10, 11, 648}, - dictWord{11, 11, 671}, - dictWord{143, 11, 46}, - dictWord{135, 0, 125}, - dictWord{ - 134, - 10, - 1753, - }, - dictWord{133, 0, 761}, - dictWord{6, 0, 912}, - dictWord{4, 11, 518}, - dictWord{6, 10, 369}, - dictWord{6, 10, 502}, - dictWord{7, 10, 1036}, - dictWord{ - 7, - 11, - 1136, - }, - dictWord{8, 10, 348}, - dictWord{9, 10, 452}, - dictWord{10, 10, 26}, - dictWord{11, 10, 224}, - dictWord{11, 10, 387}, - dictWord{11, 10, 772}, - dictWord{12, 10, 95}, - dictWord{12, 10, 629}, - dictWord{13, 10, 195}, - dictWord{13, 10, 207}, - dictWord{13, 10, 241}, - dictWord{14, 10, 260}, - dictWord{14, 10, 270}, - dictWord{143, 10, 140}, - dictWord{10, 0, 131}, - dictWord{140, 0, 72}, - dictWord{132, 10, 269}, - dictWord{5, 10, 480}, - dictWord{7, 10, 532}, - dictWord{ - 7, - 10, - 1197, - }, - dictWord{7, 10, 1358}, - dictWord{8, 10, 291}, - dictWord{11, 10, 349}, - dictWord{142, 10, 396}, - dictWord{8, 11, 689}, - dictWord{137, 11, 863}, - dictWord{ - 8, - 0, - 333, - }, - dictWord{138, 0, 182}, - dictWord{4, 11, 18}, - dictWord{7, 11, 145}, - dictWord{7, 11, 444}, - dictWord{7, 11, 1278}, - dictWord{8, 11, 49}, - dictWord{ - 8, - 11, - 400, - }, - dictWord{9, 11, 71}, - dictWord{9, 11, 250}, - dictWord{10, 11, 459}, - dictWord{12, 11, 160}, - dictWord{144, 11, 24}, - dictWord{14, 11, 35}, - dictWord{ - 142, - 11, - 191, - }, - dictWord{135, 11, 1864}, - dictWord{135, 0, 1338}, - dictWord{148, 10, 15}, - dictWord{14, 0, 94}, - dictWord{15, 0, 65}, - dictWord{16, 0, 4}, - dictWord{ - 16, - 0, - 77, - }, - dictWord{16, 0, 80}, - dictWord{145, 0, 5}, - dictWord{12, 11, 82}, - dictWord{143, 11, 36}, - dictWord{133, 11, 1010}, - dictWord{133, 0, 449}, - dictWord{ - 133, - 0, - 646, - }, - dictWord{7, 0, 86}, - dictWord{8, 0, 103}, - dictWord{135, 10, 657}, - dictWord{7, 0, 2028}, - dictWord{138, 0, 641}, - dictWord{136, 10, 533}, - dictWord{ - 134, - 0, - 1, - }, - dictWord{139, 11, 970}, - dictWord{5, 11, 87}, - dictWord{7, 11, 313}, - dictWord{7, 11, 1103}, - dictWord{10, 11, 112}, - dictWord{10, 11, 582}, - dictWord{ - 11, - 11, - 389, - }, - dictWord{11, 11, 813}, - dictWord{12, 11, 385}, - dictWord{13, 11, 286}, - dictWord{14, 11, 124}, - dictWord{146, 11, 108}, - dictWord{6, 0, 869}, - dictWord{ - 132, - 11, - 267, - }, - dictWord{6, 0, 277}, - dictWord{7, 0, 1274}, - dictWord{7, 0, 1386}, - dictWord{146, 0, 87}, - dictWord{6, 0, 187}, - dictWord{7, 0, 39}, - dictWord{7, 0, 1203}, - dictWord{8, 0, 380}, - dictWord{14, 0, 117}, - dictWord{149, 0, 28}, - dictWord{4, 10, 211}, - dictWord{4, 10, 332}, - dictWord{5, 10, 335}, - dictWord{6, 10, 238}, - dictWord{ - 7, - 10, - 269, - }, - dictWord{7, 10, 811}, - dictWord{7, 10, 1797}, - dictWord{8, 10, 836}, - dictWord{9, 10, 507}, - dictWord{141, 10, 242}, - dictWord{4, 0, 785}, - dictWord{ - 5, - 0, - 368, - }, - dictWord{6, 0, 297}, - dictWord{7, 0, 793}, - dictWord{139, 0, 938}, - dictWord{7, 0, 464}, - dictWord{8, 0, 558}, - dictWord{11, 0, 105}, - dictWord{12, 0, 231}, - dictWord{14, 0, 386}, - dictWord{15, 0, 102}, - dictWord{148, 0, 75}, - dictWord{133, 10, 1009}, - dictWord{8, 0, 877}, - dictWord{140, 0, 731}, - dictWord{ - 139, - 11, - 289, - }, - dictWord{10, 11, 249}, - dictWord{139, 11, 209}, - dictWord{132, 11, 561}, - dictWord{134, 0, 1608}, - dictWord{132, 11, 760}, - dictWord{134, 0, 1429}, - dictWord{9, 11, 154}, - dictWord{140, 11, 485}, - dictWord{5, 10, 228}, - dictWord{6, 10, 203}, - dictWord{7, 10, 156}, - dictWord{8, 10, 347}, - dictWord{ - 137, - 10, - 265, - }, - dictWord{7, 0, 1010}, - dictWord{11, 0, 733}, - dictWord{11, 0, 759}, - dictWord{13, 0, 34}, - dictWord{14, 0, 427}, - dictWord{146, 0, 45}, - dictWord{7, 10, 1131}, - dictWord{135, 10, 1468}, - dictWord{136, 11, 255}, - dictWord{7, 0, 1656}, - dictWord{9, 0, 369}, - dictWord{10, 0, 338}, - dictWord{10, 0, 490}, - dictWord{ - 11, - 0, - 154, - }, - dictWord{11, 0, 545}, - dictWord{11, 0, 775}, - dictWord{13, 0, 77}, - dictWord{141, 0, 274}, - dictWord{133, 11, 621}, - dictWord{134, 0, 1038}, - dictWord{ - 4, - 11, - 368, - }, - dictWord{135, 11, 641}, - dictWord{6, 0, 2010}, - dictWord{8, 0, 979}, - dictWord{8, 0, 985}, - dictWord{10, 0, 951}, - dictWord{138, 0, 1011}, - dictWord{ - 134, - 0, - 1005, - }, - dictWord{19, 0, 121}, - dictWord{5, 10, 291}, - dictWord{5, 10, 318}, - dictWord{7, 10, 765}, - dictWord{9, 10, 389}, - dictWord{140, 10, 548}, - dictWord{ - 5, - 0, - 20, - }, - dictWord{6, 0, 298}, - dictWord{7, 0, 659}, - dictWord{137, 0, 219}, - dictWord{7, 0, 1440}, - dictWord{11, 0, 854}, - dictWord{11, 0, 872}, - dictWord{11, 0, 921}, - dictWord{12, 0, 551}, - dictWord{13, 0, 472}, - dictWord{142, 0, 367}, - dictWord{5, 0, 490}, - dictWord{6, 0, 615}, - dictWord{6, 0, 620}, - dictWord{135, 0, 683}, - dictWord{ - 6, - 0, - 1070, - }, - dictWord{134, 0, 1597}, - dictWord{139, 0, 522}, - dictWord{132, 0, 439}, - dictWord{136, 0, 669}, - dictWord{6, 0, 766}, - dictWord{6, 0, 1143}, - dictWord{ - 6, - 0, - 1245, - }, - dictWord{10, 10, 525}, - dictWord{139, 10, 82}, - dictWord{9, 11, 92}, - dictWord{147, 11, 91}, - dictWord{6, 0, 668}, - dictWord{134, 0, 1218}, - dictWord{ - 6, - 11, - 525, - }, - dictWord{9, 11, 876}, - dictWord{140, 11, 284}, - dictWord{132, 0, 233}, - dictWord{136, 0, 547}, - dictWord{132, 10, 422}, - dictWord{5, 10, 355}, - dictWord{145, 10, 0}, - dictWord{6, 11, 300}, - dictWord{135, 11, 1515}, - dictWord{4, 0, 482}, - dictWord{137, 10, 905}, - dictWord{4, 0, 886}, - dictWord{7, 0, 346}, - dictWord{133, 11, 594}, - dictWord{133, 10, 865}, - dictWord{5, 10, 914}, - dictWord{134, 10, 1625}, - dictWord{135, 0, 334}, - dictWord{5, 0, 795}, - dictWord{ - 6, - 0, - 1741, - }, - dictWord{133, 10, 234}, - dictWord{135, 10, 1383}, - dictWord{6, 11, 1641}, - dictWord{136, 11, 820}, - dictWord{135, 0, 371}, - dictWord{7, 11, 1313}, - dictWord{138, 11, 660}, - dictWord{135, 10, 1312}, - dictWord{135, 0, 622}, - dictWord{7, 0, 625}, - dictWord{135, 0, 1750}, - dictWord{135, 0, 339}, - dictWord{ - 4, - 0, - 203, - }, - dictWord{135, 0, 1936}, - dictWord{15, 0, 29}, - dictWord{16, 0, 38}, - dictWord{15, 11, 29}, - dictWord{144, 11, 38}, - dictWord{5, 0, 338}, - dictWord{ - 135, - 0, - 1256, - }, - dictWord{135, 10, 1493}, - dictWord{10, 0, 130}, - dictWord{6, 10, 421}, - dictWord{7, 10, 61}, - dictWord{7, 10, 1540}, - dictWord{138, 10, 501}, - dictWord{ - 6, - 11, - 389, - }, - dictWord{7, 11, 149}, - dictWord{9, 11, 142}, - dictWord{138, 11, 94}, - dictWord{137, 10, 341}, - dictWord{11, 0, 678}, - dictWord{12, 0, 307}, - dictWord{142, 10, 98}, - dictWord{6, 11, 8}, - dictWord{7, 11, 1881}, - dictWord{136, 11, 91}, - dictWord{135, 0, 2044}, - dictWord{6, 0, 770}, - dictWord{6, 0, 802}, - dictWord{ - 6, - 0, - 812, - }, - dictWord{7, 0, 311}, - dictWord{9, 0, 308}, - dictWord{12, 0, 255}, - dictWord{6, 10, 102}, - dictWord{7, 10, 72}, - dictWord{15, 10, 142}, - dictWord{ - 147, - 10, - 67, - }, - dictWord{151, 10, 30}, - dictWord{135, 10, 823}, - dictWord{135, 0, 1266}, - dictWord{135, 11, 1746}, - dictWord{135, 10, 1870}, - dictWord{4, 0, 400}, - dictWord{5, 0, 267}, - dictWord{135, 0, 232}, - dictWord{7, 11, 24}, - dictWord{11, 11, 542}, - dictWord{139, 11, 852}, - dictWord{135, 11, 1739}, - dictWord{4, 11, 503}, - dictWord{135, 11, 1661}, - dictWord{5, 11, 130}, - dictWord{7, 11, 1314}, - dictWord{9, 11, 610}, - dictWord{10, 11, 718}, - dictWord{11, 11, 601}, - dictWord{ - 11, - 11, - 819, - }, - dictWord{11, 11, 946}, - dictWord{140, 11, 536}, - dictWord{10, 11, 149}, - dictWord{11, 11, 280}, - dictWord{142, 11, 336}, - dictWord{7, 0, 739}, - dictWord{11, 0, 690}, - dictWord{7, 11, 1946}, - dictWord{8, 10, 48}, - dictWord{8, 10, 88}, - dictWord{8, 10, 582}, - dictWord{8, 10, 681}, - dictWord{9, 10, 373}, - dictWord{ - 9, - 10, - 864, - }, - dictWord{11, 10, 157}, - dictWord{11, 10, 843}, - dictWord{148, 10, 27}, - dictWord{134, 0, 990}, - dictWord{4, 10, 88}, - dictWord{5, 10, 137}, - dictWord{ - 5, - 10, - 174, - }, - dictWord{5, 10, 777}, - dictWord{6, 10, 1664}, - dictWord{6, 10, 1725}, - dictWord{7, 10, 77}, - dictWord{7, 10, 426}, - dictWord{7, 10, 1317}, - dictWord{ - 7, - 10, - 1355, - }, - dictWord{8, 10, 126}, - dictWord{8, 10, 563}, - dictWord{9, 10, 523}, - dictWord{9, 10, 750}, - dictWord{10, 10, 310}, - dictWord{10, 10, 836}, - dictWord{ - 11, - 10, - 42, - }, - dictWord{11, 10, 318}, - dictWord{11, 10, 731}, - dictWord{12, 10, 68}, - dictWord{12, 10, 92}, - dictWord{12, 10, 507}, - dictWord{12, 10, 692}, - dictWord{ - 13, - 10, - 81, - }, - dictWord{13, 10, 238}, - dictWord{13, 10, 374}, - dictWord{14, 10, 436}, - dictWord{18, 10, 138}, - dictWord{19, 10, 78}, - dictWord{19, 10, 111}, - dictWord{20, 10, 55}, - dictWord{20, 10, 77}, - dictWord{148, 10, 92}, - dictWord{141, 10, 418}, - dictWord{7, 0, 1831}, - dictWord{132, 10, 938}, - dictWord{6, 0, 776}, - dictWord{134, 0, 915}, - dictWord{138, 10, 351}, - dictWord{5, 11, 348}, - dictWord{6, 11, 522}, - dictWord{6, 10, 1668}, - dictWord{7, 10, 1499}, - dictWord{8, 10, 117}, - dictWord{9, 10, 314}, - dictWord{138, 10, 174}, - dictWord{135, 10, 707}, - dictWord{132, 0, 613}, - dictWord{133, 10, 403}, - dictWord{132, 11, 392}, - dictWord{ - 5, - 11, - 433, - }, - dictWord{9, 11, 633}, - dictWord{139, 11, 629}, - dictWord{133, 0, 763}, - dictWord{132, 0, 878}, - dictWord{132, 0, 977}, - dictWord{132, 0, 100}, - dictWord{6, 0, 463}, - dictWord{4, 10, 44}, - dictWord{5, 10, 311}, - dictWord{7, 10, 639}, - dictWord{7, 10, 762}, - dictWord{7, 10, 1827}, - dictWord{9, 10, 8}, - dictWord{ - 9, - 10, - 462, - }, - dictWord{148, 10, 83}, - dictWord{134, 11, 234}, - dictWord{4, 10, 346}, - dictWord{7, 10, 115}, - dictWord{9, 10, 180}, - dictWord{9, 10, 456}, - dictWord{ - 138, - 10, - 363, - }, - dictWord{5, 0, 362}, - dictWord{5, 0, 443}, - dictWord{6, 0, 318}, - dictWord{7, 0, 1019}, - dictWord{139, 0, 623}, - dictWord{5, 0, 463}, - dictWord{8, 0, 296}, - dictWord{7, 11, 140}, - dictWord{7, 11, 1950}, - dictWord{8, 11, 680}, - dictWord{11, 11, 817}, - dictWord{147, 11, 88}, - dictWord{7, 11, 1222}, - dictWord{ - 138, - 11, - 386, - }, - dictWord{142, 0, 137}, - dictWord{132, 0, 454}, - dictWord{7, 0, 1914}, - dictWord{6, 11, 5}, - dictWord{7, 10, 1051}, - dictWord{9, 10, 545}, - dictWord{ - 11, - 11, - 249, - }, - dictWord{12, 11, 313}, - dictWord{16, 11, 66}, - dictWord{145, 11, 26}, - dictWord{135, 0, 1527}, - dictWord{145, 0, 58}, - dictWord{148, 11, 59}, - dictWord{ - 5, - 0, - 48, - }, - dictWord{5, 0, 404}, - dictWord{6, 0, 557}, - dictWord{7, 0, 458}, - dictWord{8, 0, 597}, - dictWord{10, 0, 455}, - dictWord{10, 0, 606}, - dictWord{11, 0, 49}, - dictWord{ - 11, - 0, - 548, - }, - dictWord{12, 0, 476}, - dictWord{13, 0, 18}, - dictWord{141, 0, 450}, - dictWord{5, 11, 963}, - dictWord{134, 11, 1773}, - dictWord{133, 0, 729}, - dictWord{138, 11, 586}, - dictWord{5, 0, 442}, - dictWord{135, 0, 1984}, - dictWord{134, 0, 449}, - dictWord{144, 0, 40}, - dictWord{4, 0, 853}, - dictWord{7, 11, 180}, - dictWord{8, 11, 509}, - dictWord{136, 11, 792}, - dictWord{6, 10, 185}, - dictWord{7, 10, 1899}, - dictWord{9, 10, 875}, - dictWord{139, 10, 673}, - dictWord{ - 134, - 11, - 524, - }, - dictWord{12, 0, 227}, - dictWord{4, 10, 327}, - dictWord{5, 10, 478}, - dictWord{7, 10, 1332}, - dictWord{136, 10, 753}, - dictWord{6, 0, 1491}, - dictWord{ - 5, - 10, - 1020, - }, - dictWord{133, 10, 1022}, - dictWord{4, 10, 103}, - dictWord{133, 10, 401}, - dictWord{132, 11, 931}, - dictWord{4, 10, 499}, - dictWord{135, 10, 1421}, - dictWord{5, 0, 55}, - dictWord{7, 0, 376}, - dictWord{140, 0, 161}, - dictWord{133, 0, 450}, - dictWord{6, 0, 1174}, - dictWord{134, 0, 1562}, - dictWord{10, 0, 62}, - dictWord{13, 0, 400}, - dictWord{135, 11, 1837}, - dictWord{140, 0, 207}, - dictWord{135, 0, 869}, - dictWord{4, 11, 773}, - dictWord{5, 11, 618}, - dictWord{ - 137, - 11, - 756, - }, - dictWord{132, 10, 96}, - dictWord{4, 0, 213}, - dictWord{7, 0, 223}, - dictWord{8, 0, 80}, - dictWord{135, 10, 968}, - dictWord{4, 11, 90}, - dictWord{5, 11, 337}, - dictWord{5, 11, 545}, - dictWord{7, 11, 754}, - dictWord{9, 11, 186}, - dictWord{10, 11, 72}, - dictWord{10, 11, 782}, - dictWord{11, 11, 513}, - dictWord{11, 11, 577}, - dictWord{11, 11, 610}, - dictWord{11, 11, 889}, - dictWord{11, 11, 961}, - dictWord{12, 11, 354}, - dictWord{12, 11, 362}, - dictWord{12, 11, 461}, - dictWord{ - 12, - 11, - 595, - }, - dictWord{13, 11, 79}, - dictWord{143, 11, 121}, - dictWord{7, 0, 381}, - dictWord{7, 0, 806}, - dictWord{7, 0, 820}, - dictWord{8, 0, 354}, - dictWord{8, 0, 437}, - dictWord{8, 0, 787}, - dictWord{9, 0, 657}, - dictWord{10, 0, 58}, - dictWord{10, 0, 339}, - dictWord{10, 0, 749}, - dictWord{11, 0, 914}, - dictWord{12, 0, 162}, - dictWord{ - 13, - 0, - 75, - }, - dictWord{14, 0, 106}, - dictWord{14, 0, 198}, - dictWord{14, 0, 320}, - dictWord{14, 0, 413}, - dictWord{146, 0, 43}, - dictWord{136, 0, 747}, - dictWord{ - 136, - 0, - 954, - }, - dictWord{134, 0, 1073}, - dictWord{135, 0, 556}, - dictWord{7, 11, 151}, - dictWord{9, 11, 329}, - dictWord{139, 11, 254}, - dictWord{5, 0, 692}, - dictWord{ - 134, - 0, - 1395, - }, - dictWord{6, 10, 563}, - dictWord{137, 10, 224}, - dictWord{134, 0, 191}, - dictWord{132, 0, 804}, - dictWord{9, 11, 187}, - dictWord{10, 11, 36}, - dictWord{17, 11, 44}, - dictWord{146, 11, 64}, - dictWord{7, 11, 165}, - dictWord{7, 11, 919}, - dictWord{136, 11, 517}, - dictWord{4, 11, 506}, - dictWord{5, 11, 295}, - dictWord{7, 11, 1680}, - dictWord{15, 11, 14}, - dictWord{144, 11, 5}, - dictWord{4, 0, 706}, - dictWord{6, 0, 162}, - dictWord{7, 0, 1960}, - dictWord{136, 0, 831}, - dictWord{ - 135, - 11, - 1376, - }, - dictWord{7, 11, 987}, - dictWord{9, 11, 688}, - dictWord{10, 11, 522}, - dictWord{11, 11, 788}, - dictWord{140, 11, 566}, - dictWord{150, 0, 35}, - dictWord{138, 0, 426}, - dictWord{135, 0, 1235}, - dictWord{135, 11, 1741}, - dictWord{7, 11, 389}, - dictWord{7, 11, 700}, - dictWord{7, 11, 940}, - dictWord{ - 8, - 11, - 514, - }, - dictWord{9, 11, 116}, - dictWord{9, 11, 535}, - dictWord{10, 11, 118}, - dictWord{11, 11, 107}, - dictWord{11, 11, 148}, - dictWord{11, 11, 922}, - dictWord{ - 12, - 11, - 254, - }, - dictWord{12, 11, 421}, - dictWord{142, 11, 238}, - dictWord{134, 0, 1234}, - dictWord{132, 11, 743}, - dictWord{4, 10, 910}, - dictWord{5, 10, 832}, - dictWord{135, 11, 1335}, - dictWord{141, 0, 96}, - dictWord{135, 11, 185}, - dictWord{146, 0, 149}, - dictWord{4, 0, 204}, - dictWord{137, 0, 902}, - dictWord{ - 4, - 11, - 784, - }, - dictWord{133, 11, 745}, - dictWord{136, 0, 833}, - dictWord{136, 0, 949}, - dictWord{7, 0, 366}, - dictWord{9, 0, 287}, - dictWord{12, 0, 199}, - dictWord{ - 12, - 0, - 556, - }, - dictWord{12, 0, 577}, - dictWord{5, 11, 81}, - dictWord{7, 11, 146}, - dictWord{7, 11, 1342}, - dictWord{7, 11, 1446}, - dictWord{8, 11, 53}, - dictWord{8, 11, 561}, - dictWord{8, 11, 694}, - dictWord{8, 11, 754}, - dictWord{9, 11, 97}, - dictWord{9, 11, 115}, - dictWord{9, 11, 894}, - dictWord{10, 11, 462}, - dictWord{10, 11, 813}, - dictWord{11, 11, 230}, - dictWord{11, 11, 657}, - dictWord{11, 11, 699}, - dictWord{11, 11, 748}, - dictWord{12, 11, 119}, - dictWord{12, 11, 200}, - dictWord{ - 12, - 11, - 283, - }, - dictWord{14, 11, 273}, - dictWord{145, 11, 15}, - dictWord{5, 11, 408}, - dictWord{137, 11, 747}, - dictWord{9, 11, 498}, - dictWord{140, 11, 181}, - dictWord{ - 6, - 0, - 2020, - }, - dictWord{136, 0, 992}, - dictWord{5, 0, 356}, - dictWord{135, 0, 224}, - dictWord{134, 0, 784}, - dictWord{7, 0, 630}, - dictWord{9, 0, 567}, - dictWord{ - 11, - 0, - 150, - }, - dictWord{11, 0, 444}, - dictWord{13, 0, 119}, - dictWord{8, 10, 528}, - dictWord{137, 10, 348}, - dictWord{134, 0, 539}, - dictWord{4, 10, 20}, - dictWord{ - 133, - 10, - 616, - }, - dictWord{142, 0, 27}, - dictWord{7, 11, 30}, - dictWord{8, 11, 86}, - dictWord{8, 11, 315}, - dictWord{8, 11, 700}, - dictWord{9, 11, 576}, - dictWord{9, 11, 858}, - dictWord{11, 11, 310}, - dictWord{11, 11, 888}, - dictWord{11, 11, 904}, - dictWord{12, 11, 361}, - dictWord{141, 11, 248}, - dictWord{138, 11, 839}, - dictWord{ - 134, - 0, - 755, - }, - dictWord{134, 0, 1063}, - dictWord{7, 10, 1091}, - dictWord{135, 10, 1765}, - dictWord{134, 11, 428}, - dictWord{7, 11, 524}, - dictWord{8, 11, 169}, - dictWord{8, 11, 234}, - dictWord{9, 11, 480}, - dictWord{138, 11, 646}, - dictWord{139, 0, 814}, - dictWord{7, 11, 1462}, - dictWord{139, 11, 659}, - dictWord{ - 4, - 10, - 26, - }, - dictWord{5, 10, 429}, - dictWord{6, 10, 245}, - dictWord{7, 10, 704}, - dictWord{7, 10, 1379}, - dictWord{135, 10, 1474}, - dictWord{7, 11, 1205}, - dictWord{ - 138, - 11, - 637, - }, - dictWord{139, 11, 803}, - dictWord{132, 10, 621}, - dictWord{136, 0, 987}, - dictWord{4, 11, 266}, - dictWord{8, 11, 4}, - dictWord{9, 11, 39}, - dictWord{ - 10, - 11, - 166, - }, - dictWord{11, 11, 918}, - dictWord{12, 11, 635}, - dictWord{20, 11, 10}, - dictWord{22, 11, 27}, - dictWord{150, 11, 43}, - dictWord{4, 0, 235}, - dictWord{ - 135, - 0, - 255, - }, - dictWord{4, 0, 194}, - dictWord{5, 0, 584}, - dictWord{6, 0, 384}, - dictWord{7, 0, 583}, - dictWord{10, 0, 761}, - dictWord{11, 0, 760}, - dictWord{139, 0, 851}, - dictWord{133, 10, 542}, - dictWord{134, 0, 1086}, - dictWord{133, 10, 868}, - dictWord{8, 0, 1016}, - dictWord{136, 0, 1018}, - dictWord{7, 0, 1396}, - dictWord{ - 7, - 11, - 1396, - }, - dictWord{136, 10, 433}, - dictWord{135, 10, 1495}, - dictWord{138, 10, 215}, - dictWord{141, 10, 124}, - dictWord{7, 11, 157}, - dictWord{ - 8, - 11, - 279, - }, - dictWord{9, 11, 759}, - dictWord{16, 11, 31}, - dictWord{16, 11, 39}, - dictWord{16, 11, 75}, - dictWord{18, 11, 24}, - dictWord{20, 11, 42}, - dictWord{152, 11, 1}, - dictWord{5, 0, 562}, - dictWord{134, 11, 604}, - dictWord{134, 0, 913}, - dictWord{5, 0, 191}, - dictWord{137, 0, 271}, - dictWord{4, 0, 470}, - dictWord{6, 0, 153}, - dictWord{7, 0, 1503}, - dictWord{7, 0, 1923}, - dictWord{10, 0, 701}, - dictWord{11, 0, 132}, - dictWord{11, 0, 227}, - dictWord{11, 0, 320}, - dictWord{11, 0, 436}, - dictWord{ - 11, - 0, - 525, - }, - dictWord{11, 0, 855}, - dictWord{11, 0, 873}, - dictWord{12, 0, 41}, - dictWord{12, 0, 286}, - dictWord{13, 0, 103}, - dictWord{13, 0, 284}, - dictWord{ - 14, - 0, - 255, - }, - dictWord{14, 0, 262}, - dictWord{15, 0, 117}, - dictWord{143, 0, 127}, - dictWord{7, 0, 475}, - dictWord{12, 0, 45}, - dictWord{147, 10, 112}, - dictWord{ - 132, - 11, - 567, - }, - dictWord{137, 11, 859}, - dictWord{6, 0, 713}, - dictWord{6, 0, 969}, - dictWord{6, 0, 1290}, - dictWord{134, 0, 1551}, - dictWord{133, 0, 327}, - dictWord{ - 6, - 0, - 552, - }, - dictWord{6, 0, 1292}, - dictWord{7, 0, 1754}, - dictWord{137, 0, 604}, - dictWord{4, 0, 223}, - dictWord{6, 0, 359}, - dictWord{11, 0, 3}, - dictWord{13, 0, 108}, - dictWord{14, 0, 89}, - dictWord{16, 0, 22}, - dictWord{5, 11, 762}, - dictWord{7, 11, 1880}, - dictWord{9, 11, 680}, - dictWord{139, 11, 798}, - dictWord{5, 0, 80}, - dictWord{ - 6, - 0, - 405, - }, - dictWord{7, 0, 403}, - dictWord{7, 0, 1502}, - dictWord{8, 0, 456}, - dictWord{9, 0, 487}, - dictWord{9, 0, 853}, - dictWord{9, 0, 889}, - dictWord{10, 0, 309}, - dictWord{ - 11, - 0, - 721, - }, - dictWord{11, 0, 994}, - dictWord{12, 0, 430}, - dictWord{141, 0, 165}, - dictWord{133, 11, 298}, - dictWord{132, 10, 647}, - dictWord{134, 0, 2016}, - dictWord{18, 10, 10}, - dictWord{146, 11, 10}, - dictWord{4, 0, 453}, - dictWord{5, 0, 887}, - dictWord{6, 0, 535}, - dictWord{8, 0, 6}, - dictWord{8, 0, 543}, - dictWord{ - 136, - 0, - 826, - }, - dictWord{136, 0, 975}, - dictWord{10, 0, 961}, - dictWord{138, 0, 962}, - dictWord{138, 10, 220}, - dictWord{6, 0, 1891}, - dictWord{6, 0, 1893}, - dictWord{ - 9, - 0, - 916, - }, - dictWord{9, 0, 965}, - dictWord{9, 0, 972}, - dictWord{12, 0, 801}, - dictWord{12, 0, 859}, - dictWord{12, 0, 883}, - dictWord{15, 0, 226}, - dictWord{149, 0, 51}, - dictWord{132, 10, 109}, - dictWord{135, 11, 267}, - dictWord{7, 11, 92}, - dictWord{7, 11, 182}, - dictWord{8, 11, 453}, - dictWord{9, 11, 204}, - dictWord{11, 11, 950}, - dictWord{12, 11, 94}, - dictWord{12, 11, 644}, - dictWord{16, 11, 20}, - dictWord{16, 11, 70}, - dictWord{16, 11, 90}, - dictWord{147, 11, 55}, - dictWord{ - 134, - 10, - 1746, - }, - dictWord{6, 11, 71}, - dictWord{7, 11, 845}, - dictWord{7, 11, 1308}, - dictWord{8, 11, 160}, - dictWord{137, 11, 318}, - dictWord{5, 0, 101}, - dictWord{6, 0, 88}, - dictWord{7, 0, 263}, - dictWord{7, 0, 628}, - dictWord{7, 0, 1677}, - dictWord{8, 0, 349}, - dictWord{9, 0, 100}, - dictWord{10, 0, 677}, - dictWord{14, 0, 169}, - dictWord{ - 14, - 0, - 302, - }, - dictWord{14, 0, 313}, - dictWord{15, 0, 48}, - dictWord{15, 0, 84}, - dictWord{7, 11, 237}, - dictWord{8, 11, 664}, - dictWord{9, 11, 42}, - dictWord{9, 11, 266}, - dictWord{9, 11, 380}, - dictWord{9, 11, 645}, - dictWord{10, 11, 177}, - dictWord{138, 11, 276}, - dictWord{138, 11, 69}, - dictWord{4, 0, 310}, - dictWord{7, 0, 708}, - dictWord{7, 0, 996}, - dictWord{9, 0, 795}, - dictWord{10, 0, 390}, - dictWord{10, 0, 733}, - dictWord{11, 0, 451}, - dictWord{12, 0, 249}, - dictWord{14, 0, 115}, - dictWord{ - 14, - 0, - 286, - }, - dictWord{143, 0, 100}, - dictWord{5, 0, 587}, - dictWord{4, 10, 40}, - dictWord{10, 10, 67}, - dictWord{11, 10, 117}, - dictWord{11, 10, 768}, - dictWord{ - 139, - 10, - 935, - }, - dictWord{6, 0, 1942}, - dictWord{7, 0, 512}, - dictWord{136, 0, 983}, - dictWord{7, 10, 992}, - dictWord{8, 10, 301}, - dictWord{9, 10, 722}, - dictWord{12, 10, 63}, - dictWord{13, 10, 29}, - dictWord{14, 10, 161}, - dictWord{143, 10, 18}, - dictWord{136, 11, 76}, - dictWord{139, 10, 923}, - dictWord{134, 0, 645}, - dictWord{ - 134, - 0, - 851, - }, - dictWord{4, 0, 498}, - dictWord{132, 11, 293}, - dictWord{7, 0, 217}, - dictWord{8, 0, 140}, - dictWord{10, 0, 610}, - dictWord{14, 11, 352}, - dictWord{ - 17, - 11, - 53, - }, - dictWord{18, 11, 146}, - dictWord{18, 11, 152}, - dictWord{19, 11, 11}, - dictWord{150, 11, 54}, - dictWord{134, 0, 1448}, - dictWord{138, 11, 841}, - dictWord{133, 0, 905}, - dictWord{4, 11, 605}, - dictWord{7, 11, 518}, - dictWord{7, 11, 1282}, - dictWord{7, 11, 1918}, - dictWord{10, 11, 180}, - dictWord{139, 11, 218}, - dictWord{139, 11, 917}, - dictWord{135, 10, 825}, - dictWord{140, 10, 328}, - dictWord{4, 0, 456}, - dictWord{7, 0, 105}, - dictWord{7, 0, 358}, - dictWord{7, 0, 1637}, - dictWord{8, 0, 643}, - dictWord{139, 0, 483}, - dictWord{134, 0, 792}, - dictWord{6, 11, 96}, - dictWord{135, 11, 1426}, - dictWord{137, 11, 691}, - dictWord{ - 4, - 11, - 651, - }, - dictWord{133, 11, 289}, - dictWord{7, 11, 688}, - dictWord{8, 11, 35}, - dictWord{9, 11, 511}, - dictWord{10, 11, 767}, - dictWord{147, 11, 118}, - dictWord{ - 150, - 0, - 56, - }, - dictWord{5, 0, 243}, - dictWord{5, 0, 535}, - dictWord{6, 10, 204}, - dictWord{10, 10, 320}, - dictWord{10, 10, 583}, - dictWord{13, 10, 502}, - dictWord{ - 14, - 10, - 72, - }, - dictWord{14, 10, 274}, - dictWord{14, 10, 312}, - dictWord{14, 10, 344}, - dictWord{15, 10, 159}, - dictWord{16, 10, 62}, - dictWord{16, 10, 69}, - dictWord{ - 17, - 10, - 30, - }, - dictWord{18, 10, 42}, - dictWord{18, 10, 53}, - dictWord{18, 10, 84}, - dictWord{18, 10, 140}, - dictWord{19, 10, 68}, - dictWord{19, 10, 85}, - dictWord{20, 10, 5}, - dictWord{20, 10, 45}, - dictWord{20, 10, 101}, - dictWord{22, 10, 7}, - dictWord{150, 10, 20}, - dictWord{4, 10, 558}, - dictWord{6, 10, 390}, - dictWord{7, 10, 162}, - dictWord{7, 10, 689}, - dictWord{9, 10, 360}, - dictWord{138, 10, 653}, - dictWord{146, 11, 23}, - dictWord{135, 0, 1748}, - dictWord{5, 10, 856}, - dictWord{ - 6, - 10, - 1672, - }, - dictWord{6, 10, 1757}, - dictWord{134, 10, 1781}, - dictWord{5, 0, 539}, - dictWord{5, 0, 754}, - dictWord{6, 0, 876}, - dictWord{132, 11, 704}, - dictWord{ - 135, - 11, - 1078, - }, - dictWord{5, 10, 92}, - dictWord{10, 10, 736}, - dictWord{140, 10, 102}, - dictWord{17, 0, 91}, - dictWord{5, 10, 590}, - dictWord{137, 10, 213}, - dictWord{134, 0, 1565}, - dictWord{6, 0, 91}, - dictWord{135, 0, 435}, - dictWord{4, 0, 939}, - dictWord{140, 0, 792}, - dictWord{134, 0, 1399}, - dictWord{4, 0, 16}, - dictWord{ - 5, - 0, - 316, - }, - dictWord{5, 0, 842}, - dictWord{6, 0, 370}, - dictWord{6, 0, 1778}, - dictWord{8, 0, 166}, - dictWord{11, 0, 812}, - dictWord{12, 0, 206}, - dictWord{12, 0, 351}, - dictWord{14, 0, 418}, - dictWord{16, 0, 15}, - dictWord{16, 0, 34}, - dictWord{18, 0, 3}, - dictWord{19, 0, 3}, - dictWord{19, 0, 7}, - dictWord{20, 0, 4}, - dictWord{21, 0, 21}, - dictWord{ - 4, - 11, - 720, - }, - dictWord{133, 11, 306}, - dictWord{144, 0, 95}, - dictWord{133, 11, 431}, - dictWord{132, 11, 234}, - dictWord{135, 0, 551}, - dictWord{4, 0, 999}, - dictWord{6, 0, 1966}, - dictWord{134, 0, 2042}, - dictWord{7, 0, 619}, - dictWord{10, 0, 547}, - dictWord{11, 0, 122}, - dictWord{12, 0, 601}, - dictWord{15, 0, 7}, - dictWord{148, 0, 20}, - dictWord{5, 11, 464}, - dictWord{6, 11, 236}, - dictWord{7, 11, 276}, - dictWord{7, 11, 696}, - dictWord{7, 11, 914}, - dictWord{7, 11, 1108}, - dictWord{ - 7, - 11, - 1448, - }, - dictWord{9, 11, 15}, - dictWord{9, 11, 564}, - dictWord{10, 11, 14}, - dictWord{12, 11, 565}, - dictWord{13, 11, 449}, - dictWord{14, 11, 53}, - dictWord{ - 15, - 11, - 13, - }, - dictWord{16, 11, 64}, - dictWord{145, 11, 41}, - dictWord{6, 0, 884}, - dictWord{6, 0, 1019}, - dictWord{134, 0, 1150}, - dictWord{6, 11, 1767}, - dictWord{ - 12, - 11, - 194, - }, - dictWord{145, 11, 107}, - dictWord{136, 10, 503}, - dictWord{133, 11, 840}, - dictWord{7, 0, 671}, - dictWord{134, 10, 466}, - dictWord{132, 0, 888}, - dictWord{4, 0, 149}, - dictWord{138, 0, 368}, - dictWord{4, 0, 154}, - dictWord{7, 0, 1134}, - dictWord{136, 0, 105}, - dictWord{135, 0, 983}, - dictWord{9, 11, 642}, - dictWord{11, 11, 236}, - dictWord{142, 11, 193}, - dictWord{4, 0, 31}, - dictWord{6, 0, 429}, - dictWord{7, 0, 962}, - dictWord{9, 0, 458}, - dictWord{139, 0, 691}, - dictWord{ - 6, - 0, - 643, - }, - dictWord{134, 0, 1102}, - dictWord{132, 0, 312}, - dictWord{4, 11, 68}, - dictWord{5, 11, 634}, - dictWord{6, 11, 386}, - dictWord{7, 11, 794}, - dictWord{ - 8, - 11, - 273, - }, - dictWord{9, 11, 563}, - dictWord{10, 11, 105}, - dictWord{10, 11, 171}, - dictWord{11, 11, 94}, - dictWord{139, 11, 354}, - dictWord{133, 0, 740}, - dictWord{ - 135, - 0, - 1642, - }, - dictWord{4, 11, 95}, - dictWord{7, 11, 416}, - dictWord{8, 11, 211}, - dictWord{139, 11, 830}, - dictWord{132, 0, 236}, - dictWord{138, 10, 241}, - dictWord{7, 11, 731}, - dictWord{13, 11, 20}, - dictWord{143, 11, 11}, - dictWord{5, 0, 836}, - dictWord{5, 0, 857}, - dictWord{6, 0, 1680}, - dictWord{135, 0, 59}, - dictWord{ - 10, - 0, - 68, - }, - dictWord{11, 0, 494}, - dictWord{152, 11, 6}, - dictWord{4, 0, 81}, - dictWord{139, 0, 867}, - dictWord{135, 0, 795}, - dictWord{133, 11, 689}, - dictWord{ - 4, - 0, - 1001, - }, - dictWord{5, 0, 282}, - dictWord{6, 0, 1932}, - dictWord{6, 0, 1977}, - dictWord{6, 0, 1987}, - dictWord{6, 0, 1992}, - dictWord{8, 0, 650}, - dictWord{8, 0, 919}, - dictWord{8, 0, 920}, - dictWord{8, 0, 923}, - dictWord{8, 0, 926}, - dictWord{8, 0, 927}, - dictWord{8, 0, 931}, - dictWord{8, 0, 939}, - dictWord{8, 0, 947}, - dictWord{8, 0, 956}, - dictWord{8, 0, 997}, - dictWord{9, 0, 907}, - dictWord{10, 0, 950}, - dictWord{10, 0, 953}, - dictWord{10, 0, 954}, - dictWord{10, 0, 956}, - dictWord{10, 0, 958}, - dictWord{ - 10, - 0, - 959, - }, - dictWord{10, 0, 964}, - dictWord{10, 0, 970}, - dictWord{10, 0, 972}, - dictWord{10, 0, 973}, - dictWord{10, 0, 975}, - dictWord{10, 0, 976}, - dictWord{ - 10, - 0, - 980, - }, - dictWord{10, 0, 981}, - dictWord{10, 0, 984}, - dictWord{10, 0, 988}, - dictWord{10, 0, 990}, - dictWord{10, 0, 995}, - dictWord{10, 0, 999}, - dictWord{ - 10, - 0, - 1002, - }, - dictWord{10, 0, 1003}, - dictWord{10, 0, 1005}, - dictWord{10, 0, 1006}, - dictWord{10, 0, 1008}, - dictWord{10, 0, 1009}, - dictWord{10, 0, 1012}, - dictWord{10, 0, 1014}, - dictWord{10, 0, 1015}, - dictWord{10, 0, 1019}, - dictWord{10, 0, 1020}, - dictWord{10, 0, 1022}, - dictWord{12, 0, 959}, - dictWord{12, 0, 961}, - dictWord{12, 0, 962}, - dictWord{12, 0, 963}, - dictWord{12, 0, 964}, - dictWord{12, 0, 965}, - dictWord{12, 0, 967}, - dictWord{12, 0, 968}, - dictWord{12, 0, 969}, - dictWord{12, 0, 970}, - dictWord{12, 0, 971}, - dictWord{12, 0, 972}, - dictWord{12, 0, 973}, - dictWord{12, 0, 974}, - dictWord{12, 0, 975}, - dictWord{12, 0, 976}, - dictWord{ - 12, - 0, - 977, - }, - dictWord{12, 0, 979}, - dictWord{12, 0, 981}, - dictWord{12, 0, 982}, - dictWord{12, 0, 983}, - dictWord{12, 0, 984}, - dictWord{12, 0, 985}, - dictWord{ - 12, - 0, - 986, - }, - dictWord{12, 0, 987}, - dictWord{12, 0, 989}, - dictWord{12, 0, 990}, - dictWord{12, 0, 992}, - dictWord{12, 0, 993}, - dictWord{12, 0, 995}, - dictWord{12, 0, 998}, - dictWord{12, 0, 999}, - dictWord{12, 0, 1000}, - dictWord{12, 0, 1001}, - dictWord{12, 0, 1002}, - dictWord{12, 0, 1004}, - dictWord{12, 0, 1005}, - dictWord{ - 12, - 0, - 1006, - }, - dictWord{12, 0, 1007}, - dictWord{12, 0, 1008}, - dictWord{12, 0, 1009}, - dictWord{12, 0, 1010}, - dictWord{12, 0, 1011}, - dictWord{12, 0, 1012}, - dictWord{12, 0, 1014}, - dictWord{12, 0, 1015}, - dictWord{12, 0, 1016}, - dictWord{12, 0, 1017}, - dictWord{12, 0, 1018}, - dictWord{12, 0, 1019}, - dictWord{ - 12, - 0, - 1022, - }, - dictWord{12, 0, 1023}, - dictWord{14, 0, 475}, - dictWord{14, 0, 477}, - dictWord{14, 0, 478}, - dictWord{14, 0, 479}, - dictWord{14, 0, 480}, - dictWord{ - 14, - 0, - 482, - }, - dictWord{14, 0, 483}, - dictWord{14, 0, 484}, - dictWord{14, 0, 485}, - dictWord{14, 0, 486}, - dictWord{14, 0, 487}, - dictWord{14, 0, 488}, - dictWord{14, 0, 489}, - dictWord{14, 0, 490}, - dictWord{14, 0, 491}, - dictWord{14, 0, 492}, - dictWord{14, 0, 493}, - dictWord{14, 0, 494}, - dictWord{14, 0, 495}, - dictWord{14, 0, 496}, - dictWord{14, 0, 497}, - dictWord{14, 0, 498}, - dictWord{14, 0, 499}, - dictWord{14, 0, 500}, - dictWord{14, 0, 501}, - dictWord{14, 0, 502}, - dictWord{14, 0, 503}, - dictWord{ - 14, - 0, - 504, - }, - dictWord{14, 0, 506}, - dictWord{14, 0, 507}, - dictWord{14, 0, 508}, - dictWord{14, 0, 509}, - dictWord{14, 0, 510}, - dictWord{14, 0, 511}, - dictWord{ - 16, - 0, - 113, - }, - dictWord{16, 0, 114}, - dictWord{16, 0, 115}, - dictWord{16, 0, 117}, - dictWord{16, 0, 118}, - dictWord{16, 0, 119}, - dictWord{16, 0, 121}, - dictWord{16, 0, 122}, - dictWord{16, 0, 123}, - dictWord{16, 0, 124}, - dictWord{16, 0, 125}, - dictWord{16, 0, 126}, - dictWord{16, 0, 127}, - dictWord{18, 0, 242}, - dictWord{18, 0, 243}, - dictWord{18, 0, 244}, - dictWord{18, 0, 245}, - dictWord{18, 0, 248}, - dictWord{18, 0, 249}, - dictWord{18, 0, 250}, - dictWord{18, 0, 251}, - dictWord{18, 0, 252}, - dictWord{ - 18, - 0, - 253, - }, - dictWord{18, 0, 254}, - dictWord{18, 0, 255}, - dictWord{20, 0, 125}, - dictWord{20, 0, 126}, - dictWord{148, 0, 127}, - dictWord{7, 11, 1717}, - dictWord{ - 7, - 11, - 1769, - }, - dictWord{138, 11, 546}, - dictWord{7, 11, 1127}, - dictWord{7, 11, 1572}, - dictWord{10, 11, 297}, - dictWord{10, 11, 422}, - dictWord{11, 11, 764}, - dictWord{11, 11, 810}, - dictWord{12, 11, 264}, - dictWord{13, 11, 102}, - dictWord{13, 11, 300}, - dictWord{13, 11, 484}, - dictWord{14, 11, 147}, - dictWord{ - 14, - 11, - 229, - }, - dictWord{17, 11, 71}, - dictWord{18, 11, 118}, - dictWord{147, 11, 120}, - dictWord{6, 0, 1148}, - dictWord{134, 0, 1586}, - dictWord{132, 0, 775}, - dictWord{135, 10, 954}, - dictWord{133, 11, 864}, - dictWord{133, 11, 928}, - dictWord{138, 11, 189}, - dictWord{135, 10, 1958}, - dictWord{6, 10, 549}, - dictWord{ - 8, - 10, - 34, - }, - dictWord{8, 10, 283}, - dictWord{9, 10, 165}, - dictWord{138, 10, 475}, - dictWord{5, 10, 652}, - dictWord{5, 10, 701}, - dictWord{135, 10, 449}, - dictWord{135, 11, 695}, - dictWord{4, 10, 655}, - dictWord{7, 10, 850}, - dictWord{17, 10, 75}, - dictWord{146, 10, 137}, - dictWord{140, 11, 682}, - dictWord{ - 133, - 11, - 523, - }, - dictWord{8, 0, 970}, - dictWord{136, 10, 670}, - dictWord{136, 11, 555}, - dictWord{7, 11, 76}, - dictWord{8, 11, 44}, - dictWord{9, 11, 884}, - dictWord{ - 10, - 11, - 580, - }, - dictWord{11, 11, 399}, - dictWord{11, 11, 894}, - dictWord{15, 11, 122}, - dictWord{18, 11, 144}, - dictWord{147, 11, 61}, - dictWord{6, 10, 159}, - dictWord{ - 6, - 10, - 364, - }, - dictWord{7, 10, 516}, - dictWord{7, 10, 1439}, - dictWord{137, 10, 518}, - dictWord{4, 0, 71}, - dictWord{5, 0, 376}, - dictWord{7, 0, 119}, - dictWord{ - 138, - 0, - 665, - }, - dictWord{141, 10, 151}, - dictWord{11, 0, 827}, - dictWord{14, 0, 34}, - dictWord{143, 0, 148}, - dictWord{133, 11, 518}, - dictWord{4, 0, 479}, - dictWord{ - 135, - 11, - 1787, - }, - dictWord{135, 11, 1852}, - dictWord{135, 10, 993}, - dictWord{7, 0, 607}, - dictWord{136, 0, 99}, - dictWord{134, 0, 1960}, - dictWord{132, 0, 793}, - dictWord{4, 0, 41}, - dictWord{5, 0, 74}, - dictWord{7, 0, 1627}, - dictWord{11, 0, 871}, - dictWord{140, 0, 619}, - dictWord{7, 0, 94}, - dictWord{11, 0, 329}, - dictWord{ - 11, - 0, - 965, - }, - dictWord{12, 0, 241}, - dictWord{14, 0, 354}, - dictWord{15, 0, 22}, - dictWord{148, 0, 63}, - dictWord{7, 10, 501}, - dictWord{9, 10, 111}, - dictWord{10, 10, 141}, - dictWord{11, 10, 332}, - dictWord{13, 10, 43}, - dictWord{13, 10, 429}, - dictWord{14, 10, 130}, - dictWord{14, 10, 415}, - dictWord{145, 10, 102}, - dictWord{ - 9, - 0, - 209, - }, - dictWord{137, 0, 300}, - dictWord{134, 0, 1497}, - dictWord{138, 11, 255}, - dictWord{4, 11, 934}, - dictWord{5, 11, 138}, - dictWord{136, 11, 610}, - dictWord{133, 0, 98}, - dictWord{6, 0, 1316}, - dictWord{10, 11, 804}, - dictWord{138, 11, 832}, - dictWord{8, 11, 96}, - dictWord{9, 11, 36}, - dictWord{10, 11, 607}, - dictWord{11, 11, 423}, - dictWord{11, 11, 442}, - dictWord{12, 11, 309}, - dictWord{14, 11, 199}, - dictWord{15, 11, 90}, - dictWord{145, 11, 110}, - dictWord{ - 132, - 0, - 463, - }, - dictWord{5, 10, 149}, - dictWord{136, 10, 233}, - dictWord{133, 10, 935}, - dictWord{4, 11, 652}, - dictWord{8, 11, 320}, - dictWord{9, 11, 13}, - dictWord{ - 9, - 11, - 398, - }, - dictWord{9, 11, 727}, - dictWord{10, 11, 75}, - dictWord{10, 11, 184}, - dictWord{10, 11, 230}, - dictWord{10, 11, 564}, - dictWord{10, 11, 569}, - dictWord{ - 11, - 11, - 973, - }, - dictWord{12, 11, 70}, - dictWord{12, 11, 189}, - dictWord{13, 11, 57}, - dictWord{13, 11, 257}, - dictWord{22, 11, 6}, - dictWord{150, 11, 16}, - dictWord{ - 142, - 0, - 291, - }, - dictWord{12, 10, 582}, - dictWord{146, 10, 131}, - dictWord{136, 10, 801}, - dictWord{133, 0, 984}, - dictWord{145, 11, 116}, - dictWord{4, 11, 692}, - dictWord{133, 11, 321}, - dictWord{4, 0, 182}, - dictWord{6, 0, 205}, - dictWord{135, 0, 220}, - dictWord{4, 0, 42}, - dictWord{9, 0, 205}, - dictWord{9, 0, 786}, - dictWord{ - 138, - 0, - 659, - }, - dictWord{6, 0, 801}, - dictWord{11, 11, 130}, - dictWord{140, 11, 609}, - dictWord{132, 0, 635}, - dictWord{5, 11, 345}, - dictWord{135, 11, 1016}, - dictWord{139, 0, 533}, - dictWord{132, 0, 371}, - dictWord{4, 0, 272}, - dictWord{135, 0, 836}, - dictWord{6, 0, 1282}, - dictWord{135, 11, 1100}, - dictWord{5, 0, 825}, - dictWord{134, 0, 1640}, - dictWord{135, 11, 1325}, - dictWord{133, 11, 673}, - dictWord{4, 11, 287}, - dictWord{133, 11, 1018}, - dictWord{135, 0, 357}, - dictWord{ - 6, - 0, - 467, - }, - dictWord{137, 0, 879}, - dictWord{7, 0, 317}, - dictWord{135, 0, 569}, - dictWord{6, 0, 924}, - dictWord{134, 0, 1588}, - dictWord{5, 11, 34}, - dictWord{ - 5, - 10, - 406, - }, - dictWord{10, 11, 724}, - dictWord{12, 11, 444}, - dictWord{13, 11, 354}, - dictWord{18, 11, 32}, - dictWord{23, 11, 24}, - dictWord{23, 11, 31}, - dictWord{ - 152, - 11, - 5, - }, - dictWord{6, 0, 1795}, - dictWord{6, 0, 1835}, - dictWord{6, 0, 1836}, - dictWord{6, 0, 1856}, - dictWord{8, 0, 844}, - dictWord{8, 0, 849}, - dictWord{8, 0, 854}, - dictWord{8, 0, 870}, - dictWord{8, 0, 887}, - dictWord{10, 0, 852}, - dictWord{138, 0, 942}, - dictWord{6, 10, 69}, - dictWord{135, 10, 117}, - dictWord{137, 0, 307}, - dictWord{ - 4, - 0, - 944, - }, - dictWord{6, 0, 1799}, - dictWord{6, 0, 1825}, - dictWord{10, 0, 848}, - dictWord{10, 0, 875}, - dictWord{10, 0, 895}, - dictWord{10, 0, 899}, - dictWord{ - 10, - 0, - 902, - }, - dictWord{140, 0, 773}, - dictWord{11, 0, 43}, - dictWord{13, 0, 72}, - dictWord{141, 0, 142}, - dictWord{135, 10, 1830}, - dictWord{134, 11, 382}, - dictWord{ - 4, - 10, - 432, - }, - dictWord{135, 10, 824}, - dictWord{132, 11, 329}, - dictWord{7, 0, 1820}, - dictWord{139, 11, 124}, - dictWord{133, 10, 826}, - dictWord{ - 133, - 0, - 525, - }, - dictWord{132, 11, 906}, - dictWord{7, 11, 1940}, - dictWord{136, 11, 366}, - dictWord{138, 11, 10}, - dictWord{4, 11, 123}, - dictWord{4, 11, 649}, - dictWord{ - 5, - 11, - 605, - }, - dictWord{7, 11, 1509}, - dictWord{136, 11, 36}, - dictWord{6, 0, 110}, - dictWord{135, 0, 1681}, - dictWord{133, 0, 493}, - dictWord{133, 11, 767}, - dictWord{4, 0, 174}, - dictWord{135, 0, 911}, - dictWord{138, 11, 786}, - dictWord{8, 0, 417}, - dictWord{137, 0, 782}, - dictWord{133, 10, 1000}, - dictWord{7, 0, 733}, - dictWord{137, 0, 583}, - dictWord{4, 10, 297}, - dictWord{6, 10, 529}, - dictWord{7, 10, 152}, - dictWord{7, 10, 713}, - dictWord{7, 10, 1845}, - dictWord{8, 10, 710}, - dictWord{8, 10, 717}, - dictWord{12, 10, 639}, - dictWord{140, 10, 685}, - dictWord{4, 0, 32}, - dictWord{5, 0, 215}, - dictWord{6, 0, 269}, - dictWord{7, 0, 1782}, - dictWord{ - 7, - 0, - 1892, - }, - dictWord{10, 0, 16}, - dictWord{11, 0, 822}, - dictWord{11, 0, 954}, - dictWord{141, 0, 481}, - dictWord{4, 11, 273}, - dictWord{5, 11, 658}, - dictWord{ - 133, - 11, - 995, - }, - dictWord{136, 0, 477}, - dictWord{134, 11, 72}, - dictWord{135, 11, 1345}, - dictWord{5, 0, 308}, - dictWord{7, 0, 1088}, - dictWord{4, 10, 520}, - dictWord{ - 135, - 10, - 575, - }, - dictWord{133, 11, 589}, - dictWord{5, 0, 126}, - dictWord{8, 0, 297}, - dictWord{9, 0, 366}, - dictWord{140, 0, 374}, - dictWord{7, 0, 1551}, - dictWord{ - 139, - 0, - 361, - }, - dictWord{5, 11, 117}, - dictWord{6, 11, 514}, - dictWord{6, 11, 541}, - dictWord{7, 11, 1164}, - dictWord{7, 11, 1436}, - dictWord{8, 11, 220}, - dictWord{ - 8, - 11, - 648, - }, - dictWord{10, 11, 688}, - dictWord{139, 11, 560}, - dictWord{133, 11, 686}, - dictWord{4, 0, 946}, - dictWord{6, 0, 1807}, - dictWord{8, 0, 871}, - dictWord{ - 10, - 0, - 854, - }, - dictWord{10, 0, 870}, - dictWord{10, 0, 888}, - dictWord{10, 0, 897}, - dictWord{10, 0, 920}, - dictWord{12, 0, 722}, - dictWord{12, 0, 761}, - dictWord{ - 12, - 0, - 763, - }, - dictWord{12, 0, 764}, - dictWord{14, 0, 454}, - dictWord{14, 0, 465}, - dictWord{16, 0, 107}, - dictWord{18, 0, 167}, - dictWord{18, 0, 168}, - dictWord{ - 146, - 0, - 172, - }, - dictWord{132, 0, 175}, - dictWord{135, 0, 1307}, - dictWord{132, 0, 685}, - dictWord{135, 11, 1834}, - dictWord{133, 0, 797}, - dictWord{6, 0, 745}, - dictWord{ - 6, - 0, - 858, - }, - dictWord{134, 0, 963}, - dictWord{133, 0, 565}, - dictWord{5, 10, 397}, - dictWord{6, 10, 154}, - dictWord{7, 11, 196}, - dictWord{7, 10, 676}, - dictWord{ - 8, - 10, - 443, - }, - dictWord{8, 10, 609}, - dictWord{9, 10, 24}, - dictWord{9, 10, 325}, - dictWord{10, 10, 35}, - dictWord{10, 11, 765}, - dictWord{11, 11, 347}, - dictWord{ - 11, - 10, - 535, - }, - dictWord{11, 11, 552}, - dictWord{11, 11, 576}, - dictWord{11, 10, 672}, - dictWord{11, 11, 790}, - dictWord{11, 10, 1018}, - dictWord{12, 11, 263}, - dictWord{12, 10, 637}, - dictWord{13, 11, 246}, - dictWord{13, 11, 270}, - dictWord{13, 11, 395}, - dictWord{14, 11, 74}, - dictWord{14, 11, 176}, - dictWord{ - 14, - 11, - 190, - }, - dictWord{14, 11, 398}, - dictWord{14, 11, 412}, - dictWord{15, 11, 32}, - dictWord{15, 11, 63}, - dictWord{16, 10, 30}, - dictWord{16, 11, 88}, - dictWord{ - 147, - 11, - 105, - }, - dictWord{13, 11, 84}, - dictWord{141, 11, 122}, - dictWord{4, 0, 252}, - dictWord{7, 0, 1068}, - dictWord{10, 0, 434}, - dictWord{11, 0, 228}, - dictWord{ - 11, - 0, - 426, - }, - dictWord{13, 0, 231}, - dictWord{18, 0, 106}, - dictWord{148, 0, 87}, - dictWord{137, 0, 826}, - dictWord{4, 11, 589}, - dictWord{139, 11, 282}, - dictWord{ - 5, - 11, - 381, - }, - dictWord{135, 11, 1792}, - dictWord{132, 0, 791}, - dictWord{5, 0, 231}, - dictWord{10, 0, 509}, - dictWord{133, 10, 981}, - dictWord{7, 0, 601}, - dictWord{ - 9, - 0, - 277, - }, - dictWord{9, 0, 674}, - dictWord{10, 0, 178}, - dictWord{10, 0, 418}, - dictWord{10, 0, 571}, - dictWord{11, 0, 531}, - dictWord{12, 0, 113}, - dictWord{12, 0, 475}, - dictWord{13, 0, 99}, - dictWord{142, 0, 428}, - dictWord{4, 10, 56}, - dictWord{7, 11, 616}, - dictWord{7, 10, 1791}, - dictWord{8, 10, 607}, - dictWord{8, 10, 651}, - dictWord{10, 11, 413}, - dictWord{11, 10, 465}, - dictWord{11, 10, 835}, - dictWord{12, 10, 337}, - dictWord{141, 10, 480}, - dictWord{7, 0, 1591}, - dictWord{144, 0, 43}, - dictWord{9, 10, 158}, - dictWord{138, 10, 411}, - dictWord{135, 0, 1683}, - dictWord{8, 0, 289}, - dictWord{11, 0, 45}, - dictWord{12, 0, 278}, - dictWord{140, 0, 537}, - dictWord{6, 11, 120}, - dictWord{7, 11, 1188}, - dictWord{7, 11, 1710}, - dictWord{8, 11, 286}, - dictWord{9, 11, 667}, - dictWord{11, 11, 592}, - dictWord{ - 139, - 11, - 730, - }, - dictWord{136, 10, 617}, - dictWord{135, 0, 1120}, - dictWord{135, 11, 1146}, - dictWord{139, 10, 563}, - dictWord{4, 11, 352}, - dictWord{4, 10, 369}, - dictWord{135, 11, 687}, - dictWord{143, 11, 38}, - dictWord{4, 0, 399}, - dictWord{5, 0, 119}, - dictWord{5, 0, 494}, - dictWord{7, 0, 751}, - dictWord{9, 0, 556}, - dictWord{ - 14, - 11, - 179, - }, - dictWord{15, 11, 151}, - dictWord{150, 11, 11}, - dictWord{4, 11, 192}, - dictWord{5, 11, 49}, - dictWord{6, 11, 200}, - dictWord{6, 11, 293}, - dictWord{ - 6, - 11, - 1696, - }, - dictWord{135, 11, 488}, - dictWord{4, 0, 398}, - dictWord{133, 0, 660}, - dictWord{7, 0, 1030}, - dictWord{134, 10, 622}, - dictWord{135, 11, 595}, - dictWord{141, 0, 168}, - dictWord{132, 11, 147}, - dictWord{7, 0, 973}, - dictWord{10, 10, 624}, - dictWord{142, 10, 279}, - dictWord{132, 10, 363}, - dictWord{ - 132, - 0, - 642, - }, - dictWord{133, 11, 934}, - dictWord{134, 0, 1615}, - dictWord{7, 11, 505}, - dictWord{135, 11, 523}, - dictWord{7, 0, 594}, - dictWord{7, 0, 851}, - dictWord{ - 7, - 0, - 1858, - }, - dictWord{9, 0, 411}, - dictWord{9, 0, 574}, - dictWord{9, 0, 666}, - dictWord{9, 0, 737}, - dictWord{10, 0, 346}, - dictWord{10, 0, 712}, - dictWord{11, 0, 246}, - dictWord{11, 0, 432}, - dictWord{11, 0, 517}, - dictWord{11, 0, 647}, - dictWord{11, 0, 679}, - dictWord{11, 0, 727}, - dictWord{12, 0, 304}, - dictWord{12, 0, 305}, - dictWord{ - 12, - 0, - 323, - }, - dictWord{12, 0, 483}, - dictWord{12, 0, 572}, - dictWord{12, 0, 593}, - dictWord{12, 0, 602}, - dictWord{13, 0, 95}, - dictWord{13, 0, 101}, - dictWord{ - 13, - 0, - 171, - }, - dictWord{13, 0, 315}, - dictWord{13, 0, 378}, - dictWord{13, 0, 425}, - dictWord{13, 0, 475}, - dictWord{14, 0, 63}, - dictWord{14, 0, 380}, - dictWord{14, 0, 384}, - dictWord{15, 0, 133}, - dictWord{18, 0, 112}, - dictWord{148, 0, 72}, - dictWord{135, 0, 1093}, - dictWord{132, 0, 679}, - dictWord{8, 0, 913}, - dictWord{10, 0, 903}, - dictWord{10, 0, 915}, - dictWord{12, 0, 648}, - dictWord{12, 0, 649}, - dictWord{14, 0, 455}, - dictWord{16, 0, 112}, - dictWord{138, 11, 438}, - dictWord{137, 0, 203}, - dictWord{134, 10, 292}, - dictWord{134, 0, 1492}, - dictWord{7, 0, 1374}, - dictWord{8, 0, 540}, - dictWord{5, 10, 177}, - dictWord{6, 10, 616}, - dictWord{7, 10, 827}, - dictWord{9, 10, 525}, - dictWord{138, 10, 656}, - dictWord{135, 0, 1486}, - dictWord{9, 0, 714}, - dictWord{138, 10, 31}, - dictWord{136, 0, 825}, - dictWord{ - 134, - 0, - 1511, - }, - dictWord{132, 11, 637}, - dictWord{134, 0, 952}, - dictWord{4, 10, 161}, - dictWord{133, 10, 631}, - dictWord{5, 0, 143}, - dictWord{5, 0, 769}, - dictWord{ - 6, - 0, - 1760, - }, - dictWord{7, 0, 682}, - dictWord{7, 0, 1992}, - dictWord{136, 0, 736}, - dictWord{132, 0, 700}, - dictWord{134, 0, 1540}, - dictWord{132, 11, 777}, - dictWord{ - 9, - 11, - 867, - }, - dictWord{138, 11, 837}, - dictWord{7, 0, 1557}, - dictWord{135, 10, 1684}, - dictWord{133, 0, 860}, - dictWord{6, 0, 422}, - dictWord{7, 0, 0}, - dictWord{ - 7, - 0, - 1544, - }, - dictWord{9, 0, 605}, - dictWord{11, 0, 990}, - dictWord{12, 0, 235}, - dictWord{12, 0, 453}, - dictWord{13, 0, 47}, - dictWord{13, 0, 266}, - dictWord{9, 10, 469}, - dictWord{9, 10, 709}, - dictWord{12, 10, 512}, - dictWord{14, 10, 65}, - dictWord{145, 10, 12}, - dictWord{11, 0, 807}, - dictWord{10, 10, 229}, - dictWord{11, 10, 73}, - dictWord{139, 10, 376}, - dictWord{6, 11, 170}, - dictWord{7, 11, 1080}, - dictWord{8, 11, 395}, - dictWord{8, 11, 487}, - dictWord{11, 11, 125}, - dictWord{ - 141, - 11, - 147, - }, - dictWord{5, 0, 515}, - dictWord{137, 0, 131}, - dictWord{7, 0, 1605}, - dictWord{11, 0, 962}, - dictWord{146, 0, 139}, - dictWord{132, 0, 646}, - dictWord{ - 4, - 0, - 396, - }, - dictWord{7, 0, 728}, - dictWord{9, 0, 117}, - dictWord{13, 0, 202}, - dictWord{148, 0, 51}, - dictWord{6, 0, 121}, - dictWord{6, 0, 124}, - dictWord{6, 0, 357}, - dictWord{ - 7, - 0, - 1138, - }, - dictWord{7, 0, 1295}, - dictWord{8, 0, 162}, - dictWord{8, 0, 508}, - dictWord{11, 0, 655}, - dictWord{4, 11, 535}, - dictWord{6, 10, 558}, - dictWord{ - 7, - 10, - 651, - }, - dictWord{8, 11, 618}, - dictWord{9, 10, 0}, - dictWord{10, 10, 34}, - dictWord{139, 10, 1008}, - dictWord{135, 11, 1245}, - dictWord{138, 0, 357}, - dictWord{ - 150, - 11, - 23, - }, - dictWord{133, 0, 237}, - dictWord{135, 0, 1784}, - dictWord{7, 10, 1832}, - dictWord{138, 10, 374}, - dictWord{132, 0, 713}, - dictWord{132, 11, 46}, - dictWord{6, 0, 1536}, - dictWord{10, 0, 348}, - dictWord{5, 11, 811}, - dictWord{6, 11, 1679}, - dictWord{6, 11, 1714}, - dictWord{135, 11, 2032}, - dictWord{ - 11, - 11, - 182, - }, - dictWord{142, 11, 195}, - dictWord{6, 0, 523}, - dictWord{7, 0, 738}, - dictWord{7, 10, 771}, - dictWord{7, 10, 1731}, - dictWord{9, 10, 405}, - dictWord{ - 138, - 10, - 421, - }, - dictWord{7, 11, 1458}, - dictWord{9, 11, 407}, - dictWord{139, 11, 15}, - dictWord{6, 11, 34}, - dictWord{7, 11, 69}, - dictWord{7, 11, 640}, - dictWord{ - 7, - 11, - 1089, - }, - dictWord{8, 11, 708}, - dictWord{8, 11, 721}, - dictWord{9, 11, 363}, - dictWord{9, 11, 643}, - dictWord{10, 11, 628}, - dictWord{148, 11, 98}, - dictWord{ - 133, - 0, - 434, - }, - dictWord{135, 0, 1877}, - dictWord{7, 0, 571}, - dictWord{138, 0, 366}, - dictWord{5, 10, 881}, - dictWord{133, 10, 885}, - dictWord{9, 0, 513}, - dictWord{ - 10, - 0, - 25, - }, - dictWord{10, 0, 39}, - dictWord{12, 0, 122}, - dictWord{140, 0, 187}, - dictWord{132, 0, 580}, - dictWord{5, 10, 142}, - dictWord{134, 10, 546}, - dictWord{ - 132, - 11, - 462, - }, - dictWord{137, 0, 873}, - dictWord{5, 10, 466}, - dictWord{11, 10, 571}, - dictWord{12, 10, 198}, - dictWord{13, 10, 283}, - dictWord{14, 10, 186}, - dictWord{15, 10, 21}, - dictWord{143, 10, 103}, - dictWord{7, 0, 171}, - dictWord{4, 10, 185}, - dictWord{5, 10, 257}, - dictWord{5, 10, 839}, - dictWord{5, 10, 936}, - dictWord{ - 9, - 10, - 399, - }, - dictWord{10, 10, 258}, - dictWord{10, 10, 395}, - dictWord{10, 10, 734}, - dictWord{11, 10, 1014}, - dictWord{12, 10, 23}, - dictWord{13, 10, 350}, - dictWord{14, 10, 150}, - dictWord{147, 10, 6}, - dictWord{134, 0, 625}, - dictWord{7, 0, 107}, - dictWord{7, 0, 838}, - dictWord{8, 0, 550}, - dictWord{138, 0, 401}, - dictWord{ - 5, - 11, - 73, - }, - dictWord{6, 11, 23}, - dictWord{134, 11, 338}, - dictWord{4, 0, 943}, - dictWord{6, 0, 1850}, - dictWord{12, 0, 713}, - dictWord{142, 0, 434}, - dictWord{ - 11, - 0, - 588, - }, - dictWord{11, 0, 864}, - dictWord{11, 0, 936}, - dictWord{11, 0, 968}, - dictWord{12, 0, 73}, - dictWord{12, 0, 343}, - dictWord{12, 0, 394}, - dictWord{13, 0, 275}, - dictWord{14, 0, 257}, - dictWord{15, 0, 160}, - dictWord{7, 10, 404}, - dictWord{7, 10, 1377}, - dictWord{7, 10, 1430}, - dictWord{7, 10, 2017}, - dictWord{8, 10, 149}, - dictWord{8, 10, 239}, - dictWord{8, 10, 512}, - dictWord{8, 10, 793}, - dictWord{8, 10, 818}, - dictWord{9, 10, 474}, - dictWord{9, 10, 595}, - dictWord{10, 10, 122}, - dictWord{10, 10, 565}, - dictWord{10, 10, 649}, - dictWord{10, 10, 783}, - dictWord{11, 10, 239}, - dictWord{11, 10, 295}, - dictWord{11, 10, 447}, - dictWord{ - 11, - 10, - 528, - }, - dictWord{11, 10, 639}, - dictWord{11, 10, 800}, - dictWord{12, 10, 25}, - dictWord{12, 10, 157}, - dictWord{12, 10, 316}, - dictWord{12, 10, 390}, - dictWord{ - 12, - 10, - 391, - }, - dictWord{12, 10, 395}, - dictWord{12, 10, 478}, - dictWord{12, 10, 503}, - dictWord{12, 10, 592}, - dictWord{12, 10, 680}, - dictWord{13, 10, 50}, - dictWord{13, 10, 53}, - dictWord{13, 10, 132}, - dictWord{13, 10, 198}, - dictWord{13, 10, 322}, - dictWord{13, 10, 415}, - dictWord{13, 10, 511}, - dictWord{14, 10, 71}, - dictWord{14, 10, 395}, - dictWord{15, 10, 71}, - dictWord{15, 10, 136}, - dictWord{17, 10, 123}, - dictWord{18, 10, 93}, - dictWord{147, 10, 58}, - dictWord{ - 133, - 0, - 768, - }, - dictWord{11, 0, 103}, - dictWord{142, 0, 0}, - dictWord{136, 10, 712}, - dictWord{132, 0, 799}, - dictWord{132, 0, 894}, - dictWord{7, 11, 725}, - dictWord{ - 8, - 11, - 498, - }, - dictWord{139, 11, 268}, - dictWord{135, 11, 1798}, - dictWord{135, 11, 773}, - dictWord{141, 11, 360}, - dictWord{4, 10, 377}, - dictWord{152, 10, 13}, - dictWord{135, 0, 1673}, - dictWord{132, 11, 583}, - dictWord{134, 0, 1052}, - dictWord{133, 11, 220}, - dictWord{140, 11, 69}, - dictWord{132, 11, 544}, - dictWord{ - 4, - 10, - 180, - }, - dictWord{135, 10, 1906}, - dictWord{134, 0, 272}, - dictWord{4, 0, 441}, - dictWord{134, 0, 1421}, - dictWord{4, 0, 9}, - dictWord{5, 0, 128}, - dictWord{ - 7, - 0, - 368, - }, - dictWord{11, 0, 480}, - dictWord{148, 0, 3}, - dictWord{5, 11, 176}, - dictWord{6, 11, 437}, - dictWord{6, 11, 564}, - dictWord{11, 11, 181}, - dictWord{ - 141, - 11, - 183, - }, - dictWord{132, 10, 491}, - dictWord{7, 0, 1182}, - dictWord{141, 11, 67}, - dictWord{6, 0, 1346}, - dictWord{4, 10, 171}, - dictWord{138, 10, 234}, - dictWord{ - 4, - 10, - 586, - }, - dictWord{7, 10, 1186}, - dictWord{138, 10, 631}, - dictWord{136, 0, 682}, - dictWord{134, 0, 1004}, - dictWord{15, 0, 24}, - dictWord{143, 11, 24}, - dictWord{134, 0, 968}, - dictWord{4, 0, 2}, - dictWord{6, 0, 742}, - dictWord{6, 0, 793}, - dictWord{7, 0, 545}, - dictWord{7, 0, 894}, - dictWord{9, 10, 931}, - dictWord{ - 10, - 10, - 334, - }, - dictWord{148, 10, 71}, - dictWord{136, 11, 600}, - dictWord{133, 10, 765}, - dictWord{9, 0, 769}, - dictWord{140, 0, 185}, - dictWord{4, 11, 790}, - dictWord{ - 5, - 11, - 273, - }, - dictWord{134, 11, 394}, - dictWord{7, 0, 474}, - dictWord{137, 0, 578}, - dictWord{4, 11, 135}, - dictWord{6, 11, 127}, - dictWord{7, 11, 1185}, - dictWord{ - 7, - 11, - 1511, - }, - dictWord{8, 11, 613}, - dictWord{11, 11, 5}, - dictWord{12, 11, 133}, - dictWord{12, 11, 495}, - dictWord{12, 11, 586}, - dictWord{14, 11, 385}, - dictWord{15, 11, 118}, - dictWord{17, 11, 20}, - dictWord{146, 11, 98}, - dictWord{133, 10, 424}, - dictWord{5, 0, 530}, - dictWord{142, 0, 113}, - dictWord{6, 11, 230}, - dictWord{7, 11, 961}, - dictWord{7, 11, 1085}, - dictWord{136, 11, 462}, - dictWord{7, 11, 1954}, - dictWord{137, 11, 636}, - dictWord{136, 10, 714}, - dictWord{ - 149, - 11, - 6, - }, - dictWord{135, 10, 685}, - dictWord{9, 10, 420}, - dictWord{10, 10, 269}, - dictWord{10, 10, 285}, - dictWord{10, 10, 576}, - dictWord{11, 10, 397}, - dictWord{13, 10, 175}, - dictWord{145, 10, 90}, - dictWord{132, 10, 429}, - dictWord{5, 0, 556}, - dictWord{5, 11, 162}, - dictWord{136, 11, 68}, - dictWord{132, 11, 654}, - dictWord{4, 11, 156}, - dictWord{7, 11, 998}, - dictWord{7, 11, 1045}, - dictWord{7, 11, 1860}, - dictWord{9, 11, 48}, - dictWord{9, 11, 692}, - dictWord{11, 11, 419}, - dictWord{139, 11, 602}, - dictWord{6, 0, 1317}, - dictWord{8, 0, 16}, - dictWord{9, 0, 825}, - dictWord{12, 0, 568}, - dictWord{7, 11, 1276}, - dictWord{8, 11, 474}, - dictWord{137, 11, 652}, - dictWord{18, 0, 97}, - dictWord{7, 10, 18}, - dictWord{7, 10, 699}, - dictWord{7, 10, 1966}, - dictWord{8, 10, 752}, - dictWord{9, 10, 273}, - dictWord{ - 9, - 10, - 412, - }, - dictWord{9, 10, 703}, - dictWord{10, 10, 71}, - dictWord{10, 10, 427}, - dictWord{138, 10, 508}, - dictWord{10, 0, 703}, - dictWord{7, 11, 1454}, - dictWord{138, 11, 703}, - dictWord{4, 10, 53}, - dictWord{5, 10, 186}, - dictWord{135, 10, 752}, - dictWord{134, 0, 892}, - dictWord{134, 0, 1571}, - dictWord{8, 10, 575}, - dictWord{10, 10, 289}, - dictWord{139, 10, 319}, - dictWord{6, 0, 186}, - dictWord{137, 0, 426}, - dictWord{134, 0, 1101}, - dictWord{132, 10, 675}, - dictWord{ - 132, - 0, - 585, - }, - dictWord{6, 0, 1870}, - dictWord{137, 0, 937}, - dictWord{152, 11, 10}, - dictWord{9, 11, 197}, - dictWord{10, 11, 300}, - dictWord{12, 11, 473}, - dictWord{ - 13, - 11, - 90, - }, - dictWord{141, 11, 405}, - dictWord{4, 0, 93}, - dictWord{5, 0, 252}, - dictWord{6, 0, 229}, - dictWord{7, 0, 291}, - dictWord{9, 0, 550}, - dictWord{139, 0, 644}, - dictWord{137, 0, 749}, - dictWord{9, 0, 162}, - dictWord{6, 10, 209}, - dictWord{8, 10, 468}, - dictWord{9, 10, 210}, - dictWord{11, 10, 36}, - dictWord{12, 10, 28}, - dictWord{12, 10, 630}, - dictWord{13, 10, 21}, - dictWord{13, 10, 349}, - dictWord{14, 10, 7}, - dictWord{145, 10, 13}, - dictWord{132, 0, 381}, - dictWord{132, 11, 606}, - dictWord{4, 10, 342}, - dictWord{135, 10, 1179}, - dictWord{7, 11, 1587}, - dictWord{7, 11, 1707}, - dictWord{10, 11, 528}, - dictWord{139, 11, 504}, - dictWord{ - 12, - 11, - 39, - }, - dictWord{13, 11, 265}, - dictWord{141, 11, 439}, - dictWord{4, 10, 928}, - dictWord{133, 10, 910}, - dictWord{7, 10, 1838}, - dictWord{7, 11, 1978}, - dictWord{136, 11, 676}, - dictWord{6, 0, 762}, - dictWord{6, 0, 796}, - dictWord{134, 0, 956}, - dictWord{4, 10, 318}, - dictWord{4, 10, 496}, - dictWord{7, 10, 856}, - dictWord{139, 10, 654}, - dictWord{137, 11, 242}, - dictWord{4, 11, 361}, - dictWord{133, 11, 315}, - dictWord{132, 11, 461}, - dictWord{132, 11, 472}, - dictWord{ - 132, - 0, - 857, - }, - dictWord{5, 0, 21}, - dictWord{6, 0, 77}, - dictWord{6, 0, 157}, - dictWord{7, 0, 974}, - dictWord{7, 0, 1301}, - dictWord{7, 0, 1339}, - dictWord{7, 0, 1490}, - dictWord{ - 7, - 0, - 1873, - }, - dictWord{9, 0, 628}, - dictWord{7, 10, 915}, - dictWord{8, 10, 247}, - dictWord{147, 10, 0}, - dictWord{4, 10, 202}, - dictWord{5, 10, 382}, - dictWord{ - 6, - 10, - 454, - }, - dictWord{7, 10, 936}, - dictWord{7, 10, 1803}, - dictWord{8, 10, 758}, - dictWord{9, 10, 375}, - dictWord{9, 10, 895}, - dictWord{10, 10, 743}, - dictWord{ - 10, - 10, - 792, - }, - dictWord{11, 10, 978}, - dictWord{11, 10, 1012}, - dictWord{142, 10, 109}, - dictWord{7, 11, 617}, - dictWord{10, 11, 498}, - dictWord{11, 11, 501}, - dictWord{12, 11, 16}, - dictWord{140, 11, 150}, - dictWord{7, 10, 1150}, - dictWord{7, 10, 1425}, - dictWord{7, 10, 1453}, - dictWord{10, 11, 747}, - dictWord{ - 140, - 10, - 513, - }, - dictWord{133, 11, 155}, - dictWord{11, 0, 919}, - dictWord{141, 0, 409}, - dictWord{138, 10, 791}, - dictWord{10, 0, 633}, - dictWord{139, 11, 729}, - dictWord{ - 7, - 11, - 163, - }, - dictWord{8, 11, 319}, - dictWord{9, 11, 402}, - dictWord{10, 11, 24}, - dictWord{10, 11, 681}, - dictWord{11, 11, 200}, - dictWord{11, 11, 567}, - dictWord{12, 11, 253}, - dictWord{12, 11, 410}, - dictWord{142, 11, 219}, - dictWord{5, 11, 475}, - dictWord{7, 11, 1780}, - dictWord{9, 11, 230}, - dictWord{11, 11, 297}, - dictWord{11, 11, 558}, - dictWord{14, 11, 322}, - dictWord{147, 11, 76}, - dictWord{7, 0, 332}, - dictWord{6, 10, 445}, - dictWord{137, 10, 909}, - dictWord{ - 135, - 11, - 1956, - }, - dictWord{136, 11, 274}, - dictWord{134, 10, 578}, - dictWord{135, 0, 1489}, - dictWord{135, 11, 1848}, - dictWord{5, 11, 944}, - dictWord{ - 134, - 11, - 1769, - }, - dictWord{132, 11, 144}, - dictWord{136, 10, 766}, - dictWord{4, 0, 832}, - dictWord{135, 10, 541}, - dictWord{8, 0, 398}, - dictWord{9, 0, 681}, - dictWord{ - 139, - 0, - 632, - }, - dictWord{136, 0, 645}, - dictWord{9, 0, 791}, - dictWord{10, 0, 93}, - dictWord{16, 0, 13}, - dictWord{17, 0, 23}, - dictWord{18, 0, 135}, - dictWord{19, 0, 12}, - dictWord{20, 0, 1}, - dictWord{20, 0, 12}, - dictWord{148, 0, 14}, - dictWord{6, 11, 247}, - dictWord{137, 11, 555}, - dictWord{134, 0, 20}, - dictWord{132, 0, 800}, - dictWord{135, 0, 1841}, - dictWord{139, 10, 983}, - dictWord{137, 10, 768}, - dictWord{132, 10, 584}, - dictWord{141, 11, 51}, - dictWord{6, 0, 1993}, - dictWord{ - 4, - 11, - 620, - }, - dictWord{138, 11, 280}, - dictWord{136, 0, 769}, - dictWord{11, 0, 290}, - dictWord{11, 0, 665}, - dictWord{7, 11, 1810}, - dictWord{11, 11, 866}, - dictWord{ - 12, - 11, - 103, - }, - dictWord{13, 11, 495}, - dictWord{17, 11, 67}, - dictWord{147, 11, 74}, - dictWord{134, 0, 1426}, - dictWord{139, 0, 60}, - dictWord{4, 10, 326}, - dictWord{135, 10, 1770}, - dictWord{7, 0, 1874}, - dictWord{9, 0, 641}, - dictWord{132, 10, 226}, - dictWord{6, 0, 644}, - dictWord{5, 10, 426}, - dictWord{8, 10, 30}, - dictWord{ - 9, - 10, - 2, - }, - dictWord{11, 10, 549}, - dictWord{147, 10, 122}, - dictWord{5, 11, 428}, - dictWord{138, 11, 442}, - dictWord{135, 11, 1871}, - dictWord{ - 135, - 0, - 1757, - }, - dictWord{147, 10, 117}, - dictWord{135, 0, 937}, - dictWord{135, 0, 1652}, - dictWord{6, 0, 654}, - dictWord{134, 0, 1476}, - dictWord{133, 11, 99}, - dictWord{135, 0, 527}, - dictWord{132, 10, 345}, - dictWord{4, 10, 385}, - dictWord{4, 11, 397}, - dictWord{7, 10, 265}, - dictWord{135, 10, 587}, - dictWord{4, 0, 579}, - dictWord{5, 0, 226}, - dictWord{5, 0, 323}, - dictWord{135, 0, 960}, - dictWord{134, 0, 1486}, - dictWord{8, 11, 502}, - dictWord{144, 11, 9}, - dictWord{4, 10, 347}, - dictWord{ - 5, - 10, - 423, - }, - dictWord{5, 10, 996}, - dictWord{135, 10, 1329}, - dictWord{7, 11, 727}, - dictWord{146, 11, 73}, - dictWord{4, 11, 485}, - dictWord{7, 11, 353}, - dictWord{7, 10, 1259}, - dictWord{7, 11, 1523}, - dictWord{9, 10, 125}, - dictWord{139, 10, 65}, - dictWord{6, 0, 325}, - dictWord{5, 10, 136}, - dictWord{6, 11, 366}, - dictWord{ - 7, - 11, - 1384, - }, - dictWord{7, 11, 1601}, - dictWord{136, 10, 644}, - dictWord{138, 11, 160}, - dictWord{6, 0, 1345}, - dictWord{137, 11, 282}, - dictWord{18, 0, 91}, - dictWord{147, 0, 70}, - dictWord{136, 0, 404}, - dictWord{4, 11, 157}, - dictWord{133, 11, 471}, - dictWord{133, 0, 973}, - dictWord{6, 0, 135}, - dictWord{ - 135, - 0, - 1176, - }, - dictWord{8, 11, 116}, - dictWord{11, 11, 551}, - dictWord{142, 11, 159}, - dictWord{4, 0, 549}, - dictWord{4, 10, 433}, - dictWord{133, 10, 719}, - dictWord{ - 136, - 0, - 976, - }, - dictWord{5, 11, 160}, - dictWord{7, 11, 363}, - dictWord{7, 11, 589}, - dictWord{10, 11, 170}, - dictWord{141, 11, 55}, - dictWord{144, 0, 21}, - dictWord{ - 144, - 0, - 51, - }, - dictWord{135, 0, 314}, - dictWord{135, 10, 1363}, - dictWord{4, 11, 108}, - dictWord{7, 11, 405}, - dictWord{10, 11, 491}, - dictWord{139, 11, 498}, - dictWord{146, 0, 4}, - dictWord{4, 10, 555}, - dictWord{8, 10, 536}, - dictWord{10, 10, 288}, - dictWord{139, 10, 1005}, - dictWord{135, 11, 1005}, - dictWord{6, 0, 281}, - dictWord{7, 0, 6}, - dictWord{8, 0, 282}, - dictWord{8, 0, 480}, - dictWord{8, 0, 499}, - dictWord{9, 0, 198}, - dictWord{10, 0, 143}, - dictWord{10, 0, 169}, - dictWord{ - 10, - 0, - 211, - }, - dictWord{10, 0, 417}, - dictWord{10, 0, 574}, - dictWord{11, 0, 147}, - dictWord{11, 0, 395}, - dictWord{12, 0, 75}, - dictWord{12, 0, 407}, - dictWord{12, 0, 608}, - dictWord{13, 0, 500}, - dictWord{142, 0, 251}, - dictWord{6, 0, 1093}, - dictWord{6, 0, 1405}, - dictWord{9, 10, 370}, - dictWord{138, 10, 90}, - dictWord{4, 11, 926}, - dictWord{133, 11, 983}, - dictWord{135, 0, 1776}, - dictWord{134, 0, 1528}, - dictWord{132, 0, 419}, - dictWord{132, 11, 538}, - dictWord{6, 11, 294}, - dictWord{ - 7, - 11, - 1267, - }, - dictWord{136, 11, 624}, - dictWord{135, 11, 1772}, - dictWord{138, 11, 301}, - dictWord{4, 10, 257}, - dictWord{135, 10, 2031}, - dictWord{4, 0, 138}, - dictWord{7, 0, 1012}, - dictWord{7, 0, 1280}, - dictWord{9, 0, 76}, - dictWord{135, 10, 1768}, - dictWord{132, 11, 757}, - dictWord{5, 0, 29}, - dictWord{140, 0, 638}, - dictWord{7, 11, 655}, - dictWord{135, 11, 1844}, - dictWord{7, 0, 1418}, - dictWord{6, 11, 257}, - dictWord{135, 11, 1522}, - dictWord{8, 11, 469}, - dictWord{ - 138, - 11, - 47, - }, - dictWord{142, 11, 278}, - dictWord{6, 10, 83}, - dictWord{6, 10, 1733}, - dictWord{135, 10, 1389}, - dictWord{11, 11, 204}, - dictWord{11, 11, 243}, - dictWord{140, 11, 293}, - dictWord{135, 11, 1875}, - dictWord{6, 0, 1710}, - dictWord{135, 0, 2038}, - dictWord{137, 11, 299}, - dictWord{4, 0, 17}, - dictWord{5, 0, 23}, - dictWord{7, 0, 995}, - dictWord{11, 0, 383}, - dictWord{11, 0, 437}, - dictWord{12, 0, 460}, - dictWord{140, 0, 532}, - dictWord{133, 0, 862}, - dictWord{137, 10, 696}, - dictWord{6, 0, 592}, - dictWord{138, 0, 946}, - dictWord{138, 11, 599}, - dictWord{7, 10, 1718}, - dictWord{9, 10, 95}, - dictWord{9, 10, 274}, - dictWord{10, 10, 279}, - dictWord{10, 10, 317}, - dictWord{10, 10, 420}, - dictWord{11, 10, 303}, - dictWord{11, 10, 808}, - dictWord{12, 10, 134}, - dictWord{12, 10, 367}, - dictWord{ - 13, - 10, - 149, - }, - dictWord{13, 10, 347}, - dictWord{14, 10, 349}, - dictWord{14, 10, 406}, - dictWord{18, 10, 22}, - dictWord{18, 10, 89}, - dictWord{18, 10, 122}, - dictWord{ - 147, - 10, - 47, - }, - dictWord{8, 0, 70}, - dictWord{12, 0, 171}, - dictWord{141, 0, 272}, - dictWord{133, 10, 26}, - dictWord{132, 10, 550}, - dictWord{137, 0, 812}, - dictWord{ - 10, - 0, - 233, - }, - dictWord{139, 0, 76}, - dictWord{134, 0, 988}, - dictWord{134, 0, 442}, - dictWord{136, 10, 822}, - dictWord{7, 0, 896}, - dictWord{4, 10, 902}, - dictWord{ - 5, - 10, - 809, - }, - dictWord{134, 10, 122}, - dictWord{5, 11, 150}, - dictWord{7, 11, 106}, - dictWord{8, 11, 603}, - dictWord{9, 11, 593}, - dictWord{9, 11, 634}, - dictWord{ - 10, - 11, - 44, - }, - dictWord{10, 11, 173}, - dictWord{11, 11, 462}, - dictWord{11, 11, 515}, - dictWord{13, 11, 216}, - dictWord{13, 11, 288}, - dictWord{142, 11, 400}, - dictWord{136, 0, 483}, - dictWord{135, 10, 262}, - dictWord{6, 0, 1709}, - dictWord{133, 10, 620}, - dictWord{4, 10, 34}, - dictWord{5, 10, 574}, - dictWord{7, 10, 279}, - dictWord{7, 10, 1624}, - dictWord{136, 10, 601}, - dictWord{137, 10, 170}, - dictWord{147, 0, 119}, - dictWord{12, 11, 108}, - dictWord{141, 11, 291}, - dictWord{ - 11, - 0, - 69, - }, - dictWord{12, 0, 105}, - dictWord{12, 0, 117}, - dictWord{13, 0, 213}, - dictWord{14, 0, 13}, - dictWord{14, 0, 62}, - dictWord{14, 0, 177}, - dictWord{14, 0, 421}, - dictWord{15, 0, 19}, - dictWord{146, 0, 141}, - dictWord{137, 0, 309}, - dictWord{11, 11, 278}, - dictWord{142, 11, 73}, - dictWord{7, 0, 608}, - dictWord{7, 0, 976}, - dictWord{9, 0, 146}, - dictWord{10, 0, 206}, - dictWord{10, 0, 596}, - dictWord{13, 0, 218}, - dictWord{142, 0, 153}, - dictWord{133, 10, 332}, - dictWord{6, 10, 261}, - dictWord{ - 8, - 10, - 182, - }, - dictWord{139, 10, 943}, - dictWord{4, 11, 493}, - dictWord{144, 11, 55}, - dictWord{134, 10, 1721}, - dictWord{132, 0, 768}, - dictWord{4, 10, 933}, - dictWord{133, 10, 880}, - dictWord{7, 11, 555}, - dictWord{7, 11, 1316}, - dictWord{7, 11, 1412}, - dictWord{7, 11, 1839}, - dictWord{9, 11, 192}, - dictWord{ - 9, - 11, - 589, - }, - dictWord{11, 11, 241}, - dictWord{11, 11, 676}, - dictWord{11, 11, 811}, - dictWord{11, 11, 891}, - dictWord{12, 11, 140}, - dictWord{12, 11, 346}, - dictWord{ - 12, - 11, - 479, - }, - dictWord{13, 11, 30}, - dictWord{13, 11, 49}, - dictWord{13, 11, 381}, - dictWord{14, 11, 188}, - dictWord{15, 11, 150}, - dictWord{16, 11, 76}, - dictWord{18, 11, 30}, - dictWord{148, 11, 52}, - dictWord{4, 0, 518}, - dictWord{135, 0, 1136}, - dictWord{6, 11, 568}, - dictWord{7, 11, 112}, - dictWord{7, 11, 1804}, - dictWord{8, 11, 362}, - dictWord{8, 11, 410}, - dictWord{8, 11, 830}, - dictWord{9, 11, 514}, - dictWord{11, 11, 649}, - dictWord{142, 11, 157}, - dictWord{135, 11, 673}, - dictWord{8, 0, 689}, - dictWord{137, 0, 863}, - dictWord{4, 0, 18}, - dictWord{7, 0, 145}, - dictWord{7, 0, 444}, - dictWord{7, 0, 1278}, - dictWord{8, 0, 49}, - dictWord{8, 0, 400}, - dictWord{9, 0, 71}, - dictWord{9, 0, 250}, - dictWord{10, 0, 459}, - dictWord{12, 0, 160}, - dictWord{16, 0, 24}, - dictWord{132, 11, 625}, - dictWord{140, 0, 1020}, - dictWord{4, 0, 997}, - dictWord{6, 0, 1946}, - dictWord{6, 0, 1984}, - dictWord{134, 0, 1998}, - dictWord{6, 11, 16}, - dictWord{6, 11, 158}, - dictWord{7, 11, 43}, - dictWord{ - 7, - 11, - 129, - }, - dictWord{7, 11, 181}, - dictWord{8, 11, 276}, - dictWord{8, 11, 377}, - dictWord{10, 11, 523}, - dictWord{11, 11, 816}, - dictWord{12, 11, 455}, - dictWord{ - 13, - 11, - 303, - }, - dictWord{142, 11, 135}, - dictWord{133, 10, 812}, - dictWord{134, 0, 658}, - dictWord{4, 11, 1}, - dictWord{7, 11, 1143}, - dictWord{7, 11, 1463}, - dictWord{8, 11, 61}, - dictWord{9, 11, 207}, - dictWord{9, 11, 390}, - dictWord{9, 11, 467}, - dictWord{139, 11, 836}, - dictWord{150, 11, 26}, - dictWord{140, 0, 106}, - dictWord{6, 0, 1827}, - dictWord{10, 0, 931}, - dictWord{18, 0, 166}, - dictWord{20, 0, 114}, - dictWord{4, 10, 137}, - dictWord{7, 10, 1178}, - dictWord{7, 11, 1319}, - dictWord{135, 10, 1520}, - dictWord{133, 0, 1010}, - dictWord{4, 11, 723}, - dictWord{5, 11, 895}, - dictWord{7, 11, 1031}, - dictWord{8, 11, 199}, - dictWord{8, 11, 340}, - dictWord{9, 11, 153}, - dictWord{9, 11, 215}, - dictWord{10, 11, 21}, - dictWord{10, 11, 59}, - dictWord{10, 11, 80}, - dictWord{10, 11, 224}, - dictWord{11, 11, 229}, - dictWord{11, 11, 652}, - dictWord{12, 11, 192}, - dictWord{13, 11, 146}, - dictWord{142, 11, 91}, - dictWord{132, 11, 295}, - dictWord{6, 11, 619}, - dictWord{ - 7, - 11, - 898, - }, - dictWord{7, 11, 1092}, - dictWord{8, 11, 485}, - dictWord{18, 11, 28}, - dictWord{147, 11, 116}, - dictWord{137, 11, 51}, - dictWord{6, 10, 1661}, - dictWord{ - 7, - 10, - 1975, - }, - dictWord{7, 10, 2009}, - dictWord{135, 10, 2011}, - dictWord{5, 11, 309}, - dictWord{140, 11, 211}, - dictWord{5, 0, 87}, - dictWord{7, 0, 313}, - dictWord{ - 7, - 0, - 1103, - }, - dictWord{10, 0, 208}, - dictWord{10, 0, 582}, - dictWord{11, 0, 389}, - dictWord{11, 0, 813}, - dictWord{12, 0, 385}, - dictWord{13, 0, 286}, - dictWord{ - 14, - 0, - 124, - }, - dictWord{146, 0, 108}, - dictWord{5, 11, 125}, - dictWord{8, 11, 77}, - dictWord{138, 11, 15}, - dictWord{132, 0, 267}, - dictWord{133, 0, 703}, - dictWord{ - 137, - 11, - 155, - }, - dictWord{133, 11, 439}, - dictWord{11, 11, 164}, - dictWord{140, 11, 76}, - dictWord{9, 0, 496}, - dictWord{5, 10, 89}, - dictWord{7, 10, 1915}, - dictWord{ - 9, - 10, - 185, - }, - dictWord{9, 10, 235}, - dictWord{10, 10, 64}, - dictWord{10, 10, 270}, - dictWord{10, 10, 403}, - dictWord{10, 10, 469}, - dictWord{10, 10, 529}, - dictWord{10, 10, 590}, - dictWord{11, 10, 140}, - dictWord{11, 10, 860}, - dictWord{13, 10, 1}, - dictWord{13, 10, 422}, - dictWord{14, 10, 341}, - dictWord{14, 10, 364}, - dictWord{17, 10, 93}, - dictWord{18, 10, 113}, - dictWord{19, 10, 97}, - dictWord{147, 10, 113}, - dictWord{133, 10, 695}, - dictWord{135, 0, 1121}, - dictWord{ - 5, - 10, - 6, - }, - dictWord{6, 10, 183}, - dictWord{7, 10, 680}, - dictWord{7, 10, 978}, - dictWord{7, 10, 1013}, - dictWord{7, 10, 1055}, - dictWord{12, 10, 230}, - dictWord{ - 13, - 10, - 172, - }, - dictWord{146, 10, 29}, - dictWord{4, 11, 8}, - dictWord{7, 11, 1152}, - dictWord{7, 11, 1153}, - dictWord{7, 11, 1715}, - dictWord{9, 11, 374}, - dictWord{ - 10, - 11, - 478, - }, - dictWord{139, 11, 648}, - dictWord{135, 11, 1099}, - dictWord{6, 10, 29}, - dictWord{139, 10, 63}, - dictWord{4, 0, 561}, - dictWord{10, 0, 249}, - dictWord{ - 139, - 0, - 209, - }, - dictWord{132, 0, 760}, - dictWord{7, 11, 799}, - dictWord{138, 11, 511}, - dictWord{136, 11, 87}, - dictWord{9, 0, 154}, - dictWord{140, 0, 485}, - dictWord{136, 0, 255}, - dictWord{132, 0, 323}, - dictWord{140, 0, 419}, - dictWord{132, 10, 311}, - dictWord{134, 10, 1740}, - dictWord{4, 0, 368}, - dictWord{ - 135, - 0, - 641, - }, - dictWord{7, 10, 170}, - dictWord{8, 10, 90}, - dictWord{8, 10, 177}, - dictWord{8, 10, 415}, - dictWord{11, 10, 714}, - dictWord{142, 10, 281}, - dictWord{ - 4, - 11, - 69, - }, - dictWord{5, 11, 122}, - dictWord{9, 11, 656}, - dictWord{138, 11, 464}, - dictWord{5, 11, 849}, - dictWord{134, 11, 1633}, - dictWord{8, 0, 522}, - dictWord{ - 142, - 0, - 328, - }, - dictWord{11, 10, 91}, - dictWord{13, 10, 129}, - dictWord{15, 10, 101}, - dictWord{145, 10, 125}, - dictWord{7, 0, 562}, - dictWord{8, 0, 551}, - dictWord{ - 4, - 10, - 494, - }, - dictWord{6, 10, 74}, - dictWord{7, 10, 44}, - dictWord{11, 11, 499}, - dictWord{12, 10, 17}, - dictWord{15, 10, 5}, - dictWord{148, 10, 11}, - dictWord{4, 10, 276}, - dictWord{133, 10, 296}, - dictWord{9, 0, 92}, - dictWord{147, 0, 91}, - dictWord{4, 10, 7}, - dictWord{5, 10, 90}, - dictWord{5, 10, 158}, - dictWord{6, 10, 542}, - dictWord{ - 7, - 10, - 221, - }, - dictWord{7, 10, 1574}, - dictWord{9, 10, 490}, - dictWord{10, 10, 540}, - dictWord{11, 10, 443}, - dictWord{139, 10, 757}, - dictWord{6, 0, 525}, - dictWord{ - 6, - 0, - 1976, - }, - dictWord{8, 0, 806}, - dictWord{9, 0, 876}, - dictWord{140, 0, 284}, - dictWord{5, 11, 859}, - dictWord{7, 10, 588}, - dictWord{7, 11, 1160}, - dictWord{ - 8, - 11, - 107, - }, - dictWord{9, 10, 175}, - dictWord{9, 11, 291}, - dictWord{9, 11, 439}, - dictWord{10, 10, 530}, - dictWord{10, 11, 663}, - dictWord{11, 11, 609}, - dictWord{ - 140, - 11, - 197, - }, - dictWord{7, 11, 168}, - dictWord{13, 11, 196}, - dictWord{141, 11, 237}, - dictWord{139, 0, 958}, - dictWord{133, 0, 594}, - dictWord{135, 10, 580}, - dictWord{7, 10, 88}, - dictWord{136, 10, 627}, - dictWord{6, 0, 479}, - dictWord{6, 0, 562}, - dictWord{7, 0, 1060}, - dictWord{13, 0, 6}, - dictWord{5, 10, 872}, - dictWord{ - 6, - 10, - 57, - }, - dictWord{7, 10, 471}, - dictWord{9, 10, 447}, - dictWord{137, 10, 454}, - dictWord{136, 11, 413}, - dictWord{145, 11, 19}, - dictWord{4, 11, 117}, - dictWord{ - 6, - 11, - 372, - }, - dictWord{7, 11, 1905}, - dictWord{142, 11, 323}, - dictWord{4, 11, 722}, - dictWord{139, 11, 471}, - dictWord{17, 0, 61}, - dictWord{5, 10, 31}, - dictWord{134, 10, 614}, - dictWord{8, 10, 330}, - dictWord{140, 10, 477}, - dictWord{7, 10, 1200}, - dictWord{138, 10, 460}, - dictWord{6, 10, 424}, - dictWord{ - 135, - 10, - 1866, - }, - dictWord{6, 0, 1641}, - dictWord{136, 0, 820}, - dictWord{6, 0, 1556}, - dictWord{134, 0, 1618}, - dictWord{9, 11, 5}, - dictWord{12, 11, 216}, - dictWord{ - 12, - 11, - 294, - }, - dictWord{12, 11, 298}, - dictWord{12, 11, 400}, - dictWord{12, 11, 518}, - dictWord{13, 11, 229}, - dictWord{143, 11, 139}, - dictWord{15, 11, 155}, - dictWord{144, 11, 79}, - dictWord{4, 0, 302}, - dictWord{135, 0, 1766}, - dictWord{5, 10, 13}, - dictWord{134, 10, 142}, - dictWord{6, 0, 148}, - dictWord{7, 0, 1313}, - dictWord{ - 7, - 10, - 116, - }, - dictWord{8, 10, 322}, - dictWord{8, 10, 755}, - dictWord{9, 10, 548}, - dictWord{10, 10, 714}, - dictWord{11, 10, 884}, - dictWord{141, 10, 324}, - dictWord{137, 0, 676}, - dictWord{9, 11, 88}, - dictWord{139, 11, 270}, - dictWord{5, 11, 12}, - dictWord{7, 11, 375}, - dictWord{137, 11, 438}, - dictWord{134, 0, 1674}, - dictWord{7, 10, 1472}, - dictWord{135, 10, 1554}, - dictWord{11, 0, 178}, - dictWord{7, 10, 1071}, - dictWord{7, 10, 1541}, - dictWord{7, 10, 1767}, - dictWord{ - 7, - 10, - 1806, - }, - dictWord{11, 10, 162}, - dictWord{11, 10, 242}, - dictWord{12, 10, 605}, - dictWord{15, 10, 26}, - dictWord{144, 10, 44}, - dictWord{6, 0, 389}, - dictWord{ - 7, - 0, - 149, - }, - dictWord{9, 0, 142}, - dictWord{138, 0, 94}, - dictWord{140, 11, 71}, - dictWord{145, 10, 115}, - dictWord{6, 0, 8}, - dictWord{7, 0, 1881}, - dictWord{8, 0, 91}, - dictWord{11, 11, 966}, - dictWord{12, 11, 287}, - dictWord{13, 11, 342}, - dictWord{13, 11, 402}, - dictWord{15, 11, 110}, - dictWord{143, 11, 163}, - dictWord{ - 4, - 11, - 258, - }, - dictWord{136, 11, 639}, - dictWord{6, 11, 22}, - dictWord{7, 11, 903}, - dictWord{138, 11, 577}, - dictWord{133, 11, 681}, - dictWord{135, 10, 1111}, - dictWord{135, 11, 1286}, - dictWord{9, 0, 112}, - dictWord{8, 10, 1}, - dictWord{138, 10, 326}, - dictWord{5, 10, 488}, - dictWord{6, 10, 527}, - dictWord{7, 10, 489}, - dictWord{ - 7, - 10, - 1636, - }, - dictWord{8, 10, 121}, - dictWord{8, 10, 144}, - dictWord{8, 10, 359}, - dictWord{9, 10, 193}, - dictWord{9, 10, 241}, - dictWord{9, 10, 336}, - dictWord{ - 9, - 10, - 882, - }, - dictWord{11, 10, 266}, - dictWord{11, 10, 372}, - dictWord{11, 10, 944}, - dictWord{12, 10, 401}, - dictWord{140, 10, 641}, - dictWord{4, 11, 664}, - dictWord{133, 11, 804}, - dictWord{6, 0, 747}, - dictWord{134, 0, 1015}, - dictWord{135, 0, 1746}, - dictWord{9, 10, 31}, - dictWord{10, 10, 244}, - dictWord{ - 10, - 10, - 699, - }, - dictWord{12, 10, 149}, - dictWord{141, 10, 497}, - dictWord{133, 10, 377}, - dictWord{135, 0, 24}, - dictWord{6, 0, 1352}, - dictWord{5, 11, 32}, - dictWord{ - 145, - 10, - 101, - }, - dictWord{7, 0, 1530}, - dictWord{10, 0, 158}, - dictWord{13, 0, 13}, - dictWord{13, 0, 137}, - dictWord{13, 0, 258}, - dictWord{14, 0, 111}, - dictWord{ - 14, - 0, - 225, - }, - dictWord{14, 0, 253}, - dictWord{14, 0, 304}, - dictWord{14, 0, 339}, - dictWord{14, 0, 417}, - dictWord{146, 0, 33}, - dictWord{4, 0, 503}, - dictWord{ - 135, - 0, - 1661, - }, - dictWord{5, 0, 130}, - dictWord{6, 0, 845}, - dictWord{7, 0, 1314}, - dictWord{9, 0, 610}, - dictWord{10, 0, 718}, - dictWord{11, 0, 601}, - dictWord{11, 0, 819}, - dictWord{11, 0, 946}, - dictWord{140, 0, 536}, - dictWord{10, 0, 149}, - dictWord{11, 0, 280}, - dictWord{142, 0, 336}, - dictWord{134, 0, 1401}, - dictWord{ - 135, - 0, - 1946, - }, - dictWord{8, 0, 663}, - dictWord{144, 0, 8}, - dictWord{134, 0, 1607}, - dictWord{135, 10, 2023}, - dictWord{4, 11, 289}, - dictWord{7, 11, 629}, - dictWord{ - 7, - 11, - 1698, - }, - dictWord{7, 11, 1711}, - dictWord{140, 11, 215}, - dictWord{6, 11, 450}, - dictWord{136, 11, 109}, - dictWord{10, 0, 882}, - dictWord{10, 0, 883}, - dictWord{10, 0, 914}, - dictWord{138, 0, 928}, - dictWord{133, 10, 843}, - dictWord{136, 11, 705}, - dictWord{132, 10, 554}, - dictWord{133, 10, 536}, - dictWord{ - 5, - 0, - 417, - }, - dictWord{9, 10, 79}, - dictWord{11, 10, 625}, - dictWord{145, 10, 7}, - dictWord{7, 11, 1238}, - dictWord{142, 11, 37}, - dictWord{4, 0, 392}, - dictWord{ - 135, - 0, - 1597, - }, - dictWord{5, 0, 433}, - dictWord{9, 0, 633}, - dictWord{11, 0, 629}, - dictWord{132, 10, 424}, - dictWord{7, 10, 336}, - dictWord{136, 10, 785}, - dictWord{ - 134, - 11, - 355, - }, - dictWord{6, 0, 234}, - dictWord{7, 0, 769}, - dictWord{9, 0, 18}, - dictWord{138, 0, 358}, - dictWord{4, 10, 896}, - dictWord{134, 10, 1777}, - dictWord{ - 138, - 11, - 323, - }, - dictWord{7, 0, 140}, - dictWord{7, 0, 1950}, - dictWord{8, 0, 680}, - dictWord{11, 0, 817}, - dictWord{147, 0, 88}, - dictWord{7, 0, 1222}, - dictWord{ - 138, - 0, - 386, - }, - dictWord{139, 11, 908}, - dictWord{11, 0, 249}, - dictWord{12, 0, 313}, - dictWord{16, 0, 66}, - dictWord{145, 0, 26}, - dictWord{134, 0, 5}, - dictWord{7, 10, 750}, - dictWord{9, 10, 223}, - dictWord{11, 10, 27}, - dictWord{11, 10, 466}, - dictWord{12, 10, 624}, - dictWord{14, 10, 265}, - dictWord{146, 10, 61}, - dictWord{ - 134, - 11, - 26, - }, - dictWord{134, 0, 1216}, - dictWord{5, 0, 963}, - dictWord{134, 0, 1773}, - dictWord{4, 11, 414}, - dictWord{5, 11, 467}, - dictWord{9, 11, 654}, - dictWord{ - 10, - 11, - 451, - }, - dictWord{12, 11, 59}, - dictWord{141, 11, 375}, - dictWord{135, 11, 17}, - dictWord{4, 10, 603}, - dictWord{133, 10, 661}, - dictWord{4, 10, 11}, - dictWord{ - 6, - 10, - 128, - }, - dictWord{7, 10, 231}, - dictWord{7, 10, 1533}, - dictWord{138, 10, 725}, - dictWord{135, 11, 955}, - dictWord{7, 0, 180}, - dictWord{8, 0, 509}, - dictWord{ - 136, - 0, - 792, - }, - dictWord{132, 10, 476}, - dictWord{132, 0, 1002}, - dictWord{133, 11, 538}, - dictWord{135, 10, 1807}, - dictWord{132, 0, 931}, - dictWord{7, 0, 943}, - dictWord{11, 0, 614}, - dictWord{140, 0, 747}, - dictWord{135, 0, 1837}, - dictWord{9, 10, 20}, - dictWord{10, 10, 324}, - dictWord{10, 10, 807}, - dictWord{ - 139, - 10, - 488, - }, - dictWord{134, 0, 641}, - dictWord{6, 11, 280}, - dictWord{10, 11, 502}, - dictWord{11, 11, 344}, - dictWord{140, 11, 38}, - dictWord{5, 11, 45}, - dictWord{ - 7, - 11, - 1161, - }, - dictWord{11, 11, 448}, - dictWord{11, 11, 880}, - dictWord{13, 11, 139}, - dictWord{13, 11, 407}, - dictWord{15, 11, 16}, - dictWord{17, 11, 95}, - dictWord{ - 18, - 11, - 66, - }, - dictWord{18, 11, 88}, - dictWord{18, 11, 123}, - dictWord{149, 11, 7}, - dictWord{9, 0, 280}, - dictWord{138, 0, 134}, - dictWord{22, 0, 22}, - dictWord{23, 0, 5}, - dictWord{151, 0, 29}, - dictWord{136, 11, 777}, - dictWord{4, 0, 90}, - dictWord{5, 0, 545}, - dictWord{7, 0, 754}, - dictWord{9, 0, 186}, - dictWord{10, 0, 72}, - dictWord{ - 10, - 0, - 782, - }, - dictWord{11, 0, 577}, - dictWord{11, 0, 610}, - dictWord{11, 0, 960}, - dictWord{12, 0, 354}, - dictWord{12, 0, 362}, - dictWord{12, 0, 595}, - dictWord{ - 4, - 11, - 410, - }, - dictWord{135, 11, 521}, - dictWord{135, 11, 1778}, - dictWord{5, 10, 112}, - dictWord{6, 10, 103}, - dictWord{134, 10, 150}, - dictWord{138, 10, 356}, - dictWord{132, 0, 742}, - dictWord{7, 0, 151}, - dictWord{9, 0, 329}, - dictWord{139, 0, 254}, - dictWord{8, 0, 853}, - dictWord{8, 0, 881}, - dictWord{8, 0, 911}, - dictWord{ - 8, - 0, - 912, - }, - dictWord{10, 0, 872}, - dictWord{12, 0, 741}, - dictWord{12, 0, 742}, - dictWord{152, 0, 18}, - dictWord{4, 11, 573}, - dictWord{136, 11, 655}, - dictWord{ - 6, - 0, - 921, - }, - dictWord{134, 0, 934}, - dictWord{9, 0, 187}, - dictWord{10, 0, 36}, - dictWord{11, 0, 1016}, - dictWord{17, 0, 44}, - dictWord{146, 0, 64}, - dictWord{7, 0, 833}, - dictWord{136, 0, 517}, - dictWord{4, 0, 506}, - dictWord{5, 0, 295}, - dictWord{135, 0, 1680}, - dictWord{4, 10, 708}, - dictWord{8, 10, 15}, - dictWord{9, 10, 50}, - dictWord{ - 9, - 10, - 386, - }, - dictWord{11, 10, 18}, - dictWord{11, 10, 529}, - dictWord{140, 10, 228}, - dictWord{7, 0, 251}, - dictWord{7, 0, 1701}, - dictWord{8, 0, 436}, - dictWord{ - 4, - 10, - 563, - }, - dictWord{7, 10, 592}, - dictWord{7, 10, 637}, - dictWord{7, 10, 770}, - dictWord{8, 10, 463}, - dictWord{9, 10, 60}, - dictWord{9, 10, 335}, - dictWord{9, 10, 904}, - dictWord{10, 10, 73}, - dictWord{11, 10, 434}, - dictWord{12, 10, 585}, - dictWord{13, 10, 331}, - dictWord{18, 10, 110}, - dictWord{148, 10, 60}, - dictWord{ - 132, - 10, - 502, - }, - dictWord{136, 0, 584}, - dictWord{6, 10, 347}, - dictWord{138, 10, 161}, - dictWord{7, 0, 987}, - dictWord{9, 0, 688}, - dictWord{10, 0, 522}, - dictWord{ - 11, - 0, - 788, - }, - dictWord{12, 0, 137}, - dictWord{12, 0, 566}, - dictWord{14, 0, 9}, - dictWord{14, 0, 24}, - dictWord{14, 0, 64}, - dictWord{7, 11, 899}, - dictWord{142, 11, 325}, - dictWord{4, 0, 214}, - dictWord{5, 0, 500}, - dictWord{5, 10, 102}, - dictWord{6, 10, 284}, - dictWord{7, 10, 1079}, - dictWord{7, 10, 1423}, - dictWord{7, 10, 1702}, - dictWord{ - 8, - 10, - 470, - }, - dictWord{9, 10, 554}, - dictWord{9, 10, 723}, - dictWord{139, 10, 333}, - dictWord{7, 10, 246}, - dictWord{135, 10, 840}, - dictWord{6, 10, 10}, - dictWord{ - 8, - 10, - 571, - }, - dictWord{9, 10, 739}, - dictWord{143, 10, 91}, - dictWord{133, 10, 626}, - dictWord{146, 0, 195}, - dictWord{134, 0, 1775}, - dictWord{7, 0, 389}, - dictWord{7, 0, 700}, - dictWord{7, 0, 940}, - dictWord{8, 0, 514}, - dictWord{9, 0, 116}, - dictWord{9, 0, 535}, - dictWord{10, 0, 118}, - dictWord{11, 0, 107}, - dictWord{ - 11, - 0, - 148, - }, - dictWord{11, 0, 922}, - dictWord{12, 0, 254}, - dictWord{12, 0, 421}, - dictWord{142, 0, 238}, - dictWord{5, 10, 18}, - dictWord{6, 10, 526}, - dictWord{13, 10, 24}, - dictWord{13, 10, 110}, - dictWord{19, 10, 5}, - dictWord{147, 10, 44}, - dictWord{132, 0, 743}, - dictWord{11, 0, 292}, - dictWord{4, 10, 309}, - dictWord{5, 10, 462}, - dictWord{7, 10, 970}, - dictWord{135, 10, 1097}, - dictWord{22, 10, 30}, - dictWord{150, 10, 33}, - dictWord{139, 11, 338}, - dictWord{135, 11, 1598}, - dictWord{ - 7, - 0, - 1283, - }, - dictWord{9, 0, 227}, - dictWord{11, 0, 325}, - dictWord{11, 0, 408}, - dictWord{14, 0, 180}, - dictWord{146, 0, 47}, - dictWord{4, 0, 953}, - dictWord{6, 0, 1805}, - dictWord{6, 0, 1814}, - dictWord{6, 0, 1862}, - dictWord{140, 0, 774}, - dictWord{6, 11, 611}, - dictWord{135, 11, 1733}, - dictWord{135, 11, 1464}, - dictWord{ - 5, - 0, - 81, - }, - dictWord{7, 0, 146}, - dictWord{7, 0, 1342}, - dictWord{8, 0, 53}, - dictWord{8, 0, 561}, - dictWord{8, 0, 694}, - dictWord{8, 0, 754}, - dictWord{9, 0, 115}, - dictWord{ - 9, - 0, - 179, - }, - dictWord{9, 0, 894}, - dictWord{10, 0, 462}, - dictWord{10, 0, 813}, - dictWord{11, 0, 230}, - dictWord{11, 0, 657}, - dictWord{11, 0, 699}, - dictWord{11, 0, 748}, - dictWord{12, 0, 119}, - dictWord{12, 0, 200}, - dictWord{12, 0, 283}, - dictWord{142, 0, 273}, - dictWord{5, 0, 408}, - dictWord{6, 0, 789}, - dictWord{6, 0, 877}, - dictWord{ - 6, - 0, - 1253, - }, - dictWord{6, 0, 1413}, - dictWord{137, 0, 747}, - dictWord{134, 10, 1704}, - dictWord{135, 11, 663}, - dictWord{6, 0, 1910}, - dictWord{6, 0, 1915}, - dictWord{6, 0, 1923}, - dictWord{9, 0, 913}, - dictWord{9, 0, 928}, - dictWord{9, 0, 950}, - dictWord{9, 0, 954}, - dictWord{9, 0, 978}, - dictWord{9, 0, 993}, - dictWord{12, 0, 812}, - dictWord{12, 0, 819}, - dictWord{12, 0, 831}, - dictWord{12, 0, 833}, - dictWord{12, 0, 838}, - dictWord{12, 0, 909}, - dictWord{12, 0, 928}, - dictWord{12, 0, 931}, - dictWord{12, 0, 950}, - dictWord{15, 0, 186}, - dictWord{15, 0, 187}, - dictWord{15, 0, 195}, - dictWord{15, 0, 196}, - dictWord{15, 0, 209}, - dictWord{15, 0, 215}, - dictWord{ - 15, - 0, - 236, - }, - dictWord{15, 0, 241}, - dictWord{15, 0, 249}, - dictWord{15, 0, 253}, - dictWord{18, 0, 180}, - dictWord{18, 0, 221}, - dictWord{18, 0, 224}, - dictWord{ - 18, - 0, - 227, - }, - dictWord{18, 0, 229}, - dictWord{149, 0, 60}, - dictWord{7, 0, 1826}, - dictWord{135, 0, 1938}, - dictWord{11, 0, 490}, - dictWord{18, 0, 143}, - dictWord{ - 5, - 10, - 86, - }, - dictWord{7, 10, 743}, - dictWord{9, 10, 85}, - dictWord{10, 10, 281}, - dictWord{10, 10, 432}, - dictWord{12, 10, 251}, - dictWord{13, 10, 118}, - dictWord{ - 142, - 10, - 378, - }, - dictWord{5, 10, 524}, - dictWord{133, 10, 744}, - dictWord{141, 11, 442}, - dictWord{10, 10, 107}, - dictWord{140, 10, 436}, - dictWord{135, 11, 503}, - dictWord{134, 0, 1162}, - dictWord{132, 10, 927}, - dictWord{7, 0, 30}, - dictWord{8, 0, 86}, - dictWord{8, 0, 315}, - dictWord{8, 0, 700}, - dictWord{9, 0, 576}, - dictWord{ - 9, - 0, - 858, - }, - dictWord{10, 0, 414}, - dictWord{11, 0, 310}, - dictWord{11, 0, 888}, - dictWord{11, 0, 904}, - dictWord{12, 0, 361}, - dictWord{13, 0, 248}, - dictWord{13, 0, 371}, - dictWord{14, 0, 142}, - dictWord{12, 10, 670}, - dictWord{146, 10, 94}, - dictWord{134, 0, 721}, - dictWord{4, 11, 113}, - dictWord{5, 11, 163}, - dictWord{5, 11, 735}, - dictWord{7, 11, 1009}, - dictWord{7, 10, 1149}, - dictWord{9, 11, 9}, - dictWord{9, 10, 156}, - dictWord{9, 11, 771}, - dictWord{12, 11, 90}, - dictWord{13, 11, 138}, - dictWord{13, 11, 410}, - dictWord{143, 11, 128}, - dictWord{138, 0, 839}, - dictWord{133, 10, 778}, - dictWord{137, 0, 617}, - dictWord{133, 10, 502}, - dictWord{ - 8, - 10, - 196, - }, - dictWord{10, 10, 283}, - dictWord{139, 10, 406}, - dictWord{6, 0, 428}, - dictWord{7, 0, 524}, - dictWord{8, 0, 169}, - dictWord{8, 0, 234}, - dictWord{9, 0, 480}, - dictWord{138, 0, 646}, - dictWord{133, 10, 855}, - dictWord{134, 0, 1648}, - dictWord{7, 0, 1205}, - dictWord{138, 0, 637}, - dictWord{7, 0, 1596}, - dictWord{ - 4, - 11, - 935, - }, - dictWord{133, 11, 823}, - dictWord{5, 11, 269}, - dictWord{7, 11, 434}, - dictWord{7, 11, 891}, - dictWord{8, 11, 339}, - dictWord{9, 11, 702}, - dictWord{ - 11, - 11, - 594, - }, - dictWord{11, 11, 718}, - dictWord{145, 11, 100}, - dictWord{7, 11, 878}, - dictWord{9, 11, 485}, - dictWord{141, 11, 264}, - dictWord{4, 0, 266}, - dictWord{ - 8, - 0, - 4, - }, - dictWord{9, 0, 39}, - dictWord{10, 0, 166}, - dictWord{11, 0, 918}, - dictWord{12, 0, 635}, - dictWord{20, 0, 10}, - dictWord{22, 0, 27}, - dictWord{22, 0, 43}, - dictWord{ - 22, - 0, - 52, - }, - dictWord{134, 11, 1713}, - dictWord{7, 10, 1400}, - dictWord{9, 10, 446}, - dictWord{138, 10, 45}, - dictWord{135, 11, 900}, - dictWord{132, 0, 862}, - dictWord{134, 0, 1554}, - dictWord{135, 11, 1033}, - dictWord{19, 0, 16}, - dictWord{147, 11, 16}, - dictWord{135, 11, 1208}, - dictWord{7, 0, 157}, - dictWord{ - 136, - 0, - 279, - }, - dictWord{6, 0, 604}, - dictWord{136, 0, 391}, - dictWord{13, 10, 455}, - dictWord{15, 10, 99}, - dictWord{15, 10, 129}, - dictWord{144, 10, 68}, - dictWord{ - 135, - 10, - 172, - }, - dictWord{7, 0, 945}, - dictWord{11, 0, 713}, - dictWord{139, 0, 744}, - dictWord{4, 0, 973}, - dictWord{10, 0, 877}, - dictWord{10, 0, 937}, - dictWord{ - 10, - 0, - 938, - }, - dictWord{140, 0, 711}, - dictWord{139, 0, 1022}, - dictWord{132, 10, 568}, - dictWord{142, 11, 143}, - dictWord{4, 0, 567}, - dictWord{9, 0, 859}, - dictWord{ - 132, - 10, - 732, - }, - dictWord{7, 0, 1846}, - dictWord{136, 0, 628}, - dictWord{136, 10, 733}, - dictWord{133, 0, 762}, - dictWord{4, 10, 428}, - dictWord{135, 10, 1789}, - dictWord{10, 0, 784}, - dictWord{13, 0, 191}, - dictWord{7, 10, 2015}, - dictWord{140, 10, 665}, - dictWord{133, 0, 298}, - dictWord{7, 0, 633}, - dictWord{7, 0, 905}, - dictWord{7, 0, 909}, - dictWord{7, 0, 1538}, - dictWord{9, 0, 767}, - dictWord{140, 0, 636}, - dictWord{138, 10, 806}, - dictWord{132, 0, 795}, - dictWord{139, 0, 301}, - dictWord{135, 0, 1970}, - dictWord{5, 11, 625}, - dictWord{135, 11, 1617}, - dictWord{135, 11, 275}, - dictWord{7, 11, 37}, - dictWord{8, 11, 425}, - dictWord{ - 8, - 11, - 693, - }, - dictWord{9, 11, 720}, - dictWord{10, 11, 380}, - dictWord{10, 11, 638}, - dictWord{11, 11, 273}, - dictWord{11, 11, 307}, - dictWord{11, 11, 473}, - dictWord{ - 12, - 11, - 61, - }, - dictWord{143, 11, 43}, - dictWord{135, 11, 198}, - dictWord{134, 0, 1236}, - dictWord{7, 0, 369}, - dictWord{12, 0, 644}, - dictWord{12, 0, 645}, - dictWord{144, 0, 90}, - dictWord{19, 0, 15}, - dictWord{149, 0, 27}, - dictWord{6, 0, 71}, - dictWord{7, 0, 845}, - dictWord{8, 0, 160}, - dictWord{9, 0, 318}, - dictWord{6, 10, 1623}, - dictWord{134, 10, 1681}, - dictWord{134, 0, 1447}, - dictWord{134, 0, 1255}, - dictWord{138, 0, 735}, - dictWord{8, 0, 76}, - dictWord{132, 11, 168}, - dictWord{ - 6, - 10, - 1748, - }, - dictWord{8, 10, 715}, - dictWord{9, 10, 802}, - dictWord{10, 10, 46}, - dictWord{10, 10, 819}, - dictWord{13, 10, 308}, - dictWord{14, 10, 351}, - dictWord{14, 10, 363}, - dictWord{146, 10, 67}, - dictWord{135, 11, 91}, - dictWord{6, 0, 474}, - dictWord{4, 10, 63}, - dictWord{133, 10, 347}, - dictWord{133, 10, 749}, - dictWord{138, 0, 841}, - dictWord{133, 10, 366}, - dictWord{6, 0, 836}, - dictWord{132, 11, 225}, - dictWord{135, 0, 1622}, - dictWord{135, 10, 89}, - dictWord{ - 140, - 0, - 735, - }, - dictWord{134, 0, 1601}, - dictWord{138, 11, 145}, - dictWord{6, 0, 1390}, - dictWord{137, 0, 804}, - dictWord{142, 0, 394}, - dictWord{6, 11, 15}, - dictWord{ - 7, - 11, - 70, - }, - dictWord{10, 11, 240}, - dictWord{147, 11, 93}, - dictWord{6, 0, 96}, - dictWord{135, 0, 1426}, - dictWord{4, 0, 651}, - dictWord{133, 0, 289}, - dictWord{ - 7, - 11, - 956, - }, - dictWord{7, 10, 977}, - dictWord{7, 11, 1157}, - dictWord{7, 11, 1506}, - dictWord{7, 11, 1606}, - dictWord{7, 11, 1615}, - dictWord{7, 11, 1619}, - dictWord{ - 7, - 11, - 1736, - }, - dictWord{7, 11, 1775}, - dictWord{8, 11, 590}, - dictWord{9, 11, 324}, - dictWord{9, 11, 736}, - dictWord{9, 11, 774}, - dictWord{9, 11, 776}, - dictWord{ - 9, - 11, - 784, - }, - dictWord{10, 11, 567}, - dictWord{10, 11, 708}, - dictWord{11, 11, 518}, - dictWord{11, 11, 613}, - dictWord{11, 11, 695}, - dictWord{11, 11, 716}, - dictWord{11, 11, 739}, - dictWord{11, 11, 770}, - dictWord{11, 11, 771}, - dictWord{11, 11, 848}, - dictWord{11, 11, 857}, - dictWord{11, 11, 931}, - dictWord{ - 11, - 11, - 947, - }, - dictWord{12, 11, 326}, - dictWord{12, 11, 387}, - dictWord{12, 11, 484}, - dictWord{12, 11, 528}, - dictWord{12, 11, 552}, - dictWord{12, 11, 613}, - dictWord{ - 13, - 11, - 189, - }, - dictWord{13, 11, 256}, - dictWord{13, 11, 340}, - dictWord{13, 11, 432}, - dictWord{13, 11, 436}, - dictWord{13, 11, 440}, - dictWord{13, 11, 454}, - dictWord{14, 11, 174}, - dictWord{14, 11, 220}, - dictWord{14, 11, 284}, - dictWord{14, 11, 390}, - dictWord{145, 11, 121}, - dictWord{7, 0, 688}, - dictWord{8, 0, 35}, - dictWord{9, 0, 511}, - dictWord{10, 0, 767}, - dictWord{147, 0, 118}, - dictWord{134, 0, 667}, - dictWord{4, 0, 513}, - dictWord{5, 10, 824}, - dictWord{133, 10, 941}, - dictWord{7, 10, 440}, - dictWord{8, 10, 230}, - dictWord{139, 10, 106}, - dictWord{134, 0, 2034}, - dictWord{135, 11, 1399}, - dictWord{143, 11, 66}, - dictWord{ - 135, - 11, - 1529, - }, - dictWord{4, 11, 145}, - dictWord{6, 11, 176}, - dictWord{7, 11, 395}, - dictWord{9, 11, 562}, - dictWord{144, 11, 28}, - dictWord{132, 11, 501}, - dictWord{132, 0, 704}, - dictWord{134, 0, 1524}, - dictWord{7, 0, 1078}, - dictWord{134, 11, 464}, - dictWord{6, 11, 509}, - dictWord{10, 11, 82}, - dictWord{20, 11, 91}, - dictWord{151, 11, 13}, - dictWord{4, 0, 720}, - dictWord{133, 0, 306}, - dictWord{133, 0, 431}, - dictWord{7, 0, 1196}, - dictWord{4, 10, 914}, - dictWord{5, 10, 800}, - dictWord{133, 10, 852}, - dictWord{135, 11, 1189}, - dictWord{10, 0, 54}, - dictWord{141, 10, 115}, - dictWord{7, 10, 564}, - dictWord{142, 10, 168}, - dictWord{ - 5, - 0, - 464, - }, - dictWord{6, 0, 236}, - dictWord{7, 0, 696}, - dictWord{7, 0, 914}, - dictWord{7, 0, 1108}, - dictWord{7, 0, 1448}, - dictWord{9, 0, 15}, - dictWord{9, 0, 564}, - dictWord{ - 10, - 0, - 14, - }, - dictWord{12, 0, 565}, - dictWord{13, 0, 449}, - dictWord{14, 0, 53}, - dictWord{15, 0, 13}, - dictWord{16, 0, 64}, - dictWord{17, 0, 41}, - dictWord{4, 10, 918}, - dictWord{133, 10, 876}, - dictWord{6, 0, 1418}, - dictWord{134, 10, 1764}, - dictWord{4, 10, 92}, - dictWord{133, 10, 274}, - dictWord{134, 0, 907}, - dictWord{ - 4, - 11, - 114, - }, - dictWord{8, 10, 501}, - dictWord{9, 11, 492}, - dictWord{13, 11, 462}, - dictWord{142, 11, 215}, - dictWord{4, 11, 77}, - dictWord{5, 11, 361}, - dictWord{ - 6, - 11, - 139, - }, - dictWord{6, 11, 401}, - dictWord{6, 11, 404}, - dictWord{7, 11, 413}, - dictWord{7, 11, 715}, - dictWord{7, 11, 1716}, - dictWord{11, 11, 279}, - dictWord{ - 12, - 11, - 179, - }, - dictWord{12, 11, 258}, - dictWord{13, 11, 244}, - dictWord{142, 11, 358}, - dictWord{6, 0, 1767}, - dictWord{12, 0, 194}, - dictWord{145, 0, 107}, - dictWord{ - 134, - 11, - 1717, - }, - dictWord{5, 10, 743}, - dictWord{142, 11, 329}, - dictWord{4, 10, 49}, - dictWord{7, 10, 280}, - dictWord{135, 10, 1633}, - dictWord{5, 0, 840}, - dictWord{7, 11, 1061}, - dictWord{8, 11, 82}, - dictWord{11, 11, 250}, - dictWord{12, 11, 420}, - dictWord{141, 11, 184}, - dictWord{135, 11, 724}, - dictWord{ - 134, - 0, - 900, - }, - dictWord{136, 10, 47}, - dictWord{134, 0, 1436}, - dictWord{144, 11, 0}, - dictWord{6, 0, 675}, - dictWord{7, 0, 1008}, - dictWord{7, 0, 1560}, - dictWord{ - 9, - 0, - 642, - }, - dictWord{11, 0, 236}, - dictWord{14, 0, 193}, - dictWord{5, 10, 272}, - dictWord{5, 10, 908}, - dictWord{5, 10, 942}, - dictWord{8, 10, 197}, - dictWord{9, 10, 47}, - dictWord{11, 10, 538}, - dictWord{139, 10, 742}, - dictWord{4, 0, 68}, - dictWord{5, 0, 628}, - dictWord{5, 0, 634}, - dictWord{6, 0, 386}, - dictWord{7, 0, 794}, - dictWord{ - 8, - 0, - 273, - }, - dictWord{9, 0, 563}, - dictWord{10, 0, 105}, - dictWord{10, 0, 171}, - dictWord{11, 0, 94}, - dictWord{139, 0, 354}, - dictWord{135, 10, 1911}, - dictWord{ - 137, - 10, - 891, - }, - dictWord{4, 0, 95}, - dictWord{6, 0, 1297}, - dictWord{6, 0, 1604}, - dictWord{7, 0, 416}, - dictWord{139, 0, 830}, - dictWord{6, 11, 513}, - dictWord{ - 135, - 11, - 1052, - }, - dictWord{7, 0, 731}, - dictWord{13, 0, 20}, - dictWord{143, 0, 11}, - dictWord{137, 11, 899}, - dictWord{10, 0, 850}, - dictWord{140, 0, 697}, - dictWord{ - 4, - 0, - 662, - }, - dictWord{7, 11, 1417}, - dictWord{12, 11, 382}, - dictWord{17, 11, 48}, - dictWord{152, 11, 12}, - dictWord{133, 0, 736}, - dictWord{132, 0, 861}, - dictWord{ - 4, - 10, - 407, - }, - dictWord{132, 10, 560}, - dictWord{141, 10, 490}, - dictWord{6, 11, 545}, - dictWord{7, 11, 565}, - dictWord{7, 11, 1669}, - dictWord{10, 11, 114}, - dictWord{11, 11, 642}, - dictWord{140, 11, 618}, - dictWord{6, 0, 871}, - dictWord{134, 0, 1000}, - dictWord{5, 0, 864}, - dictWord{10, 0, 648}, - dictWord{11, 0, 671}, - dictWord{15, 0, 46}, - dictWord{133, 11, 5}, - dictWord{133, 0, 928}, - dictWord{11, 0, 90}, - dictWord{13, 0, 7}, - dictWord{4, 10, 475}, - dictWord{11, 10, 35}, - dictWord{ - 13, - 10, - 71, - }, - dictWord{13, 10, 177}, - dictWord{142, 10, 422}, - dictWord{136, 0, 332}, - dictWord{135, 11, 192}, - dictWord{134, 0, 1055}, - dictWord{136, 11, 763}, - dictWord{11, 0, 986}, - dictWord{140, 0, 682}, - dictWord{7, 0, 76}, - dictWord{8, 0, 44}, - dictWord{9, 0, 884}, - dictWord{10, 0, 580}, - dictWord{11, 0, 399}, - dictWord{ - 11, - 0, - 894, - }, - dictWord{143, 0, 122}, - dictWord{135, 11, 1237}, - dictWord{135, 10, 636}, - dictWord{11, 0, 300}, - dictWord{6, 10, 222}, - dictWord{7, 10, 1620}, - dictWord{ - 8, - 10, - 409, - }, - dictWord{137, 10, 693}, - dictWord{4, 11, 87}, - dictWord{5, 11, 250}, - dictWord{10, 11, 601}, - dictWord{13, 11, 298}, - dictWord{13, 11, 353}, - dictWord{141, 11, 376}, - dictWord{5, 0, 518}, - dictWord{10, 0, 340}, - dictWord{11, 0, 175}, - dictWord{149, 0, 16}, - dictWord{140, 0, 771}, - dictWord{6, 0, 1108}, - dictWord{137, 0, 831}, - dictWord{132, 0, 836}, - dictWord{135, 0, 1852}, - dictWord{4, 0, 957}, - dictWord{6, 0, 1804}, - dictWord{8, 0, 842}, - dictWord{8, 0, 843}, - dictWord{ - 8, - 0, - 851, - }, - dictWord{8, 0, 855}, - dictWord{140, 0, 767}, - dictWord{135, 11, 814}, - dictWord{4, 11, 57}, - dictWord{7, 11, 1195}, - dictWord{7, 11, 1438}, - dictWord{ - 7, - 11, - 1548, - }, - dictWord{7, 11, 1835}, - dictWord{7, 11, 1904}, - dictWord{9, 11, 757}, - dictWord{10, 11, 604}, - dictWord{139, 11, 519}, - dictWord{133, 10, 882}, - dictWord{138, 0, 246}, - dictWord{4, 0, 934}, - dictWord{5, 0, 202}, - dictWord{8, 0, 610}, - dictWord{7, 11, 1897}, - dictWord{12, 11, 290}, - dictWord{13, 11, 80}, - dictWord{13, 11, 437}, - dictWord{145, 11, 74}, - dictWord{8, 0, 96}, - dictWord{9, 0, 36}, - dictWord{10, 0, 607}, - dictWord{10, 0, 804}, - dictWord{10, 0, 832}, - dictWord{ - 11, - 0, - 423, - }, - dictWord{11, 0, 442}, - dictWord{12, 0, 309}, - dictWord{14, 0, 199}, - dictWord{15, 0, 90}, - dictWord{145, 0, 110}, - dictWord{132, 10, 426}, - dictWord{ - 7, - 0, - 654, - }, - dictWord{8, 0, 240}, - dictWord{6, 10, 58}, - dictWord{7, 10, 745}, - dictWord{7, 10, 1969}, - dictWord{8, 10, 675}, - dictWord{9, 10, 479}, - dictWord{9, 10, 731}, - dictWord{10, 10, 330}, - dictWord{10, 10, 593}, - dictWord{10, 10, 817}, - dictWord{11, 10, 32}, - dictWord{11, 10, 133}, - dictWord{11, 10, 221}, - dictWord{ - 145, - 10, - 68, - }, - dictWord{9, 0, 13}, - dictWord{9, 0, 398}, - dictWord{9, 0, 727}, - dictWord{10, 0, 75}, - dictWord{10, 0, 184}, - dictWord{10, 0, 230}, - dictWord{10, 0, 564}, - dictWord{ - 10, - 0, - 569, - }, - dictWord{11, 0, 973}, - dictWord{12, 0, 70}, - dictWord{12, 0, 189}, - dictWord{13, 0, 57}, - dictWord{141, 0, 257}, - dictWord{4, 11, 209}, - dictWord{ - 135, - 11, - 902, - }, - dictWord{7, 0, 391}, - dictWord{137, 10, 538}, - dictWord{134, 0, 403}, - dictWord{6, 11, 303}, - dictWord{7, 11, 335}, - dictWord{7, 11, 1437}, - dictWord{ - 7, - 11, - 1668, - }, - dictWord{8, 11, 553}, - dictWord{8, 11, 652}, - dictWord{8, 11, 656}, - dictWord{9, 11, 558}, - dictWord{11, 11, 743}, - dictWord{149, 11, 18}, - dictWord{ - 132, - 11, - 559, - }, - dictWord{11, 0, 75}, - dictWord{142, 0, 267}, - dictWord{6, 0, 815}, - dictWord{141, 11, 2}, - dictWord{141, 0, 366}, - dictWord{137, 0, 631}, - dictWord{ - 133, - 11, - 1017, - }, - dictWord{5, 0, 345}, - dictWord{135, 0, 1016}, - dictWord{133, 11, 709}, - dictWord{134, 11, 1745}, - dictWord{133, 10, 566}, - dictWord{7, 0, 952}, - dictWord{6, 10, 48}, - dictWord{9, 10, 139}, - dictWord{10, 10, 399}, - dictWord{11, 10, 469}, - dictWord{12, 10, 634}, - dictWord{141, 10, 223}, - dictWord{ - 133, - 0, - 673, - }, - dictWord{9, 0, 850}, - dictWord{7, 11, 8}, - dictWord{136, 11, 206}, - dictWord{6, 0, 662}, - dictWord{149, 0, 35}, - dictWord{4, 0, 287}, - dictWord{133, 0, 1018}, - dictWord{6, 10, 114}, - dictWord{7, 10, 1224}, - dictWord{7, 10, 1556}, - dictWord{136, 10, 3}, - dictWord{8, 10, 576}, - dictWord{137, 10, 267}, - dictWord{4, 0, 884}, - dictWord{5, 0, 34}, - dictWord{10, 0, 724}, - dictWord{12, 0, 444}, - dictWord{13, 0, 354}, - dictWord{18, 0, 32}, - dictWord{23, 0, 24}, - dictWord{23, 0, 31}, - dictWord{ - 152, - 0, - 5, - }, - dictWord{133, 10, 933}, - dictWord{132, 11, 776}, - dictWord{138, 0, 151}, - dictWord{136, 0, 427}, - dictWord{134, 0, 382}, - dictWord{132, 0, 329}, - dictWord{ - 9, - 0, - 846, - }, - dictWord{10, 0, 827}, - dictWord{138, 11, 33}, - dictWord{9, 0, 279}, - dictWord{10, 0, 407}, - dictWord{14, 0, 84}, - dictWord{22, 0, 18}, - dictWord{ - 135, - 11, - 1297, - }, - dictWord{136, 11, 406}, - dictWord{132, 0, 906}, - dictWord{136, 0, 366}, - dictWord{134, 0, 843}, - dictWord{134, 0, 1443}, - dictWord{135, 0, 1372}, - dictWord{138, 0, 992}, - dictWord{4, 0, 123}, - dictWord{5, 0, 605}, - dictWord{7, 0, 1509}, - dictWord{136, 0, 36}, - dictWord{132, 0, 649}, - dictWord{8, 11, 175}, - dictWord{10, 11, 168}, - dictWord{138, 11, 573}, - dictWord{133, 0, 767}, - dictWord{134, 0, 1018}, - dictWord{135, 11, 1305}, - dictWord{12, 10, 30}, - dictWord{ - 13, - 10, - 148, - }, - dictWord{14, 10, 87}, - dictWord{14, 10, 182}, - dictWord{16, 10, 42}, - dictWord{148, 10, 70}, - dictWord{134, 11, 607}, - dictWord{4, 0, 273}, - dictWord{ - 5, - 0, - 658, - }, - dictWord{133, 0, 995}, - dictWord{6, 0, 72}, - dictWord{139, 11, 174}, - dictWord{10, 0, 483}, - dictWord{12, 0, 368}, - dictWord{7, 10, 56}, - dictWord{ - 7, - 10, - 1989, - }, - dictWord{8, 10, 337}, - dictWord{8, 10, 738}, - dictWord{9, 10, 600}, - dictWord{13, 10, 447}, - dictWord{142, 10, 92}, - dictWord{5, 11, 784}, - dictWord{ - 138, - 10, - 666, - }, - dictWord{135, 0, 1345}, - dictWord{139, 11, 882}, - dictWord{134, 0, 1293}, - dictWord{133, 0, 589}, - dictWord{134, 0, 1988}, - dictWord{5, 0, 117}, - dictWord{6, 0, 514}, - dictWord{6, 0, 541}, - dictWord{7, 0, 1164}, - dictWord{7, 0, 1436}, - dictWord{8, 0, 220}, - dictWord{8, 0, 648}, - dictWord{10, 0, 688}, - dictWord{ - 139, - 0, - 560, - }, - dictWord{136, 0, 379}, - dictWord{5, 0, 686}, - dictWord{7, 10, 866}, - dictWord{135, 10, 1163}, - dictWord{132, 10, 328}, - dictWord{9, 11, 14}, - dictWord{ - 9, - 11, - 441, - }, - dictWord{10, 11, 306}, - dictWord{139, 11, 9}, - dictWord{4, 10, 101}, - dictWord{135, 10, 1171}, - dictWord{5, 10, 833}, - dictWord{136, 10, 744}, - dictWord{5, 11, 161}, - dictWord{7, 11, 839}, - dictWord{135, 11, 887}, - dictWord{7, 0, 196}, - dictWord{10, 0, 765}, - dictWord{11, 0, 347}, - dictWord{11, 0, 552}, - dictWord{11, 0, 790}, - dictWord{12, 0, 263}, - dictWord{13, 0, 246}, - dictWord{13, 0, 270}, - dictWord{13, 0, 395}, - dictWord{14, 0, 176}, - dictWord{14, 0, 190}, - dictWord{ - 14, - 0, - 398, - }, - dictWord{14, 0, 412}, - dictWord{15, 0, 32}, - dictWord{15, 0, 63}, - dictWord{16, 0, 88}, - dictWord{147, 0, 105}, - dictWord{6, 10, 9}, - dictWord{6, 10, 397}, - dictWord{7, 10, 53}, - dictWord{7, 10, 1742}, - dictWord{10, 10, 632}, - dictWord{11, 10, 828}, - dictWord{140, 10, 146}, - dictWord{5, 0, 381}, - dictWord{135, 0, 1792}, - dictWord{134, 0, 1452}, - dictWord{135, 11, 429}, - dictWord{8, 0, 367}, - dictWord{10, 0, 760}, - dictWord{14, 0, 79}, - dictWord{20, 0, 17}, - dictWord{152, 0, 0}, - dictWord{7, 0, 616}, - dictWord{138, 0, 413}, - dictWord{11, 10, 417}, - dictWord{12, 10, 223}, - dictWord{140, 10, 265}, - dictWord{7, 11, 1611}, - dictWord{13, 11, 14}, - dictWord{15, 11, 44}, - dictWord{19, 11, 13}, - dictWord{148, 11, 76}, - dictWord{135, 0, 1229}, - dictWord{6, 0, 120}, - dictWord{7, 0, 1188}, - dictWord{7, 0, 1710}, - dictWord{8, 0, 286}, - dictWord{9, 0, 667}, - dictWord{11, 0, 592}, - dictWord{139, 0, 730}, - dictWord{135, 11, 1814}, - dictWord{135, 0, 1146}, - dictWord{4, 10, 186}, - dictWord{5, 10, 157}, - dictWord{8, 10, 168}, - dictWord{138, 10, 6}, - dictWord{4, 0, 352}, - dictWord{135, 0, 687}, - dictWord{4, 0, 192}, - dictWord{5, 0, 49}, - dictWord{ - 6, - 0, - 200, - }, - dictWord{6, 0, 293}, - dictWord{6, 0, 1696}, - dictWord{135, 0, 1151}, - dictWord{133, 10, 875}, - dictWord{5, 10, 773}, - dictWord{5, 10, 991}, - dictWord{ - 6, - 10, - 1635, - }, - dictWord{134, 10, 1788}, - dictWord{7, 10, 111}, - dictWord{136, 10, 581}, - dictWord{6, 0, 935}, - dictWord{134, 0, 1151}, - dictWord{134, 0, 1050}, - dictWord{132, 0, 650}, - dictWord{132, 0, 147}, - dictWord{11, 0, 194}, - dictWord{12, 0, 62}, - dictWord{12, 0, 88}, - dictWord{11, 11, 194}, - dictWord{12, 11, 62}, - dictWord{140, 11, 88}, - dictWord{6, 0, 339}, - dictWord{135, 0, 923}, - dictWord{134, 10, 1747}, - dictWord{7, 11, 643}, - dictWord{136, 11, 236}, - dictWord{ - 133, - 0, - 934, - }, - dictWord{7, 10, 1364}, - dictWord{7, 10, 1907}, - dictWord{141, 10, 158}, - dictWord{132, 10, 659}, - dictWord{4, 10, 404}, - dictWord{135, 10, 675}, - dictWord{7, 11, 581}, - dictWord{9, 11, 644}, - dictWord{137, 11, 699}, - dictWord{13, 0, 211}, - dictWord{14, 0, 133}, - dictWord{14, 0, 204}, - dictWord{15, 0, 64}, - dictWord{ - 15, - 0, - 69, - }, - dictWord{15, 0, 114}, - dictWord{16, 0, 10}, - dictWord{19, 0, 23}, - dictWord{19, 0, 35}, - dictWord{19, 0, 39}, - dictWord{19, 0, 51}, - dictWord{19, 0, 71}, - dictWord{19, 0, 75}, - dictWord{152, 0, 15}, - dictWord{133, 10, 391}, - dictWord{5, 11, 54}, - dictWord{135, 11, 1513}, - dictWord{7, 0, 222}, - dictWord{8, 0, 341}, - dictWord{ - 5, - 10, - 540, - }, - dictWord{134, 10, 1697}, - dictWord{134, 10, 78}, - dictWord{132, 11, 744}, - dictWord{136, 0, 293}, - dictWord{137, 11, 701}, - dictWord{ - 7, - 11, - 930, - }, - dictWord{10, 11, 402}, - dictWord{10, 11, 476}, - dictWord{13, 11, 452}, - dictWord{18, 11, 55}, - dictWord{147, 11, 104}, - dictWord{132, 0, 637}, - dictWord{133, 10, 460}, - dictWord{8, 11, 50}, - dictWord{137, 11, 624}, - dictWord{132, 11, 572}, - dictWord{134, 0, 1159}, - dictWord{4, 10, 199}, - dictWord{ - 139, - 10, - 34, - }, - dictWord{134, 0, 847}, - dictWord{134, 10, 388}, - dictWord{6, 11, 43}, - dictWord{7, 11, 38}, - dictWord{8, 11, 248}, - dictWord{9, 11, 504}, - dictWord{ - 138, - 11, - 513, - }, - dictWord{9, 0, 683}, - dictWord{4, 10, 511}, - dictWord{6, 10, 608}, - dictWord{9, 10, 333}, - dictWord{10, 10, 602}, - dictWord{11, 10, 441}, - dictWord{ - 11, - 10, - 723, - }, - dictWord{11, 10, 976}, - dictWord{140, 10, 357}, - dictWord{9, 0, 867}, - dictWord{138, 0, 837}, - dictWord{6, 0, 944}, - dictWord{135, 11, 326}, - dictWord{ - 135, - 0, - 1809, - }, - dictWord{5, 10, 938}, - dictWord{7, 11, 783}, - dictWord{136, 10, 707}, - dictWord{133, 11, 766}, - dictWord{133, 11, 363}, - dictWord{6, 0, 170}, - dictWord{7, 0, 1080}, - dictWord{8, 0, 395}, - dictWord{8, 0, 487}, - dictWord{141, 0, 147}, - dictWord{6, 11, 258}, - dictWord{140, 11, 409}, - dictWord{4, 0, 535}, - dictWord{ - 8, - 0, - 618, - }, - dictWord{5, 11, 249}, - dictWord{148, 11, 82}, - dictWord{6, 0, 1379}, - dictWord{149, 11, 15}, - dictWord{135, 0, 1625}, - dictWord{150, 0, 23}, - dictWord{ - 5, - 11, - 393, - }, - dictWord{6, 11, 378}, - dictWord{7, 11, 1981}, - dictWord{9, 11, 32}, - dictWord{9, 11, 591}, - dictWord{10, 11, 685}, - dictWord{10, 11, 741}, - dictWord{ - 142, - 11, - 382, - }, - dictWord{133, 11, 788}, - dictWord{7, 11, 1968}, - dictWord{10, 11, 19}, - dictWord{139, 11, 911}, - dictWord{7, 11, 1401}, - dictWord{ - 135, - 11, - 1476, - }, - dictWord{4, 11, 61}, - dictWord{5, 11, 58}, - dictWord{5, 11, 171}, - dictWord{5, 11, 635}, - dictWord{5, 11, 683}, - dictWord{5, 11, 700}, - dictWord{6, 11, 291}, - dictWord{6, 11, 566}, - dictWord{7, 11, 1650}, - dictWord{11, 11, 523}, - dictWord{12, 11, 273}, - dictWord{12, 11, 303}, - dictWord{15, 11, 39}, - dictWord{ - 143, - 11, - 111, - }, - dictWord{6, 10, 469}, - dictWord{7, 10, 1709}, - dictWord{138, 10, 515}, - dictWord{4, 0, 778}, - dictWord{134, 11, 589}, - dictWord{132, 0, 46}, - dictWord{ - 5, - 0, - 811, - }, - dictWord{6, 0, 1679}, - dictWord{6, 0, 1714}, - dictWord{135, 0, 2032}, - dictWord{7, 0, 1458}, - dictWord{9, 0, 407}, - dictWord{11, 0, 15}, - dictWord{12, 0, 651}, - dictWord{149, 0, 37}, - dictWord{7, 0, 938}, - dictWord{132, 10, 500}, - dictWord{6, 0, 34}, - dictWord{7, 0, 69}, - dictWord{7, 0, 1089}, - dictWord{7, 0, 1281}, - dictWord{ - 8, - 0, - 708, - }, - dictWord{8, 0, 721}, - dictWord{9, 0, 363}, - dictWord{148, 0, 98}, - dictWord{10, 11, 231}, - dictWord{147, 11, 124}, - dictWord{7, 11, 726}, - dictWord{ - 152, - 11, - 9, - }, - dictWord{5, 10, 68}, - dictWord{134, 10, 383}, - dictWord{136, 11, 583}, - dictWord{4, 11, 917}, - dictWord{133, 11, 1005}, - dictWord{11, 10, 216}, - dictWord{139, 10, 340}, - dictWord{135, 11, 1675}, - dictWord{8, 0, 441}, - dictWord{10, 0, 314}, - dictWord{143, 0, 3}, - dictWord{132, 11, 919}, - dictWord{4, 10, 337}, - dictWord{6, 10, 353}, - dictWord{7, 10, 1934}, - dictWord{8, 10, 488}, - dictWord{137, 10, 429}, - dictWord{7, 0, 889}, - dictWord{7, 10, 1795}, - dictWord{8, 10, 259}, - dictWord{9, 10, 135}, - dictWord{9, 10, 177}, - dictWord{9, 10, 860}, - dictWord{10, 10, 825}, - dictWord{11, 10, 115}, - dictWord{11, 10, 370}, - dictWord{11, 10, 405}, - dictWord{11, 10, 604}, - dictWord{12, 10, 10}, - dictWord{12, 10, 667}, - dictWord{12, 10, 669}, - dictWord{13, 10, 76}, - dictWord{14, 10, 310}, - dictWord{ - 15, - 10, - 76, - }, - dictWord{15, 10, 147}, - dictWord{148, 10, 23}, - dictWord{4, 10, 15}, - dictWord{4, 11, 255}, - dictWord{5, 10, 22}, - dictWord{5, 11, 302}, - dictWord{6, 11, 132}, - dictWord{6, 10, 244}, - dictWord{7, 10, 40}, - dictWord{7, 11, 128}, - dictWord{7, 10, 200}, - dictWord{7, 11, 283}, - dictWord{7, 10, 906}, - dictWord{7, 10, 1199}, - dictWord{ - 7, - 11, - 1299, - }, - dictWord{9, 10, 616}, - dictWord{10, 11, 52}, - dictWord{10, 11, 514}, - dictWord{10, 10, 716}, - dictWord{11, 10, 635}, - dictWord{11, 10, 801}, - dictWord{11, 11, 925}, - dictWord{12, 10, 458}, - dictWord{13, 11, 92}, - dictWord{142, 11, 309}, - dictWord{132, 0, 462}, - dictWord{137, 11, 173}, - dictWord{ - 135, - 10, - 1735, - }, - dictWord{8, 0, 525}, - dictWord{5, 10, 598}, - dictWord{7, 10, 791}, - dictWord{8, 10, 108}, - dictWord{137, 10, 123}, - dictWord{5, 0, 73}, - dictWord{6, 0, 23}, - dictWord{134, 0, 338}, - dictWord{132, 0, 676}, - dictWord{132, 10, 683}, - dictWord{7, 0, 725}, - dictWord{8, 0, 498}, - dictWord{139, 0, 268}, - dictWord{12, 0, 21}, - dictWord{151, 0, 7}, - dictWord{135, 0, 773}, - dictWord{4, 10, 155}, - dictWord{135, 10, 1689}, - dictWord{4, 0, 164}, - dictWord{5, 0, 730}, - dictWord{5, 10, 151}, - dictWord{ - 5, - 10, - 741, - }, - dictWord{6, 11, 210}, - dictWord{7, 10, 498}, - dictWord{7, 10, 870}, - dictWord{7, 10, 1542}, - dictWord{12, 10, 213}, - dictWord{14, 10, 36}, - dictWord{ - 14, - 10, - 391, - }, - dictWord{17, 10, 111}, - dictWord{18, 10, 6}, - dictWord{18, 10, 46}, - dictWord{18, 10, 151}, - dictWord{19, 10, 36}, - dictWord{20, 10, 32}, - dictWord{ - 20, - 10, - 56, - }, - dictWord{20, 10, 69}, - dictWord{20, 10, 102}, - dictWord{21, 10, 4}, - dictWord{22, 10, 8}, - dictWord{22, 10, 10}, - dictWord{22, 10, 14}, - dictWord{ - 150, - 10, - 31, - }, - dictWord{4, 10, 624}, - dictWord{135, 10, 1752}, - dictWord{4, 0, 583}, - dictWord{9, 0, 936}, - dictWord{15, 0, 214}, - dictWord{18, 0, 199}, - dictWord{24, 0, 26}, - dictWord{134, 11, 588}, - dictWord{7, 0, 1462}, - dictWord{11, 0, 659}, - dictWord{4, 11, 284}, - dictWord{134, 11, 223}, - dictWord{133, 0, 220}, - dictWord{ - 139, - 0, - 803, - }, - dictWord{132, 0, 544}, - dictWord{4, 10, 492}, - dictWord{133, 10, 451}, - dictWord{16, 0, 98}, - dictWord{148, 0, 119}, - dictWord{4, 11, 218}, - dictWord{ - 7, - 11, - 526, - }, - dictWord{143, 11, 137}, - dictWord{135, 10, 835}, - dictWord{4, 11, 270}, - dictWord{5, 11, 192}, - dictWord{6, 11, 332}, - dictWord{7, 11, 1322}, - dictWord{ - 13, - 11, - 9, - }, - dictWord{13, 10, 70}, - dictWord{14, 11, 104}, - dictWord{142, 11, 311}, - dictWord{132, 10, 539}, - dictWord{140, 11, 661}, - dictWord{5, 0, 176}, - dictWord{ - 6, - 0, - 437, - }, - dictWord{6, 0, 564}, - dictWord{11, 0, 181}, - dictWord{141, 0, 183}, - dictWord{135, 0, 1192}, - dictWord{6, 10, 113}, - dictWord{135, 10, 436}, - dictWord{136, 10, 718}, - dictWord{135, 10, 520}, - dictWord{135, 0, 1878}, - dictWord{140, 11, 196}, - dictWord{7, 11, 379}, - dictWord{8, 11, 481}, - dictWord{ - 137, - 11, - 377, - }, - dictWord{5, 11, 1003}, - dictWord{6, 11, 149}, - dictWord{137, 11, 746}, - dictWord{8, 11, 262}, - dictWord{9, 11, 627}, - dictWord{10, 11, 18}, - dictWord{ - 11, - 11, - 214, - }, - dictWord{11, 11, 404}, - dictWord{11, 11, 457}, - dictWord{11, 11, 780}, - dictWord{11, 11, 849}, - dictWord{11, 11, 913}, - dictWord{13, 11, 330}, - dictWord{13, 11, 401}, - dictWord{142, 11, 200}, - dictWord{149, 0, 26}, - dictWord{136, 11, 304}, - dictWord{132, 11, 142}, - dictWord{135, 0, 944}, - dictWord{ - 4, - 0, - 790, - }, - dictWord{5, 0, 273}, - dictWord{134, 0, 394}, - dictWord{134, 0, 855}, - dictWord{4, 0, 135}, - dictWord{6, 0, 127}, - dictWord{7, 0, 1185}, - dictWord{7, 0, 1511}, - dictWord{8, 0, 613}, - dictWord{11, 0, 5}, - dictWord{12, 0, 336}, - dictWord{12, 0, 495}, - dictWord{12, 0, 586}, - dictWord{12, 0, 660}, - dictWord{12, 0, 668}, - dictWord{ - 14, - 0, - 385, - }, - dictWord{15, 0, 118}, - dictWord{17, 0, 20}, - dictWord{146, 0, 98}, - dictWord{6, 0, 230}, - dictWord{9, 0, 752}, - dictWord{18, 0, 109}, - dictWord{12, 10, 610}, - dictWord{13, 10, 431}, - dictWord{144, 10, 59}, - dictWord{7, 0, 1954}, - dictWord{135, 11, 925}, - dictWord{4, 11, 471}, - dictWord{5, 11, 51}, - dictWord{6, 11, 602}, - dictWord{8, 11, 484}, - dictWord{10, 11, 195}, - dictWord{140, 11, 159}, - dictWord{132, 10, 307}, - dictWord{136, 11, 688}, - dictWord{132, 11, 697}, - dictWord{ - 7, - 11, - 812, - }, - dictWord{7, 11, 1261}, - dictWord{7, 11, 1360}, - dictWord{9, 11, 632}, - dictWord{140, 11, 352}, - dictWord{5, 0, 162}, - dictWord{8, 0, 68}, - dictWord{ - 133, - 10, - 964, - }, - dictWord{4, 0, 654}, - dictWord{136, 11, 212}, - dictWord{4, 0, 156}, - dictWord{7, 0, 998}, - dictWord{7, 0, 1045}, - dictWord{7, 0, 1860}, - dictWord{9, 0, 48}, - dictWord{9, 0, 692}, - dictWord{11, 0, 419}, - dictWord{139, 0, 602}, - dictWord{133, 11, 221}, - dictWord{4, 11, 373}, - dictWord{5, 11, 283}, - dictWord{6, 11, 480}, - dictWord{135, 11, 609}, - dictWord{142, 11, 216}, - dictWord{132, 0, 240}, - dictWord{6, 11, 192}, - dictWord{9, 11, 793}, - dictWord{145, 11, 55}, - dictWord{ - 4, - 10, - 75, - }, - dictWord{5, 10, 180}, - dictWord{6, 10, 500}, - dictWord{7, 10, 58}, - dictWord{7, 10, 710}, - dictWord{138, 10, 645}, - dictWord{4, 11, 132}, - dictWord{5, 11, 69}, - dictWord{5, 10, 649}, - dictWord{135, 11, 1242}, - dictWord{6, 10, 276}, - dictWord{7, 10, 282}, - dictWord{7, 10, 879}, - dictWord{7, 10, 924}, - dictWord{8, 10, 459}, - dictWord{9, 10, 599}, - dictWord{9, 10, 754}, - dictWord{11, 10, 574}, - dictWord{12, 10, 128}, - dictWord{12, 10, 494}, - dictWord{13, 10, 52}, - dictWord{13, 10, 301}, - dictWord{15, 10, 30}, - dictWord{143, 10, 132}, - dictWord{132, 10, 200}, - dictWord{4, 11, 111}, - dictWord{135, 11, 302}, - dictWord{9, 0, 197}, - dictWord{ - 10, - 0, - 300, - }, - dictWord{12, 0, 473}, - dictWord{13, 0, 90}, - dictWord{141, 0, 405}, - dictWord{132, 11, 767}, - dictWord{6, 11, 42}, - dictWord{7, 11, 1416}, - dictWord{ - 7, - 11, - 1590, - }, - dictWord{7, 11, 2005}, - dictWord{8, 11, 131}, - dictWord{8, 11, 466}, - dictWord{9, 11, 672}, - dictWord{13, 11, 252}, - dictWord{148, 11, 103}, - dictWord{ - 8, - 0, - 958, - }, - dictWord{8, 0, 999}, - dictWord{10, 0, 963}, - dictWord{138, 0, 1001}, - dictWord{135, 10, 1621}, - dictWord{135, 0, 858}, - dictWord{4, 0, 606}, - dictWord{ - 137, - 11, - 444, - }, - dictWord{6, 11, 44}, - dictWord{136, 11, 368}, - dictWord{139, 11, 172}, - dictWord{4, 11, 570}, - dictWord{133, 11, 120}, - dictWord{139, 11, 624}, - dictWord{7, 0, 1978}, - dictWord{8, 0, 676}, - dictWord{6, 10, 225}, - dictWord{137, 10, 211}, - dictWord{7, 0, 972}, - dictWord{11, 0, 102}, - dictWord{136, 10, 687}, - dictWord{6, 11, 227}, - dictWord{135, 11, 1589}, - dictWord{8, 10, 58}, - dictWord{9, 10, 724}, - dictWord{11, 10, 809}, - dictWord{13, 10, 113}, - dictWord{ - 145, - 10, - 72, - }, - dictWord{4, 0, 361}, - dictWord{133, 0, 315}, - dictWord{132, 0, 461}, - dictWord{6, 10, 345}, - dictWord{135, 10, 1247}, - dictWord{132, 0, 472}, - dictWord{ - 8, - 10, - 767, - }, - dictWord{8, 10, 803}, - dictWord{9, 10, 301}, - dictWord{137, 10, 903}, - dictWord{135, 11, 1333}, - dictWord{135, 11, 477}, - dictWord{7, 10, 1949}, - dictWord{136, 10, 674}, - dictWord{6, 0, 905}, - dictWord{138, 0, 747}, - dictWord{133, 0, 155}, - dictWord{134, 10, 259}, - dictWord{7, 0, 163}, - dictWord{8, 0, 319}, - dictWord{9, 0, 402}, - dictWord{10, 0, 24}, - dictWord{10, 0, 681}, - dictWord{11, 0, 200}, - dictWord{12, 0, 253}, - dictWord{12, 0, 410}, - dictWord{142, 0, 219}, - dictWord{ - 5, - 0, - 475, - }, - dictWord{7, 0, 1780}, - dictWord{9, 0, 230}, - dictWord{11, 0, 297}, - dictWord{11, 0, 558}, - dictWord{14, 0, 322}, - dictWord{19, 0, 76}, - dictWord{6, 11, 1667}, - dictWord{7, 11, 2036}, - dictWord{138, 11, 600}, - dictWord{136, 10, 254}, - dictWord{6, 0, 848}, - dictWord{135, 0, 1956}, - dictWord{6, 11, 511}, - dictWord{ - 140, - 11, - 132, - }, - dictWord{5, 11, 568}, - dictWord{6, 11, 138}, - dictWord{135, 11, 1293}, - dictWord{6, 0, 631}, - dictWord{137, 0, 838}, - dictWord{149, 0, 36}, - dictWord{ - 4, - 11, - 565, - }, - dictWord{8, 11, 23}, - dictWord{136, 11, 827}, - dictWord{5, 0, 944}, - dictWord{134, 0, 1769}, - dictWord{4, 0, 144}, - dictWord{6, 0, 842}, - dictWord{ - 6, - 0, - 1400, - }, - dictWord{4, 11, 922}, - dictWord{133, 11, 1023}, - dictWord{133, 10, 248}, - dictWord{9, 10, 800}, - dictWord{10, 10, 693}, - dictWord{11, 10, 482}, - dictWord{11, 10, 734}, - dictWord{139, 10, 789}, - dictWord{7, 11, 1002}, - dictWord{139, 11, 145}, - dictWord{4, 10, 116}, - dictWord{5, 10, 95}, - dictWord{5, 10, 445}, - dictWord{7, 10, 1688}, - dictWord{8, 10, 29}, - dictWord{9, 10, 272}, - dictWord{11, 10, 509}, - dictWord{139, 10, 915}, - dictWord{14, 0, 369}, - dictWord{146, 0, 72}, - dictWord{135, 10, 1641}, - dictWord{132, 11, 740}, - dictWord{133, 10, 543}, - dictWord{140, 11, 116}, - dictWord{6, 0, 247}, - dictWord{9, 0, 555}, - dictWord{ - 5, - 10, - 181, - }, - dictWord{136, 10, 41}, - dictWord{133, 10, 657}, - dictWord{136, 0, 996}, - dictWord{138, 10, 709}, - dictWord{7, 0, 189}, - dictWord{8, 10, 202}, - dictWord{ - 138, - 10, - 536, - }, - dictWord{136, 11, 402}, - dictWord{4, 11, 716}, - dictWord{141, 11, 31}, - dictWord{10, 0, 280}, - dictWord{138, 0, 797}, - dictWord{9, 10, 423}, - dictWord{140, 10, 89}, - dictWord{8, 10, 113}, - dictWord{9, 10, 877}, - dictWord{10, 10, 554}, - dictWord{11, 10, 83}, - dictWord{12, 10, 136}, - dictWord{147, 10, 109}, - dictWord{133, 10, 976}, - dictWord{7, 0, 746}, - dictWord{132, 10, 206}, - dictWord{136, 0, 526}, - dictWord{139, 0, 345}, - dictWord{136, 0, 1017}, - dictWord{ - 8, - 11, - 152, - }, - dictWord{9, 11, 53}, - dictWord{9, 11, 268}, - dictWord{9, 11, 901}, - dictWord{10, 11, 518}, - dictWord{10, 11, 829}, - dictWord{11, 11, 188}, - dictWord{ - 13, - 11, - 74, - }, - dictWord{14, 11, 46}, - dictWord{15, 11, 17}, - dictWord{15, 11, 33}, - dictWord{17, 11, 40}, - dictWord{18, 11, 36}, - dictWord{19, 11, 20}, - dictWord{22, 11, 1}, - dictWord{152, 11, 2}, - dictWord{133, 11, 736}, - dictWord{136, 11, 532}, - dictWord{5, 0, 428}, - dictWord{138, 0, 651}, - dictWord{135, 11, 681}, - dictWord{ - 135, - 0, - 1162, - }, - dictWord{7, 0, 327}, - dictWord{13, 0, 230}, - dictWord{17, 0, 113}, - dictWord{8, 10, 226}, - dictWord{10, 10, 537}, - dictWord{11, 10, 570}, - dictWord{ - 11, - 10, - 605, - }, - dictWord{11, 10, 799}, - dictWord{11, 10, 804}, - dictWord{12, 10, 85}, - dictWord{12, 10, 516}, - dictWord{12, 10, 623}, - dictWord{12, 11, 677}, - dictWord{ - 13, - 10, - 361, - }, - dictWord{14, 10, 77}, - dictWord{14, 10, 78}, - dictWord{147, 10, 110}, - dictWord{4, 0, 792}, - dictWord{7, 0, 1717}, - dictWord{10, 0, 546}, - dictWord{ - 132, - 10, - 769, - }, - dictWord{4, 11, 684}, - dictWord{136, 11, 384}, - dictWord{132, 10, 551}, - dictWord{134, 0, 1203}, - dictWord{9, 10, 57}, - dictWord{9, 10, 459}, - dictWord{10, 10, 425}, - dictWord{11, 10, 119}, - dictWord{12, 10, 184}, - dictWord{12, 10, 371}, - dictWord{13, 10, 358}, - dictWord{145, 10, 51}, - dictWord{5, 0, 672}, - dictWord{5, 10, 814}, - dictWord{8, 10, 10}, - dictWord{9, 10, 421}, - dictWord{9, 10, 729}, - dictWord{10, 10, 609}, - dictWord{139, 10, 689}, - dictWord{138, 0, 189}, - dictWord{134, 10, 624}, - dictWord{7, 11, 110}, - dictWord{7, 11, 188}, - dictWord{8, 11, 290}, - dictWord{8, 11, 591}, - dictWord{9, 11, 382}, - dictWord{9, 11, 649}, - dictWord{11, 11, 71}, - dictWord{11, 11, 155}, - dictWord{11, 11, 313}, - dictWord{12, 11, 5}, - dictWord{13, 11, 325}, - dictWord{142, 11, 287}, - dictWord{133, 0, 99}, - dictWord{6, 0, 1053}, - dictWord{135, 0, 298}, - dictWord{7, 11, 360}, - dictWord{7, 11, 425}, - dictWord{9, 11, 66}, - dictWord{9, 11, 278}, - dictWord{138, 11, 644}, - dictWord{4, 0, 397}, - dictWord{136, 0, 555}, - dictWord{137, 10, 269}, - dictWord{132, 10, 528}, - dictWord{4, 11, 900}, - dictWord{133, 11, 861}, - dictWord{ - 6, - 0, - 1157, - }, - dictWord{5, 11, 254}, - dictWord{7, 11, 985}, - dictWord{136, 11, 73}, - dictWord{7, 11, 1959}, - dictWord{136, 11, 683}, - dictWord{12, 0, 398}, - dictWord{ - 20, - 0, - 39, - }, - dictWord{21, 0, 11}, - dictWord{150, 0, 41}, - dictWord{4, 0, 485}, - dictWord{7, 0, 353}, - dictWord{135, 0, 1523}, - dictWord{6, 0, 366}, - dictWord{7, 0, 1384}, - dictWord{135, 0, 1601}, - dictWord{138, 0, 787}, - dictWord{137, 0, 282}, - dictWord{5, 10, 104}, - dictWord{6, 10, 173}, - dictWord{135, 10, 1631}, - dictWord{ - 139, - 11, - 146, - }, - dictWord{4, 0, 157}, - dictWord{133, 0, 471}, - dictWord{134, 0, 941}, - dictWord{132, 11, 725}, - dictWord{7, 0, 1336}, - dictWord{8, 10, 138}, - dictWord{ - 8, - 10, - 342, - }, - dictWord{9, 10, 84}, - dictWord{10, 10, 193}, - dictWord{11, 10, 883}, - dictWord{140, 10, 359}, - dictWord{134, 11, 196}, - dictWord{136, 0, 116}, - dictWord{133, 11, 831}, - dictWord{134, 0, 787}, - dictWord{134, 10, 95}, - dictWord{6, 10, 406}, - dictWord{10, 10, 409}, - dictWord{10, 10, 447}, - dictWord{ - 11, - 10, - 44, - }, - dictWord{140, 10, 100}, - dictWord{5, 0, 160}, - dictWord{7, 0, 363}, - dictWord{7, 0, 589}, - dictWord{10, 0, 170}, - dictWord{141, 0, 55}, - dictWord{134, 0, 1815}, - dictWord{132, 0, 866}, - dictWord{6, 0, 889}, - dictWord{6, 0, 1067}, - dictWord{6, 0, 1183}, - dictWord{4, 11, 321}, - dictWord{134, 11, 569}, - dictWord{5, 11, 848}, - dictWord{134, 11, 66}, - dictWord{4, 11, 36}, - dictWord{6, 10, 1636}, - dictWord{7, 11, 1387}, - dictWord{10, 11, 205}, - dictWord{11, 11, 755}, - dictWord{ - 141, - 11, - 271, - }, - dictWord{132, 0, 689}, - dictWord{9, 0, 820}, - dictWord{4, 10, 282}, - dictWord{7, 10, 1034}, - dictWord{11, 10, 398}, - dictWord{11, 10, 634}, - dictWord{ - 12, - 10, - 1, - }, - dictWord{12, 10, 79}, - dictWord{12, 10, 544}, - dictWord{14, 10, 237}, - dictWord{17, 10, 10}, - dictWord{146, 10, 20}, - dictWord{4, 0, 108}, - dictWord{7, 0, 804}, - dictWord{139, 0, 498}, - dictWord{132, 11, 887}, - dictWord{6, 0, 1119}, - dictWord{135, 11, 620}, - dictWord{6, 11, 165}, - dictWord{138, 11, 388}, - dictWord{ - 5, - 0, - 244, - }, - dictWord{5, 10, 499}, - dictWord{6, 10, 476}, - dictWord{7, 10, 600}, - dictWord{7, 10, 888}, - dictWord{135, 10, 1096}, - dictWord{140, 0, 609}, - dictWord{ - 135, - 0, - 1005, - }, - dictWord{4, 0, 412}, - dictWord{133, 0, 581}, - dictWord{4, 11, 719}, - dictWord{135, 11, 155}, - dictWord{7, 10, 296}, - dictWord{7, 10, 596}, - dictWord{ - 8, - 10, - 560, - }, - dictWord{8, 10, 586}, - dictWord{9, 10, 612}, - dictWord{11, 10, 304}, - dictWord{12, 10, 46}, - dictWord{13, 10, 89}, - dictWord{14, 10, 112}, - dictWord{ - 145, - 10, - 122, - }, - dictWord{4, 0, 895}, - dictWord{133, 0, 772}, - dictWord{142, 11, 307}, - dictWord{135, 0, 1898}, - dictWord{4, 0, 926}, - dictWord{133, 0, 983}, - dictWord{4, 11, 353}, - dictWord{6, 11, 146}, - dictWord{6, 11, 1789}, - dictWord{7, 11, 288}, - dictWord{7, 11, 990}, - dictWord{7, 11, 1348}, - dictWord{9, 11, 665}, - dictWord{ - 9, - 11, - 898, - }, - dictWord{11, 11, 893}, - dictWord{142, 11, 212}, - dictWord{132, 0, 538}, - dictWord{133, 11, 532}, - dictWord{6, 0, 294}, - dictWord{7, 0, 1267}, - dictWord{8, 0, 624}, - dictWord{141, 0, 496}, - dictWord{7, 0, 1325}, - dictWord{4, 11, 45}, - dictWord{135, 11, 1257}, - dictWord{138, 0, 301}, - dictWord{9, 0, 298}, - dictWord{12, 0, 291}, - dictWord{13, 0, 276}, - dictWord{14, 0, 6}, - dictWord{17, 0, 18}, - dictWord{21, 0, 32}, - dictWord{7, 10, 1599}, - dictWord{7, 10, 1723}, - dictWord{ - 8, - 10, - 79, - }, - dictWord{8, 10, 106}, - dictWord{8, 10, 190}, - dictWord{8, 10, 302}, - dictWord{8, 10, 383}, - dictWord{8, 10, 713}, - dictWord{9, 10, 119}, - dictWord{9, 10, 233}, - dictWord{9, 10, 419}, - dictWord{9, 10, 471}, - dictWord{10, 10, 181}, - dictWord{10, 10, 406}, - dictWord{11, 10, 57}, - dictWord{11, 10, 85}, - dictWord{11, 10, 120}, - dictWord{11, 10, 177}, - dictWord{11, 10, 296}, - dictWord{11, 10, 382}, - dictWord{11, 10, 454}, - dictWord{11, 10, 758}, - dictWord{11, 10, 999}, - dictWord{ - 12, - 10, - 27, - }, - dictWord{12, 10, 131}, - dictWord{12, 10, 245}, - dictWord{12, 10, 312}, - dictWord{12, 10, 446}, - dictWord{12, 10, 454}, - dictWord{13, 10, 98}, - dictWord{ - 13, - 10, - 426, - }, - dictWord{13, 10, 508}, - dictWord{14, 10, 163}, - dictWord{14, 10, 272}, - dictWord{14, 10, 277}, - dictWord{14, 10, 370}, - dictWord{15, 10, 95}, - dictWord{15, 10, 138}, - dictWord{15, 10, 167}, - dictWord{17, 10, 38}, - dictWord{148, 10, 96}, - dictWord{132, 0, 757}, - dictWord{134, 0, 1263}, - dictWord{4, 0, 820}, - dictWord{134, 10, 1759}, - dictWord{133, 0, 722}, - dictWord{136, 11, 816}, - dictWord{138, 10, 372}, - dictWord{145, 10, 16}, - dictWord{134, 0, 1039}, - dictWord{ - 4, - 0, - 991, - }, - dictWord{134, 0, 2028}, - dictWord{133, 10, 258}, - dictWord{7, 0, 1875}, - dictWord{139, 0, 124}, - dictWord{6, 11, 559}, - dictWord{6, 11, 1691}, - dictWord{135, 11, 586}, - dictWord{5, 0, 324}, - dictWord{7, 0, 881}, - dictWord{8, 10, 134}, - dictWord{9, 10, 788}, - dictWord{140, 10, 438}, - dictWord{7, 11, 1823}, - dictWord{139, 11, 693}, - dictWord{6, 0, 1348}, - dictWord{134, 0, 1545}, - dictWord{134, 0, 911}, - dictWord{132, 0, 954}, - dictWord{8, 0, 329}, - dictWord{8, 0, 414}, - dictWord{7, 10, 1948}, - dictWord{135, 10, 2004}, - dictWord{5, 0, 517}, - dictWord{6, 10, 439}, - dictWord{7, 10, 780}, - dictWord{135, 10, 1040}, - dictWord{ - 132, - 0, - 816, - }, - dictWord{5, 10, 1}, - dictWord{6, 10, 81}, - dictWord{138, 10, 520}, - dictWord{9, 0, 713}, - dictWord{10, 0, 222}, - dictWord{5, 10, 482}, - dictWord{8, 10, 98}, - dictWord{10, 10, 700}, - dictWord{10, 10, 822}, - dictWord{11, 10, 302}, - dictWord{11, 10, 778}, - dictWord{12, 10, 50}, - dictWord{12, 10, 127}, - dictWord{12, 10, 396}, - dictWord{13, 10, 62}, - dictWord{13, 10, 328}, - dictWord{14, 10, 122}, - dictWord{147, 10, 72}, - dictWord{137, 0, 33}, - dictWord{5, 10, 2}, - dictWord{7, 10, 1494}, - dictWord{136, 10, 589}, - dictWord{6, 10, 512}, - dictWord{7, 10, 797}, - dictWord{8, 10, 253}, - dictWord{9, 10, 77}, - dictWord{10, 10, 1}, - dictWord{10, 11, 108}, - dictWord{10, 10, 129}, - dictWord{10, 10, 225}, - dictWord{11, 11, 116}, - dictWord{11, 10, 118}, - dictWord{11, 10, 226}, - dictWord{11, 10, 251}, - dictWord{ - 11, - 10, - 430, - }, - dictWord{11, 10, 701}, - dictWord{11, 10, 974}, - dictWord{11, 10, 982}, - dictWord{12, 10, 64}, - dictWord{12, 10, 260}, - dictWord{12, 10, 488}, - dictWord{ - 140, - 10, - 690, - }, - dictWord{134, 11, 456}, - dictWord{133, 11, 925}, - dictWord{5, 0, 150}, - dictWord{7, 0, 106}, - dictWord{7, 0, 774}, - dictWord{8, 0, 603}, - dictWord{ - 9, - 0, - 593, - }, - dictWord{9, 0, 634}, - dictWord{10, 0, 44}, - dictWord{10, 0, 173}, - dictWord{11, 0, 462}, - dictWord{11, 0, 515}, - dictWord{13, 0, 216}, - dictWord{13, 0, 288}, - dictWord{142, 0, 400}, - dictWord{137, 10, 347}, - dictWord{5, 0, 748}, - dictWord{134, 0, 553}, - dictWord{12, 0, 108}, - dictWord{141, 0, 291}, - dictWord{7, 0, 420}, - dictWord{4, 10, 12}, - dictWord{7, 10, 522}, - dictWord{7, 10, 809}, - dictWord{8, 10, 797}, - dictWord{141, 10, 88}, - dictWord{6, 11, 193}, - dictWord{7, 11, 240}, - dictWord{ - 7, - 11, - 1682, - }, - dictWord{10, 11, 51}, - dictWord{10, 11, 640}, - dictWord{11, 11, 410}, - dictWord{13, 11, 82}, - dictWord{14, 11, 247}, - dictWord{14, 11, 331}, - dictWord{142, 11, 377}, - dictWord{133, 10, 528}, - dictWord{135, 0, 1777}, - dictWord{4, 0, 493}, - dictWord{144, 0, 55}, - dictWord{136, 11, 633}, - dictWord{ - 139, - 0, - 81, - }, - dictWord{6, 0, 980}, - dictWord{136, 0, 321}, - dictWord{148, 10, 109}, - dictWord{5, 10, 266}, - dictWord{9, 10, 290}, - dictWord{9, 10, 364}, - dictWord{ - 10, - 10, - 293, - }, - dictWord{11, 10, 606}, - dictWord{142, 10, 45}, - dictWord{6, 0, 568}, - dictWord{7, 0, 112}, - dictWord{7, 0, 1804}, - dictWord{8, 0, 362}, - dictWord{8, 0, 410}, - dictWord{8, 0, 830}, - dictWord{9, 0, 514}, - dictWord{11, 0, 649}, - dictWord{142, 0, 157}, - dictWord{4, 0, 74}, - dictWord{6, 0, 510}, - dictWord{6, 10, 594}, - dictWord{ - 9, - 10, - 121, - }, - dictWord{10, 10, 49}, - dictWord{10, 10, 412}, - dictWord{139, 10, 834}, - dictWord{134, 0, 838}, - dictWord{136, 10, 748}, - dictWord{132, 10, 466}, - dictWord{132, 0, 625}, - dictWord{135, 11, 1443}, - dictWord{4, 11, 237}, - dictWord{135, 11, 514}, - dictWord{9, 10, 378}, - dictWord{141, 10, 162}, - dictWord{6, 0, 16}, - dictWord{6, 0, 158}, - dictWord{7, 0, 43}, - dictWord{7, 0, 129}, - dictWord{7, 0, 181}, - dictWord{8, 0, 276}, - dictWord{8, 0, 377}, - dictWord{10, 0, 523}, - dictWord{ - 11, - 0, - 816, - }, - dictWord{12, 0, 455}, - dictWord{13, 0, 303}, - dictWord{142, 0, 135}, - dictWord{135, 0, 281}, - dictWord{4, 0, 1}, - dictWord{7, 0, 1143}, - dictWord{7, 0, 1463}, - dictWord{8, 0, 61}, - dictWord{9, 0, 207}, - dictWord{9, 0, 390}, - dictWord{9, 0, 467}, - dictWord{139, 0, 836}, - dictWord{6, 11, 392}, - dictWord{7, 11, 65}, - dictWord{ - 135, - 11, - 2019, - }, - dictWord{132, 10, 667}, - dictWord{4, 0, 723}, - dictWord{5, 0, 895}, - dictWord{7, 0, 1031}, - dictWord{8, 0, 199}, - dictWord{8, 0, 340}, - dictWord{9, 0, 153}, - dictWord{9, 0, 215}, - dictWord{10, 0, 21}, - dictWord{10, 0, 59}, - dictWord{10, 0, 80}, - dictWord{10, 0, 224}, - dictWord{10, 0, 838}, - dictWord{11, 0, 229}, - dictWord{ - 11, - 0, - 652, - }, - dictWord{12, 0, 192}, - dictWord{13, 0, 146}, - dictWord{142, 0, 91}, - dictWord{132, 0, 295}, - dictWord{137, 0, 51}, - dictWord{9, 11, 222}, - dictWord{ - 10, - 11, - 43, - }, - dictWord{139, 11, 900}, - dictWord{5, 0, 309}, - dictWord{140, 0, 211}, - dictWord{5, 0, 125}, - dictWord{8, 0, 77}, - dictWord{138, 0, 15}, - dictWord{136, 11, 604}, - dictWord{138, 0, 789}, - dictWord{5, 0, 173}, - dictWord{4, 10, 39}, - dictWord{7, 10, 1843}, - dictWord{8, 10, 407}, - dictWord{11, 10, 144}, - dictWord{140, 10, 523}, - dictWord{138, 11, 265}, - dictWord{133, 0, 439}, - dictWord{132, 10, 510}, - dictWord{7, 0, 648}, - dictWord{7, 0, 874}, - dictWord{11, 0, 164}, - dictWord{12, 0, 76}, - dictWord{18, 0, 9}, - dictWord{7, 10, 1980}, - dictWord{10, 10, 487}, - dictWord{138, 10, 809}, - dictWord{12, 0, 111}, - dictWord{14, 0, 294}, - dictWord{19, 0, 45}, - dictWord{13, 10, 260}, - dictWord{146, 10, 63}, - dictWord{133, 11, 549}, - dictWord{134, 10, 570}, - dictWord{4, 0, 8}, - dictWord{7, 0, 1152}, - dictWord{7, 0, 1153}, - dictWord{7, 0, 1715}, - dictWord{9, 0, 374}, - dictWord{10, 0, 478}, - dictWord{139, 0, 648}, - dictWord{135, 0, 1099}, - dictWord{5, 0, 575}, - dictWord{6, 0, 354}, - dictWord{ - 135, - 0, - 701, - }, - dictWord{7, 11, 36}, - dictWord{8, 11, 201}, - dictWord{136, 11, 605}, - dictWord{4, 10, 787}, - dictWord{136, 11, 156}, - dictWord{6, 0, 518}, - dictWord{ - 149, - 11, - 13, - }, - dictWord{140, 11, 224}, - dictWord{134, 0, 702}, - dictWord{132, 10, 516}, - dictWord{5, 11, 724}, - dictWord{10, 11, 305}, - dictWord{11, 11, 151}, - dictWord{12, 11, 33}, - dictWord{12, 11, 121}, - dictWord{12, 11, 381}, - dictWord{17, 11, 3}, - dictWord{17, 11, 27}, - dictWord{17, 11, 78}, - dictWord{18, 11, 18}, - dictWord{19, 11, 54}, - dictWord{149, 11, 5}, - dictWord{8, 0, 87}, - dictWord{4, 11, 523}, - dictWord{5, 11, 638}, - dictWord{11, 10, 887}, - dictWord{14, 10, 365}, - dictWord{ - 142, - 10, - 375, - }, - dictWord{138, 0, 438}, - dictWord{136, 10, 821}, - dictWord{135, 11, 1908}, - dictWord{6, 11, 242}, - dictWord{7, 11, 227}, - dictWord{7, 11, 1581}, - dictWord{8, 11, 104}, - dictWord{9, 11, 113}, - dictWord{9, 11, 220}, - dictWord{9, 11, 427}, - dictWord{10, 11, 74}, - dictWord{10, 11, 239}, - dictWord{11, 11, 579}, - dictWord{11, 11, 1023}, - dictWord{13, 11, 4}, - dictWord{13, 11, 204}, - dictWord{13, 11, 316}, - dictWord{18, 11, 95}, - dictWord{148, 11, 86}, - dictWord{4, 0, 69}, - dictWord{5, 0, 122}, - dictWord{5, 0, 849}, - dictWord{6, 0, 1633}, - dictWord{9, 0, 656}, - dictWord{138, 0, 464}, - dictWord{7, 0, 1802}, - dictWord{4, 10, 10}, - dictWord{ - 139, - 10, - 786, - }, - dictWord{135, 11, 861}, - dictWord{139, 0, 499}, - dictWord{7, 0, 476}, - dictWord{7, 0, 1592}, - dictWord{138, 0, 87}, - dictWord{133, 10, 684}, - dictWord{ - 4, - 0, - 840, - }, - dictWord{134, 10, 27}, - dictWord{142, 0, 283}, - dictWord{6, 0, 1620}, - dictWord{7, 11, 1328}, - dictWord{136, 11, 494}, - dictWord{5, 0, 859}, - dictWord{ - 7, - 0, - 1160, - }, - dictWord{8, 0, 107}, - dictWord{9, 0, 291}, - dictWord{9, 0, 439}, - dictWord{10, 0, 663}, - dictWord{11, 0, 609}, - dictWord{140, 0, 197}, - dictWord{ - 7, - 11, - 1306, - }, - dictWord{8, 11, 505}, - dictWord{9, 11, 482}, - dictWord{10, 11, 126}, - dictWord{11, 11, 225}, - dictWord{12, 11, 347}, - dictWord{12, 11, 449}, - dictWord{ - 13, - 11, - 19, - }, - dictWord{142, 11, 218}, - dictWord{5, 11, 268}, - dictWord{10, 11, 764}, - dictWord{12, 11, 120}, - dictWord{13, 11, 39}, - dictWord{145, 11, 127}, - dictWord{145, 10, 56}, - dictWord{7, 11, 1672}, - dictWord{10, 11, 472}, - dictWord{11, 11, 189}, - dictWord{143, 11, 51}, - dictWord{6, 10, 342}, - dictWord{6, 10, 496}, - dictWord{8, 10, 275}, - dictWord{137, 10, 206}, - dictWord{133, 0, 600}, - dictWord{4, 0, 117}, - dictWord{6, 0, 372}, - dictWord{7, 0, 1905}, - dictWord{142, 0, 323}, - dictWord{4, 10, 909}, - dictWord{5, 10, 940}, - dictWord{135, 11, 1471}, - dictWord{132, 10, 891}, - dictWord{4, 0, 722}, - dictWord{139, 0, 471}, - dictWord{4, 11, 384}, - dictWord{135, 11, 1022}, - dictWord{132, 10, 687}, - dictWord{9, 0, 5}, - dictWord{12, 0, 216}, - dictWord{12, 0, 294}, - dictWord{12, 0, 298}, - dictWord{12, 0, 400}, - dictWord{12, 0, 518}, - dictWord{13, 0, 229}, - dictWord{143, 0, 139}, - dictWord{135, 11, 1703}, - dictWord{7, 11, 1602}, - dictWord{10, 11, 698}, - dictWord{ - 12, - 11, - 212, - }, - dictWord{141, 11, 307}, - dictWord{6, 10, 41}, - dictWord{141, 10, 160}, - dictWord{135, 11, 1077}, - dictWord{9, 11, 159}, - dictWord{11, 11, 28}, - dictWord{140, 11, 603}, - dictWord{4, 0, 514}, - dictWord{7, 0, 1304}, - dictWord{138, 0, 477}, - dictWord{134, 0, 1774}, - dictWord{9, 0, 88}, - dictWord{139, 0, 270}, - dictWord{5, 0, 12}, - dictWord{7, 0, 375}, - dictWord{9, 0, 438}, - dictWord{134, 10, 1718}, - dictWord{132, 11, 515}, - dictWord{136, 10, 778}, - dictWord{8, 11, 632}, - dictWord{8, 11, 697}, - dictWord{137, 11, 854}, - dictWord{6, 0, 362}, - dictWord{6, 0, 997}, - dictWord{146, 0, 51}, - dictWord{7, 0, 816}, - dictWord{7, 0, 1241}, - dictWord{ - 9, - 0, - 283, - }, - dictWord{9, 0, 520}, - dictWord{10, 0, 213}, - dictWord{10, 0, 307}, - dictWord{10, 0, 463}, - dictWord{10, 0, 671}, - dictWord{10, 0, 746}, - dictWord{11, 0, 401}, - dictWord{11, 0, 794}, - dictWord{12, 0, 517}, - dictWord{18, 0, 107}, - dictWord{147, 0, 115}, - dictWord{133, 10, 115}, - dictWord{150, 11, 28}, - dictWord{4, 11, 136}, - dictWord{133, 11, 551}, - dictWord{142, 10, 314}, - dictWord{132, 0, 258}, - dictWord{6, 0, 22}, - dictWord{7, 0, 903}, - dictWord{7, 0, 1963}, - dictWord{8, 0, 639}, - dictWord{138, 0, 577}, - dictWord{5, 0, 681}, - dictWord{8, 0, 782}, - dictWord{13, 0, 130}, - dictWord{17, 0, 84}, - dictWord{5, 10, 193}, - dictWord{140, 10, 178}, - dictWord{ - 9, - 11, - 17, - }, - dictWord{138, 11, 291}, - dictWord{7, 11, 1287}, - dictWord{9, 11, 44}, - dictWord{10, 11, 552}, - dictWord{10, 11, 642}, - dictWord{11, 11, 839}, - dictWord{12, 11, 274}, - dictWord{12, 11, 275}, - dictWord{12, 11, 372}, - dictWord{13, 11, 91}, - dictWord{142, 11, 125}, - dictWord{135, 10, 174}, - dictWord{4, 0, 664}, - dictWord{5, 0, 804}, - dictWord{139, 0, 1013}, - dictWord{134, 0, 942}, - dictWord{6, 0, 1349}, - dictWord{6, 0, 1353}, - dictWord{6, 0, 1450}, - dictWord{7, 11, 1518}, - dictWord{139, 11, 694}, - dictWord{11, 0, 356}, - dictWord{4, 10, 122}, - dictWord{5, 10, 796}, - dictWord{5, 10, 952}, - dictWord{6, 10, 1660}, - dictWord{ - 6, - 10, - 1671, - }, - dictWord{8, 10, 567}, - dictWord{9, 10, 687}, - dictWord{9, 10, 742}, - dictWord{10, 10, 686}, - dictWord{11, 10, 682}, - dictWord{140, 10, 281}, - dictWord{ - 5, - 0, - 32, - }, - dictWord{6, 11, 147}, - dictWord{7, 11, 886}, - dictWord{9, 11, 753}, - dictWord{138, 11, 268}, - dictWord{5, 10, 179}, - dictWord{7, 10, 1095}, - dictWord{ - 135, - 10, - 1213, - }, - dictWord{4, 10, 66}, - dictWord{7, 10, 722}, - dictWord{135, 10, 904}, - dictWord{135, 10, 352}, - dictWord{9, 11, 245}, - dictWord{138, 11, 137}, - dictWord{4, 0, 289}, - dictWord{7, 0, 629}, - dictWord{7, 0, 1698}, - dictWord{7, 0, 1711}, - dictWord{12, 0, 215}, - dictWord{133, 11, 414}, - dictWord{6, 0, 1975}, - dictWord{135, 11, 1762}, - dictWord{6, 0, 450}, - dictWord{136, 0, 109}, - dictWord{141, 10, 35}, - dictWord{134, 11, 599}, - dictWord{136, 0, 705}, - dictWord{ - 133, - 0, - 664, - }, - dictWord{134, 11, 1749}, - dictWord{11, 11, 402}, - dictWord{12, 11, 109}, - dictWord{12, 11, 431}, - dictWord{13, 11, 179}, - dictWord{13, 11, 206}, - dictWord{14, 11, 175}, - dictWord{14, 11, 217}, - dictWord{16, 11, 3}, - dictWord{148, 11, 53}, - dictWord{135, 0, 1238}, - dictWord{134, 11, 1627}, - dictWord{ - 132, - 11, - 488, - }, - dictWord{13, 0, 318}, - dictWord{10, 10, 592}, - dictWord{10, 10, 753}, - dictWord{12, 10, 317}, - dictWord{12, 10, 355}, - dictWord{12, 10, 465}, - dictWord{ - 12, - 10, - 469, - }, - dictWord{12, 10, 560}, - dictWord{140, 10, 578}, - dictWord{133, 10, 564}, - dictWord{132, 11, 83}, - dictWord{140, 11, 676}, - dictWord{6, 0, 1872}, - dictWord{6, 0, 1906}, - dictWord{6, 0, 1907}, - dictWord{9, 0, 934}, - dictWord{9, 0, 956}, - dictWord{9, 0, 960}, - dictWord{9, 0, 996}, - dictWord{12, 0, 794}, - dictWord{ - 12, - 0, - 876, - }, - dictWord{12, 0, 880}, - dictWord{12, 0, 918}, - dictWord{15, 0, 230}, - dictWord{18, 0, 234}, - dictWord{18, 0, 238}, - dictWord{21, 0, 38}, - dictWord{149, 0, 62}, - dictWord{134, 10, 556}, - dictWord{134, 11, 278}, - dictWord{137, 0, 103}, - dictWord{7, 10, 544}, - dictWord{8, 10, 719}, - dictWord{138, 10, 61}, - dictWord{ - 4, - 10, - 5, - }, - dictWord{5, 10, 498}, - dictWord{8, 10, 637}, - dictWord{137, 10, 521}, - dictWord{7, 0, 777}, - dictWord{12, 0, 229}, - dictWord{12, 0, 239}, - dictWord{15, 0, 12}, - dictWord{12, 11, 229}, - dictWord{12, 11, 239}, - dictWord{143, 11, 12}, - dictWord{6, 0, 26}, - dictWord{7, 11, 388}, - dictWord{7, 11, 644}, - dictWord{139, 11, 781}, - dictWord{7, 11, 229}, - dictWord{8, 11, 59}, - dictWord{9, 11, 190}, - dictWord{9, 11, 257}, - dictWord{10, 11, 378}, - dictWord{140, 11, 191}, - dictWord{133, 10, 927}, - dictWord{135, 10, 1441}, - dictWord{4, 10, 893}, - dictWord{5, 10, 780}, - dictWord{133, 10, 893}, - dictWord{4, 0, 414}, - dictWord{5, 0, 467}, - dictWord{9, 0, 654}, - dictWord{10, 0, 451}, - dictWord{12, 0, 59}, - dictWord{141, 0, 375}, - dictWord{142, 0, 173}, - dictWord{135, 0, 17}, - dictWord{7, 0, 1350}, - dictWord{133, 10, 238}, - dictWord{135, 0, 955}, - dictWord{4, 0, 960}, - dictWord{10, 0, 887}, - dictWord{12, 0, 753}, - dictWord{18, 0, 161}, - dictWord{18, 0, 162}, - dictWord{152, 0, 19}, - dictWord{136, 11, 344}, - dictWord{6, 10, 1729}, - dictWord{137, 11, 288}, - dictWord{132, 11, 660}, - dictWord{4, 0, 217}, - dictWord{5, 0, 710}, - dictWord{7, 0, 760}, - dictWord{7, 0, 1926}, - dictWord{9, 0, 428}, - dictWord{9, 0, 708}, - dictWord{10, 0, 254}, - dictWord{10, 0, 296}, - dictWord{10, 0, 720}, - dictWord{11, 0, 109}, - dictWord{ - 11, - 0, - 255, - }, - dictWord{12, 0, 165}, - dictWord{12, 0, 315}, - dictWord{13, 0, 107}, - dictWord{13, 0, 203}, - dictWord{14, 0, 54}, - dictWord{14, 0, 99}, - dictWord{14, 0, 114}, - dictWord{14, 0, 388}, - dictWord{16, 0, 85}, - dictWord{17, 0, 9}, - dictWord{17, 0, 33}, - dictWord{20, 0, 25}, - dictWord{20, 0, 28}, - dictWord{20, 0, 29}, - dictWord{21, 0, 9}, - dictWord{21, 0, 10}, - dictWord{21, 0, 34}, - dictWord{22, 0, 17}, - dictWord{4, 10, 60}, - dictWord{7, 10, 1800}, - dictWord{8, 10, 314}, - dictWord{9, 10, 700}, - dictWord{ - 139, - 10, - 487, - }, - dictWord{7, 11, 1035}, - dictWord{138, 11, 737}, - dictWord{7, 11, 690}, - dictWord{9, 11, 217}, - dictWord{9, 11, 587}, - dictWord{140, 11, 521}, - dictWord{6, 0, 919}, - dictWord{7, 11, 706}, - dictWord{7, 11, 1058}, - dictWord{138, 11, 538}, - dictWord{7, 10, 1853}, - dictWord{138, 10, 437}, - dictWord{ - 136, - 10, - 419, - }, - dictWord{6, 0, 280}, - dictWord{10, 0, 502}, - dictWord{11, 0, 344}, - dictWord{140, 0, 38}, - dictWord{5, 0, 45}, - dictWord{7, 0, 1161}, - dictWord{11, 0, 448}, - dictWord{11, 0, 880}, - dictWord{13, 0, 139}, - dictWord{13, 0, 407}, - dictWord{15, 0, 16}, - dictWord{17, 0, 95}, - dictWord{18, 0, 66}, - dictWord{18, 0, 88}, - dictWord{ - 18, - 0, - 123, - }, - dictWord{149, 0, 7}, - dictWord{11, 11, 92}, - dictWord{11, 11, 196}, - dictWord{11, 11, 409}, - dictWord{11, 11, 450}, - dictWord{11, 11, 666}, - dictWord{ - 11, - 11, - 777, - }, - dictWord{12, 11, 262}, - dictWord{13, 11, 385}, - dictWord{13, 11, 393}, - dictWord{15, 11, 115}, - dictWord{16, 11, 45}, - dictWord{145, 11, 82}, - dictWord{136, 0, 777}, - dictWord{134, 11, 1744}, - dictWord{4, 0, 410}, - dictWord{7, 0, 521}, - dictWord{133, 10, 828}, - dictWord{134, 0, 673}, - dictWord{7, 0, 1110}, - dictWord{7, 0, 1778}, - dictWord{7, 10, 176}, - dictWord{135, 10, 178}, - dictWord{5, 10, 806}, - dictWord{7, 11, 268}, - dictWord{7, 10, 1976}, - dictWord{ - 136, - 11, - 569, - }, - dictWord{4, 11, 733}, - dictWord{9, 11, 194}, - dictWord{10, 11, 92}, - dictWord{11, 11, 198}, - dictWord{12, 11, 84}, - dictWord{12, 11, 87}, - dictWord{ - 13, - 11, - 128, - }, - dictWord{144, 11, 74}, - dictWord{5, 0, 341}, - dictWord{7, 0, 1129}, - dictWord{11, 0, 414}, - dictWord{4, 10, 51}, - dictWord{6, 10, 4}, - dictWord{7, 10, 591}, - dictWord{7, 10, 849}, - dictWord{7, 10, 951}, - dictWord{7, 10, 1613}, - dictWord{7, 10, 1760}, - dictWord{7, 10, 1988}, - dictWord{9, 10, 434}, - dictWord{10, 10, 754}, - dictWord{11, 10, 25}, - dictWord{139, 10, 37}, - dictWord{133, 10, 902}, - dictWord{135, 10, 928}, - dictWord{135, 0, 787}, - dictWord{132, 0, 436}, - dictWord{ - 134, - 10, - 270, - }, - dictWord{7, 0, 1587}, - dictWord{135, 0, 1707}, - dictWord{6, 0, 377}, - dictWord{7, 0, 1025}, - dictWord{9, 0, 613}, - dictWord{145, 0, 104}, - dictWord{ - 7, - 11, - 982, - }, - dictWord{7, 11, 1361}, - dictWord{10, 11, 32}, - dictWord{143, 11, 56}, - dictWord{139, 0, 96}, - dictWord{132, 0, 451}, - dictWord{132, 10, 416}, - dictWord{ - 142, - 10, - 372, - }, - dictWord{5, 10, 152}, - dictWord{5, 10, 197}, - dictWord{7, 11, 306}, - dictWord{7, 10, 340}, - dictWord{7, 10, 867}, - dictWord{10, 10, 548}, - dictWord{ - 10, - 10, - 581, - }, - dictWord{11, 10, 6}, - dictWord{12, 10, 3}, - dictWord{12, 10, 19}, - dictWord{14, 10, 110}, - dictWord{142, 10, 289}, - dictWord{134, 0, 680}, - dictWord{ - 134, - 11, - 609, - }, - dictWord{7, 0, 483}, - dictWord{7, 10, 190}, - dictWord{8, 10, 28}, - dictWord{8, 10, 141}, - dictWord{8, 10, 444}, - dictWord{8, 10, 811}, - dictWord{ - 9, - 10, - 468, - }, - dictWord{11, 10, 334}, - dictWord{12, 10, 24}, - dictWord{12, 10, 386}, - dictWord{140, 10, 576}, - dictWord{10, 0, 916}, - dictWord{133, 10, 757}, - dictWord{ - 5, - 10, - 721, - }, - dictWord{135, 10, 1553}, - dictWord{133, 11, 178}, - dictWord{134, 0, 937}, - dictWord{132, 10, 898}, - dictWord{133, 0, 739}, - dictWord{ - 147, - 0, - 82, - }, - dictWord{135, 0, 663}, - dictWord{146, 0, 128}, - dictWord{5, 10, 277}, - dictWord{141, 10, 247}, - dictWord{134, 0, 1087}, - dictWord{132, 10, 435}, - dictWord{ - 6, - 11, - 381, - }, - dictWord{7, 11, 645}, - dictWord{7, 11, 694}, - dictWord{136, 11, 546}, - dictWord{7, 0, 503}, - dictWord{135, 0, 1885}, - dictWord{6, 0, 1965}, - dictWord{ - 8, - 0, - 925, - }, - dictWord{138, 0, 955}, - dictWord{4, 0, 113}, - dictWord{5, 0, 163}, - dictWord{5, 0, 735}, - dictWord{7, 0, 1009}, - dictWord{9, 0, 9}, - dictWord{9, 0, 771}, - dictWord{12, 0, 90}, - dictWord{13, 0, 138}, - dictWord{13, 0, 410}, - dictWord{143, 0, 128}, - dictWord{4, 0, 324}, - dictWord{138, 0, 104}, - dictWord{7, 0, 460}, - dictWord{ - 5, - 10, - 265, - }, - dictWord{134, 10, 212}, - dictWord{133, 11, 105}, - dictWord{7, 11, 261}, - dictWord{7, 11, 1107}, - dictWord{7, 11, 1115}, - dictWord{7, 11, 1354}, - dictWord{7, 11, 1588}, - dictWord{7, 11, 1705}, - dictWord{7, 11, 1902}, - dictWord{9, 11, 465}, - dictWord{10, 11, 248}, - dictWord{10, 11, 349}, - dictWord{10, 11, 647}, - dictWord{11, 11, 527}, - dictWord{11, 11, 660}, - dictWord{11, 11, 669}, - dictWord{12, 11, 529}, - dictWord{141, 11, 305}, - dictWord{5, 11, 438}, - dictWord{ - 9, - 11, - 694, - }, - dictWord{12, 11, 627}, - dictWord{141, 11, 210}, - dictWord{152, 11, 11}, - dictWord{4, 0, 935}, - dictWord{133, 0, 823}, - dictWord{132, 10, 702}, - dictWord{ - 5, - 0, - 269, - }, - dictWord{7, 0, 434}, - dictWord{7, 0, 891}, - dictWord{8, 0, 339}, - dictWord{9, 0, 702}, - dictWord{11, 0, 594}, - dictWord{11, 0, 718}, - dictWord{17, 0, 100}, - dictWord{5, 10, 808}, - dictWord{135, 10, 2045}, - dictWord{7, 0, 1014}, - dictWord{9, 0, 485}, - dictWord{141, 0, 264}, - dictWord{134, 0, 1713}, - dictWord{7, 0, 1810}, - dictWord{11, 0, 866}, - dictWord{12, 0, 103}, - dictWord{13, 0, 495}, - dictWord{140, 11, 233}, - dictWord{4, 0, 423}, - dictWord{10, 0, 949}, - dictWord{138, 0, 1013}, - dictWord{135, 0, 900}, - dictWord{8, 11, 25}, - dictWord{138, 11, 826}, - dictWord{5, 10, 166}, - dictWord{8, 10, 739}, - dictWord{140, 10, 511}, - dictWord{ - 134, - 0, - 2018, - }, - dictWord{7, 11, 1270}, - dictWord{139, 11, 612}, - dictWord{4, 10, 119}, - dictWord{5, 10, 170}, - dictWord{5, 10, 447}, - dictWord{7, 10, 1708}, - dictWord{ - 7, - 10, - 1889, - }, - dictWord{9, 10, 357}, - dictWord{9, 10, 719}, - dictWord{12, 10, 486}, - dictWord{140, 10, 596}, - dictWord{12, 0, 574}, - dictWord{140, 11, 574}, - dictWord{132, 11, 308}, - dictWord{6, 0, 964}, - dictWord{6, 0, 1206}, - dictWord{134, 0, 1302}, - dictWord{4, 10, 450}, - dictWord{135, 10, 1158}, - dictWord{ - 135, - 11, - 150, - }, - dictWord{136, 11, 649}, - dictWord{14, 0, 213}, - dictWord{148, 0, 38}, - dictWord{9, 11, 45}, - dictWord{9, 11, 311}, - dictWord{141, 11, 42}, - dictWord{ - 134, - 11, - 521, - }, - dictWord{7, 10, 1375}, - dictWord{7, 10, 1466}, - dictWord{138, 10, 331}, - dictWord{132, 10, 754}, - dictWord{5, 11, 339}, - dictWord{7, 11, 1442}, - dictWord{14, 11, 3}, - dictWord{15, 11, 41}, - dictWord{147, 11, 66}, - dictWord{136, 11, 378}, - dictWord{134, 0, 1022}, - dictWord{5, 10, 850}, - dictWord{136, 10, 799}, - dictWord{142, 0, 143}, - dictWord{135, 0, 2029}, - dictWord{134, 11, 1628}, - dictWord{8, 0, 523}, - dictWord{150, 0, 34}, - dictWord{5, 0, 625}, - dictWord{ - 135, - 0, - 1617, - }, - dictWord{7, 0, 275}, - dictWord{7, 10, 238}, - dictWord{7, 10, 2033}, - dictWord{8, 10, 120}, - dictWord{8, 10, 188}, - dictWord{8, 10, 659}, - dictWord{ - 9, - 10, - 598, - }, - dictWord{10, 10, 466}, - dictWord{12, 10, 342}, - dictWord{12, 10, 588}, - dictWord{13, 10, 503}, - dictWord{14, 10, 246}, - dictWord{143, 10, 92}, - dictWord{ - 7, - 0, - 37, - }, - dictWord{8, 0, 425}, - dictWord{8, 0, 693}, - dictWord{9, 0, 720}, - dictWord{10, 0, 380}, - dictWord{10, 0, 638}, - dictWord{11, 0, 273}, - dictWord{11, 0, 473}, - dictWord{12, 0, 61}, - dictWord{143, 0, 43}, - dictWord{135, 11, 829}, - dictWord{135, 0, 1943}, - dictWord{132, 0, 765}, - dictWord{5, 11, 486}, - dictWord{ - 135, - 11, - 1349, - }, - dictWord{7, 11, 1635}, - dictWord{8, 11, 17}, - dictWord{10, 11, 217}, - dictWord{138, 11, 295}, - dictWord{4, 10, 201}, - dictWord{7, 10, 1744}, - dictWord{ - 8, - 10, - 602, - }, - dictWord{11, 10, 247}, - dictWord{11, 10, 826}, - dictWord{145, 10, 65}, - dictWord{138, 11, 558}, - dictWord{11, 0, 551}, - dictWord{142, 0, 159}, - dictWord{8, 10, 164}, - dictWord{146, 10, 62}, - dictWord{139, 11, 176}, - dictWord{132, 0, 168}, - dictWord{136, 0, 1010}, - dictWord{134, 0, 1994}, - dictWord{ - 135, - 0, - 91, - }, - dictWord{138, 0, 532}, - dictWord{135, 10, 1243}, - dictWord{135, 0, 1884}, - dictWord{132, 10, 907}, - dictWord{5, 10, 100}, - dictWord{10, 10, 329}, - dictWord{12, 10, 416}, - dictWord{149, 10, 29}, - dictWord{134, 11, 447}, - dictWord{132, 10, 176}, - dictWord{5, 10, 636}, - dictWord{5, 10, 998}, - dictWord{7, 10, 9}, - dictWord{7, 10, 1508}, - dictWord{8, 10, 26}, - dictWord{9, 10, 317}, - dictWord{9, 10, 358}, - dictWord{10, 10, 210}, - dictWord{10, 10, 292}, - dictWord{10, 10, 533}, - dictWord{11, 10, 555}, - dictWord{12, 10, 526}, - dictWord{12, 10, 607}, - dictWord{13, 10, 263}, - dictWord{13, 10, 459}, - dictWord{142, 10, 271}, - dictWord{ - 4, - 11, - 609, - }, - dictWord{135, 11, 756}, - dictWord{6, 0, 15}, - dictWord{7, 0, 70}, - dictWord{10, 0, 240}, - dictWord{147, 0, 93}, - dictWord{4, 11, 930}, - dictWord{133, 11, 947}, - dictWord{134, 0, 1227}, - dictWord{134, 0, 1534}, - dictWord{133, 11, 939}, - dictWord{133, 11, 962}, - dictWord{5, 11, 651}, - dictWord{8, 11, 170}, - dictWord{ - 9, - 11, - 61, - }, - dictWord{9, 11, 63}, - dictWord{10, 11, 23}, - dictWord{10, 11, 37}, - dictWord{10, 11, 834}, - dictWord{11, 11, 4}, - dictWord{11, 11, 187}, - dictWord{ - 11, - 11, - 281, - }, - dictWord{11, 11, 503}, - dictWord{11, 11, 677}, - dictWord{12, 11, 96}, - dictWord{12, 11, 130}, - dictWord{12, 11, 244}, - dictWord{14, 11, 5}, - dictWord{ - 14, - 11, - 40, - }, - dictWord{14, 11, 162}, - dictWord{14, 11, 202}, - dictWord{146, 11, 133}, - dictWord{4, 11, 406}, - dictWord{5, 11, 579}, - dictWord{12, 11, 492}, - dictWord{ - 150, - 11, - 15, - }, - dictWord{139, 0, 392}, - dictWord{6, 10, 610}, - dictWord{10, 10, 127}, - dictWord{141, 10, 27}, - dictWord{7, 0, 655}, - dictWord{7, 0, 1844}, - dictWord{ - 136, - 10, - 119, - }, - dictWord{4, 0, 145}, - dictWord{6, 0, 176}, - dictWord{7, 0, 395}, - dictWord{137, 0, 562}, - dictWord{132, 0, 501}, - dictWord{140, 11, 145}, - dictWord{ - 136, - 0, - 1019, - }, - dictWord{134, 0, 509}, - dictWord{139, 0, 267}, - dictWord{6, 11, 17}, - dictWord{7, 11, 16}, - dictWord{7, 11, 1001}, - dictWord{7, 11, 1982}, - dictWord{ - 9, - 11, - 886, - }, - dictWord{10, 11, 489}, - dictWord{10, 11, 800}, - dictWord{11, 11, 782}, - dictWord{12, 11, 320}, - dictWord{13, 11, 467}, - dictWord{14, 11, 145}, - dictWord{14, 11, 387}, - dictWord{143, 11, 119}, - dictWord{145, 11, 17}, - dictWord{6, 0, 1099}, - dictWord{133, 11, 458}, - dictWord{7, 11, 1983}, - dictWord{8, 11, 0}, - dictWord{8, 11, 171}, - dictWord{9, 11, 120}, - dictWord{9, 11, 732}, - dictWord{10, 11, 473}, - dictWord{11, 11, 656}, - dictWord{11, 11, 998}, - dictWord{18, 11, 0}, - dictWord{18, 11, 2}, - dictWord{147, 11, 21}, - dictWord{12, 11, 427}, - dictWord{146, 11, 38}, - dictWord{10, 0, 948}, - dictWord{138, 0, 968}, - dictWord{7, 10, 126}, - dictWord{136, 10, 84}, - dictWord{136, 10, 790}, - dictWord{4, 0, 114}, - dictWord{9, 0, 492}, - dictWord{13, 0, 462}, - dictWord{142, 0, 215}, - dictWord{6, 10, 64}, - dictWord{12, 10, 377}, - dictWord{141, 10, 309}, - dictWord{4, 0, 77}, - dictWord{5, 0, 361}, - dictWord{6, 0, 139}, - dictWord{6, 0, 401}, - dictWord{6, 0, 404}, - dictWord{ - 7, - 0, - 413, - }, - dictWord{7, 0, 715}, - dictWord{7, 0, 1716}, - dictWord{11, 0, 279}, - dictWord{12, 0, 179}, - dictWord{12, 0, 258}, - dictWord{13, 0, 244}, - dictWord{142, 0, 358}, - dictWord{134, 0, 1717}, - dictWord{7, 0, 772}, - dictWord{7, 0, 1061}, - dictWord{7, 0, 1647}, - dictWord{8, 0, 82}, - dictWord{11, 0, 250}, - dictWord{11, 0, 607}, - dictWord{12, 0, 311}, - dictWord{12, 0, 420}, - dictWord{13, 0, 184}, - dictWord{13, 0, 367}, - dictWord{7, 10, 1104}, - dictWord{11, 10, 269}, - dictWord{11, 10, 539}, - dictWord{11, 10, 627}, - dictWord{11, 10, 706}, - dictWord{11, 10, 975}, - dictWord{12, 10, 248}, - dictWord{12, 10, 434}, - dictWord{12, 10, 600}, - dictWord{ - 12, - 10, - 622, - }, - dictWord{13, 10, 297}, - dictWord{13, 10, 485}, - dictWord{14, 10, 69}, - dictWord{14, 10, 409}, - dictWord{143, 10, 108}, - dictWord{135, 0, 724}, - dictWord{ - 4, - 11, - 512, - }, - dictWord{4, 11, 519}, - dictWord{133, 11, 342}, - dictWord{134, 0, 1133}, - dictWord{145, 11, 29}, - dictWord{11, 10, 977}, - dictWord{141, 10, 507}, - dictWord{6, 0, 841}, - dictWord{6, 0, 1042}, - dictWord{6, 0, 1194}, - dictWord{10, 0, 993}, - dictWord{140, 0, 1021}, - dictWord{6, 11, 31}, - dictWord{7, 11, 491}, - dictWord{7, 11, 530}, - dictWord{8, 11, 592}, - dictWord{9, 10, 34}, - dictWord{11, 11, 53}, - dictWord{11, 10, 484}, - dictWord{11, 11, 779}, - dictWord{12, 11, 167}, - dictWord{12, 11, 411}, - dictWord{14, 11, 14}, - dictWord{14, 11, 136}, - dictWord{15, 11, 72}, - dictWord{16, 11, 17}, - dictWord{144, 11, 72}, - dictWord{4, 0, 1021}, - dictWord{6, 0, 2037}, - dictWord{133, 11, 907}, - dictWord{7, 0, 373}, - dictWord{8, 0, 335}, - dictWord{8, 0, 596}, - dictWord{9, 0, 488}, - dictWord{6, 10, 1700}, - dictWord{ - 7, - 10, - 293, - }, - dictWord{7, 10, 382}, - dictWord{7, 10, 1026}, - dictWord{7, 10, 1087}, - dictWord{7, 10, 2027}, - dictWord{8, 10, 252}, - dictWord{8, 10, 727}, - dictWord{ - 8, - 10, - 729, - }, - dictWord{9, 10, 30}, - dictWord{9, 10, 199}, - dictWord{9, 10, 231}, - dictWord{9, 10, 251}, - dictWord{9, 10, 334}, - dictWord{9, 10, 361}, - dictWord{9, 10, 712}, - dictWord{10, 10, 55}, - dictWord{10, 10, 60}, - dictWord{10, 10, 232}, - dictWord{10, 10, 332}, - dictWord{10, 10, 384}, - dictWord{10, 10, 396}, - dictWord{ - 10, - 10, - 504, - }, - dictWord{10, 10, 542}, - dictWord{10, 10, 652}, - dictWord{11, 10, 20}, - dictWord{11, 10, 48}, - dictWord{11, 10, 207}, - dictWord{11, 10, 291}, - dictWord{ - 11, - 10, - 298, - }, - dictWord{11, 10, 342}, - dictWord{11, 10, 365}, - dictWord{11, 10, 394}, - dictWord{11, 10, 620}, - dictWord{11, 10, 705}, - dictWord{11, 10, 1017}, - dictWord{12, 10, 123}, - dictWord{12, 10, 340}, - dictWord{12, 10, 406}, - dictWord{12, 10, 643}, - dictWord{13, 10, 61}, - dictWord{13, 10, 269}, - dictWord{ - 13, - 10, - 311, - }, - dictWord{13, 10, 319}, - dictWord{13, 10, 486}, - dictWord{14, 10, 234}, - dictWord{15, 10, 62}, - dictWord{15, 10, 85}, - dictWord{16, 10, 71}, - dictWord{ - 18, - 10, - 119, - }, - dictWord{148, 10, 105}, - dictWord{150, 0, 37}, - dictWord{4, 11, 208}, - dictWord{5, 11, 106}, - dictWord{6, 11, 531}, - dictWord{8, 11, 408}, - dictWord{ - 9, - 11, - 188, - }, - dictWord{138, 11, 572}, - dictWord{132, 0, 564}, - dictWord{6, 0, 513}, - dictWord{135, 0, 1052}, - dictWord{132, 0, 825}, - dictWord{9, 0, 899}, - dictWord{ - 140, - 11, - 441, - }, - dictWord{134, 0, 778}, - dictWord{133, 11, 379}, - dictWord{7, 0, 1417}, - dictWord{12, 0, 382}, - dictWord{17, 0, 48}, - dictWord{152, 0, 12}, - dictWord{ - 132, - 11, - 241, - }, - dictWord{7, 0, 1116}, - dictWord{6, 10, 379}, - dictWord{7, 10, 270}, - dictWord{8, 10, 176}, - dictWord{8, 10, 183}, - dictWord{9, 10, 432}, - dictWord{ - 9, - 10, - 661, - }, - dictWord{12, 10, 247}, - dictWord{12, 10, 617}, - dictWord{146, 10, 125}, - dictWord{5, 10, 792}, - dictWord{133, 10, 900}, - dictWord{6, 0, 545}, - dictWord{ - 7, - 0, - 565, - }, - dictWord{7, 0, 1669}, - dictWord{10, 0, 114}, - dictWord{11, 0, 642}, - dictWord{140, 0, 618}, - dictWord{133, 0, 5}, - dictWord{138, 11, 7}, - dictWord{ - 132, - 11, - 259, - }, - dictWord{135, 0, 192}, - dictWord{134, 0, 701}, - dictWord{136, 0, 763}, - dictWord{135, 10, 1979}, - dictWord{4, 10, 901}, - dictWord{133, 10, 776}, - dictWord{10, 0, 755}, - dictWord{147, 0, 29}, - dictWord{133, 0, 759}, - dictWord{4, 11, 173}, - dictWord{5, 11, 312}, - dictWord{5, 11, 512}, - dictWord{135, 11, 1285}, - dictWord{7, 11, 1603}, - dictWord{7, 11, 1691}, - dictWord{9, 11, 464}, - dictWord{11, 11, 195}, - dictWord{12, 11, 279}, - dictWord{12, 11, 448}, - dictWord{ - 14, - 11, - 11, - }, - dictWord{147, 11, 102}, - dictWord{7, 0, 370}, - dictWord{7, 0, 1007}, - dictWord{7, 0, 1177}, - dictWord{135, 0, 1565}, - dictWord{135, 0, 1237}, - dictWord{ - 4, - 0, - 87, - }, - dictWord{5, 0, 250}, - dictWord{141, 0, 298}, - dictWord{4, 11, 452}, - dictWord{5, 11, 583}, - dictWord{5, 11, 817}, - dictWord{6, 11, 433}, - dictWord{7, 11, 593}, - dictWord{7, 11, 720}, - dictWord{7, 11, 1378}, - dictWord{8, 11, 161}, - dictWord{9, 11, 284}, - dictWord{10, 11, 313}, - dictWord{139, 11, 886}, - dictWord{4, 11, 547}, - dictWord{135, 11, 1409}, - dictWord{136, 11, 722}, - dictWord{4, 10, 37}, - dictWord{5, 10, 334}, - dictWord{135, 10, 1253}, - dictWord{132, 10, 508}, - dictWord{ - 12, - 0, - 107, - }, - dictWord{146, 0, 31}, - dictWord{8, 11, 420}, - dictWord{139, 11, 193}, - dictWord{135, 0, 814}, - dictWord{135, 11, 409}, - dictWord{140, 0, 991}, - dictWord{4, 0, 57}, - dictWord{7, 0, 1195}, - dictWord{7, 0, 1438}, - dictWord{7, 0, 1548}, - dictWord{7, 0, 1835}, - dictWord{7, 0, 1904}, - dictWord{9, 0, 757}, - dictWord{ - 10, - 0, - 604, - }, - dictWord{139, 0, 519}, - dictWord{132, 0, 540}, - dictWord{138, 11, 308}, - dictWord{132, 10, 533}, - dictWord{136, 0, 608}, - dictWord{144, 11, 65}, - dictWord{4, 0, 1014}, - dictWord{134, 0, 2029}, - dictWord{4, 0, 209}, - dictWord{7, 0, 902}, - dictWord{5, 11, 1002}, - dictWord{136, 11, 745}, - dictWord{134, 0, 2030}, - dictWord{6, 0, 303}, - dictWord{7, 0, 335}, - dictWord{7, 0, 1437}, - dictWord{7, 0, 1668}, - dictWord{8, 0, 553}, - dictWord{8, 0, 652}, - dictWord{8, 0, 656}, - dictWord{ - 9, - 0, - 558, - }, - dictWord{11, 0, 743}, - dictWord{149, 0, 18}, - dictWord{5, 11, 575}, - dictWord{6, 11, 354}, - dictWord{135, 11, 701}, - dictWord{4, 11, 239}, - dictWord{ - 6, - 11, - 477, - }, - dictWord{7, 11, 1607}, - dictWord{11, 11, 68}, - dictWord{139, 11, 617}, - dictWord{132, 0, 559}, - dictWord{8, 0, 527}, - dictWord{18, 0, 60}, - dictWord{ - 147, - 0, - 24, - }, - dictWord{133, 10, 920}, - dictWord{138, 0, 511}, - dictWord{133, 0, 1017}, - dictWord{133, 0, 675}, - dictWord{138, 10, 391}, - dictWord{11, 0, 156}, - dictWord{135, 10, 1952}, - dictWord{138, 11, 369}, - dictWord{132, 11, 367}, - dictWord{133, 0, 709}, - dictWord{6, 0, 698}, - dictWord{134, 0, 887}, - dictWord{ - 142, - 10, - 126, - }, - dictWord{134, 0, 1745}, - dictWord{132, 10, 483}, - dictWord{13, 11, 299}, - dictWord{142, 11, 75}, - dictWord{133, 0, 714}, - dictWord{7, 0, 8}, - dictWord{ - 136, - 0, - 206, - }, - dictWord{138, 10, 480}, - dictWord{4, 11, 694}, - dictWord{9, 10, 495}, - dictWord{146, 10, 104}, - dictWord{7, 11, 1248}, - dictWord{11, 11, 621}, - dictWord{139, 11, 702}, - dictWord{140, 11, 687}, - dictWord{132, 0, 776}, - dictWord{139, 10, 1009}, - dictWord{135, 0, 1272}, - dictWord{134, 0, 1059}, - dictWord{ - 8, - 10, - 653, - }, - dictWord{13, 10, 93}, - dictWord{147, 10, 14}, - dictWord{135, 11, 213}, - dictWord{136, 0, 406}, - dictWord{133, 10, 172}, - dictWord{132, 0, 947}, - dictWord{8, 0, 175}, - dictWord{10, 0, 168}, - dictWord{138, 0, 573}, - dictWord{132, 0, 870}, - dictWord{6, 0, 1567}, - dictWord{151, 11, 28}, - dictWord{ - 134, - 11, - 472, - }, - dictWord{5, 10, 260}, - dictWord{136, 11, 132}, - dictWord{4, 11, 751}, - dictWord{11, 11, 390}, - dictWord{140, 11, 32}, - dictWord{4, 11, 409}, - dictWord{ - 133, - 11, - 78, - }, - dictWord{12, 0, 554}, - dictWord{6, 11, 473}, - dictWord{145, 11, 105}, - dictWord{133, 0, 784}, - dictWord{8, 0, 908}, - dictWord{136, 11, 306}, - dictWord{139, 0, 882}, - dictWord{6, 0, 358}, - dictWord{7, 0, 1393}, - dictWord{8, 0, 396}, - dictWord{10, 0, 263}, - dictWord{14, 0, 154}, - dictWord{16, 0, 48}, - dictWord{ - 17, - 0, - 8, - }, - dictWord{7, 11, 1759}, - dictWord{8, 11, 396}, - dictWord{10, 11, 263}, - dictWord{14, 11, 154}, - dictWord{16, 11, 48}, - dictWord{145, 11, 8}, - dictWord{ - 13, - 11, - 163, - }, - dictWord{13, 11, 180}, - dictWord{18, 11, 78}, - dictWord{148, 11, 35}, - dictWord{14, 0, 32}, - dictWord{18, 0, 85}, - dictWord{20, 0, 2}, - dictWord{152, 0, 16}, - dictWord{7, 0, 228}, - dictWord{10, 0, 770}, - dictWord{8, 10, 167}, - dictWord{8, 10, 375}, - dictWord{9, 10, 82}, - dictWord{9, 10, 561}, - dictWord{138, 10, 620}, - dictWord{132, 0, 845}, - dictWord{9, 0, 14}, - dictWord{9, 0, 441}, - dictWord{10, 0, 306}, - dictWord{139, 0, 9}, - dictWord{11, 0, 966}, - dictWord{12, 0, 287}, - dictWord{ - 13, - 0, - 342, - }, - dictWord{13, 0, 402}, - dictWord{15, 0, 110}, - dictWord{15, 0, 163}, - dictWord{8, 10, 194}, - dictWord{136, 10, 756}, - dictWord{134, 0, 1578}, - dictWord{ - 4, - 0, - 967, - }, - dictWord{6, 0, 1820}, - dictWord{6, 0, 1847}, - dictWord{140, 0, 716}, - dictWord{136, 0, 594}, - dictWord{7, 0, 1428}, - dictWord{7, 0, 1640}, - dictWord{ - 7, - 0, - 1867, - }, - dictWord{9, 0, 169}, - dictWord{9, 0, 182}, - dictWord{9, 0, 367}, - dictWord{9, 0, 478}, - dictWord{9, 0, 506}, - dictWord{9, 0, 551}, - dictWord{9, 0, 557}, - dictWord{ - 9, - 0, - 648, - }, - dictWord{9, 0, 697}, - dictWord{9, 0, 705}, - dictWord{9, 0, 725}, - dictWord{9, 0, 787}, - dictWord{9, 0, 794}, - dictWord{10, 0, 198}, - dictWord{10, 0, 214}, - dictWord{10, 0, 267}, - dictWord{10, 0, 275}, - dictWord{10, 0, 456}, - dictWord{10, 0, 551}, - dictWord{10, 0, 561}, - dictWord{10, 0, 613}, - dictWord{10, 0, 627}, - dictWord{ - 10, - 0, - 668, - }, - dictWord{10, 0, 675}, - dictWord{10, 0, 691}, - dictWord{10, 0, 695}, - dictWord{10, 0, 707}, - dictWord{10, 0, 715}, - dictWord{11, 0, 183}, - dictWord{ - 11, - 0, - 201, - }, - dictWord{11, 0, 244}, - dictWord{11, 0, 262}, - dictWord{11, 0, 352}, - dictWord{11, 0, 439}, - dictWord{11, 0, 493}, - dictWord{11, 0, 572}, - dictWord{11, 0, 591}, - dictWord{11, 0, 608}, - dictWord{11, 0, 611}, - dictWord{11, 0, 646}, - dictWord{11, 0, 674}, - dictWord{11, 0, 711}, - dictWord{11, 0, 751}, - dictWord{11, 0, 761}, - dictWord{11, 0, 776}, - dictWord{11, 0, 785}, - dictWord{11, 0, 850}, - dictWord{11, 0, 853}, - dictWord{11, 0, 862}, - dictWord{11, 0, 865}, - dictWord{11, 0, 868}, - dictWord{ - 11, - 0, - 875, - }, - dictWord{11, 0, 898}, - dictWord{11, 0, 902}, - dictWord{11, 0, 903}, - dictWord{11, 0, 910}, - dictWord{11, 0, 932}, - dictWord{11, 0, 942}, - dictWord{ - 11, - 0, - 957, - }, - dictWord{11, 0, 967}, - dictWord{11, 0, 972}, - dictWord{12, 0, 148}, - dictWord{12, 0, 195}, - dictWord{12, 0, 220}, - dictWord{12, 0, 237}, - dictWord{12, 0, 318}, - dictWord{12, 0, 339}, - dictWord{12, 0, 393}, - dictWord{12, 0, 445}, - dictWord{12, 0, 450}, - dictWord{12, 0, 474}, - dictWord{12, 0, 505}, - dictWord{12, 0, 509}, - dictWord{12, 0, 533}, - dictWord{12, 0, 591}, - dictWord{12, 0, 594}, - dictWord{12, 0, 597}, - dictWord{12, 0, 621}, - dictWord{12, 0, 633}, - dictWord{12, 0, 642}, - dictWord{ - 13, - 0, - 59, - }, - dictWord{13, 0, 60}, - dictWord{13, 0, 145}, - dictWord{13, 0, 239}, - dictWord{13, 0, 250}, - dictWord{13, 0, 329}, - dictWord{13, 0, 344}, - dictWord{13, 0, 365}, - dictWord{13, 0, 372}, - dictWord{13, 0, 387}, - dictWord{13, 0, 403}, - dictWord{13, 0, 414}, - dictWord{13, 0, 456}, - dictWord{13, 0, 470}, - dictWord{13, 0, 478}, - dictWord{13, 0, 483}, - dictWord{13, 0, 489}, - dictWord{14, 0, 55}, - dictWord{14, 0, 57}, - dictWord{14, 0, 81}, - dictWord{14, 0, 90}, - dictWord{14, 0, 148}, - dictWord{ - 14, - 0, - 239, - }, - dictWord{14, 0, 266}, - dictWord{14, 0, 321}, - dictWord{14, 0, 326}, - dictWord{14, 0, 327}, - dictWord{14, 0, 330}, - dictWord{14, 0, 347}, - dictWord{14, 0, 355}, - dictWord{14, 0, 401}, - dictWord{14, 0, 404}, - dictWord{14, 0, 411}, - dictWord{14, 0, 414}, - dictWord{14, 0, 416}, - dictWord{14, 0, 420}, - dictWord{15, 0, 61}, - dictWord{15, 0, 74}, - dictWord{15, 0, 87}, - dictWord{15, 0, 88}, - dictWord{15, 0, 94}, - dictWord{15, 0, 96}, - dictWord{15, 0, 116}, - dictWord{15, 0, 149}, - dictWord{15, 0, 154}, - dictWord{16, 0, 50}, - dictWord{16, 0, 63}, - dictWord{16, 0, 73}, - dictWord{17, 0, 2}, - dictWord{17, 0, 66}, - dictWord{17, 0, 92}, - dictWord{17, 0, 103}, - dictWord{ - 17, - 0, - 112, - }, - dictWord{17, 0, 120}, - dictWord{18, 0, 50}, - dictWord{18, 0, 54}, - dictWord{18, 0, 82}, - dictWord{18, 0, 86}, - dictWord{18, 0, 90}, - dictWord{18, 0, 111}, - dictWord{ - 18, - 0, - 115, - }, - dictWord{18, 0, 156}, - dictWord{19, 0, 40}, - dictWord{19, 0, 79}, - dictWord{20, 0, 78}, - dictWord{21, 0, 22}, - dictWord{135, 11, 883}, - dictWord{5, 0, 161}, - dictWord{135, 0, 839}, - dictWord{4, 0, 782}, - dictWord{13, 11, 293}, - dictWord{142, 11, 56}, - dictWord{133, 11, 617}, - dictWord{139, 11, 50}, - dictWord{ - 135, - 10, - 22, - }, - dictWord{145, 0, 64}, - dictWord{5, 10, 639}, - dictWord{7, 10, 1249}, - dictWord{139, 10, 896}, - dictWord{138, 0, 998}, - dictWord{135, 11, 2042}, - dictWord{ - 4, - 11, - 546, - }, - dictWord{142, 11, 233}, - dictWord{6, 0, 1043}, - dictWord{134, 0, 1574}, - dictWord{134, 0, 1496}, - dictWord{4, 10, 102}, - dictWord{7, 10, 815}, - dictWord{7, 10, 1699}, - dictWord{139, 10, 964}, - dictWord{12, 0, 781}, - dictWord{142, 0, 461}, - dictWord{4, 11, 313}, - dictWord{133, 11, 577}, - dictWord{ - 6, - 0, - 639, - }, - dictWord{6, 0, 1114}, - dictWord{137, 0, 817}, - dictWord{8, 11, 184}, - dictWord{141, 11, 433}, - dictWord{7, 0, 1814}, - dictWord{135, 11, 935}, - dictWord{ - 10, - 0, - 997, - }, - dictWord{140, 0, 958}, - dictWord{4, 0, 812}, - dictWord{137, 11, 625}, - dictWord{132, 10, 899}, - dictWord{136, 10, 795}, - dictWord{5, 11, 886}, - dictWord{6, 11, 46}, - dictWord{6, 11, 1790}, - dictWord{7, 11, 14}, - dictWord{7, 11, 732}, - dictWord{7, 11, 1654}, - dictWord{8, 11, 95}, - dictWord{8, 11, 327}, - dictWord{ - 8, - 11, - 616, - }, - dictWord{10, 11, 598}, - dictWord{10, 11, 769}, - dictWord{11, 11, 134}, - dictWord{11, 11, 747}, - dictWord{12, 11, 378}, - dictWord{142, 11, 97}, - dictWord{136, 0, 139}, - dictWord{6, 10, 52}, - dictWord{9, 10, 104}, - dictWord{9, 10, 559}, - dictWord{12, 10, 308}, - dictWord{147, 10, 87}, - dictWord{133, 11, 1021}, - dictWord{132, 10, 604}, - dictWord{132, 10, 301}, - dictWord{136, 10, 779}, - dictWord{7, 0, 643}, - dictWord{136, 0, 236}, - dictWord{132, 11, 153}, - dictWord{ - 134, - 0, - 1172, - }, - dictWord{147, 10, 32}, - dictWord{133, 11, 798}, - dictWord{6, 0, 1338}, - dictWord{132, 11, 587}, - dictWord{6, 11, 598}, - dictWord{7, 11, 42}, - dictWord{ - 8, - 11, - 695, - }, - dictWord{10, 11, 212}, - dictWord{11, 11, 158}, - dictWord{14, 11, 196}, - dictWord{145, 11, 85}, - dictWord{135, 10, 508}, - dictWord{5, 11, 957}, - dictWord{5, 11, 1008}, - dictWord{135, 11, 249}, - dictWord{4, 11, 129}, - dictWord{135, 11, 465}, - dictWord{5, 0, 54}, - dictWord{7, 11, 470}, - dictWord{7, 11, 1057}, - dictWord{7, 11, 1201}, - dictWord{9, 11, 755}, - dictWord{11, 11, 906}, - dictWord{140, 11, 527}, - dictWord{7, 11, 908}, - dictWord{146, 11, 7}, - dictWord{ - 5, - 11, - 148, - }, - dictWord{136, 11, 450}, - dictWord{144, 11, 1}, - dictWord{4, 0, 256}, - dictWord{135, 0, 1488}, - dictWord{9, 0, 351}, - dictWord{6, 10, 310}, - dictWord{ - 7, - 10, - 1849, - }, - dictWord{8, 10, 72}, - dictWord{8, 10, 272}, - dictWord{8, 10, 431}, - dictWord{9, 10, 12}, - dictWord{10, 10, 563}, - dictWord{10, 10, 630}, - dictWord{ - 10, - 10, - 796, - }, - dictWord{10, 10, 810}, - dictWord{11, 10, 367}, - dictWord{11, 10, 599}, - dictWord{11, 10, 686}, - dictWord{140, 10, 672}, - dictWord{6, 0, 1885}, - dictWord{ - 6, - 0, - 1898, - }, - dictWord{6, 0, 1899}, - dictWord{140, 0, 955}, - dictWord{4, 0, 714}, - dictWord{133, 0, 469}, - dictWord{6, 0, 1270}, - dictWord{134, 0, 1456}, - dictWord{132, 0, 744}, - dictWord{6, 0, 313}, - dictWord{7, 10, 537}, - dictWord{8, 10, 64}, - dictWord{9, 10, 127}, - dictWord{10, 10, 496}, - dictWord{12, 10, 510}, - dictWord{141, 10, 384}, - dictWord{4, 11, 217}, - dictWord{4, 10, 244}, - dictWord{5, 11, 710}, - dictWord{7, 10, 233}, - dictWord{7, 11, 1926}, - dictWord{9, 11, 428}, - dictWord{9, 11, 708}, - dictWord{10, 11, 254}, - dictWord{10, 11, 296}, - dictWord{10, 11, 720}, - dictWord{11, 11, 109}, - dictWord{11, 11, 255}, - dictWord{12, 11, 165}, - dictWord{12, 11, 315}, - dictWord{13, 11, 107}, - dictWord{13, 11, 203}, - dictWord{14, 11, 54}, - dictWord{14, 11, 99}, - dictWord{14, 11, 114}, - dictWord{ - 14, - 11, - 388, - }, - dictWord{16, 11, 85}, - dictWord{17, 11, 9}, - dictWord{17, 11, 33}, - dictWord{20, 11, 25}, - dictWord{20, 11, 28}, - dictWord{20, 11, 29}, - dictWord{21, 11, 9}, - dictWord{21, 11, 10}, - dictWord{21, 11, 34}, - dictWord{150, 11, 17}, - dictWord{138, 0, 402}, - dictWord{7, 0, 969}, - dictWord{146, 0, 55}, - dictWord{8, 0, 50}, - dictWord{ - 137, - 0, - 624, - }, - dictWord{134, 0, 1355}, - dictWord{132, 0, 572}, - dictWord{134, 10, 1650}, - dictWord{10, 10, 702}, - dictWord{139, 10, 245}, - dictWord{ - 10, - 0, - 847, - }, - dictWord{142, 0, 445}, - dictWord{6, 0, 43}, - dictWord{7, 0, 38}, - dictWord{8, 0, 248}, - dictWord{138, 0, 513}, - dictWord{133, 0, 369}, - dictWord{137, 10, 338}, - dictWord{133, 0, 766}, - dictWord{133, 0, 363}, - dictWord{133, 10, 896}, - dictWord{8, 11, 392}, - dictWord{11, 11, 54}, - dictWord{13, 11, 173}, - dictWord{ - 13, - 11, - 294, - }, - dictWord{148, 11, 7}, - dictWord{134, 0, 678}, - dictWord{7, 11, 1230}, - dictWord{136, 11, 531}, - dictWord{6, 0, 258}, - dictWord{140, 0, 409}, - dictWord{ - 5, - 0, - 249, - }, - dictWord{148, 0, 82}, - dictWord{7, 10, 1117}, - dictWord{136, 10, 539}, - dictWord{5, 0, 393}, - dictWord{6, 0, 378}, - dictWord{7, 0, 1981}, - dictWord{9, 0, 32}, - dictWord{9, 0, 591}, - dictWord{10, 0, 685}, - dictWord{10, 0, 741}, - dictWord{142, 0, 382}, - dictWord{133, 0, 788}, - dictWord{134, 0, 1281}, - dictWord{ - 134, - 0, - 1295, - }, - dictWord{7, 0, 1968}, - dictWord{141, 0, 509}, - dictWord{4, 0, 61}, - dictWord{5, 0, 58}, - dictWord{5, 0, 171}, - dictWord{5, 0, 683}, - dictWord{6, 0, 291}, - dictWord{ - 6, - 0, - 566, - }, - dictWord{7, 0, 1650}, - dictWord{11, 0, 523}, - dictWord{12, 0, 273}, - dictWord{12, 0, 303}, - dictWord{15, 0, 39}, - dictWord{143, 0, 111}, - dictWord{ - 6, - 0, - 706, - }, - dictWord{134, 0, 1283}, - dictWord{134, 0, 589}, - dictWord{135, 11, 1433}, - dictWord{133, 11, 435}, - dictWord{7, 0, 1059}, - dictWord{13, 0, 54}, - dictWord{ - 5, - 10, - 4, - }, - dictWord{5, 10, 810}, - dictWord{6, 10, 13}, - dictWord{6, 10, 538}, - dictWord{6, 10, 1690}, - dictWord{6, 10, 1726}, - dictWord{7, 10, 1819}, - dictWord{ - 8, - 10, - 148, - }, - dictWord{8, 10, 696}, - dictWord{8, 10, 791}, - dictWord{12, 10, 125}, - dictWord{143, 10, 9}, - dictWord{135, 10, 1268}, - dictWord{5, 11, 85}, - dictWord{ - 6, - 11, - 419, - }, - dictWord{7, 11, 134}, - dictWord{7, 11, 305}, - dictWord{7, 11, 361}, - dictWord{7, 11, 1337}, - dictWord{8, 11, 71}, - dictWord{140, 11, 519}, - dictWord{ - 137, - 0, - 824, - }, - dictWord{140, 11, 688}, - dictWord{5, 11, 691}, - dictWord{7, 11, 345}, - dictWord{7, 10, 1385}, - dictWord{9, 11, 94}, - dictWord{11, 10, 582}, - dictWord{ - 11, - 10, - 650, - }, - dictWord{11, 10, 901}, - dictWord{11, 10, 949}, - dictWord{12, 11, 169}, - dictWord{12, 10, 232}, - dictWord{12, 10, 236}, - dictWord{13, 10, 413}, - dictWord{13, 10, 501}, - dictWord{146, 10, 116}, - dictWord{4, 0, 917}, - dictWord{133, 0, 1005}, - dictWord{7, 0, 1598}, - dictWord{5, 11, 183}, - dictWord{6, 11, 582}, - dictWord{9, 11, 344}, - dictWord{10, 11, 679}, - dictWord{140, 11, 435}, - dictWord{4, 10, 925}, - dictWord{5, 10, 803}, - dictWord{8, 10, 698}, - dictWord{ - 138, - 10, - 828, - }, - dictWord{132, 0, 919}, - dictWord{135, 11, 511}, - dictWord{139, 10, 992}, - dictWord{4, 0, 255}, - dictWord{5, 0, 302}, - dictWord{6, 0, 132}, - dictWord{ - 7, - 0, - 128, - }, - dictWord{7, 0, 283}, - dictWord{7, 0, 1299}, - dictWord{10, 0, 52}, - dictWord{10, 0, 514}, - dictWord{11, 0, 925}, - dictWord{13, 0, 92}, - dictWord{142, 0, 309}, - dictWord{134, 0, 1369}, - dictWord{135, 10, 1847}, - dictWord{134, 0, 328}, - dictWord{7, 11, 1993}, - dictWord{136, 11, 684}, - dictWord{133, 10, 383}, - dictWord{137, 0, 173}, - dictWord{134, 11, 583}, - dictWord{134, 0, 1411}, - dictWord{19, 0, 65}, - dictWord{5, 11, 704}, - dictWord{8, 11, 357}, - dictWord{10, 11, 745}, - dictWord{14, 11, 426}, - dictWord{17, 11, 94}, - dictWord{147, 11, 57}, - dictWord{9, 10, 660}, - dictWord{138, 10, 347}, - dictWord{4, 11, 179}, - dictWord{5, 11, 198}, - dictWord{133, 11, 697}, - dictWord{7, 11, 347}, - dictWord{7, 11, 971}, - dictWord{8, 11, 181}, - dictWord{138, 11, 711}, - dictWord{141, 0, 442}, - dictWord{ - 11, - 0, - 842, - }, - dictWord{11, 0, 924}, - dictWord{13, 0, 317}, - dictWord{13, 0, 370}, - dictWord{13, 0, 469}, - dictWord{13, 0, 471}, - dictWord{14, 0, 397}, - dictWord{18, 0, 69}, - dictWord{18, 0, 145}, - dictWord{7, 10, 572}, - dictWord{9, 10, 592}, - dictWord{11, 10, 680}, - dictWord{12, 10, 356}, - dictWord{140, 10, 550}, - dictWord{14, 11, 19}, - dictWord{14, 11, 28}, - dictWord{144, 11, 29}, - dictWord{136, 0, 534}, - dictWord{4, 11, 243}, - dictWord{5, 11, 203}, - dictWord{7, 11, 19}, - dictWord{7, 11, 71}, - dictWord{7, 11, 113}, - dictWord{10, 11, 405}, - dictWord{11, 11, 357}, - dictWord{142, 11, 240}, - dictWord{6, 0, 210}, - dictWord{10, 0, 845}, - dictWord{138, 0, 862}, - dictWord{7, 11, 1351}, - dictWord{9, 11, 581}, - dictWord{10, 11, 639}, - dictWord{11, 11, 453}, - dictWord{140, 11, 584}, - dictWord{7, 11, 1450}, - dictWord{ - 139, - 11, - 99, - }, - dictWord{10, 0, 892}, - dictWord{12, 0, 719}, - dictWord{144, 0, 105}, - dictWord{4, 0, 284}, - dictWord{6, 0, 223}, - dictWord{134, 11, 492}, - dictWord{5, 11, 134}, - dictWord{6, 11, 408}, - dictWord{6, 11, 495}, - dictWord{135, 11, 1593}, - dictWord{136, 0, 529}, - dictWord{137, 0, 807}, - dictWord{4, 0, 218}, - dictWord{7, 0, 526}, - dictWord{143, 0, 137}, - dictWord{6, 0, 1444}, - dictWord{142, 11, 4}, - dictWord{132, 11, 665}, - dictWord{4, 0, 270}, - dictWord{5, 0, 192}, - dictWord{6, 0, 332}, - dictWord{7, 0, 1322}, - dictWord{4, 11, 248}, - dictWord{7, 11, 137}, - dictWord{137, 11, 349}, - dictWord{140, 0, 661}, - dictWord{7, 0, 1517}, - dictWord{11, 0, 597}, - dictWord{14, 0, 76}, - dictWord{14, 0, 335}, - dictWord{20, 0, 33}, - dictWord{7, 10, 748}, - dictWord{139, 10, 700}, - dictWord{5, 11, 371}, - dictWord{135, 11, 563}, - dictWord{146, 11, 57}, - dictWord{133, 10, 127}, - dictWord{133, 0, 418}, - dictWord{4, 11, 374}, - dictWord{7, 11, 547}, - dictWord{7, 11, 1700}, - dictWord{7, 11, 1833}, - dictWord{139, 11, 858}, - dictWord{6, 10, 198}, - dictWord{140, 10, 83}, - dictWord{7, 11, 1812}, - dictWord{13, 11, 259}, - dictWord{13, 11, 356}, - dictWord{ - 14, - 11, - 242, - }, - dictWord{147, 11, 114}, - dictWord{7, 0, 379}, - dictWord{8, 0, 481}, - dictWord{9, 0, 377}, - dictWord{5, 10, 276}, - dictWord{6, 10, 55}, - dictWord{ - 135, - 10, - 1369, - }, - dictWord{138, 11, 286}, - dictWord{5, 0, 1003}, - dictWord{6, 0, 149}, - dictWord{6, 10, 1752}, - dictWord{136, 10, 726}, - dictWord{8, 0, 262}, - dictWord{ - 9, - 0, - 627, - }, - dictWord{10, 0, 18}, - dictWord{11, 0, 214}, - dictWord{11, 0, 404}, - dictWord{11, 0, 457}, - dictWord{11, 0, 780}, - dictWord{11, 0, 913}, - dictWord{13, 0, 401}, - dictWord{14, 0, 200}, - dictWord{6, 11, 1647}, - dictWord{7, 11, 1552}, - dictWord{7, 11, 2010}, - dictWord{9, 11, 494}, - dictWord{137, 11, 509}, - dictWord{ - 135, - 0, - 742, - }, - dictWord{136, 0, 304}, - dictWord{132, 0, 142}, - dictWord{133, 10, 764}, - dictWord{6, 10, 309}, - dictWord{7, 10, 331}, - dictWord{138, 10, 550}, - dictWord{135, 10, 1062}, - dictWord{6, 11, 123}, - dictWord{7, 11, 214}, - dictWord{7, 10, 986}, - dictWord{9, 11, 728}, - dictWord{10, 11, 157}, - dictWord{11, 11, 346}, - dictWord{11, 11, 662}, - dictWord{143, 11, 106}, - dictWord{135, 10, 1573}, - dictWord{7, 0, 925}, - dictWord{137, 0, 799}, - dictWord{4, 0, 471}, - dictWord{5, 0, 51}, - dictWord{6, 0, 602}, - dictWord{8, 0, 484}, - dictWord{138, 0, 195}, - dictWord{136, 0, 688}, - dictWord{132, 0, 697}, - dictWord{6, 0, 1169}, - dictWord{6, 0, 1241}, - dictWord{6, 10, 194}, - dictWord{7, 10, 133}, - dictWord{10, 10, 493}, - dictWord{10, 10, 570}, - dictWord{139, 10, 664}, - dictWord{140, 0, 751}, - dictWord{7, 0, 929}, - dictWord{10, 0, 452}, - dictWord{11, 0, 878}, - dictWord{16, 0, 33}, - dictWord{5, 10, 24}, - dictWord{5, 10, 569}, - dictWord{6, 10, 3}, - dictWord{6, 10, 119}, - dictWord{ - 6, - 10, - 143, - }, - dictWord{6, 10, 440}, - dictWord{7, 10, 599}, - dictWord{7, 10, 1686}, - dictWord{7, 10, 1854}, - dictWord{8, 10, 424}, - dictWord{9, 10, 43}, - dictWord{ - 9, - 10, - 584, - }, - dictWord{9, 10, 760}, - dictWord{10, 10, 328}, - dictWord{11, 10, 159}, - dictWord{11, 10, 253}, - dictWord{12, 10, 487}, - dictWord{140, 10, 531}, - dictWord{ - 4, - 11, - 707, - }, - dictWord{13, 11, 106}, - dictWord{18, 11, 49}, - dictWord{147, 11, 41}, - dictWord{5, 0, 221}, - dictWord{5, 11, 588}, - dictWord{134, 11, 393}, - dictWord{134, 0, 1437}, - dictWord{6, 11, 211}, - dictWord{7, 11, 1690}, - dictWord{11, 11, 486}, - dictWord{140, 11, 369}, - dictWord{5, 10, 14}, - dictWord{5, 10, 892}, - dictWord{6, 10, 283}, - dictWord{7, 10, 234}, - dictWord{136, 10, 537}, - dictWord{4, 0, 988}, - dictWord{136, 0, 955}, - dictWord{135, 0, 1251}, - dictWord{4, 10, 126}, - dictWord{8, 10, 635}, - dictWord{147, 10, 34}, - dictWord{4, 10, 316}, - dictWord{135, 10, 1561}, - dictWord{137, 10, 861}, - dictWord{4, 10, 64}, - dictWord{ - 5, - 10, - 352, - }, - dictWord{5, 10, 720}, - dictWord{6, 10, 368}, - dictWord{139, 10, 359}, - dictWord{134, 0, 192}, - dictWord{4, 0, 132}, - dictWord{5, 0, 69}, - dictWord{ - 135, - 0, - 1242, - }, - dictWord{7, 10, 1577}, - dictWord{10, 10, 304}, - dictWord{10, 10, 549}, - dictWord{12, 10, 365}, - dictWord{13, 10, 220}, - dictWord{13, 10, 240}, - dictWord{142, 10, 33}, - dictWord{4, 0, 111}, - dictWord{7, 0, 865}, - dictWord{134, 11, 219}, - dictWord{5, 11, 582}, - dictWord{6, 11, 1646}, - dictWord{7, 11, 99}, - dictWord{ - 7, - 11, - 1962, - }, - dictWord{7, 11, 1986}, - dictWord{8, 11, 515}, - dictWord{8, 11, 773}, - dictWord{9, 11, 23}, - dictWord{9, 11, 491}, - dictWord{12, 11, 620}, - dictWord{ - 14, - 11, - 52, - }, - dictWord{145, 11, 50}, - dictWord{132, 0, 767}, - dictWord{7, 11, 568}, - dictWord{148, 11, 21}, - dictWord{6, 0, 42}, - dictWord{7, 0, 1416}, - dictWord{ - 7, - 0, - 2005, - }, - dictWord{8, 0, 131}, - dictWord{8, 0, 466}, - dictWord{9, 0, 672}, - dictWord{13, 0, 252}, - dictWord{20, 0, 103}, - dictWord{133, 11, 851}, - dictWord{ - 135, - 0, - 1050, - }, - dictWord{6, 10, 175}, - dictWord{137, 10, 289}, - dictWord{5, 10, 432}, - dictWord{133, 10, 913}, - dictWord{6, 0, 44}, - dictWord{136, 0, 368}, - dictWord{ - 135, - 11, - 784, - }, - dictWord{132, 0, 570}, - dictWord{133, 0, 120}, - dictWord{139, 10, 595}, - dictWord{140, 0, 29}, - dictWord{6, 0, 227}, - dictWord{135, 0, 1589}, - dictWord{4, 11, 98}, - dictWord{7, 11, 1365}, - dictWord{9, 11, 422}, - dictWord{9, 11, 670}, - dictWord{10, 11, 775}, - dictWord{11, 11, 210}, - dictWord{13, 11, 26}, - dictWord{13, 11, 457}, - dictWord{141, 11, 476}, - dictWord{140, 10, 80}, - dictWord{5, 10, 931}, - dictWord{134, 10, 1698}, - dictWord{133, 0, 522}, - dictWord{ - 134, - 0, - 1120, - }, - dictWord{135, 0, 1529}, - dictWord{12, 0, 739}, - dictWord{14, 0, 448}, - dictWord{142, 0, 467}, - dictWord{11, 10, 526}, - dictWord{11, 10, 939}, - dictWord{141, 10, 290}, - dictWord{5, 10, 774}, - dictWord{6, 10, 1637}, - dictWord{6, 10, 1686}, - dictWord{134, 10, 1751}, - dictWord{6, 0, 1667}, - dictWord{ - 135, - 0, - 2036, - }, - dictWord{7, 10, 1167}, - dictWord{11, 10, 934}, - dictWord{13, 10, 391}, - dictWord{145, 10, 76}, - dictWord{137, 11, 147}, - dictWord{6, 10, 260}, - dictWord{ - 7, - 10, - 1484, - }, - dictWord{11, 11, 821}, - dictWord{12, 11, 110}, - dictWord{12, 11, 153}, - dictWord{18, 11, 41}, - dictWord{150, 11, 19}, - dictWord{6, 0, 511}, - dictWord{12, 0, 132}, - dictWord{134, 10, 573}, - dictWord{5, 0, 568}, - dictWord{6, 0, 138}, - dictWord{135, 0, 1293}, - dictWord{132, 0, 1020}, - dictWord{8, 0, 258}, - dictWord{9, 0, 208}, - dictWord{137, 0, 359}, - dictWord{4, 0, 565}, - dictWord{8, 0, 23}, - dictWord{136, 0, 827}, - dictWord{134, 0, 344}, - dictWord{4, 0, 922}, - dictWord{ - 5, - 0, - 1023, - }, - dictWord{13, 11, 477}, - dictWord{14, 11, 120}, - dictWord{148, 11, 61}, - dictWord{134, 0, 240}, - dictWord{5, 11, 209}, - dictWord{6, 11, 30}, - dictWord{ - 11, - 11, - 56, - }, - dictWord{139, 11, 305}, - dictWord{6, 0, 171}, - dictWord{7, 0, 1002}, - dictWord{7, 0, 1324}, - dictWord{9, 0, 415}, - dictWord{14, 0, 230}, - dictWord{ - 18, - 0, - 68, - }, - dictWord{4, 10, 292}, - dictWord{4, 10, 736}, - dictWord{5, 10, 871}, - dictWord{6, 10, 1689}, - dictWord{7, 10, 1944}, - dictWord{137, 10, 580}, - dictWord{ - 9, - 11, - 635, - }, - dictWord{139, 11, 559}, - dictWord{4, 11, 150}, - dictWord{5, 11, 303}, - dictWord{134, 11, 327}, - dictWord{6, 10, 63}, - dictWord{135, 10, 920}, - dictWord{ - 133, - 10, - 793, - }, - dictWord{8, 11, 192}, - dictWord{10, 11, 78}, - dictWord{10, 11, 555}, - dictWord{11, 11, 308}, - dictWord{13, 11, 359}, - dictWord{147, 11, 95}, - dictWord{135, 11, 786}, - dictWord{135, 11, 1712}, - dictWord{136, 0, 402}, - dictWord{6, 0, 754}, - dictWord{6, 11, 1638}, - dictWord{7, 11, 79}, - dictWord{7, 11, 496}, - dictWord{9, 11, 138}, - dictWord{10, 11, 336}, - dictWord{11, 11, 12}, - dictWord{12, 11, 412}, - dictWord{12, 11, 440}, - dictWord{142, 11, 305}, - dictWord{4, 0, 716}, - dictWord{141, 0, 31}, - dictWord{133, 0, 982}, - dictWord{8, 0, 691}, - dictWord{8, 0, 731}, - dictWord{5, 10, 67}, - dictWord{6, 10, 62}, - dictWord{6, 10, 374}, - dictWord{ - 135, - 10, - 1391, - }, - dictWord{9, 10, 790}, - dictWord{140, 10, 47}, - dictWord{139, 11, 556}, - dictWord{151, 11, 1}, - dictWord{7, 11, 204}, - dictWord{7, 11, 415}, - dictWord{8, 11, 42}, - dictWord{10, 11, 85}, - dictWord{11, 11, 33}, - dictWord{11, 11, 564}, - dictWord{12, 11, 571}, - dictWord{149, 11, 1}, - dictWord{8, 0, 888}, - dictWord{ - 7, - 11, - 610, - }, - dictWord{135, 11, 1501}, - dictWord{4, 10, 391}, - dictWord{135, 10, 1169}, - dictWord{5, 0, 847}, - dictWord{9, 0, 840}, - dictWord{138, 0, 803}, - dictWord{137, 0, 823}, - dictWord{134, 0, 785}, - dictWord{8, 0, 152}, - dictWord{9, 0, 53}, - dictWord{9, 0, 268}, - dictWord{9, 0, 901}, - dictWord{10, 0, 518}, - dictWord{ - 10, - 0, - 829, - }, - dictWord{11, 0, 188}, - dictWord{13, 0, 74}, - dictWord{14, 0, 46}, - dictWord{15, 0, 17}, - dictWord{15, 0, 33}, - dictWord{17, 0, 40}, - dictWord{18, 0, 36}, - dictWord{ - 19, - 0, - 20, - }, - dictWord{22, 0, 1}, - dictWord{152, 0, 2}, - dictWord{4, 11, 3}, - dictWord{5, 11, 247}, - dictWord{5, 11, 644}, - dictWord{7, 11, 744}, - dictWord{7, 11, 1207}, - dictWord{7, 11, 1225}, - dictWord{7, 11, 1909}, - dictWord{146, 11, 147}, - dictWord{136, 0, 532}, - dictWord{135, 0, 681}, - dictWord{132, 10, 271}, - dictWord{ - 140, - 0, - 314, - }, - dictWord{140, 0, 677}, - dictWord{4, 0, 684}, - dictWord{136, 0, 384}, - dictWord{5, 11, 285}, - dictWord{9, 11, 67}, - dictWord{13, 11, 473}, - dictWord{ - 143, - 11, - 82, - }, - dictWord{4, 10, 253}, - dictWord{5, 10, 544}, - dictWord{7, 10, 300}, - dictWord{137, 10, 340}, - dictWord{7, 0, 110}, - dictWord{7, 0, 447}, - dictWord{8, 0, 290}, - dictWord{8, 0, 591}, - dictWord{9, 0, 382}, - dictWord{9, 0, 649}, - dictWord{11, 0, 71}, - dictWord{11, 0, 155}, - dictWord{11, 0, 313}, - dictWord{12, 0, 5}, - dictWord{13, 0, 325}, - dictWord{142, 0, 287}, - dictWord{134, 0, 1818}, - dictWord{136, 0, 1007}, - dictWord{138, 0, 321}, - dictWord{7, 0, 360}, - dictWord{7, 0, 425}, - dictWord{9, 0, 66}, - dictWord{9, 0, 278}, - dictWord{138, 0, 644}, - dictWord{133, 10, 818}, - dictWord{5, 0, 385}, - dictWord{5, 10, 541}, - dictWord{6, 10, 94}, - dictWord{6, 10, 499}, - dictWord{ - 7, - 10, - 230, - }, - dictWord{139, 10, 321}, - dictWord{4, 10, 920}, - dictWord{5, 10, 25}, - dictWord{5, 10, 790}, - dictWord{6, 10, 457}, - dictWord{7, 10, 853}, - dictWord{ - 136, - 10, - 788, - }, - dictWord{4, 0, 900}, - dictWord{133, 0, 861}, - dictWord{5, 0, 254}, - dictWord{7, 0, 985}, - dictWord{136, 0, 73}, - dictWord{7, 0, 1959}, - dictWord{ - 136, - 0, - 683, - }, - dictWord{134, 10, 1765}, - dictWord{133, 10, 822}, - dictWord{132, 10, 634}, - dictWord{4, 11, 29}, - dictWord{6, 11, 532}, - dictWord{7, 11, 1628}, - dictWord{ - 7, - 11, - 1648, - }, - dictWord{9, 11, 303}, - dictWord{9, 11, 350}, - dictWord{10, 11, 433}, - dictWord{11, 11, 97}, - dictWord{11, 11, 557}, - dictWord{11, 11, 745}, - dictWord{12, 11, 289}, - dictWord{12, 11, 335}, - dictWord{12, 11, 348}, - dictWord{12, 11, 606}, - dictWord{13, 11, 116}, - dictWord{13, 11, 233}, - dictWord{ - 13, - 11, - 466, - }, - dictWord{14, 11, 181}, - dictWord{14, 11, 209}, - dictWord{14, 11, 232}, - dictWord{14, 11, 236}, - dictWord{14, 11, 300}, - dictWord{16, 11, 41}, - dictWord{ - 148, - 11, - 97, - }, - dictWord{19, 0, 86}, - dictWord{6, 10, 36}, - dictWord{7, 10, 658}, - dictWord{136, 10, 454}, - dictWord{135, 11, 1692}, - dictWord{132, 0, 725}, - dictWord{ - 5, - 11, - 501, - }, - dictWord{7, 11, 1704}, - dictWord{9, 11, 553}, - dictWord{11, 11, 520}, - dictWord{12, 11, 557}, - dictWord{141, 11, 249}, - dictWord{134, 0, 196}, - dictWord{133, 0, 831}, - dictWord{136, 0, 723}, - dictWord{7, 0, 1897}, - dictWord{13, 0, 80}, - dictWord{13, 0, 437}, - dictWord{145, 0, 74}, - dictWord{4, 0, 992}, - dictWord{ - 6, - 0, - 627, - }, - dictWord{136, 0, 994}, - dictWord{135, 11, 1294}, - dictWord{132, 10, 104}, - dictWord{5, 0, 848}, - dictWord{6, 0, 66}, - dictWord{136, 0, 764}, - dictWord{ - 4, - 0, - 36, - }, - dictWord{7, 0, 1387}, - dictWord{10, 0, 205}, - dictWord{139, 0, 755}, - dictWord{6, 0, 1046}, - dictWord{134, 0, 1485}, - dictWord{134, 0, 950}, - dictWord{132, 0, 887}, - dictWord{14, 0, 450}, - dictWord{148, 0, 111}, - dictWord{7, 0, 620}, - dictWord{7, 0, 831}, - dictWord{9, 10, 542}, - dictWord{9, 10, 566}, - dictWord{ - 138, - 10, - 728, - }, - dictWord{6, 0, 165}, - dictWord{138, 0, 388}, - dictWord{139, 10, 263}, - dictWord{4, 0, 719}, - dictWord{135, 0, 155}, - dictWord{138, 10, 468}, - dictWord{6, 11, 453}, - dictWord{144, 11, 36}, - dictWord{134, 11, 129}, - dictWord{5, 0, 533}, - dictWord{7, 0, 755}, - dictWord{138, 0, 780}, - dictWord{134, 0, 1465}, - dictWord{4, 0, 353}, - dictWord{6, 0, 146}, - dictWord{6, 0, 1789}, - dictWord{7, 0, 427}, - dictWord{7, 0, 990}, - dictWord{7, 0, 1348}, - dictWord{9, 0, 665}, - dictWord{9, 0, 898}, - dictWord{11, 0, 893}, - dictWord{142, 0, 212}, - dictWord{7, 10, 87}, - dictWord{142, 10, 288}, - dictWord{4, 0, 45}, - dictWord{135, 0, 1257}, - dictWord{12, 0, 7}, - dictWord{7, 10, 988}, - dictWord{7, 10, 1939}, - dictWord{9, 10, 64}, - dictWord{9, 10, 502}, - dictWord{12, 10, 34}, - dictWord{13, 10, 12}, - dictWord{13, 10, 234}, - dictWord{147, 10, 77}, - dictWord{4, 0, 607}, - dictWord{5, 11, 60}, - dictWord{6, 11, 504}, - dictWord{7, 11, 614}, - dictWord{7, 11, 1155}, - dictWord{140, 11, 0}, - dictWord{ - 135, - 10, - 141, - }, - dictWord{8, 11, 198}, - dictWord{11, 11, 29}, - dictWord{140, 11, 534}, - dictWord{140, 0, 65}, - dictWord{136, 0, 816}, - dictWord{132, 10, 619}, - dictWord{139, 0, 88}, - dictWord{5, 10, 246}, - dictWord{8, 10, 189}, - dictWord{9, 10, 355}, - dictWord{9, 10, 512}, - dictWord{10, 10, 124}, - dictWord{10, 10, 453}, - dictWord{11, 10, 143}, - dictWord{11, 10, 416}, - dictWord{11, 10, 859}, - dictWord{141, 10, 341}, - dictWord{4, 11, 379}, - dictWord{135, 11, 1397}, - dictWord{ - 4, - 0, - 600, - }, - dictWord{137, 0, 621}, - dictWord{133, 0, 367}, - dictWord{134, 0, 561}, - dictWord{6, 0, 559}, - dictWord{134, 0, 1691}, - dictWord{6, 0, 585}, - dictWord{ - 134, - 11, - 585, - }, - dictWord{135, 11, 1228}, - dictWord{4, 11, 118}, - dictWord{5, 10, 678}, - dictWord{6, 11, 274}, - dictWord{6, 11, 361}, - dictWord{7, 11, 75}, - dictWord{ - 141, - 11, - 441, - }, - dictWord{135, 11, 1818}, - dictWord{137, 11, 841}, - dictWord{5, 0, 573}, - dictWord{6, 0, 287}, - dictWord{7, 10, 862}, - dictWord{7, 10, 1886}, - dictWord{138, 10, 179}, - dictWord{132, 10, 517}, - dictWord{140, 11, 693}, - dictWord{5, 11, 314}, - dictWord{6, 11, 221}, - dictWord{7, 11, 419}, - dictWord{ - 10, - 11, - 650, - }, - dictWord{11, 11, 396}, - dictWord{12, 11, 156}, - dictWord{13, 11, 369}, - dictWord{14, 11, 333}, - dictWord{145, 11, 47}, - dictWord{140, 10, 540}, - dictWord{136, 10, 667}, - dictWord{11, 10, 403}, - dictWord{146, 10, 83}, - dictWord{6, 0, 672}, - dictWord{133, 10, 761}, - dictWord{9, 0, 157}, - dictWord{10, 10, 131}, - dictWord{140, 10, 72}, - dictWord{7, 0, 714}, - dictWord{134, 11, 460}, - dictWord{134, 0, 456}, - dictWord{133, 0, 925}, - dictWord{5, 11, 682}, - dictWord{ - 135, - 11, - 1887, - }, - dictWord{136, 11, 510}, - dictWord{136, 11, 475}, - dictWord{133, 11, 1016}, - dictWord{9, 0, 19}, - dictWord{7, 11, 602}, - dictWord{8, 11, 179}, - dictWord{ - 10, - 11, - 781, - }, - dictWord{140, 11, 126}, - dictWord{6, 11, 329}, - dictWord{138, 11, 111}, - dictWord{6, 0, 822}, - dictWord{134, 0, 1473}, - dictWord{144, 11, 86}, - dictWord{11, 0, 113}, - dictWord{139, 11, 113}, - dictWord{5, 11, 821}, - dictWord{134, 11, 1687}, - dictWord{133, 10, 449}, - dictWord{7, 0, 463}, - dictWord{ - 17, - 0, - 69, - }, - dictWord{136, 10, 103}, - dictWord{7, 10, 2028}, - dictWord{138, 10, 641}, - dictWord{6, 0, 193}, - dictWord{7, 0, 240}, - dictWord{7, 0, 1682}, - dictWord{ - 10, - 0, - 51, - }, - dictWord{10, 0, 640}, - dictWord{11, 0, 410}, - dictWord{13, 0, 82}, - dictWord{14, 0, 247}, - dictWord{14, 0, 331}, - dictWord{142, 0, 377}, - dictWord{6, 0, 471}, - dictWord{11, 0, 411}, - dictWord{142, 0, 2}, - dictWord{5, 11, 71}, - dictWord{7, 11, 1407}, - dictWord{9, 11, 388}, - dictWord{9, 11, 704}, - dictWord{10, 11, 261}, - dictWord{ - 10, - 11, - 619, - }, - dictWord{11, 11, 547}, - dictWord{11, 11, 619}, - dictWord{143, 11, 157}, - dictWord{136, 0, 633}, - dictWord{135, 0, 1148}, - dictWord{6, 0, 554}, - dictWord{7, 0, 1392}, - dictWord{12, 0, 129}, - dictWord{7, 10, 1274}, - dictWord{7, 10, 1386}, - dictWord{7, 11, 2008}, - dictWord{9, 11, 337}, - dictWord{10, 11, 517}, - dictWord{146, 10, 87}, - dictWord{7, 0, 803}, - dictWord{8, 0, 542}, - dictWord{6, 10, 187}, - dictWord{7, 10, 1203}, - dictWord{8, 10, 380}, - dictWord{14, 10, 117}, - dictWord{149, 10, 28}, - dictWord{6, 10, 297}, - dictWord{7, 10, 793}, - dictWord{139, 10, 938}, - dictWord{8, 0, 438}, - dictWord{11, 0, 363}, - dictWord{7, 10, 464}, - dictWord{11, 10, 105}, - dictWord{12, 10, 231}, - dictWord{14, 10, 386}, - dictWord{15, 10, 102}, - dictWord{148, 10, 75}, - dictWord{5, 11, 16}, - dictWord{6, 11, 86}, - dictWord{6, 11, 603}, - dictWord{7, 11, 292}, - dictWord{7, 11, 561}, - dictWord{8, 11, 257}, - dictWord{8, 11, 382}, - dictWord{9, 11, 721}, - dictWord{9, 11, 778}, - dictWord{ - 11, - 11, - 581, - }, - dictWord{140, 11, 466}, - dictWord{6, 0, 717}, - dictWord{4, 11, 486}, - dictWord{133, 11, 491}, - dictWord{132, 0, 875}, - dictWord{132, 11, 72}, - dictWord{6, 11, 265}, - dictWord{135, 11, 847}, - dictWord{4, 0, 237}, - dictWord{135, 0, 514}, - dictWord{6, 0, 392}, - dictWord{7, 0, 65}, - dictWord{135, 0, 2019}, - dictWord{140, 11, 261}, - dictWord{135, 11, 922}, - dictWord{137, 11, 404}, - dictWord{12, 0, 563}, - dictWord{14, 0, 101}, - dictWord{18, 0, 129}, - dictWord{ - 7, - 10, - 1010, - }, - dictWord{11, 10, 733}, - dictWord{11, 10, 759}, - dictWord{13, 10, 34}, - dictWord{146, 10, 45}, - dictWord{7, 10, 1656}, - dictWord{9, 10, 369}, - dictWord{ - 10, - 10, - 338, - }, - dictWord{10, 10, 490}, - dictWord{11, 10, 154}, - dictWord{11, 10, 545}, - dictWord{11, 10, 775}, - dictWord{13, 10, 77}, - dictWord{141, 10, 274}, - dictWord{4, 0, 444}, - dictWord{10, 0, 146}, - dictWord{140, 0, 9}, - dictWord{139, 11, 163}, - dictWord{7, 0, 1260}, - dictWord{135, 0, 1790}, - dictWord{9, 0, 222}, - dictWord{10, 0, 43}, - dictWord{139, 0, 900}, - dictWord{137, 11, 234}, - dictWord{138, 0, 971}, - dictWord{137, 0, 761}, - dictWord{134, 0, 699}, - dictWord{ - 136, - 11, - 434, - }, - dictWord{6, 0, 1116}, - dictWord{7, 0, 1366}, - dictWord{5, 10, 20}, - dictWord{6, 11, 197}, - dictWord{6, 10, 298}, - dictWord{7, 10, 659}, - dictWord{8, 11, 205}, - dictWord{137, 10, 219}, - dictWord{132, 11, 490}, - dictWord{11, 11, 820}, - dictWord{150, 11, 51}, - dictWord{7, 10, 1440}, - dictWord{11, 10, 854}, - dictWord{ - 11, - 10, - 872, - }, - dictWord{11, 10, 921}, - dictWord{12, 10, 551}, - dictWord{13, 10, 472}, - dictWord{142, 10, 367}, - dictWord{140, 11, 13}, - dictWord{132, 0, 829}, - dictWord{12, 0, 242}, - dictWord{132, 10, 439}, - dictWord{136, 10, 669}, - dictWord{6, 0, 593}, - dictWord{6, 11, 452}, - dictWord{7, 11, 312}, - dictWord{ - 138, - 11, - 219, - }, - dictWord{4, 11, 333}, - dictWord{9, 11, 176}, - dictWord{12, 11, 353}, - dictWord{141, 11, 187}, - dictWord{7, 0, 36}, - dictWord{8, 0, 201}, - dictWord{ - 136, - 0, - 605, - }, - dictWord{140, 0, 224}, - dictWord{132, 10, 233}, - dictWord{134, 0, 1430}, - dictWord{134, 0, 1806}, - dictWord{4, 0, 523}, - dictWord{133, 0, 638}, - dictWord{ - 6, - 0, - 1889, - }, - dictWord{9, 0, 958}, - dictWord{9, 0, 971}, - dictWord{9, 0, 976}, - dictWord{12, 0, 796}, - dictWord{12, 0, 799}, - dictWord{12, 0, 808}, - dictWord{ - 12, - 0, - 835, - }, - dictWord{12, 0, 836}, - dictWord{12, 0, 914}, - dictWord{12, 0, 946}, - dictWord{15, 0, 216}, - dictWord{15, 0, 232}, - dictWord{18, 0, 183}, - dictWord{18, 0, 187}, - dictWord{18, 0, 194}, - dictWord{18, 0, 212}, - dictWord{18, 0, 232}, - dictWord{149, 0, 49}, - dictWord{132, 10, 482}, - dictWord{6, 0, 827}, - dictWord{134, 0, 1434}, - dictWord{135, 10, 346}, - dictWord{134, 0, 2043}, - dictWord{6, 0, 242}, - dictWord{7, 0, 227}, - dictWord{7, 0, 1581}, - dictWord{8, 0, 104}, - dictWord{9, 0, 113}, - dictWord{9, 0, 220}, - dictWord{9, 0, 427}, - dictWord{10, 0, 136}, - dictWord{10, 0, 239}, - dictWord{11, 0, 579}, - dictWord{11, 0, 1023}, - dictWord{13, 0, 4}, - dictWord{ - 13, - 0, - 204, - }, - dictWord{13, 0, 316}, - dictWord{148, 0, 86}, - dictWord{134, 11, 1685}, - dictWord{7, 0, 148}, - dictWord{8, 0, 284}, - dictWord{141, 0, 63}, - dictWord{ - 142, - 0, - 10, - }, - dictWord{135, 11, 584}, - dictWord{134, 0, 1249}, - dictWord{7, 0, 861}, - dictWord{135, 10, 334}, - dictWord{5, 10, 795}, - dictWord{6, 10, 1741}, - dictWord{ - 137, - 11, - 70, - }, - dictWord{132, 0, 807}, - dictWord{7, 11, 135}, - dictWord{8, 11, 7}, - dictWord{8, 11, 62}, - dictWord{9, 11, 243}, - dictWord{10, 11, 658}, - dictWord{ - 10, - 11, - 697, - }, - dictWord{11, 11, 456}, - dictWord{139, 11, 756}, - dictWord{9, 11, 395}, - dictWord{138, 11, 79}, - dictWord{137, 11, 108}, - dictWord{147, 0, 94}, - dictWord{136, 0, 494}, - dictWord{135, 11, 631}, - dictWord{135, 10, 622}, - dictWord{7, 0, 1510}, - dictWord{135, 10, 1750}, - dictWord{4, 10, 203}, - dictWord{ - 135, - 10, - 1936, - }, - dictWord{7, 11, 406}, - dictWord{7, 11, 459}, - dictWord{8, 11, 606}, - dictWord{139, 11, 726}, - dictWord{7, 0, 1306}, - dictWord{8, 0, 505}, - dictWord{ - 9, - 0, - 482, - }, - dictWord{10, 0, 126}, - dictWord{11, 0, 225}, - dictWord{12, 0, 347}, - dictWord{12, 0, 449}, - dictWord{13, 0, 19}, - dictWord{14, 0, 218}, - dictWord{142, 0, 435}, - dictWord{5, 0, 268}, - dictWord{10, 0, 764}, - dictWord{12, 0, 120}, - dictWord{13, 0, 39}, - dictWord{145, 0, 127}, - dictWord{142, 11, 68}, - dictWord{11, 10, 678}, - dictWord{140, 10, 307}, - dictWord{12, 11, 268}, - dictWord{12, 11, 640}, - dictWord{142, 11, 119}, - dictWord{135, 10, 2044}, - dictWord{133, 11, 612}, - dictWord{ - 4, - 11, - 372, - }, - dictWord{7, 11, 482}, - dictWord{8, 11, 158}, - dictWord{9, 11, 602}, - dictWord{9, 11, 615}, - dictWord{10, 11, 245}, - dictWord{10, 11, 678}, - dictWord{ - 10, - 11, - 744, - }, - dictWord{11, 11, 248}, - dictWord{139, 11, 806}, - dictWord{7, 10, 311}, - dictWord{9, 10, 308}, - dictWord{140, 10, 255}, - dictWord{4, 0, 384}, - dictWord{135, 0, 1022}, - dictWord{5, 11, 854}, - dictWord{135, 11, 1991}, - dictWord{135, 10, 1266}, - dictWord{4, 10, 400}, - dictWord{5, 10, 267}, - dictWord{ - 135, - 10, - 232, - }, - dictWord{135, 0, 1703}, - dictWord{9, 0, 159}, - dictWord{11, 0, 661}, - dictWord{140, 0, 603}, - dictWord{4, 0, 964}, - dictWord{14, 0, 438}, - dictWord{ - 14, - 0, - 444, - }, - dictWord{14, 0, 456}, - dictWord{22, 0, 60}, - dictWord{22, 0, 63}, - dictWord{9, 11, 106}, - dictWord{9, 11, 163}, - dictWord{9, 11, 296}, - dictWord{10, 11, 167}, - dictWord{10, 11, 172}, - dictWord{10, 11, 777}, - dictWord{139, 11, 16}, - dictWord{136, 0, 583}, - dictWord{132, 0, 515}, - dictWord{8, 0, 632}, - dictWord{8, 0, 697}, - dictWord{137, 0, 854}, - dictWord{5, 11, 195}, - dictWord{135, 11, 1685}, - dictWord{6, 0, 1123}, - dictWord{134, 0, 1365}, - dictWord{134, 11, 328}, - dictWord{ - 7, - 11, - 1997, - }, - dictWord{8, 11, 730}, - dictWord{139, 11, 1006}, - dictWord{4, 0, 136}, - dictWord{133, 0, 551}, - dictWord{134, 0, 1782}, - dictWord{7, 0, 1287}, - dictWord{ - 9, - 0, - 44, - }, - dictWord{10, 0, 552}, - dictWord{10, 0, 642}, - dictWord{11, 0, 839}, - dictWord{12, 0, 274}, - dictWord{12, 0, 275}, - dictWord{12, 0, 372}, - dictWord{ - 13, - 0, - 91, - }, - dictWord{142, 0, 125}, - dictWord{5, 11, 751}, - dictWord{11, 11, 797}, - dictWord{140, 11, 203}, - dictWord{133, 0, 732}, - dictWord{7, 0, 679}, - dictWord{ - 8, - 0, - 313, - }, - dictWord{4, 10, 100}, - dictWord{135, 11, 821}, - dictWord{10, 0, 361}, - dictWord{142, 0, 316}, - dictWord{134, 0, 595}, - dictWord{6, 0, 147}, - dictWord{ - 7, - 0, - 886, - }, - dictWord{9, 0, 753}, - dictWord{138, 0, 268}, - dictWord{5, 10, 362}, - dictWord{5, 10, 443}, - dictWord{6, 10, 318}, - dictWord{7, 10, 1019}, - dictWord{ - 139, - 10, - 623, - }, - dictWord{5, 10, 463}, - dictWord{136, 10, 296}, - dictWord{4, 10, 454}, - dictWord{5, 11, 950}, - dictWord{5, 11, 994}, - dictWord{134, 11, 351}, - dictWord{ - 138, - 0, - 137, - }, - dictWord{5, 10, 48}, - dictWord{5, 10, 404}, - dictWord{6, 10, 557}, - dictWord{7, 10, 458}, - dictWord{8, 10, 597}, - dictWord{10, 10, 455}, - dictWord{ - 10, - 10, - 606, - }, - dictWord{11, 10, 49}, - dictWord{11, 10, 548}, - dictWord{12, 10, 476}, - dictWord{13, 10, 18}, - dictWord{141, 10, 450}, - dictWord{133, 0, 414}, - dictWord{ - 135, - 0, - 1762, - }, - dictWord{5, 11, 421}, - dictWord{135, 11, 47}, - dictWord{5, 10, 442}, - dictWord{135, 10, 1984}, - dictWord{134, 0, 599}, - dictWord{134, 0, 1749}, - dictWord{134, 0, 1627}, - dictWord{4, 0, 488}, - dictWord{132, 11, 350}, - dictWord{137, 11, 751}, - dictWord{132, 0, 83}, - dictWord{140, 0, 676}, - dictWord{ - 133, - 11, - 967, - }, - dictWord{7, 0, 1639}, - dictWord{5, 10, 55}, - dictWord{140, 10, 161}, - dictWord{4, 11, 473}, - dictWord{7, 11, 623}, - dictWord{8, 11, 808}, - dictWord{ - 9, - 11, - 871, - }, - dictWord{9, 11, 893}, - dictWord{11, 11, 38}, - dictWord{11, 11, 431}, - dictWord{12, 11, 112}, - dictWord{12, 11, 217}, - dictWord{12, 11, 243}, - dictWord{ - 12, - 11, - 562, - }, - dictWord{12, 11, 683}, - dictWord{13, 11, 141}, - dictWord{13, 11, 197}, - dictWord{13, 11, 227}, - dictWord{13, 11, 406}, - dictWord{13, 11, 487}, - dictWord{14, 11, 156}, - dictWord{14, 11, 203}, - dictWord{14, 11, 224}, - dictWord{14, 11, 256}, - dictWord{18, 11, 58}, - dictWord{150, 11, 0}, - dictWord{ - 133, - 10, - 450, - }, - dictWord{7, 11, 736}, - dictWord{139, 11, 264}, - dictWord{134, 0, 278}, - dictWord{4, 11, 222}, - dictWord{7, 11, 286}, - dictWord{136, 11, 629}, - dictWord{ - 135, - 10, - 869, - }, - dictWord{140, 0, 97}, - dictWord{144, 0, 14}, - dictWord{134, 0, 1085}, - dictWord{4, 10, 213}, - dictWord{7, 10, 223}, - dictWord{136, 10, 80}, - dictWord{ - 7, - 0, - 388, - }, - dictWord{7, 0, 644}, - dictWord{139, 0, 781}, - dictWord{132, 0, 849}, - dictWord{7, 0, 229}, - dictWord{8, 0, 59}, - dictWord{9, 0, 190}, - dictWord{10, 0, 378}, - dictWord{140, 0, 191}, - dictWord{7, 10, 381}, - dictWord{7, 10, 806}, - dictWord{7, 10, 820}, - dictWord{8, 10, 354}, - dictWord{8, 10, 437}, - dictWord{8, 10, 787}, - dictWord{9, 10, 657}, - dictWord{10, 10, 58}, - dictWord{10, 10, 339}, - dictWord{10, 10, 749}, - dictWord{11, 10, 914}, - dictWord{12, 10, 162}, - dictWord{13, 10, 75}, - dictWord{14, 10, 106}, - dictWord{14, 10, 198}, - dictWord{14, 10, 320}, - dictWord{14, 10, 413}, - dictWord{146, 10, 43}, - dictWord{141, 11, 306}, - dictWord{ - 136, - 10, - 747, - }, - dictWord{134, 0, 1115}, - dictWord{16, 0, 94}, - dictWord{16, 0, 108}, - dictWord{136, 11, 146}, - dictWord{6, 0, 700}, - dictWord{6, 0, 817}, - dictWord{ - 134, - 0, - 1002, - }, - dictWord{133, 10, 692}, - dictWord{4, 11, 465}, - dictWord{135, 11, 1663}, - dictWord{134, 10, 191}, - dictWord{6, 0, 1414}, - dictWord{ - 135, - 11, - 913, - }, - dictWord{132, 0, 660}, - dictWord{7, 0, 1035}, - dictWord{138, 0, 737}, - dictWord{6, 10, 162}, - dictWord{7, 10, 1960}, - dictWord{136, 10, 831}, - dictWord{ - 132, - 10, - 706, - }, - dictWord{7, 0, 690}, - dictWord{9, 0, 217}, - dictWord{9, 0, 587}, - dictWord{140, 0, 521}, - dictWord{138, 10, 426}, - dictWord{135, 10, 1235}, - dictWord{ - 6, - 11, - 82, - }, - dictWord{7, 11, 138}, - dictWord{7, 11, 517}, - dictWord{9, 11, 673}, - dictWord{139, 11, 238}, - dictWord{138, 0, 272}, - dictWord{5, 11, 495}, - dictWord{ - 7, - 11, - 834, - }, - dictWord{9, 11, 733}, - dictWord{139, 11, 378}, - dictWord{134, 0, 1744}, - dictWord{132, 0, 1011}, - dictWord{7, 11, 828}, - dictWord{142, 11, 116}, - dictWord{4, 0, 733}, - dictWord{9, 0, 194}, - dictWord{10, 0, 92}, - dictWord{11, 0, 198}, - dictWord{12, 0, 84}, - dictWord{13, 0, 128}, - dictWord{133, 11, 559}, - dictWord{ - 10, - 0, - 57, - }, - dictWord{10, 0, 277}, - dictWord{6, 11, 21}, - dictWord{6, 11, 1737}, - dictWord{7, 11, 1444}, - dictWord{136, 11, 224}, - dictWord{4, 10, 204}, - dictWord{ - 137, - 10, - 902, - }, - dictWord{136, 10, 833}, - dictWord{11, 0, 348}, - dictWord{12, 0, 99}, - dictWord{18, 0, 1}, - dictWord{18, 0, 11}, - dictWord{19, 0, 4}, - dictWord{7, 10, 366}, - dictWord{9, 10, 287}, - dictWord{12, 10, 199}, - dictWord{12, 10, 556}, - dictWord{140, 10, 577}, - dictWord{6, 0, 1981}, - dictWord{136, 0, 936}, - dictWord{ - 21, - 0, - 33, - }, - dictWord{150, 0, 40}, - dictWord{5, 11, 519}, - dictWord{138, 11, 204}, - dictWord{5, 10, 356}, - dictWord{135, 10, 224}, - dictWord{134, 0, 775}, - dictWord{ - 135, - 0, - 306, - }, - dictWord{7, 10, 630}, - dictWord{9, 10, 567}, - dictWord{11, 10, 150}, - dictWord{11, 10, 444}, - dictWord{141, 10, 119}, - dictWord{5, 0, 979}, - dictWord{ - 134, - 10, - 539, - }, - dictWord{133, 0, 611}, - dictWord{4, 11, 402}, - dictWord{135, 11, 1679}, - dictWord{5, 0, 178}, - dictWord{7, 11, 2}, - dictWord{8, 11, 323}, - dictWord{ - 136, - 11, - 479, - }, - dictWord{5, 11, 59}, - dictWord{135, 11, 672}, - dictWord{4, 0, 1010}, - dictWord{6, 0, 1969}, - dictWord{138, 11, 237}, - dictWord{133, 11, 412}, - dictWord{146, 11, 34}, - dictWord{7, 11, 1740}, - dictWord{146, 11, 48}, - dictWord{134, 0, 664}, - dictWord{139, 10, 814}, - dictWord{4, 11, 85}, - dictWord{ - 135, - 11, - 549, - }, - dictWord{133, 11, 94}, - dictWord{133, 11, 457}, - dictWord{132, 0, 390}, - dictWord{134, 0, 1510}, - dictWord{4, 10, 235}, - dictWord{135, 10, 255}, - dictWord{4, 10, 194}, - dictWord{5, 10, 584}, - dictWord{6, 11, 11}, - dictWord{6, 10, 384}, - dictWord{7, 11, 187}, - dictWord{7, 10, 583}, - dictWord{10, 10, 761}, - dictWord{ - 11, - 10, - 760, - }, - dictWord{139, 10, 851}, - dictWord{4, 11, 522}, - dictWord{139, 11, 802}, - dictWord{135, 0, 493}, - dictWord{10, 11, 776}, - dictWord{13, 11, 345}, - dictWord{142, 11, 425}, - dictWord{146, 0, 37}, - dictWord{4, 11, 52}, - dictWord{135, 11, 661}, - dictWord{134, 0, 724}, - dictWord{134, 0, 829}, - dictWord{ - 133, - 11, - 520, - }, - dictWord{133, 10, 562}, - dictWord{4, 11, 281}, - dictWord{5, 11, 38}, - dictWord{7, 11, 194}, - dictWord{7, 11, 668}, - dictWord{7, 11, 1893}, - dictWord{ - 137, - 11, - 397, - }, - dictWord{5, 10, 191}, - dictWord{137, 10, 271}, - dictWord{7, 0, 1537}, - dictWord{14, 0, 96}, - dictWord{143, 0, 73}, - dictWord{5, 0, 473}, - dictWord{ - 11, - 0, - 168, - }, - dictWord{4, 10, 470}, - dictWord{6, 10, 153}, - dictWord{7, 10, 1503}, - dictWord{7, 10, 1923}, - dictWord{10, 10, 701}, - dictWord{11, 10, 132}, - dictWord{ - 11, - 10, - 227, - }, - dictWord{11, 10, 320}, - dictWord{11, 10, 436}, - dictWord{11, 10, 525}, - dictWord{11, 10, 855}, - dictWord{12, 10, 41}, - dictWord{12, 10, 286}, - dictWord{13, 10, 103}, - dictWord{13, 10, 284}, - dictWord{14, 10, 255}, - dictWord{14, 10, 262}, - dictWord{15, 10, 117}, - dictWord{143, 10, 127}, - dictWord{ - 133, - 0, - 105, - }, - dictWord{5, 0, 438}, - dictWord{9, 0, 694}, - dictWord{12, 0, 627}, - dictWord{141, 0, 210}, - dictWord{133, 10, 327}, - dictWord{6, 10, 552}, - dictWord{ - 7, - 10, - 1754, - }, - dictWord{137, 10, 604}, - dictWord{134, 0, 1256}, - dictWord{152, 0, 11}, - dictWord{5, 11, 448}, - dictWord{11, 11, 98}, - dictWord{139, 11, 524}, - dictWord{ - 7, - 0, - 1626, - }, - dictWord{5, 10, 80}, - dictWord{6, 10, 405}, - dictWord{7, 10, 403}, - dictWord{7, 10, 1502}, - dictWord{8, 10, 456}, - dictWord{9, 10, 487}, - dictWord{ - 9, - 10, - 853, - }, - dictWord{9, 10, 889}, - dictWord{10, 10, 309}, - dictWord{11, 10, 721}, - dictWord{11, 10, 994}, - dictWord{12, 10, 430}, - dictWord{13, 10, 165}, - dictWord{ - 14, - 11, - 16, - }, - dictWord{146, 11, 44}, - dictWord{132, 0, 779}, - dictWord{8, 0, 25}, - dictWord{138, 0, 826}, - dictWord{4, 10, 453}, - dictWord{5, 10, 887}, - dictWord{ - 6, - 10, - 535, - }, - dictWord{8, 10, 6}, - dictWord{8, 10, 543}, - dictWord{136, 10, 826}, - dictWord{137, 11, 461}, - dictWord{140, 11, 632}, - dictWord{132, 0, 308}, - dictWord{135, 0, 741}, - dictWord{132, 0, 671}, - dictWord{7, 0, 150}, - dictWord{8, 0, 649}, - dictWord{136, 0, 1020}, - dictWord{9, 0, 99}, - dictWord{6, 11, 336}, - dictWord{ - 8, - 11, - 552, - }, - dictWord{9, 11, 285}, - dictWord{10, 11, 99}, - dictWord{139, 11, 568}, - dictWord{134, 0, 521}, - dictWord{5, 0, 339}, - dictWord{14, 0, 3}, - dictWord{ - 15, - 0, - 41, - }, - dictWord{15, 0, 166}, - dictWord{147, 0, 66}, - dictWord{6, 11, 423}, - dictWord{7, 11, 665}, - dictWord{7, 11, 1210}, - dictWord{9, 11, 218}, - dictWord{ - 141, - 11, - 222, - }, - dictWord{6, 0, 543}, - dictWord{5, 10, 101}, - dictWord{5, 11, 256}, - dictWord{6, 10, 88}, - dictWord{7, 10, 1677}, - dictWord{9, 10, 100}, - dictWord{10, 10, 677}, - dictWord{14, 10, 169}, - dictWord{14, 10, 302}, - dictWord{14, 10, 313}, - dictWord{15, 10, 48}, - dictWord{143, 10, 84}, - dictWord{4, 10, 310}, - dictWord{ - 7, - 10, - 708, - }, - dictWord{7, 10, 996}, - dictWord{9, 10, 795}, - dictWord{10, 10, 390}, - dictWord{10, 10, 733}, - dictWord{11, 10, 451}, - dictWord{12, 10, 249}, - dictWord{ - 14, - 10, - 115, - }, - dictWord{14, 10, 286}, - dictWord{143, 10, 100}, - dictWord{133, 10, 587}, - dictWord{13, 11, 417}, - dictWord{14, 11, 129}, - dictWord{143, 11, 15}, - dictWord{134, 0, 1358}, - dictWord{136, 11, 554}, - dictWord{132, 10, 498}, - dictWord{7, 10, 217}, - dictWord{8, 10, 140}, - dictWord{138, 10, 610}, - dictWord{ - 135, - 11, - 989, - }, - dictWord{135, 11, 634}, - dictWord{6, 0, 155}, - dictWord{140, 0, 234}, - dictWord{135, 11, 462}, - dictWord{132, 11, 618}, - dictWord{ - 134, - 0, - 1628, - }, - dictWord{132, 0, 766}, - dictWord{4, 11, 339}, - dictWord{5, 10, 905}, - dictWord{135, 11, 259}, - dictWord{135, 0, 829}, - dictWord{4, 11, 759}, - dictWord{ - 141, - 11, - 169, - }, - dictWord{7, 0, 1445}, - dictWord{4, 10, 456}, - dictWord{7, 10, 358}, - dictWord{7, 10, 1637}, - dictWord{8, 10, 643}, - dictWord{139, 10, 483}, - dictWord{ - 5, - 0, - 486, - }, - dictWord{135, 0, 1349}, - dictWord{5, 11, 688}, - dictWord{135, 11, 712}, - dictWord{7, 0, 1635}, - dictWord{8, 0, 17}, - dictWord{10, 0, 217}, - dictWord{ - 10, - 0, - 295, - }, - dictWord{12, 0, 2}, - dictWord{140, 11, 2}, - dictWord{138, 0, 558}, - dictWord{150, 10, 56}, - dictWord{4, 11, 278}, - dictWord{5, 11, 465}, - dictWord{ - 135, - 11, - 1367, - }, - dictWord{136, 11, 482}, - dictWord{133, 10, 535}, - dictWord{6, 0, 1362}, - dictWord{6, 0, 1461}, - dictWord{10, 11, 274}, - dictWord{10, 11, 625}, - dictWord{139, 11, 530}, - dictWord{5, 0, 599}, - dictWord{5, 11, 336}, - dictWord{6, 11, 341}, - dictWord{6, 11, 478}, - dictWord{6, 11, 1763}, - dictWord{136, 11, 386}, - dictWord{7, 10, 1748}, - dictWord{137, 11, 151}, - dictWord{134, 0, 1376}, - dictWord{133, 10, 539}, - dictWord{135, 11, 73}, - dictWord{135, 11, 1971}, - dictWord{139, 11, 283}, - dictWord{9, 0, 93}, - dictWord{139, 0, 474}, - dictWord{6, 10, 91}, - dictWord{135, 10, 435}, - dictWord{6, 0, 447}, - dictWord{5, 11, 396}, - dictWord{134, 11, 501}, - dictWord{4, 10, 16}, - dictWord{5, 10, 316}, - dictWord{5, 10, 842}, - dictWord{6, 10, 370}, - dictWord{6, 10, 1778}, - dictWord{8, 10, 166}, - dictWord{11, 10, 812}, - dictWord{12, 10, 206}, - dictWord{12, 10, 351}, - dictWord{14, 10, 418}, - dictWord{16, 10, 15}, - dictWord{16, 10, 34}, - dictWord{18, 10, 3}, - dictWord{19, 10, 3}, - dictWord{19, 10, 7}, - dictWord{20, 10, 4}, - dictWord{149, 10, 21}, - dictWord{7, 0, 577}, - dictWord{7, 0, 1432}, - dictWord{9, 0, 475}, - dictWord{9, 0, 505}, - dictWord{9, 0, 526}, - dictWord{9, 0, 609}, - dictWord{9, 0, 689}, - dictWord{9, 0, 726}, - dictWord{9, 0, 735}, - dictWord{9, 0, 738}, - dictWord{10, 0, 556}, - dictWord{ - 10, - 0, - 674, - }, - dictWord{10, 0, 684}, - dictWord{11, 0, 89}, - dictWord{11, 0, 202}, - dictWord{11, 0, 272}, - dictWord{11, 0, 380}, - dictWord{11, 0, 415}, - dictWord{11, 0, 505}, - dictWord{11, 0, 537}, - dictWord{11, 0, 550}, - dictWord{11, 0, 562}, - dictWord{11, 0, 640}, - dictWord{11, 0, 667}, - dictWord{11, 0, 688}, - dictWord{11, 0, 847}, - dictWord{11, 0, 927}, - dictWord{11, 0, 930}, - dictWord{11, 0, 940}, - dictWord{12, 0, 144}, - dictWord{12, 0, 325}, - dictWord{12, 0, 329}, - dictWord{12, 0, 389}, - dictWord{ - 12, - 0, - 403, - }, - dictWord{12, 0, 451}, - dictWord{12, 0, 515}, - dictWord{12, 0, 604}, - dictWord{12, 0, 616}, - dictWord{12, 0, 626}, - dictWord{13, 0, 66}, - dictWord{ - 13, - 0, - 131, - }, - dictWord{13, 0, 167}, - dictWord{13, 0, 236}, - dictWord{13, 0, 368}, - dictWord{13, 0, 411}, - dictWord{13, 0, 434}, - dictWord{13, 0, 453}, - dictWord{13, 0, 461}, - dictWord{13, 0, 474}, - dictWord{14, 0, 59}, - dictWord{14, 0, 60}, - dictWord{14, 0, 139}, - dictWord{14, 0, 152}, - dictWord{14, 0, 276}, - dictWord{14, 0, 353}, - dictWord{ - 14, - 0, - 402, - }, - dictWord{15, 0, 28}, - dictWord{15, 0, 81}, - dictWord{15, 0, 123}, - dictWord{15, 0, 152}, - dictWord{18, 0, 136}, - dictWord{148, 0, 88}, - dictWord{ - 4, - 11, - 929, - }, - dictWord{133, 11, 799}, - dictWord{136, 11, 46}, - dictWord{142, 0, 307}, - dictWord{4, 0, 609}, - dictWord{7, 0, 756}, - dictWord{9, 0, 544}, - dictWord{ - 11, - 0, - 413, - }, - dictWord{144, 0, 25}, - dictWord{10, 0, 687}, - dictWord{7, 10, 619}, - dictWord{10, 10, 547}, - dictWord{11, 10, 122}, - dictWord{140, 10, 601}, - dictWord{ - 4, - 0, - 930, - }, - dictWord{133, 0, 947}, - dictWord{133, 0, 939}, - dictWord{142, 0, 21}, - dictWord{4, 11, 892}, - dictWord{133, 11, 770}, - dictWord{133, 0, 962}, - dictWord{ - 5, - 0, - 651, - }, - dictWord{8, 0, 170}, - dictWord{9, 0, 61}, - dictWord{9, 0, 63}, - dictWord{10, 0, 23}, - dictWord{10, 0, 37}, - dictWord{10, 0, 834}, - dictWord{11, 0, 4}, - dictWord{ - 11, - 0, - 187, - }, - dictWord{11, 0, 281}, - dictWord{11, 0, 503}, - dictWord{11, 0, 677}, - dictWord{12, 0, 96}, - dictWord{12, 0, 130}, - dictWord{12, 0, 244}, - dictWord{14, 0, 5}, - dictWord{14, 0, 40}, - dictWord{14, 0, 162}, - dictWord{14, 0, 202}, - dictWord{146, 0, 133}, - dictWord{4, 0, 406}, - dictWord{5, 0, 579}, - dictWord{12, 0, 492}, - dictWord{ - 150, - 0, - 15, - }, - dictWord{135, 11, 158}, - dictWord{135, 0, 597}, - dictWord{132, 0, 981}, - dictWord{132, 10, 888}, - dictWord{4, 10, 149}, - dictWord{138, 10, 368}, - dictWord{132, 0, 545}, - dictWord{4, 10, 154}, - dictWord{7, 10, 1134}, - dictWord{136, 10, 105}, - dictWord{135, 11, 2001}, - dictWord{134, 0, 1558}, - dictWord{ - 4, - 10, - 31, - }, - dictWord{6, 10, 429}, - dictWord{7, 10, 962}, - dictWord{9, 10, 458}, - dictWord{139, 10, 691}, - dictWord{132, 10, 312}, - dictWord{135, 10, 1642}, - dictWord{ - 6, - 0, - 17, - }, - dictWord{6, 0, 1304}, - dictWord{7, 0, 16}, - dictWord{7, 0, 1001}, - dictWord{9, 0, 886}, - dictWord{10, 0, 489}, - dictWord{10, 0, 800}, - dictWord{11, 0, 782}, - dictWord{12, 0, 320}, - dictWord{13, 0, 467}, - dictWord{14, 0, 145}, - dictWord{14, 0, 387}, - dictWord{143, 0, 119}, - dictWord{135, 0, 1982}, - dictWord{17, 0, 17}, - dictWord{7, 11, 1461}, - dictWord{140, 11, 91}, - dictWord{4, 10, 236}, - dictWord{132, 11, 602}, - dictWord{138, 0, 907}, - dictWord{136, 0, 110}, - dictWord{7, 0, 272}, - dictWord{19, 0, 53}, - dictWord{5, 10, 836}, - dictWord{5, 10, 857}, - dictWord{134, 10, 1680}, - dictWord{5, 0, 458}, - dictWord{7, 11, 1218}, - dictWord{136, 11, 303}, - dictWord{7, 0, 1983}, - dictWord{8, 0, 0}, - dictWord{8, 0, 171}, - dictWord{9, 0, 120}, - dictWord{9, 0, 732}, - dictWord{10, 0, 473}, - dictWord{11, 0, 656}, - dictWord{ - 11, - 0, - 998, - }, - dictWord{18, 0, 0}, - dictWord{18, 0, 2}, - dictWord{19, 0, 21}, - dictWord{10, 10, 68}, - dictWord{139, 10, 494}, - dictWord{137, 11, 662}, - dictWord{4, 11, 13}, - dictWord{5, 11, 567}, - dictWord{7, 11, 1498}, - dictWord{9, 11, 124}, - dictWord{11, 11, 521}, - dictWord{140, 11, 405}, - dictWord{4, 10, 81}, - dictWord{139, 10, 867}, - dictWord{135, 11, 1006}, - dictWord{7, 11, 800}, - dictWord{7, 11, 1783}, - dictWord{138, 11, 12}, - dictWord{9, 0, 295}, - dictWord{10, 0, 443}, - dictWord{ - 5, - 10, - 282, - }, - dictWord{8, 10, 650}, - dictWord{137, 10, 907}, - dictWord{132, 11, 735}, - dictWord{4, 11, 170}, - dictWord{4, 10, 775}, - dictWord{135, 11, 323}, - dictWord{ - 6, - 0, - 1844, - }, - dictWord{10, 0, 924}, - dictWord{11, 11, 844}, - dictWord{12, 11, 104}, - dictWord{140, 11, 625}, - dictWord{5, 11, 304}, - dictWord{7, 11, 1403}, - dictWord{140, 11, 498}, - dictWord{134, 0, 1232}, - dictWord{4, 0, 519}, - dictWord{10, 0, 70}, - dictWord{12, 0, 26}, - dictWord{14, 0, 17}, - dictWord{14, 0, 178}, - dictWord{ - 15, - 0, - 34, - }, - dictWord{149, 0, 12}, - dictWord{132, 0, 993}, - dictWord{4, 11, 148}, - dictWord{133, 11, 742}, - dictWord{6, 0, 31}, - dictWord{7, 0, 491}, - dictWord{7, 0, 530}, - dictWord{8, 0, 592}, - dictWord{11, 0, 53}, - dictWord{11, 0, 779}, - dictWord{12, 0, 167}, - dictWord{12, 0, 411}, - dictWord{14, 0, 14}, - dictWord{14, 0, 136}, - dictWord{ - 15, - 0, - 72, - }, - dictWord{16, 0, 17}, - dictWord{144, 0, 72}, - dictWord{133, 0, 907}, - dictWord{134, 0, 733}, - dictWord{133, 11, 111}, - dictWord{4, 10, 71}, - dictWord{ - 5, - 10, - 376, - }, - dictWord{7, 10, 119}, - dictWord{138, 10, 665}, - dictWord{136, 0, 55}, - dictWord{8, 0, 430}, - dictWord{136, 11, 430}, - dictWord{4, 0, 208}, - dictWord{ - 5, - 0, - 106, - }, - dictWord{6, 0, 531}, - dictWord{8, 0, 408}, - dictWord{9, 0, 188}, - dictWord{138, 0, 572}, - dictWord{12, 0, 56}, - dictWord{11, 10, 827}, - dictWord{14, 10, 34}, - dictWord{143, 10, 148}, - dictWord{134, 0, 1693}, - dictWord{133, 11, 444}, - dictWord{132, 10, 479}, - dictWord{140, 0, 441}, - dictWord{9, 0, 449}, - dictWord{ - 10, - 0, - 192, - }, - dictWord{138, 0, 740}, - dictWord{134, 0, 928}, - dictWord{4, 0, 241}, - dictWord{7, 10, 607}, - dictWord{136, 10, 99}, - dictWord{8, 11, 123}, - dictWord{ - 15, - 11, - 6, - }, - dictWord{144, 11, 7}, - dictWord{6, 11, 285}, - dictWord{8, 11, 654}, - dictWord{11, 11, 749}, - dictWord{12, 11, 190}, - dictWord{12, 11, 327}, - dictWord{ - 13, - 11, - 120, - }, - dictWord{13, 11, 121}, - dictWord{13, 11, 327}, - dictWord{15, 11, 47}, - dictWord{146, 11, 40}, - dictWord{4, 10, 41}, - dictWord{5, 10, 74}, - dictWord{ - 7, - 10, - 1627, - }, - dictWord{11, 10, 871}, - dictWord{140, 10, 619}, - dictWord{7, 0, 1525}, - dictWord{11, 10, 329}, - dictWord{11, 10, 965}, - dictWord{12, 10, 241}, - dictWord{14, 10, 354}, - dictWord{15, 10, 22}, - dictWord{148, 10, 63}, - dictWord{132, 0, 259}, - dictWord{135, 11, 183}, - dictWord{9, 10, 209}, - dictWord{ - 137, - 10, - 300, - }, - dictWord{5, 11, 937}, - dictWord{135, 11, 100}, - dictWord{133, 10, 98}, - dictWord{4, 0, 173}, - dictWord{5, 0, 312}, - dictWord{5, 0, 512}, - dictWord{ - 135, - 0, - 1285, - }, - dictWord{141, 0, 185}, - dictWord{7, 0, 1603}, - dictWord{7, 0, 1691}, - dictWord{9, 0, 464}, - dictWord{11, 0, 195}, - dictWord{12, 0, 279}, - dictWord{ - 12, - 0, - 448, - }, - dictWord{14, 0, 11}, - dictWord{147, 0, 102}, - dictWord{135, 0, 1113}, - dictWord{133, 10, 984}, - dictWord{4, 0, 452}, - dictWord{5, 0, 583}, - dictWord{ - 135, - 0, - 720, - }, - dictWord{4, 0, 547}, - dictWord{5, 0, 817}, - dictWord{6, 0, 433}, - dictWord{7, 0, 593}, - dictWord{7, 0, 1378}, - dictWord{8, 0, 161}, - dictWord{9, 0, 284}, - dictWord{ - 10, - 0, - 313, - }, - dictWord{139, 0, 886}, - dictWord{8, 0, 722}, - dictWord{4, 10, 182}, - dictWord{6, 10, 205}, - dictWord{135, 10, 220}, - dictWord{150, 0, 13}, - dictWord{ - 4, - 10, - 42, - }, - dictWord{9, 10, 205}, - dictWord{9, 10, 786}, - dictWord{138, 10, 659}, - dictWord{6, 0, 289}, - dictWord{7, 0, 1670}, - dictWord{12, 0, 57}, - dictWord{151, 0, 4}, - dictWord{132, 10, 635}, - dictWord{14, 0, 43}, - dictWord{146, 0, 21}, - dictWord{139, 10, 533}, - dictWord{135, 0, 1694}, - dictWord{8, 0, 420}, - dictWord{ - 139, - 0, - 193, - }, - dictWord{135, 0, 409}, - dictWord{132, 10, 371}, - dictWord{4, 10, 272}, - dictWord{135, 10, 836}, - dictWord{5, 10, 825}, - dictWord{134, 10, 1640}, - dictWord{5, 11, 251}, - dictWord{5, 11, 956}, - dictWord{8, 11, 268}, - dictWord{9, 11, 214}, - dictWord{146, 11, 142}, - dictWord{138, 0, 308}, - dictWord{6, 0, 1863}, - dictWord{141, 11, 37}, - dictWord{137, 10, 879}, - dictWord{7, 10, 317}, - dictWord{135, 10, 569}, - dictWord{132, 11, 294}, - dictWord{134, 0, 790}, - dictWord{ - 5, - 0, - 1002, - }, - dictWord{136, 0, 745}, - dictWord{5, 11, 346}, - dictWord{5, 11, 711}, - dictWord{136, 11, 390}, - dictWord{135, 0, 289}, - dictWord{5, 0, 504}, - dictWord{ - 11, - 0, - 68, - }, - dictWord{137, 10, 307}, - dictWord{4, 0, 239}, - dictWord{6, 0, 477}, - dictWord{7, 0, 1607}, - dictWord{139, 0, 617}, - dictWord{149, 0, 13}, - dictWord{ - 133, - 0, - 609, - }, - dictWord{133, 11, 624}, - dictWord{5, 11, 783}, - dictWord{7, 11, 1998}, - dictWord{135, 11, 2047}, - dictWord{133, 10, 525}, - dictWord{132, 0, 367}, - dictWord{132, 11, 594}, - dictWord{6, 0, 528}, - dictWord{133, 10, 493}, - dictWord{4, 10, 174}, - dictWord{135, 10, 911}, - dictWord{8, 10, 417}, - dictWord{ - 137, - 10, - 782, - }, - dictWord{132, 0, 694}, - dictWord{7, 0, 548}, - dictWord{137, 0, 58}, - dictWord{4, 10, 32}, - dictWord{5, 10, 215}, - dictWord{6, 10, 269}, - dictWord{7, 10, 1782}, - dictWord{7, 10, 1892}, - dictWord{10, 10, 16}, - dictWord{11, 10, 822}, - dictWord{11, 10, 954}, - dictWord{141, 10, 481}, - dictWord{140, 0, 687}, - dictWord{ - 7, - 0, - 1749, - }, - dictWord{136, 10, 477}, - dictWord{132, 11, 569}, - dictWord{133, 10, 308}, - dictWord{135, 10, 1088}, - dictWord{4, 0, 661}, - dictWord{138, 0, 1004}, - dictWord{5, 11, 37}, - dictWord{6, 11, 39}, - dictWord{6, 11, 451}, - dictWord{7, 11, 218}, - dictWord{7, 11, 667}, - dictWord{7, 11, 1166}, - dictWord{7, 11, 1687}, - dictWord{8, 11, 662}, - dictWord{144, 11, 2}, - dictWord{9, 0, 445}, - dictWord{12, 0, 53}, - dictWord{13, 0, 492}, - dictWord{5, 10, 126}, - dictWord{8, 10, 297}, - dictWord{ - 9, - 10, - 366, - }, - dictWord{140, 10, 374}, - dictWord{7, 10, 1551}, - dictWord{139, 10, 361}, - dictWord{148, 0, 74}, - dictWord{134, 11, 508}, - dictWord{135, 0, 213}, - dictWord{132, 10, 175}, - dictWord{132, 10, 685}, - dictWord{6, 0, 760}, - dictWord{6, 0, 834}, - dictWord{134, 0, 1248}, - dictWord{7, 11, 453}, - dictWord{7, 11, 635}, - dictWord{7, 11, 796}, - dictWord{8, 11, 331}, - dictWord{9, 11, 328}, - dictWord{9, 11, 330}, - dictWord{9, 11, 865}, - dictWord{10, 11, 119}, - dictWord{10, 11, 235}, - dictWord{11, 11, 111}, - dictWord{11, 11, 129}, - dictWord{11, 11, 240}, - dictWord{12, 11, 31}, - dictWord{12, 11, 66}, - dictWord{12, 11, 222}, - dictWord{12, 11, 269}, - dictWord{12, 11, 599}, - dictWord{12, 11, 689}, - dictWord{13, 11, 186}, - dictWord{13, 11, 364}, - dictWord{142, 11, 345}, - dictWord{7, 0, 1672}, - dictWord{ - 139, - 0, - 189, - }, - dictWord{133, 10, 797}, - dictWord{133, 10, 565}, - dictWord{6, 0, 1548}, - dictWord{6, 11, 98}, - dictWord{7, 11, 585}, - dictWord{135, 11, 702}, - dictWord{ - 9, - 0, - 968, - }, - dictWord{15, 0, 192}, - dictWord{149, 0, 56}, - dictWord{4, 10, 252}, - dictWord{6, 11, 37}, - dictWord{7, 11, 299}, - dictWord{7, 10, 1068}, - dictWord{ - 7, - 11, - 1666, - }, - dictWord{8, 11, 195}, - dictWord{8, 11, 316}, - dictWord{9, 11, 178}, - dictWord{9, 11, 276}, - dictWord{9, 11, 339}, - dictWord{9, 11, 536}, - dictWord{ - 10, - 11, - 102, - }, - dictWord{10, 11, 362}, - dictWord{10, 10, 434}, - dictWord{10, 11, 785}, - dictWord{11, 11, 55}, - dictWord{11, 11, 149}, - dictWord{11, 10, 228}, - dictWord{ - 11, - 10, - 426, - }, - dictWord{11, 11, 773}, - dictWord{13, 10, 231}, - dictWord{13, 11, 416}, - dictWord{13, 11, 419}, - dictWord{14, 11, 38}, - dictWord{14, 11, 41}, - dictWord{14, 11, 210}, - dictWord{18, 10, 106}, - dictWord{148, 10, 87}, - dictWord{4, 0, 751}, - dictWord{11, 0, 390}, - dictWord{140, 0, 32}, - dictWord{4, 0, 409}, - dictWord{133, 0, 78}, - dictWord{11, 11, 458}, - dictWord{12, 11, 15}, - dictWord{140, 11, 432}, - dictWord{7, 0, 1602}, - dictWord{10, 0, 257}, - dictWord{10, 0, 698}, - dictWord{11, 0, 544}, - dictWord{11, 0, 585}, - dictWord{12, 0, 212}, - dictWord{13, 0, 307}, - dictWord{5, 10, 231}, - dictWord{7, 10, 601}, - dictWord{9, 10, 277}, - dictWord{ - 9, - 10, - 674, - }, - dictWord{10, 10, 178}, - dictWord{10, 10, 418}, - dictWord{10, 10, 509}, - dictWord{11, 10, 531}, - dictWord{12, 10, 113}, - dictWord{12, 10, 475}, - dictWord{13, 10, 99}, - dictWord{142, 10, 428}, - dictWord{6, 0, 473}, - dictWord{145, 0, 105}, - dictWord{6, 0, 1949}, - dictWord{15, 0, 156}, - dictWord{133, 11, 645}, - dictWord{7, 10, 1591}, - dictWord{144, 10, 43}, - dictWord{135, 0, 1779}, - dictWord{135, 10, 1683}, - dictWord{4, 11, 290}, - dictWord{135, 11, 1356}, - dictWord{134, 0, 763}, - dictWord{6, 11, 70}, - dictWord{7, 11, 1292}, - dictWord{10, 11, 762}, - dictWord{139, 11, 288}, - dictWord{142, 0, 29}, - dictWord{140, 11, 428}, - dictWord{7, 0, 883}, - dictWord{7, 11, 131}, - dictWord{7, 11, 422}, - dictWord{8, 11, 210}, - dictWord{140, 11, 573}, - dictWord{134, 0, 488}, - dictWord{4, 10, 399}, - dictWord{5, 10, 119}, - dictWord{5, 10, 494}, - dictWord{7, 10, 751}, - dictWord{137, 10, 556}, - dictWord{133, 0, 617}, - dictWord{132, 11, 936}, - dictWord{ - 139, - 0, - 50, - }, - dictWord{7, 0, 1518}, - dictWord{139, 0, 694}, - dictWord{137, 0, 785}, - dictWord{4, 0, 546}, - dictWord{135, 0, 2042}, - dictWord{7, 11, 716}, - dictWord{ - 13, - 11, - 97, - }, - dictWord{141, 11, 251}, - dictWord{132, 11, 653}, - dictWord{145, 0, 22}, - dictWord{134, 0, 1016}, - dictWord{4, 0, 313}, - dictWord{133, 0, 577}, - dictWord{ - 136, - 11, - 657, - }, - dictWord{8, 0, 184}, - dictWord{141, 0, 433}, - dictWord{135, 0, 935}, - dictWord{6, 0, 720}, - dictWord{9, 0, 114}, - dictWord{146, 11, 80}, - dictWord{ - 12, - 0, - 186, - }, - dictWord{12, 0, 292}, - dictWord{14, 0, 100}, - dictWord{18, 0, 70}, - dictWord{7, 10, 594}, - dictWord{7, 10, 851}, - dictWord{7, 10, 1858}, - dictWord{ - 9, - 10, - 411, - }, - dictWord{9, 10, 574}, - dictWord{9, 10, 666}, - dictWord{9, 10, 737}, - dictWord{10, 10, 346}, - dictWord{10, 10, 712}, - dictWord{11, 10, 246}, - dictWord{ - 11, - 10, - 432, - }, - dictWord{11, 10, 517}, - dictWord{11, 10, 647}, - dictWord{11, 10, 679}, - dictWord{11, 10, 727}, - dictWord{12, 10, 304}, - dictWord{12, 10, 305}, - dictWord{12, 10, 323}, - dictWord{12, 10, 483}, - dictWord{12, 10, 572}, - dictWord{12, 10, 593}, - dictWord{12, 10, 602}, - dictWord{13, 10, 95}, - dictWord{13, 10, 101}, - dictWord{13, 10, 171}, - dictWord{13, 10, 315}, - dictWord{13, 10, 378}, - dictWord{13, 10, 425}, - dictWord{13, 10, 475}, - dictWord{14, 10, 63}, - dictWord{ - 14, - 10, - 380, - }, - dictWord{14, 10, 384}, - dictWord{15, 10, 133}, - dictWord{18, 10, 112}, - dictWord{148, 10, 72}, - dictWord{135, 10, 1093}, - dictWord{135, 11, 1836}, - dictWord{132, 10, 679}, - dictWord{137, 10, 203}, - dictWord{11, 0, 402}, - dictWord{12, 0, 109}, - dictWord{12, 0, 431}, - dictWord{13, 0, 179}, - dictWord{13, 0, 206}, - dictWord{14, 0, 217}, - dictWord{16, 0, 3}, - dictWord{148, 0, 53}, - dictWord{7, 11, 1368}, - dictWord{8, 11, 232}, - dictWord{8, 11, 361}, - dictWord{10, 11, 682}, - dictWord{138, 11, 742}, - dictWord{137, 10, 714}, - dictWord{5, 0, 886}, - dictWord{6, 0, 46}, - dictWord{6, 0, 1790}, - dictWord{7, 0, 14}, - dictWord{7, 0, 732}, - dictWord{ - 7, - 0, - 1654, - }, - dictWord{8, 0, 95}, - dictWord{8, 0, 327}, - dictWord{8, 0, 616}, - dictWord{9, 0, 892}, - dictWord{10, 0, 598}, - dictWord{10, 0, 769}, - dictWord{11, 0, 134}, - dictWord{11, 0, 747}, - dictWord{12, 0, 378}, - dictWord{14, 0, 97}, - dictWord{137, 11, 534}, - dictWord{4, 0, 969}, - dictWord{136, 10, 825}, - dictWord{137, 11, 27}, - dictWord{6, 0, 727}, - dictWord{142, 11, 12}, - dictWord{133, 0, 1021}, - dictWord{134, 0, 1190}, - dictWord{134, 11, 1657}, - dictWord{5, 10, 143}, - dictWord{ - 5, - 10, - 769, - }, - dictWord{6, 10, 1760}, - dictWord{7, 10, 682}, - dictWord{7, 10, 1992}, - dictWord{136, 10, 736}, - dictWord{132, 0, 153}, - dictWord{135, 11, 127}, - dictWord{133, 0, 798}, - dictWord{132, 0, 587}, - dictWord{6, 0, 598}, - dictWord{7, 0, 42}, - dictWord{8, 0, 695}, - dictWord{10, 0, 212}, - dictWord{11, 0, 158}, - dictWord{ - 14, - 0, - 196, - }, - dictWord{145, 0, 85}, - dictWord{133, 10, 860}, - dictWord{6, 0, 1929}, - dictWord{134, 0, 1933}, - dictWord{5, 0, 957}, - dictWord{5, 0, 1008}, - dictWord{ - 9, - 0, - 577, - }, - dictWord{12, 0, 141}, - dictWord{6, 10, 422}, - dictWord{7, 10, 0}, - dictWord{7, 10, 1544}, - dictWord{8, 11, 364}, - dictWord{11, 10, 990}, - dictWord{ - 12, - 10, - 453, - }, - dictWord{13, 10, 47}, - dictWord{141, 10, 266}, - dictWord{134, 0, 1319}, - dictWord{4, 0, 129}, - dictWord{135, 0, 465}, - dictWord{7, 0, 470}, - dictWord{ - 7, - 0, - 1057, - }, - dictWord{7, 0, 1201}, - dictWord{9, 0, 755}, - dictWord{11, 0, 906}, - dictWord{140, 0, 527}, - dictWord{7, 0, 908}, - dictWord{146, 0, 7}, - dictWord{5, 0, 148}, - dictWord{136, 0, 450}, - dictWord{5, 10, 515}, - dictWord{137, 10, 131}, - dictWord{7, 10, 1605}, - dictWord{11, 10, 962}, - dictWord{146, 10, 139}, - dictWord{ - 132, - 10, - 646, - }, - dictWord{134, 0, 1166}, - dictWord{4, 10, 396}, - dictWord{7, 10, 728}, - dictWord{9, 10, 117}, - dictWord{13, 10, 202}, - dictWord{148, 10, 51}, - dictWord{ - 6, - 10, - 121, - }, - dictWord{6, 10, 124}, - dictWord{6, 10, 357}, - dictWord{7, 10, 1138}, - dictWord{7, 10, 1295}, - dictWord{8, 10, 162}, - dictWord{139, 10, 655}, - dictWord{14, 0, 374}, - dictWord{142, 11, 374}, - dictWord{138, 0, 253}, - dictWord{139, 0, 1003}, - dictWord{5, 11, 909}, - dictWord{9, 11, 849}, - dictWord{ - 138, - 11, - 805, - }, - dictWord{133, 10, 237}, - dictWord{7, 11, 525}, - dictWord{7, 11, 1579}, - dictWord{8, 11, 497}, - dictWord{136, 11, 573}, - dictWord{137, 0, 46}, - dictWord{ - 132, - 0, - 879, - }, - dictWord{134, 0, 806}, - dictWord{135, 0, 1868}, - dictWord{6, 0, 1837}, - dictWord{134, 0, 1846}, - dictWord{6, 0, 730}, - dictWord{134, 0, 881}, - dictWord{7, 0, 965}, - dictWord{7, 0, 1460}, - dictWord{7, 0, 1604}, - dictWord{7, 11, 193}, - dictWord{7, 11, 397}, - dictWord{7, 11, 1105}, - dictWord{8, 11, 124}, - dictWord{ - 8, - 11, - 619, - }, - dictWord{9, 11, 305}, - dictWord{10, 11, 264}, - dictWord{11, 11, 40}, - dictWord{12, 11, 349}, - dictWord{13, 11, 134}, - dictWord{13, 11, 295}, - dictWord{14, 11, 155}, - dictWord{15, 11, 120}, - dictWord{146, 11, 105}, - dictWord{136, 0, 506}, - dictWord{143, 0, 10}, - dictWord{4, 11, 262}, - dictWord{7, 11, 342}, - dictWord{7, 10, 571}, - dictWord{7, 10, 1877}, - dictWord{10, 10, 366}, - dictWord{141, 11, 23}, - dictWord{133, 11, 641}, - dictWord{10, 0, 22}, - dictWord{9, 10, 513}, - dictWord{10, 10, 39}, - dictWord{12, 10, 122}, - dictWord{140, 10, 187}, - dictWord{135, 11, 1431}, - dictWord{150, 11, 49}, - dictWord{4, 11, 99}, - dictWord{ - 6, - 11, - 250, - }, - dictWord{6, 11, 346}, - dictWord{8, 11, 127}, - dictWord{138, 11, 81}, - dictWord{6, 0, 2014}, - dictWord{8, 0, 928}, - dictWord{10, 0, 960}, - dictWord{10, 0, 979}, - dictWord{140, 0, 996}, - dictWord{134, 0, 296}, - dictWord{132, 11, 915}, - dictWord{5, 11, 75}, - dictWord{9, 11, 517}, - dictWord{10, 11, 470}, - dictWord{ - 12, - 11, - 155, - }, - dictWord{141, 11, 224}, - dictWord{137, 10, 873}, - dictWord{4, 0, 854}, - dictWord{140, 11, 18}, - dictWord{134, 0, 587}, - dictWord{7, 10, 107}, - dictWord{ - 7, - 10, - 838, - }, - dictWord{8, 10, 550}, - dictWord{138, 10, 401}, - dictWord{11, 0, 636}, - dictWord{15, 0, 145}, - dictWord{17, 0, 34}, - dictWord{19, 0, 50}, - dictWord{ - 23, - 0, - 20, - }, - dictWord{11, 10, 588}, - dictWord{11, 10, 864}, - dictWord{11, 10, 968}, - dictWord{143, 10, 160}, - dictWord{135, 11, 216}, - dictWord{7, 0, 982}, - dictWord{ - 10, - 0, - 32, - }, - dictWord{143, 0, 56}, - dictWord{133, 10, 768}, - dictWord{133, 11, 954}, - dictWord{6, 11, 304}, - dictWord{7, 11, 1114}, - dictWord{8, 11, 418}, - dictWord{ - 10, - 11, - 345, - }, - dictWord{11, 11, 341}, - dictWord{11, 11, 675}, - dictWord{141, 11, 40}, - dictWord{9, 11, 410}, - dictWord{139, 11, 425}, - dictWord{136, 0, 941}, - dictWord{5, 0, 435}, - dictWord{132, 10, 894}, - dictWord{5, 0, 85}, - dictWord{6, 0, 419}, - dictWord{7, 0, 134}, - dictWord{7, 0, 305}, - dictWord{7, 0, 361}, - dictWord{ - 7, - 0, - 1337, - }, - dictWord{8, 0, 71}, - dictWord{140, 0, 519}, - dictWord{140, 0, 688}, - dictWord{135, 0, 740}, - dictWord{5, 0, 691}, - dictWord{7, 0, 345}, - dictWord{9, 0, 94}, - dictWord{140, 0, 169}, - dictWord{5, 0, 183}, - dictWord{6, 0, 582}, - dictWord{10, 0, 679}, - dictWord{140, 0, 435}, - dictWord{134, 11, 14}, - dictWord{6, 0, 945}, - dictWord{135, 0, 511}, - dictWord{134, 11, 1708}, - dictWord{5, 11, 113}, - dictWord{6, 11, 243}, - dictWord{7, 11, 1865}, - dictWord{11, 11, 161}, - dictWord{16, 11, 37}, - dictWord{145, 11, 99}, - dictWord{132, 11, 274}, - dictWord{137, 0, 539}, - dictWord{7, 0, 1993}, - dictWord{8, 0, 684}, - dictWord{134, 10, 272}, - dictWord{ - 6, - 0, - 659, - }, - dictWord{134, 0, 982}, - dictWord{4, 10, 9}, - dictWord{5, 10, 128}, - dictWord{7, 10, 368}, - dictWord{11, 10, 480}, - dictWord{148, 10, 3}, - dictWord{ - 134, - 0, - 583, - }, - dictWord{132, 0, 803}, - dictWord{133, 0, 704}, - dictWord{4, 0, 179}, - dictWord{5, 0, 198}, - dictWord{133, 0, 697}, - dictWord{7, 0, 347}, - dictWord{7, 0, 971}, - dictWord{8, 0, 181}, - dictWord{10, 0, 711}, - dictWord{135, 11, 166}, - dictWord{136, 10, 682}, - dictWord{4, 10, 2}, - dictWord{7, 10, 545}, - dictWord{7, 10, 894}, - dictWord{136, 11, 521}, - dictWord{135, 0, 481}, - dictWord{132, 0, 243}, - dictWord{5, 0, 203}, - dictWord{7, 0, 19}, - dictWord{7, 0, 71}, - dictWord{7, 0, 113}, - dictWord{ - 10, - 0, - 405, - }, - dictWord{11, 0, 357}, - dictWord{142, 0, 240}, - dictWord{5, 11, 725}, - dictWord{5, 11, 727}, - dictWord{135, 11, 1811}, - dictWord{6, 0, 826}, - dictWord{ - 137, - 11, - 304, - }, - dictWord{7, 0, 1450}, - dictWord{139, 0, 99}, - dictWord{133, 11, 654}, - dictWord{134, 0, 492}, - dictWord{5, 0, 134}, - dictWord{6, 0, 408}, - dictWord{ - 6, - 0, - 495, - }, - dictWord{7, 0, 1593}, - dictWord{6, 11, 273}, - dictWord{10, 11, 188}, - dictWord{13, 11, 377}, - dictWord{146, 11, 77}, - dictWord{9, 10, 769}, - dictWord{ - 140, - 10, - 185, - }, - dictWord{135, 11, 410}, - dictWord{142, 0, 4}, - dictWord{4, 0, 665}, - dictWord{134, 11, 1785}, - dictWord{4, 0, 248}, - dictWord{7, 0, 137}, - dictWord{ - 137, - 0, - 349, - }, - dictWord{5, 10, 530}, - dictWord{142, 10, 113}, - dictWord{7, 0, 1270}, - dictWord{139, 0, 612}, - dictWord{132, 11, 780}, - dictWord{5, 0, 371}, - dictWord{135, 0, 563}, - dictWord{135, 0, 826}, - dictWord{6, 0, 1535}, - dictWord{23, 0, 21}, - dictWord{151, 0, 23}, - dictWord{4, 0, 374}, - dictWord{7, 0, 547}, - dictWord{ - 7, - 0, - 1700, - }, - dictWord{7, 0, 1833}, - dictWord{139, 0, 858}, - dictWord{133, 10, 556}, - dictWord{7, 11, 612}, - dictWord{8, 11, 545}, - dictWord{8, 11, 568}, - dictWord{ - 8, - 11, - 642, - }, - dictWord{9, 11, 717}, - dictWord{10, 11, 541}, - dictWord{10, 11, 763}, - dictWord{11, 11, 449}, - dictWord{12, 11, 489}, - dictWord{13, 11, 153}, - dictWord{ - 13, - 11, - 296, - }, - dictWord{14, 11, 138}, - dictWord{14, 11, 392}, - dictWord{15, 11, 50}, - dictWord{16, 11, 6}, - dictWord{16, 11, 12}, - dictWord{148, 11, 9}, - dictWord{ - 9, - 0, - 311, - }, - dictWord{141, 0, 42}, - dictWord{8, 10, 16}, - dictWord{140, 10, 568}, - dictWord{6, 0, 1968}, - dictWord{6, 0, 2027}, - dictWord{138, 0, 991}, - dictWord{ - 6, - 0, - 1647, - }, - dictWord{7, 0, 1552}, - dictWord{7, 0, 2010}, - dictWord{9, 0, 494}, - dictWord{137, 0, 509}, - dictWord{133, 11, 948}, - dictWord{6, 10, 186}, - dictWord{ - 137, - 10, - 426, - }, - dictWord{134, 0, 769}, - dictWord{134, 0, 642}, - dictWord{132, 10, 585}, - dictWord{6, 0, 123}, - dictWord{7, 0, 214}, - dictWord{9, 0, 728}, - dictWord{ - 10, - 0, - 157, - }, - dictWord{11, 0, 346}, - dictWord{11, 0, 662}, - dictWord{143, 0, 106}, - dictWord{142, 11, 381}, - dictWord{135, 0, 1435}, - dictWord{4, 11, 532}, - dictWord{ - 5, - 11, - 706, - }, - dictWord{135, 11, 662}, - dictWord{5, 11, 837}, - dictWord{134, 11, 1651}, - dictWord{4, 10, 93}, - dictWord{5, 10, 252}, - dictWord{6, 10, 229}, - dictWord{ - 7, - 10, - 291, - }, - dictWord{9, 10, 550}, - dictWord{139, 10, 644}, - dictWord{148, 0, 79}, - dictWord{137, 10, 749}, - dictWord{134, 0, 1425}, - dictWord{ - 137, - 10, - 162, - }, - dictWord{4, 11, 362}, - dictWord{7, 11, 52}, - dictWord{7, 11, 303}, - dictWord{140, 11, 166}, - dictWord{132, 10, 381}, - dictWord{4, 11, 330}, - dictWord{ - 7, - 11, - 933, - }, - dictWord{7, 11, 2012}, - dictWord{136, 11, 292}, - dictWord{135, 11, 767}, - dictWord{4, 0, 707}, - dictWord{5, 0, 588}, - dictWord{6, 0, 393}, - dictWord{ - 13, - 0, - 106, - }, - dictWord{18, 0, 49}, - dictWord{147, 0, 41}, - dictWord{6, 0, 211}, - dictWord{7, 0, 1690}, - dictWord{11, 0, 486}, - dictWord{140, 0, 369}, - dictWord{ - 137, - 11, - 883, - }, - dictWord{4, 11, 703}, - dictWord{135, 11, 207}, - dictWord{4, 0, 187}, - dictWord{5, 0, 184}, - dictWord{5, 0, 690}, - dictWord{7, 0, 1869}, - dictWord{10, 0, 756}, - dictWord{139, 0, 783}, - dictWord{132, 11, 571}, - dictWord{134, 0, 1382}, - dictWord{5, 0, 175}, - dictWord{6, 10, 77}, - dictWord{6, 10, 157}, - dictWord{7, 10, 974}, - dictWord{7, 10, 1301}, - dictWord{7, 10, 1339}, - dictWord{7, 10, 1490}, - dictWord{7, 10, 1873}, - dictWord{137, 10, 628}, - dictWord{134, 0, 1493}, - dictWord{ - 5, - 11, - 873, - }, - dictWord{133, 11, 960}, - dictWord{134, 0, 1007}, - dictWord{12, 11, 93}, - dictWord{12, 11, 501}, - dictWord{13, 11, 362}, - dictWord{14, 11, 151}, - dictWord{15, 11, 40}, - dictWord{15, 11, 59}, - dictWord{16, 11, 46}, - dictWord{17, 11, 25}, - dictWord{18, 11, 14}, - dictWord{18, 11, 134}, - dictWord{19, 11, 25}, - dictWord{ - 19, - 11, - 69, - }, - dictWord{20, 11, 16}, - dictWord{20, 11, 19}, - dictWord{20, 11, 66}, - dictWord{21, 11, 23}, - dictWord{21, 11, 25}, - dictWord{150, 11, 42}, - dictWord{ - 11, - 10, - 919, - }, - dictWord{141, 10, 409}, - dictWord{134, 0, 219}, - dictWord{5, 0, 582}, - dictWord{6, 0, 1646}, - dictWord{7, 0, 99}, - dictWord{7, 0, 1962}, - dictWord{ - 7, - 0, - 1986, - }, - dictWord{8, 0, 515}, - dictWord{8, 0, 773}, - dictWord{9, 0, 23}, - dictWord{9, 0, 491}, - dictWord{12, 0, 620}, - dictWord{142, 0, 93}, - dictWord{133, 0, 851}, - dictWord{5, 11, 33}, - dictWord{134, 11, 470}, - dictWord{135, 11, 1291}, - dictWord{134, 0, 1278}, - dictWord{135, 11, 1882}, - dictWord{135, 10, 1489}, - dictWord{132, 0, 1000}, - dictWord{138, 0, 982}, - dictWord{8, 0, 762}, - dictWord{8, 0, 812}, - dictWord{137, 0, 910}, - dictWord{6, 11, 47}, - dictWord{7, 11, 90}, - dictWord{ - 7, - 11, - 664, - }, - dictWord{7, 11, 830}, - dictWord{7, 11, 1380}, - dictWord{7, 11, 2025}, - dictWord{8, 11, 448}, - dictWord{136, 11, 828}, - dictWord{4, 0, 98}, - dictWord{ - 4, - 0, - 940, - }, - dictWord{6, 0, 1819}, - dictWord{6, 0, 1834}, - dictWord{6, 0, 1841}, - dictWord{7, 0, 1365}, - dictWord{8, 0, 859}, - dictWord{8, 0, 897}, - dictWord{8, 0, 918}, - dictWord{9, 0, 422}, - dictWord{9, 0, 670}, - dictWord{10, 0, 775}, - dictWord{10, 0, 894}, - dictWord{10, 0, 909}, - dictWord{10, 0, 910}, - dictWord{10, 0, 935}, - dictWord{ - 11, - 0, - 210, - }, - dictWord{12, 0, 750}, - dictWord{12, 0, 755}, - dictWord{13, 0, 26}, - dictWord{13, 0, 457}, - dictWord{13, 0, 476}, - dictWord{16, 0, 100}, - dictWord{16, 0, 109}, - dictWord{18, 0, 173}, - dictWord{18, 0, 175}, - dictWord{8, 10, 398}, - dictWord{9, 10, 681}, - dictWord{139, 10, 632}, - dictWord{9, 11, 417}, - dictWord{ - 137, - 11, - 493, - }, - dictWord{136, 10, 645}, - dictWord{138, 0, 906}, - dictWord{134, 0, 1730}, - dictWord{134, 10, 20}, - dictWord{133, 11, 1019}, - dictWord{134, 0, 1185}, - dictWord{10, 0, 40}, - dictWord{136, 10, 769}, - dictWord{9, 0, 147}, - dictWord{134, 11, 208}, - dictWord{140, 0, 650}, - dictWord{5, 0, 209}, - dictWord{6, 0, 30}, - dictWord{11, 0, 56}, - dictWord{139, 0, 305}, - dictWord{132, 0, 553}, - dictWord{138, 11, 344}, - dictWord{6, 11, 68}, - dictWord{7, 11, 398}, - dictWord{7, 11, 448}, - dictWord{ - 7, - 11, - 1629, - }, - dictWord{7, 11, 1813}, - dictWord{8, 11, 387}, - dictWord{8, 11, 442}, - dictWord{9, 11, 710}, - dictWord{10, 11, 282}, - dictWord{138, 11, 722}, - dictWord{5, 0, 597}, - dictWord{14, 0, 20}, - dictWord{142, 11, 20}, - dictWord{135, 0, 1614}, - dictWord{135, 10, 1757}, - dictWord{4, 0, 150}, - dictWord{5, 0, 303}, - dictWord{6, 0, 327}, - dictWord{135, 10, 937}, - dictWord{16, 0, 49}, - dictWord{7, 10, 1652}, - dictWord{144, 11, 49}, - dictWord{8, 0, 192}, - dictWord{10, 0, 78}, - dictWord{ - 141, - 0, - 359, - }, - dictWord{135, 0, 786}, - dictWord{143, 0, 134}, - dictWord{6, 0, 1638}, - dictWord{7, 0, 79}, - dictWord{7, 0, 496}, - dictWord{9, 0, 138}, - dictWord{ - 10, - 0, - 336, - }, - dictWord{11, 0, 12}, - dictWord{12, 0, 412}, - dictWord{12, 0, 440}, - dictWord{142, 0, 305}, - dictWord{136, 11, 491}, - dictWord{4, 10, 579}, - dictWord{ - 5, - 10, - 226, - }, - dictWord{5, 10, 323}, - dictWord{135, 10, 960}, - dictWord{7, 0, 204}, - dictWord{7, 0, 415}, - dictWord{8, 0, 42}, - dictWord{10, 0, 85}, - dictWord{139, 0, 564}, - dictWord{132, 0, 614}, - dictWord{4, 11, 403}, - dictWord{5, 11, 441}, - dictWord{7, 11, 450}, - dictWord{11, 11, 101}, - dictWord{12, 11, 193}, - dictWord{141, 11, 430}, - dictWord{135, 11, 1927}, - dictWord{135, 11, 1330}, - dictWord{4, 0, 3}, - dictWord{5, 0, 247}, - dictWord{5, 0, 644}, - dictWord{7, 0, 744}, - dictWord{7, 0, 1207}, - dictWord{7, 0, 1225}, - dictWord{7, 0, 1909}, - dictWord{146, 0, 147}, - dictWord{136, 0, 942}, - dictWord{4, 0, 1019}, - dictWord{134, 0, 2023}, - dictWord{5, 11, 679}, - dictWord{133, 10, 973}, - dictWord{5, 0, 285}, - dictWord{9, 0, 67}, - dictWord{13, 0, 473}, - dictWord{143, 0, 82}, - dictWord{7, 11, 328}, - dictWord{137, 11, 326}, - dictWord{151, 0, 8}, - dictWord{6, 10, 135}, - dictWord{135, 10, 1176}, - dictWord{135, 11, 1128}, - dictWord{134, 0, 1309}, - dictWord{135, 11, 1796}, - dictWord{ - 135, - 10, - 314, - }, - dictWord{4, 11, 574}, - dictWord{7, 11, 350}, - dictWord{7, 11, 1024}, - dictWord{8, 11, 338}, - dictWord{9, 11, 677}, - dictWord{10, 11, 808}, - dictWord{ - 139, - 11, - 508, - }, - dictWord{7, 11, 818}, - dictWord{17, 11, 14}, - dictWord{17, 11, 45}, - dictWord{18, 11, 75}, - dictWord{148, 11, 18}, - dictWord{146, 10, 4}, - dictWord{ - 135, - 11, - 1081, - }, - dictWord{4, 0, 29}, - dictWord{6, 0, 532}, - dictWord{7, 0, 1628}, - dictWord{7, 0, 1648}, - dictWord{9, 0, 350}, - dictWord{10, 0, 433}, - dictWord{11, 0, 97}, - dictWord{11, 0, 557}, - dictWord{11, 0, 745}, - dictWord{12, 0, 289}, - dictWord{12, 0, 335}, - dictWord{12, 0, 348}, - dictWord{12, 0, 606}, - dictWord{13, 0, 116}, - dictWord{13, 0, 233}, - dictWord{13, 0, 466}, - dictWord{14, 0, 181}, - dictWord{14, 0, 209}, - dictWord{14, 0, 232}, - dictWord{14, 0, 236}, - dictWord{14, 0, 300}, - dictWord{ - 16, - 0, - 41, - }, - dictWord{148, 0, 97}, - dictWord{7, 0, 318}, - dictWord{6, 10, 281}, - dictWord{8, 10, 282}, - dictWord{8, 10, 480}, - dictWord{8, 10, 499}, - dictWord{9, 10, 198}, - dictWord{10, 10, 143}, - dictWord{10, 10, 169}, - dictWord{10, 10, 211}, - dictWord{10, 10, 417}, - dictWord{10, 10, 574}, - dictWord{11, 10, 147}, - dictWord{ - 11, - 10, - 395, - }, - dictWord{12, 10, 75}, - dictWord{12, 10, 407}, - dictWord{12, 10, 608}, - dictWord{13, 10, 500}, - dictWord{142, 10, 251}, - dictWord{135, 11, 1676}, - dictWord{135, 11, 2037}, - dictWord{135, 0, 1692}, - dictWord{5, 0, 501}, - dictWord{7, 0, 1704}, - dictWord{9, 0, 553}, - dictWord{11, 0, 520}, - dictWord{12, 0, 557}, - dictWord{141, 0, 249}, - dictWord{6, 0, 1527}, - dictWord{14, 0, 324}, - dictWord{15, 0, 55}, - dictWord{15, 0, 80}, - dictWord{14, 11, 324}, - dictWord{15, 11, 55}, - dictWord{143, 11, 80}, - dictWord{135, 10, 1776}, - dictWord{8, 0, 988}, - dictWord{137, 11, 297}, - dictWord{132, 10, 419}, - dictWord{142, 0, 223}, - dictWord{ - 139, - 11, - 234, - }, - dictWord{7, 0, 1123}, - dictWord{12, 0, 508}, - dictWord{14, 0, 102}, - dictWord{14, 0, 226}, - dictWord{144, 0, 57}, - dictWord{4, 10, 138}, - dictWord{ - 7, - 10, - 1012, - }, - dictWord{7, 10, 1280}, - dictWord{137, 10, 76}, - dictWord{7, 0, 1764}, - dictWord{5, 10, 29}, - dictWord{140, 10, 638}, - dictWord{134, 0, 2015}, - dictWord{134, 0, 1599}, - dictWord{138, 11, 56}, - dictWord{6, 11, 306}, - dictWord{7, 11, 1140}, - dictWord{7, 11, 1340}, - dictWord{8, 11, 133}, - dictWord{ - 138, - 11, - 449, - }, - dictWord{139, 11, 1011}, - dictWord{6, 10, 1710}, - dictWord{135, 10, 2038}, - dictWord{7, 11, 1763}, - dictWord{140, 11, 310}, - dictWord{6, 0, 129}, - dictWord{4, 10, 17}, - dictWord{5, 10, 23}, - dictWord{7, 10, 995}, - dictWord{11, 10, 383}, - dictWord{11, 10, 437}, - dictWord{12, 10, 460}, - dictWord{140, 10, 532}, - dictWord{5, 11, 329}, - dictWord{136, 11, 260}, - dictWord{133, 10, 862}, - dictWord{132, 0, 534}, - dictWord{6, 0, 811}, - dictWord{135, 0, 626}, - dictWord{ - 132, - 11, - 657, - }, - dictWord{4, 0, 25}, - dictWord{5, 0, 60}, - dictWord{6, 0, 504}, - dictWord{7, 0, 614}, - dictWord{7, 0, 1155}, - dictWord{12, 0, 0}, - dictWord{152, 11, 7}, - dictWord{ - 7, - 0, - 1248, - }, - dictWord{11, 0, 621}, - dictWord{139, 0, 702}, - dictWord{137, 0, 321}, - dictWord{8, 10, 70}, - dictWord{12, 10, 171}, - dictWord{141, 10, 272}, - dictWord{ - 10, - 10, - 233, - }, - dictWord{139, 10, 76}, - dictWord{4, 0, 379}, - dictWord{7, 0, 1397}, - dictWord{134, 10, 442}, - dictWord{5, 11, 66}, - dictWord{7, 11, 1896}, - dictWord{ - 136, - 11, - 288, - }, - dictWord{134, 11, 1643}, - dictWord{134, 10, 1709}, - dictWord{4, 11, 21}, - dictWord{5, 11, 91}, - dictWord{5, 11, 570}, - dictWord{5, 11, 648}, - dictWord{5, 11, 750}, - dictWord{5, 11, 781}, - dictWord{6, 11, 54}, - dictWord{6, 11, 112}, - dictWord{6, 11, 402}, - dictWord{6, 11, 1732}, - dictWord{7, 11, 315}, - dictWord{ - 7, - 11, - 749, - }, - dictWord{7, 11, 1347}, - dictWord{7, 11, 1900}, - dictWord{9, 11, 78}, - dictWord{9, 11, 508}, - dictWord{10, 11, 611}, - dictWord{11, 11, 510}, - dictWord{ - 11, - 11, - 728, - }, - dictWord{13, 11, 36}, - dictWord{14, 11, 39}, - dictWord{16, 11, 83}, - dictWord{17, 11, 124}, - dictWord{148, 11, 30}, - dictWord{4, 0, 118}, - dictWord{ - 6, - 0, - 274, - }, - dictWord{6, 0, 361}, - dictWord{7, 0, 75}, - dictWord{141, 0, 441}, - dictWord{10, 11, 322}, - dictWord{10, 11, 719}, - dictWord{139, 11, 407}, - dictWord{ - 147, - 10, - 119, - }, - dictWord{12, 11, 549}, - dictWord{14, 11, 67}, - dictWord{147, 11, 60}, - dictWord{11, 10, 69}, - dictWord{12, 10, 105}, - dictWord{12, 10, 117}, - dictWord{13, 10, 213}, - dictWord{14, 10, 13}, - dictWord{14, 10, 62}, - dictWord{14, 10, 177}, - dictWord{14, 10, 421}, - dictWord{15, 10, 19}, - dictWord{146, 10, 141}, - dictWord{9, 0, 841}, - dictWord{137, 10, 309}, - dictWord{7, 10, 608}, - dictWord{7, 10, 976}, - dictWord{8, 11, 125}, - dictWord{8, 11, 369}, - dictWord{8, 11, 524}, - dictWord{9, 10, 146}, - dictWord{10, 10, 206}, - dictWord{10, 11, 486}, - dictWord{10, 10, 596}, - dictWord{11, 11, 13}, - dictWord{11, 11, 381}, - dictWord{11, 11, 736}, - dictWord{11, 11, 766}, - dictWord{11, 11, 845}, - dictWord{13, 11, 114}, - dictWord{13, 10, 218}, - dictWord{13, 11, 292}, - dictWord{14, 11, 47}, - dictWord{ - 142, - 10, - 153, - }, - dictWord{12, 0, 693}, - dictWord{135, 11, 759}, - dictWord{5, 0, 314}, - dictWord{6, 0, 221}, - dictWord{7, 0, 419}, - dictWord{10, 0, 650}, - dictWord{11, 0, 396}, - dictWord{12, 0, 156}, - dictWord{13, 0, 369}, - dictWord{14, 0, 333}, - dictWord{145, 0, 47}, - dictWord{6, 11, 1684}, - dictWord{6, 11, 1731}, - dictWord{7, 11, 356}, - dictWord{7, 11, 1932}, - dictWord{8, 11, 54}, - dictWord{8, 11, 221}, - dictWord{9, 11, 225}, - dictWord{9, 11, 356}, - dictWord{10, 11, 77}, - dictWord{10, 11, 446}, - dictWord{10, 11, 731}, - dictWord{12, 11, 404}, - dictWord{141, 11, 491}, - dictWord{132, 11, 375}, - dictWord{4, 10, 518}, - dictWord{135, 10, 1136}, - dictWord{ - 4, - 0, - 913, - }, - dictWord{4, 11, 411}, - dictWord{11, 11, 643}, - dictWord{140, 11, 115}, - dictWord{4, 11, 80}, - dictWord{133, 11, 44}, - dictWord{8, 10, 689}, - dictWord{ - 137, - 10, - 863, - }, - dictWord{138, 0, 880}, - dictWord{4, 10, 18}, - dictWord{7, 10, 145}, - dictWord{7, 10, 444}, - dictWord{7, 10, 1278}, - dictWord{8, 10, 49}, - dictWord{ - 8, - 10, - 400, - }, - dictWord{9, 10, 71}, - dictWord{9, 10, 250}, - dictWord{10, 10, 459}, - dictWord{12, 10, 160}, - dictWord{144, 10, 24}, - dictWord{136, 0, 475}, - dictWord{ - 5, - 0, - 1016, - }, - dictWord{5, 11, 299}, - dictWord{135, 11, 1083}, - dictWord{7, 0, 602}, - dictWord{8, 0, 179}, - dictWord{10, 0, 781}, - dictWord{140, 0, 126}, - dictWord{ - 6, - 0, - 329, - }, - dictWord{138, 0, 111}, - dictWord{135, 0, 1864}, - dictWord{4, 11, 219}, - dictWord{7, 11, 1761}, - dictWord{137, 11, 86}, - dictWord{6, 0, 1888}, - dictWord{ - 6, - 0, - 1892, - }, - dictWord{6, 0, 1901}, - dictWord{6, 0, 1904}, - dictWord{9, 0, 953}, - dictWord{9, 0, 985}, - dictWord{9, 0, 991}, - dictWord{9, 0, 1001}, - dictWord{12, 0, 818}, - dictWord{12, 0, 846}, - dictWord{12, 0, 847}, - dictWord{12, 0, 861}, - dictWord{12, 0, 862}, - dictWord{12, 0, 873}, - dictWord{12, 0, 875}, - dictWord{12, 0, 877}, - dictWord{12, 0, 879}, - dictWord{12, 0, 881}, - dictWord{12, 0, 884}, - dictWord{12, 0, 903}, - dictWord{12, 0, 915}, - dictWord{12, 0, 926}, - dictWord{12, 0, 939}, - dictWord{ - 15, - 0, - 182, - }, - dictWord{15, 0, 219}, - dictWord{15, 0, 255}, - dictWord{18, 0, 191}, - dictWord{18, 0, 209}, - dictWord{18, 0, 211}, - dictWord{149, 0, 41}, - dictWord{ - 5, - 11, - 328, - }, - dictWord{135, 11, 918}, - dictWord{137, 0, 780}, - dictWord{12, 0, 82}, - dictWord{143, 0, 36}, - dictWord{133, 10, 1010}, - dictWord{5, 0, 821}, - dictWord{ - 134, - 0, - 1687, - }, - dictWord{133, 11, 514}, - dictWord{132, 0, 956}, - dictWord{134, 0, 1180}, - dictWord{10, 0, 112}, - dictWord{5, 10, 87}, - dictWord{7, 10, 313}, - dictWord{ - 7, - 10, - 1103, - }, - dictWord{10, 10, 582}, - dictWord{11, 10, 389}, - dictWord{11, 10, 813}, - dictWord{12, 10, 385}, - dictWord{13, 10, 286}, - dictWord{14, 10, 124}, - dictWord{146, 10, 108}, - dictWord{5, 0, 71}, - dictWord{7, 0, 1407}, - dictWord{9, 0, 704}, - dictWord{10, 0, 261}, - dictWord{10, 0, 619}, - dictWord{11, 0, 547}, - dictWord{11, 0, 619}, - dictWord{143, 0, 157}, - dictWord{4, 0, 531}, - dictWord{5, 0, 455}, - dictWord{5, 11, 301}, - dictWord{6, 11, 571}, - dictWord{14, 11, 49}, - dictWord{ - 146, - 11, - 102, - }, - dictWord{132, 10, 267}, - dictWord{6, 0, 385}, - dictWord{7, 0, 2008}, - dictWord{9, 0, 337}, - dictWord{138, 0, 517}, - dictWord{133, 11, 726}, - dictWord{133, 11, 364}, - dictWord{4, 11, 76}, - dictWord{7, 11, 1550}, - dictWord{9, 11, 306}, - dictWord{9, 11, 430}, - dictWord{9, 11, 663}, - dictWord{10, 11, 683}, - dictWord{11, 11, 427}, - dictWord{11, 11, 753}, - dictWord{12, 11, 334}, - dictWord{12, 11, 442}, - dictWord{14, 11, 258}, - dictWord{14, 11, 366}, - dictWord{ - 143, - 11, - 131, - }, - dictWord{6, 0, 1865}, - dictWord{6, 0, 1879}, - dictWord{6, 0, 1881}, - dictWord{6, 0, 1894}, - dictWord{6, 0, 1908}, - dictWord{9, 0, 915}, - dictWord{9, 0, 926}, - dictWord{9, 0, 940}, - dictWord{9, 0, 943}, - dictWord{9, 0, 966}, - dictWord{9, 0, 980}, - dictWord{9, 0, 989}, - dictWord{9, 0, 1005}, - dictWord{9, 0, 1010}, - dictWord{ - 12, - 0, - 813, - }, - dictWord{12, 0, 817}, - dictWord{12, 0, 840}, - dictWord{12, 0, 843}, - dictWord{12, 0, 855}, - dictWord{12, 0, 864}, - dictWord{12, 0, 871}, - dictWord{12, 0, 872}, - dictWord{12, 0, 899}, - dictWord{12, 0, 905}, - dictWord{12, 0, 924}, - dictWord{15, 0, 171}, - dictWord{15, 0, 181}, - dictWord{15, 0, 224}, - dictWord{15, 0, 235}, - dictWord{15, 0, 251}, - dictWord{146, 0, 184}, - dictWord{137, 11, 52}, - dictWord{5, 0, 16}, - dictWord{6, 0, 86}, - dictWord{6, 0, 603}, - dictWord{7, 0, 292}, - dictWord{7, 0, 561}, - dictWord{8, 0, 257}, - dictWord{8, 0, 382}, - dictWord{9, 0, 721}, - dictWord{9, 0, 778}, - dictWord{11, 0, 581}, - dictWord{140, 0, 466}, - dictWord{4, 0, 486}, - dictWord{ - 5, - 0, - 491, - }, - dictWord{135, 10, 1121}, - dictWord{4, 0, 72}, - dictWord{6, 0, 265}, - dictWord{135, 0, 1300}, - dictWord{135, 11, 1183}, - dictWord{10, 10, 249}, - dictWord{139, 10, 209}, - dictWord{132, 10, 561}, - dictWord{137, 11, 519}, - dictWord{4, 11, 656}, - dictWord{4, 10, 760}, - dictWord{135, 11, 779}, - dictWord{ - 9, - 10, - 154, - }, - dictWord{140, 10, 485}, - dictWord{135, 11, 1793}, - dictWord{135, 11, 144}, - dictWord{136, 10, 255}, - dictWord{133, 0, 621}, - dictWord{4, 10, 368}, - dictWord{135, 10, 641}, - dictWord{135, 11, 1373}, - dictWord{7, 11, 554}, - dictWord{7, 11, 605}, - dictWord{141, 11, 10}, - dictWord{137, 0, 234}, - dictWord{ - 5, - 0, - 815, - }, - dictWord{6, 0, 1688}, - dictWord{134, 0, 1755}, - dictWord{5, 11, 838}, - dictWord{5, 11, 841}, - dictWord{134, 11, 1649}, - dictWord{7, 0, 1987}, - dictWord{ - 7, - 0, - 2040, - }, - dictWord{136, 0, 743}, - dictWord{133, 11, 1012}, - dictWord{6, 0, 197}, - dictWord{136, 0, 205}, - dictWord{6, 0, 314}, - dictWord{134, 11, 314}, - dictWord{144, 11, 53}, - dictWord{6, 11, 251}, - dictWord{7, 11, 365}, - dictWord{7, 11, 1357}, - dictWord{7, 11, 1497}, - dictWord{8, 11, 154}, - dictWord{141, 11, 281}, - dictWord{133, 11, 340}, - dictWord{6, 0, 452}, - dictWord{7, 0, 312}, - dictWord{138, 0, 219}, - dictWord{138, 0, 589}, - dictWord{4, 0, 333}, - dictWord{9, 0, 176}, - dictWord{12, 0, 353}, - dictWord{141, 0, 187}, - dictWord{9, 10, 92}, - dictWord{147, 10, 91}, - dictWord{134, 0, 1110}, - dictWord{11, 0, 47}, - dictWord{139, 11, 495}, - dictWord{6, 10, 525}, - dictWord{8, 10, 806}, - dictWord{9, 10, 876}, - dictWord{140, 10, 284}, - dictWord{8, 11, 261}, - dictWord{9, 11, 144}, - dictWord{9, 11, 466}, - dictWord{10, 11, 370}, - dictWord{12, 11, 470}, - dictWord{13, 11, 144}, - dictWord{142, 11, 348}, - dictWord{137, 11, 897}, - dictWord{8, 0, 863}, - dictWord{8, 0, 864}, - dictWord{8, 0, 868}, - dictWord{8, 0, 884}, - dictWord{10, 0, 866}, - dictWord{10, 0, 868}, - dictWord{10, 0, 873}, - dictWord{10, 0, 911}, - dictWord{10, 0, 912}, - dictWord{ - 10, - 0, - 944, - }, - dictWord{12, 0, 727}, - dictWord{6, 11, 248}, - dictWord{9, 11, 546}, - dictWord{10, 11, 535}, - dictWord{11, 11, 681}, - dictWord{141, 11, 135}, - dictWord{ - 6, - 0, - 300, - }, - dictWord{135, 0, 1515}, - dictWord{134, 0, 1237}, - dictWord{139, 10, 958}, - dictWord{133, 10, 594}, - dictWord{140, 11, 250}, - dictWord{ - 134, - 0, - 1685, - }, - dictWord{134, 11, 567}, - dictWord{7, 0, 135}, - dictWord{8, 0, 7}, - dictWord{8, 0, 62}, - dictWord{9, 0, 243}, - dictWord{10, 0, 658}, - dictWord{10, 0, 697}, - dictWord{11, 0, 456}, - dictWord{139, 0, 756}, - dictWord{9, 0, 395}, - dictWord{138, 0, 79}, - dictWord{6, 10, 1641}, - dictWord{136, 10, 820}, - dictWord{4, 10, 302}, - dictWord{135, 10, 1766}, - dictWord{134, 11, 174}, - dictWord{135, 10, 1313}, - dictWord{135, 0, 631}, - dictWord{134, 10, 1674}, - dictWord{134, 11, 395}, - dictWord{138, 0, 835}, - dictWord{7, 0, 406}, - dictWord{7, 0, 459}, - dictWord{8, 0, 606}, - dictWord{139, 0, 726}, - dictWord{134, 11, 617}, - dictWord{134, 0, 979}, - dictWord{ - 6, - 10, - 389, - }, - dictWord{7, 10, 149}, - dictWord{9, 10, 142}, - dictWord{138, 10, 94}, - dictWord{5, 11, 878}, - dictWord{133, 11, 972}, - dictWord{6, 10, 8}, - dictWord{ - 7, - 10, - 1881, - }, - dictWord{8, 10, 91}, - dictWord{136, 11, 511}, - dictWord{133, 0, 612}, - dictWord{132, 11, 351}, - dictWord{4, 0, 372}, - dictWord{7, 0, 482}, - dictWord{ - 8, - 0, - 158, - }, - dictWord{9, 0, 602}, - dictWord{9, 0, 615}, - dictWord{10, 0, 245}, - dictWord{10, 0, 678}, - dictWord{10, 0, 744}, - dictWord{11, 0, 248}, - dictWord{ - 139, - 0, - 806, - }, - dictWord{5, 0, 854}, - dictWord{135, 0, 1991}, - dictWord{132, 11, 286}, - dictWord{135, 11, 344}, - dictWord{7, 11, 438}, - dictWord{7, 11, 627}, - dictWord{ - 7, - 11, - 1516, - }, - dictWord{8, 11, 40}, - dictWord{9, 11, 56}, - dictWord{9, 11, 294}, - dictWord{10, 11, 30}, - dictWord{10, 11, 259}, - dictWord{11, 11, 969}, - dictWord{ - 146, - 11, - 148, - }, - dictWord{135, 0, 1492}, - dictWord{5, 11, 259}, - dictWord{7, 11, 414}, - dictWord{7, 11, 854}, - dictWord{142, 11, 107}, - dictWord{135, 10, 1746}, - dictWord{6, 0, 833}, - dictWord{134, 0, 998}, - dictWord{135, 10, 24}, - dictWord{6, 0, 750}, - dictWord{135, 0, 1739}, - dictWord{4, 10, 503}, - dictWord{ - 135, - 10, - 1661, - }, - dictWord{5, 10, 130}, - dictWord{7, 10, 1314}, - dictWord{9, 10, 610}, - dictWord{10, 10, 718}, - dictWord{11, 10, 601}, - dictWord{11, 10, 819}, - dictWord{ - 11, - 10, - 946, - }, - dictWord{140, 10, 536}, - dictWord{10, 10, 149}, - dictWord{11, 10, 280}, - dictWord{142, 10, 336}, - dictWord{132, 11, 738}, - dictWord{ - 135, - 10, - 1946, - }, - dictWord{5, 0, 195}, - dictWord{135, 0, 1685}, - dictWord{7, 0, 1997}, - dictWord{8, 0, 730}, - dictWord{139, 0, 1006}, - dictWord{151, 11, 17}, - dictWord{ - 133, - 11, - 866, - }, - dictWord{14, 0, 463}, - dictWord{14, 0, 470}, - dictWord{150, 0, 61}, - dictWord{5, 0, 751}, - dictWord{8, 0, 266}, - dictWord{11, 0, 578}, - dictWord{ - 4, - 10, - 392, - }, - dictWord{135, 10, 1597}, - dictWord{5, 10, 433}, - dictWord{9, 10, 633}, - dictWord{139, 10, 629}, - dictWord{135, 0, 821}, - dictWord{6, 0, 715}, - dictWord{ - 134, - 0, - 1325, - }, - dictWord{133, 11, 116}, - dictWord{6, 0, 868}, - dictWord{132, 11, 457}, - dictWord{134, 0, 959}, - dictWord{6, 10, 234}, - dictWord{138, 11, 199}, - dictWord{7, 0, 1053}, - dictWord{7, 10, 1950}, - dictWord{8, 10, 680}, - dictWord{11, 10, 817}, - dictWord{147, 10, 88}, - dictWord{7, 10, 1222}, - dictWord{ - 138, - 10, - 386, - }, - dictWord{5, 0, 950}, - dictWord{5, 0, 994}, - dictWord{6, 0, 351}, - dictWord{134, 0, 1124}, - dictWord{134, 0, 1081}, - dictWord{7, 0, 1595}, - dictWord{6, 10, 5}, - dictWord{11, 10, 249}, - dictWord{12, 10, 313}, - dictWord{16, 10, 66}, - dictWord{145, 10, 26}, - dictWord{148, 0, 59}, - dictWord{5, 11, 527}, - dictWord{6, 11, 189}, - dictWord{135, 11, 859}, - dictWord{5, 10, 963}, - dictWord{6, 10, 1773}, - dictWord{11, 11, 104}, - dictWord{11, 11, 554}, - dictWord{15, 11, 60}, - dictWord{ - 143, - 11, - 125, - }, - dictWord{135, 0, 47}, - dictWord{137, 0, 684}, - dictWord{134, 11, 116}, - dictWord{134, 0, 1606}, - dictWord{134, 0, 777}, - dictWord{7, 0, 1020}, - dictWord{ - 8, - 10, - 509, - }, - dictWord{136, 10, 792}, - dictWord{135, 0, 1094}, - dictWord{132, 0, 350}, - dictWord{133, 11, 487}, - dictWord{4, 11, 86}, - dictWord{5, 11, 667}, - dictWord{5, 11, 753}, - dictWord{6, 11, 316}, - dictWord{6, 11, 455}, - dictWord{135, 11, 946}, - dictWord{7, 0, 1812}, - dictWord{13, 0, 259}, - dictWord{13, 0, 356}, - dictWord{14, 0, 242}, - dictWord{147, 0, 114}, - dictWord{132, 10, 931}, - dictWord{133, 0, 967}, - dictWord{4, 0, 473}, - dictWord{7, 0, 623}, - dictWord{8, 0, 808}, - dictWord{ - 9, - 0, - 871, - }, - dictWord{9, 0, 893}, - dictWord{11, 0, 38}, - dictWord{11, 0, 431}, - dictWord{12, 0, 112}, - dictWord{12, 0, 217}, - dictWord{12, 0, 243}, - dictWord{12, 0, 562}, - dictWord{12, 0, 663}, - dictWord{12, 0, 683}, - dictWord{13, 0, 141}, - dictWord{13, 0, 197}, - dictWord{13, 0, 227}, - dictWord{13, 0, 406}, - dictWord{13, 0, 487}, - dictWord{14, 0, 156}, - dictWord{14, 0, 203}, - dictWord{14, 0, 224}, - dictWord{14, 0, 256}, - dictWord{18, 0, 58}, - dictWord{150, 0, 0}, - dictWord{138, 0, 286}, - dictWord{ - 7, - 10, - 943, - }, - dictWord{139, 10, 614}, - dictWord{135, 10, 1837}, - dictWord{150, 11, 45}, - dictWord{132, 0, 798}, - dictWord{4, 0, 222}, - dictWord{7, 0, 286}, - dictWord{136, 0, 629}, - dictWord{4, 11, 79}, - dictWord{7, 11, 1773}, - dictWord{10, 11, 450}, - dictWord{11, 11, 589}, - dictWord{13, 11, 332}, - dictWord{13, 11, 493}, - dictWord{14, 11, 183}, - dictWord{14, 11, 334}, - dictWord{14, 11, 362}, - dictWord{14, 11, 368}, - dictWord{14, 11, 376}, - dictWord{14, 11, 379}, - dictWord{ - 19, - 11, - 90, - }, - dictWord{19, 11, 103}, - dictWord{19, 11, 127}, - dictWord{148, 11, 90}, - dictWord{5, 0, 337}, - dictWord{11, 0, 513}, - dictWord{11, 0, 889}, - dictWord{ - 11, - 0, - 961, - }, - dictWord{12, 0, 461}, - dictWord{13, 0, 79}, - dictWord{15, 0, 121}, - dictWord{4, 10, 90}, - dictWord{5, 10, 545}, - dictWord{7, 10, 754}, - dictWord{9, 10, 186}, - dictWord{10, 10, 72}, - dictWord{10, 10, 782}, - dictWord{11, 10, 577}, - dictWord{11, 10, 610}, - dictWord{12, 10, 354}, - dictWord{12, 10, 362}, - dictWord{ - 140, - 10, - 595, - }, - dictWord{141, 0, 306}, - dictWord{136, 0, 146}, - dictWord{7, 0, 1646}, - dictWord{9, 10, 329}, - dictWord{11, 10, 254}, - dictWord{141, 11, 124}, - dictWord{ - 4, - 0, - 465, - }, - dictWord{135, 0, 1663}, - dictWord{132, 0, 525}, - dictWord{133, 11, 663}, - dictWord{10, 0, 299}, - dictWord{18, 0, 74}, - dictWord{9, 10, 187}, - dictWord{ - 11, - 10, - 1016, - }, - dictWord{145, 10, 44}, - dictWord{7, 0, 165}, - dictWord{7, 0, 919}, - dictWord{4, 10, 506}, - dictWord{136, 10, 517}, - dictWord{5, 10, 295}, - dictWord{ - 135, - 10, - 1680, - }, - dictWord{133, 11, 846}, - dictWord{134, 0, 1064}, - dictWord{5, 11, 378}, - dictWord{7, 11, 1402}, - dictWord{7, 11, 1414}, - dictWord{8, 11, 465}, - dictWord{9, 11, 286}, - dictWord{10, 11, 185}, - dictWord{10, 11, 562}, - dictWord{10, 11, 635}, - dictWord{11, 11, 31}, - dictWord{11, 11, 393}, - dictWord{ - 12, - 11, - 456, - }, - dictWord{13, 11, 312}, - dictWord{18, 11, 65}, - dictWord{18, 11, 96}, - dictWord{147, 11, 89}, - dictWord{132, 0, 596}, - dictWord{7, 10, 987}, - dictWord{ - 9, - 10, - 688, - }, - dictWord{10, 10, 522}, - dictWord{11, 10, 788}, - dictWord{140, 10, 566}, - dictWord{6, 0, 82}, - dictWord{7, 0, 138}, - dictWord{7, 0, 517}, - dictWord{7, 0, 1741}, - dictWord{11, 0, 238}, - dictWord{4, 11, 648}, - dictWord{134, 10, 1775}, - dictWord{7, 0, 1233}, - dictWord{7, 10, 700}, - dictWord{7, 10, 940}, - dictWord{8, 10, 514}, - dictWord{9, 10, 116}, - dictWord{9, 10, 535}, - dictWord{10, 10, 118}, - dictWord{11, 10, 107}, - dictWord{11, 10, 148}, - dictWord{11, 10, 922}, - dictWord{ - 12, - 10, - 254, - }, - dictWord{12, 10, 421}, - dictWord{142, 10, 238}, - dictWord{4, 0, 962}, - dictWord{6, 0, 1824}, - dictWord{8, 0, 894}, - dictWord{12, 0, 708}, - dictWord{ - 12, - 0, - 725, - }, - dictWord{14, 0, 451}, - dictWord{20, 0, 94}, - dictWord{22, 0, 59}, - dictWord{150, 0, 62}, - dictWord{5, 11, 945}, - dictWord{6, 11, 1656}, - dictWord{6, 11, 1787}, - dictWord{7, 11, 167}, - dictWord{8, 11, 824}, - dictWord{9, 11, 391}, - dictWord{10, 11, 375}, - dictWord{139, 11, 185}, - dictWord{5, 0, 495}, - dictWord{7, 0, 834}, - dictWord{9, 0, 733}, - dictWord{139, 0, 378}, - dictWord{4, 10, 743}, - dictWord{135, 11, 1273}, - dictWord{6, 0, 1204}, - dictWord{7, 11, 1645}, - dictWord{8, 11, 352}, - dictWord{137, 11, 249}, - dictWord{139, 10, 292}, - dictWord{133, 0, 559}, - dictWord{132, 11, 152}, - dictWord{9, 0, 499}, - dictWord{10, 0, 341}, - dictWord{ - 15, - 0, - 144, - }, - dictWord{19, 0, 49}, - dictWord{7, 10, 1283}, - dictWord{9, 10, 227}, - dictWord{11, 10, 325}, - dictWord{11, 10, 408}, - dictWord{14, 10, 180}, - dictWord{ - 146, - 10, - 47, - }, - dictWord{6, 0, 21}, - dictWord{6, 0, 1737}, - dictWord{7, 0, 1444}, - dictWord{136, 0, 224}, - dictWord{133, 11, 1006}, - dictWord{7, 0, 1446}, - dictWord{ - 9, - 0, - 97, - }, - dictWord{17, 0, 15}, - dictWord{5, 10, 81}, - dictWord{7, 10, 146}, - dictWord{7, 10, 1342}, - dictWord{8, 10, 53}, - dictWord{8, 10, 561}, - dictWord{8, 10, 694}, - dictWord{8, 10, 754}, - dictWord{9, 10, 115}, - dictWord{9, 10, 894}, - dictWord{10, 10, 462}, - dictWord{10, 10, 813}, - dictWord{11, 10, 230}, - dictWord{11, 10, 657}, - dictWord{11, 10, 699}, - dictWord{11, 10, 748}, - dictWord{12, 10, 119}, - dictWord{12, 10, 200}, - dictWord{12, 10, 283}, - dictWord{142, 10, 273}, - dictWord{ - 5, - 10, - 408, - }, - dictWord{137, 10, 747}, - dictWord{135, 11, 431}, - dictWord{135, 11, 832}, - dictWord{6, 0, 729}, - dictWord{134, 0, 953}, - dictWord{4, 0, 727}, - dictWord{ - 8, - 0, - 565, - }, - dictWord{5, 11, 351}, - dictWord{7, 11, 264}, - dictWord{136, 11, 565}, - dictWord{134, 0, 1948}, - dictWord{5, 0, 519}, - dictWord{5, 11, 40}, - dictWord{ - 7, - 11, - 598, - }, - dictWord{7, 11, 1638}, - dictWord{8, 11, 78}, - dictWord{9, 11, 166}, - dictWord{9, 11, 640}, - dictWord{9, 11, 685}, - dictWord{9, 11, 773}, - dictWord{ - 11, - 11, - 215, - }, - dictWord{13, 11, 65}, - dictWord{14, 11, 172}, - dictWord{14, 11, 317}, - dictWord{145, 11, 6}, - dictWord{8, 11, 60}, - dictWord{9, 11, 343}, - dictWord{ - 139, - 11, - 769, - }, - dictWord{137, 11, 455}, - dictWord{134, 0, 1193}, - dictWord{140, 0, 790}, - dictWord{7, 11, 1951}, - dictWord{8, 11, 765}, - dictWord{8, 11, 772}, - dictWord{140, 11, 671}, - dictWord{7, 11, 108}, - dictWord{8, 11, 219}, - dictWord{8, 11, 388}, - dictWord{9, 11, 639}, - dictWord{9, 11, 775}, - dictWord{11, 11, 275}, - dictWord{140, 11, 464}, - dictWord{132, 11, 468}, - dictWord{7, 10, 30}, - dictWord{8, 10, 86}, - dictWord{8, 10, 315}, - dictWord{8, 10, 700}, - dictWord{9, 10, 576}, - dictWord{ - 9, - 10, - 858, - }, - dictWord{11, 10, 310}, - dictWord{11, 10, 888}, - dictWord{11, 10, 904}, - dictWord{12, 10, 361}, - dictWord{141, 10, 248}, - dictWord{5, 11, 15}, - dictWord{6, 11, 56}, - dictWord{7, 11, 1758}, - dictWord{8, 11, 500}, - dictWord{9, 11, 730}, - dictWord{11, 11, 331}, - dictWord{13, 11, 150}, - dictWord{142, 11, 282}, - dictWord{4, 0, 402}, - dictWord{7, 0, 2}, - dictWord{8, 0, 323}, - dictWord{136, 0, 479}, - dictWord{138, 10, 839}, - dictWord{11, 0, 580}, - dictWord{142, 0, 201}, - dictWord{ - 5, - 0, - 59, - }, - dictWord{135, 0, 672}, - dictWord{137, 10, 617}, - dictWord{146, 0, 34}, - dictWord{134, 11, 1886}, - dictWord{4, 0, 961}, - dictWord{136, 0, 896}, - dictWord{ - 6, - 0, - 1285, - }, - dictWord{5, 11, 205}, - dictWord{6, 11, 438}, - dictWord{137, 11, 711}, - dictWord{134, 10, 428}, - dictWord{7, 10, 524}, - dictWord{8, 10, 169}, - dictWord{8, 10, 234}, - dictWord{9, 10, 480}, - dictWord{138, 10, 646}, - dictWord{148, 0, 46}, - dictWord{141, 0, 479}, - dictWord{133, 11, 534}, - dictWord{6, 0, 2019}, - dictWord{134, 10, 1648}, - dictWord{4, 0, 85}, - dictWord{7, 0, 549}, - dictWord{7, 10, 1205}, - dictWord{138, 10, 637}, - dictWord{4, 0, 663}, - dictWord{5, 0, 94}, - dictWord{ - 7, - 11, - 235, - }, - dictWord{7, 11, 1475}, - dictWord{15, 11, 68}, - dictWord{146, 11, 120}, - dictWord{6, 11, 443}, - dictWord{9, 11, 237}, - dictWord{9, 11, 571}, - dictWord{ - 9, - 11, - 695, - }, - dictWord{10, 11, 139}, - dictWord{11, 11, 715}, - dictWord{12, 11, 417}, - dictWord{141, 11, 421}, - dictWord{132, 0, 783}, - dictWord{4, 0, 682}, - dictWord{8, 0, 65}, - dictWord{9, 10, 39}, - dictWord{10, 10, 166}, - dictWord{11, 10, 918}, - dictWord{12, 10, 635}, - dictWord{20, 10, 10}, - dictWord{22, 10, 27}, - dictWord{ - 22, - 10, - 43, - }, - dictWord{150, 10, 52}, - dictWord{6, 0, 11}, - dictWord{135, 0, 187}, - dictWord{132, 0, 522}, - dictWord{4, 0, 52}, - dictWord{135, 0, 661}, - dictWord{ - 4, - 0, - 383, - }, - dictWord{133, 0, 520}, - dictWord{135, 11, 546}, - dictWord{11, 0, 343}, - dictWord{142, 0, 127}, - dictWord{4, 11, 578}, - dictWord{7, 10, 157}, - dictWord{ - 7, - 11, - 624, - }, - dictWord{7, 11, 916}, - dictWord{8, 10, 279}, - dictWord{10, 11, 256}, - dictWord{11, 11, 87}, - dictWord{139, 11, 703}, - dictWord{134, 10, 604}, - dictWord{ - 4, - 0, - 281, - }, - dictWord{5, 0, 38}, - dictWord{7, 0, 194}, - dictWord{7, 0, 668}, - dictWord{7, 0, 1893}, - dictWord{137, 0, 397}, - dictWord{7, 10, 945}, - dictWord{11, 10, 713}, - dictWord{139, 10, 744}, - dictWord{139, 10, 1022}, - dictWord{9, 0, 635}, - dictWord{139, 0, 559}, - dictWord{5, 11, 923}, - dictWord{7, 11, 490}, - dictWord{ - 12, - 11, - 553, - }, - dictWord{13, 11, 100}, - dictWord{14, 11, 118}, - dictWord{143, 11, 75}, - dictWord{132, 0, 975}, - dictWord{132, 10, 567}, - dictWord{137, 10, 859}, - dictWord{7, 10, 1846}, - dictWord{7, 11, 1846}, - dictWord{8, 10, 628}, - dictWord{136, 11, 628}, - dictWord{148, 0, 116}, - dictWord{138, 11, 750}, - dictWord{14, 0, 51}, - dictWord{14, 11, 51}, - dictWord{15, 11, 7}, - dictWord{148, 11, 20}, - dictWord{132, 0, 858}, - dictWord{134, 0, 1075}, - dictWord{4, 11, 924}, - dictWord{ - 133, - 10, - 762, - }, - dictWord{136, 0, 535}, - dictWord{133, 0, 448}, - dictWord{10, 10, 784}, - dictWord{141, 10, 191}, - dictWord{133, 10, 298}, - dictWord{7, 0, 610}, - dictWord{135, 0, 1501}, - dictWord{7, 10, 633}, - dictWord{7, 10, 905}, - dictWord{7, 10, 909}, - dictWord{7, 10, 1538}, - dictWord{9, 10, 767}, - dictWord{140, 10, 636}, - dictWord{4, 11, 265}, - dictWord{7, 11, 807}, - dictWord{135, 11, 950}, - dictWord{5, 11, 93}, - dictWord{12, 11, 267}, - dictWord{144, 11, 26}, - dictWord{136, 0, 191}, - dictWord{139, 10, 301}, - dictWord{135, 10, 1970}, - dictWord{135, 0, 267}, - dictWord{4, 0, 319}, - dictWord{5, 0, 699}, - dictWord{138, 0, 673}, - dictWord{ - 6, - 0, - 336, - }, - dictWord{7, 0, 92}, - dictWord{7, 0, 182}, - dictWord{8, 0, 453}, - dictWord{8, 0, 552}, - dictWord{9, 0, 204}, - dictWord{9, 0, 285}, - dictWord{10, 0, 99}, - dictWord{ - 11, - 0, - 568, - }, - dictWord{11, 0, 950}, - dictWord{12, 0, 94}, - dictWord{16, 0, 20}, - dictWord{16, 0, 70}, - dictWord{19, 0, 55}, - dictWord{12, 10, 644}, - dictWord{144, 10, 90}, - dictWord{6, 0, 551}, - dictWord{7, 0, 1308}, - dictWord{7, 10, 845}, - dictWord{7, 11, 994}, - dictWord{8, 10, 160}, - dictWord{137, 10, 318}, - dictWord{19, 11, 1}, - dictWord{ - 19, - 11, - 26, - }, - dictWord{150, 11, 9}, - dictWord{7, 0, 1406}, - dictWord{9, 0, 218}, - dictWord{141, 0, 222}, - dictWord{5, 0, 256}, - dictWord{138, 0, 69}, - dictWord{ - 5, - 11, - 233, - }, - dictWord{5, 11, 320}, - dictWord{6, 11, 140}, - dictWord{7, 11, 330}, - dictWord{136, 11, 295}, - dictWord{6, 0, 1980}, - dictWord{136, 0, 952}, - dictWord{ - 4, - 0, - 833, - }, - dictWord{137, 11, 678}, - dictWord{133, 11, 978}, - dictWord{4, 11, 905}, - dictWord{6, 11, 1701}, - dictWord{137, 11, 843}, - dictWord{138, 10, 735}, - dictWord{136, 10, 76}, - dictWord{17, 0, 39}, - dictWord{148, 0, 36}, - dictWord{18, 0, 81}, - dictWord{146, 11, 81}, - dictWord{14, 0, 352}, - dictWord{17, 0, 53}, - dictWord{ - 18, - 0, - 146, - }, - dictWord{18, 0, 152}, - dictWord{19, 0, 11}, - dictWord{150, 0, 54}, - dictWord{135, 0, 634}, - dictWord{138, 10, 841}, - dictWord{132, 0, 618}, - dictWord{ - 4, - 0, - 339, - }, - dictWord{7, 0, 259}, - dictWord{17, 0, 73}, - dictWord{4, 11, 275}, - dictWord{140, 11, 376}, - dictWord{132, 11, 509}, - dictWord{7, 11, 273}, - dictWord{ - 139, - 11, - 377, - }, - dictWord{4, 0, 759}, - dictWord{13, 0, 169}, - dictWord{137, 10, 804}, - dictWord{6, 10, 96}, - dictWord{135, 10, 1426}, - dictWord{4, 10, 651}, - dictWord{133, 10, 289}, - dictWord{7, 0, 1075}, - dictWord{8, 10, 35}, - dictWord{9, 10, 511}, - dictWord{10, 10, 767}, - dictWord{147, 10, 118}, - dictWord{6, 0, 649}, - dictWord{6, 0, 670}, - dictWord{136, 0, 482}, - dictWord{5, 0, 336}, - dictWord{6, 0, 341}, - dictWord{6, 0, 478}, - dictWord{6, 0, 1763}, - dictWord{136, 0, 386}, - dictWord{ - 5, - 11, - 802, - }, - dictWord{7, 11, 2021}, - dictWord{8, 11, 805}, - dictWord{14, 11, 94}, - dictWord{15, 11, 65}, - dictWord{16, 11, 4}, - dictWord{16, 11, 77}, - dictWord{16, 11, 80}, - dictWord{145, 11, 5}, - dictWord{6, 0, 1035}, - dictWord{5, 11, 167}, - dictWord{5, 11, 899}, - dictWord{6, 11, 410}, - dictWord{137, 11, 777}, - dictWord{ - 134, - 11, - 1705, - }, - dictWord{5, 0, 924}, - dictWord{133, 0, 969}, - dictWord{132, 10, 704}, - dictWord{135, 0, 73}, - dictWord{135, 11, 10}, - dictWord{135, 10, 1078}, - dictWord{ - 5, - 11, - 11, - }, - dictWord{6, 11, 117}, - dictWord{6, 11, 485}, - dictWord{7, 11, 1133}, - dictWord{9, 11, 582}, - dictWord{9, 11, 594}, - dictWord{11, 11, 21}, - dictWord{ - 11, - 11, - 818, - }, - dictWord{12, 11, 535}, - dictWord{141, 11, 86}, - dictWord{135, 0, 1971}, - dictWord{4, 11, 264}, - dictWord{7, 11, 1067}, - dictWord{8, 11, 204}, - dictWord{8, 11, 385}, - dictWord{139, 11, 953}, - dictWord{6, 0, 1458}, - dictWord{135, 0, 1344}, - dictWord{5, 0, 396}, - dictWord{134, 0, 501}, - dictWord{4, 10, 720}, - dictWord{133, 10, 306}, - dictWord{4, 0, 929}, - dictWord{5, 0, 799}, - dictWord{8, 0, 46}, - dictWord{8, 0, 740}, - dictWord{133, 10, 431}, - dictWord{7, 11, 646}, - dictWord{ - 7, - 11, - 1730, - }, - dictWord{11, 11, 446}, - dictWord{141, 11, 178}, - dictWord{7, 0, 276}, - dictWord{5, 10, 464}, - dictWord{6, 10, 236}, - dictWord{7, 10, 696}, - dictWord{ - 7, - 10, - 914, - }, - dictWord{7, 10, 1108}, - dictWord{7, 10, 1448}, - dictWord{9, 10, 15}, - dictWord{9, 10, 564}, - dictWord{10, 10, 14}, - dictWord{12, 10, 565}, - dictWord{ - 13, - 10, - 449, - }, - dictWord{14, 10, 53}, - dictWord{15, 10, 13}, - dictWord{16, 10, 64}, - dictWord{145, 10, 41}, - dictWord{4, 0, 892}, - dictWord{133, 0, 770}, - dictWord{ - 6, - 10, - 1767, - }, - dictWord{12, 10, 194}, - dictWord{145, 10, 107}, - dictWord{135, 0, 158}, - dictWord{5, 10, 840}, - dictWord{138, 11, 608}, - dictWord{134, 0, 1432}, - dictWord{138, 11, 250}, - dictWord{8, 11, 794}, - dictWord{9, 11, 400}, - dictWord{10, 11, 298}, - dictWord{142, 11, 228}, - dictWord{151, 0, 25}, - dictWord{ - 7, - 11, - 1131, - }, - dictWord{135, 11, 1468}, - dictWord{135, 0, 2001}, - dictWord{9, 10, 642}, - dictWord{11, 10, 236}, - dictWord{142, 10, 193}, - dictWord{4, 10, 68}, - dictWord{5, 10, 634}, - dictWord{6, 10, 386}, - dictWord{7, 10, 794}, - dictWord{8, 10, 273}, - dictWord{9, 10, 563}, - dictWord{10, 10, 105}, - dictWord{10, 10, 171}, - dictWord{11, 10, 94}, - dictWord{139, 10, 354}, - dictWord{136, 11, 724}, - dictWord{132, 0, 478}, - dictWord{11, 11, 512}, - dictWord{13, 11, 205}, - dictWord{ - 19, - 11, - 30, - }, - dictWord{22, 11, 36}, - dictWord{151, 11, 19}, - dictWord{7, 0, 1461}, - dictWord{140, 0, 91}, - dictWord{6, 11, 190}, - dictWord{7, 11, 768}, - dictWord{ - 135, - 11, - 1170, - }, - dictWord{4, 0, 602}, - dictWord{8, 0, 211}, - dictWord{4, 10, 95}, - dictWord{7, 10, 416}, - dictWord{139, 10, 830}, - dictWord{7, 10, 731}, - dictWord{13, 10, 20}, - dictWord{143, 10, 11}, - dictWord{6, 0, 1068}, - dictWord{135, 0, 1872}, - dictWord{4, 0, 13}, - dictWord{5, 0, 567}, - dictWord{7, 0, 1498}, - dictWord{9, 0, 124}, - dictWord{11, 0, 521}, - dictWord{12, 0, 405}, - dictWord{135, 11, 1023}, - dictWord{135, 0, 1006}, - dictWord{132, 0, 735}, - dictWord{138, 0, 812}, - dictWord{4, 0, 170}, - dictWord{135, 0, 323}, - dictWord{6, 11, 137}, - dictWord{9, 11, 75}, - dictWord{9, 11, 253}, - dictWord{10, 11, 194}, - dictWord{138, 11, 444}, - dictWord{5, 0, 304}, - dictWord{7, 0, 1403}, - dictWord{5, 10, 864}, - dictWord{10, 10, 648}, - dictWord{11, 10, 671}, - dictWord{143, 10, 46}, - dictWord{135, 11, 1180}, - dictWord{ - 133, - 10, - 928, - }, - dictWord{4, 0, 148}, - dictWord{133, 0, 742}, - dictWord{11, 10, 986}, - dictWord{140, 10, 682}, - dictWord{133, 0, 523}, - dictWord{135, 11, 1743}, - dictWord{7, 0, 730}, - dictWord{18, 0, 144}, - dictWord{19, 0, 61}, - dictWord{8, 10, 44}, - dictWord{9, 10, 884}, - dictWord{10, 10, 580}, - dictWord{11, 10, 399}, - dictWord{ - 11, - 10, - 894, - }, - dictWord{143, 10, 122}, - dictWord{5, 11, 760}, - dictWord{7, 11, 542}, - dictWord{8, 11, 135}, - dictWord{136, 11, 496}, - dictWord{136, 0, 981}, - dictWord{133, 0, 111}, - dictWord{10, 0, 132}, - dictWord{11, 0, 191}, - dictWord{11, 0, 358}, - dictWord{139, 0, 460}, - dictWord{7, 11, 319}, - dictWord{7, 11, 355}, - dictWord{ - 7, - 11, - 763, - }, - dictWord{10, 11, 389}, - dictWord{145, 11, 43}, - dictWord{134, 0, 890}, - dictWord{134, 0, 1420}, - dictWord{136, 11, 557}, - dictWord{ - 133, - 10, - 518, - }, - dictWord{133, 0, 444}, - dictWord{135, 0, 1787}, - dictWord{135, 10, 1852}, - dictWord{8, 0, 123}, - dictWord{15, 0, 6}, - dictWord{144, 0, 7}, - dictWord{ - 6, - 0, - 2041, - }, - dictWord{10, 11, 38}, - dictWord{139, 11, 784}, - dictWord{136, 0, 932}, - dictWord{5, 0, 937}, - dictWord{135, 0, 100}, - dictWord{6, 0, 995}, - dictWord{ - 4, - 11, - 58, - }, - dictWord{5, 11, 286}, - dictWord{6, 11, 319}, - dictWord{7, 11, 402}, - dictWord{7, 11, 1254}, - dictWord{7, 11, 1903}, - dictWord{8, 11, 356}, - dictWord{ - 140, - 11, - 408, - }, - dictWord{4, 11, 389}, - dictWord{9, 11, 181}, - dictWord{9, 11, 255}, - dictWord{10, 11, 8}, - dictWord{10, 11, 29}, - dictWord{10, 11, 816}, - dictWord{ - 11, - 11, - 311, - }, - dictWord{11, 11, 561}, - dictWord{12, 11, 67}, - dictWord{141, 11, 181}, - dictWord{138, 0, 255}, - dictWord{5, 0, 138}, - dictWord{4, 10, 934}, - dictWord{ - 136, - 10, - 610, - }, - dictWord{4, 0, 965}, - dictWord{10, 0, 863}, - dictWord{138, 0, 898}, - dictWord{10, 10, 804}, - dictWord{138, 10, 832}, - dictWord{12, 0, 631}, - dictWord{ - 8, - 10, - 96, - }, - dictWord{9, 10, 36}, - dictWord{10, 10, 607}, - dictWord{11, 10, 423}, - dictWord{11, 10, 442}, - dictWord{12, 10, 309}, - dictWord{14, 10, 199}, - dictWord{ - 15, - 10, - 90, - }, - dictWord{145, 10, 110}, - dictWord{134, 0, 1394}, - dictWord{4, 0, 652}, - dictWord{8, 0, 320}, - dictWord{22, 0, 6}, - dictWord{22, 0, 16}, - dictWord{ - 9, - 10, - 13, - }, - dictWord{9, 10, 398}, - dictWord{9, 10, 727}, - dictWord{10, 10, 75}, - dictWord{10, 10, 184}, - dictWord{10, 10, 230}, - dictWord{10, 10, 564}, - dictWord{ - 10, - 10, - 569, - }, - dictWord{11, 10, 973}, - dictWord{12, 10, 70}, - dictWord{12, 10, 189}, - dictWord{13, 10, 57}, - dictWord{141, 10, 257}, - dictWord{6, 0, 897}, - dictWord{ - 134, - 0, - 1333, - }, - dictWord{4, 0, 692}, - dictWord{133, 0, 321}, - dictWord{133, 11, 373}, - dictWord{135, 0, 922}, - dictWord{5, 0, 619}, - dictWord{133, 0, 698}, - dictWord{ - 137, - 10, - 631, - }, - dictWord{5, 10, 345}, - dictWord{135, 10, 1016}, - dictWord{9, 0, 957}, - dictWord{9, 0, 1018}, - dictWord{12, 0, 828}, - dictWord{12, 0, 844}, - dictWord{ - 12, - 0, - 897, - }, - dictWord{12, 0, 901}, - dictWord{12, 0, 943}, - dictWord{15, 0, 180}, - dictWord{18, 0, 197}, - dictWord{18, 0, 200}, - dictWord{18, 0, 213}, - dictWord{ - 18, - 0, - 214, - }, - dictWord{146, 0, 226}, - dictWord{5, 0, 917}, - dictWord{134, 0, 1659}, - dictWord{135, 0, 1100}, - dictWord{134, 0, 1173}, - dictWord{134, 0, 1930}, - dictWord{5, 0, 251}, - dictWord{5, 0, 956}, - dictWord{8, 0, 268}, - dictWord{9, 0, 214}, - dictWord{146, 0, 142}, - dictWord{133, 10, 673}, - dictWord{137, 10, 850}, - dictWord{ - 4, - 10, - 287, - }, - dictWord{133, 10, 1018}, - dictWord{132, 11, 672}, - dictWord{5, 0, 346}, - dictWord{5, 0, 711}, - dictWord{8, 0, 390}, - dictWord{11, 11, 752}, - dictWord{139, 11, 885}, - dictWord{5, 10, 34}, - dictWord{10, 10, 724}, - dictWord{12, 10, 444}, - dictWord{13, 10, 354}, - dictWord{18, 10, 32}, - dictWord{23, 10, 24}, - dictWord{23, 10, 31}, - dictWord{152, 10, 5}, - dictWord{4, 11, 710}, - dictWord{134, 11, 606}, - dictWord{134, 0, 744}, - dictWord{134, 10, 382}, - dictWord{ - 133, - 11, - 145, - }, - dictWord{4, 10, 329}, - dictWord{7, 11, 884}, - dictWord{140, 11, 124}, - dictWord{4, 11, 467}, - dictWord{5, 11, 405}, - dictWord{134, 11, 544}, - dictWord{ - 9, - 10, - 846, - }, - dictWord{138, 10, 827}, - dictWord{133, 0, 624}, - dictWord{9, 11, 372}, - dictWord{15, 11, 2}, - dictWord{19, 11, 10}, - dictWord{147, 11, 18}, - dictWord{ - 4, - 11, - 387, - }, - dictWord{135, 11, 1288}, - dictWord{5, 0, 783}, - dictWord{7, 0, 1998}, - dictWord{135, 0, 2047}, - dictWord{132, 10, 906}, - dictWord{136, 10, 366}, - dictWord{135, 11, 550}, - dictWord{4, 10, 123}, - dictWord{4, 10, 649}, - dictWord{5, 10, 605}, - dictWord{7, 10, 1509}, - dictWord{136, 10, 36}, - dictWord{ - 134, - 0, - 1125, - }, - dictWord{132, 0, 594}, - dictWord{133, 10, 767}, - dictWord{135, 11, 1227}, - dictWord{136, 11, 467}, - dictWord{4, 11, 576}, - dictWord{ - 135, - 11, - 1263, - }, - dictWord{4, 0, 268}, - dictWord{7, 0, 1534}, - dictWord{135, 11, 1534}, - dictWord{4, 10, 273}, - dictWord{5, 10, 658}, - dictWord{5, 11, 919}, - dictWord{ - 5, - 10, - 995, - }, - dictWord{134, 11, 1673}, - dictWord{133, 0, 563}, - dictWord{134, 10, 72}, - dictWord{135, 10, 1345}, - dictWord{4, 11, 82}, - dictWord{5, 11, 333}, - dictWord{ - 5, - 11, - 904, - }, - dictWord{6, 11, 207}, - dictWord{7, 11, 325}, - dictWord{7, 11, 1726}, - dictWord{8, 11, 101}, - dictWord{10, 11, 778}, - dictWord{139, 11, 220}, - dictWord{5, 0, 37}, - dictWord{6, 0, 39}, - dictWord{6, 0, 451}, - dictWord{7, 0, 218}, - dictWord{7, 0, 667}, - dictWord{7, 0, 1166}, - dictWord{7, 0, 1687}, - dictWord{8, 0, 662}, - dictWord{16, 0, 2}, - dictWord{133, 10, 589}, - dictWord{134, 0, 1332}, - dictWord{133, 11, 903}, - dictWord{134, 0, 508}, - dictWord{5, 10, 117}, - dictWord{6, 10, 514}, - dictWord{6, 10, 541}, - dictWord{7, 10, 1164}, - dictWord{7, 10, 1436}, - dictWord{8, 10, 220}, - dictWord{8, 10, 648}, - dictWord{10, 10, 688}, - dictWord{11, 10, 560}, - dictWord{140, 11, 147}, - dictWord{6, 11, 555}, - dictWord{135, 11, 485}, - dictWord{133, 10, 686}, - dictWord{7, 0, 453}, - dictWord{7, 0, 635}, - dictWord{7, 0, 796}, - dictWord{8, 0, 331}, - dictWord{9, 0, 330}, - dictWord{9, 0, 865}, - dictWord{10, 0, 119}, - dictWord{10, 0, 235}, - dictWord{11, 0, 111}, - dictWord{11, 0, 129}, - dictWord{ - 11, - 0, - 240, - }, - dictWord{12, 0, 31}, - dictWord{12, 0, 66}, - dictWord{12, 0, 222}, - dictWord{12, 0, 269}, - dictWord{12, 0, 599}, - dictWord{12, 0, 684}, - dictWord{12, 0, 689}, - dictWord{12, 0, 691}, - dictWord{142, 0, 345}, - dictWord{135, 0, 1834}, - dictWord{4, 11, 705}, - dictWord{7, 11, 615}, - dictWord{138, 11, 251}, - dictWord{ - 136, - 11, - 345, - }, - dictWord{137, 0, 527}, - dictWord{6, 0, 98}, - dictWord{7, 0, 702}, - dictWord{135, 0, 991}, - dictWord{11, 0, 576}, - dictWord{14, 0, 74}, - dictWord{7, 10, 196}, - dictWord{10, 10, 765}, - dictWord{11, 10, 347}, - dictWord{11, 10, 552}, - dictWord{11, 10, 790}, - dictWord{12, 10, 263}, - dictWord{13, 10, 246}, - dictWord{ - 13, - 10, - 270, - }, - dictWord{13, 10, 395}, - dictWord{14, 10, 176}, - dictWord{14, 10, 190}, - dictWord{14, 10, 398}, - dictWord{14, 10, 412}, - dictWord{15, 10, 32}, - dictWord{ - 15, - 10, - 63, - }, - dictWord{16, 10, 88}, - dictWord{147, 10, 105}, - dictWord{134, 11, 90}, - dictWord{13, 0, 84}, - dictWord{141, 0, 122}, - dictWord{6, 0, 37}, - dictWord{ - 7, - 0, - 299, - }, - dictWord{7, 0, 1666}, - dictWord{8, 0, 195}, - dictWord{8, 0, 316}, - dictWord{9, 0, 178}, - dictWord{9, 0, 276}, - dictWord{9, 0, 339}, - dictWord{9, 0, 536}, - dictWord{ - 10, - 0, - 102, - }, - dictWord{10, 0, 362}, - dictWord{10, 0, 785}, - dictWord{11, 0, 55}, - dictWord{11, 0, 149}, - dictWord{11, 0, 773}, - dictWord{13, 0, 416}, - dictWord{ - 13, - 0, - 419, - }, - dictWord{14, 0, 38}, - dictWord{14, 0, 41}, - dictWord{142, 0, 210}, - dictWord{5, 10, 381}, - dictWord{135, 10, 1792}, - dictWord{7, 11, 813}, - dictWord{ - 12, - 11, - 497, - }, - dictWord{141, 11, 56}, - dictWord{7, 10, 616}, - dictWord{138, 10, 413}, - dictWord{133, 0, 645}, - dictWord{6, 11, 125}, - dictWord{135, 11, 1277}, - dictWord{132, 0, 290}, - dictWord{6, 0, 70}, - dictWord{7, 0, 1292}, - dictWord{10, 0, 762}, - dictWord{139, 0, 288}, - dictWord{6, 10, 120}, - dictWord{7, 10, 1188}, - dictWord{ - 7, - 10, - 1710, - }, - dictWord{8, 10, 286}, - dictWord{9, 10, 667}, - dictWord{11, 10, 592}, - dictWord{139, 10, 730}, - dictWord{135, 11, 1784}, - dictWord{7, 0, 1315}, - dictWord{135, 11, 1315}, - dictWord{134, 0, 1955}, - dictWord{135, 10, 1146}, - dictWord{7, 0, 131}, - dictWord{7, 0, 422}, - dictWord{8, 0, 210}, - dictWord{ - 140, - 0, - 573, - }, - dictWord{4, 10, 352}, - dictWord{135, 10, 687}, - dictWord{139, 0, 797}, - dictWord{143, 0, 38}, - dictWord{14, 0, 179}, - dictWord{15, 0, 151}, - dictWord{ - 150, - 0, - 11, - }, - dictWord{7, 0, 488}, - dictWord{4, 10, 192}, - dictWord{5, 10, 49}, - dictWord{6, 10, 200}, - dictWord{6, 10, 293}, - dictWord{134, 10, 1696}, - dictWord{ - 132, - 0, - 936, - }, - dictWord{135, 11, 703}, - dictWord{6, 11, 160}, - dictWord{7, 11, 1106}, - dictWord{9, 11, 770}, - dictWord{10, 11, 618}, - dictWord{11, 11, 112}, - dictWord{ - 140, - 11, - 413, - }, - dictWord{5, 0, 453}, - dictWord{134, 0, 441}, - dictWord{135, 0, 595}, - dictWord{132, 10, 650}, - dictWord{132, 10, 147}, - dictWord{6, 0, 991}, - dictWord{6, 0, 1182}, - dictWord{12, 11, 271}, - dictWord{145, 11, 109}, - dictWord{133, 10, 934}, - dictWord{140, 11, 221}, - dictWord{132, 0, 653}, - dictWord{ - 7, - 0, - 505, - }, - dictWord{135, 0, 523}, - dictWord{134, 0, 903}, - dictWord{135, 11, 479}, - dictWord{7, 11, 304}, - dictWord{9, 11, 646}, - dictWord{9, 11, 862}, - dictWord{ - 10, - 11, - 262, - }, - dictWord{11, 11, 696}, - dictWord{12, 11, 208}, - dictWord{15, 11, 79}, - dictWord{147, 11, 108}, - dictWord{146, 0, 80}, - dictWord{135, 11, 981}, - dictWord{142, 0, 432}, - dictWord{132, 0, 314}, - dictWord{137, 11, 152}, - dictWord{7, 0, 1368}, - dictWord{8, 0, 232}, - dictWord{8, 0, 361}, - dictWord{10, 0, 682}, - dictWord{138, 0, 742}, - dictWord{135, 11, 1586}, - dictWord{9, 0, 534}, - dictWord{4, 11, 434}, - dictWord{11, 11, 663}, - dictWord{12, 11, 210}, - dictWord{13, 11, 166}, - dictWord{13, 11, 310}, - dictWord{14, 11, 373}, - dictWord{147, 11, 43}, - dictWord{7, 11, 1091}, - dictWord{135, 11, 1765}, - dictWord{6, 11, 550}, - dictWord{ - 135, - 11, - 652, - }, - dictWord{137, 0, 27}, - dictWord{142, 0, 12}, - dictWord{4, 10, 637}, - dictWord{5, 11, 553}, - dictWord{7, 11, 766}, - dictWord{138, 11, 824}, - dictWord{ - 7, - 11, - 737, - }, - dictWord{8, 11, 298}, - dictWord{136, 11, 452}, - dictWord{7, 0, 736}, - dictWord{139, 0, 264}, - dictWord{134, 0, 1657}, - dictWord{133, 11, 292}, - dictWord{138, 11, 135}, - dictWord{6, 0, 844}, - dictWord{134, 0, 1117}, - dictWord{135, 0, 127}, - dictWord{9, 10, 867}, - dictWord{138, 10, 837}, - dictWord{ - 6, - 0, - 1184, - }, - dictWord{134, 0, 1208}, - dictWord{134, 0, 1294}, - dictWord{136, 0, 364}, - dictWord{6, 0, 1415}, - dictWord{7, 0, 1334}, - dictWord{11, 0, 125}, - dictWord{ - 6, - 10, - 170, - }, - dictWord{7, 11, 393}, - dictWord{8, 10, 395}, - dictWord{8, 10, 487}, - dictWord{10, 11, 603}, - dictWord{11, 11, 206}, - dictWord{141, 10, 147}, - dictWord{137, 11, 748}, - dictWord{4, 11, 912}, - dictWord{137, 11, 232}, - dictWord{4, 10, 535}, - dictWord{136, 10, 618}, - dictWord{137, 0, 792}, - dictWord{ - 7, - 11, - 1973, - }, - dictWord{136, 11, 716}, - dictWord{135, 11, 98}, - dictWord{5, 0, 909}, - dictWord{9, 0, 849}, - dictWord{138, 0, 805}, - dictWord{4, 0, 630}, - dictWord{ - 132, - 0, - 699, - }, - dictWord{5, 11, 733}, - dictWord{14, 11, 103}, - dictWord{150, 10, 23}, - dictWord{12, 11, 158}, - dictWord{18, 11, 8}, - dictWord{19, 11, 62}, - dictWord{ - 20, - 11, - 6, - }, - dictWord{22, 11, 4}, - dictWord{23, 11, 2}, - dictWord{151, 11, 9}, - dictWord{132, 0, 968}, - dictWord{132, 10, 778}, - dictWord{132, 10, 46}, - dictWord{5, 10, 811}, - dictWord{6, 10, 1679}, - dictWord{6, 10, 1714}, - dictWord{135, 10, 2032}, - dictWord{6, 0, 1446}, - dictWord{7, 10, 1458}, - dictWord{9, 10, 407}, - dictWord{ - 139, - 10, - 15, - }, - dictWord{7, 0, 206}, - dictWord{7, 0, 397}, - dictWord{7, 0, 621}, - dictWord{7, 0, 640}, - dictWord{8, 0, 124}, - dictWord{8, 0, 619}, - dictWord{9, 0, 305}, - dictWord{ - 9, - 0, - 643, - }, - dictWord{10, 0, 264}, - dictWord{10, 0, 628}, - dictWord{11, 0, 40}, - dictWord{12, 0, 349}, - dictWord{13, 0, 134}, - dictWord{13, 0, 295}, - dictWord{ - 14, - 0, - 155, - }, - dictWord{15, 0, 120}, - dictWord{18, 0, 105}, - dictWord{6, 10, 34}, - dictWord{7, 10, 1089}, - dictWord{8, 10, 708}, - dictWord{8, 10, 721}, - dictWord{9, 10, 363}, - dictWord{148, 10, 98}, - dictWord{4, 0, 262}, - dictWord{5, 0, 641}, - dictWord{135, 0, 342}, - dictWord{137, 11, 72}, - dictWord{4, 0, 99}, - dictWord{6, 0, 250}, - dictWord{ - 6, - 0, - 346, - }, - dictWord{8, 0, 127}, - dictWord{138, 0, 81}, - dictWord{132, 0, 915}, - dictWord{5, 0, 75}, - dictWord{9, 0, 517}, - dictWord{10, 0, 470}, - dictWord{12, 0, 155}, - dictWord{141, 0, 224}, - dictWord{132, 10, 462}, - dictWord{11, 11, 600}, - dictWord{11, 11, 670}, - dictWord{141, 11, 245}, - dictWord{142, 0, 83}, - dictWord{ - 5, - 10, - 73, - }, - dictWord{6, 10, 23}, - dictWord{134, 10, 338}, - dictWord{6, 0, 1031}, - dictWord{139, 11, 923}, - dictWord{7, 11, 164}, - dictWord{7, 11, 1571}, - dictWord{ - 9, - 11, - 107, - }, - dictWord{140, 11, 225}, - dictWord{134, 0, 1470}, - dictWord{133, 0, 954}, - dictWord{6, 0, 304}, - dictWord{8, 0, 418}, - dictWord{10, 0, 345}, - dictWord{ - 11, - 0, - 341, - }, - dictWord{139, 0, 675}, - dictWord{9, 0, 410}, - dictWord{139, 0, 425}, - dictWord{4, 11, 27}, - dictWord{5, 11, 484}, - dictWord{5, 11, 510}, - dictWord{6, 11, 434}, - dictWord{7, 11, 1000}, - dictWord{7, 11, 1098}, - dictWord{8, 11, 2}, - dictWord{136, 11, 200}, - dictWord{134, 0, 734}, - dictWord{140, 11, 257}, - dictWord{ - 7, - 10, - 725, - }, - dictWord{8, 10, 498}, - dictWord{139, 10, 268}, - dictWord{134, 0, 1822}, - dictWord{135, 0, 1798}, - dictWord{135, 10, 773}, - dictWord{132, 11, 460}, - dictWord{4, 11, 932}, - dictWord{133, 11, 891}, - dictWord{134, 0, 14}, - dictWord{132, 10, 583}, - dictWord{7, 10, 1462}, - dictWord{8, 11, 625}, - dictWord{ - 139, - 10, - 659, - }, - dictWord{5, 0, 113}, - dictWord{6, 0, 243}, - dictWord{6, 0, 1708}, - dictWord{7, 0, 1865}, - dictWord{11, 0, 161}, - dictWord{16, 0, 37}, - dictWord{17, 0, 99}, - dictWord{133, 10, 220}, - dictWord{134, 11, 76}, - dictWord{5, 11, 461}, - dictWord{135, 11, 1925}, - dictWord{140, 0, 69}, - dictWord{8, 11, 92}, - dictWord{ - 137, - 11, - 221, - }, - dictWord{139, 10, 803}, - dictWord{132, 10, 544}, - dictWord{4, 0, 274}, - dictWord{134, 0, 922}, - dictWord{132, 0, 541}, - dictWord{5, 0, 627}, - dictWord{ - 6, - 10, - 437, - }, - dictWord{6, 10, 564}, - dictWord{11, 10, 181}, - dictWord{141, 10, 183}, - dictWord{135, 10, 1192}, - dictWord{7, 0, 166}, - dictWord{132, 11, 763}, - dictWord{133, 11, 253}, - dictWord{134, 0, 849}, - dictWord{9, 11, 73}, - dictWord{10, 11, 110}, - dictWord{14, 11, 185}, - dictWord{145, 11, 119}, - dictWord{5, 11, 212}, - dictWord{12, 11, 35}, - dictWord{141, 11, 382}, - dictWord{133, 0, 717}, - dictWord{137, 0, 304}, - dictWord{136, 0, 600}, - dictWord{133, 0, 654}, - dictWord{ - 6, - 0, - 273, - }, - dictWord{10, 0, 188}, - dictWord{13, 0, 377}, - dictWord{146, 0, 77}, - dictWord{4, 10, 790}, - dictWord{5, 10, 273}, - dictWord{134, 10, 394}, - dictWord{ - 132, - 0, - 543, - }, - dictWord{135, 0, 410}, - dictWord{11, 0, 98}, - dictWord{11, 0, 524}, - dictWord{141, 0, 87}, - dictWord{132, 0, 941}, - dictWord{135, 11, 1175}, - dictWord{ - 4, - 0, - 250, - }, - dictWord{7, 0, 1612}, - dictWord{11, 0, 186}, - dictWord{12, 0, 133}, - dictWord{6, 10, 127}, - dictWord{7, 10, 1511}, - dictWord{8, 10, 613}, - dictWord{ - 12, - 10, - 495, - }, - dictWord{12, 10, 586}, - dictWord{12, 10, 660}, - dictWord{12, 10, 668}, - dictWord{14, 10, 385}, - dictWord{15, 10, 118}, - dictWord{17, 10, 20}, - dictWord{ - 146, - 10, - 98, - }, - dictWord{6, 0, 1785}, - dictWord{133, 11, 816}, - dictWord{134, 0, 1339}, - dictWord{7, 0, 961}, - dictWord{7, 0, 1085}, - dictWord{7, 0, 1727}, - dictWord{ - 8, - 0, - 462, - }, - dictWord{6, 10, 230}, - dictWord{135, 11, 1727}, - dictWord{9, 0, 636}, - dictWord{135, 10, 1954}, - dictWord{132, 0, 780}, - dictWord{5, 11, 869}, - dictWord{5, 11, 968}, - dictWord{6, 11, 1626}, - dictWord{8, 11, 734}, - dictWord{136, 11, 784}, - dictWord{4, 11, 542}, - dictWord{6, 11, 1716}, - dictWord{6, 11, 1727}, - dictWord{7, 11, 1082}, - dictWord{7, 11, 1545}, - dictWord{8, 11, 56}, - dictWord{8, 11, 118}, - dictWord{8, 11, 412}, - dictWord{8, 11, 564}, - dictWord{9, 11, 888}, - dictWord{9, 11, 908}, - dictWord{10, 11, 50}, - dictWord{10, 11, 423}, - dictWord{11, 11, 685}, - dictWord{11, 11, 697}, - dictWord{11, 11, 933}, - dictWord{12, 11, 299}, - dictWord{13, 11, 126}, - dictWord{13, 11, 136}, - dictWord{13, 11, 170}, - dictWord{141, 11, 190}, - dictWord{134, 11, 226}, - dictWord{4, 11, 232}, - dictWord{ - 9, - 11, - 202, - }, - dictWord{10, 11, 474}, - dictWord{140, 11, 433}, - dictWord{137, 11, 500}, - dictWord{5, 0, 529}, - dictWord{136, 10, 68}, - dictWord{132, 10, 654}, - dictWord{ - 4, - 10, - 156, - }, - dictWord{7, 10, 998}, - dictWord{7, 10, 1045}, - dictWord{7, 10, 1860}, - dictWord{9, 10, 48}, - dictWord{9, 10, 692}, - dictWord{11, 10, 419}, - dictWord{139, 10, 602}, - dictWord{7, 0, 1276}, - dictWord{8, 0, 474}, - dictWord{9, 0, 652}, - dictWord{6, 11, 108}, - dictWord{7, 11, 1003}, - dictWord{7, 11, 1181}, - dictWord{136, 11, 343}, - dictWord{7, 11, 1264}, - dictWord{7, 11, 1678}, - dictWord{11, 11, 945}, - dictWord{12, 11, 341}, - dictWord{12, 11, 471}, - dictWord{ - 140, - 11, - 569, - }, - dictWord{134, 11, 1712}, - dictWord{5, 0, 948}, - dictWord{12, 0, 468}, - dictWord{19, 0, 96}, - dictWord{148, 0, 24}, - dictWord{4, 11, 133}, - dictWord{ - 7, - 11, - 711, - }, - dictWord{7, 11, 1298}, - dictWord{7, 11, 1585}, - dictWord{135, 11, 1929}, - dictWord{6, 0, 753}, - dictWord{140, 0, 657}, - dictWord{139, 0, 941}, - dictWord{ - 6, - 11, - 99, - }, - dictWord{7, 11, 1808}, - dictWord{145, 11, 57}, - dictWord{6, 11, 574}, - dictWord{7, 11, 428}, - dictWord{7, 11, 1250}, - dictWord{10, 11, 669}, - dictWord{ - 11, - 11, - 485, - }, - dictWord{11, 11, 840}, - dictWord{12, 11, 300}, - dictWord{142, 11, 250}, - dictWord{4, 0, 532}, - dictWord{5, 0, 706}, - dictWord{135, 0, 662}, - dictWord{ - 5, - 0, - 837, - }, - dictWord{6, 0, 1651}, - dictWord{139, 0, 985}, - dictWord{7, 0, 1861}, - dictWord{9, 10, 197}, - dictWord{10, 10, 300}, - dictWord{12, 10, 473}, - dictWord{ - 13, - 10, - 90, - }, - dictWord{141, 10, 405}, - dictWord{137, 11, 252}, - dictWord{6, 11, 323}, - dictWord{135, 11, 1564}, - dictWord{4, 0, 330}, - dictWord{4, 0, 863}, - dictWord{7, 0, 933}, - dictWord{7, 0, 2012}, - dictWord{8, 0, 292}, - dictWord{7, 11, 461}, - dictWord{8, 11, 775}, - dictWord{138, 11, 435}, - dictWord{132, 10, 606}, - dictWord{ - 4, - 11, - 655, - }, - dictWord{7, 11, 850}, - dictWord{17, 11, 75}, - dictWord{146, 11, 137}, - dictWord{135, 0, 767}, - dictWord{7, 10, 1978}, - dictWord{136, 10, 676}, - dictWord{132, 0, 641}, - dictWord{135, 11, 1559}, - dictWord{134, 0, 1233}, - dictWord{137, 0, 242}, - dictWord{17, 0, 114}, - dictWord{4, 10, 361}, - dictWord{ - 133, - 10, - 315, - }, - dictWord{137, 0, 883}, - dictWord{132, 10, 461}, - dictWord{138, 0, 274}, - dictWord{134, 0, 2008}, - dictWord{134, 0, 1794}, - dictWord{4, 0, 703}, - dictWord{135, 0, 207}, - dictWord{12, 0, 285}, - dictWord{132, 10, 472}, - dictWord{132, 0, 571}, - dictWord{5, 0, 873}, - dictWord{5, 0, 960}, - dictWord{8, 0, 823}, - dictWord{9, 0, 881}, - dictWord{136, 11, 577}, - dictWord{7, 0, 617}, - dictWord{10, 0, 498}, - dictWord{11, 0, 501}, - dictWord{12, 0, 16}, - dictWord{140, 0, 150}, - dictWord{ - 138, - 10, - 747, - }, - dictWord{132, 0, 431}, - dictWord{133, 10, 155}, - dictWord{11, 0, 283}, - dictWord{11, 0, 567}, - dictWord{7, 10, 163}, - dictWord{8, 10, 319}, - dictWord{ - 9, - 10, - 402, - }, - dictWord{10, 10, 24}, - dictWord{10, 10, 681}, - dictWord{11, 10, 200}, - dictWord{12, 10, 253}, - dictWord{12, 10, 410}, - dictWord{142, 10, 219}, - dictWord{4, 11, 413}, - dictWord{5, 11, 677}, - dictWord{8, 11, 432}, - dictWord{140, 11, 280}, - dictWord{9, 0, 401}, - dictWord{5, 10, 475}, - dictWord{7, 10, 1780}, - dictWord{11, 10, 297}, - dictWord{11, 10, 558}, - dictWord{14, 10, 322}, - dictWord{147, 10, 76}, - dictWord{6, 0, 781}, - dictWord{9, 0, 134}, - dictWord{10, 0, 2}, - dictWord{ - 10, - 0, - 27, - }, - dictWord{10, 0, 333}, - dictWord{11, 0, 722}, - dictWord{143, 0, 1}, - dictWord{5, 0, 33}, - dictWord{6, 0, 470}, - dictWord{139, 0, 424}, - dictWord{ - 135, - 0, - 2006, - }, - dictWord{12, 0, 783}, - dictWord{135, 10, 1956}, - dictWord{136, 0, 274}, - dictWord{135, 0, 1882}, - dictWord{132, 0, 794}, - dictWord{135, 0, 1848}, - dictWord{5, 10, 944}, - dictWord{134, 10, 1769}, - dictWord{6, 0, 47}, - dictWord{7, 0, 90}, - dictWord{7, 0, 664}, - dictWord{7, 0, 830}, - dictWord{7, 0, 1380}, - dictWord{ - 7, - 0, - 2025, - }, - dictWord{8, 0, 448}, - dictWord{136, 0, 828}, - dictWord{132, 10, 144}, - dictWord{134, 0, 1199}, - dictWord{4, 11, 395}, - dictWord{139, 11, 762}, - dictWord{135, 11, 1504}, - dictWord{9, 0, 417}, - dictWord{137, 0, 493}, - dictWord{9, 11, 174}, - dictWord{10, 11, 164}, - dictWord{11, 11, 440}, - dictWord{11, 11, 841}, - dictWord{143, 11, 98}, - dictWord{134, 11, 426}, - dictWord{139, 11, 1002}, - dictWord{134, 0, 295}, - dictWord{134, 0, 816}, - dictWord{6, 10, 247}, - dictWord{ - 137, - 10, - 555, - }, - dictWord{133, 0, 1019}, - dictWord{4, 0, 620}, - dictWord{5, 11, 476}, - dictWord{10, 10, 280}, - dictWord{138, 10, 797}, - dictWord{139, 0, 464}, - dictWord{5, 11, 76}, - dictWord{6, 11, 458}, - dictWord{6, 11, 497}, - dictWord{7, 11, 764}, - dictWord{7, 11, 868}, - dictWord{9, 11, 658}, - dictWord{10, 11, 594}, - dictWord{ - 11, - 11, - 173, - }, - dictWord{11, 11, 566}, - dictWord{12, 11, 20}, - dictWord{12, 11, 338}, - dictWord{141, 11, 200}, - dictWord{134, 0, 208}, - dictWord{4, 11, 526}, - dictWord{7, 11, 1029}, - dictWord{135, 11, 1054}, - dictWord{132, 11, 636}, - dictWord{6, 11, 233}, - dictWord{7, 11, 660}, - dictWord{7, 11, 1124}, - dictWord{ - 17, - 11, - 31, - }, - dictWord{19, 11, 22}, - dictWord{151, 11, 14}, - dictWord{10, 0, 442}, - dictWord{133, 10, 428}, - dictWord{10, 0, 930}, - dictWord{140, 0, 778}, - dictWord{ - 6, - 0, - 68, - }, - dictWord{7, 0, 448}, - dictWord{7, 0, 1629}, - dictWord{7, 0, 1769}, - dictWord{7, 0, 1813}, - dictWord{8, 0, 442}, - dictWord{8, 0, 516}, - dictWord{9, 0, 710}, - dictWord{ - 10, - 0, - 282, - }, - dictWord{10, 0, 722}, - dictWord{7, 10, 1717}, - dictWord{138, 10, 546}, - dictWord{134, 0, 1128}, - dictWord{11, 0, 844}, - dictWord{12, 0, 104}, - dictWord{140, 0, 625}, - dictWord{4, 11, 432}, - dictWord{135, 11, 824}, - dictWord{138, 10, 189}, - dictWord{133, 0, 787}, - dictWord{133, 10, 99}, - dictWord{ - 4, - 11, - 279, - }, - dictWord{7, 11, 301}, - dictWord{137, 11, 362}, - dictWord{8, 0, 491}, - dictWord{4, 10, 397}, - dictWord{136, 10, 555}, - dictWord{4, 11, 178}, - dictWord{ - 133, - 11, - 399, - }, - dictWord{134, 0, 711}, - dictWord{144, 0, 9}, - dictWord{4, 0, 403}, - dictWord{5, 0, 441}, - dictWord{7, 0, 450}, - dictWord{10, 0, 840}, - dictWord{11, 0, 101}, - dictWord{12, 0, 193}, - dictWord{141, 0, 430}, - dictWord{135, 11, 1246}, - dictWord{12, 10, 398}, - dictWord{20, 10, 39}, - dictWord{21, 10, 11}, - dictWord{ - 150, - 10, - 41, - }, - dictWord{4, 10, 485}, - dictWord{7, 10, 353}, - dictWord{135, 10, 1523}, - dictWord{6, 10, 366}, - dictWord{7, 10, 1384}, - dictWord{7, 10, 1601}, - dictWord{ - 135, - 11, - 1912, - }, - dictWord{7, 0, 396}, - dictWord{10, 0, 160}, - dictWord{135, 11, 396}, - dictWord{137, 10, 282}, - dictWord{134, 11, 1692}, - dictWord{4, 10, 157}, - dictWord{5, 10, 471}, - dictWord{6, 11, 202}, - dictWord{10, 11, 448}, - dictWord{11, 11, 208}, - dictWord{12, 11, 360}, - dictWord{17, 11, 117}, - dictWord{ - 17, - 11, - 118, - }, - dictWord{18, 11, 27}, - dictWord{148, 11, 67}, - dictWord{133, 0, 679}, - dictWord{137, 0, 326}, - dictWord{136, 10, 116}, - dictWord{7, 11, 872}, - dictWord{ - 10, - 11, - 516, - }, - dictWord{139, 11, 167}, - dictWord{132, 11, 224}, - dictWord{5, 11, 546}, - dictWord{7, 11, 35}, - dictWord{8, 11, 11}, - dictWord{8, 11, 12}, - dictWord{ - 9, - 11, - 315, - }, - dictWord{9, 11, 533}, - dictWord{10, 11, 802}, - dictWord{11, 11, 166}, - dictWord{12, 11, 525}, - dictWord{142, 11, 243}, - dictWord{7, 0, 1128}, - dictWord{135, 11, 1920}, - dictWord{5, 11, 241}, - dictWord{8, 11, 242}, - dictWord{9, 11, 451}, - dictWord{10, 11, 667}, - dictWord{11, 11, 598}, - dictWord{ - 140, - 11, - 429, - }, - dictWord{6, 0, 737}, - dictWord{5, 10, 160}, - dictWord{7, 10, 363}, - dictWord{7, 10, 589}, - dictWord{10, 10, 170}, - dictWord{141, 10, 55}, - dictWord{ - 135, - 0, - 1796, - }, - dictWord{142, 11, 254}, - dictWord{4, 0, 574}, - dictWord{7, 0, 350}, - dictWord{7, 0, 1024}, - dictWord{8, 0, 338}, - dictWord{9, 0, 677}, - dictWord{138, 0, 808}, - dictWord{134, 0, 1096}, - dictWord{137, 11, 516}, - dictWord{7, 0, 405}, - dictWord{10, 0, 491}, - dictWord{4, 10, 108}, - dictWord{4, 11, 366}, - dictWord{ - 139, - 10, - 498, - }, - dictWord{11, 11, 337}, - dictWord{142, 11, 303}, - dictWord{134, 11, 1736}, - dictWord{7, 0, 1081}, - dictWord{140, 11, 364}, - dictWord{7, 10, 1005}, - dictWord{140, 10, 609}, - dictWord{7, 0, 1676}, - dictWord{4, 10, 895}, - dictWord{133, 10, 772}, - dictWord{135, 0, 2037}, - dictWord{6, 0, 1207}, - dictWord{ - 11, - 11, - 916, - }, - dictWord{142, 11, 419}, - dictWord{14, 11, 140}, - dictWord{148, 11, 41}, - dictWord{6, 11, 331}, - dictWord{136, 11, 623}, - dictWord{9, 0, 944}, - dictWord{ - 9, - 0, - 969, - }, - dictWord{9, 0, 1022}, - dictWord{12, 0, 913}, - dictWord{12, 0, 936}, - dictWord{15, 0, 177}, - dictWord{15, 0, 193}, - dictWord{4, 10, 926}, - dictWord{ - 133, - 10, - 983, - }, - dictWord{5, 0, 354}, - dictWord{135, 11, 506}, - dictWord{8, 0, 598}, - dictWord{9, 0, 664}, - dictWord{138, 0, 441}, - dictWord{4, 11, 640}, - dictWord{ - 133, - 11, - 513, - }, - dictWord{137, 0, 297}, - dictWord{132, 10, 538}, - dictWord{6, 10, 294}, - dictWord{7, 10, 1267}, - dictWord{136, 10, 624}, - dictWord{7, 0, 1772}, - dictWord{ - 7, - 11, - 1888, - }, - dictWord{8, 11, 289}, - dictWord{11, 11, 45}, - dictWord{12, 11, 278}, - dictWord{140, 11, 537}, - dictWord{135, 10, 1325}, - dictWord{138, 0, 751}, - dictWord{141, 0, 37}, - dictWord{134, 0, 1828}, - dictWord{132, 10, 757}, - dictWord{132, 11, 394}, - dictWord{6, 0, 257}, - dictWord{135, 0, 1522}, - dictWord{ - 4, - 0, - 582, - }, - dictWord{9, 0, 191}, - dictWord{135, 11, 1931}, - dictWord{7, 11, 574}, - dictWord{7, 11, 1719}, - dictWord{137, 11, 145}, - dictWord{132, 11, 658}, - dictWord{10, 0, 790}, - dictWord{132, 11, 369}, - dictWord{9, 11, 781}, - dictWord{10, 11, 144}, - dictWord{11, 11, 385}, - dictWord{13, 11, 161}, - dictWord{13, 11, 228}, - dictWord{13, 11, 268}, - dictWord{148, 11, 107}, - dictWord{8, 0, 469}, - dictWord{10, 0, 47}, - dictWord{136, 11, 374}, - dictWord{6, 0, 306}, - dictWord{7, 0, 1140}, - dictWord{7, 0, 1340}, - dictWord{8, 0, 133}, - dictWord{138, 0, 449}, - dictWord{139, 0, 1011}, - dictWord{7, 10, 1875}, - dictWord{139, 10, 124}, - dictWord{ - 4, - 11, - 344, - }, - dictWord{6, 11, 498}, - dictWord{139, 11, 323}, - dictWord{137, 0, 299}, - dictWord{132, 0, 837}, - dictWord{133, 11, 906}, - dictWord{5, 0, 329}, - dictWord{ - 8, - 0, - 260, - }, - dictWord{138, 0, 10}, - dictWord{134, 0, 1320}, - dictWord{4, 0, 657}, - dictWord{146, 0, 158}, - dictWord{135, 0, 1191}, - dictWord{152, 0, 7}, - dictWord{ - 6, - 0, - 1939, - }, - dictWord{8, 0, 974}, - dictWord{138, 0, 996}, - dictWord{135, 0, 1665}, - dictWord{11, 11, 126}, - dictWord{139, 11, 287}, - dictWord{143, 0, 8}, - dictWord{ - 14, - 11, - 149, - }, - dictWord{14, 11, 399}, - dictWord{143, 11, 57}, - dictWord{5, 0, 66}, - dictWord{7, 0, 1896}, - dictWord{136, 0, 288}, - dictWord{7, 0, 175}, - dictWord{ - 10, - 0, - 494, - }, - dictWord{5, 10, 150}, - dictWord{8, 10, 603}, - dictWord{9, 10, 593}, - dictWord{9, 10, 634}, - dictWord{10, 10, 173}, - dictWord{11, 10, 462}, - dictWord{ - 11, - 10, - 515, - }, - dictWord{13, 10, 216}, - dictWord{13, 10, 288}, - dictWord{142, 10, 400}, - dictWord{134, 0, 1643}, - dictWord{136, 11, 21}, - dictWord{4, 0, 21}, - dictWord{ - 5, - 0, - 91, - }, - dictWord{5, 0, 648}, - dictWord{5, 0, 750}, - dictWord{5, 0, 781}, - dictWord{6, 0, 54}, - dictWord{6, 0, 112}, - dictWord{6, 0, 402}, - dictWord{6, 0, 1732}, - dictWord{ - 7, - 0, - 315, - }, - dictWord{7, 0, 749}, - dictWord{7, 0, 1427}, - dictWord{7, 0, 1900}, - dictWord{9, 0, 78}, - dictWord{9, 0, 508}, - dictWord{10, 0, 611}, - dictWord{10, 0, 811}, - dictWord{11, 0, 510}, - dictWord{11, 0, 728}, - dictWord{13, 0, 36}, - dictWord{14, 0, 39}, - dictWord{16, 0, 83}, - dictWord{17, 0, 124}, - dictWord{148, 0, 30}, - dictWord{ - 4, - 0, - 668, - }, - dictWord{136, 0, 570}, - dictWord{10, 0, 322}, - dictWord{10, 0, 719}, - dictWord{139, 0, 407}, - dictWord{135, 11, 1381}, - dictWord{136, 11, 193}, - dictWord{12, 10, 108}, - dictWord{141, 10, 291}, - dictWord{132, 11, 616}, - dictWord{136, 11, 692}, - dictWord{8, 0, 125}, - dictWord{8, 0, 369}, - dictWord{8, 0, 524}, - dictWord{10, 0, 486}, - dictWord{11, 0, 13}, - dictWord{11, 0, 381}, - dictWord{11, 0, 736}, - dictWord{11, 0, 766}, - dictWord{11, 0, 845}, - dictWord{13, 0, 114}, - dictWord{ - 13, - 0, - 292, - }, - dictWord{142, 0, 47}, - dictWord{134, 0, 1247}, - dictWord{6, 0, 1684}, - dictWord{6, 0, 1731}, - dictWord{7, 0, 356}, - dictWord{8, 0, 54}, - dictWord{8, 0, 221}, - dictWord{9, 0, 225}, - dictWord{9, 0, 356}, - dictWord{10, 0, 77}, - dictWord{10, 0, 446}, - dictWord{10, 0, 731}, - dictWord{12, 0, 404}, - dictWord{141, 0, 491}, - dictWord{135, 10, 1777}, - dictWord{4, 11, 305}, - dictWord{4, 10, 493}, - dictWord{144, 10, 55}, - dictWord{4, 0, 951}, - dictWord{6, 0, 1809}, - dictWord{6, 0, 1849}, - dictWord{8, 0, 846}, - dictWord{8, 0, 866}, - dictWord{8, 0, 899}, - dictWord{10, 0, 896}, - dictWord{12, 0, 694}, - dictWord{142, 0, 468}, - dictWord{5, 11, 214}, - dictWord{ - 7, - 11, - 603, - }, - dictWord{8, 11, 611}, - dictWord{9, 11, 686}, - dictWord{10, 11, 88}, - dictWord{11, 11, 459}, - dictWord{11, 11, 496}, - dictWord{12, 11, 463}, - dictWord{ - 12, - 11, - 590, - }, - dictWord{13, 11, 0}, - dictWord{142, 11, 214}, - dictWord{132, 0, 411}, - dictWord{4, 0, 80}, - dictWord{133, 0, 44}, - dictWord{140, 11, 74}, - dictWord{ - 143, - 0, - 31, - }, - dictWord{7, 0, 669}, - dictWord{6, 10, 568}, - dictWord{7, 10, 1804}, - dictWord{8, 10, 362}, - dictWord{8, 10, 410}, - dictWord{8, 10, 830}, - dictWord{9, 10, 514}, - dictWord{11, 10, 649}, - dictWord{142, 10, 157}, - dictWord{7, 0, 673}, - dictWord{134, 11, 1703}, - dictWord{132, 10, 625}, - dictWord{134, 0, 1303}, - dictWord{ - 5, - 0, - 299, - }, - dictWord{135, 0, 1083}, - dictWord{138, 0, 704}, - dictWord{6, 0, 275}, - dictWord{7, 0, 408}, - dictWord{6, 10, 158}, - dictWord{7, 10, 129}, - dictWord{ - 7, - 10, - 181, - }, - dictWord{8, 10, 276}, - dictWord{8, 10, 377}, - dictWord{10, 10, 523}, - dictWord{11, 10, 816}, - dictWord{12, 10, 455}, - dictWord{13, 10, 303}, - dictWord{ - 142, - 10, - 135, - }, - dictWord{4, 0, 219}, - dictWord{7, 0, 367}, - dictWord{7, 0, 1713}, - dictWord{7, 0, 1761}, - dictWord{9, 0, 86}, - dictWord{9, 0, 537}, - dictWord{10, 0, 165}, - dictWord{12, 0, 219}, - dictWord{140, 0, 561}, - dictWord{8, 0, 216}, - dictWord{4, 10, 1}, - dictWord{4, 11, 737}, - dictWord{6, 11, 317}, - dictWord{7, 10, 1143}, - dictWord{ - 7, - 10, - 1463, - }, - dictWord{9, 10, 207}, - dictWord{9, 10, 390}, - dictWord{9, 10, 467}, - dictWord{10, 11, 98}, - dictWord{11, 11, 294}, - dictWord{11, 10, 836}, - dictWord{ - 12, - 11, - 60, - }, - dictWord{12, 11, 437}, - dictWord{13, 11, 64}, - dictWord{13, 11, 380}, - dictWord{142, 11, 430}, - dictWord{6, 11, 1758}, - dictWord{8, 11, 520}, - dictWord{9, 11, 345}, - dictWord{9, 11, 403}, - dictWord{142, 11, 350}, - dictWord{5, 11, 47}, - dictWord{10, 11, 242}, - dictWord{138, 11, 579}, - dictWord{5, 11, 139}, - dictWord{7, 11, 1168}, - dictWord{138, 11, 539}, - dictWord{135, 0, 1319}, - dictWord{4, 10, 295}, - dictWord{4, 10, 723}, - dictWord{5, 10, 895}, - dictWord{ - 7, - 10, - 1031, - }, - dictWord{8, 10, 199}, - dictWord{8, 10, 340}, - dictWord{9, 10, 153}, - dictWord{9, 10, 215}, - dictWord{10, 10, 21}, - dictWord{10, 10, 59}, - dictWord{ - 10, - 10, - 80, - }, - dictWord{10, 10, 224}, - dictWord{10, 10, 838}, - dictWord{11, 10, 229}, - dictWord{11, 10, 652}, - dictWord{12, 10, 192}, - dictWord{13, 10, 146}, - dictWord{ - 142, - 10, - 91, - }, - dictWord{140, 0, 428}, - dictWord{137, 10, 51}, - dictWord{133, 0, 514}, - dictWord{5, 10, 309}, - dictWord{140, 10, 211}, - dictWord{6, 0, 1010}, - dictWord{5, 10, 125}, - dictWord{8, 10, 77}, - dictWord{138, 10, 15}, - dictWord{4, 0, 55}, - dictWord{5, 0, 301}, - dictWord{6, 0, 571}, - dictWord{142, 0, 49}, - dictWord{ - 146, - 0, - 102, - }, - dictWord{136, 11, 370}, - dictWord{4, 11, 107}, - dictWord{7, 11, 613}, - dictWord{8, 11, 358}, - dictWord{8, 11, 439}, - dictWord{8, 11, 504}, - dictWord{ - 9, - 11, - 501, - }, - dictWord{10, 11, 383}, - dictWord{139, 11, 477}, - dictWord{132, 11, 229}, - dictWord{133, 0, 364}, - dictWord{133, 10, 439}, - dictWord{4, 11, 903}, - dictWord{135, 11, 1816}, - dictWord{11, 0, 379}, - dictWord{140, 10, 76}, - dictWord{4, 0, 76}, - dictWord{4, 0, 971}, - dictWord{7, 0, 1550}, - dictWord{9, 0, 306}, - dictWord{ - 9, - 0, - 430, - }, - dictWord{9, 0, 663}, - dictWord{10, 0, 683}, - dictWord{10, 0, 921}, - dictWord{11, 0, 427}, - dictWord{11, 0, 753}, - dictWord{12, 0, 334}, - dictWord{12, 0, 442}, - dictWord{14, 0, 258}, - dictWord{14, 0, 366}, - dictWord{143, 0, 131}, - dictWord{137, 0, 52}, - dictWord{4, 11, 47}, - dictWord{6, 11, 373}, - dictWord{7, 11, 452}, - dictWord{7, 11, 543}, - dictWord{7, 11, 1714}, - dictWord{7, 11, 1856}, - dictWord{9, 11, 6}, - dictWord{11, 11, 257}, - dictWord{139, 11, 391}, - dictWord{4, 10, 8}, - dictWord{ - 7, - 10, - 1152, - }, - dictWord{7, 10, 1153}, - dictWord{7, 10, 1715}, - dictWord{9, 10, 374}, - dictWord{10, 10, 478}, - dictWord{139, 10, 648}, - dictWord{4, 11, 785}, - dictWord{133, 11, 368}, - dictWord{135, 10, 1099}, - dictWord{135, 11, 860}, - dictWord{5, 11, 980}, - dictWord{134, 11, 1754}, - dictWord{134, 0, 1258}, - dictWord{ - 6, - 0, - 1058, - }, - dictWord{6, 0, 1359}, - dictWord{7, 11, 536}, - dictWord{7, 11, 1331}, - dictWord{136, 11, 143}, - dictWord{4, 0, 656}, - dictWord{135, 0, 779}, - dictWord{136, 10, 87}, - dictWord{5, 11, 19}, - dictWord{6, 11, 533}, - dictWord{146, 11, 126}, - dictWord{7, 0, 144}, - dictWord{138, 10, 438}, - dictWord{5, 11, 395}, - dictWord{5, 11, 951}, - dictWord{134, 11, 1776}, - dictWord{135, 0, 1373}, - dictWord{7, 0, 554}, - dictWord{7, 0, 605}, - dictWord{141, 0, 10}, - dictWord{4, 10, 69}, - dictWord{ - 5, - 10, - 122, - }, - dictWord{9, 10, 656}, - dictWord{138, 10, 464}, - dictWord{5, 10, 849}, - dictWord{134, 10, 1633}, - dictWord{5, 0, 838}, - dictWord{5, 0, 841}, - dictWord{134, 0, 1649}, - dictWord{133, 0, 1012}, - dictWord{139, 10, 499}, - dictWord{7, 10, 476}, - dictWord{7, 10, 1592}, - dictWord{138, 10, 87}, - dictWord{ - 6, - 0, - 251, - }, - dictWord{7, 0, 365}, - dictWord{7, 0, 1357}, - dictWord{7, 0, 1497}, - dictWord{8, 0, 154}, - dictWord{141, 0, 281}, - dictWord{132, 11, 441}, - dictWord{ - 132, - 11, - 695, - }, - dictWord{7, 11, 497}, - dictWord{9, 11, 387}, - dictWord{147, 11, 81}, - dictWord{133, 0, 340}, - dictWord{14, 10, 283}, - dictWord{142, 11, 283}, - dictWord{ - 134, - 0, - 810, - }, - dictWord{135, 11, 1894}, - dictWord{139, 0, 495}, - dictWord{5, 11, 284}, - dictWord{6, 11, 49}, - dictWord{6, 11, 350}, - dictWord{7, 11, 1}, - dictWord{ - 7, - 11, - 377, - }, - dictWord{7, 11, 1693}, - dictWord{8, 11, 18}, - dictWord{8, 11, 678}, - dictWord{9, 11, 161}, - dictWord{9, 11, 585}, - dictWord{9, 11, 671}, - dictWord{ - 9, - 11, - 839, - }, - dictWord{11, 11, 912}, - dictWord{141, 11, 427}, - dictWord{5, 10, 859}, - dictWord{7, 10, 1160}, - dictWord{8, 10, 107}, - dictWord{9, 10, 291}, - dictWord{ - 9, - 10, - 439, - }, - dictWord{10, 10, 663}, - dictWord{11, 10, 609}, - dictWord{140, 10, 197}, - dictWord{8, 0, 261}, - dictWord{9, 0, 144}, - dictWord{9, 0, 466}, - dictWord{ - 10, - 0, - 370, - }, - dictWord{12, 0, 470}, - dictWord{13, 0, 144}, - dictWord{142, 0, 348}, - dictWord{137, 0, 897}, - dictWord{6, 0, 248}, - dictWord{9, 0, 546}, - dictWord{10, 0, 535}, - dictWord{11, 0, 681}, - dictWord{141, 0, 135}, - dictWord{4, 0, 358}, - dictWord{135, 0, 1496}, - dictWord{134, 0, 567}, - dictWord{136, 0, 445}, - dictWord{ - 4, - 10, - 117, - }, - dictWord{6, 10, 372}, - dictWord{7, 10, 1905}, - dictWord{142, 10, 323}, - dictWord{4, 10, 722}, - dictWord{139, 10, 471}, - dictWord{6, 0, 697}, - dictWord{ - 134, - 0, - 996, - }, - dictWord{7, 11, 2007}, - dictWord{9, 11, 101}, - dictWord{9, 11, 450}, - dictWord{10, 11, 66}, - dictWord{10, 11, 842}, - dictWord{11, 11, 536}, - dictWord{ - 140, - 11, - 587, - }, - dictWord{132, 0, 577}, - dictWord{134, 0, 1336}, - dictWord{9, 10, 5}, - dictWord{12, 10, 216}, - dictWord{12, 10, 294}, - dictWord{12, 10, 298}, - dictWord{12, 10, 400}, - dictWord{12, 10, 518}, - dictWord{13, 10, 229}, - dictWord{143, 10, 139}, - dictWord{6, 0, 174}, - dictWord{138, 0, 917}, - dictWord{ - 134, - 10, - 1774, - }, - dictWord{5, 10, 12}, - dictWord{7, 10, 375}, - dictWord{9, 10, 88}, - dictWord{9, 10, 438}, - dictWord{11, 11, 62}, - dictWord{139, 10, 270}, - dictWord{ - 134, - 11, - 1766, - }, - dictWord{6, 11, 0}, - dictWord{7, 11, 84}, - dictWord{7, 10, 816}, - dictWord{7, 10, 1241}, - dictWord{9, 10, 283}, - dictWord{9, 10, 520}, - dictWord{10, 10, 213}, - dictWord{10, 10, 307}, - dictWord{10, 10, 463}, - dictWord{10, 10, 671}, - dictWord{10, 10, 746}, - dictWord{11, 10, 401}, - dictWord{11, 10, 794}, - dictWord{ - 11, - 11, - 895, - }, - dictWord{12, 10, 517}, - dictWord{17, 11, 11}, - dictWord{18, 10, 107}, - dictWord{147, 10, 115}, - dictWord{5, 0, 878}, - dictWord{133, 0, 972}, - dictWord{ - 6, - 11, - 1665, - }, - dictWord{7, 11, 256}, - dictWord{7, 11, 1388}, - dictWord{138, 11, 499}, - dictWord{4, 10, 258}, - dictWord{136, 10, 639}, - dictWord{4, 11, 22}, - dictWord{5, 11, 10}, - dictWord{6, 10, 22}, - dictWord{7, 11, 848}, - dictWord{7, 10, 903}, - dictWord{7, 10, 1963}, - dictWord{8, 11, 97}, - dictWord{138, 10, 577}, - dictWord{ - 5, - 10, - 681, - }, - dictWord{136, 10, 782}, - dictWord{133, 11, 481}, - dictWord{132, 0, 351}, - dictWord{4, 10, 664}, - dictWord{5, 10, 804}, - dictWord{139, 10, 1013}, - dictWord{6, 11, 134}, - dictWord{7, 11, 437}, - dictWord{7, 11, 959}, - dictWord{9, 11, 37}, - dictWord{14, 11, 285}, - dictWord{14, 11, 371}, - dictWord{144, 11, 60}, - dictWord{7, 11, 486}, - dictWord{8, 11, 155}, - dictWord{11, 11, 93}, - dictWord{140, 11, 164}, - dictWord{132, 0, 286}, - dictWord{7, 0, 438}, - dictWord{7, 0, 627}, - dictWord{7, 0, 1516}, - dictWord{8, 0, 40}, - dictWord{9, 0, 56}, - dictWord{9, 0, 294}, - dictWord{10, 0, 30}, - dictWord{11, 0, 969}, - dictWord{11, 0, 995}, - dictWord{146, 0, 148}, - dictWord{5, 11, 591}, - dictWord{135, 11, 337}, - dictWord{134, 0, 1950}, - dictWord{133, 10, 32}, - dictWord{138, 11, 500}, - dictWord{5, 11, 380}, - dictWord{ - 5, - 11, - 650, - }, - dictWord{136, 11, 310}, - dictWord{4, 11, 364}, - dictWord{7, 11, 1156}, - dictWord{7, 11, 1187}, - dictWord{137, 11, 409}, - dictWord{4, 0, 738}, - dictWord{134, 11, 482}, - dictWord{4, 11, 781}, - dictWord{6, 11, 487}, - dictWord{7, 11, 926}, - dictWord{8, 11, 263}, - dictWord{139, 11, 500}, - dictWord{135, 11, 418}, - dictWord{6, 0, 2047}, - dictWord{10, 0, 969}, - dictWord{4, 10, 289}, - dictWord{7, 10, 629}, - dictWord{7, 10, 1698}, - dictWord{7, 10, 1711}, - dictWord{ - 140, - 10, - 215, - }, - dictWord{6, 10, 450}, - dictWord{136, 10, 109}, - dictWord{134, 0, 818}, - dictWord{136, 10, 705}, - dictWord{133, 0, 866}, - dictWord{4, 11, 94}, - dictWord{ - 135, - 11, - 1265, - }, - dictWord{132, 11, 417}, - dictWord{134, 0, 1467}, - dictWord{135, 10, 1238}, - dictWord{4, 0, 972}, - dictWord{6, 0, 1851}, - dictWord{ - 134, - 0, - 1857, - }, - dictWord{134, 0, 355}, - dictWord{133, 0, 116}, - dictWord{132, 0, 457}, - dictWord{135, 11, 1411}, - dictWord{4, 11, 408}, - dictWord{4, 11, 741}, - dictWord{135, 11, 500}, - dictWord{134, 10, 26}, - dictWord{142, 11, 137}, - dictWord{5, 0, 527}, - dictWord{6, 0, 189}, - dictWord{7, 0, 859}, - dictWord{136, 0, 267}, - dictWord{11, 0, 104}, - dictWord{11, 0, 554}, - dictWord{15, 0, 60}, - dictWord{143, 0, 125}, - dictWord{134, 0, 1613}, - dictWord{4, 10, 414}, - dictWord{5, 10, 467}, - dictWord{ - 9, - 10, - 654, - }, - dictWord{10, 10, 451}, - dictWord{12, 10, 59}, - dictWord{141, 10, 375}, - dictWord{135, 10, 17}, - dictWord{134, 0, 116}, - dictWord{135, 11, 541}, - dictWord{135, 10, 955}, - dictWord{6, 11, 73}, - dictWord{135, 11, 177}, - dictWord{133, 11, 576}, - dictWord{134, 0, 886}, - dictWord{133, 0, 487}, - dictWord{ - 4, - 0, - 86, - }, - dictWord{5, 0, 667}, - dictWord{5, 0, 753}, - dictWord{6, 0, 316}, - dictWord{6, 0, 455}, - dictWord{135, 0, 946}, - dictWord{142, 11, 231}, - dictWord{150, 0, 45}, - dictWord{134, 0, 863}, - dictWord{134, 0, 1953}, - dictWord{6, 10, 280}, - dictWord{10, 10, 502}, - dictWord{11, 10, 344}, - dictWord{140, 10, 38}, - dictWord{4, 0, 79}, - dictWord{7, 0, 1773}, - dictWord{10, 0, 450}, - dictWord{11, 0, 589}, - dictWord{13, 0, 332}, - dictWord{13, 0, 493}, - dictWord{14, 0, 183}, - dictWord{14, 0, 334}, - dictWord{14, 0, 362}, - dictWord{14, 0, 368}, - dictWord{14, 0, 376}, - dictWord{14, 0, 379}, - dictWord{19, 0, 90}, - dictWord{19, 0, 103}, - dictWord{19, 0, 127}, - dictWord{ - 148, - 0, - 90, - }, - dictWord{5, 10, 45}, - dictWord{7, 10, 1161}, - dictWord{11, 10, 448}, - dictWord{11, 10, 880}, - dictWord{13, 10, 139}, - dictWord{13, 10, 407}, - dictWord{ - 15, - 10, - 16, - }, - dictWord{17, 10, 95}, - dictWord{18, 10, 66}, - dictWord{18, 10, 88}, - dictWord{18, 10, 123}, - dictWord{149, 10, 7}, - dictWord{136, 10, 777}, - dictWord{ - 4, - 10, - 410, - }, - dictWord{135, 10, 521}, - dictWord{135, 10, 1778}, - dictWord{135, 11, 538}, - dictWord{142, 0, 381}, - dictWord{133, 11, 413}, - dictWord{ - 134, - 0, - 1142, - }, - dictWord{6, 0, 1189}, - dictWord{136, 11, 495}, - dictWord{5, 0, 663}, - dictWord{6, 0, 1962}, - dictWord{134, 0, 2003}, - dictWord{7, 11, 54}, - dictWord{ - 8, - 11, - 312, - }, - dictWord{10, 11, 191}, - dictWord{10, 11, 614}, - dictWord{140, 11, 567}, - dictWord{132, 10, 436}, - dictWord{133, 0, 846}, - dictWord{10, 0, 528}, - dictWord{11, 0, 504}, - dictWord{7, 10, 1587}, - dictWord{135, 10, 1707}, - dictWord{5, 0, 378}, - dictWord{8, 0, 465}, - dictWord{9, 0, 286}, - dictWord{10, 0, 185}, - dictWord{ - 10, - 0, - 562, - }, - dictWord{10, 0, 635}, - dictWord{11, 0, 31}, - dictWord{11, 0, 393}, - dictWord{13, 0, 312}, - dictWord{18, 0, 65}, - dictWord{18, 0, 96}, - dictWord{147, 0, 89}, - dictWord{7, 0, 899}, - dictWord{14, 0, 325}, - dictWord{6, 11, 468}, - dictWord{7, 11, 567}, - dictWord{7, 11, 1478}, - dictWord{8, 11, 530}, - dictWord{142, 11, 290}, - dictWord{7, 0, 1880}, - dictWord{9, 0, 680}, - dictWord{139, 0, 798}, - dictWord{134, 0, 1770}, - dictWord{132, 0, 648}, - dictWord{150, 11, 35}, - dictWord{5, 0, 945}, - dictWord{6, 0, 1656}, - dictWord{6, 0, 1787}, - dictWord{7, 0, 167}, - dictWord{8, 0, 824}, - dictWord{9, 0, 391}, - dictWord{10, 0, 375}, - dictWord{139, 0, 185}, - dictWord{ - 6, - 11, - 484, - }, - dictWord{135, 11, 822}, - dictWord{134, 0, 2046}, - dictWord{7, 0, 1645}, - dictWord{8, 0, 352}, - dictWord{137, 0, 249}, - dictWord{132, 0, 152}, - dictWord{6, 0, 611}, - dictWord{135, 0, 1733}, - dictWord{6, 11, 1724}, - dictWord{135, 11, 2022}, - dictWord{133, 0, 1006}, - dictWord{141, 11, 96}, - dictWord{ - 5, - 0, - 420, - }, - dictWord{135, 0, 1449}, - dictWord{146, 11, 149}, - dictWord{135, 0, 832}, - dictWord{135, 10, 663}, - dictWord{133, 0, 351}, - dictWord{5, 0, 40}, - dictWord{ - 7, - 0, - 598, - }, - dictWord{7, 0, 1638}, - dictWord{8, 0, 78}, - dictWord{9, 0, 166}, - dictWord{9, 0, 640}, - dictWord{9, 0, 685}, - dictWord{9, 0, 773}, - dictWord{11, 0, 215}, - dictWord{13, 0, 65}, - dictWord{14, 0, 172}, - dictWord{14, 0, 317}, - dictWord{145, 0, 6}, - dictWord{8, 0, 60}, - dictWord{9, 0, 343}, - dictWord{139, 0, 769}, - dictWord{ - 134, - 0, - 1354, - }, - dictWord{132, 0, 724}, - dictWord{137, 0, 745}, - dictWord{132, 11, 474}, - dictWord{7, 0, 1951}, - dictWord{8, 0, 765}, - dictWord{8, 0, 772}, - dictWord{ - 140, - 0, - 671, - }, - dictWord{7, 0, 108}, - dictWord{8, 0, 219}, - dictWord{8, 0, 388}, - dictWord{9, 0, 775}, - dictWord{11, 0, 275}, - dictWord{140, 0, 464}, - dictWord{137, 0, 639}, - dictWord{135, 10, 503}, - dictWord{133, 11, 366}, - dictWord{5, 0, 15}, - dictWord{6, 0, 56}, - dictWord{7, 0, 1758}, - dictWord{8, 0, 500}, - dictWord{9, 0, 730}, - dictWord{ - 11, - 0, - 331, - }, - dictWord{13, 0, 150}, - dictWord{14, 0, 282}, - dictWord{5, 11, 305}, - dictWord{9, 11, 560}, - dictWord{141, 11, 208}, - dictWord{4, 10, 113}, - dictWord{ - 5, - 10, - 163, - }, - dictWord{5, 10, 735}, - dictWord{7, 10, 1009}, - dictWord{9, 10, 9}, - dictWord{9, 10, 771}, - dictWord{12, 10, 90}, - dictWord{13, 10, 138}, - dictWord{ - 13, - 10, - 410, - }, - dictWord{143, 10, 128}, - dictWord{4, 10, 324}, - dictWord{138, 10, 104}, - dictWord{135, 11, 466}, - dictWord{142, 11, 27}, - dictWord{134, 0, 1886}, - dictWord{5, 0, 205}, - dictWord{6, 0, 438}, - dictWord{9, 0, 711}, - dictWord{4, 11, 480}, - dictWord{6, 11, 167}, - dictWord{6, 11, 302}, - dictWord{6, 11, 1642}, - dictWord{ - 7, - 11, - 130, - }, - dictWord{7, 11, 656}, - dictWord{7, 11, 837}, - dictWord{7, 11, 1547}, - dictWord{7, 11, 1657}, - dictWord{8, 11, 429}, - dictWord{9, 11, 228}, - dictWord{ - 10, - 11, - 643, - }, - dictWord{13, 11, 289}, - dictWord{13, 11, 343}, - dictWord{147, 11, 101}, - dictWord{134, 0, 865}, - dictWord{6, 0, 2025}, - dictWord{136, 0, 965}, - dictWord{ - 7, - 11, - 278, - }, - dictWord{10, 11, 739}, - dictWord{11, 11, 708}, - dictWord{141, 11, 348}, - dictWord{133, 0, 534}, - dictWord{135, 11, 1922}, - dictWord{ - 137, - 0, - 691, - }, - dictWord{4, 10, 935}, - dictWord{133, 10, 823}, - dictWord{6, 0, 443}, - dictWord{9, 0, 237}, - dictWord{9, 0, 571}, - dictWord{9, 0, 695}, - dictWord{10, 0, 139}, - dictWord{11, 0, 715}, - dictWord{12, 0, 417}, - dictWord{141, 0, 421}, - dictWord{5, 10, 269}, - dictWord{7, 10, 434}, - dictWord{7, 10, 891}, - dictWord{8, 10, 339}, - dictWord{ - 9, - 10, - 702, - }, - dictWord{11, 10, 594}, - dictWord{11, 10, 718}, - dictWord{145, 10, 100}, - dictWord{6, 0, 1555}, - dictWord{7, 0, 878}, - dictWord{9, 10, 485}, - dictWord{141, 10, 264}, - dictWord{134, 10, 1713}, - dictWord{7, 10, 1810}, - dictWord{11, 10, 866}, - dictWord{12, 10, 103}, - dictWord{141, 10, 495}, - dictWord{ - 135, - 10, - 900, - }, - dictWord{6, 0, 1410}, - dictWord{9, 11, 316}, - dictWord{139, 11, 256}, - dictWord{4, 0, 995}, - dictWord{135, 0, 1033}, - dictWord{132, 0, 578}, - dictWord{10, 0, 881}, - dictWord{12, 0, 740}, - dictWord{12, 0, 743}, - dictWord{140, 0, 759}, - dictWord{132, 0, 822}, - dictWord{133, 0, 923}, - dictWord{142, 10, 143}, - dictWord{135, 11, 1696}, - dictWord{6, 11, 363}, - dictWord{7, 11, 1955}, - dictWord{136, 11, 725}, - dictWord{132, 0, 924}, - dictWord{133, 0, 665}, - dictWord{ - 135, - 10, - 2029, - }, - dictWord{135, 0, 1901}, - dictWord{4, 0, 265}, - dictWord{6, 0, 1092}, - dictWord{6, 0, 1417}, - dictWord{7, 0, 807}, - dictWord{135, 0, 950}, - dictWord{ - 5, - 0, - 93, - }, - dictWord{12, 0, 267}, - dictWord{141, 0, 498}, - dictWord{135, 0, 1451}, - dictWord{5, 11, 813}, - dictWord{135, 11, 2046}, - dictWord{5, 10, 625}, - dictWord{135, 10, 1617}, - dictWord{135, 0, 747}, - dictWord{6, 0, 788}, - dictWord{137, 0, 828}, - dictWord{7, 0, 184}, - dictWord{11, 0, 307}, - dictWord{11, 0, 400}, - dictWord{15, 0, 130}, - dictWord{5, 11, 712}, - dictWord{7, 11, 1855}, - dictWord{8, 10, 425}, - dictWord{8, 10, 693}, - dictWord{9, 10, 720}, - dictWord{10, 10, 380}, - dictWord{10, 10, 638}, - dictWord{11, 11, 17}, - dictWord{11, 10, 473}, - dictWord{12, 10, 61}, - dictWord{13, 11, 321}, - dictWord{144, 11, 67}, - dictWord{135, 0, 198}, - dictWord{6, 11, 320}, - dictWord{7, 11, 781}, - dictWord{7, 11, 1921}, - dictWord{9, 11, 55}, - dictWord{10, 11, 186}, - dictWord{10, 11, 273}, - dictWord{10, 11, 664}, - dictWord{10, 11, 801}, - dictWord{11, 11, 996}, - dictWord{11, 11, 997}, - dictWord{13, 11, 157}, - dictWord{142, 11, 170}, - dictWord{136, 11, 271}, - dictWord{ - 135, - 0, - 994, - }, - dictWord{7, 11, 103}, - dictWord{7, 11, 863}, - dictWord{11, 11, 184}, - dictWord{14, 11, 299}, - dictWord{145, 11, 62}, - dictWord{11, 10, 551}, - dictWord{142, 10, 159}, - dictWord{5, 0, 233}, - dictWord{5, 0, 320}, - dictWord{6, 0, 140}, - dictWord{8, 0, 295}, - dictWord{8, 0, 615}, - dictWord{136, 11, 615}, - dictWord{ - 133, - 0, - 978, - }, - dictWord{4, 0, 905}, - dictWord{6, 0, 1701}, - dictWord{137, 0, 843}, - dictWord{132, 10, 168}, - dictWord{4, 0, 974}, - dictWord{8, 0, 850}, - dictWord{ - 12, - 0, - 709, - }, - dictWord{12, 0, 768}, - dictWord{140, 0, 786}, - dictWord{135, 10, 91}, - dictWord{152, 0, 6}, - dictWord{138, 10, 532}, - dictWord{135, 10, 1884}, - dictWord{132, 0, 509}, - dictWord{6, 0, 1307}, - dictWord{135, 0, 273}, - dictWord{5, 11, 77}, - dictWord{7, 11, 1455}, - dictWord{10, 11, 843}, - dictWord{19, 11, 73}, - dictWord{150, 11, 5}, - dictWord{132, 11, 458}, - dictWord{135, 11, 1420}, - dictWord{6, 11, 109}, - dictWord{138, 11, 382}, - dictWord{6, 0, 201}, - dictWord{6, 11, 330}, - dictWord{7, 10, 70}, - dictWord{7, 11, 1084}, - dictWord{10, 10, 240}, - dictWord{11, 11, 142}, - dictWord{147, 10, 93}, - dictWord{7, 0, 1041}, - dictWord{ - 140, - 11, - 328, - }, - dictWord{133, 11, 354}, - dictWord{134, 0, 1040}, - dictWord{133, 0, 693}, - dictWord{134, 0, 774}, - dictWord{139, 0, 234}, - dictWord{132, 0, 336}, - dictWord{7, 0, 1399}, - dictWord{139, 10, 392}, - dictWord{20, 0, 22}, - dictWord{148, 11, 22}, - dictWord{5, 0, 802}, - dictWord{7, 0, 2021}, - dictWord{136, 0, 805}, - dictWord{ - 5, - 0, - 167, - }, - dictWord{5, 0, 899}, - dictWord{6, 0, 410}, - dictWord{137, 0, 777}, - dictWord{137, 0, 789}, - dictWord{134, 0, 1705}, - dictWord{7, 10, 655}, - dictWord{ - 135, - 10, - 1844, - }, - dictWord{4, 10, 145}, - dictWord{6, 10, 176}, - dictWord{7, 10, 395}, - dictWord{137, 10, 562}, - dictWord{132, 10, 501}, - dictWord{135, 0, 10}, - dictWord{5, 0, 11}, - dictWord{6, 0, 117}, - dictWord{6, 0, 485}, - dictWord{7, 0, 1133}, - dictWord{9, 0, 582}, - dictWord{9, 0, 594}, - dictWord{10, 0, 82}, - dictWord{11, 0, 21}, - dictWord{11, 0, 818}, - dictWord{12, 0, 535}, - dictWord{13, 0, 86}, - dictWord{20, 0, 91}, - dictWord{23, 0, 13}, - dictWord{134, 10, 509}, - dictWord{4, 0, 264}, - dictWord{ - 7, - 0, - 1067, - }, - dictWord{8, 0, 204}, - dictWord{8, 0, 385}, - dictWord{139, 0, 953}, - dictWord{139, 11, 737}, - dictWord{138, 0, 56}, - dictWord{134, 0, 1917}, - dictWord{ - 133, - 0, - 470, - }, - dictWord{10, 11, 657}, - dictWord{14, 11, 297}, - dictWord{142, 11, 361}, - dictWord{135, 11, 412}, - dictWord{7, 0, 1198}, - dictWord{7, 11, 1198}, - dictWord{8, 11, 556}, - dictWord{14, 11, 123}, - dictWord{14, 11, 192}, - dictWord{143, 11, 27}, - dictWord{7, 11, 1985}, - dictWord{14, 11, 146}, - dictWord{15, 11, 42}, - dictWord{16, 11, 23}, - dictWord{17, 11, 86}, - dictWord{146, 11, 17}, - dictWord{11, 0, 1015}, - dictWord{136, 11, 122}, - dictWord{4, 10, 114}, - dictWord{ - 9, - 10, - 492, - }, - dictWord{13, 10, 462}, - dictWord{142, 10, 215}, - dictWord{4, 10, 77}, - dictWord{5, 10, 361}, - dictWord{6, 10, 139}, - dictWord{6, 10, 401}, - dictWord{ - 6, - 10, - 404, - }, - dictWord{7, 10, 413}, - dictWord{7, 10, 715}, - dictWord{7, 10, 1716}, - dictWord{11, 10, 279}, - dictWord{12, 10, 179}, - dictWord{12, 10, 258}, - dictWord{ - 13, - 10, - 244, - }, - dictWord{142, 10, 358}, - dictWord{134, 10, 1717}, - dictWord{7, 10, 1061}, - dictWord{8, 10, 82}, - dictWord{11, 10, 250}, - dictWord{12, 10, 420}, - dictWord{141, 10, 184}, - dictWord{133, 0, 715}, - dictWord{135, 10, 724}, - dictWord{9, 0, 919}, - dictWord{9, 0, 922}, - dictWord{9, 0, 927}, - dictWord{9, 0, 933}, - dictWord{9, 0, 962}, - dictWord{9, 0, 1000}, - dictWord{9, 0, 1002}, - dictWord{9, 0, 1021}, - dictWord{12, 0, 890}, - dictWord{12, 0, 907}, - dictWord{12, 0, 930}, - dictWord{ - 15, - 0, - 207, - }, - dictWord{15, 0, 228}, - dictWord{15, 0, 238}, - dictWord{149, 0, 61}, - dictWord{8, 0, 794}, - dictWord{9, 0, 400}, - dictWord{10, 0, 298}, - dictWord{142, 0, 228}, - dictWord{5, 11, 430}, - dictWord{5, 11, 932}, - dictWord{6, 11, 131}, - dictWord{7, 11, 417}, - dictWord{9, 11, 522}, - dictWord{11, 11, 314}, - dictWord{141, 11, 390}, - dictWord{132, 0, 867}, - dictWord{8, 0, 724}, - dictWord{132, 11, 507}, - dictWord{137, 11, 261}, - dictWord{4, 11, 343}, - dictWord{133, 11, 511}, - dictWord{ - 6, - 0, - 190, - }, - dictWord{7, 0, 768}, - dictWord{135, 0, 1170}, - dictWord{6, 10, 513}, - dictWord{135, 10, 1052}, - dictWord{7, 11, 455}, - dictWord{138, 11, 591}, - dictWord{134, 0, 1066}, - dictWord{137, 10, 899}, - dictWord{14, 0, 67}, - dictWord{147, 0, 60}, - dictWord{4, 0, 948}, - dictWord{18, 0, 174}, - dictWord{146, 0, 176}, - dictWord{135, 0, 1023}, - dictWord{7, 10, 1417}, - dictWord{12, 10, 382}, - dictWord{17, 10, 48}, - dictWord{152, 10, 12}, - dictWord{134, 11, 575}, - dictWord{ - 132, - 0, - 764, - }, - dictWord{6, 10, 545}, - dictWord{7, 10, 565}, - dictWord{7, 10, 1669}, - dictWord{10, 10, 114}, - dictWord{11, 10, 642}, - dictWord{140, 10, 618}, - dictWord{ - 6, - 0, - 137, - }, - dictWord{9, 0, 75}, - dictWord{9, 0, 253}, - dictWord{10, 0, 194}, - dictWord{138, 0, 444}, - dictWord{4, 0, 756}, - dictWord{133, 10, 5}, - dictWord{8, 0, 1008}, - dictWord{135, 10, 192}, - dictWord{132, 0, 842}, - dictWord{11, 0, 643}, - dictWord{12, 0, 115}, - dictWord{136, 10, 763}, - dictWord{139, 0, 67}, - dictWord{ - 133, - 10, - 759, - }, - dictWord{4, 0, 821}, - dictWord{5, 0, 760}, - dictWord{7, 0, 542}, - dictWord{8, 0, 135}, - dictWord{8, 0, 496}, - dictWord{135, 11, 580}, - dictWord{7, 10, 370}, - dictWord{7, 10, 1007}, - dictWord{7, 10, 1177}, - dictWord{135, 10, 1565}, - dictWord{135, 10, 1237}, - dictWord{140, 0, 736}, - dictWord{7, 0, 319}, - dictWord{ - 7, - 0, - 355, - }, - dictWord{7, 0, 763}, - dictWord{10, 0, 389}, - dictWord{145, 0, 43}, - dictWord{8, 11, 333}, - dictWord{138, 11, 182}, - dictWord{4, 10, 87}, - dictWord{5, 10, 250}, - dictWord{141, 10, 298}, - dictWord{138, 0, 786}, - dictWord{134, 0, 2044}, - dictWord{8, 11, 330}, - dictWord{140, 11, 477}, - dictWord{135, 11, 1338}, - dictWord{132, 11, 125}, - dictWord{134, 0, 1030}, - dictWord{134, 0, 1083}, - dictWord{132, 11, 721}, - dictWord{135, 10, 814}, - dictWord{7, 11, 776}, - dictWord{ - 8, - 11, - 145, - }, - dictWord{147, 11, 56}, - dictWord{134, 0, 1226}, - dictWord{4, 10, 57}, - dictWord{7, 10, 1195}, - dictWord{7, 10, 1438}, - dictWord{7, 10, 1548}, - dictWord{ - 7, - 10, - 1835, - }, - dictWord{7, 10, 1904}, - dictWord{9, 10, 757}, - dictWord{10, 10, 604}, - dictWord{139, 10, 519}, - dictWord{7, 11, 792}, - dictWord{8, 11, 147}, - dictWord{10, 11, 821}, - dictWord{139, 11, 1021}, - dictWord{137, 11, 797}, - dictWord{4, 0, 58}, - dictWord{5, 0, 286}, - dictWord{6, 0, 319}, - dictWord{7, 0, 402}, - dictWord{ - 7, - 0, - 1254, - }, - dictWord{7, 0, 1903}, - dictWord{8, 0, 356}, - dictWord{140, 0, 408}, - dictWord{4, 0, 389}, - dictWord{4, 0, 815}, - dictWord{9, 0, 181}, - dictWord{9, 0, 255}, - dictWord{10, 0, 8}, - dictWord{10, 0, 29}, - dictWord{10, 0, 816}, - dictWord{11, 0, 311}, - dictWord{11, 0, 561}, - dictWord{12, 0, 67}, - dictWord{141, 0, 181}, - dictWord{ - 7, - 11, - 1472, - }, - dictWord{135, 11, 1554}, - dictWord{7, 11, 1071}, - dictWord{7, 11, 1541}, - dictWord{7, 11, 1767}, - dictWord{7, 11, 1806}, - dictWord{7, 11, 1999}, - dictWord{9, 11, 248}, - dictWord{10, 11, 400}, - dictWord{11, 11, 162}, - dictWord{11, 11, 178}, - dictWord{11, 11, 242}, - dictWord{12, 11, 605}, - dictWord{ - 15, - 11, - 26, - }, - dictWord{144, 11, 44}, - dictWord{5, 11, 168}, - dictWord{5, 11, 930}, - dictWord{8, 11, 74}, - dictWord{9, 11, 623}, - dictWord{12, 11, 500}, - dictWord{ - 12, - 11, - 579, - }, - dictWord{13, 11, 41}, - dictWord{143, 11, 93}, - dictWord{6, 11, 220}, - dictWord{7, 11, 1101}, - dictWord{141, 11, 105}, - dictWord{5, 0, 474}, - dictWord{ - 7, - 0, - 507, - }, - dictWord{4, 10, 209}, - dictWord{7, 11, 507}, - dictWord{135, 10, 902}, - dictWord{132, 0, 427}, - dictWord{6, 0, 413}, - dictWord{7, 10, 335}, - dictWord{ - 7, - 10, - 1437, - }, - dictWord{7, 10, 1668}, - dictWord{8, 10, 553}, - dictWord{8, 10, 652}, - dictWord{8, 10, 656}, - dictWord{9, 10, 558}, - dictWord{11, 10, 743}, - dictWord{ - 149, - 10, - 18, - }, - dictWord{132, 0, 730}, - dictWord{6, 11, 19}, - dictWord{7, 11, 1413}, - dictWord{139, 11, 428}, - dictWord{133, 0, 373}, - dictWord{132, 10, 559}, - dictWord{7, 11, 96}, - dictWord{8, 11, 401}, - dictWord{137, 11, 896}, - dictWord{7, 0, 799}, - dictWord{7, 0, 1972}, - dictWord{5, 10, 1017}, - dictWord{138, 10, 511}, - dictWord{135, 0, 1793}, - dictWord{7, 11, 1961}, - dictWord{7, 11, 1965}, - dictWord{8, 11, 702}, - dictWord{136, 11, 750}, - dictWord{8, 11, 150}, - dictWord{8, 11, 737}, - dictWord{140, 11, 366}, - dictWord{132, 0, 322}, - dictWord{133, 10, 709}, - dictWord{8, 11, 800}, - dictWord{9, 11, 148}, - dictWord{9, 11, 872}, - dictWord{ - 9, - 11, - 890, - }, - dictWord{11, 11, 309}, - dictWord{11, 11, 1001}, - dictWord{13, 11, 267}, - dictWord{141, 11, 323}, - dictWord{134, 10, 1745}, - dictWord{7, 0, 290}, - dictWord{136, 10, 206}, - dictWord{7, 0, 1651}, - dictWord{145, 0, 89}, - dictWord{139, 0, 2}, - dictWord{132, 0, 672}, - dictWord{6, 0, 1860}, - dictWord{8, 0, 905}, - dictWord{ - 10, - 0, - 844, - }, - dictWord{10, 0, 846}, - dictWord{10, 0, 858}, - dictWord{12, 0, 699}, - dictWord{12, 0, 746}, - dictWord{140, 0, 772}, - dictWord{135, 11, 424}, - dictWord{133, 11, 547}, - dictWord{133, 0, 737}, - dictWord{5, 11, 490}, - dictWord{6, 11, 615}, - dictWord{6, 11, 620}, - dictWord{135, 11, 683}, - dictWord{6, 0, 746}, - dictWord{134, 0, 1612}, - dictWord{132, 10, 776}, - dictWord{9, 11, 385}, - dictWord{149, 11, 17}, - dictWord{133, 0, 145}, - dictWord{135, 10, 1272}, - dictWord{ - 7, - 0, - 884, - }, - dictWord{140, 0, 124}, - dictWord{4, 0, 387}, - dictWord{135, 0, 1288}, - dictWord{5, 11, 133}, - dictWord{136, 10, 406}, - dictWord{136, 11, 187}, - dictWord{ - 6, - 0, - 679, - }, - dictWord{8, 11, 8}, - dictWord{138, 11, 0}, - dictWord{135, 0, 550}, - dictWord{135, 11, 798}, - dictWord{136, 11, 685}, - dictWord{7, 11, 1086}, - dictWord{145, 11, 46}, - dictWord{8, 10, 175}, - dictWord{10, 10, 168}, - dictWord{138, 10, 573}, - dictWord{135, 0, 1305}, - dictWord{4, 0, 576}, - dictWord{ - 135, - 0, - 1263, - }, - dictWord{6, 0, 686}, - dictWord{134, 0, 1563}, - dictWord{134, 0, 607}, - dictWord{5, 0, 919}, - dictWord{134, 0, 1673}, - dictWord{148, 0, 37}, - dictWord{ - 8, - 11, - 774, - }, - dictWord{10, 11, 670}, - dictWord{140, 11, 51}, - dictWord{133, 10, 784}, - dictWord{139, 10, 882}, - dictWord{4, 0, 82}, - dictWord{5, 0, 333}, - dictWord{ - 5, - 0, - 904, - }, - dictWord{6, 0, 207}, - dictWord{7, 0, 325}, - dictWord{7, 0, 1726}, - dictWord{8, 0, 101}, - dictWord{10, 0, 778}, - dictWord{139, 0, 220}, - dictWord{135, 11, 371}, - dictWord{132, 0, 958}, - dictWord{133, 0, 903}, - dictWord{4, 11, 127}, - dictWord{5, 11, 350}, - dictWord{6, 11, 356}, - dictWord{8, 11, 426}, - dictWord{9, 11, 572}, - dictWord{10, 11, 247}, - dictWord{139, 11, 312}, - dictWord{140, 0, 147}, - dictWord{6, 11, 59}, - dictWord{7, 11, 885}, - dictWord{9, 11, 603}, - dictWord{ - 141, - 11, - 397, - }, - dictWord{10, 0, 367}, - dictWord{9, 10, 14}, - dictWord{9, 10, 441}, - dictWord{139, 10, 9}, - dictWord{11, 10, 966}, - dictWord{12, 10, 287}, - dictWord{ - 13, - 10, - 342, - }, - dictWord{13, 10, 402}, - dictWord{15, 10, 110}, - dictWord{143, 10, 163}, - dictWord{134, 0, 690}, - dictWord{132, 0, 705}, - dictWord{9, 0, 651}, - dictWord{ - 11, - 0, - 971, - }, - dictWord{13, 0, 273}, - dictWord{7, 10, 1428}, - dictWord{7, 10, 1640}, - dictWord{7, 10, 1867}, - dictWord{9, 10, 169}, - dictWord{9, 10, 182}, - dictWord{ - 9, - 10, - 367, - }, - dictWord{9, 10, 478}, - dictWord{9, 10, 506}, - dictWord{9, 10, 551}, - dictWord{9, 10, 557}, - dictWord{9, 10, 648}, - dictWord{9, 10, 697}, - dictWord{ - 9, - 10, - 705, - }, - dictWord{9, 10, 725}, - dictWord{9, 10, 787}, - dictWord{9, 10, 794}, - dictWord{10, 10, 198}, - dictWord{10, 10, 214}, - dictWord{10, 10, 267}, - dictWord{ - 10, - 10, - 275, - }, - dictWord{10, 10, 456}, - dictWord{10, 10, 551}, - dictWord{10, 10, 561}, - dictWord{10, 10, 613}, - dictWord{10, 10, 627}, - dictWord{10, 10, 668}, - dictWord{10, 10, 675}, - dictWord{10, 10, 691}, - dictWord{10, 10, 695}, - dictWord{10, 10, 707}, - dictWord{10, 10, 715}, - dictWord{11, 10, 183}, - dictWord{ - 11, - 10, - 201, - }, - dictWord{11, 10, 262}, - dictWord{11, 10, 352}, - dictWord{11, 10, 439}, - dictWord{11, 10, 493}, - dictWord{11, 10, 572}, - dictWord{11, 10, 591}, - dictWord{ - 11, - 10, - 608, - }, - dictWord{11, 10, 611}, - dictWord{11, 10, 646}, - dictWord{11, 10, 674}, - dictWord{11, 10, 711}, - dictWord{11, 10, 751}, - dictWord{11, 10, 761}, - dictWord{11, 10, 776}, - dictWord{11, 10, 785}, - dictWord{11, 10, 850}, - dictWord{11, 10, 853}, - dictWord{11, 10, 862}, - dictWord{11, 10, 865}, - dictWord{ - 11, - 10, - 868, - }, - dictWord{11, 10, 875}, - dictWord{11, 10, 898}, - dictWord{11, 10, 902}, - dictWord{11, 10, 903}, - dictWord{11, 10, 910}, - dictWord{11, 10, 932}, - dictWord{ - 11, - 10, - 942, - }, - dictWord{11, 10, 957}, - dictWord{11, 10, 967}, - dictWord{11, 10, 972}, - dictWord{12, 10, 148}, - dictWord{12, 10, 195}, - dictWord{12, 10, 220}, - dictWord{12, 10, 237}, - dictWord{12, 10, 318}, - dictWord{12, 10, 339}, - dictWord{12, 10, 393}, - dictWord{12, 10, 445}, - dictWord{12, 10, 450}, - dictWord{ - 12, - 10, - 474, - }, - dictWord{12, 10, 505}, - dictWord{12, 10, 509}, - dictWord{12, 10, 533}, - dictWord{12, 10, 591}, - dictWord{12, 10, 594}, - dictWord{12, 10, 597}, - dictWord{ - 12, - 10, - 621, - }, - dictWord{12, 10, 633}, - dictWord{12, 10, 642}, - dictWord{13, 10, 59}, - dictWord{13, 10, 60}, - dictWord{13, 10, 145}, - dictWord{13, 10, 239}, - dictWord{13, 10, 250}, - dictWord{13, 10, 329}, - dictWord{13, 10, 344}, - dictWord{13, 10, 365}, - dictWord{13, 10, 372}, - dictWord{13, 10, 387}, - dictWord{ - 13, - 10, - 403, - }, - dictWord{13, 10, 414}, - dictWord{13, 10, 456}, - dictWord{13, 10, 470}, - dictWord{13, 10, 478}, - dictWord{13, 10, 483}, - dictWord{13, 10, 489}, - dictWord{ - 14, - 10, - 55, - }, - dictWord{14, 10, 57}, - dictWord{14, 10, 81}, - dictWord{14, 10, 90}, - dictWord{14, 10, 148}, - dictWord{14, 10, 239}, - dictWord{14, 10, 266}, - dictWord{ - 14, - 10, - 321, - }, - dictWord{14, 10, 326}, - dictWord{14, 10, 327}, - dictWord{14, 10, 330}, - dictWord{14, 10, 347}, - dictWord{14, 10, 355}, - dictWord{14, 10, 401}, - dictWord{14, 10, 404}, - dictWord{14, 10, 411}, - dictWord{14, 10, 414}, - dictWord{14, 10, 416}, - dictWord{14, 10, 420}, - dictWord{15, 10, 61}, - dictWord{ - 15, - 10, - 74, - }, - dictWord{15, 10, 87}, - dictWord{15, 10, 88}, - dictWord{15, 10, 94}, - dictWord{15, 10, 96}, - dictWord{15, 10, 116}, - dictWord{15, 10, 149}, - dictWord{ - 15, - 10, - 154, - }, - dictWord{16, 10, 50}, - dictWord{16, 10, 63}, - dictWord{16, 10, 73}, - dictWord{17, 10, 2}, - dictWord{17, 10, 66}, - dictWord{17, 10, 92}, - dictWord{17, 10, 103}, - dictWord{17, 10, 112}, - dictWord{17, 10, 120}, - dictWord{18, 10, 50}, - dictWord{18, 10, 54}, - dictWord{18, 10, 82}, - dictWord{18, 10, 86}, - dictWord{18, 10, 90}, - dictWord{18, 10, 111}, - dictWord{18, 10, 115}, - dictWord{18, 10, 156}, - dictWord{19, 10, 40}, - dictWord{19, 10, 79}, - dictWord{20, 10, 78}, - dictWord{149, 10, 22}, - dictWord{7, 0, 887}, - dictWord{5, 10, 161}, - dictWord{135, 10, 839}, - dictWord{142, 11, 98}, - dictWord{134, 0, 90}, - dictWord{138, 11, 356}, - dictWord{ - 135, - 11, - 441, - }, - dictWord{6, 11, 111}, - dictWord{7, 11, 4}, - dictWord{8, 11, 163}, - dictWord{8, 11, 776}, - dictWord{138, 11, 566}, - dictWord{134, 0, 908}, - dictWord{ - 134, - 0, - 1261, - }, - dictWord{7, 0, 813}, - dictWord{12, 0, 497}, - dictWord{141, 0, 56}, - dictWord{134, 0, 1235}, - dictWord{135, 0, 429}, - dictWord{135, 11, 1994}, - dictWord{138, 0, 904}, - dictWord{6, 0, 125}, - dictWord{7, 0, 1277}, - dictWord{137, 0, 772}, - dictWord{151, 0, 12}, - dictWord{4, 0, 841}, - dictWord{5, 0, 386}, - dictWord{ - 133, - 11, - 386, - }, - dictWord{5, 11, 297}, - dictWord{135, 11, 1038}, - dictWord{6, 0, 860}, - dictWord{6, 0, 1069}, - dictWord{135, 11, 309}, - dictWord{136, 0, 946}, - dictWord{135, 10, 1814}, - dictWord{141, 11, 418}, - dictWord{136, 11, 363}, - dictWord{10, 0, 768}, - dictWord{139, 0, 787}, - dictWord{22, 11, 30}, - dictWord{ - 150, - 11, - 33, - }, - dictWord{6, 0, 160}, - dictWord{7, 0, 1106}, - dictWord{9, 0, 770}, - dictWord{11, 0, 112}, - dictWord{140, 0, 413}, - dictWord{11, 11, 216}, - dictWord{ - 139, - 11, - 340, - }, - dictWord{136, 10, 139}, - dictWord{135, 11, 1390}, - dictWord{135, 11, 808}, - dictWord{132, 11, 280}, - dictWord{12, 0, 271}, - dictWord{17, 0, 109}, - dictWord{7, 10, 643}, - dictWord{136, 10, 236}, - dictWord{140, 11, 54}, - dictWord{4, 11, 421}, - dictWord{133, 11, 548}, - dictWord{11, 0, 719}, - dictWord{12, 0, 36}, - dictWord{141, 0, 337}, - dictWord{7, 0, 581}, - dictWord{9, 0, 644}, - dictWord{137, 0, 699}, - dictWord{11, 11, 511}, - dictWord{13, 11, 394}, - dictWord{14, 11, 298}, - dictWord{14, 11, 318}, - dictWord{146, 11, 103}, - dictWord{7, 0, 304}, - dictWord{9, 0, 646}, - dictWord{9, 0, 862}, - dictWord{11, 0, 696}, - dictWord{12, 0, 208}, - dictWord{15, 0, 79}, - dictWord{147, 0, 108}, - dictWord{4, 0, 631}, - dictWord{7, 0, 1126}, - dictWord{135, 0, 1536}, - dictWord{135, 11, 1527}, - dictWord{8, 0, 880}, - dictWord{10, 0, 869}, - dictWord{138, 0, 913}, - dictWord{7, 0, 1513}, - dictWord{5, 10, 54}, - dictWord{6, 11, 254}, - dictWord{9, 11, 109}, - dictWord{138, 11, 103}, - dictWord{135, 0, 981}, - dictWord{133, 11, 729}, - dictWord{132, 10, 744}, - dictWord{132, 0, 434}, - dictWord{134, 0, 550}, - dictWord{7, 0, 930}, - dictWord{10, 0, 476}, - dictWord{13, 0, 452}, - dictWord{19, 0, 104}, - dictWord{6, 11, 1630}, - dictWord{10, 10, 402}, - dictWord{146, 10, 55}, - dictWord{5, 0, 553}, - dictWord{138, 0, 824}, - dictWord{136, 0, 452}, - dictWord{8, 0, 151}, - dictWord{137, 10, 624}, - dictWord{132, 10, 572}, - dictWord{132, 0, 772}, - dictWord{133, 11, 671}, - dictWord{ - 133, - 0, - 292, - }, - dictWord{138, 0, 135}, - dictWord{132, 11, 889}, - dictWord{140, 11, 207}, - dictWord{9, 0, 504}, - dictWord{6, 10, 43}, - dictWord{7, 10, 38}, - dictWord{ - 8, - 10, - 248, - }, - dictWord{138, 10, 513}, - dictWord{6, 0, 1089}, - dictWord{135, 11, 1910}, - dictWord{4, 11, 627}, - dictWord{133, 11, 775}, - dictWord{135, 0, 783}, - dictWord{133, 10, 766}, - dictWord{133, 10, 363}, - dictWord{7, 0, 387}, - dictWord{135, 11, 387}, - dictWord{7, 0, 393}, - dictWord{10, 0, 603}, - dictWord{11, 0, 206}, - dictWord{7, 11, 202}, - dictWord{11, 11, 362}, - dictWord{11, 11, 948}, - dictWord{140, 11, 388}, - dictWord{6, 11, 507}, - dictWord{7, 11, 451}, - dictWord{8, 11, 389}, - dictWord{12, 11, 490}, - dictWord{13, 11, 16}, - dictWord{13, 11, 215}, - dictWord{13, 11, 351}, - dictWord{18, 11, 132}, - dictWord{147, 11, 125}, - dictWord{ - 4, - 0, - 912, - }, - dictWord{9, 0, 232}, - dictWord{135, 11, 841}, - dictWord{6, 10, 258}, - dictWord{140, 10, 409}, - dictWord{5, 10, 249}, - dictWord{148, 10, 82}, - dictWord{ - 136, - 11, - 566, - }, - dictWord{6, 0, 977}, - dictWord{135, 11, 1214}, - dictWord{7, 0, 1973}, - dictWord{136, 0, 716}, - dictWord{135, 0, 98}, - dictWord{133, 0, 733}, - dictWord{ - 5, - 11, - 912, - }, - dictWord{134, 11, 1695}, - dictWord{5, 10, 393}, - dictWord{6, 10, 378}, - dictWord{7, 10, 1981}, - dictWord{9, 10, 32}, - dictWord{9, 10, 591}, - dictWord{10, 10, 685}, - dictWord{10, 10, 741}, - dictWord{142, 10, 382}, - dictWord{133, 10, 788}, - dictWord{10, 0, 19}, - dictWord{11, 0, 911}, - dictWord{7, 10, 1968}, - dictWord{141, 10, 509}, - dictWord{5, 0, 668}, - dictWord{5, 11, 236}, - dictWord{6, 11, 572}, - dictWord{8, 11, 492}, - dictWord{11, 11, 618}, - dictWord{144, 11, 56}, - dictWord{135, 11, 1789}, - dictWord{4, 0, 360}, - dictWord{5, 0, 635}, - dictWord{5, 0, 700}, - dictWord{5, 10, 58}, - dictWord{5, 10, 171}, - dictWord{5, 10, 683}, - dictWord{ - 6, - 10, - 291, - }, - dictWord{6, 10, 566}, - dictWord{7, 10, 1650}, - dictWord{11, 10, 523}, - dictWord{12, 10, 273}, - dictWord{12, 10, 303}, - dictWord{15, 10, 39}, - dictWord{143, 10, 111}, - dictWord{133, 0, 901}, - dictWord{134, 10, 589}, - dictWord{5, 11, 190}, - dictWord{136, 11, 318}, - dictWord{140, 0, 656}, - dictWord{ - 7, - 0, - 726, - }, - dictWord{152, 0, 9}, - dictWord{4, 10, 917}, - dictWord{133, 10, 1005}, - dictWord{135, 10, 1598}, - dictWord{134, 11, 491}, - dictWord{4, 10, 919}, - dictWord{133, 11, 434}, - dictWord{137, 0, 72}, - dictWord{6, 0, 1269}, - dictWord{6, 0, 1566}, - dictWord{134, 0, 1621}, - dictWord{9, 0, 463}, - dictWord{10, 0, 595}, - dictWord{4, 10, 255}, - dictWord{5, 10, 302}, - dictWord{6, 10, 132}, - dictWord{7, 10, 128}, - dictWord{7, 10, 283}, - dictWord{7, 10, 1299}, - dictWord{10, 10, 52}, - dictWord{ - 10, - 10, - 514, - }, - dictWord{11, 10, 925}, - dictWord{13, 10, 92}, - dictWord{142, 10, 309}, - dictWord{135, 0, 1454}, - dictWord{134, 0, 1287}, - dictWord{11, 0, 600}, - dictWord{13, 0, 245}, - dictWord{137, 10, 173}, - dictWord{136, 0, 989}, - dictWord{7, 0, 164}, - dictWord{7, 0, 1571}, - dictWord{9, 0, 107}, - dictWord{140, 0, 225}, - dictWord{6, 0, 1061}, - dictWord{141, 10, 442}, - dictWord{4, 0, 27}, - dictWord{5, 0, 484}, - dictWord{5, 0, 510}, - dictWord{6, 0, 434}, - dictWord{7, 0, 1000}, - dictWord{ - 7, - 0, - 1098, - }, - dictWord{136, 0, 2}, - dictWord{7, 11, 85}, - dictWord{7, 11, 247}, - dictWord{8, 11, 585}, - dictWord{10, 11, 163}, - dictWord{138, 11, 316}, - dictWord{ - 11, - 11, - 103, - }, - dictWord{142, 11, 0}, - dictWord{134, 0, 1127}, - dictWord{4, 0, 460}, - dictWord{134, 0, 852}, - dictWord{134, 10, 210}, - dictWord{4, 0, 932}, - dictWord{ - 133, - 0, - 891, - }, - dictWord{6, 0, 588}, - dictWord{147, 11, 83}, - dictWord{8, 0, 625}, - dictWord{4, 10, 284}, - dictWord{134, 10, 223}, - dictWord{134, 0, 76}, - dictWord{8, 0, 92}, - dictWord{137, 0, 221}, - dictWord{4, 11, 124}, - dictWord{10, 11, 457}, - dictWord{11, 11, 121}, - dictWord{11, 11, 169}, - dictWord{11, 11, 422}, - dictWord{ - 11, - 11, - 870, - }, - dictWord{12, 11, 214}, - dictWord{13, 11, 389}, - dictWord{14, 11, 187}, - dictWord{143, 11, 77}, - dictWord{9, 11, 618}, - dictWord{138, 11, 482}, - dictWord{ - 4, - 10, - 218, - }, - dictWord{7, 10, 526}, - dictWord{143, 10, 137}, - dictWord{13, 0, 9}, - dictWord{14, 0, 104}, - dictWord{14, 0, 311}, - dictWord{4, 10, 270}, - dictWord{ - 5, - 10, - 192, - }, - dictWord{6, 10, 332}, - dictWord{135, 10, 1322}, - dictWord{140, 10, 661}, - dictWord{135, 11, 1193}, - dictWord{6, 11, 107}, - dictWord{7, 11, 638}, - dictWord{7, 11, 1632}, - dictWord{137, 11, 396}, - dictWord{132, 0, 763}, - dictWord{4, 0, 622}, - dictWord{5, 11, 370}, - dictWord{134, 11, 1756}, - dictWord{ - 133, - 0, - 253, - }, - dictWord{135, 0, 546}, - dictWord{9, 0, 73}, - dictWord{10, 0, 110}, - dictWord{14, 0, 185}, - dictWord{17, 0, 119}, - dictWord{133, 11, 204}, - dictWord{7, 0, 624}, - dictWord{7, 0, 916}, - dictWord{10, 0, 256}, - dictWord{139, 0, 87}, - dictWord{7, 10, 379}, - dictWord{8, 10, 481}, - dictWord{137, 10, 377}, - dictWord{5, 0, 212}, - dictWord{12, 0, 35}, - dictWord{13, 0, 382}, - dictWord{5, 11, 970}, - dictWord{134, 11, 1706}, - dictWord{9, 0, 746}, - dictWord{5, 10, 1003}, - dictWord{134, 10, 149}, - dictWord{10, 0, 150}, - dictWord{11, 0, 849}, - dictWord{13, 0, 330}, - dictWord{8, 10, 262}, - dictWord{9, 10, 627}, - dictWord{11, 10, 214}, - dictWord{11, 10, 404}, - dictWord{11, 10, 457}, - dictWord{11, 10, 780}, - dictWord{11, 10, 913}, - dictWord{13, 10, 401}, - dictWord{142, 10, 200}, - dictWord{134, 0, 1466}, - dictWord{ - 135, - 11, - 3, - }, - dictWord{6, 0, 1299}, - dictWord{4, 11, 35}, - dictWord{5, 11, 121}, - dictWord{5, 11, 483}, - dictWord{5, 11, 685}, - dictWord{6, 11, 489}, - dictWord{7, 11, 1204}, - dictWord{136, 11, 394}, - dictWord{135, 10, 742}, - dictWord{4, 10, 142}, - dictWord{136, 10, 304}, - dictWord{4, 11, 921}, - dictWord{133, 11, 1007}, - dictWord{ - 134, - 0, - 1518, - }, - dictWord{6, 0, 1229}, - dictWord{135, 0, 1175}, - dictWord{133, 0, 816}, - dictWord{12, 0, 159}, - dictWord{4, 10, 471}, - dictWord{4, 11, 712}, - dictWord{ - 5, - 10, - 51, - }, - dictWord{6, 10, 602}, - dictWord{7, 10, 925}, - dictWord{8, 10, 484}, - dictWord{138, 10, 195}, - dictWord{134, 11, 1629}, - dictWord{5, 0, 869}, - dictWord{ - 5, - 0, - 968, - }, - dictWord{6, 0, 1626}, - dictWord{8, 0, 734}, - dictWord{136, 0, 784}, - dictWord{4, 0, 542}, - dictWord{6, 0, 1716}, - dictWord{6, 0, 1727}, - dictWord{ - 7, - 0, - 1082, - }, - dictWord{7, 0, 1545}, - dictWord{8, 0, 56}, - dictWord{8, 0, 118}, - dictWord{8, 0, 412}, - dictWord{8, 0, 564}, - dictWord{9, 0, 888}, - dictWord{9, 0, 908}, - dictWord{ - 10, - 0, - 50, - }, - dictWord{10, 0, 423}, - dictWord{11, 0, 685}, - dictWord{11, 0, 697}, - dictWord{11, 0, 933}, - dictWord{12, 0, 299}, - dictWord{13, 0, 126}, - dictWord{ - 13, - 0, - 136, - }, - dictWord{13, 0, 170}, - dictWord{13, 0, 190}, - dictWord{136, 10, 688}, - dictWord{132, 10, 697}, - dictWord{4, 0, 232}, - dictWord{9, 0, 202}, - dictWord{ - 10, - 0, - 474, - }, - dictWord{140, 0, 433}, - dictWord{136, 0, 212}, - dictWord{6, 0, 108}, - dictWord{7, 0, 1003}, - dictWord{7, 0, 1181}, - dictWord{8, 0, 111}, - dictWord{ - 136, - 0, - 343, - }, - dictWord{5, 10, 221}, - dictWord{135, 11, 1255}, - dictWord{133, 11, 485}, - dictWord{134, 0, 1712}, - dictWord{142, 0, 216}, - dictWord{5, 0, 643}, - dictWord{ - 6, - 0, - 516, - }, - dictWord{4, 11, 285}, - dictWord{5, 11, 317}, - dictWord{6, 11, 301}, - dictWord{7, 11, 7}, - dictWord{8, 11, 153}, - dictWord{10, 11, 766}, - dictWord{ - 11, - 11, - 468, - }, - dictWord{12, 11, 467}, - dictWord{141, 11, 143}, - dictWord{4, 0, 133}, - dictWord{7, 0, 711}, - dictWord{7, 0, 1298}, - dictWord{135, 0, 1585}, - dictWord{ - 134, - 0, - 650, - }, - dictWord{135, 11, 512}, - dictWord{6, 0, 99}, - dictWord{7, 0, 1808}, - dictWord{145, 0, 57}, - dictWord{6, 0, 246}, - dictWord{6, 0, 574}, - dictWord{7, 0, 428}, - dictWord{9, 0, 793}, - dictWord{10, 0, 669}, - dictWord{11, 0, 485}, - dictWord{11, 0, 840}, - dictWord{12, 0, 300}, - dictWord{14, 0, 250}, - dictWord{145, 0, 55}, - dictWord{ - 4, - 10, - 132, - }, - dictWord{5, 10, 69}, - dictWord{135, 10, 1242}, - dictWord{136, 0, 1023}, - dictWord{7, 0, 302}, - dictWord{132, 10, 111}, - dictWord{135, 0, 1871}, - dictWord{132, 0, 728}, - dictWord{9, 0, 252}, - dictWord{132, 10, 767}, - dictWord{6, 0, 461}, - dictWord{7, 0, 1590}, - dictWord{7, 10, 1416}, - dictWord{7, 10, 2005}, - dictWord{8, 10, 131}, - dictWord{8, 10, 466}, - dictWord{9, 10, 672}, - dictWord{13, 10, 252}, - dictWord{148, 10, 103}, - dictWord{6, 0, 323}, - dictWord{135, 0, 1564}, - dictWord{7, 0, 461}, - dictWord{136, 0, 775}, - dictWord{6, 10, 44}, - dictWord{136, 10, 368}, - dictWord{139, 0, 172}, - dictWord{132, 0, 464}, - dictWord{4, 10, 570}, - dictWord{133, 10, 120}, - dictWord{137, 11, 269}, - dictWord{6, 10, 227}, - dictWord{135, 10, 1589}, - dictWord{6, 11, 1719}, - dictWord{6, 11, 1735}, - dictWord{ - 7, - 11, - 2016, - }, - dictWord{7, 11, 2020}, - dictWord{8, 11, 837}, - dictWord{137, 11, 852}, - dictWord{7, 0, 727}, - dictWord{146, 0, 73}, - dictWord{132, 0, 1023}, - dictWord{135, 11, 852}, - dictWord{135, 10, 1529}, - dictWord{136, 0, 577}, - dictWord{138, 11, 568}, - dictWord{134, 0, 1037}, - dictWord{8, 11, 67}, - dictWord{ - 138, - 11, - 419, - }, - dictWord{4, 0, 413}, - dictWord{5, 0, 677}, - dictWord{8, 0, 432}, - dictWord{140, 0, 280}, - dictWord{10, 0, 600}, - dictWord{6, 10, 1667}, - dictWord{ - 7, - 11, - 967, - }, - dictWord{7, 10, 2036}, - dictWord{141, 11, 11}, - dictWord{6, 10, 511}, - dictWord{140, 10, 132}, - dictWord{6, 0, 799}, - dictWord{5, 10, 568}, - dictWord{ - 6, - 10, - 138, - }, - dictWord{135, 10, 1293}, - dictWord{8, 0, 159}, - dictWord{4, 10, 565}, - dictWord{136, 10, 827}, - dictWord{7, 0, 646}, - dictWord{7, 0, 1730}, - dictWord{ - 11, - 0, - 446, - }, - dictWord{141, 0, 178}, - dictWord{4, 10, 922}, - dictWord{133, 10, 1023}, - dictWord{135, 11, 11}, - dictWord{132, 0, 395}, - dictWord{11, 0, 145}, - dictWord{135, 10, 1002}, - dictWord{9, 0, 174}, - dictWord{10, 0, 164}, - dictWord{11, 0, 440}, - dictWord{11, 0, 514}, - dictWord{11, 0, 841}, - dictWord{15, 0, 98}, - dictWord{149, 0, 20}, - dictWord{134, 0, 426}, - dictWord{10, 0, 608}, - dictWord{139, 0, 1002}, - dictWord{7, 11, 320}, - dictWord{8, 11, 51}, - dictWord{12, 11, 481}, - dictWord{12, 11, 570}, - dictWord{148, 11, 106}, - dictWord{9, 0, 977}, - dictWord{9, 0, 983}, - dictWord{132, 11, 445}, - dictWord{138, 0, 250}, - dictWord{139, 0, 100}, - dictWord{6, 0, 1982}, - dictWord{136, 10, 402}, - dictWord{133, 11, 239}, - dictWord{4, 10, 716}, - dictWord{141, 10, 31}, - dictWord{5, 0, 476}, - dictWord{7, 11, 83}, - dictWord{7, 11, 1990}, - dictWord{8, 11, 130}, - dictWord{139, 11, 720}, - dictWord{8, 10, 691}, - dictWord{136, 10, 731}, - dictWord{5, 11, 123}, - dictWord{ - 6, - 11, - 530, - }, - dictWord{7, 11, 348}, - dictWord{135, 11, 1419}, - dictWord{5, 0, 76}, - dictWord{6, 0, 458}, - dictWord{6, 0, 497}, - dictWord{7, 0, 868}, - dictWord{9, 0, 658}, - dictWord{10, 0, 594}, - dictWord{11, 0, 173}, - dictWord{11, 0, 566}, - dictWord{12, 0, 20}, - dictWord{12, 0, 338}, - dictWord{141, 0, 200}, - dictWord{9, 11, 139}, - dictWord{ - 10, - 11, - 399, - }, - dictWord{11, 11, 469}, - dictWord{12, 11, 634}, - dictWord{141, 11, 223}, - dictWord{9, 10, 840}, - dictWord{138, 10, 803}, - dictWord{133, 10, 847}, - dictWord{11, 11, 223}, - dictWord{140, 11, 168}, - dictWord{132, 11, 210}, - dictWord{8, 0, 447}, - dictWord{9, 10, 53}, - dictWord{9, 10, 268}, - dictWord{9, 10, 901}, - dictWord{10, 10, 518}, - dictWord{10, 10, 829}, - dictWord{11, 10, 188}, - dictWord{13, 10, 74}, - dictWord{14, 10, 46}, - dictWord{15, 10, 17}, - dictWord{15, 10, 33}, - dictWord{17, 10, 40}, - dictWord{18, 10, 36}, - dictWord{19, 10, 20}, - dictWord{22, 10, 1}, - dictWord{152, 10, 2}, - dictWord{4, 0, 526}, - dictWord{7, 0, 1029}, - dictWord{135, 0, 1054}, - dictWord{19, 11, 59}, - dictWord{150, 11, 2}, - dictWord{4, 0, 636}, - dictWord{6, 0, 1875}, - dictWord{6, 0, 1920}, - dictWord{9, 0, 999}, - dictWord{ - 12, - 0, - 807, - }, - dictWord{12, 0, 825}, - dictWord{15, 0, 179}, - dictWord{15, 0, 190}, - dictWord{18, 0, 182}, - dictWord{136, 10, 532}, - dictWord{6, 0, 1699}, - dictWord{ - 7, - 0, - 660, - }, - dictWord{7, 0, 1124}, - dictWord{17, 0, 31}, - dictWord{19, 0, 22}, - dictWord{151, 0, 14}, - dictWord{135, 10, 681}, - dictWord{132, 11, 430}, - dictWord{ - 140, - 10, - 677, - }, - dictWord{4, 10, 684}, - dictWord{136, 10, 384}, - dictWord{132, 11, 756}, - dictWord{133, 11, 213}, - dictWord{7, 0, 188}, - dictWord{7, 10, 110}, - dictWord{ - 8, - 10, - 290, - }, - dictWord{8, 10, 591}, - dictWord{9, 10, 382}, - dictWord{9, 10, 649}, - dictWord{11, 10, 71}, - dictWord{11, 10, 155}, - dictWord{11, 10, 313}, - dictWord{ - 12, - 10, - 5, - }, - dictWord{13, 10, 325}, - dictWord{142, 10, 287}, - dictWord{7, 10, 360}, - dictWord{7, 10, 425}, - dictWord{9, 10, 66}, - dictWord{9, 10, 278}, - dictWord{ - 138, - 10, - 644, - }, - dictWord{142, 11, 164}, - dictWord{4, 0, 279}, - dictWord{7, 0, 301}, - dictWord{137, 0, 362}, - dictWord{134, 11, 586}, - dictWord{135, 0, 1743}, - dictWord{4, 0, 178}, - dictWord{133, 0, 399}, - dictWord{4, 10, 900}, - dictWord{133, 10, 861}, - dictWord{5, 10, 254}, - dictWord{7, 10, 985}, - dictWord{136, 10, 73}, - dictWord{133, 11, 108}, - dictWord{7, 10, 1959}, - dictWord{136, 10, 683}, - dictWord{133, 11, 219}, - dictWord{4, 11, 193}, - dictWord{5, 11, 916}, - dictWord{ - 7, - 11, - 364, - }, - dictWord{10, 11, 398}, - dictWord{10, 11, 726}, - dictWord{11, 11, 317}, - dictWord{11, 11, 626}, - dictWord{12, 11, 142}, - dictWord{12, 11, 288}, - dictWord{ - 12, - 11, - 678, - }, - dictWord{13, 11, 313}, - dictWord{15, 11, 113}, - dictWord{18, 11, 114}, - dictWord{21, 11, 30}, - dictWord{150, 11, 53}, - dictWord{6, 11, 241}, - dictWord{7, 11, 907}, - dictWord{8, 11, 832}, - dictWord{9, 11, 342}, - dictWord{10, 11, 729}, - dictWord{11, 11, 284}, - dictWord{11, 11, 445}, - dictWord{11, 11, 651}, - dictWord{11, 11, 863}, - dictWord{13, 11, 398}, - dictWord{146, 11, 99}, - dictWord{132, 0, 872}, - dictWord{134, 0, 831}, - dictWord{134, 0, 1692}, - dictWord{ - 6, - 0, - 202, - }, - dictWord{6, 0, 1006}, - dictWord{9, 0, 832}, - dictWord{10, 0, 636}, - dictWord{11, 0, 208}, - dictWord{12, 0, 360}, - dictWord{17, 0, 118}, - dictWord{18, 0, 27}, - dictWord{20, 0, 67}, - dictWord{137, 11, 734}, - dictWord{132, 10, 725}, - dictWord{7, 11, 993}, - dictWord{138, 11, 666}, - dictWord{134, 0, 1954}, - dictWord{ - 134, - 10, - 196, - }, - dictWord{7, 0, 872}, - dictWord{10, 0, 516}, - dictWord{139, 0, 167}, - dictWord{133, 10, 831}, - dictWord{4, 11, 562}, - dictWord{9, 11, 254}, - dictWord{ - 139, - 11, - 879, - }, - dictWord{137, 0, 313}, - dictWord{4, 0, 224}, - dictWord{132, 11, 786}, - dictWord{11, 0, 24}, - dictWord{12, 0, 170}, - dictWord{136, 10, 723}, - dictWord{ - 5, - 0, - 546, - }, - dictWord{7, 0, 35}, - dictWord{8, 0, 11}, - dictWord{8, 0, 12}, - dictWord{9, 0, 315}, - dictWord{9, 0, 533}, - dictWord{10, 0, 802}, - dictWord{11, 0, 166}, - dictWord{ - 12, - 0, - 525, - }, - dictWord{142, 0, 243}, - dictWord{7, 0, 1937}, - dictWord{13, 10, 80}, - dictWord{13, 10, 437}, - dictWord{145, 10, 74}, - dictWord{5, 0, 241}, - dictWord{ - 8, - 0, - 242, - }, - dictWord{9, 0, 451}, - dictWord{10, 0, 667}, - dictWord{11, 0, 598}, - dictWord{140, 0, 429}, - dictWord{150, 0, 46}, - dictWord{6, 0, 1273}, - dictWord{ - 137, - 0, - 830, - }, - dictWord{5, 10, 848}, - dictWord{6, 10, 66}, - dictWord{136, 10, 764}, - dictWord{6, 0, 825}, - dictWord{134, 0, 993}, - dictWord{4, 0, 1006}, - dictWord{ - 10, - 0, - 327, - }, - dictWord{13, 0, 271}, - dictWord{4, 10, 36}, - dictWord{7, 10, 1387}, - dictWord{139, 10, 755}, - dictWord{134, 0, 1023}, - dictWord{135, 0, 1580}, - dictWord{ - 4, - 0, - 366, - }, - dictWord{137, 0, 516}, - dictWord{132, 10, 887}, - dictWord{6, 0, 1736}, - dictWord{135, 0, 1891}, - dictWord{6, 11, 216}, - dictWord{7, 11, 901}, - dictWord{ - 7, - 11, - 1343, - }, - dictWord{136, 11, 493}, - dictWord{6, 10, 165}, - dictWord{138, 10, 388}, - dictWord{7, 11, 341}, - dictWord{139, 11, 219}, - dictWord{4, 10, 719}, - dictWord{135, 10, 155}, - dictWord{134, 0, 1935}, - dictWord{132, 0, 826}, - dictWord{6, 0, 331}, - dictWord{6, 0, 1605}, - dictWord{8, 0, 623}, - dictWord{11, 0, 139}, - dictWord{139, 0, 171}, - dictWord{135, 11, 1734}, - dictWord{10, 11, 115}, - dictWord{11, 11, 420}, - dictWord{12, 11, 154}, - dictWord{13, 11, 404}, - dictWord{ - 14, - 11, - 346, - }, - dictWord{15, 11, 54}, - dictWord{143, 11, 112}, - dictWord{7, 0, 288}, - dictWord{4, 10, 353}, - dictWord{6, 10, 146}, - dictWord{6, 10, 1789}, - dictWord{ - 7, - 10, - 990, - }, - dictWord{7, 10, 1348}, - dictWord{9, 10, 665}, - dictWord{9, 10, 898}, - dictWord{11, 10, 893}, - dictWord{142, 10, 212}, - dictWord{6, 0, 916}, - dictWord{134, 0, 1592}, - dictWord{7, 0, 1888}, - dictWord{4, 10, 45}, - dictWord{135, 10, 1257}, - dictWord{5, 11, 1011}, - dictWord{136, 11, 701}, - dictWord{ - 139, - 11, - 596, - }, - dictWord{4, 11, 54}, - dictWord{5, 11, 666}, - dictWord{7, 11, 1039}, - dictWord{7, 11, 1130}, - dictWord{9, 11, 195}, - dictWord{138, 11, 302}, - dictWord{ - 134, - 0, - 1471, - }, - dictWord{134, 0, 1570}, - dictWord{132, 0, 394}, - dictWord{140, 10, 65}, - dictWord{136, 10, 816}, - dictWord{135, 0, 1931}, - dictWord{7, 0, 574}, - dictWord{135, 0, 1719}, - dictWord{134, 11, 467}, - dictWord{132, 0, 658}, - dictWord{9, 0, 781}, - dictWord{10, 0, 144}, - dictWord{11, 0, 385}, - dictWord{13, 0, 161}, - dictWord{13, 0, 228}, - dictWord{13, 0, 268}, - dictWord{20, 0, 107}, - dictWord{134, 11, 1669}, - dictWord{136, 0, 374}, - dictWord{135, 0, 735}, - dictWord{4, 0, 344}, - dictWord{6, 0, 498}, - dictWord{139, 0, 323}, - dictWord{7, 0, 586}, - dictWord{7, 0, 1063}, - dictWord{6, 10, 559}, - dictWord{134, 10, 1691}, - dictWord{137, 0, 155}, - dictWord{133, 0, 906}, - dictWord{7, 11, 122}, - dictWord{9, 11, 259}, - dictWord{10, 11, 84}, - dictWord{11, 11, 470}, - dictWord{12, 11, 541}, - dictWord{ - 141, - 11, - 379, - }, - dictWord{134, 0, 1139}, - dictWord{10, 0, 108}, - dictWord{139, 0, 116}, - dictWord{134, 10, 456}, - dictWord{133, 10, 925}, - dictWord{5, 11, 82}, - dictWord{ - 5, - 11, - 131, - }, - dictWord{7, 11, 1755}, - dictWord{8, 11, 31}, - dictWord{9, 11, 168}, - dictWord{9, 11, 764}, - dictWord{139, 11, 869}, - dictWord{134, 11, 605}, - dictWord{ - 5, - 11, - 278, - }, - dictWord{137, 11, 68}, - dictWord{4, 11, 163}, - dictWord{5, 11, 201}, - dictWord{5, 11, 307}, - dictWord{5, 11, 310}, - dictWord{6, 11, 335}, - dictWord{ - 7, - 11, - 284, - }, - dictWord{136, 11, 165}, - dictWord{135, 11, 1660}, - dictWord{6, 11, 33}, - dictWord{135, 11, 1244}, - dictWord{4, 0, 616}, - dictWord{136, 11, 483}, - dictWord{8, 0, 857}, - dictWord{8, 0, 902}, - dictWord{8, 0, 910}, - dictWord{10, 0, 879}, - dictWord{12, 0, 726}, - dictWord{4, 11, 199}, - dictWord{139, 11, 34}, - dictWord{136, 0, 692}, - dictWord{6, 10, 193}, - dictWord{7, 10, 240}, - dictWord{7, 10, 1682}, - dictWord{10, 10, 51}, - dictWord{10, 10, 640}, - dictWord{11, 10, 410}, - dictWord{13, 10, 82}, - dictWord{14, 10, 247}, - dictWord{14, 10, 331}, - dictWord{142, 10, 377}, - dictWord{6, 0, 823}, - dictWord{134, 0, 983}, - dictWord{ - 139, - 10, - 411, - }, - dictWord{132, 0, 305}, - dictWord{136, 10, 633}, - dictWord{138, 11, 203}, - dictWord{134, 0, 681}, - dictWord{6, 11, 326}, - dictWord{7, 11, 677}, - dictWord{137, 11, 425}, - dictWord{5, 0, 214}, - dictWord{7, 0, 603}, - dictWord{8, 0, 611}, - dictWord{9, 0, 686}, - dictWord{10, 0, 88}, - dictWord{11, 0, 459}, - dictWord{ - 11, - 0, - 496, - }, - dictWord{12, 0, 463}, - dictWord{12, 0, 590}, - dictWord{141, 0, 0}, - dictWord{136, 0, 1004}, - dictWord{142, 0, 23}, - dictWord{134, 0, 1703}, - dictWord{ - 147, - 11, - 8, - }, - dictWord{145, 11, 56}, - dictWord{135, 0, 1443}, - dictWord{4, 10, 237}, - dictWord{135, 10, 514}, - dictWord{6, 0, 714}, - dictWord{145, 0, 19}, - dictWord{ - 5, - 11, - 358, - }, - dictWord{7, 11, 473}, - dictWord{7, 11, 1184}, - dictWord{10, 11, 662}, - dictWord{13, 11, 212}, - dictWord{13, 11, 304}, - dictWord{13, 11, 333}, - dictWord{145, 11, 98}, - dictWord{4, 0, 737}, - dictWord{10, 0, 98}, - dictWord{11, 0, 294}, - dictWord{12, 0, 60}, - dictWord{12, 0, 437}, - dictWord{13, 0, 64}, - dictWord{ - 13, - 0, - 380, - }, - dictWord{142, 0, 430}, - dictWord{6, 10, 392}, - dictWord{7, 10, 65}, - dictWord{135, 10, 2019}, - dictWord{6, 0, 1758}, - dictWord{8, 0, 520}, - dictWord{ - 9, - 0, - 345, - }, - dictWord{9, 0, 403}, - dictWord{142, 0, 350}, - dictWord{5, 0, 47}, - dictWord{10, 0, 242}, - dictWord{138, 0, 579}, - dictWord{5, 0, 139}, - dictWord{7, 0, 1168}, - dictWord{138, 0, 539}, - dictWord{134, 0, 1459}, - dictWord{13, 0, 388}, - dictWord{141, 11, 388}, - dictWord{134, 0, 253}, - dictWord{7, 10, 1260}, - dictWord{ - 135, - 10, - 1790, - }, - dictWord{10, 0, 252}, - dictWord{9, 10, 222}, - dictWord{139, 10, 900}, - dictWord{140, 0, 745}, - dictWord{133, 11, 946}, - dictWord{4, 0, 107}, - dictWord{ - 7, - 0, - 613, - }, - dictWord{8, 0, 439}, - dictWord{8, 0, 504}, - dictWord{9, 0, 501}, - dictWord{10, 0, 383}, - dictWord{139, 0, 477}, - dictWord{135, 11, 1485}, - dictWord{ - 132, - 0, - 871, - }, - dictWord{7, 11, 411}, - dictWord{7, 11, 590}, - dictWord{8, 11, 631}, - dictWord{9, 11, 323}, - dictWord{10, 11, 355}, - dictWord{11, 11, 491}, - dictWord{ - 12, - 11, - 143, - }, - dictWord{12, 11, 402}, - dictWord{13, 11, 73}, - dictWord{14, 11, 408}, - dictWord{15, 11, 107}, - dictWord{146, 11, 71}, - dictWord{132, 0, 229}, - dictWord{132, 0, 903}, - dictWord{140, 0, 71}, - dictWord{133, 0, 549}, - dictWord{4, 0, 47}, - dictWord{6, 0, 373}, - dictWord{7, 0, 452}, - dictWord{7, 0, 543}, - dictWord{ - 7, - 0, - 1828, - }, - dictWord{7, 0, 1856}, - dictWord{9, 0, 6}, - dictWord{11, 0, 257}, - dictWord{139, 0, 391}, - dictWord{7, 11, 1467}, - dictWord{8, 11, 328}, - dictWord{ - 10, - 11, - 544, - }, - dictWord{11, 11, 955}, - dictWord{13, 11, 320}, - dictWord{145, 11, 83}, - dictWord{5, 0, 980}, - dictWord{134, 0, 1754}, - dictWord{136, 0, 865}, - dictWord{ - 5, - 0, - 705, - }, - dictWord{137, 0, 606}, - dictWord{7, 0, 161}, - dictWord{8, 10, 201}, - dictWord{136, 10, 605}, - dictWord{143, 11, 35}, - dictWord{5, 11, 835}, - dictWord{ - 6, - 11, - 483, - }, - dictWord{140, 10, 224}, - dictWord{7, 0, 536}, - dictWord{7, 0, 1331}, - dictWord{136, 0, 143}, - dictWord{134, 0, 1388}, - dictWord{5, 0, 724}, - dictWord{ - 10, - 0, - 305, - }, - dictWord{11, 0, 151}, - dictWord{12, 0, 33}, - dictWord{12, 0, 121}, - dictWord{12, 0, 381}, - dictWord{17, 0, 3}, - dictWord{17, 0, 27}, - dictWord{17, 0, 78}, - dictWord{18, 0, 18}, - dictWord{19, 0, 54}, - dictWord{149, 0, 5}, - dictWord{4, 10, 523}, - dictWord{133, 10, 638}, - dictWord{5, 0, 19}, - dictWord{134, 0, 533}, - dictWord{ - 5, - 0, - 395, - }, - dictWord{5, 0, 951}, - dictWord{134, 0, 1776}, - dictWord{135, 0, 1908}, - dictWord{132, 0, 846}, - dictWord{10, 0, 74}, - dictWord{11, 0, 663}, - dictWord{ - 12, - 0, - 210, - }, - dictWord{13, 0, 166}, - dictWord{13, 0, 310}, - dictWord{14, 0, 373}, - dictWord{18, 0, 95}, - dictWord{19, 0, 43}, - dictWord{6, 10, 242}, - dictWord{7, 10, 227}, - dictWord{7, 10, 1581}, - dictWord{8, 10, 104}, - dictWord{9, 10, 113}, - dictWord{9, 10, 220}, - dictWord{9, 10, 427}, - dictWord{10, 10, 239}, - dictWord{11, 10, 579}, - dictWord{11, 10, 1023}, - dictWord{13, 10, 4}, - dictWord{13, 10, 204}, - dictWord{13, 10, 316}, - dictWord{148, 10, 86}, - dictWord{9, 11, 716}, - dictWord{11, 11, 108}, - dictWord{13, 11, 123}, - dictWord{14, 11, 252}, - dictWord{19, 11, 38}, - dictWord{21, 11, 3}, - dictWord{151, 11, 11}, - dictWord{8, 0, 372}, - dictWord{9, 0, 122}, - dictWord{138, 0, 175}, - dictWord{132, 11, 677}, - dictWord{7, 11, 1374}, - dictWord{136, 11, 540}, - dictWord{135, 10, 861}, - dictWord{132, 0, 695}, - dictWord{ - 7, - 0, - 497, - }, - dictWord{9, 0, 387}, - dictWord{147, 0, 81}, - dictWord{136, 0, 937}, - dictWord{134, 0, 718}, - dictWord{7, 0, 1328}, - dictWord{136, 10, 494}, - dictWord{ - 132, - 11, - 331, - }, - dictWord{6, 0, 1581}, - dictWord{133, 11, 747}, - dictWord{5, 0, 284}, - dictWord{6, 0, 49}, - dictWord{6, 0, 350}, - dictWord{7, 0, 1}, - dictWord{7, 0, 377}, - dictWord{7, 0, 1693}, - dictWord{8, 0, 18}, - dictWord{8, 0, 678}, - dictWord{9, 0, 161}, - dictWord{9, 0, 585}, - dictWord{9, 0, 671}, - dictWord{9, 0, 839}, - dictWord{11, 0, 912}, - dictWord{141, 0, 427}, - dictWord{7, 10, 1306}, - dictWord{8, 10, 505}, - dictWord{9, 10, 482}, - dictWord{10, 10, 126}, - dictWord{11, 10, 225}, - dictWord{12, 10, 347}, - dictWord{12, 10, 449}, - dictWord{13, 10, 19}, - dictWord{14, 10, 218}, - dictWord{142, 10, 435}, - dictWord{10, 10, 764}, - dictWord{12, 10, 120}, - dictWord{ - 13, - 10, - 39, - }, - dictWord{145, 10, 127}, - dictWord{4, 0, 597}, - dictWord{133, 10, 268}, - dictWord{134, 0, 1094}, - dictWord{4, 0, 1008}, - dictWord{134, 0, 1973}, - dictWord{132, 0, 811}, - dictWord{139, 0, 908}, - dictWord{135, 0, 1471}, - dictWord{133, 11, 326}, - dictWord{4, 10, 384}, - dictWord{135, 10, 1022}, - dictWord{ - 7, - 0, - 1935, - }, - dictWord{8, 0, 324}, - dictWord{12, 0, 42}, - dictWord{4, 11, 691}, - dictWord{7, 11, 1935}, - dictWord{8, 11, 324}, - dictWord{9, 11, 35}, - dictWord{10, 11, 680}, - dictWord{11, 11, 364}, - dictWord{12, 11, 42}, - dictWord{13, 11, 357}, - dictWord{146, 11, 16}, - dictWord{135, 0, 2014}, - dictWord{7, 0, 2007}, - dictWord{ - 9, - 0, - 101, - }, - dictWord{9, 0, 450}, - dictWord{10, 0, 66}, - dictWord{10, 0, 842}, - dictWord{11, 0, 536}, - dictWord{12, 0, 587}, - dictWord{6, 11, 32}, - dictWord{7, 11, 385}, - dictWord{7, 11, 757}, - dictWord{7, 11, 1916}, - dictWord{8, 11, 37}, - dictWord{8, 11, 94}, - dictWord{8, 11, 711}, - dictWord{9, 11, 541}, - dictWord{10, 11, 162}, - dictWord{ - 10, - 11, - 795, - }, - dictWord{11, 11, 989}, - dictWord{11, 11, 1010}, - dictWord{12, 11, 14}, - dictWord{142, 11, 308}, - dictWord{139, 0, 586}, - dictWord{ - 135, - 10, - 1703, - }, - dictWord{7, 0, 1077}, - dictWord{11, 0, 28}, - dictWord{9, 10, 159}, - dictWord{140, 10, 603}, - dictWord{6, 0, 1221}, - dictWord{136, 10, 583}, - dictWord{ - 6, - 11, - 152, - }, - dictWord{6, 11, 349}, - dictWord{6, 11, 1682}, - dictWord{7, 11, 1252}, - dictWord{8, 11, 112}, - dictWord{9, 11, 435}, - dictWord{9, 11, 668}, - dictWord{ - 10, - 11, - 290, - }, - dictWord{10, 11, 319}, - dictWord{10, 11, 815}, - dictWord{11, 11, 180}, - dictWord{11, 11, 837}, - dictWord{12, 11, 240}, - dictWord{13, 11, 152}, - dictWord{13, 11, 219}, - dictWord{142, 11, 158}, - dictWord{139, 0, 62}, - dictWord{132, 10, 515}, - dictWord{8, 10, 632}, - dictWord{8, 10, 697}, - dictWord{ - 137, - 10, - 854, - }, - dictWord{134, 0, 1766}, - dictWord{132, 11, 581}, - dictWord{6, 11, 126}, - dictWord{7, 11, 573}, - dictWord{8, 11, 397}, - dictWord{142, 11, 44}, - dictWord{ - 150, - 0, - 28, - }, - dictWord{11, 0, 670}, - dictWord{22, 0, 25}, - dictWord{4, 10, 136}, - dictWord{133, 10, 551}, - dictWord{6, 0, 1665}, - dictWord{7, 0, 256}, - dictWord{ - 7, - 0, - 1388, - }, - dictWord{138, 0, 499}, - dictWord{4, 0, 22}, - dictWord{5, 0, 10}, - dictWord{7, 0, 1576}, - dictWord{136, 0, 97}, - dictWord{134, 10, 1782}, - dictWord{5, 0, 481}, - dictWord{7, 10, 1287}, - dictWord{9, 10, 44}, - dictWord{10, 10, 552}, - dictWord{10, 10, 642}, - dictWord{11, 10, 839}, - dictWord{12, 10, 274}, - dictWord{ - 12, - 10, - 275, - }, - dictWord{12, 10, 372}, - dictWord{13, 10, 91}, - dictWord{142, 10, 125}, - dictWord{133, 11, 926}, - dictWord{7, 11, 1232}, - dictWord{137, 11, 531}, - dictWord{6, 0, 134}, - dictWord{7, 0, 437}, - dictWord{7, 0, 1824}, - dictWord{9, 0, 37}, - dictWord{14, 0, 285}, - dictWord{142, 0, 371}, - dictWord{7, 0, 486}, - dictWord{8, 0, 155}, - dictWord{11, 0, 93}, - dictWord{140, 0, 164}, - dictWord{6, 0, 1391}, - dictWord{134, 0, 1442}, - dictWord{133, 11, 670}, - dictWord{133, 0, 591}, - dictWord{ - 6, - 10, - 147, - }, - dictWord{7, 10, 886}, - dictWord{7, 11, 1957}, - dictWord{9, 10, 753}, - dictWord{138, 10, 268}, - dictWord{5, 0, 380}, - dictWord{5, 0, 650}, - dictWord{ - 7, - 0, - 1173, - }, - dictWord{136, 0, 310}, - dictWord{4, 0, 364}, - dictWord{7, 0, 1156}, - dictWord{7, 0, 1187}, - dictWord{137, 0, 409}, - dictWord{135, 11, 1621}, - dictWord{ - 134, - 0, - 482, - }, - dictWord{133, 11, 506}, - dictWord{4, 0, 781}, - dictWord{6, 0, 487}, - dictWord{7, 0, 926}, - dictWord{8, 0, 263}, - dictWord{139, 0, 500}, - dictWord{ - 138, - 10, - 137, - }, - dictWord{135, 11, 242}, - dictWord{139, 11, 96}, - dictWord{133, 10, 414}, - dictWord{135, 10, 1762}, - dictWord{134, 0, 804}, - dictWord{5, 11, 834}, - dictWord{7, 11, 1202}, - dictWord{8, 11, 14}, - dictWord{9, 11, 481}, - dictWord{137, 11, 880}, - dictWord{134, 10, 599}, - dictWord{4, 0, 94}, - dictWord{135, 0, 1265}, - dictWord{4, 0, 415}, - dictWord{132, 0, 417}, - dictWord{5, 0, 348}, - dictWord{6, 0, 522}, - dictWord{6, 10, 1749}, - dictWord{7, 11, 1526}, - dictWord{138, 11, 465}, - dictWord{134, 10, 1627}, - dictWord{132, 0, 1012}, - dictWord{132, 10, 488}, - dictWord{4, 11, 357}, - dictWord{6, 11, 172}, - dictWord{7, 11, 143}, - dictWord{ - 137, - 11, - 413, - }, - dictWord{4, 10, 83}, - dictWord{4, 11, 590}, - dictWord{146, 11, 76}, - dictWord{140, 10, 676}, - dictWord{7, 11, 287}, - dictWord{8, 11, 355}, - dictWord{ - 9, - 11, - 293, - }, - dictWord{137, 11, 743}, - dictWord{134, 10, 278}, - dictWord{6, 0, 1803}, - dictWord{18, 0, 165}, - dictWord{24, 0, 21}, - dictWord{5, 11, 169}, - dictWord{ - 7, - 11, - 333, - }, - dictWord{136, 11, 45}, - dictWord{12, 10, 97}, - dictWord{140, 11, 97}, - dictWord{4, 0, 408}, - dictWord{4, 0, 741}, - dictWord{135, 0, 500}, - dictWord{ - 132, - 11, - 198, - }, - dictWord{7, 10, 388}, - dictWord{7, 10, 644}, - dictWord{139, 10, 781}, - dictWord{4, 11, 24}, - dictWord{5, 11, 140}, - dictWord{5, 11, 185}, - dictWord{ - 7, - 11, - 1500, - }, - dictWord{11, 11, 565}, - dictWord{139, 11, 838}, - dictWord{6, 0, 1321}, - dictWord{9, 0, 257}, - dictWord{7, 10, 229}, - dictWord{8, 10, 59}, - dictWord{ - 9, - 10, - 190, - }, - dictWord{10, 10, 378}, - dictWord{140, 10, 191}, - dictWord{4, 11, 334}, - dictWord{133, 11, 593}, - dictWord{135, 11, 1885}, - dictWord{134, 0, 1138}, - dictWord{4, 0, 249}, - dictWord{6, 0, 73}, - dictWord{135, 0, 177}, - dictWord{133, 0, 576}, - dictWord{142, 0, 231}, - dictWord{137, 0, 288}, - dictWord{132, 10, 660}, - dictWord{7, 10, 1035}, - dictWord{138, 10, 737}, - dictWord{135, 0, 1487}, - dictWord{6, 0, 989}, - dictWord{9, 0, 433}, - dictWord{7, 10, 690}, - dictWord{9, 10, 587}, - dictWord{140, 10, 521}, - dictWord{7, 0, 1264}, - dictWord{7, 0, 1678}, - dictWord{11, 0, 945}, - dictWord{12, 0, 341}, - dictWord{12, 0, 471}, - dictWord{140, 0, 569}, - dictWord{132, 11, 709}, - dictWord{133, 11, 897}, - dictWord{5, 11, 224}, - dictWord{13, 11, 174}, - dictWord{146, 11, 52}, - dictWord{135, 11, 1840}, - dictWord{ - 134, - 10, - 1744, - }, - dictWord{12, 0, 87}, - dictWord{16, 0, 74}, - dictWord{4, 10, 733}, - dictWord{9, 10, 194}, - dictWord{10, 10, 92}, - dictWord{11, 10, 198}, - dictWord{ - 12, - 10, - 84, - }, - dictWord{141, 10, 128}, - dictWord{140, 0, 779}, - dictWord{135, 0, 538}, - dictWord{4, 11, 608}, - dictWord{133, 11, 497}, - dictWord{133, 0, 413}, - dictWord{7, 11, 1375}, - dictWord{7, 11, 1466}, - dictWord{138, 11, 331}, - dictWord{136, 0, 495}, - dictWord{6, 11, 540}, - dictWord{136, 11, 136}, - dictWord{7, 0, 54}, - dictWord{8, 0, 312}, - dictWord{10, 0, 191}, - dictWord{10, 0, 614}, - dictWord{140, 0, 567}, - dictWord{6, 0, 468}, - dictWord{7, 0, 567}, - dictWord{7, 0, 1478}, - dictWord{ - 8, - 0, - 530, - }, - dictWord{14, 0, 290}, - dictWord{133, 11, 999}, - dictWord{4, 11, 299}, - dictWord{7, 10, 306}, - dictWord{135, 11, 1004}, - dictWord{142, 11, 296}, - dictWord{134, 0, 1484}, - dictWord{133, 10, 979}, - dictWord{6, 0, 609}, - dictWord{9, 0, 815}, - dictWord{12, 11, 137}, - dictWord{14, 11, 9}, - dictWord{14, 11, 24}, - dictWord{142, 11, 64}, - dictWord{133, 11, 456}, - dictWord{6, 0, 484}, - dictWord{135, 0, 822}, - dictWord{133, 10, 178}, - dictWord{136, 11, 180}, - dictWord{ - 132, - 11, - 755, - }, - dictWord{137, 0, 900}, - dictWord{135, 0, 1335}, - dictWord{6, 0, 1724}, - dictWord{135, 0, 2022}, - dictWord{135, 11, 1139}, - dictWord{5, 0, 640}, - dictWord{132, 10, 390}, - dictWord{6, 0, 1831}, - dictWord{138, 11, 633}, - dictWord{135, 11, 566}, - dictWord{4, 11, 890}, - dictWord{5, 11, 805}, - dictWord{5, 11, 819}, - dictWord{5, 11, 961}, - dictWord{6, 11, 396}, - dictWord{6, 11, 1631}, - dictWord{6, 11, 1678}, - dictWord{7, 11, 1967}, - dictWord{7, 11, 2041}, - dictWord{ - 9, - 11, - 630, - }, - dictWord{11, 11, 8}, - dictWord{11, 11, 1019}, - dictWord{12, 11, 176}, - dictWord{13, 11, 225}, - dictWord{14, 11, 292}, - dictWord{149, 11, 24}, - dictWord{ - 132, - 0, - 474, - }, - dictWord{134, 0, 1103}, - dictWord{135, 0, 1504}, - dictWord{134, 0, 1576}, - dictWord{6, 0, 961}, - dictWord{6, 0, 1034}, - dictWord{140, 0, 655}, - dictWord{11, 11, 514}, - dictWord{149, 11, 20}, - dictWord{5, 0, 305}, - dictWord{135, 11, 1815}, - dictWord{7, 11, 1505}, - dictWord{10, 11, 190}, - dictWord{ - 10, - 11, - 634, - }, - dictWord{11, 11, 792}, - dictWord{12, 11, 358}, - dictWord{140, 11, 447}, - dictWord{5, 11, 0}, - dictWord{6, 11, 536}, - dictWord{7, 11, 604}, - dictWord{ - 13, - 11, - 445, - }, - dictWord{145, 11, 126}, - dictWord{7, 0, 1236}, - dictWord{133, 10, 105}, - dictWord{4, 0, 480}, - dictWord{6, 0, 217}, - dictWord{6, 0, 302}, - dictWord{ - 6, - 0, - 1642, - }, - dictWord{7, 0, 130}, - dictWord{7, 0, 837}, - dictWord{7, 0, 1321}, - dictWord{7, 0, 1547}, - dictWord{7, 0, 1657}, - dictWord{8, 0, 429}, - dictWord{9, 0, 228}, - dictWord{13, 0, 289}, - dictWord{13, 0, 343}, - dictWord{19, 0, 101}, - dictWord{6, 11, 232}, - dictWord{6, 11, 412}, - dictWord{7, 11, 1074}, - dictWord{8, 11, 9}, - dictWord{ - 8, - 11, - 157, - }, - dictWord{8, 11, 786}, - dictWord{9, 11, 196}, - dictWord{9, 11, 352}, - dictWord{9, 11, 457}, - dictWord{10, 11, 337}, - dictWord{11, 11, 232}, - dictWord{ - 11, - 11, - 877, - }, - dictWord{12, 11, 480}, - dictWord{140, 11, 546}, - dictWord{5, 10, 438}, - dictWord{7, 11, 958}, - dictWord{9, 10, 694}, - dictWord{12, 10, 627}, - dictWord{ - 13, - 11, - 38, - }, - dictWord{141, 10, 210}, - dictWord{4, 11, 382}, - dictWord{136, 11, 579}, - dictWord{7, 0, 278}, - dictWord{10, 0, 739}, - dictWord{11, 0, 708}, - dictWord{ - 141, - 0, - 348, - }, - dictWord{4, 11, 212}, - dictWord{135, 11, 1206}, - dictWord{135, 11, 1898}, - dictWord{6, 0, 708}, - dictWord{6, 0, 1344}, - dictWord{152, 10, 11}, - dictWord{137, 11, 768}, - dictWord{134, 0, 1840}, - dictWord{140, 0, 233}, - dictWord{8, 10, 25}, - dictWord{138, 10, 826}, - dictWord{6, 0, 2017}, - dictWord{ - 133, - 11, - 655, - }, - dictWord{6, 0, 1488}, - dictWord{139, 11, 290}, - dictWord{132, 10, 308}, - dictWord{134, 0, 1590}, - dictWord{134, 0, 1800}, - dictWord{134, 0, 1259}, - dictWord{16, 0, 28}, - dictWord{6, 11, 231}, - dictWord{7, 11, 95}, - dictWord{136, 11, 423}, - dictWord{133, 11, 300}, - dictWord{135, 10, 150}, - dictWord{ - 136, - 10, - 649, - }, - dictWord{7, 11, 1874}, - dictWord{137, 11, 641}, - dictWord{6, 11, 237}, - dictWord{7, 11, 611}, - dictWord{8, 11, 100}, - dictWord{9, 11, 416}, - dictWord{ - 11, - 11, - 335, - }, - dictWord{12, 11, 173}, - dictWord{146, 11, 101}, - dictWord{137, 0, 45}, - dictWord{134, 10, 521}, - dictWord{17, 0, 36}, - dictWord{14, 11, 26}, - dictWord{ - 146, - 11, - 150, - }, - dictWord{7, 0, 1442}, - dictWord{14, 0, 22}, - dictWord{5, 10, 339}, - dictWord{15, 10, 41}, - dictWord{15, 10, 166}, - dictWord{147, 10, 66}, - dictWord{ - 8, - 0, - 378, - }, - dictWord{6, 11, 581}, - dictWord{135, 11, 1119}, - dictWord{134, 0, 1507}, - dictWord{147, 11, 117}, - dictWord{139, 0, 39}, - dictWord{134, 0, 1054}, - dictWord{6, 0, 363}, - dictWord{7, 0, 1955}, - dictWord{136, 0, 725}, - dictWord{134, 0, 2036}, - dictWord{133, 11, 199}, - dictWord{6, 0, 1871}, - dictWord{9, 0, 935}, - dictWord{9, 0, 961}, - dictWord{9, 0, 1004}, - dictWord{9, 0, 1016}, - dictWord{12, 0, 805}, - dictWord{12, 0, 852}, - dictWord{12, 0, 853}, - dictWord{12, 0, 869}, - dictWord{ - 12, - 0, - 882, - }, - dictWord{12, 0, 896}, - dictWord{12, 0, 906}, - dictWord{12, 0, 917}, - dictWord{12, 0, 940}, - dictWord{15, 0, 170}, - dictWord{15, 0, 176}, - dictWord{ - 15, - 0, - 188, - }, - dictWord{15, 0, 201}, - dictWord{15, 0, 205}, - dictWord{15, 0, 212}, - dictWord{15, 0, 234}, - dictWord{15, 0, 244}, - dictWord{18, 0, 181}, - dictWord{18, 0, 193}, - dictWord{18, 0, 196}, - dictWord{18, 0, 201}, - dictWord{18, 0, 202}, - dictWord{18, 0, 210}, - dictWord{18, 0, 217}, - dictWord{18, 0, 235}, - dictWord{18, 0, 236}, - dictWord{18, 0, 237}, - dictWord{21, 0, 54}, - dictWord{21, 0, 55}, - dictWord{21, 0, 58}, - dictWord{21, 0, 59}, - dictWord{152, 0, 22}, - dictWord{134, 10, 1628}, - dictWord{ - 137, - 0, - 805, - }, - dictWord{5, 0, 813}, - dictWord{135, 0, 2046}, - dictWord{142, 11, 42}, - dictWord{5, 0, 712}, - dictWord{6, 0, 1240}, - dictWord{11, 0, 17}, - dictWord{ - 13, - 0, - 321, - }, - dictWord{144, 0, 67}, - dictWord{132, 0, 617}, - dictWord{135, 10, 829}, - dictWord{6, 0, 320}, - dictWord{7, 0, 781}, - dictWord{7, 0, 1921}, - dictWord{9, 0, 55}, - dictWord{10, 0, 186}, - dictWord{10, 0, 273}, - dictWord{10, 0, 664}, - dictWord{10, 0, 801}, - dictWord{11, 0, 996}, - dictWord{11, 0, 997}, - dictWord{13, 0, 157}, - dictWord{142, 0, 170}, - dictWord{136, 0, 271}, - dictWord{5, 10, 486}, - dictWord{135, 10, 1349}, - dictWord{18, 11, 91}, - dictWord{147, 11, 70}, - dictWord{10, 0, 445}, - dictWord{7, 10, 1635}, - dictWord{8, 10, 17}, - dictWord{138, 10, 295}, - dictWord{136, 11, 404}, - dictWord{7, 0, 103}, - dictWord{7, 0, 863}, - dictWord{11, 0, 184}, - dictWord{145, 0, 62}, - dictWord{138, 10, 558}, - dictWord{137, 0, 659}, - dictWord{6, 11, 312}, - dictWord{6, 11, 1715}, - dictWord{10, 11, 584}, - dictWord{ - 11, - 11, - 546, - }, - dictWord{11, 11, 692}, - dictWord{12, 11, 259}, - dictWord{12, 11, 295}, - dictWord{13, 11, 46}, - dictWord{141, 11, 154}, - dictWord{134, 0, 676}, - dictWord{132, 11, 588}, - dictWord{4, 11, 231}, - dictWord{5, 11, 61}, - dictWord{6, 11, 104}, - dictWord{7, 11, 729}, - dictWord{7, 11, 964}, - dictWord{7, 11, 1658}, - dictWord{140, 11, 414}, - dictWord{6, 11, 263}, - dictWord{138, 11, 757}, - dictWord{11, 0, 337}, - dictWord{142, 0, 303}, - dictWord{135, 11, 1363}, - dictWord{ - 132, - 11, - 320, - }, - dictWord{140, 0, 506}, - dictWord{134, 10, 447}, - dictWord{5, 0, 77}, - dictWord{7, 0, 1455}, - dictWord{10, 0, 843}, - dictWord{147, 0, 73}, - dictWord{ - 7, - 10, - 577, - }, - dictWord{7, 10, 1432}, - dictWord{9, 10, 475}, - dictWord{9, 10, 505}, - dictWord{9, 10, 526}, - dictWord{9, 10, 609}, - dictWord{9, 10, 689}, - dictWord{ - 9, - 10, - 726, - }, - dictWord{9, 10, 735}, - dictWord{9, 10, 738}, - dictWord{10, 10, 556}, - dictWord{10, 10, 674}, - dictWord{10, 10, 684}, - dictWord{11, 10, 89}, - dictWord{ - 11, - 10, - 202, - }, - dictWord{11, 10, 272}, - dictWord{11, 10, 380}, - dictWord{11, 10, 415}, - dictWord{11, 10, 505}, - dictWord{11, 10, 537}, - dictWord{11, 10, 550}, - dictWord{11, 10, 562}, - dictWord{11, 10, 640}, - dictWord{11, 10, 667}, - dictWord{11, 10, 688}, - dictWord{11, 10, 847}, - dictWord{11, 10, 927}, - dictWord{ - 11, - 10, - 930, - }, - dictWord{11, 10, 940}, - dictWord{12, 10, 144}, - dictWord{12, 10, 325}, - dictWord{12, 10, 329}, - dictWord{12, 10, 389}, - dictWord{12, 10, 403}, - dictWord{ - 12, - 10, - 451, - }, - dictWord{12, 10, 515}, - dictWord{12, 10, 604}, - dictWord{12, 10, 616}, - dictWord{12, 10, 626}, - dictWord{13, 10, 66}, - dictWord{13, 10, 131}, - dictWord{13, 10, 167}, - dictWord{13, 10, 236}, - dictWord{13, 10, 368}, - dictWord{13, 10, 411}, - dictWord{13, 10, 434}, - dictWord{13, 10, 453}, - dictWord{ - 13, - 10, - 461, - }, - dictWord{13, 10, 474}, - dictWord{14, 10, 59}, - dictWord{14, 10, 60}, - dictWord{14, 10, 139}, - dictWord{14, 10, 152}, - dictWord{14, 10, 276}, - dictWord{ - 14, - 10, - 353, - }, - dictWord{14, 10, 402}, - dictWord{15, 10, 28}, - dictWord{15, 10, 81}, - dictWord{15, 10, 123}, - dictWord{15, 10, 152}, - dictWord{18, 10, 136}, - dictWord{148, 10, 88}, - dictWord{132, 0, 458}, - dictWord{135, 0, 1420}, - dictWord{6, 0, 109}, - dictWord{10, 0, 382}, - dictWord{4, 11, 405}, - dictWord{4, 10, 609}, - dictWord{7, 10, 756}, - dictWord{7, 11, 817}, - dictWord{9, 10, 544}, - dictWord{11, 10, 413}, - dictWord{14, 11, 58}, - dictWord{14, 10, 307}, - dictWord{16, 10, 25}, - dictWord{17, 11, 37}, - dictWord{146, 11, 124}, - dictWord{6, 0, 330}, - dictWord{7, 0, 1084}, - dictWord{11, 0, 142}, - dictWord{133, 11, 974}, - dictWord{4, 10, 930}, - dictWord{133, 10, 947}, - dictWord{5, 10, 939}, - dictWord{142, 11, 394}, - dictWord{16, 0, 91}, - dictWord{145, 0, 87}, - dictWord{5, 11, 235}, - dictWord{5, 10, 962}, - dictWord{7, 11, 1239}, - dictWord{11, 11, 131}, - dictWord{140, 11, 370}, - dictWord{11, 0, 492}, - dictWord{5, 10, 651}, - dictWord{8, 10, 170}, - dictWord{9, 10, 61}, - dictWord{9, 10, 63}, - dictWord{10, 10, 23}, - dictWord{10, 10, 37}, - dictWord{10, 10, 834}, - dictWord{11, 10, 4}, - dictWord{11, 10, 281}, - dictWord{11, 10, 503}, - dictWord{ - 11, - 10, - 677, - }, - dictWord{12, 10, 96}, - dictWord{12, 10, 130}, - dictWord{12, 10, 244}, - dictWord{14, 10, 5}, - dictWord{14, 10, 40}, - dictWord{14, 10, 162}, - dictWord{ - 14, - 10, - 202, - }, - dictWord{146, 10, 133}, - dictWord{4, 10, 406}, - dictWord{5, 10, 579}, - dictWord{12, 10, 492}, - dictWord{150, 10, 15}, - dictWord{9, 11, 137}, - dictWord{138, 11, 221}, - dictWord{134, 0, 1239}, - dictWord{11, 0, 211}, - dictWord{140, 0, 145}, - dictWord{7, 11, 390}, - dictWord{138, 11, 140}, - dictWord{ - 135, - 11, - 1418, - }, - dictWord{135, 11, 1144}, - dictWord{134, 0, 1049}, - dictWord{7, 0, 321}, - dictWord{6, 10, 17}, - dictWord{7, 10, 1001}, - dictWord{7, 10, 1982}, - dictWord{ - 9, - 10, - 886, - }, - dictWord{10, 10, 489}, - dictWord{10, 10, 800}, - dictWord{11, 10, 782}, - dictWord{12, 10, 320}, - dictWord{13, 10, 467}, - dictWord{14, 10, 145}, - dictWord{14, 10, 387}, - dictWord{143, 10, 119}, - dictWord{145, 10, 17}, - dictWord{5, 11, 407}, - dictWord{11, 11, 489}, - dictWord{19, 11, 37}, - dictWord{20, 11, 73}, - dictWord{150, 11, 38}, - dictWord{133, 10, 458}, - dictWord{135, 0, 1985}, - dictWord{7, 10, 1983}, - dictWord{8, 10, 0}, - dictWord{8, 10, 171}, - dictWord{ - 9, - 10, - 120, - }, - dictWord{9, 10, 732}, - dictWord{10, 10, 473}, - dictWord{11, 10, 656}, - dictWord{11, 10, 998}, - dictWord{18, 10, 0}, - dictWord{18, 10, 2}, - dictWord{ - 147, - 10, - 21, - }, - dictWord{5, 11, 325}, - dictWord{7, 11, 1483}, - dictWord{8, 11, 5}, - dictWord{8, 11, 227}, - dictWord{9, 11, 105}, - dictWord{10, 11, 585}, - dictWord{ - 140, - 11, - 614, - }, - dictWord{136, 0, 122}, - dictWord{132, 0, 234}, - dictWord{135, 11, 1196}, - dictWord{6, 0, 976}, - dictWord{6, 0, 1098}, - dictWord{134, 0, 1441}, - dictWord{ - 7, - 0, - 253, - }, - dictWord{136, 0, 549}, - dictWord{6, 11, 621}, - dictWord{13, 11, 504}, - dictWord{144, 11, 19}, - dictWord{132, 10, 519}, - dictWord{5, 0, 430}, - dictWord{ - 5, - 0, - 932, - }, - dictWord{6, 0, 131}, - dictWord{7, 0, 417}, - dictWord{9, 0, 522}, - dictWord{11, 0, 314}, - dictWord{141, 0, 390}, - dictWord{14, 0, 149}, - dictWord{14, 0, 399}, - dictWord{143, 0, 57}, - dictWord{5, 10, 907}, - dictWord{6, 10, 31}, - dictWord{6, 11, 218}, - dictWord{7, 10, 491}, - dictWord{7, 10, 530}, - dictWord{8, 10, 592}, - dictWord{11, 10, 53}, - dictWord{11, 10, 779}, - dictWord{12, 10, 167}, - dictWord{12, 10, 411}, - dictWord{14, 10, 14}, - dictWord{14, 10, 136}, - dictWord{15, 10, 72}, - dictWord{16, 10, 17}, - dictWord{144, 10, 72}, - dictWord{140, 11, 330}, - dictWord{7, 11, 454}, - dictWord{7, 11, 782}, - dictWord{136, 11, 768}, - dictWord{ - 132, - 0, - 507, - }, - dictWord{10, 11, 676}, - dictWord{140, 11, 462}, - dictWord{6, 0, 630}, - dictWord{9, 0, 811}, - dictWord{4, 10, 208}, - dictWord{5, 10, 106}, - dictWord{ - 6, - 10, - 531, - }, - dictWord{8, 10, 408}, - dictWord{9, 10, 188}, - dictWord{138, 10, 572}, - dictWord{4, 0, 343}, - dictWord{5, 0, 511}, - dictWord{134, 10, 1693}, - dictWord{ - 134, - 11, - 164, - }, - dictWord{132, 0, 448}, - dictWord{7, 0, 455}, - dictWord{138, 0, 591}, - dictWord{135, 0, 1381}, - dictWord{12, 10, 441}, - dictWord{150, 11, 50}, - dictWord{9, 10, 449}, - dictWord{10, 10, 192}, - dictWord{138, 10, 740}, - dictWord{6, 0, 575}, - dictWord{132, 10, 241}, - dictWord{134, 0, 1175}, - dictWord{ - 134, - 0, - 653, - }, - dictWord{134, 0, 1761}, - dictWord{134, 0, 1198}, - dictWord{132, 10, 259}, - dictWord{6, 11, 343}, - dictWord{7, 11, 195}, - dictWord{9, 11, 226}, - dictWord{ - 10, - 11, - 197, - }, - dictWord{10, 11, 575}, - dictWord{11, 11, 502}, - dictWord{139, 11, 899}, - dictWord{7, 0, 1127}, - dictWord{7, 0, 1572}, - dictWord{10, 0, 297}, - dictWord{10, 0, 422}, - dictWord{11, 0, 764}, - dictWord{11, 0, 810}, - dictWord{12, 0, 264}, - dictWord{13, 0, 102}, - dictWord{13, 0, 300}, - dictWord{13, 0, 484}, - dictWord{ - 14, - 0, - 147, - }, - dictWord{14, 0, 229}, - dictWord{17, 0, 71}, - dictWord{18, 0, 118}, - dictWord{147, 0, 120}, - dictWord{135, 11, 666}, - dictWord{132, 0, 678}, - dictWord{ - 4, - 10, - 173, - }, - dictWord{5, 10, 312}, - dictWord{5, 10, 512}, - dictWord{135, 10, 1285}, - dictWord{7, 10, 1603}, - dictWord{7, 10, 1691}, - dictWord{9, 10, 464}, - dictWord{11, 10, 195}, - dictWord{12, 10, 279}, - dictWord{12, 10, 448}, - dictWord{14, 10, 11}, - dictWord{147, 10, 102}, - dictWord{16, 0, 99}, - dictWord{146, 0, 164}, - dictWord{7, 11, 1125}, - dictWord{9, 11, 143}, - dictWord{11, 11, 61}, - dictWord{14, 11, 405}, - dictWord{150, 11, 21}, - dictWord{137, 11, 260}, - dictWord{ - 4, - 10, - 452, - }, - dictWord{5, 10, 583}, - dictWord{5, 10, 817}, - dictWord{6, 10, 433}, - dictWord{7, 10, 593}, - dictWord{7, 10, 720}, - dictWord{7, 10, 1378}, - dictWord{ - 8, - 10, - 161, - }, - dictWord{9, 10, 284}, - dictWord{10, 10, 313}, - dictWord{139, 10, 886}, - dictWord{132, 10, 547}, - dictWord{136, 10, 722}, - dictWord{14, 0, 35}, - dictWord{142, 0, 191}, - dictWord{141, 0, 45}, - dictWord{138, 0, 121}, - dictWord{132, 0, 125}, - dictWord{134, 0, 1622}, - dictWord{133, 11, 959}, - dictWord{ - 8, - 10, - 420, - }, - dictWord{139, 10, 193}, - dictWord{132, 0, 721}, - dictWord{135, 10, 409}, - dictWord{136, 0, 145}, - dictWord{7, 0, 792}, - dictWord{8, 0, 147}, - dictWord{ - 10, - 0, - 821, - }, - dictWord{11, 0, 970}, - dictWord{11, 0, 1021}, - dictWord{136, 11, 173}, - dictWord{134, 11, 266}, - dictWord{132, 0, 715}, - dictWord{7, 0, 1999}, - dictWord{138, 10, 308}, - dictWord{133, 0, 531}, - dictWord{5, 0, 168}, - dictWord{5, 0, 930}, - dictWord{8, 0, 74}, - dictWord{9, 0, 623}, - dictWord{12, 0, 500}, - dictWord{ - 140, - 0, - 579, - }, - dictWord{144, 0, 65}, - dictWord{138, 11, 246}, - dictWord{6, 0, 220}, - dictWord{7, 0, 1101}, - dictWord{13, 0, 105}, - dictWord{142, 11, 314}, - dictWord{ - 5, - 10, - 1002, - }, - dictWord{136, 10, 745}, - dictWord{134, 0, 960}, - dictWord{20, 0, 0}, - dictWord{148, 11, 0}, - dictWord{4, 0, 1005}, - dictWord{4, 10, 239}, - dictWord{ - 6, - 10, - 477, - }, - dictWord{7, 10, 1607}, - dictWord{11, 10, 68}, - dictWord{139, 10, 617}, - dictWord{6, 0, 19}, - dictWord{7, 0, 1413}, - dictWord{139, 0, 428}, - dictWord{ - 149, - 10, - 13, - }, - dictWord{7, 0, 96}, - dictWord{8, 0, 401}, - dictWord{8, 0, 703}, - dictWord{9, 0, 896}, - dictWord{136, 11, 300}, - dictWord{134, 0, 1595}, - dictWord{145, 0, 116}, - dictWord{136, 0, 1021}, - dictWord{7, 0, 1961}, - dictWord{7, 0, 1965}, - dictWord{7, 0, 2030}, - dictWord{8, 0, 150}, - dictWord{8, 0, 702}, - dictWord{8, 0, 737}, - dictWord{ - 8, - 0, - 750, - }, - dictWord{140, 0, 366}, - dictWord{11, 11, 75}, - dictWord{142, 11, 267}, - dictWord{132, 10, 367}, - dictWord{8, 0, 800}, - dictWord{9, 0, 148}, - dictWord{ - 9, - 0, - 872, - }, - dictWord{9, 0, 890}, - dictWord{11, 0, 309}, - dictWord{11, 0, 1001}, - dictWord{13, 0, 267}, - dictWord{13, 0, 323}, - dictWord{5, 11, 427}, - dictWord{ - 5, - 11, - 734, - }, - dictWord{7, 11, 478}, - dictWord{136, 11, 52}, - dictWord{7, 11, 239}, - dictWord{11, 11, 217}, - dictWord{142, 11, 165}, - dictWord{132, 11, 323}, - dictWord{140, 11, 419}, - dictWord{13, 0, 299}, - dictWord{142, 0, 75}, - dictWord{6, 11, 87}, - dictWord{6, 11, 1734}, - dictWord{7, 11, 20}, - dictWord{7, 11, 1056}, - dictWord{ - 8, - 11, - 732, - }, - dictWord{9, 11, 406}, - dictWord{9, 11, 911}, - dictWord{138, 11, 694}, - dictWord{134, 0, 1383}, - dictWord{132, 10, 694}, - dictWord{ - 133, - 11, - 613, - }, - dictWord{137, 0, 779}, - dictWord{4, 0, 598}, - dictWord{140, 10, 687}, - dictWord{6, 0, 970}, - dictWord{135, 0, 424}, - dictWord{133, 0, 547}, - dictWord{ - 7, - 11, - 32, - }, - dictWord{7, 11, 984}, - dictWord{8, 11, 85}, - dictWord{8, 11, 709}, - dictWord{9, 11, 579}, - dictWord{9, 11, 847}, - dictWord{9, 11, 856}, - dictWord{10, 11, 799}, - dictWord{11, 11, 258}, - dictWord{11, 11, 1007}, - dictWord{12, 11, 331}, - dictWord{12, 11, 615}, - dictWord{13, 11, 188}, - dictWord{13, 11, 435}, - dictWord{ - 14, - 11, - 8, - }, - dictWord{15, 11, 165}, - dictWord{16, 11, 27}, - dictWord{148, 11, 40}, - dictWord{6, 0, 1222}, - dictWord{134, 0, 1385}, - dictWord{132, 0, 876}, - dictWord{ - 138, - 11, - 151, - }, - dictWord{135, 10, 213}, - dictWord{4, 11, 167}, - dictWord{135, 11, 82}, - dictWord{133, 0, 133}, - dictWord{6, 11, 24}, - dictWord{7, 11, 74}, - dictWord{ - 7, - 11, - 678, - }, - dictWord{137, 11, 258}, - dictWord{5, 11, 62}, - dictWord{6, 11, 534}, - dictWord{7, 11, 684}, - dictWord{7, 11, 1043}, - dictWord{7, 11, 1072}, - dictWord{ - 8, - 11, - 280, - }, - dictWord{8, 11, 541}, - dictWord{8, 11, 686}, - dictWord{10, 11, 519}, - dictWord{11, 11, 252}, - dictWord{140, 11, 282}, - dictWord{136, 0, 187}, - dictWord{8, 0, 8}, - dictWord{10, 0, 0}, - dictWord{10, 0, 818}, - dictWord{139, 0, 988}, - dictWord{132, 11, 359}, - dictWord{11, 0, 429}, - dictWord{15, 0, 51}, - dictWord{ - 135, - 10, - 1672, - }, - dictWord{136, 0, 685}, - dictWord{5, 11, 211}, - dictWord{7, 11, 88}, - dictWord{136, 11, 627}, - dictWord{134, 0, 472}, - dictWord{136, 0, 132}, - dictWord{ - 6, - 11, - 145, - }, - dictWord{141, 11, 336}, - dictWord{4, 10, 751}, - dictWord{11, 10, 390}, - dictWord{140, 10, 32}, - dictWord{6, 0, 938}, - dictWord{6, 0, 1060}, - dictWord{ - 4, - 11, - 263, - }, - dictWord{4, 10, 409}, - dictWord{133, 10, 78}, - dictWord{137, 0, 874}, - dictWord{8, 0, 774}, - dictWord{10, 0, 670}, - dictWord{12, 0, 51}, - dictWord{ - 4, - 11, - 916, - }, - dictWord{6, 10, 473}, - dictWord{7, 10, 1602}, - dictWord{10, 10, 698}, - dictWord{12, 10, 212}, - dictWord{13, 10, 307}, - dictWord{145, 10, 105}, - dictWord{146, 0, 92}, - dictWord{143, 10, 156}, - dictWord{132, 0, 830}, - dictWord{137, 0, 701}, - dictWord{4, 11, 599}, - dictWord{6, 11, 1634}, - dictWord{7, 11, 5}, - dictWord{7, 11, 55}, - dictWord{7, 11, 67}, - dictWord{7, 11, 97}, - dictWord{7, 11, 691}, - dictWord{7, 11, 979}, - dictWord{7, 11, 1697}, - dictWord{8, 11, 207}, - dictWord{ - 8, - 11, - 214, - }, - dictWord{8, 11, 231}, - dictWord{8, 11, 294}, - dictWord{8, 11, 336}, - dictWord{8, 11, 428}, - dictWord{8, 11, 451}, - dictWord{8, 11, 460}, - dictWord{8, 11, 471}, - dictWord{8, 11, 622}, - dictWord{8, 11, 626}, - dictWord{8, 11, 679}, - dictWord{8, 11, 759}, - dictWord{8, 11, 829}, - dictWord{9, 11, 11}, - dictWord{9, 11, 246}, - dictWord{ - 9, - 11, - 484, - }, - dictWord{9, 11, 573}, - dictWord{9, 11, 706}, - dictWord{9, 11, 762}, - dictWord{9, 11, 798}, - dictWord{9, 11, 855}, - dictWord{9, 11, 870}, - dictWord{ - 9, - 11, - 912, - }, - dictWord{10, 11, 303}, - dictWord{10, 11, 335}, - dictWord{10, 11, 424}, - dictWord{10, 11, 461}, - dictWord{10, 11, 543}, - dictWord{10, 11, 759}, - dictWord{10, 11, 814}, - dictWord{11, 11, 59}, - dictWord{11, 11, 199}, - dictWord{11, 11, 235}, - dictWord{11, 11, 475}, - dictWord{11, 11, 590}, - dictWord{11, 11, 929}, - dictWord{11, 11, 963}, - dictWord{12, 11, 114}, - dictWord{12, 11, 182}, - dictWord{12, 11, 226}, - dictWord{12, 11, 332}, - dictWord{12, 11, 439}, - dictWord{ - 12, - 11, - 575, - }, - dictWord{12, 11, 598}, - dictWord{13, 11, 8}, - dictWord{13, 11, 125}, - dictWord{13, 11, 194}, - dictWord{13, 11, 287}, - dictWord{14, 11, 197}, - dictWord{ - 14, - 11, - 383, - }, - dictWord{15, 11, 53}, - dictWord{17, 11, 63}, - dictWord{19, 11, 46}, - dictWord{19, 11, 98}, - dictWord{19, 11, 106}, - dictWord{148, 11, 85}, - dictWord{ - 4, - 0, - 127, - }, - dictWord{5, 0, 350}, - dictWord{6, 0, 356}, - dictWord{8, 0, 426}, - dictWord{9, 0, 572}, - dictWord{10, 0, 247}, - dictWord{139, 0, 312}, - dictWord{134, 0, 1215}, - dictWord{6, 0, 59}, - dictWord{9, 0, 603}, - dictWord{13, 0, 397}, - dictWord{7, 11, 1853}, - dictWord{138, 11, 437}, - dictWord{134, 0, 1762}, - dictWord{ - 147, - 11, - 126, - }, - dictWord{135, 10, 883}, - dictWord{13, 0, 293}, - dictWord{142, 0, 56}, - dictWord{133, 10, 617}, - dictWord{139, 10, 50}, - dictWord{5, 11, 187}, - dictWord{ - 7, - 10, - 1518, - }, - dictWord{139, 10, 694}, - dictWord{135, 0, 441}, - dictWord{6, 0, 111}, - dictWord{7, 0, 4}, - dictWord{8, 0, 163}, - dictWord{8, 0, 776}, - dictWord{ - 138, - 0, - 566, - }, - dictWord{132, 0, 806}, - dictWord{4, 11, 215}, - dictWord{9, 11, 38}, - dictWord{10, 11, 3}, - dictWord{11, 11, 23}, - dictWord{11, 11, 127}, - dictWord{ - 139, - 11, - 796, - }, - dictWord{14, 0, 233}, - dictWord{4, 10, 546}, - dictWord{135, 10, 2042}, - dictWord{135, 0, 1994}, - dictWord{134, 0, 1739}, - dictWord{135, 11, 1530}, - dictWord{136, 0, 393}, - dictWord{5, 0, 297}, - dictWord{7, 0, 1038}, - dictWord{14, 0, 359}, - dictWord{19, 0, 52}, - dictWord{148, 0, 47}, - dictWord{135, 0, 309}, - dictWord{ - 4, - 10, - 313, - }, - dictWord{133, 10, 577}, - dictWord{8, 10, 184}, - dictWord{141, 10, 433}, - dictWord{135, 10, 935}, - dictWord{12, 10, 186}, - dictWord{ - 12, - 10, - 292, - }, - dictWord{14, 10, 100}, - dictWord{146, 10, 70}, - dictWord{136, 0, 363}, - dictWord{14, 0, 175}, - dictWord{11, 10, 402}, - dictWord{12, 10, 109}, - dictWord{ - 12, - 10, - 431, - }, - dictWord{13, 10, 179}, - dictWord{13, 10, 206}, - dictWord{14, 10, 217}, - dictWord{16, 10, 3}, - dictWord{148, 10, 53}, - dictWord{5, 10, 886}, - dictWord{ - 6, - 10, - 46, - }, - dictWord{6, 10, 1790}, - dictWord{7, 10, 14}, - dictWord{7, 10, 732}, - dictWord{7, 10, 1654}, - dictWord{8, 10, 95}, - dictWord{8, 10, 327}, - dictWord{ - 8, - 10, - 616, - }, - dictWord{9, 10, 892}, - dictWord{10, 10, 598}, - dictWord{10, 10, 769}, - dictWord{11, 10, 134}, - dictWord{11, 10, 747}, - dictWord{12, 10, 378}, - dictWord{ - 142, - 10, - 97, - }, - dictWord{136, 0, 666}, - dictWord{135, 0, 1675}, - dictWord{6, 0, 655}, - dictWord{134, 0, 1600}, - dictWord{135, 0, 808}, - dictWord{133, 10, 1021}, - dictWord{4, 11, 28}, - dictWord{5, 11, 440}, - dictWord{7, 11, 248}, - dictWord{11, 11, 833}, - dictWord{140, 11, 344}, - dictWord{134, 11, 1654}, - dictWord{ - 132, - 0, - 280, - }, - dictWord{140, 0, 54}, - dictWord{4, 0, 421}, - dictWord{133, 0, 548}, - dictWord{132, 10, 153}, - dictWord{6, 11, 339}, - dictWord{135, 11, 923}, - dictWord{ - 133, - 11, - 853, - }, - dictWord{133, 10, 798}, - dictWord{132, 10, 587}, - dictWord{6, 11, 249}, - dictWord{7, 11, 1234}, - dictWord{139, 11, 573}, - dictWord{6, 10, 598}, - dictWord{7, 10, 42}, - dictWord{8, 10, 695}, - dictWord{10, 10, 212}, - dictWord{11, 10, 158}, - dictWord{14, 10, 196}, - dictWord{145, 10, 85}, - dictWord{7, 0, 249}, - dictWord{5, 10, 957}, - dictWord{133, 10, 1008}, - dictWord{4, 10, 129}, - dictWord{135, 10, 465}, - dictWord{6, 0, 254}, - dictWord{7, 0, 842}, - dictWord{7, 0, 1659}, - dictWord{9, 0, 109}, - dictWord{10, 0, 103}, - dictWord{7, 10, 908}, - dictWord{7, 10, 1201}, - dictWord{9, 10, 755}, - dictWord{11, 10, 906}, - dictWord{12, 10, 527}, - dictWord{146, 10, 7}, - dictWord{5, 0, 262}, - dictWord{136, 10, 450}, - dictWord{144, 0, 1}, - dictWord{10, 11, 201}, - dictWord{142, 11, 319}, - dictWord{7, 11, 49}, - dictWord{ - 7, - 11, - 392, - }, - dictWord{8, 11, 20}, - dictWord{8, 11, 172}, - dictWord{8, 11, 690}, - dictWord{9, 11, 383}, - dictWord{9, 11, 845}, - dictWord{10, 11, 48}, - dictWord{ - 11, - 11, - 293, - }, - dictWord{11, 11, 832}, - dictWord{11, 11, 920}, - dictWord{141, 11, 221}, - dictWord{5, 11, 858}, - dictWord{133, 11, 992}, - dictWord{134, 0, 805}, - dictWord{139, 10, 1003}, - dictWord{6, 0, 1630}, - dictWord{134, 11, 307}, - dictWord{7, 11, 1512}, - dictWord{135, 11, 1794}, - dictWord{6, 11, 268}, - dictWord{ - 137, - 11, - 62, - }, - dictWord{135, 10, 1868}, - dictWord{133, 0, 671}, - dictWord{4, 0, 989}, - dictWord{8, 0, 972}, - dictWord{136, 0, 998}, - dictWord{132, 11, 423}, - dictWord{132, 0, 889}, - dictWord{135, 0, 1382}, - dictWord{135, 0, 1910}, - dictWord{7, 10, 965}, - dictWord{7, 10, 1460}, - dictWord{135, 10, 1604}, - dictWord{ - 4, - 0, - 627, - }, - dictWord{5, 0, 775}, - dictWord{138, 11, 106}, - dictWord{134, 11, 348}, - dictWord{7, 0, 202}, - dictWord{11, 0, 362}, - dictWord{11, 0, 948}, - dictWord{ - 140, - 0, - 388, - }, - dictWord{138, 11, 771}, - dictWord{6, 11, 613}, - dictWord{136, 11, 223}, - dictWord{6, 0, 560}, - dictWord{7, 0, 451}, - dictWord{8, 0, 389}, - dictWord{ - 12, - 0, - 490, - }, - dictWord{13, 0, 16}, - dictWord{13, 0, 215}, - dictWord{13, 0, 351}, - dictWord{18, 0, 132}, - dictWord{147, 0, 125}, - dictWord{135, 0, 841}, - dictWord{ - 136, - 0, - 566, - }, - dictWord{136, 0, 938}, - dictWord{132, 11, 670}, - dictWord{5, 0, 912}, - dictWord{6, 0, 1695}, - dictWord{140, 11, 55}, - dictWord{9, 11, 40}, - dictWord{ - 139, - 11, - 136, - }, - dictWord{7, 0, 1361}, - dictWord{7, 10, 982}, - dictWord{10, 10, 32}, - dictWord{143, 10, 56}, - dictWord{11, 11, 259}, - dictWord{140, 11, 270}, - dictWord{ - 5, - 0, - 236, - }, - dictWord{6, 0, 572}, - dictWord{8, 0, 492}, - dictWord{11, 0, 618}, - dictWord{144, 0, 56}, - dictWord{8, 11, 572}, - dictWord{9, 11, 310}, - dictWord{9, 11, 682}, - dictWord{137, 11, 698}, - dictWord{134, 0, 1854}, - dictWord{5, 0, 190}, - dictWord{136, 0, 318}, - dictWord{133, 10, 435}, - dictWord{135, 0, 1376}, - dictWord{ - 4, - 11, - 296, - }, - dictWord{6, 11, 352}, - dictWord{7, 11, 401}, - dictWord{7, 11, 1410}, - dictWord{7, 11, 1594}, - dictWord{7, 11, 1674}, - dictWord{8, 11, 63}, - dictWord{ - 8, - 11, - 660, - }, - dictWord{137, 11, 74}, - dictWord{7, 0, 349}, - dictWord{5, 10, 85}, - dictWord{6, 10, 419}, - dictWord{7, 10, 305}, - dictWord{7, 10, 361}, - dictWord{7, 10, 1337}, - dictWord{8, 10, 71}, - dictWord{140, 10, 519}, - dictWord{4, 11, 139}, - dictWord{4, 11, 388}, - dictWord{140, 11, 188}, - dictWord{6, 0, 1972}, - dictWord{6, 0, 2013}, - dictWord{8, 0, 951}, - dictWord{10, 0, 947}, - dictWord{10, 0, 974}, - dictWord{10, 0, 1018}, - dictWord{142, 0, 476}, - dictWord{140, 10, 688}, - dictWord{ - 135, - 10, - 740, - }, - dictWord{5, 10, 691}, - dictWord{7, 10, 345}, - dictWord{9, 10, 94}, - dictWord{140, 10, 169}, - dictWord{9, 0, 344}, - dictWord{5, 10, 183}, - dictWord{6, 10, 582}, - dictWord{10, 10, 679}, - dictWord{140, 10, 435}, - dictWord{135, 10, 511}, - dictWord{132, 0, 850}, - dictWord{8, 11, 441}, - dictWord{10, 11, 314}, - dictWord{ - 143, - 11, - 3, - }, - dictWord{7, 10, 1993}, - dictWord{136, 10, 684}, - dictWord{4, 11, 747}, - dictWord{6, 11, 290}, - dictWord{6, 10, 583}, - dictWord{7, 11, 649}, - dictWord{ - 7, - 11, - 1479, - }, - dictWord{135, 11, 1583}, - dictWord{133, 11, 232}, - dictWord{133, 10, 704}, - dictWord{134, 0, 910}, - dictWord{4, 10, 179}, - dictWord{5, 10, 198}, - dictWord{133, 10, 697}, - dictWord{7, 10, 347}, - dictWord{7, 10, 971}, - dictWord{8, 10, 181}, - dictWord{138, 10, 711}, - dictWord{136, 11, 525}, - dictWord{ - 14, - 0, - 19, - }, - dictWord{14, 0, 28}, - dictWord{144, 0, 29}, - dictWord{7, 0, 85}, - dictWord{7, 0, 247}, - dictWord{8, 0, 585}, - dictWord{138, 0, 163}, - dictWord{4, 0, 487}, - dictWord{ - 7, - 11, - 472, - }, - dictWord{7, 11, 1801}, - dictWord{10, 11, 748}, - dictWord{141, 11, 458}, - dictWord{4, 10, 243}, - dictWord{5, 10, 203}, - dictWord{7, 10, 19}, - dictWord{ - 7, - 10, - 71, - }, - dictWord{7, 10, 113}, - dictWord{10, 10, 405}, - dictWord{11, 10, 357}, - dictWord{142, 10, 240}, - dictWord{7, 10, 1450}, - dictWord{139, 10, 99}, - dictWord{132, 11, 425}, - dictWord{138, 0, 145}, - dictWord{147, 0, 83}, - dictWord{6, 10, 492}, - dictWord{137, 11, 247}, - dictWord{4, 0, 1013}, - dictWord{ - 134, - 0, - 2033, - }, - dictWord{5, 10, 134}, - dictWord{6, 10, 408}, - dictWord{6, 10, 495}, - dictWord{135, 10, 1593}, - dictWord{135, 0, 1922}, - dictWord{134, 11, 1768}, - dictWord{4, 0, 124}, - dictWord{10, 0, 457}, - dictWord{11, 0, 121}, - dictWord{11, 0, 169}, - dictWord{11, 0, 870}, - dictWord{11, 0, 874}, - dictWord{12, 0, 214}, - dictWord{ - 14, - 0, - 187, - }, - dictWord{143, 0, 77}, - dictWord{5, 0, 557}, - dictWord{135, 0, 1457}, - dictWord{139, 0, 66}, - dictWord{5, 11, 943}, - dictWord{6, 11, 1779}, - dictWord{ - 142, - 10, - 4, - }, - dictWord{4, 10, 248}, - dictWord{4, 10, 665}, - dictWord{7, 10, 137}, - dictWord{137, 10, 349}, - dictWord{7, 0, 1193}, - dictWord{5, 11, 245}, - dictWord{ - 6, - 11, - 576, - }, - dictWord{7, 11, 582}, - dictWord{136, 11, 225}, - dictWord{144, 0, 82}, - dictWord{7, 10, 1270}, - dictWord{139, 10, 612}, - dictWord{5, 0, 454}, - dictWord{ - 10, - 0, - 352, - }, - dictWord{138, 11, 352}, - dictWord{18, 0, 57}, - dictWord{5, 10, 371}, - dictWord{135, 10, 563}, - dictWord{135, 0, 1333}, - dictWord{6, 0, 107}, - dictWord{ - 7, - 0, - 638, - }, - dictWord{7, 0, 1632}, - dictWord{9, 0, 396}, - dictWord{134, 11, 610}, - dictWord{5, 0, 370}, - dictWord{134, 0, 1756}, - dictWord{4, 10, 374}, - dictWord{ - 7, - 10, - 547, - }, - dictWord{7, 10, 1700}, - dictWord{7, 10, 1833}, - dictWord{139, 10, 858}, - dictWord{133, 0, 204}, - dictWord{6, 0, 1305}, - dictWord{9, 10, 311}, - dictWord{ - 141, - 10, - 42, - }, - dictWord{5, 0, 970}, - dictWord{134, 0, 1706}, - dictWord{6, 10, 1647}, - dictWord{7, 10, 1552}, - dictWord{7, 10, 2010}, - dictWord{9, 10, 494}, - dictWord{137, 10, 509}, - dictWord{13, 11, 455}, - dictWord{15, 11, 99}, - dictWord{15, 11, 129}, - dictWord{144, 11, 68}, - dictWord{135, 0, 3}, - dictWord{4, 0, 35}, - dictWord{ - 5, - 0, - 121, - }, - dictWord{5, 0, 483}, - dictWord{5, 0, 685}, - dictWord{6, 0, 489}, - dictWord{6, 0, 782}, - dictWord{6, 0, 1032}, - dictWord{7, 0, 1204}, - dictWord{136, 0, 394}, - dictWord{4, 0, 921}, - dictWord{133, 0, 1007}, - dictWord{8, 11, 360}, - dictWord{138, 11, 63}, - dictWord{135, 0, 1696}, - dictWord{134, 0, 1519}, - dictWord{ - 132, - 11, - 443, - }, - dictWord{135, 11, 944}, - dictWord{6, 10, 123}, - dictWord{7, 10, 214}, - dictWord{9, 10, 728}, - dictWord{10, 10, 157}, - dictWord{11, 10, 346}, - dictWord{11, 10, 662}, - dictWord{143, 10, 106}, - dictWord{137, 0, 981}, - dictWord{135, 10, 1435}, - dictWord{134, 0, 1072}, - dictWord{132, 0, 712}, - dictWord{ - 134, - 0, - 1629, - }, - dictWord{134, 0, 728}, - dictWord{4, 11, 298}, - dictWord{137, 11, 483}, - dictWord{6, 0, 1177}, - dictWord{6, 0, 1271}, - dictWord{5, 11, 164}, - dictWord{ - 7, - 11, - 121, - }, - dictWord{142, 11, 189}, - dictWord{7, 0, 1608}, - dictWord{4, 10, 707}, - dictWord{5, 10, 588}, - dictWord{6, 10, 393}, - dictWord{13, 10, 106}, - dictWord{ - 18, - 10, - 49, - }, - dictWord{147, 10, 41}, - dictWord{23, 0, 16}, - dictWord{151, 11, 16}, - dictWord{6, 10, 211}, - dictWord{7, 10, 1690}, - dictWord{11, 10, 486}, - dictWord{140, 10, 369}, - dictWord{133, 0, 485}, - dictWord{19, 11, 15}, - dictWord{149, 11, 27}, - dictWord{4, 11, 172}, - dictWord{9, 11, 611}, - dictWord{10, 11, 436}, - dictWord{12, 11, 673}, - dictWord{141, 11, 255}, - dictWord{5, 11, 844}, - dictWord{10, 11, 484}, - dictWord{11, 11, 754}, - dictWord{12, 11, 457}, - dictWord{ - 14, - 11, - 171, - }, - dictWord{14, 11, 389}, - dictWord{146, 11, 153}, - dictWord{4, 0, 285}, - dictWord{5, 0, 27}, - dictWord{5, 0, 317}, - dictWord{6, 0, 301}, - dictWord{7, 0, 7}, - dictWord{ - 8, - 0, - 153, - }, - dictWord{10, 0, 766}, - dictWord{11, 0, 468}, - dictWord{12, 0, 467}, - dictWord{141, 0, 143}, - dictWord{134, 0, 1462}, - dictWord{9, 11, 263}, - dictWord{ - 10, - 11, - 147, - }, - dictWord{138, 11, 492}, - dictWord{133, 11, 537}, - dictWord{6, 0, 1945}, - dictWord{6, 0, 1986}, - dictWord{6, 0, 1991}, - dictWord{134, 0, 2038}, - dictWord{134, 10, 219}, - dictWord{137, 11, 842}, - dictWord{14, 0, 52}, - dictWord{17, 0, 50}, - dictWord{5, 10, 582}, - dictWord{6, 10, 1646}, - dictWord{7, 10, 99}, - dictWord{7, 10, 1962}, - dictWord{7, 10, 1986}, - dictWord{8, 10, 515}, - dictWord{8, 10, 773}, - dictWord{9, 10, 23}, - dictWord{9, 10, 491}, - dictWord{12, 10, 620}, - dictWord{142, 10, 93}, - dictWord{138, 11, 97}, - dictWord{20, 0, 21}, - dictWord{20, 0, 44}, - dictWord{133, 10, 851}, - dictWord{136, 0, 819}, - dictWord{139, 0, 917}, - dictWord{5, 11, 230}, - dictWord{5, 11, 392}, - dictWord{6, 11, 420}, - dictWord{8, 10, 762}, - dictWord{8, 10, 812}, - dictWord{9, 11, 568}, - dictWord{9, 10, 910}, - dictWord{140, 11, 612}, - dictWord{135, 0, 784}, - dictWord{15, 0, 135}, - dictWord{143, 11, 135}, - dictWord{10, 0, 454}, - dictWord{140, 0, 324}, - dictWord{4, 11, 0}, - dictWord{5, 11, 41}, - dictWord{7, 11, 1459}, - dictWord{7, 11, 1469}, - dictWord{7, 11, 1618}, - dictWord{7, 11, 1859}, - dictWord{9, 11, 549}, - dictWord{139, 11, 905}, - dictWord{4, 10, 98}, - dictWord{7, 10, 1365}, - dictWord{9, 10, 422}, - dictWord{9, 10, 670}, - dictWord{10, 10, 775}, - dictWord{11, 10, 210}, - dictWord{13, 10, 26}, - dictWord{13, 10, 457}, - dictWord{141, 10, 476}, - dictWord{6, 0, 1719}, - dictWord{6, 0, 1735}, - dictWord{7, 0, 2016}, - dictWord{7, 0, 2020}, - dictWord{8, 0, 837}, - dictWord{137, 0, 852}, - dictWord{133, 11, 696}, - dictWord{135, 0, 852}, - dictWord{132, 0, 952}, - dictWord{134, 10, 1730}, - dictWord{132, 11, 771}, - dictWord{ - 138, - 0, - 568, - }, - dictWord{137, 0, 448}, - dictWord{139, 0, 146}, - dictWord{8, 0, 67}, - dictWord{138, 0, 419}, - dictWord{133, 11, 921}, - dictWord{137, 10, 147}, - dictWord{134, 0, 1826}, - dictWord{10, 0, 657}, - dictWord{14, 0, 297}, - dictWord{142, 0, 361}, - dictWord{6, 0, 666}, - dictWord{6, 0, 767}, - dictWord{134, 0, 1542}, - dictWord{139, 0, 729}, - dictWord{6, 11, 180}, - dictWord{7, 11, 1137}, - dictWord{8, 11, 751}, - dictWord{139, 11, 805}, - dictWord{4, 11, 183}, - dictWord{7, 11, 271}, - dictWord{11, 11, 824}, - dictWord{11, 11, 952}, - dictWord{13, 11, 278}, - dictWord{13, 11, 339}, - dictWord{13, 11, 482}, - dictWord{14, 11, 424}, - dictWord{ - 148, - 11, - 99, - }, - dictWord{4, 0, 669}, - dictWord{5, 11, 477}, - dictWord{5, 11, 596}, - dictWord{6, 11, 505}, - dictWord{7, 11, 1221}, - dictWord{11, 11, 907}, - dictWord{ - 12, - 11, - 209, - }, - dictWord{141, 11, 214}, - dictWord{135, 11, 1215}, - dictWord{5, 0, 402}, - dictWord{6, 10, 30}, - dictWord{11, 10, 56}, - dictWord{139, 10, 305}, - dictWord{ - 7, - 11, - 564, - }, - dictWord{142, 11, 168}, - dictWord{139, 0, 152}, - dictWord{7, 0, 912}, - dictWord{135, 10, 1614}, - dictWord{4, 10, 150}, - dictWord{5, 10, 303}, - dictWord{134, 10, 327}, - dictWord{7, 0, 320}, - dictWord{8, 0, 51}, - dictWord{9, 0, 868}, - dictWord{10, 0, 833}, - dictWord{12, 0, 481}, - dictWord{12, 0, 570}, - dictWord{ - 148, - 0, - 106, - }, - dictWord{132, 0, 445}, - dictWord{7, 11, 274}, - dictWord{11, 11, 263}, - dictWord{11, 11, 479}, - dictWord{11, 11, 507}, - dictWord{140, 11, 277}, - dictWord{10, 0, 555}, - dictWord{11, 0, 308}, - dictWord{19, 0, 95}, - dictWord{6, 11, 1645}, - dictWord{8, 10, 192}, - dictWord{10, 10, 78}, - dictWord{141, 10, 359}, - dictWord{135, 10, 786}, - dictWord{6, 11, 92}, - dictWord{6, 11, 188}, - dictWord{7, 11, 1269}, - dictWord{7, 11, 1524}, - dictWord{7, 11, 1876}, - dictWord{10, 11, 228}, - dictWord{139, 11, 1020}, - dictWord{4, 11, 459}, - dictWord{133, 11, 966}, - dictWord{11, 0, 386}, - dictWord{6, 10, 1638}, - dictWord{7, 10, 79}, - dictWord{ - 7, - 10, - 496, - }, - dictWord{9, 10, 138}, - dictWord{10, 10, 336}, - dictWord{12, 10, 412}, - dictWord{12, 10, 440}, - dictWord{142, 10, 305}, - dictWord{133, 0, 239}, - dictWord{ - 7, - 0, - 83, - }, - dictWord{7, 0, 1990}, - dictWord{8, 0, 130}, - dictWord{139, 0, 720}, - dictWord{138, 11, 709}, - dictWord{4, 0, 143}, - dictWord{5, 0, 550}, - dictWord{ - 133, - 0, - 752, - }, - dictWord{5, 0, 123}, - dictWord{6, 0, 530}, - dictWord{7, 0, 348}, - dictWord{135, 0, 1419}, - dictWord{135, 0, 2024}, - dictWord{6, 11, 18}, - dictWord{7, 11, 179}, - dictWord{7, 11, 721}, - dictWord{7, 11, 932}, - dictWord{8, 11, 548}, - dictWord{8, 11, 757}, - dictWord{9, 11, 54}, - dictWord{9, 11, 65}, - dictWord{9, 11, 532}, - dictWord{ - 9, - 11, - 844, - }, - dictWord{10, 11, 113}, - dictWord{10, 11, 117}, - dictWord{10, 11, 236}, - dictWord{10, 11, 315}, - dictWord{10, 11, 430}, - dictWord{10, 11, 798}, - dictWord{11, 11, 153}, - dictWord{11, 11, 351}, - dictWord{11, 11, 375}, - dictWord{12, 11, 78}, - dictWord{12, 11, 151}, - dictWord{12, 11, 392}, - dictWord{ - 14, - 11, - 248, - }, - dictWord{143, 11, 23}, - dictWord{7, 10, 204}, - dictWord{7, 10, 415}, - dictWord{8, 10, 42}, - dictWord{10, 10, 85}, - dictWord{139, 10, 564}, - dictWord{ - 134, - 0, - 958, - }, - dictWord{133, 11, 965}, - dictWord{132, 0, 210}, - dictWord{135, 11, 1429}, - dictWord{138, 11, 480}, - dictWord{134, 11, 182}, - dictWord{ - 139, - 11, - 345, - }, - dictWord{10, 11, 65}, - dictWord{10, 11, 488}, - dictWord{138, 11, 497}, - dictWord{4, 10, 3}, - dictWord{5, 10, 247}, - dictWord{5, 10, 644}, - dictWord{ - 7, - 10, - 744, - }, - dictWord{7, 10, 1207}, - dictWord{7, 10, 1225}, - dictWord{7, 10, 1909}, - dictWord{146, 10, 147}, - dictWord{132, 0, 430}, - dictWord{5, 10, 285}, - dictWord{ - 9, - 10, - 67, - }, - dictWord{13, 10, 473}, - dictWord{143, 10, 82}, - dictWord{144, 11, 16}, - dictWord{7, 11, 1162}, - dictWord{9, 11, 588}, - dictWord{10, 11, 260}, - dictWord{151, 10, 8}, - dictWord{133, 0, 213}, - dictWord{138, 0, 7}, - dictWord{135, 0, 801}, - dictWord{134, 11, 1786}, - dictWord{135, 11, 308}, - dictWord{6, 0, 936}, - dictWord{134, 0, 1289}, - dictWord{133, 0, 108}, - dictWord{132, 0, 885}, - dictWord{133, 0, 219}, - dictWord{139, 0, 587}, - dictWord{4, 0, 193}, - dictWord{5, 0, 916}, - dictWord{6, 0, 1041}, - dictWord{7, 0, 364}, - dictWord{10, 0, 398}, - dictWord{10, 0, 726}, - dictWord{11, 0, 317}, - dictWord{11, 0, 626}, - dictWord{12, 0, 142}, - dictWord{12, 0, 288}, - dictWord{12, 0, 678}, - dictWord{13, 0, 313}, - dictWord{15, 0, 113}, - dictWord{146, 0, 114}, - dictWord{135, 0, 1165}, - dictWord{6, 0, 241}, - dictWord{ - 9, - 0, - 342, - }, - dictWord{10, 0, 729}, - dictWord{11, 0, 284}, - dictWord{11, 0, 445}, - dictWord{11, 0, 651}, - dictWord{11, 0, 863}, - dictWord{13, 0, 398}, - dictWord{ - 146, - 0, - 99, - }, - dictWord{7, 0, 907}, - dictWord{136, 0, 832}, - dictWord{9, 0, 303}, - dictWord{4, 10, 29}, - dictWord{6, 10, 532}, - dictWord{7, 10, 1628}, - dictWord{7, 10, 1648}, - dictWord{9, 10, 350}, - dictWord{10, 10, 433}, - dictWord{11, 10, 97}, - dictWord{11, 10, 557}, - dictWord{11, 10, 745}, - dictWord{12, 10, 289}, - dictWord{ - 12, - 10, - 335, - }, - dictWord{12, 10, 348}, - dictWord{12, 10, 606}, - dictWord{13, 10, 116}, - dictWord{13, 10, 233}, - dictWord{13, 10, 466}, - dictWord{14, 10, 181}, - dictWord{ - 14, - 10, - 209, - }, - dictWord{14, 10, 232}, - dictWord{14, 10, 236}, - dictWord{14, 10, 300}, - dictWord{16, 10, 41}, - dictWord{148, 10, 97}, - dictWord{7, 11, 423}, - dictWord{7, 10, 1692}, - dictWord{136, 11, 588}, - dictWord{6, 0, 931}, - dictWord{134, 0, 1454}, - dictWord{5, 10, 501}, - dictWord{7, 10, 1704}, - dictWord{9, 10, 553}, - dictWord{11, 10, 520}, - dictWord{12, 10, 557}, - dictWord{141, 10, 249}, - dictWord{136, 11, 287}, - dictWord{4, 0, 562}, - dictWord{9, 0, 254}, - dictWord{ - 139, - 0, - 879, - }, - dictWord{132, 0, 786}, - dictWord{14, 11, 32}, - dictWord{18, 11, 85}, - dictWord{20, 11, 2}, - dictWord{152, 11, 16}, - dictWord{135, 0, 1294}, - dictWord{ - 7, - 11, - 723, - }, - dictWord{135, 11, 1135}, - dictWord{6, 0, 216}, - dictWord{7, 0, 901}, - dictWord{7, 0, 1343}, - dictWord{8, 0, 493}, - dictWord{134, 11, 403}, - dictWord{ - 7, - 11, - 719, - }, - dictWord{8, 11, 809}, - dictWord{136, 11, 834}, - dictWord{5, 11, 210}, - dictWord{6, 11, 213}, - dictWord{7, 11, 60}, - dictWord{10, 11, 364}, - dictWord{ - 139, - 11, - 135, - }, - dictWord{7, 0, 341}, - dictWord{11, 0, 219}, - dictWord{5, 11, 607}, - dictWord{8, 11, 326}, - dictWord{136, 11, 490}, - dictWord{4, 11, 701}, - dictWord{ - 5, - 11, - 472, - }, - dictWord{5, 11, 639}, - dictWord{7, 11, 1249}, - dictWord{9, 11, 758}, - dictWord{139, 11, 896}, - dictWord{135, 11, 380}, - dictWord{135, 11, 1947}, - dictWord{139, 0, 130}, - dictWord{135, 0, 1734}, - dictWord{10, 0, 115}, - dictWord{11, 0, 420}, - dictWord{12, 0, 154}, - dictWord{13, 0, 404}, - dictWord{14, 0, 346}, - dictWord{143, 0, 54}, - dictWord{134, 10, 129}, - dictWord{4, 11, 386}, - dictWord{7, 11, 41}, - dictWord{8, 11, 405}, - dictWord{9, 11, 497}, - dictWord{11, 11, 110}, - dictWord{11, 11, 360}, - dictWord{15, 11, 37}, - dictWord{144, 11, 84}, - dictWord{141, 11, 282}, - dictWord{5, 11, 46}, - dictWord{7, 11, 1452}, - dictWord{7, 11, 1480}, - dictWord{8, 11, 634}, - dictWord{140, 11, 472}, - dictWord{4, 11, 524}, - dictWord{136, 11, 810}, - dictWord{10, 11, 238}, - dictWord{141, 11, 33}, - dictWord{ - 133, - 0, - 604, - }, - dictWord{5, 0, 1011}, - dictWord{136, 0, 701}, - dictWord{8, 0, 856}, - dictWord{8, 0, 858}, - dictWord{8, 0, 879}, - dictWord{12, 0, 702}, - dictWord{142, 0, 447}, - dictWord{4, 0, 54}, - dictWord{5, 0, 666}, - dictWord{7, 0, 1039}, - dictWord{7, 0, 1130}, - dictWord{9, 0, 195}, - dictWord{138, 0, 302}, - dictWord{4, 10, 25}, - dictWord{ - 5, - 10, - 60, - }, - dictWord{6, 10, 504}, - dictWord{7, 10, 614}, - dictWord{7, 10, 1155}, - dictWord{140, 10, 0}, - dictWord{7, 10, 1248}, - dictWord{11, 10, 621}, - dictWord{ - 139, - 10, - 702, - }, - dictWord{133, 11, 997}, - dictWord{137, 10, 321}, - dictWord{134, 0, 1669}, - dictWord{134, 0, 1791}, - dictWord{4, 10, 379}, - dictWord{ - 135, - 10, - 1397, - }, - dictWord{138, 11, 372}, - dictWord{5, 11, 782}, - dictWord{5, 11, 829}, - dictWord{134, 11, 1738}, - dictWord{135, 0, 1228}, - dictWord{4, 10, 118}, - dictWord{6, 10, 274}, - dictWord{6, 10, 361}, - dictWord{7, 10, 75}, - dictWord{141, 10, 441}, - dictWord{132, 0, 623}, - dictWord{9, 11, 279}, - dictWord{10, 11, 407}, - dictWord{14, 11, 84}, - dictWord{150, 11, 18}, - dictWord{137, 10, 841}, - dictWord{135, 0, 798}, - dictWord{140, 10, 693}, - dictWord{5, 10, 314}, - dictWord{6, 10, 221}, - dictWord{7, 10, 419}, - dictWord{10, 10, 650}, - dictWord{11, 10, 396}, - dictWord{12, 10, 156}, - dictWord{13, 10, 369}, - dictWord{14, 10, 333}, - dictWord{ - 145, - 10, - 47, - }, - dictWord{135, 11, 1372}, - dictWord{7, 0, 122}, - dictWord{9, 0, 259}, - dictWord{10, 0, 84}, - dictWord{11, 0, 470}, - dictWord{12, 0, 541}, - dictWord{ - 141, - 0, - 379, - }, - dictWord{134, 0, 837}, - dictWord{8, 0, 1013}, - dictWord{4, 11, 78}, - dictWord{5, 11, 96}, - dictWord{5, 11, 182}, - dictWord{7, 11, 1724}, - dictWord{ - 7, - 11, - 1825, - }, - dictWord{10, 11, 394}, - dictWord{10, 11, 471}, - dictWord{11, 11, 532}, - dictWord{14, 11, 340}, - dictWord{145, 11, 88}, - dictWord{134, 0, 577}, - dictWord{135, 11, 1964}, - dictWord{132, 10, 913}, - dictWord{134, 0, 460}, - dictWord{8, 0, 891}, - dictWord{10, 0, 901}, - dictWord{10, 0, 919}, - dictWord{10, 0, 932}, - dictWord{12, 0, 715}, - dictWord{12, 0, 728}, - dictWord{12, 0, 777}, - dictWord{14, 0, 457}, - dictWord{144, 0, 103}, - dictWord{5, 0, 82}, - dictWord{5, 0, 131}, - dictWord{ - 7, - 0, - 1755, - }, - dictWord{8, 0, 31}, - dictWord{9, 0, 168}, - dictWord{9, 0, 764}, - dictWord{139, 0, 869}, - dictWord{136, 10, 475}, - dictWord{6, 0, 605}, - dictWord{ - 5, - 10, - 1016, - }, - dictWord{9, 11, 601}, - dictWord{9, 11, 619}, - dictWord{10, 11, 505}, - dictWord{10, 11, 732}, - dictWord{11, 11, 355}, - dictWord{140, 11, 139}, - dictWord{ - 7, - 10, - 602, - }, - dictWord{8, 10, 179}, - dictWord{10, 10, 781}, - dictWord{140, 10, 126}, - dictWord{134, 0, 1246}, - dictWord{6, 10, 329}, - dictWord{138, 10, 111}, - dictWord{6, 11, 215}, - dictWord{7, 11, 1028}, - dictWord{7, 11, 1473}, - dictWord{7, 11, 1721}, - dictWord{9, 11, 424}, - dictWord{138, 11, 779}, - dictWord{5, 0, 278}, - dictWord{137, 0, 68}, - dictWord{6, 0, 932}, - dictWord{6, 0, 1084}, - dictWord{144, 0, 86}, - dictWord{4, 0, 163}, - dictWord{5, 0, 201}, - dictWord{5, 0, 307}, - dictWord{ - 5, - 0, - 310, - }, - dictWord{6, 0, 335}, - dictWord{7, 0, 284}, - dictWord{7, 0, 1660}, - dictWord{136, 0, 165}, - dictWord{136, 0, 781}, - dictWord{134, 0, 707}, - dictWord{6, 0, 33}, - dictWord{135, 0, 1244}, - dictWord{5, 10, 821}, - dictWord{6, 11, 67}, - dictWord{6, 10, 1687}, - dictWord{7, 11, 258}, - dictWord{7, 11, 1630}, - dictWord{9, 11, 354}, - dictWord{9, 11, 675}, - dictWord{10, 11, 830}, - dictWord{14, 11, 80}, - dictWord{145, 11, 80}, - dictWord{6, 11, 141}, - dictWord{7, 11, 225}, - dictWord{9, 11, 59}, - dictWord{9, 11, 607}, - dictWord{10, 11, 312}, - dictWord{11, 11, 687}, - dictWord{12, 11, 555}, - dictWord{13, 11, 373}, - dictWord{13, 11, 494}, - dictWord{148, 11, 58}, - dictWord{134, 0, 1113}, - dictWord{9, 0, 388}, - dictWord{5, 10, 71}, - dictWord{7, 10, 1407}, - dictWord{9, 10, 704}, - dictWord{10, 10, 261}, - dictWord{10, 10, 619}, - dictWord{11, 10, 547}, - dictWord{11, 10, 619}, - dictWord{143, 10, 157}, - dictWord{7, 0, 1953}, - dictWord{136, 0, 720}, - dictWord{138, 0, 203}, - dictWord{ - 7, - 10, - 2008, - }, - dictWord{9, 10, 337}, - dictWord{138, 10, 517}, - dictWord{6, 0, 326}, - dictWord{7, 0, 677}, - dictWord{137, 0, 425}, - dictWord{139, 11, 81}, - dictWord{ - 7, - 0, - 1316, - }, - dictWord{7, 0, 1412}, - dictWord{7, 0, 1839}, - dictWord{9, 0, 589}, - dictWord{11, 0, 241}, - dictWord{11, 0, 676}, - dictWord{11, 0, 811}, - dictWord{11, 0, 891}, - dictWord{12, 0, 140}, - dictWord{12, 0, 346}, - dictWord{12, 0, 479}, - dictWord{13, 0, 140}, - dictWord{13, 0, 381}, - dictWord{14, 0, 188}, - dictWord{18, 0, 30}, - dictWord{148, 0, 108}, - dictWord{5, 0, 416}, - dictWord{6, 10, 86}, - dictWord{6, 10, 603}, - dictWord{7, 10, 292}, - dictWord{7, 10, 561}, - dictWord{8, 10, 257}, - dictWord{ - 8, - 10, - 382, - }, - dictWord{9, 10, 721}, - dictWord{9, 10, 778}, - dictWord{11, 10, 581}, - dictWord{140, 10, 466}, - dictWord{4, 10, 486}, - dictWord{133, 10, 491}, - dictWord{134, 0, 1300}, - dictWord{132, 10, 72}, - dictWord{7, 0, 847}, - dictWord{6, 10, 265}, - dictWord{7, 11, 430}, - dictWord{139, 11, 46}, - dictWord{5, 11, 602}, - dictWord{6, 11, 106}, - dictWord{7, 11, 1786}, - dictWord{7, 11, 1821}, - dictWord{7, 11, 2018}, - dictWord{9, 11, 418}, - dictWord{137, 11, 763}, - dictWord{5, 0, 358}, - dictWord{7, 0, 535}, - dictWord{7, 0, 1184}, - dictWord{10, 0, 662}, - dictWord{13, 0, 212}, - dictWord{13, 0, 304}, - dictWord{13, 0, 333}, - dictWord{145, 0, 98}, - dictWord{ - 5, - 11, - 65, - }, - dictWord{6, 11, 416}, - dictWord{7, 11, 1720}, - dictWord{7, 11, 1924}, - dictWord{8, 11, 677}, - dictWord{10, 11, 109}, - dictWord{11, 11, 14}, - dictWord{ - 11, - 11, - 70, - }, - dictWord{11, 11, 569}, - dictWord{11, 11, 735}, - dictWord{15, 11, 153}, - dictWord{148, 11, 80}, - dictWord{6, 0, 1823}, - dictWord{8, 0, 839}, - dictWord{ - 8, - 0, - 852, - }, - dictWord{8, 0, 903}, - dictWord{10, 0, 940}, - dictWord{12, 0, 707}, - dictWord{140, 0, 775}, - dictWord{135, 11, 1229}, - dictWord{6, 0, 1522}, - dictWord{ - 140, - 0, - 654, - }, - dictWord{136, 11, 595}, - dictWord{139, 0, 163}, - dictWord{141, 0, 314}, - dictWord{132, 0, 978}, - dictWord{4, 0, 601}, - dictWord{6, 0, 2035}, - dictWord{137, 10, 234}, - dictWord{5, 10, 815}, - dictWord{6, 10, 1688}, - dictWord{134, 10, 1755}, - dictWord{133, 0, 946}, - dictWord{136, 0, 434}, - dictWord{ - 6, - 10, - 197, - }, - dictWord{136, 10, 205}, - dictWord{7, 0, 411}, - dictWord{7, 0, 590}, - dictWord{8, 0, 631}, - dictWord{9, 0, 323}, - dictWord{10, 0, 355}, - dictWord{11, 0, 491}, - dictWord{12, 0, 143}, - dictWord{12, 0, 402}, - dictWord{13, 0, 73}, - dictWord{14, 0, 408}, - dictWord{15, 0, 107}, - dictWord{146, 0, 71}, - dictWord{7, 0, 1467}, - dictWord{ - 8, - 0, - 328, - }, - dictWord{10, 0, 544}, - dictWord{11, 0, 955}, - dictWord{12, 0, 13}, - dictWord{13, 0, 320}, - dictWord{145, 0, 83}, - dictWord{142, 0, 410}, - dictWord{ - 11, - 0, - 511, - }, - dictWord{13, 0, 394}, - dictWord{14, 0, 298}, - dictWord{14, 0, 318}, - dictWord{146, 0, 103}, - dictWord{6, 10, 452}, - dictWord{7, 10, 312}, - dictWord{ - 138, - 10, - 219, - }, - dictWord{138, 10, 589}, - dictWord{4, 10, 333}, - dictWord{9, 10, 176}, - dictWord{12, 10, 353}, - dictWord{141, 10, 187}, - dictWord{135, 11, 329}, - dictWord{132, 11, 469}, - dictWord{5, 0, 835}, - dictWord{134, 0, 483}, - dictWord{134, 11, 1743}, - dictWord{5, 11, 929}, - dictWord{6, 11, 340}, - dictWord{8, 11, 376}, - dictWord{136, 11, 807}, - dictWord{134, 10, 1685}, - dictWord{132, 0, 677}, - dictWord{5, 11, 218}, - dictWord{7, 11, 1610}, - dictWord{138, 11, 83}, - dictWord{ - 5, - 11, - 571, - }, - dictWord{135, 11, 1842}, - dictWord{132, 11, 455}, - dictWord{137, 0, 70}, - dictWord{135, 0, 1405}, - dictWord{7, 10, 135}, - dictWord{8, 10, 7}, - dictWord{ - 8, - 10, - 62, - }, - dictWord{9, 10, 243}, - dictWord{10, 10, 658}, - dictWord{10, 10, 697}, - dictWord{11, 10, 456}, - dictWord{139, 10, 756}, - dictWord{9, 10, 395}, - dictWord{138, 10, 79}, - dictWord{137, 0, 108}, - dictWord{6, 11, 161}, - dictWord{7, 11, 372}, - dictWord{137, 11, 597}, - dictWord{132, 11, 349}, - dictWord{ - 132, - 0, - 777, - }, - dictWord{132, 0, 331}, - dictWord{135, 10, 631}, - dictWord{133, 0, 747}, - dictWord{6, 11, 432}, - dictWord{6, 11, 608}, - dictWord{139, 11, 322}, - dictWord{138, 10, 835}, - dictWord{5, 11, 468}, - dictWord{7, 11, 1809}, - dictWord{10, 11, 325}, - dictWord{11, 11, 856}, - dictWord{12, 11, 345}, - dictWord{ - 143, - 11, - 104, - }, - dictWord{133, 11, 223}, - dictWord{7, 10, 406}, - dictWord{7, 10, 459}, - dictWord{8, 10, 606}, - dictWord{139, 10, 726}, - dictWord{132, 11, 566}, - dictWord{142, 0, 68}, - dictWord{4, 11, 59}, - dictWord{135, 11, 1394}, - dictWord{6, 11, 436}, - dictWord{139, 11, 481}, - dictWord{4, 11, 48}, - dictWord{5, 11, 271}, - dictWord{135, 11, 953}, - dictWord{139, 11, 170}, - dictWord{5, 11, 610}, - dictWord{136, 11, 457}, - dictWord{133, 11, 755}, - dictWord{135, 11, 1217}, - dictWord{ - 133, - 10, - 612, - }, - dictWord{132, 11, 197}, - dictWord{132, 0, 505}, - dictWord{4, 10, 372}, - dictWord{7, 10, 482}, - dictWord{8, 10, 158}, - dictWord{9, 10, 602}, - dictWord{ - 9, - 10, - 615, - }, - dictWord{10, 10, 245}, - dictWord{10, 10, 678}, - dictWord{10, 10, 744}, - dictWord{11, 10, 248}, - dictWord{139, 10, 806}, - dictWord{133, 0, 326}, - dictWord{5, 10, 854}, - dictWord{135, 10, 1991}, - dictWord{4, 0, 691}, - dictWord{146, 0, 16}, - dictWord{6, 0, 628}, - dictWord{9, 0, 35}, - dictWord{10, 0, 680}, - dictWord{10, 0, 793}, - dictWord{11, 0, 364}, - dictWord{13, 0, 357}, - dictWord{143, 0, 164}, - dictWord{138, 0, 654}, - dictWord{6, 0, 32}, - dictWord{7, 0, 385}, - dictWord{ - 7, - 0, - 757, - }, - dictWord{7, 0, 1916}, - dictWord{8, 0, 37}, - dictWord{8, 0, 94}, - dictWord{8, 0, 711}, - dictWord{9, 0, 541}, - dictWord{10, 0, 162}, - dictWord{10, 0, 795}, - dictWord{ - 11, - 0, - 989, - }, - dictWord{11, 0, 1010}, - dictWord{12, 0, 14}, - dictWord{142, 0, 308}, - dictWord{133, 11, 217}, - dictWord{6, 0, 152}, - dictWord{6, 0, 349}, - dictWord{ - 6, - 0, - 1682, - }, - dictWord{7, 0, 1252}, - dictWord{8, 0, 112}, - dictWord{9, 0, 435}, - dictWord{9, 0, 668}, - dictWord{10, 0, 290}, - dictWord{10, 0, 319}, - dictWord{10, 0, 815}, - dictWord{11, 0, 180}, - dictWord{11, 0, 837}, - dictWord{12, 0, 240}, - dictWord{13, 0, 152}, - dictWord{13, 0, 219}, - dictWord{142, 0, 158}, - dictWord{4, 0, 581}, - dictWord{134, 0, 726}, - dictWord{5, 10, 195}, - dictWord{135, 10, 1685}, - dictWord{6, 0, 126}, - dictWord{7, 0, 573}, - dictWord{8, 0, 397}, - dictWord{142, 0, 44}, - dictWord{138, 0, 89}, - dictWord{7, 10, 1997}, - dictWord{8, 10, 730}, - dictWord{139, 10, 1006}, - dictWord{134, 0, 1531}, - dictWord{134, 0, 1167}, - dictWord{ - 5, - 0, - 926, - }, - dictWord{12, 0, 203}, - dictWord{133, 10, 751}, - dictWord{4, 11, 165}, - dictWord{7, 11, 1398}, - dictWord{135, 11, 1829}, - dictWord{7, 0, 1232}, - dictWord{137, 0, 531}, - dictWord{135, 10, 821}, - dictWord{134, 0, 943}, - dictWord{133, 0, 670}, - dictWord{4, 0, 880}, - dictWord{139, 0, 231}, - dictWord{ - 134, - 0, - 1617, - }, - dictWord{135, 0, 1957}, - dictWord{5, 11, 9}, - dictWord{7, 11, 297}, - dictWord{7, 11, 966}, - dictWord{140, 11, 306}, - dictWord{6, 0, 975}, - dictWord{ - 134, - 0, - 985, - }, - dictWord{5, 10, 950}, - dictWord{5, 10, 994}, - dictWord{134, 10, 351}, - dictWord{12, 11, 21}, - dictWord{151, 11, 7}, - dictWord{5, 11, 146}, - dictWord{ - 6, - 11, - 411, - }, - dictWord{138, 11, 721}, - dictWord{7, 0, 242}, - dictWord{135, 0, 1942}, - dictWord{6, 11, 177}, - dictWord{135, 11, 467}, - dictWord{5, 0, 421}, - dictWord{ - 7, - 10, - 47, - }, - dictWord{137, 10, 684}, - dictWord{5, 0, 834}, - dictWord{7, 0, 1202}, - dictWord{8, 0, 14}, - dictWord{9, 0, 481}, - dictWord{137, 0, 880}, - dictWord{138, 0, 465}, - dictWord{6, 0, 688}, - dictWord{9, 0, 834}, - dictWord{132, 10, 350}, - dictWord{132, 0, 855}, - dictWord{4, 0, 357}, - dictWord{6, 0, 172}, - dictWord{7, 0, 143}, - dictWord{137, 0, 413}, - dictWord{133, 11, 200}, - dictWord{132, 0, 590}, - dictWord{7, 10, 1812}, - dictWord{13, 10, 259}, - dictWord{13, 10, 356}, - dictWord{ - 14, - 10, - 242, - }, - dictWord{147, 10, 114}, - dictWord{133, 10, 967}, - dictWord{11, 0, 114}, - dictWord{4, 10, 473}, - dictWord{7, 10, 623}, - dictWord{8, 10, 808}, - dictWord{ - 9, - 10, - 871, - }, - dictWord{9, 10, 893}, - dictWord{11, 10, 431}, - dictWord{12, 10, 112}, - dictWord{12, 10, 217}, - dictWord{12, 10, 243}, - dictWord{12, 10, 562}, - dictWord{ - 12, - 10, - 663, - }, - dictWord{12, 10, 683}, - dictWord{13, 10, 141}, - dictWord{13, 10, 197}, - dictWord{13, 10, 227}, - dictWord{13, 10, 406}, - dictWord{13, 10, 487}, - dictWord{14, 10, 156}, - dictWord{14, 10, 203}, - dictWord{14, 10, 224}, - dictWord{14, 10, 256}, - dictWord{18, 10, 58}, - dictWord{150, 10, 0}, - dictWord{ - 138, - 10, - 286, - }, - dictWord{4, 10, 222}, - dictWord{7, 10, 286}, - dictWord{136, 10, 629}, - dictWord{5, 0, 169}, - dictWord{7, 0, 333}, - dictWord{136, 0, 45}, - dictWord{ - 134, - 11, - 481, - }, - dictWord{132, 0, 198}, - dictWord{4, 0, 24}, - dictWord{5, 0, 140}, - dictWord{5, 0, 185}, - dictWord{7, 0, 1500}, - dictWord{11, 0, 565}, - dictWord{11, 0, 838}, - dictWord{4, 11, 84}, - dictWord{7, 11, 1482}, - dictWord{10, 11, 76}, - dictWord{138, 11, 142}, - dictWord{133, 0, 585}, - dictWord{141, 10, 306}, - dictWord{ - 133, - 11, - 1015, - }, - dictWord{4, 11, 315}, - dictWord{5, 11, 507}, - dictWord{135, 11, 1370}, - dictWord{136, 10, 146}, - dictWord{6, 0, 691}, - dictWord{134, 0, 1503}, - dictWord{ - 4, - 0, - 334, - }, - dictWord{133, 0, 593}, - dictWord{4, 10, 465}, - dictWord{135, 10, 1663}, - dictWord{142, 11, 173}, - dictWord{135, 0, 913}, - dictWord{12, 0, 116}, - dictWord{134, 11, 1722}, - dictWord{134, 0, 1360}, - dictWord{132, 0, 802}, - dictWord{8, 11, 222}, - dictWord{8, 11, 476}, - dictWord{9, 11, 238}, - dictWord{ - 11, - 11, - 516, - }, - dictWord{11, 11, 575}, - dictWord{15, 11, 109}, - dictWord{146, 11, 100}, - dictWord{6, 0, 308}, - dictWord{9, 0, 673}, - dictWord{7, 10, 138}, - dictWord{ - 7, - 10, - 517, - }, - dictWord{139, 10, 238}, - dictWord{132, 0, 709}, - dictWord{6, 0, 1876}, - dictWord{6, 0, 1895}, - dictWord{9, 0, 994}, - dictWord{9, 0, 1006}, - dictWord{ - 12, - 0, - 829, - }, - dictWord{12, 0, 888}, - dictWord{12, 0, 891}, - dictWord{146, 0, 185}, - dictWord{148, 10, 94}, - dictWord{4, 0, 228}, - dictWord{133, 0, 897}, - dictWord{ - 7, - 0, - 1840, - }, - dictWord{5, 10, 495}, - dictWord{7, 10, 834}, - dictWord{9, 10, 733}, - dictWord{139, 10, 378}, - dictWord{133, 10, 559}, - dictWord{6, 10, 21}, - dictWord{ - 6, - 10, - 1737, - }, - dictWord{7, 10, 1444}, - dictWord{136, 10, 224}, - dictWord{4, 0, 608}, - dictWord{133, 0, 497}, - dictWord{6, 11, 40}, - dictWord{135, 11, 1781}, - dictWord{134, 0, 1573}, - dictWord{135, 0, 2039}, - dictWord{6, 0, 540}, - dictWord{136, 0, 136}, - dictWord{4, 0, 897}, - dictWord{5, 0, 786}, - dictWord{133, 10, 519}, - dictWord{6, 0, 1878}, - dictWord{6, 0, 1884}, - dictWord{9, 0, 938}, - dictWord{9, 0, 948}, - dictWord{9, 0, 955}, - dictWord{9, 0, 973}, - dictWord{9, 0, 1012}, - dictWord{ - 12, - 0, - 895, - }, - dictWord{12, 0, 927}, - dictWord{143, 0, 254}, - dictWord{134, 0, 1469}, - dictWord{133, 0, 999}, - dictWord{4, 0, 299}, - dictWord{135, 0, 1004}, - dictWord{ - 4, - 0, - 745, - }, - dictWord{133, 0, 578}, - dictWord{136, 11, 574}, - dictWord{133, 0, 456}, - dictWord{134, 0, 1457}, - dictWord{7, 0, 1679}, - dictWord{132, 10, 402}, - dictWord{7, 0, 693}, - dictWord{8, 0, 180}, - dictWord{12, 0, 163}, - dictWord{8, 10, 323}, - dictWord{136, 10, 479}, - dictWord{11, 10, 580}, - dictWord{142, 10, 201}, - dictWord{5, 10, 59}, - dictWord{135, 10, 672}, - dictWord{132, 11, 354}, - dictWord{146, 10, 34}, - dictWord{4, 0, 755}, - dictWord{135, 11, 1558}, - dictWord{ - 7, - 0, - 1740, - }, - dictWord{146, 0, 48}, - dictWord{4, 10, 85}, - dictWord{135, 10, 549}, - dictWord{139, 0, 338}, - dictWord{133, 10, 94}, - dictWord{134, 0, 1091}, - dictWord{135, 11, 469}, - dictWord{12, 0, 695}, - dictWord{12, 0, 704}, - dictWord{20, 0, 113}, - dictWord{5, 11, 830}, - dictWord{14, 11, 338}, - dictWord{148, 11, 81}, - dictWord{135, 0, 1464}, - dictWord{6, 10, 11}, - dictWord{135, 10, 187}, - dictWord{135, 0, 975}, - dictWord{13, 0, 335}, - dictWord{132, 10, 522}, - dictWord{ - 134, - 0, - 1979, - }, - dictWord{5, 11, 496}, - dictWord{135, 11, 203}, - dictWord{4, 10, 52}, - dictWord{135, 10, 661}, - dictWord{7, 0, 1566}, - dictWord{8, 0, 269}, - dictWord{ - 9, - 0, - 212, - }, - dictWord{9, 0, 718}, - dictWord{14, 0, 15}, - dictWord{14, 0, 132}, - dictWord{142, 0, 227}, - dictWord{4, 0, 890}, - dictWord{5, 0, 805}, - dictWord{5, 0, 819}, - dictWord{ - 5, - 0, - 961, - }, - dictWord{6, 0, 396}, - dictWord{6, 0, 1631}, - dictWord{6, 0, 1678}, - dictWord{7, 0, 1967}, - dictWord{7, 0, 2041}, - dictWord{9, 0, 630}, - dictWord{11, 0, 8}, - dictWord{11, 0, 1019}, - dictWord{12, 0, 176}, - dictWord{13, 0, 225}, - dictWord{14, 0, 292}, - dictWord{21, 0, 24}, - dictWord{4, 10, 383}, - dictWord{133, 10, 520}, - dictWord{134, 11, 547}, - dictWord{135, 11, 1748}, - dictWord{5, 11, 88}, - dictWord{137, 11, 239}, - dictWord{146, 11, 128}, - dictWord{7, 11, 650}, - dictWord{ - 135, - 11, - 1310, - }, - dictWord{4, 10, 281}, - dictWord{5, 10, 38}, - dictWord{7, 10, 194}, - dictWord{7, 10, 668}, - dictWord{7, 10, 1893}, - dictWord{137, 10, 397}, - dictWord{135, 0, 1815}, - dictWord{9, 10, 635}, - dictWord{139, 10, 559}, - dictWord{7, 0, 1505}, - dictWord{10, 0, 190}, - dictWord{10, 0, 634}, - dictWord{11, 0, 792}, - dictWord{12, 0, 358}, - dictWord{140, 0, 447}, - dictWord{5, 0, 0}, - dictWord{6, 0, 536}, - dictWord{7, 0, 604}, - dictWord{13, 0, 445}, - dictWord{145, 0, 126}, - dictWord{ - 7, - 11, - 1076, - }, - dictWord{9, 11, 80}, - dictWord{11, 11, 78}, - dictWord{11, 11, 421}, - dictWord{11, 11, 534}, - dictWord{140, 11, 545}, - dictWord{8, 0, 966}, - dictWord{ - 10, - 0, - 1023, - }, - dictWord{14, 11, 369}, - dictWord{146, 11, 72}, - dictWord{135, 11, 1641}, - dictWord{6, 0, 232}, - dictWord{6, 0, 412}, - dictWord{7, 0, 1074}, - dictWord{ - 8, - 0, - 9, - }, - dictWord{8, 0, 157}, - dictWord{8, 0, 786}, - dictWord{9, 0, 196}, - dictWord{9, 0, 352}, - dictWord{9, 0, 457}, - dictWord{10, 0, 337}, - dictWord{11, 0, 232}, - dictWord{ - 11, - 0, - 877, - }, - dictWord{12, 0, 480}, - dictWord{140, 0, 546}, - dictWord{135, 0, 958}, - dictWord{4, 0, 382}, - dictWord{136, 0, 579}, - dictWord{4, 0, 212}, - dictWord{ - 135, - 0, - 1206, - }, - dictWord{4, 11, 497}, - dictWord{5, 11, 657}, - dictWord{135, 11, 1584}, - dictWord{132, 0, 681}, - dictWord{8, 0, 971}, - dictWord{138, 0, 965}, - dictWord{ - 5, - 10, - 448, - }, - dictWord{136, 10, 535}, - dictWord{14, 0, 16}, - dictWord{146, 0, 44}, - dictWord{11, 0, 584}, - dictWord{11, 0, 616}, - dictWord{14, 0, 275}, - dictWord{ - 11, - 11, - 584, - }, - dictWord{11, 11, 616}, - dictWord{142, 11, 275}, - dictWord{136, 11, 13}, - dictWord{7, 10, 610}, - dictWord{135, 10, 1501}, - dictWord{7, 11, 642}, - dictWord{8, 11, 250}, - dictWord{11, 11, 123}, - dictWord{11, 11, 137}, - dictWord{13, 11, 48}, - dictWord{142, 11, 95}, - dictWord{133, 0, 655}, - dictWord{17, 0, 67}, - dictWord{147, 0, 74}, - dictWord{134, 0, 751}, - dictWord{134, 0, 1967}, - dictWord{6, 0, 231}, - dictWord{136, 0, 423}, - dictWord{5, 0, 300}, - dictWord{138, 0, 1016}, - dictWord{4, 10, 319}, - dictWord{5, 10, 699}, - dictWord{138, 10, 673}, - dictWord{6, 0, 237}, - dictWord{7, 0, 611}, - dictWord{8, 0, 100}, - dictWord{9, 0, 416}, - dictWord{ - 11, - 0, - 335, - }, - dictWord{12, 0, 173}, - dictWord{18, 0, 101}, - dictWord{6, 10, 336}, - dictWord{8, 10, 552}, - dictWord{9, 10, 285}, - dictWord{10, 10, 99}, - dictWord{ - 139, - 10, - 568, - }, - dictWord{134, 0, 1370}, - dictWord{7, 10, 1406}, - dictWord{9, 10, 218}, - dictWord{141, 10, 222}, - dictWord{133, 10, 256}, - dictWord{ - 135, - 0, - 1208, - }, - dictWord{14, 11, 213}, - dictWord{148, 11, 38}, - dictWord{6, 0, 1219}, - dictWord{135, 11, 1642}, - dictWord{13, 0, 417}, - dictWord{14, 0, 129}, - dictWord{143, 0, 15}, - dictWord{10, 11, 545}, - dictWord{140, 11, 301}, - dictWord{17, 10, 39}, - dictWord{148, 10, 36}, - dictWord{133, 0, 199}, - dictWord{4, 11, 904}, - dictWord{133, 11, 794}, - dictWord{12, 0, 427}, - dictWord{146, 0, 38}, - dictWord{134, 0, 949}, - dictWord{8, 0, 665}, - dictWord{135, 10, 634}, - dictWord{ - 132, - 10, - 618, - }, - dictWord{135, 10, 259}, - dictWord{132, 10, 339}, - dictWord{133, 11, 761}, - dictWord{141, 10, 169}, - dictWord{132, 10, 759}, - dictWord{5, 0, 688}, - dictWord{7, 0, 539}, - dictWord{135, 0, 712}, - dictWord{7, 11, 386}, - dictWord{138, 11, 713}, - dictWord{134, 0, 1186}, - dictWord{6, 11, 7}, - dictWord{6, 11, 35}, - dictWord{ - 7, - 11, - 147, - }, - dictWord{7, 11, 1069}, - dictWord{7, 11, 1568}, - dictWord{7, 11, 1575}, - dictWord{7, 11, 1917}, - dictWord{8, 11, 43}, - dictWord{8, 11, 208}, - dictWord{ - 9, - 11, - 128, - }, - dictWord{9, 11, 866}, - dictWord{10, 11, 20}, - dictWord{11, 11, 981}, - dictWord{147, 11, 33}, - dictWord{7, 11, 893}, - dictWord{8, 10, 482}, - dictWord{141, 11, 424}, - dictWord{6, 0, 312}, - dictWord{6, 0, 1715}, - dictWord{10, 0, 584}, - dictWord{11, 0, 546}, - dictWord{11, 0, 692}, - dictWord{12, 0, 259}, - dictWord{ - 12, - 0, - 295, - }, - dictWord{13, 0, 46}, - dictWord{141, 0, 154}, - dictWord{5, 10, 336}, - dictWord{6, 10, 341}, - dictWord{6, 10, 478}, - dictWord{6, 10, 1763}, - dictWord{ - 136, - 10, - 386, - }, - dictWord{137, 0, 151}, - dictWord{132, 0, 588}, - dictWord{152, 0, 4}, - dictWord{6, 11, 322}, - dictWord{9, 11, 552}, - dictWord{11, 11, 274}, - dictWord{ - 13, - 11, - 209, - }, - dictWord{13, 11, 499}, - dictWord{14, 11, 85}, - dictWord{15, 11, 126}, - dictWord{145, 11, 70}, - dictWord{135, 10, 73}, - dictWord{4, 0, 231}, - dictWord{ - 5, - 0, - 61, - }, - dictWord{6, 0, 104}, - dictWord{7, 0, 729}, - dictWord{7, 0, 964}, - dictWord{7, 0, 1658}, - dictWord{140, 0, 414}, - dictWord{6, 0, 263}, - dictWord{138, 0, 757}, - dictWord{135, 10, 1971}, - dictWord{4, 0, 612}, - dictWord{133, 0, 561}, - dictWord{132, 0, 320}, - dictWord{135, 10, 1344}, - dictWord{8, 11, 83}, - dictWord{ - 8, - 11, - 817, - }, - dictWord{9, 11, 28}, - dictWord{9, 11, 29}, - dictWord{9, 11, 885}, - dictWord{10, 11, 387}, - dictWord{11, 11, 633}, - dictWord{11, 11, 740}, - dictWord{ - 13, - 11, - 235, - }, - dictWord{13, 11, 254}, - dictWord{15, 11, 143}, - dictWord{143, 11, 146}, - dictWord{5, 10, 396}, - dictWord{134, 10, 501}, - dictWord{140, 11, 49}, - dictWord{132, 0, 225}, - dictWord{4, 10, 929}, - dictWord{5, 10, 799}, - dictWord{8, 10, 46}, - dictWord{136, 10, 740}, - dictWord{4, 0, 405}, - dictWord{7, 0, 817}, - dictWord{ - 14, - 0, - 58, - }, - dictWord{17, 0, 37}, - dictWord{146, 0, 124}, - dictWord{133, 0, 974}, - dictWord{4, 11, 412}, - dictWord{133, 11, 581}, - dictWord{4, 10, 892}, - dictWord{ - 133, - 10, - 770, - }, - dictWord{4, 0, 996}, - dictWord{134, 0, 2026}, - dictWord{4, 0, 527}, - dictWord{5, 0, 235}, - dictWord{7, 0, 1239}, - dictWord{11, 0, 131}, - dictWord{ - 140, - 0, - 370, - }, - dictWord{9, 0, 16}, - dictWord{13, 0, 386}, - dictWord{135, 11, 421}, - dictWord{7, 0, 956}, - dictWord{7, 0, 1157}, - dictWord{7, 0, 1506}, - dictWord{7, 0, 1606}, - dictWord{7, 0, 1615}, - dictWord{7, 0, 1619}, - dictWord{7, 0, 1736}, - dictWord{7, 0, 1775}, - dictWord{8, 0, 590}, - dictWord{9, 0, 324}, - dictWord{9, 0, 736}, - dictWord{ - 9, - 0, - 774, - }, - dictWord{9, 0, 776}, - dictWord{9, 0, 784}, - dictWord{10, 0, 567}, - dictWord{10, 0, 708}, - dictWord{11, 0, 518}, - dictWord{11, 0, 613}, - dictWord{11, 0, 695}, - dictWord{11, 0, 716}, - dictWord{11, 0, 739}, - dictWord{11, 0, 770}, - dictWord{11, 0, 771}, - dictWord{11, 0, 848}, - dictWord{11, 0, 857}, - dictWord{11, 0, 931}, - dictWord{ - 11, - 0, - 947, - }, - dictWord{12, 0, 326}, - dictWord{12, 0, 387}, - dictWord{12, 0, 484}, - dictWord{12, 0, 528}, - dictWord{12, 0, 552}, - dictWord{12, 0, 613}, - dictWord{ - 13, - 0, - 189, - }, - dictWord{13, 0, 256}, - dictWord{13, 0, 340}, - dictWord{13, 0, 432}, - dictWord{13, 0, 436}, - dictWord{13, 0, 440}, - dictWord{13, 0, 454}, - dictWord{14, 0, 174}, - dictWord{14, 0, 220}, - dictWord{14, 0, 284}, - dictWord{14, 0, 390}, - dictWord{145, 0, 121}, - dictWord{135, 10, 158}, - dictWord{9, 0, 137}, - dictWord{138, 0, 221}, - dictWord{4, 11, 110}, - dictWord{10, 11, 415}, - dictWord{10, 11, 597}, - dictWord{142, 11, 206}, - dictWord{141, 11, 496}, - dictWord{135, 11, 205}, - dictWord{ - 151, - 10, - 25, - }, - dictWord{135, 11, 778}, - dictWord{7, 11, 1656}, - dictWord{7, 10, 2001}, - dictWord{9, 11, 369}, - dictWord{10, 11, 338}, - dictWord{10, 11, 490}, - dictWord{11, 11, 154}, - dictWord{11, 11, 545}, - dictWord{11, 11, 775}, - dictWord{13, 11, 77}, - dictWord{141, 11, 274}, - dictWord{4, 11, 444}, - dictWord{ - 10, - 11, - 146, - }, - dictWord{140, 11, 9}, - dictWord{7, 0, 390}, - dictWord{138, 0, 140}, - dictWord{135, 0, 1144}, - dictWord{134, 0, 464}, - dictWord{7, 10, 1461}, - dictWord{ - 140, - 10, - 91, - }, - dictWord{132, 10, 602}, - dictWord{4, 11, 283}, - dictWord{135, 11, 1194}, - dictWord{5, 0, 407}, - dictWord{11, 0, 204}, - dictWord{11, 0, 243}, - dictWord{ - 11, - 0, - 489, - }, - dictWord{12, 0, 293}, - dictWord{19, 0, 37}, - dictWord{20, 0, 73}, - dictWord{150, 0, 38}, - dictWord{7, 0, 1218}, - dictWord{136, 0, 303}, - dictWord{ - 5, - 0, - 325, - }, - dictWord{8, 0, 5}, - dictWord{8, 0, 227}, - dictWord{9, 0, 105}, - dictWord{10, 0, 585}, - dictWord{12, 0, 614}, - dictWord{4, 10, 13}, - dictWord{5, 10, 567}, - dictWord{ - 7, - 10, - 1498, - }, - dictWord{9, 10, 124}, - dictWord{11, 10, 521}, - dictWord{140, 10, 405}, - dictWord{135, 10, 1006}, - dictWord{7, 0, 800}, - dictWord{10, 0, 12}, - dictWord{134, 11, 1720}, - dictWord{135, 0, 1783}, - dictWord{132, 10, 735}, - dictWord{138, 10, 812}, - dictWord{4, 10, 170}, - dictWord{135, 10, 323}, - dictWord{ - 6, - 0, - 621, - }, - dictWord{13, 0, 504}, - dictWord{144, 0, 89}, - dictWord{5, 10, 304}, - dictWord{135, 10, 1403}, - dictWord{137, 11, 216}, - dictWord{6, 0, 920}, - dictWord{ - 6, - 0, - 1104, - }, - dictWord{9, 11, 183}, - dictWord{139, 11, 286}, - dictWord{4, 0, 376}, - dictWord{133, 10, 742}, - dictWord{134, 0, 218}, - dictWord{8, 0, 641}, - dictWord{ - 11, - 0, - 388, - }, - dictWord{140, 0, 580}, - dictWord{7, 0, 454}, - dictWord{7, 0, 782}, - dictWord{8, 0, 768}, - dictWord{140, 0, 686}, - dictWord{137, 11, 33}, - dictWord{ - 133, - 10, - 111, - }, - dictWord{144, 0, 0}, - dictWord{10, 0, 676}, - dictWord{140, 0, 462}, - dictWord{6, 0, 164}, - dictWord{136, 11, 735}, - dictWord{133, 10, 444}, - dictWord{ - 150, - 0, - 50, - }, - dictWord{7, 11, 1862}, - dictWord{12, 11, 491}, - dictWord{12, 11, 520}, - dictWord{13, 11, 383}, - dictWord{14, 11, 244}, - dictWord{146, 11, 12}, - dictWord{ - 5, - 11, - 132, - }, - dictWord{9, 11, 486}, - dictWord{9, 11, 715}, - dictWord{10, 11, 458}, - dictWord{11, 11, 373}, - dictWord{11, 11, 668}, - dictWord{11, 11, 795}, - dictWord{11, 11, 897}, - dictWord{12, 11, 272}, - dictWord{12, 11, 424}, - dictWord{12, 11, 539}, - dictWord{12, 11, 558}, - dictWord{14, 11, 245}, - dictWord{ - 14, - 11, - 263, - }, - dictWord{14, 11, 264}, - dictWord{14, 11, 393}, - dictWord{142, 11, 403}, - dictWord{8, 10, 123}, - dictWord{15, 10, 6}, - dictWord{144, 10, 7}, - dictWord{ - 6, - 0, - 285, - }, - dictWord{8, 0, 654}, - dictWord{11, 0, 749}, - dictWord{12, 0, 190}, - dictWord{12, 0, 327}, - dictWord{13, 0, 120}, - dictWord{13, 0, 121}, - dictWord{13, 0, 327}, - dictWord{15, 0, 47}, - dictWord{146, 0, 40}, - dictWord{5, 11, 8}, - dictWord{6, 11, 89}, - dictWord{6, 11, 400}, - dictWord{7, 11, 1569}, - dictWord{7, 11, 1623}, - dictWord{ - 7, - 11, - 1850, - }, - dictWord{8, 11, 218}, - dictWord{8, 11, 422}, - dictWord{9, 11, 570}, - dictWord{138, 11, 626}, - dictWord{6, 11, 387}, - dictWord{7, 11, 882}, - dictWord{141, 11, 111}, - dictWord{6, 0, 343}, - dictWord{7, 0, 195}, - dictWord{9, 0, 226}, - dictWord{10, 0, 197}, - dictWord{10, 0, 575}, - dictWord{11, 0, 502}, - dictWord{ - 11, - 0, - 899, - }, - dictWord{6, 11, 224}, - dictWord{7, 11, 877}, - dictWord{137, 11, 647}, - dictWord{5, 10, 937}, - dictWord{135, 10, 100}, - dictWord{135, 11, 790}, - dictWord{150, 0, 29}, - dictWord{147, 0, 8}, - dictWord{134, 0, 1812}, - dictWord{149, 0, 8}, - dictWord{135, 11, 394}, - dictWord{7, 0, 1125}, - dictWord{9, 0, 143}, - dictWord{ - 11, - 0, - 61, - }, - dictWord{14, 0, 405}, - dictWord{150, 0, 21}, - dictWord{10, 11, 755}, - dictWord{147, 11, 29}, - dictWord{9, 11, 378}, - dictWord{141, 11, 162}, - dictWord{135, 10, 922}, - dictWord{5, 10, 619}, - dictWord{133, 10, 698}, - dictWord{134, 0, 1327}, - dictWord{6, 0, 1598}, - dictWord{137, 0, 575}, - dictWord{ - 9, - 11, - 569, - }, - dictWord{12, 11, 12}, - dictWord{12, 11, 81}, - dictWord{12, 11, 319}, - dictWord{13, 11, 69}, - dictWord{14, 11, 259}, - dictWord{16, 11, 87}, - dictWord{ - 17, - 11, - 1, - }, - dictWord{17, 11, 21}, - dictWord{17, 11, 24}, - dictWord{18, 11, 15}, - dictWord{18, 11, 56}, - dictWord{18, 11, 59}, - dictWord{18, 11, 127}, - dictWord{18, 11, 154}, - dictWord{19, 11, 19}, - dictWord{148, 11, 31}, - dictWord{6, 0, 895}, - dictWord{135, 11, 1231}, - dictWord{5, 0, 959}, - dictWord{7, 11, 124}, - dictWord{136, 11, 38}, - dictWord{5, 11, 261}, - dictWord{7, 11, 78}, - dictWord{7, 11, 199}, - dictWord{8, 11, 815}, - dictWord{9, 11, 126}, - dictWord{138, 11, 342}, - dictWord{5, 10, 917}, - dictWord{134, 10, 1659}, - dictWord{7, 0, 1759}, - dictWord{5, 11, 595}, - dictWord{135, 11, 1863}, - dictWord{136, 0, 173}, - dictWord{134, 0, 266}, - dictWord{ - 142, - 0, - 261, - }, - dictWord{132, 11, 628}, - dictWord{5, 10, 251}, - dictWord{5, 10, 956}, - dictWord{8, 10, 268}, - dictWord{9, 10, 214}, - dictWord{146, 10, 142}, - dictWord{ - 7, - 11, - 266, - }, - dictWord{136, 11, 804}, - dictWord{135, 11, 208}, - dictWord{6, 11, 79}, - dictWord{7, 11, 1021}, - dictWord{135, 11, 1519}, - dictWord{11, 11, 704}, - dictWord{141, 11, 396}, - dictWord{5, 10, 346}, - dictWord{5, 10, 711}, - dictWord{136, 10, 390}, - dictWord{136, 11, 741}, - dictWord{134, 11, 376}, - dictWord{ - 134, - 0, - 1427, - }, - dictWord{6, 0, 1033}, - dictWord{6, 0, 1217}, - dictWord{136, 0, 300}, - dictWord{133, 10, 624}, - dictWord{6, 11, 100}, - dictWord{7, 11, 244}, - dictWord{ - 7, - 11, - 632, - }, - dictWord{7, 11, 1609}, - dictWord{8, 11, 178}, - dictWord{8, 11, 638}, - dictWord{141, 11, 58}, - dictWord{6, 0, 584}, - dictWord{5, 10, 783}, - dictWord{ - 7, - 10, - 1998, - }, - dictWord{135, 10, 2047}, - dictWord{5, 0, 427}, - dictWord{5, 0, 734}, - dictWord{7, 0, 478}, - dictWord{136, 0, 52}, - dictWord{7, 0, 239}, - dictWord{ - 11, - 0, - 217, - }, - dictWord{142, 0, 165}, - dictWord{134, 0, 1129}, - dictWord{6, 0, 168}, - dictWord{6, 0, 1734}, - dictWord{7, 0, 20}, - dictWord{7, 0, 1056}, - dictWord{8, 0, 732}, - dictWord{9, 0, 406}, - dictWord{9, 0, 911}, - dictWord{138, 0, 694}, - dictWord{132, 10, 594}, - dictWord{133, 11, 791}, - dictWord{7, 11, 686}, - dictWord{8, 11, 33}, - dictWord{8, 11, 238}, - dictWord{10, 11, 616}, - dictWord{11, 11, 467}, - dictWord{11, 11, 881}, - dictWord{13, 11, 217}, - dictWord{13, 11, 253}, - dictWord{ - 142, - 11, - 268, - }, - dictWord{137, 11, 476}, - dictWord{134, 0, 418}, - dictWord{133, 0, 613}, - dictWord{132, 0, 632}, - dictWord{132, 11, 447}, - dictWord{7, 0, 32}, - dictWord{ - 7, - 0, - 984, - }, - dictWord{8, 0, 85}, - dictWord{8, 0, 709}, - dictWord{9, 0, 579}, - dictWord{9, 0, 847}, - dictWord{9, 0, 856}, - dictWord{10, 0, 799}, - dictWord{11, 0, 258}, - dictWord{ - 11, - 0, - 1007, - }, - dictWord{12, 0, 331}, - dictWord{12, 0, 615}, - dictWord{13, 0, 188}, - dictWord{13, 0, 435}, - dictWord{14, 0, 8}, - dictWord{15, 0, 165}, - dictWord{ - 16, - 0, - 27, - }, - dictWord{20, 0, 40}, - dictWord{144, 11, 35}, - dictWord{4, 11, 128}, - dictWord{5, 11, 415}, - dictWord{6, 11, 462}, - dictWord{7, 11, 294}, - dictWord{7, 11, 578}, - dictWord{10, 11, 710}, - dictWord{139, 11, 86}, - dictWord{5, 0, 694}, - dictWord{136, 0, 909}, - dictWord{7, 0, 1109}, - dictWord{11, 0, 7}, - dictWord{5, 10, 37}, - dictWord{ - 6, - 10, - 39, - }, - dictWord{6, 10, 451}, - dictWord{7, 10, 218}, - dictWord{7, 10, 1166}, - dictWord{7, 10, 1687}, - dictWord{8, 10, 662}, - dictWord{144, 10, 2}, - dictWord{ - 136, - 11, - 587, - }, - dictWord{6, 11, 427}, - dictWord{7, 11, 1018}, - dictWord{138, 11, 692}, - dictWord{4, 11, 195}, - dictWord{6, 10, 508}, - dictWord{135, 11, 802}, - dictWord{4, 0, 167}, - dictWord{135, 0, 82}, - dictWord{5, 0, 62}, - dictWord{6, 0, 24}, - dictWord{6, 0, 534}, - dictWord{7, 0, 74}, - dictWord{7, 0, 678}, - dictWord{7, 0, 684}, - dictWord{ - 7, - 0, - 1043, - }, - dictWord{7, 0, 1072}, - dictWord{8, 0, 280}, - dictWord{8, 0, 541}, - dictWord{8, 0, 686}, - dictWord{9, 0, 258}, - dictWord{10, 0, 519}, - dictWord{11, 0, 252}, - dictWord{140, 0, 282}, - dictWord{138, 0, 33}, - dictWord{4, 0, 359}, - dictWord{133, 11, 738}, - dictWord{7, 0, 980}, - dictWord{9, 0, 328}, - dictWord{13, 0, 186}, - dictWord{13, 0, 364}, - dictWord{7, 10, 635}, - dictWord{7, 10, 796}, - dictWord{8, 10, 331}, - dictWord{9, 10, 330}, - dictWord{9, 10, 865}, - dictWord{10, 10, 119}, - dictWord{ - 10, - 10, - 235, - }, - dictWord{11, 10, 111}, - dictWord{11, 10, 129}, - dictWord{11, 10, 240}, - dictWord{12, 10, 31}, - dictWord{12, 10, 66}, - dictWord{12, 10, 222}, - dictWord{12, 10, 269}, - dictWord{12, 10, 599}, - dictWord{12, 10, 684}, - dictWord{12, 10, 689}, - dictWord{12, 10, 691}, - dictWord{142, 10, 345}, - dictWord{ - 137, - 10, - 527, - }, - dictWord{6, 0, 596}, - dictWord{7, 0, 585}, - dictWord{135, 10, 702}, - dictWord{134, 11, 1683}, - dictWord{133, 0, 211}, - dictWord{6, 0, 145}, - dictWord{ - 141, - 0, - 336, - }, - dictWord{134, 0, 1130}, - dictWord{7, 0, 873}, - dictWord{6, 10, 37}, - dictWord{7, 10, 1666}, - dictWord{8, 10, 195}, - dictWord{8, 10, 316}, - dictWord{ - 9, - 10, - 178, - }, - dictWord{9, 10, 276}, - dictWord{9, 10, 339}, - dictWord{9, 10, 536}, - dictWord{10, 10, 102}, - dictWord{10, 10, 362}, - dictWord{10, 10, 785}, - dictWord{ - 11, - 10, - 55, - }, - dictWord{11, 10, 149}, - dictWord{11, 10, 773}, - dictWord{13, 10, 416}, - dictWord{13, 10, 419}, - dictWord{14, 10, 38}, - dictWord{14, 10, 41}, - dictWord{ - 142, - 10, - 210, - }, - dictWord{8, 0, 840}, - dictWord{136, 0, 841}, - dictWord{132, 0, 263}, - dictWord{5, 11, 3}, - dictWord{8, 11, 578}, - dictWord{9, 11, 118}, - dictWord{ - 10, - 11, - 705, - }, - dictWord{12, 11, 383}, - dictWord{141, 11, 279}, - dictWord{132, 0, 916}, - dictWord{133, 11, 229}, - dictWord{133, 10, 645}, - dictWord{15, 0, 155}, - dictWord{16, 0, 79}, - dictWord{8, 11, 102}, - dictWord{10, 11, 578}, - dictWord{10, 11, 672}, - dictWord{12, 11, 496}, - dictWord{13, 11, 408}, - dictWord{14, 11, 121}, - dictWord{145, 11, 106}, - dictWord{4, 0, 599}, - dictWord{5, 0, 592}, - dictWord{6, 0, 1634}, - dictWord{7, 0, 5}, - dictWord{7, 0, 55}, - dictWord{7, 0, 67}, - dictWord{7, 0, 97}, - dictWord{7, 0, 691}, - dictWord{7, 0, 979}, - dictWord{7, 0, 1600}, - dictWord{7, 0, 1697}, - dictWord{8, 0, 207}, - dictWord{8, 0, 214}, - dictWord{8, 0, 231}, - dictWord{8, 0, 294}, - dictWord{8, 0, 336}, - dictWord{8, 0, 428}, - dictWord{8, 0, 471}, - dictWord{8, 0, 622}, - dictWord{8, 0, 626}, - dictWord{8, 0, 679}, - dictWord{8, 0, 759}, - dictWord{8, 0, 829}, - dictWord{9, 0, 11}, - dictWord{9, 0, 246}, - dictWord{9, 0, 484}, - dictWord{9, 0, 573}, - dictWord{9, 0, 706}, - dictWord{9, 0, 762}, - dictWord{9, 0, 798}, - dictWord{9, 0, 855}, - dictWord{9, 0, 870}, - dictWord{9, 0, 912}, - dictWord{10, 0, 303}, - dictWord{10, 0, 335}, - dictWord{10, 0, 424}, - dictWord{10, 0, 461}, - dictWord{10, 0, 543}, - dictWord{ - 10, - 0, - 759, - }, - dictWord{10, 0, 814}, - dictWord{11, 0, 59}, - dictWord{11, 0, 199}, - dictWord{11, 0, 235}, - dictWord{11, 0, 590}, - dictWord{11, 0, 631}, - dictWord{11, 0, 929}, - dictWord{11, 0, 963}, - dictWord{11, 0, 987}, - dictWord{12, 0, 114}, - dictWord{12, 0, 182}, - dictWord{12, 0, 226}, - dictWord{12, 0, 332}, - dictWord{12, 0, 439}, - dictWord{12, 0, 575}, - dictWord{12, 0, 598}, - dictWord{12, 0, 675}, - dictWord{13, 0, 8}, - dictWord{13, 0, 125}, - dictWord{13, 0, 194}, - dictWord{13, 0, 287}, - dictWord{ - 14, - 0, - 197, - }, - dictWord{14, 0, 383}, - dictWord{15, 0, 53}, - dictWord{17, 0, 63}, - dictWord{19, 0, 46}, - dictWord{19, 0, 98}, - dictWord{19, 0, 106}, - dictWord{148, 0, 85}, - dictWord{ - 7, - 0, - 1356, - }, - dictWord{132, 10, 290}, - dictWord{6, 10, 70}, - dictWord{7, 10, 1292}, - dictWord{10, 10, 762}, - dictWord{139, 10, 288}, - dictWord{150, 11, 55}, - dictWord{4, 0, 593}, - dictWord{8, 11, 115}, - dictWord{8, 11, 350}, - dictWord{9, 11, 489}, - dictWord{10, 11, 128}, - dictWord{11, 11, 306}, - dictWord{12, 11, 373}, - dictWord{14, 11, 30}, - dictWord{17, 11, 79}, - dictWord{147, 11, 80}, - dictWord{135, 11, 1235}, - dictWord{134, 0, 1392}, - dictWord{4, 11, 230}, - dictWord{ - 133, - 11, - 702, - }, - dictWord{147, 0, 126}, - dictWord{7, 10, 131}, - dictWord{7, 10, 422}, - dictWord{8, 10, 210}, - dictWord{140, 10, 573}, - dictWord{134, 0, 1179}, - dictWord{ - 139, - 11, - 435, - }, - dictWord{139, 10, 797}, - dictWord{134, 11, 1728}, - dictWord{4, 0, 162}, - dictWord{18, 11, 26}, - dictWord{19, 11, 42}, - dictWord{20, 11, 43}, - dictWord{21, 11, 0}, - dictWord{23, 11, 27}, - dictWord{152, 11, 14}, - dictWord{132, 10, 936}, - dictWord{6, 0, 765}, - dictWord{5, 10, 453}, - dictWord{134, 10, 441}, - dictWord{133, 0, 187}, - dictWord{135, 0, 1286}, - dictWord{6, 0, 635}, - dictWord{6, 0, 904}, - dictWord{6, 0, 1210}, - dictWord{134, 0, 1489}, - dictWord{4, 0, 215}, - dictWord{ - 8, - 0, - 890, - }, - dictWord{9, 0, 38}, - dictWord{10, 0, 923}, - dictWord{11, 0, 23}, - dictWord{11, 0, 127}, - dictWord{139, 0, 796}, - dictWord{6, 0, 1165}, - dictWord{ - 134, - 0, - 1306, - }, - dictWord{7, 0, 716}, - dictWord{13, 0, 97}, - dictWord{141, 0, 251}, - dictWord{132, 10, 653}, - dictWord{136, 0, 657}, - dictWord{146, 10, 80}, - dictWord{ - 5, - 11, - 622, - }, - dictWord{7, 11, 1032}, - dictWord{11, 11, 26}, - dictWord{11, 11, 213}, - dictWord{11, 11, 707}, - dictWord{12, 11, 380}, - dictWord{13, 11, 226}, - dictWord{141, 11, 355}, - dictWord{6, 0, 299}, - dictWord{5, 11, 70}, - dictWord{6, 11, 334}, - dictWord{9, 11, 171}, - dictWord{11, 11, 637}, - dictWord{12, 11, 202}, - dictWord{14, 11, 222}, - dictWord{145, 11, 42}, - dictWord{142, 0, 134}, - dictWord{4, 11, 23}, - dictWord{5, 11, 313}, - dictWord{5, 11, 1014}, - dictWord{6, 11, 50}, - dictWord{ - 6, - 11, - 51, - }, - dictWord{7, 11, 142}, - dictWord{7, 11, 384}, - dictWord{9, 11, 783}, - dictWord{139, 11, 741}, - dictWord{4, 11, 141}, - dictWord{7, 11, 559}, - dictWord{ - 8, - 11, - 640, - }, - dictWord{9, 11, 460}, - dictWord{12, 11, 183}, - dictWord{141, 11, 488}, - dictWord{136, 11, 614}, - dictWord{7, 10, 1368}, - dictWord{8, 10, 232}, - dictWord{8, 10, 361}, - dictWord{10, 10, 682}, - dictWord{138, 10, 742}, - dictWord{137, 10, 534}, - dictWord{6, 0, 1082}, - dictWord{140, 0, 658}, - dictWord{ - 137, - 10, - 27, - }, - dictWord{135, 0, 2002}, - dictWord{142, 10, 12}, - dictWord{4, 0, 28}, - dictWord{5, 0, 440}, - dictWord{7, 0, 248}, - dictWord{11, 0, 833}, - dictWord{140, 0, 344}, - dictWord{7, 10, 736}, - dictWord{139, 10, 264}, - dictWord{134, 10, 1657}, - dictWord{134, 0, 1654}, - dictWord{138, 0, 531}, - dictWord{5, 11, 222}, - dictWord{ - 9, - 11, - 140, - }, - dictWord{138, 11, 534}, - dictWord{6, 0, 634}, - dictWord{6, 0, 798}, - dictWord{134, 0, 840}, - dictWord{138, 11, 503}, - dictWord{135, 10, 127}, - dictWord{133, 0, 853}, - dictWord{5, 11, 154}, - dictWord{7, 11, 1491}, - dictWord{10, 11, 379}, - dictWord{138, 11, 485}, - dictWord{6, 0, 249}, - dictWord{7, 0, 1234}, - dictWord{139, 0, 573}, - dictWord{133, 11, 716}, - dictWord{7, 11, 1570}, - dictWord{140, 11, 542}, - dictWord{136, 10, 364}, - dictWord{138, 0, 527}, - dictWord{ - 4, - 11, - 91, - }, - dictWord{5, 11, 388}, - dictWord{5, 11, 845}, - dictWord{6, 11, 206}, - dictWord{6, 11, 252}, - dictWord{6, 11, 365}, - dictWord{7, 11, 136}, - dictWord{7, 11, 531}, - dictWord{8, 11, 264}, - dictWord{136, 11, 621}, - dictWord{134, 0, 1419}, - dictWord{135, 11, 1441}, - dictWord{7, 0, 49}, - dictWord{7, 0, 392}, - dictWord{8, 0, 20}, - dictWord{8, 0, 172}, - dictWord{8, 0, 690}, - dictWord{9, 0, 383}, - dictWord{9, 0, 845}, - dictWord{10, 0, 48}, - dictWord{11, 0, 293}, - dictWord{11, 0, 832}, - dictWord{ - 11, - 0, - 920, - }, - dictWord{11, 0, 984}, - dictWord{141, 0, 221}, - dictWord{5, 0, 858}, - dictWord{133, 0, 992}, - dictWord{5, 0, 728}, - dictWord{137, 10, 792}, - dictWord{ - 5, - 10, - 909, - }, - dictWord{9, 10, 849}, - dictWord{138, 10, 805}, - dictWord{7, 0, 525}, - dictWord{7, 0, 1579}, - dictWord{8, 0, 497}, - dictWord{136, 0, 573}, - dictWord{6, 0, 268}, - dictWord{137, 0, 62}, - dictWord{135, 11, 576}, - dictWord{134, 0, 1201}, - dictWord{5, 11, 771}, - dictWord{5, 11, 863}, - dictWord{5, 11, 898}, - dictWord{ - 6, - 11, - 1632, - }, - dictWord{6, 11, 1644}, - dictWord{134, 11, 1780}, - dictWord{133, 11, 331}, - dictWord{7, 0, 193}, - dictWord{7, 0, 1105}, - dictWord{10, 0, 495}, - dictWord{ - 7, - 10, - 397, - }, - dictWord{8, 10, 124}, - dictWord{8, 10, 619}, - dictWord{9, 10, 305}, - dictWord{11, 10, 40}, - dictWord{12, 10, 349}, - dictWord{13, 10, 134}, - dictWord{ - 13, - 10, - 295, - }, - dictWord{14, 10, 155}, - dictWord{15, 10, 120}, - dictWord{146, 10, 105}, - dictWord{138, 0, 106}, - dictWord{6, 0, 859}, - dictWord{5, 11, 107}, - dictWord{ - 7, - 11, - 201, - }, - dictWord{136, 11, 518}, - dictWord{6, 11, 446}, - dictWord{135, 11, 1817}, - dictWord{13, 0, 23}, - dictWord{4, 10, 262}, - dictWord{135, 10, 342}, - dictWord{133, 10, 641}, - dictWord{137, 11, 851}, - dictWord{6, 0, 925}, - dictWord{137, 0, 813}, - dictWord{132, 11, 504}, - dictWord{6, 0, 613}, - dictWord{ - 136, - 0, - 223, - }, - dictWord{4, 10, 99}, - dictWord{6, 10, 250}, - dictWord{6, 10, 346}, - dictWord{8, 10, 127}, - dictWord{138, 10, 81}, - dictWord{136, 0, 953}, - dictWord{ - 132, - 10, - 915, - }, - dictWord{139, 11, 892}, - dictWord{5, 10, 75}, - dictWord{9, 10, 517}, - dictWord{10, 10, 470}, - dictWord{12, 10, 155}, - dictWord{141, 10, 224}, - dictWord{ - 4, - 0, - 666, - }, - dictWord{7, 0, 1017}, - dictWord{7, 11, 996}, - dictWord{138, 11, 390}, - dictWord{5, 11, 883}, - dictWord{133, 11, 975}, - dictWord{14, 10, 83}, - dictWord{ - 142, - 11, - 83, - }, - dictWord{4, 0, 670}, - dictWord{5, 11, 922}, - dictWord{134, 11, 1707}, - dictWord{135, 0, 216}, - dictWord{9, 0, 40}, - dictWord{11, 0, 136}, - dictWord{ - 135, - 11, - 787, - }, - dictWord{5, 10, 954}, - dictWord{5, 11, 993}, - dictWord{7, 11, 515}, - dictWord{137, 11, 91}, - dictWord{139, 0, 259}, - dictWord{7, 0, 1114}, - dictWord{ - 9, - 0, - 310, - }, - dictWord{9, 0, 682}, - dictWord{10, 0, 440}, - dictWord{13, 0, 40}, - dictWord{6, 10, 304}, - dictWord{8, 10, 418}, - dictWord{11, 10, 341}, - dictWord{ - 139, - 10, - 675, - }, - dictWord{14, 0, 296}, - dictWord{9, 10, 410}, - dictWord{139, 10, 425}, - dictWord{10, 11, 377}, - dictWord{12, 11, 363}, - dictWord{13, 11, 68}, - dictWord{ - 13, - 11, - 94, - }, - dictWord{14, 11, 108}, - dictWord{142, 11, 306}, - dictWord{7, 0, 1401}, - dictWord{135, 0, 1476}, - dictWord{4, 0, 296}, - dictWord{6, 0, 475}, - dictWord{ - 7, - 0, - 401, - }, - dictWord{7, 0, 1410}, - dictWord{7, 0, 1594}, - dictWord{7, 0, 1674}, - dictWord{8, 0, 63}, - dictWord{8, 0, 660}, - dictWord{137, 0, 74}, - dictWord{4, 0, 139}, - dictWord{4, 0, 388}, - dictWord{140, 0, 188}, - dictWord{132, 0, 797}, - dictWord{132, 11, 766}, - dictWord{5, 11, 103}, - dictWord{7, 11, 921}, - dictWord{8, 11, 580}, - dictWord{8, 11, 593}, - dictWord{8, 11, 630}, - dictWord{138, 11, 28}, - dictWord{4, 11, 911}, - dictWord{5, 11, 867}, - dictWord{133, 11, 1013}, - dictWord{134, 10, 14}, - dictWord{134, 0, 1572}, - dictWord{134, 10, 1708}, - dictWord{21, 0, 39}, - dictWord{5, 10, 113}, - dictWord{6, 10, 243}, - dictWord{7, 10, 1865}, - dictWord{ - 11, - 10, - 161, - }, - dictWord{16, 10, 37}, - dictWord{145, 10, 99}, - dictWord{7, 11, 1563}, - dictWord{141, 11, 182}, - dictWord{5, 11, 135}, - dictWord{6, 11, 519}, - dictWord{ - 7, - 11, - 1722, - }, - dictWord{10, 11, 271}, - dictWord{11, 11, 261}, - dictWord{145, 11, 54}, - dictWord{132, 10, 274}, - dictWord{134, 0, 1594}, - dictWord{4, 11, 300}, - dictWord{5, 11, 436}, - dictWord{135, 11, 484}, - dictWord{4, 0, 747}, - dictWord{6, 0, 290}, - dictWord{7, 0, 649}, - dictWord{7, 0, 1479}, - dictWord{135, 0, 1583}, - dictWord{133, 11, 535}, - dictWord{147, 11, 82}, - dictWord{133, 0, 232}, - dictWord{137, 0, 887}, - dictWord{135, 10, 166}, - dictWord{136, 0, 521}, - dictWord{4, 0, 14}, - dictWord{7, 0, 472}, - dictWord{7, 0, 1801}, - dictWord{10, 0, 748}, - dictWord{141, 0, 458}, - dictWord{134, 0, 741}, - dictWord{134, 0, 992}, - dictWord{16, 0, 111}, - dictWord{137, 10, 304}, - dictWord{4, 0, 425}, - dictWord{5, 11, 387}, - dictWord{7, 11, 557}, - dictWord{12, 11, 547}, - dictWord{142, 11, 86}, - dictWord{ - 135, - 11, - 1747, - }, - dictWord{5, 10, 654}, - dictWord{135, 11, 1489}, - dictWord{7, 0, 789}, - dictWord{4, 11, 6}, - dictWord{5, 11, 708}, - dictWord{136, 11, 75}, - dictWord{ - 6, - 10, - 273, - }, - dictWord{10, 10, 188}, - dictWord{13, 10, 377}, - dictWord{146, 10, 77}, - dictWord{6, 0, 1593}, - dictWord{4, 11, 303}, - dictWord{7, 11, 619}, - dictWord{ - 10, - 11, - 547, - }, - dictWord{10, 11, 687}, - dictWord{11, 11, 122}, - dictWord{140, 11, 601}, - dictWord{134, 0, 1768}, - dictWord{135, 10, 410}, - dictWord{138, 11, 772}, - dictWord{11, 0, 233}, - dictWord{139, 10, 524}, - dictWord{5, 0, 943}, - dictWord{134, 0, 1779}, - dictWord{134, 10, 1785}, - dictWord{136, 11, 529}, - dictWord{ - 132, - 0, - 955, - }, - dictWord{5, 0, 245}, - dictWord{6, 0, 576}, - dictWord{7, 0, 582}, - dictWord{136, 0, 225}, - dictWord{132, 10, 780}, - dictWord{142, 0, 241}, - dictWord{ - 134, - 0, - 1943, - }, - dictWord{4, 11, 106}, - dictWord{7, 11, 310}, - dictWord{7, 11, 1785}, - dictWord{10, 11, 690}, - dictWord{139, 11, 717}, - dictWord{134, 0, 1284}, - dictWord{5, 11, 890}, - dictWord{133, 11, 988}, - dictWord{6, 11, 626}, - dictWord{142, 11, 431}, - dictWord{10, 11, 706}, - dictWord{145, 11, 32}, - dictWord{ - 137, - 11, - 332, - }, - dictWord{132, 11, 698}, - dictWord{135, 0, 709}, - dictWord{5, 10, 948}, - dictWord{138, 11, 17}, - dictWord{136, 0, 554}, - dictWord{134, 0, 1564}, - dictWord{139, 10, 941}, - dictWord{132, 0, 443}, - dictWord{134, 0, 909}, - dictWord{134, 11, 84}, - dictWord{142, 0, 280}, - dictWord{4, 10, 532}, - dictWord{5, 10, 706}, - dictWord{135, 10, 662}, - dictWord{132, 0, 729}, - dictWord{5, 10, 837}, - dictWord{6, 10, 1651}, - dictWord{139, 10, 985}, - dictWord{135, 10, 1861}, - dictWord{ - 4, - 0, - 348, - }, - dictWord{152, 11, 3}, - dictWord{5, 11, 986}, - dictWord{6, 11, 130}, - dictWord{7, 11, 1582}, - dictWord{8, 11, 458}, - dictWord{10, 11, 101}, - dictWord{ - 10, - 11, - 318, - }, - dictWord{138, 11, 823}, - dictWord{134, 0, 758}, - dictWord{4, 0, 298}, - dictWord{137, 0, 848}, - dictWord{4, 10, 330}, - dictWord{7, 10, 933}, - dictWord{ - 7, - 10, - 2012, - }, - dictWord{136, 10, 292}, - dictWord{7, 11, 1644}, - dictWord{137, 11, 129}, - dictWord{6, 0, 1422}, - dictWord{9, 0, 829}, - dictWord{135, 10, 767}, - dictWord{5, 0, 164}, - dictWord{7, 0, 121}, - dictWord{142, 0, 189}, - dictWord{7, 0, 812}, - dictWord{7, 0, 1261}, - dictWord{7, 0, 1360}, - dictWord{9, 0, 632}, - dictWord{ - 140, - 0, - 352, - }, - dictWord{135, 11, 1788}, - dictWord{139, 0, 556}, - dictWord{135, 11, 997}, - dictWord{145, 10, 114}, - dictWord{4, 0, 172}, - dictWord{9, 0, 611}, - dictWord{10, 0, 436}, - dictWord{12, 0, 673}, - dictWord{13, 0, 255}, - dictWord{137, 10, 883}, - dictWord{11, 0, 530}, - dictWord{138, 10, 274}, - dictWord{133, 0, 844}, - dictWord{134, 0, 984}, - dictWord{13, 0, 232}, - dictWord{18, 0, 35}, - dictWord{4, 10, 703}, - dictWord{135, 10, 207}, - dictWord{132, 10, 571}, - dictWord{9, 0, 263}, - dictWord{10, 0, 147}, - dictWord{138, 0, 492}, - dictWord{7, 11, 1756}, - dictWord{137, 11, 98}, - dictWord{5, 10, 873}, - dictWord{5, 10, 960}, - dictWord{8, 10, 823}, - dictWord{137, 10, 881}, - dictWord{133, 0, 537}, - dictWord{132, 0, 859}, - dictWord{7, 11, 1046}, - dictWord{139, 11, 160}, - dictWord{137, 0, 842}, - dictWord{ - 139, - 10, - 283, - }, - dictWord{5, 10, 33}, - dictWord{6, 10, 470}, - dictWord{139, 10, 424}, - dictWord{6, 11, 45}, - dictWord{7, 11, 433}, - dictWord{8, 11, 129}, - dictWord{ - 9, - 11, - 21, - }, - dictWord{10, 11, 392}, - dictWord{11, 11, 79}, - dictWord{12, 11, 499}, - dictWord{13, 11, 199}, - dictWord{141, 11, 451}, - dictWord{135, 0, 1291}, - dictWord{135, 10, 1882}, - dictWord{7, 11, 558}, - dictWord{136, 11, 353}, - dictWord{134, 0, 1482}, - dictWord{5, 0, 230}, - dictWord{5, 0, 392}, - dictWord{6, 0, 420}, - dictWord{9, 0, 568}, - dictWord{140, 0, 612}, - dictWord{6, 0, 262}, - dictWord{7, 10, 90}, - dictWord{7, 10, 664}, - dictWord{7, 10, 830}, - dictWord{7, 10, 1380}, - dictWord{ - 7, - 10, - 2025, - }, - dictWord{8, 11, 81}, - dictWord{8, 10, 448}, - dictWord{8, 10, 828}, - dictWord{9, 11, 189}, - dictWord{9, 11, 201}, - dictWord{11, 11, 478}, - dictWord{ - 11, - 11, - 712, - }, - dictWord{141, 11, 338}, - dictWord{142, 0, 31}, - dictWord{5, 11, 353}, - dictWord{151, 11, 26}, - dictWord{132, 0, 753}, - dictWord{4, 0, 0}, - dictWord{ - 5, - 0, - 41, - }, - dictWord{7, 0, 1459}, - dictWord{7, 0, 1469}, - dictWord{7, 0, 1859}, - dictWord{9, 0, 549}, - dictWord{139, 0, 905}, - dictWord{9, 10, 417}, - dictWord{ - 137, - 10, - 493, - }, - dictWord{135, 11, 1113}, - dictWord{133, 0, 696}, - dictWord{141, 11, 448}, - dictWord{134, 10, 295}, - dictWord{132, 0, 834}, - dictWord{4, 0, 771}, - dictWord{5, 10, 1019}, - dictWord{6, 11, 25}, - dictWord{7, 11, 855}, - dictWord{7, 11, 1258}, - dictWord{144, 11, 32}, - dictWord{134, 0, 1076}, - dictWord{133, 0, 921}, - dictWord{133, 0, 674}, - dictWord{4, 11, 4}, - dictWord{7, 11, 1118}, - dictWord{7, 11, 1320}, - dictWord{7, 11, 1706}, - dictWord{8, 11, 277}, - dictWord{9, 11, 622}, - dictWord{10, 11, 9}, - dictWord{11, 11, 724}, - dictWord{12, 11, 350}, - dictWord{12, 11, 397}, - dictWord{13, 11, 28}, - dictWord{13, 11, 159}, - dictWord{15, 11, 89}, - dictWord{18, 11, 5}, - dictWord{19, 11, 9}, - dictWord{20, 11, 34}, - dictWord{150, 11, 47}, - dictWord{134, 10, 208}, - dictWord{6, 0, 444}, - dictWord{136, 0, 308}, - dictWord{ - 6, - 0, - 180, - }, - dictWord{7, 0, 1137}, - dictWord{8, 0, 751}, - dictWord{139, 0, 805}, - dictWord{4, 0, 183}, - dictWord{7, 0, 271}, - dictWord{11, 0, 824}, - dictWord{ - 11, - 0, - 952, - }, - dictWord{13, 0, 278}, - dictWord{13, 0, 339}, - dictWord{13, 0, 482}, - dictWord{14, 0, 424}, - dictWord{148, 0, 99}, - dictWord{7, 11, 317}, - dictWord{ - 135, - 11, - 569, - }, - dictWord{4, 0, 19}, - dictWord{5, 0, 477}, - dictWord{5, 0, 596}, - dictWord{6, 0, 505}, - dictWord{7, 0, 1221}, - dictWord{11, 0, 907}, - dictWord{12, 0, 209}, - dictWord{141, 0, 214}, - dictWord{135, 0, 1215}, - dictWord{6, 0, 271}, - dictWord{7, 0, 398}, - dictWord{8, 0, 387}, - dictWord{10, 0, 344}, - dictWord{7, 10, 448}, - dictWord{ - 7, - 10, - 1629, - }, - dictWord{7, 10, 1813}, - dictWord{8, 10, 442}, - dictWord{9, 10, 710}, - dictWord{10, 10, 282}, - dictWord{138, 10, 722}, - dictWord{11, 10, 844}, - dictWord{12, 10, 104}, - dictWord{140, 10, 625}, - dictWord{134, 11, 255}, - dictWord{133, 10, 787}, - dictWord{134, 0, 1645}, - dictWord{11, 11, 956}, - dictWord{ - 151, - 11, - 3, - }, - dictWord{6, 0, 92}, - dictWord{6, 0, 188}, - dictWord{7, 0, 209}, - dictWord{7, 0, 1269}, - dictWord{7, 0, 1524}, - dictWord{7, 0, 1876}, - dictWord{8, 0, 661}, - dictWord{10, 0, 42}, - dictWord{10, 0, 228}, - dictWord{11, 0, 58}, - dictWord{11, 0, 1020}, - dictWord{12, 0, 58}, - dictWord{12, 0, 118}, - dictWord{141, 0, 32}, - dictWord{ - 4, - 0, - 459, - }, - dictWord{133, 0, 966}, - dictWord{4, 11, 536}, - dictWord{7, 11, 1141}, - dictWord{10, 11, 723}, - dictWord{139, 11, 371}, - dictWord{140, 0, 330}, - dictWord{134, 0, 1557}, - dictWord{7, 11, 285}, - dictWord{135, 11, 876}, - dictWord{136, 10, 491}, - dictWord{135, 11, 560}, - dictWord{6, 0, 18}, - dictWord{7, 0, 179}, - dictWord{7, 0, 932}, - dictWord{8, 0, 548}, - dictWord{8, 0, 757}, - dictWord{9, 0, 54}, - dictWord{9, 0, 65}, - dictWord{9, 0, 532}, - dictWord{9, 0, 844}, - dictWord{10, 0, 113}, - dictWord{10, 0, 117}, - dictWord{10, 0, 315}, - dictWord{10, 0, 560}, - dictWord{10, 0, 622}, - dictWord{10, 0, 798}, - dictWord{11, 0, 153}, - dictWord{11, 0, 351}, - dictWord{ - 11, - 0, - 375, - }, - dictWord{12, 0, 78}, - dictWord{12, 0, 151}, - dictWord{12, 0, 392}, - dictWord{12, 0, 666}, - dictWord{14, 0, 248}, - dictWord{143, 0, 23}, - dictWord{ - 6, - 0, - 1742, - }, - dictWord{132, 11, 690}, - dictWord{4, 10, 403}, - dictWord{5, 10, 441}, - dictWord{7, 10, 450}, - dictWord{10, 10, 840}, - dictWord{11, 10, 101}, - dictWord{ - 12, - 10, - 193, - }, - dictWord{141, 10, 430}, - dictWord{133, 0, 965}, - dictWord{134, 0, 182}, - dictWord{10, 0, 65}, - dictWord{10, 0, 488}, - dictWord{138, 0, 497}, - dictWord{135, 11, 1346}, - dictWord{6, 0, 973}, - dictWord{6, 0, 1158}, - dictWord{10, 11, 200}, - dictWord{19, 11, 2}, - dictWord{151, 11, 22}, - dictWord{4, 11, 190}, - dictWord{133, 11, 554}, - dictWord{133, 10, 679}, - dictWord{7, 0, 328}, - dictWord{137, 10, 326}, - dictWord{133, 11, 1001}, - dictWord{9, 0, 588}, - dictWord{ - 138, - 0, - 260, - }, - dictWord{133, 11, 446}, - dictWord{135, 10, 1128}, - dictWord{135, 10, 1796}, - dictWord{147, 11, 119}, - dictWord{134, 0, 1786}, - dictWord{ - 6, - 0, - 1328, - }, - dictWord{6, 0, 1985}, - dictWord{8, 0, 962}, - dictWord{138, 0, 1017}, - dictWord{135, 0, 308}, - dictWord{11, 0, 508}, - dictWord{4, 10, 574}, - dictWord{ - 7, - 10, - 350, - }, - dictWord{7, 10, 1024}, - dictWord{8, 10, 338}, - dictWord{9, 10, 677}, - dictWord{138, 10, 808}, - dictWord{138, 11, 752}, - dictWord{135, 10, 1081}, - dictWord{137, 11, 96}, - dictWord{7, 10, 1676}, - dictWord{135, 10, 2037}, - dictWord{136, 0, 588}, - dictWord{132, 11, 304}, - dictWord{133, 0, 614}, - dictWord{ - 140, - 0, - 793, - }, - dictWord{136, 0, 287}, - dictWord{137, 10, 297}, - dictWord{141, 10, 37}, - dictWord{6, 11, 53}, - dictWord{6, 11, 199}, - dictWord{7, 11, 1408}, - dictWord{ - 8, - 11, - 32, - }, - dictWord{8, 11, 93}, - dictWord{9, 11, 437}, - dictWord{10, 11, 397}, - dictWord{10, 11, 629}, - dictWord{11, 11, 593}, - dictWord{11, 11, 763}, - dictWord{ - 13, - 11, - 326, - }, - dictWord{145, 11, 35}, - dictWord{134, 11, 105}, - dictWord{9, 11, 320}, - dictWord{10, 11, 506}, - dictWord{138, 11, 794}, - dictWord{5, 11, 114}, - dictWord{5, 11, 255}, - dictWord{141, 11, 285}, - dictWord{140, 0, 290}, - dictWord{7, 11, 2035}, - dictWord{8, 11, 19}, - dictWord{9, 11, 89}, - dictWord{138, 11, 831}, - dictWord{134, 0, 1136}, - dictWord{7, 0, 719}, - dictWord{8, 0, 796}, - dictWord{8, 0, 809}, - dictWord{8, 0, 834}, - dictWord{6, 10, 306}, - dictWord{7, 10, 1140}, - dictWord{ - 7, - 10, - 1340, - }, - dictWord{8, 10, 133}, - dictWord{138, 10, 449}, - dictWord{139, 10, 1011}, - dictWord{5, 0, 210}, - dictWord{6, 0, 213}, - dictWord{7, 0, 60}, - dictWord{ - 10, - 0, - 364, - }, - dictWord{139, 0, 135}, - dictWord{5, 0, 607}, - dictWord{8, 0, 326}, - dictWord{136, 0, 490}, - dictWord{138, 11, 176}, - dictWord{132, 0, 701}, - dictWord{ - 5, - 0, - 472, - }, - dictWord{7, 0, 380}, - dictWord{137, 0, 758}, - dictWord{135, 0, 1947}, - dictWord{6, 0, 1079}, - dictWord{138, 0, 278}, - dictWord{138, 11, 391}, - dictWord{ - 5, - 10, - 329, - }, - dictWord{8, 10, 260}, - dictWord{139, 11, 156}, - dictWord{4, 0, 386}, - dictWord{7, 0, 41}, - dictWord{8, 0, 405}, - dictWord{8, 0, 728}, - dictWord{9, 0, 497}, - dictWord{11, 0, 110}, - dictWord{11, 0, 360}, - dictWord{15, 0, 37}, - dictWord{144, 0, 84}, - dictWord{5, 0, 46}, - dictWord{7, 0, 1452}, - dictWord{7, 0, 1480}, - dictWord{ - 8, - 0, - 634, - }, - dictWord{140, 0, 472}, - dictWord{136, 0, 961}, - dictWord{4, 0, 524}, - dictWord{136, 0, 810}, - dictWord{10, 0, 238}, - dictWord{141, 0, 33}, - dictWord{ - 132, - 10, - 657, - }, - dictWord{152, 10, 7}, - dictWord{133, 0, 532}, - dictWord{5, 0, 997}, - dictWord{135, 10, 1665}, - dictWord{7, 11, 594}, - dictWord{7, 11, 851}, - dictWord{ - 7, - 11, - 1858, - }, - dictWord{9, 11, 411}, - dictWord{9, 11, 574}, - dictWord{9, 11, 666}, - dictWord{9, 11, 737}, - dictWord{10, 11, 346}, - dictWord{10, 11, 712}, - dictWord{ - 11, - 11, - 246, - }, - dictWord{11, 11, 432}, - dictWord{11, 11, 517}, - dictWord{11, 11, 647}, - dictWord{11, 11, 679}, - dictWord{11, 11, 727}, - dictWord{12, 11, 304}, - dictWord{12, 11, 305}, - dictWord{12, 11, 323}, - dictWord{12, 11, 483}, - dictWord{12, 11, 572}, - dictWord{12, 11, 593}, - dictWord{12, 11, 602}, - dictWord{ - 13, - 11, - 95, - }, - dictWord{13, 11, 101}, - dictWord{13, 11, 171}, - dictWord{13, 11, 315}, - dictWord{13, 11, 378}, - dictWord{13, 11, 425}, - dictWord{13, 11, 475}, - dictWord{ - 14, - 11, - 63, - }, - dictWord{14, 11, 380}, - dictWord{14, 11, 384}, - dictWord{15, 11, 133}, - dictWord{18, 11, 112}, - dictWord{148, 11, 72}, - dictWord{5, 11, 955}, - dictWord{136, 11, 814}, - dictWord{134, 0, 1301}, - dictWord{5, 10, 66}, - dictWord{7, 10, 1896}, - dictWord{136, 10, 288}, - dictWord{133, 11, 56}, - dictWord{ - 134, - 10, - 1643, - }, - dictWord{6, 0, 1298}, - dictWord{148, 11, 100}, - dictWord{5, 0, 782}, - dictWord{5, 0, 829}, - dictWord{6, 0, 671}, - dictWord{6, 0, 1156}, - dictWord{6, 0, 1738}, - dictWord{137, 11, 621}, - dictWord{4, 0, 306}, - dictWord{5, 0, 570}, - dictWord{7, 0, 1347}, - dictWord{5, 10, 91}, - dictWord{5, 10, 648}, - dictWord{5, 10, 750}, - dictWord{ - 5, - 10, - 781, - }, - dictWord{6, 10, 54}, - dictWord{6, 10, 112}, - dictWord{6, 10, 402}, - dictWord{6, 10, 1732}, - dictWord{7, 10, 315}, - dictWord{7, 10, 749}, - dictWord{ - 7, - 10, - 1900, - }, - dictWord{9, 10, 78}, - dictWord{9, 10, 508}, - dictWord{10, 10, 611}, - dictWord{10, 10, 811}, - dictWord{11, 10, 510}, - dictWord{11, 10, 728}, - dictWord{ - 13, - 10, - 36, - }, - dictWord{14, 10, 39}, - dictWord{16, 10, 83}, - dictWord{17, 10, 124}, - dictWord{148, 10, 30}, - dictWord{8, 10, 570}, - dictWord{9, 11, 477}, - dictWord{ - 141, - 11, - 78, - }, - dictWord{4, 11, 639}, - dictWord{10, 11, 4}, - dictWord{10, 10, 322}, - dictWord{10, 10, 719}, - dictWord{11, 10, 407}, - dictWord{11, 11, 638}, - dictWord{ - 12, - 11, - 177, - }, - dictWord{148, 11, 57}, - dictWord{7, 0, 1823}, - dictWord{139, 0, 693}, - dictWord{7, 0, 759}, - dictWord{5, 11, 758}, - dictWord{8, 10, 125}, - dictWord{ - 8, - 10, - 369, - }, - dictWord{8, 10, 524}, - dictWord{10, 10, 486}, - dictWord{11, 10, 13}, - dictWord{11, 10, 381}, - dictWord{11, 10, 736}, - dictWord{11, 10, 766}, - dictWord{ - 11, - 10, - 845, - }, - dictWord{13, 10, 114}, - dictWord{13, 10, 292}, - dictWord{142, 10, 47}, - dictWord{7, 0, 1932}, - dictWord{6, 10, 1684}, - dictWord{6, 10, 1731}, - dictWord{7, 10, 356}, - dictWord{8, 10, 54}, - dictWord{8, 10, 221}, - dictWord{9, 10, 225}, - dictWord{9, 10, 356}, - dictWord{10, 10, 77}, - dictWord{10, 10, 446}, - dictWord{ - 10, - 10, - 731, - }, - dictWord{12, 10, 404}, - dictWord{141, 10, 491}, - dictWord{135, 11, 552}, - dictWord{135, 11, 1112}, - dictWord{4, 0, 78}, - dictWord{5, 0, 96}, - dictWord{ - 5, - 0, - 182, - }, - dictWord{6, 0, 1257}, - dictWord{7, 0, 1724}, - dictWord{7, 0, 1825}, - dictWord{10, 0, 394}, - dictWord{10, 0, 471}, - dictWord{11, 0, 532}, - dictWord{ - 14, - 0, - 340, - }, - dictWord{145, 0, 88}, - dictWord{139, 11, 328}, - dictWord{135, 0, 1964}, - dictWord{132, 10, 411}, - dictWord{4, 10, 80}, - dictWord{5, 10, 44}, - dictWord{ - 137, - 11, - 133, - }, - dictWord{5, 11, 110}, - dictWord{6, 11, 169}, - dictWord{6, 11, 1702}, - dictWord{7, 11, 400}, - dictWord{8, 11, 538}, - dictWord{9, 11, 184}, - dictWord{ - 9, - 11, - 524, - }, - dictWord{140, 11, 218}, - dictWord{4, 0, 521}, - dictWord{5, 10, 299}, - dictWord{7, 10, 1083}, - dictWord{140, 11, 554}, - dictWord{6, 11, 133}, - dictWord{ - 9, - 11, - 353, - }, - dictWord{12, 11, 628}, - dictWord{146, 11, 79}, - dictWord{6, 0, 215}, - dictWord{7, 0, 584}, - dictWord{7, 0, 1028}, - dictWord{7, 0, 1473}, - dictWord{ - 7, - 0, - 1721, - }, - dictWord{9, 0, 424}, - dictWord{138, 0, 779}, - dictWord{7, 0, 857}, - dictWord{7, 0, 1209}, - dictWord{7, 10, 1713}, - dictWord{9, 10, 537}, - dictWord{ - 10, - 10, - 165, - }, - dictWord{12, 10, 219}, - dictWord{140, 10, 561}, - dictWord{4, 10, 219}, - dictWord{6, 11, 93}, - dictWord{7, 11, 1422}, - dictWord{7, 10, 1761}, - dictWord{ - 7, - 11, - 1851, - }, - dictWord{8, 11, 673}, - dictWord{9, 10, 86}, - dictWord{9, 11, 529}, - dictWord{140, 11, 43}, - dictWord{137, 11, 371}, - dictWord{136, 0, 671}, - dictWord{ - 5, - 0, - 328, - }, - dictWord{135, 0, 918}, - dictWord{132, 0, 529}, - dictWord{9, 11, 25}, - dictWord{10, 11, 467}, - dictWord{138, 11, 559}, - dictWord{4, 11, 335}, - dictWord{ - 135, - 11, - 942, - }, - dictWord{134, 0, 716}, - dictWord{134, 0, 1509}, - dictWord{6, 0, 67}, - dictWord{7, 0, 258}, - dictWord{7, 0, 1630}, - dictWord{9, 0, 354}, - dictWord{ - 9, - 0, - 675, - }, - dictWord{10, 0, 830}, - dictWord{14, 0, 80}, - dictWord{17, 0, 80}, - dictWord{140, 10, 428}, - dictWord{134, 0, 1112}, - dictWord{6, 0, 141}, - dictWord{7, 0, 225}, - dictWord{9, 0, 59}, - dictWord{9, 0, 607}, - dictWord{10, 0, 312}, - dictWord{11, 0, 687}, - dictWord{12, 0, 555}, - dictWord{13, 0, 373}, - dictWord{13, 0, 494}, - dictWord{ - 148, - 0, - 58, - }, - dictWord{133, 10, 514}, - dictWord{8, 11, 39}, - dictWord{10, 11, 773}, - dictWord{11, 11, 84}, - dictWord{12, 11, 205}, - dictWord{142, 11, 1}, - dictWord{ - 8, - 0, - 783, - }, - dictWord{5, 11, 601}, - dictWord{133, 11, 870}, - dictWord{136, 11, 594}, - dictWord{4, 10, 55}, - dictWord{5, 10, 301}, - dictWord{6, 10, 571}, - dictWord{ - 14, - 10, - 49, - }, - dictWord{146, 10, 102}, - dictWord{132, 11, 181}, - dictWord{134, 11, 1652}, - dictWord{133, 10, 364}, - dictWord{4, 11, 97}, - dictWord{5, 11, 147}, - dictWord{6, 11, 286}, - dictWord{7, 11, 1362}, - dictWord{141, 11, 176}, - dictWord{4, 10, 76}, - dictWord{7, 10, 1550}, - dictWord{9, 10, 306}, - dictWord{9, 10, 430}, - dictWord{9, 10, 663}, - dictWord{10, 10, 683}, - dictWord{11, 10, 427}, - dictWord{11, 10, 753}, - dictWord{12, 10, 334}, - dictWord{12, 10, 442}, - dictWord{ - 14, - 10, - 258, - }, - dictWord{14, 10, 366}, - dictWord{143, 10, 131}, - dictWord{137, 10, 52}, - dictWord{6, 0, 955}, - dictWord{134, 0, 1498}, - dictWord{6, 11, 375}, - dictWord{ - 7, - 11, - 169, - }, - dictWord{7, 11, 254}, - dictWord{136, 11, 780}, - dictWord{7, 0, 430}, - dictWord{11, 0, 46}, - dictWord{14, 0, 343}, - dictWord{142, 11, 343}, - dictWord{ - 135, - 0, - 1183, - }, - dictWord{5, 0, 602}, - dictWord{7, 0, 2018}, - dictWord{9, 0, 418}, - dictWord{9, 0, 803}, - dictWord{135, 11, 1447}, - dictWord{8, 0, 677}, - dictWord{ - 135, - 11, - 1044, - }, - dictWord{139, 11, 285}, - dictWord{4, 10, 656}, - dictWord{135, 10, 779}, - dictWord{135, 10, 144}, - dictWord{5, 11, 629}, - dictWord{ - 135, - 11, - 1549, - }, - dictWord{135, 10, 1373}, - dictWord{138, 11, 209}, - dictWord{7, 10, 554}, - dictWord{7, 10, 605}, - dictWord{141, 10, 10}, - dictWord{5, 10, 838}, - dictWord{ - 5, - 10, - 841, - }, - dictWord{134, 10, 1649}, - dictWord{133, 10, 1012}, - dictWord{6, 0, 1357}, - dictWord{134, 0, 1380}, - dictWord{144, 0, 53}, - dictWord{6, 0, 590}, - dictWord{7, 10, 365}, - dictWord{7, 10, 1357}, - dictWord{7, 10, 1497}, - dictWord{8, 10, 154}, - dictWord{141, 10, 281}, - dictWord{133, 10, 340}, - dictWord{ - 132, - 11, - 420, - }, - dictWord{135, 0, 329}, - dictWord{147, 11, 32}, - dictWord{4, 0, 469}, - dictWord{10, 11, 429}, - dictWord{139, 10, 495}, - dictWord{8, 10, 261}, - dictWord{ - 9, - 10, - 144, - }, - dictWord{9, 10, 466}, - dictWord{10, 10, 370}, - dictWord{12, 10, 470}, - dictWord{13, 10, 144}, - dictWord{142, 10, 348}, - dictWord{142, 0, 460}, - dictWord{4, 11, 325}, - dictWord{9, 10, 897}, - dictWord{138, 11, 125}, - dictWord{6, 0, 1743}, - dictWord{6, 10, 248}, - dictWord{9, 10, 546}, - dictWord{10, 10, 535}, - dictWord{11, 10, 681}, - dictWord{141, 10, 135}, - dictWord{4, 0, 990}, - dictWord{5, 0, 929}, - dictWord{6, 0, 340}, - dictWord{8, 0, 376}, - dictWord{8, 0, 807}, - dictWord{ - 8, - 0, - 963, - }, - dictWord{8, 0, 980}, - dictWord{138, 0, 1007}, - dictWord{134, 0, 1603}, - dictWord{140, 0, 250}, - dictWord{4, 11, 714}, - dictWord{133, 11, 469}, - dictWord{134, 10, 567}, - dictWord{136, 10, 445}, - dictWord{5, 0, 218}, - dictWord{7, 0, 1610}, - dictWord{8, 0, 646}, - dictWord{10, 0, 83}, - dictWord{11, 11, 138}, - dictWord{140, 11, 40}, - dictWord{7, 0, 1512}, - dictWord{135, 0, 1794}, - dictWord{135, 11, 1216}, - dictWord{11, 0, 0}, - dictWord{16, 0, 78}, - dictWord{132, 11, 718}, - dictWord{133, 0, 571}, - dictWord{132, 0, 455}, - dictWord{134, 0, 1012}, - dictWord{5, 11, 124}, - dictWord{5, 11, 144}, - dictWord{6, 11, 548}, - dictWord{7, 11, 15}, - dictWord{7, 11, 153}, - dictWord{137, 11, 629}, - dictWord{142, 11, 10}, - dictWord{6, 11, 75}, - dictWord{7, 11, 1531}, - dictWord{8, 11, 416}, - dictWord{9, 11, 240}, - dictWord{9, 11, 275}, - dictWord{10, 11, 100}, - dictWord{11, 11, 658}, - dictWord{11, 11, 979}, - dictWord{12, 11, 86}, - dictWord{13, 11, 468}, - dictWord{14, 11, 66}, - dictWord{14, 11, 207}, - dictWord{15, 11, 20}, - dictWord{15, 11, 25}, - dictWord{144, 11, 58}, - dictWord{132, 10, 577}, - dictWord{5, 11, 141}, - dictWord{ - 5, - 11, - 915, - }, - dictWord{6, 11, 1783}, - dictWord{7, 11, 211}, - dictWord{7, 11, 698}, - dictWord{7, 11, 1353}, - dictWord{9, 11, 83}, - dictWord{9, 11, 281}, - dictWord{ - 10, - 11, - 376, - }, - dictWord{10, 11, 431}, - dictWord{11, 11, 543}, - dictWord{12, 11, 664}, - dictWord{13, 11, 280}, - dictWord{13, 11, 428}, - dictWord{14, 11, 61}, - dictWord{ - 14, - 11, - 128, - }, - dictWord{17, 11, 52}, - dictWord{145, 11, 81}, - dictWord{6, 0, 161}, - dictWord{7, 0, 372}, - dictWord{137, 0, 597}, - dictWord{132, 0, 349}, - dictWord{ - 10, - 11, - 702, - }, - dictWord{139, 11, 245}, - dictWord{134, 0, 524}, - dictWord{134, 10, 174}, - dictWord{6, 0, 432}, - dictWord{9, 0, 751}, - dictWord{139, 0, 322}, - dictWord{147, 11, 94}, - dictWord{4, 11, 338}, - dictWord{133, 11, 400}, - dictWord{5, 0, 468}, - dictWord{10, 0, 325}, - dictWord{11, 0, 856}, - dictWord{12, 0, 345}, - dictWord{143, 0, 104}, - dictWord{133, 0, 223}, - dictWord{132, 0, 566}, - dictWord{4, 11, 221}, - dictWord{5, 11, 659}, - dictWord{5, 11, 989}, - dictWord{7, 11, 697}, - dictWord{7, 11, 1211}, - dictWord{138, 11, 284}, - dictWord{135, 11, 1070}, - dictWord{4, 0, 59}, - dictWord{135, 0, 1394}, - dictWord{6, 0, 436}, - dictWord{11, 0, 481}, - dictWord{5, 10, 878}, - dictWord{133, 10, 972}, - dictWord{4, 0, 48}, - dictWord{5, 0, 271}, - dictWord{135, 0, 953}, - dictWord{5, 0, 610}, - dictWord{136, 0, 457}, - dictWord{ - 4, - 0, - 773, - }, - dictWord{5, 0, 618}, - dictWord{137, 0, 756}, - dictWord{133, 0, 755}, - dictWord{135, 0, 1217}, - dictWord{138, 11, 507}, - dictWord{132, 10, 351}, - dictWord{132, 0, 197}, - dictWord{143, 11, 78}, - dictWord{4, 11, 188}, - dictWord{7, 11, 805}, - dictWord{11, 11, 276}, - dictWord{142, 11, 293}, - dictWord{ - 5, - 11, - 884, - }, - dictWord{139, 11, 991}, - dictWord{132, 10, 286}, - dictWord{10, 0, 259}, - dictWord{10, 0, 428}, - dictWord{7, 10, 438}, - dictWord{7, 10, 627}, - dictWord{ - 7, - 10, - 1516, - }, - dictWord{8, 10, 40}, - dictWord{9, 10, 56}, - dictWord{9, 10, 294}, - dictWord{11, 10, 969}, - dictWord{11, 10, 995}, - dictWord{146, 10, 148}, - dictWord{ - 4, - 0, - 356, - }, - dictWord{5, 0, 217}, - dictWord{5, 0, 492}, - dictWord{5, 0, 656}, - dictWord{8, 0, 544}, - dictWord{136, 11, 544}, - dictWord{5, 0, 259}, - dictWord{6, 0, 1230}, - dictWord{7, 0, 414}, - dictWord{7, 0, 854}, - dictWord{142, 0, 107}, - dictWord{132, 0, 1007}, - dictWord{15, 0, 14}, - dictWord{144, 0, 5}, - dictWord{6, 0, 1580}, - dictWord{ - 132, - 10, - 738, - }, - dictWord{132, 11, 596}, - dictWord{132, 0, 673}, - dictWord{133, 10, 866}, - dictWord{6, 0, 1843}, - dictWord{135, 11, 1847}, - dictWord{4, 0, 165}, - dictWord{7, 0, 1398}, - dictWord{135, 0, 1829}, - dictWord{135, 11, 1634}, - dictWord{147, 11, 65}, - dictWord{6, 0, 885}, - dictWord{6, 0, 1009}, - dictWord{ - 137, - 0, - 809, - }, - dictWord{133, 10, 116}, - dictWord{132, 10, 457}, - dictWord{136, 11, 770}, - dictWord{9, 0, 498}, - dictWord{12, 0, 181}, - dictWord{10, 11, 361}, - dictWord{142, 11, 316}, - dictWord{134, 11, 595}, - dictWord{5, 0, 9}, - dictWord{7, 0, 297}, - dictWord{7, 0, 966}, - dictWord{140, 0, 306}, - dictWord{4, 11, 89}, - dictWord{ - 5, - 11, - 489, - }, - dictWord{6, 11, 315}, - dictWord{7, 11, 553}, - dictWord{7, 11, 1745}, - dictWord{138, 11, 243}, - dictWord{134, 0, 1487}, - dictWord{132, 0, 437}, - dictWord{ - 5, - 0, - 146, - }, - dictWord{6, 0, 411}, - dictWord{138, 0, 721}, - dictWord{5, 10, 527}, - dictWord{6, 10, 189}, - dictWord{135, 10, 859}, - dictWord{11, 10, 104}, - dictWord{ - 11, - 10, - 554, - }, - dictWord{15, 10, 60}, - dictWord{143, 10, 125}, - dictWord{6, 11, 1658}, - dictWord{9, 11, 3}, - dictWord{10, 11, 154}, - dictWord{11, 11, 641}, - dictWord{13, 11, 85}, - dictWord{13, 11, 201}, - dictWord{141, 11, 346}, - dictWord{6, 0, 177}, - dictWord{135, 0, 467}, - dictWord{134, 0, 1377}, - dictWord{ - 134, - 10, - 116, - }, - dictWord{136, 11, 645}, - dictWord{4, 11, 166}, - dictWord{5, 11, 505}, - dictWord{6, 11, 1670}, - dictWord{137, 11, 110}, - dictWord{133, 10, 487}, - dictWord{ - 4, - 10, - 86, - }, - dictWord{5, 10, 667}, - dictWord{5, 10, 753}, - dictWord{6, 10, 316}, - dictWord{6, 10, 455}, - dictWord{135, 10, 946}, - dictWord{133, 0, 200}, - dictWord{132, 0, 959}, - dictWord{6, 0, 1928}, - dictWord{134, 0, 1957}, - dictWord{139, 11, 203}, - dictWord{150, 10, 45}, - dictWord{4, 10, 79}, - dictWord{7, 10, 1773}, - dictWord{10, 10, 450}, - dictWord{11, 10, 589}, - dictWord{13, 10, 332}, - dictWord{13, 10, 493}, - dictWord{14, 10, 183}, - dictWord{14, 10, 334}, - dictWord{ - 14, - 10, - 362, - }, - dictWord{14, 10, 368}, - dictWord{14, 10, 376}, - dictWord{14, 10, 379}, - dictWord{19, 10, 90}, - dictWord{19, 10, 103}, - dictWord{19, 10, 127}, - dictWord{148, 10, 90}, - dictWord{6, 0, 1435}, - dictWord{135, 11, 1275}, - dictWord{134, 0, 481}, - dictWord{7, 11, 445}, - dictWord{8, 11, 307}, - dictWord{8, 11, 704}, - dictWord{10, 11, 41}, - dictWord{10, 11, 439}, - dictWord{11, 11, 237}, - dictWord{11, 11, 622}, - dictWord{140, 11, 201}, - dictWord{135, 11, 869}, - dictWord{ - 4, - 0, - 84, - }, - dictWord{7, 0, 1482}, - dictWord{10, 0, 76}, - dictWord{138, 0, 142}, - dictWord{11, 11, 277}, - dictWord{144, 11, 14}, - dictWord{135, 11, 1977}, - dictWord{ - 4, - 11, - 189, - }, - dictWord{5, 11, 713}, - dictWord{136, 11, 57}, - dictWord{133, 0, 1015}, - dictWord{138, 11, 371}, - dictWord{4, 0, 315}, - dictWord{5, 0, 507}, - dictWord{ - 135, - 0, - 1370, - }, - dictWord{4, 11, 552}, - dictWord{142, 10, 381}, - dictWord{9, 0, 759}, - dictWord{16, 0, 31}, - dictWord{16, 0, 39}, - dictWord{16, 0, 75}, - dictWord{18, 0, 24}, - dictWord{20, 0, 42}, - dictWord{152, 0, 1}, - dictWord{134, 0, 712}, - dictWord{134, 0, 1722}, - dictWord{133, 10, 663}, - dictWord{133, 10, 846}, - dictWord{ - 8, - 0, - 222, - }, - dictWord{8, 0, 476}, - dictWord{9, 0, 238}, - dictWord{11, 0, 516}, - dictWord{11, 0, 575}, - dictWord{15, 0, 109}, - dictWord{146, 0, 100}, - dictWord{7, 0, 1402}, - dictWord{7, 0, 1414}, - dictWord{12, 0, 456}, - dictWord{5, 10, 378}, - dictWord{8, 10, 465}, - dictWord{9, 10, 286}, - dictWord{10, 10, 185}, - dictWord{10, 10, 562}, - dictWord{10, 10, 635}, - dictWord{11, 10, 31}, - dictWord{11, 10, 393}, - dictWord{13, 10, 312}, - dictWord{18, 10, 65}, - dictWord{18, 10, 96}, - dictWord{147, 10, 89}, - dictWord{4, 0, 986}, - dictWord{6, 0, 1958}, - dictWord{6, 0, 2032}, - dictWord{8, 0, 934}, - dictWord{138, 0, 985}, - dictWord{7, 10, 1880}, - dictWord{9, 10, 680}, - dictWord{139, 10, 798}, - dictWord{134, 10, 1770}, - dictWord{145, 11, 49}, - dictWord{132, 11, 614}, - dictWord{132, 10, 648}, - dictWord{5, 10, 945}, - dictWord{ - 6, - 10, - 1656, - }, - dictWord{6, 10, 1787}, - dictWord{7, 10, 167}, - dictWord{8, 10, 824}, - dictWord{9, 10, 391}, - dictWord{10, 10, 375}, - dictWord{139, 10, 185}, - dictWord{138, 11, 661}, - dictWord{7, 0, 1273}, - dictWord{135, 11, 1945}, - dictWord{7, 0, 706}, - dictWord{7, 0, 1058}, - dictWord{138, 0, 538}, - dictWord{7, 10, 1645}, - dictWord{8, 10, 352}, - dictWord{137, 10, 249}, - dictWord{132, 10, 152}, - dictWord{11, 0, 92}, - dictWord{11, 0, 196}, - dictWord{11, 0, 409}, - dictWord{11, 0, 450}, - dictWord{11, 0, 666}, - dictWord{11, 0, 777}, - dictWord{12, 0, 262}, - dictWord{13, 0, 385}, - dictWord{13, 0, 393}, - dictWord{15, 0, 115}, - dictWord{16, 0, 45}, - dictWord{145, 0, 82}, - dictWord{133, 10, 1006}, - dictWord{6, 0, 40}, - dictWord{135, 0, 1781}, - dictWord{9, 11, 614}, - dictWord{139, 11, 327}, - dictWord{5, 10, 420}, - dictWord{135, 10, 1449}, - dictWord{135, 0, 431}, - dictWord{10, 0, 97}, - dictWord{135, 10, 832}, - dictWord{6, 0, 423}, - dictWord{7, 0, 665}, - dictWord{ - 135, - 0, - 1210, - }, - dictWord{7, 0, 237}, - dictWord{8, 0, 664}, - dictWord{9, 0, 42}, - dictWord{9, 0, 266}, - dictWord{9, 0, 380}, - dictWord{9, 0, 645}, - dictWord{10, 0, 177}, - dictWord{ - 138, - 0, - 276, - }, - dictWord{7, 0, 264}, - dictWord{133, 10, 351}, - dictWord{8, 0, 213}, - dictWord{5, 10, 40}, - dictWord{7, 10, 598}, - dictWord{7, 10, 1638}, - dictWord{ - 9, - 10, - 166, - }, - dictWord{9, 10, 640}, - dictWord{9, 10, 685}, - dictWord{9, 10, 773}, - dictWord{11, 10, 215}, - dictWord{13, 10, 65}, - dictWord{14, 10, 172}, - dictWord{ - 14, - 10, - 317, - }, - dictWord{145, 10, 6}, - dictWord{5, 11, 84}, - dictWord{134, 11, 163}, - dictWord{8, 10, 60}, - dictWord{9, 10, 343}, - dictWord{139, 10, 769}, - dictWord{ - 137, - 0, - 455, - }, - dictWord{133, 11, 410}, - dictWord{8, 0, 906}, - dictWord{12, 0, 700}, - dictWord{12, 0, 706}, - dictWord{140, 0, 729}, - dictWord{21, 11, 33}, - dictWord{ - 150, - 11, - 40, - }, - dictWord{7, 10, 1951}, - dictWord{8, 10, 765}, - dictWord{8, 10, 772}, - dictWord{140, 10, 671}, - dictWord{7, 10, 108}, - dictWord{8, 10, 219}, - dictWord{ - 8, - 10, - 388, - }, - dictWord{9, 10, 639}, - dictWord{9, 10, 775}, - dictWord{11, 10, 275}, - dictWord{140, 10, 464}, - dictWord{5, 11, 322}, - dictWord{7, 11, 1941}, - dictWord{ - 8, - 11, - 186, - }, - dictWord{9, 11, 262}, - dictWord{10, 11, 187}, - dictWord{14, 11, 208}, - dictWord{146, 11, 130}, - dictWord{139, 0, 624}, - dictWord{8, 0, 574}, - dictWord{ - 5, - 11, - 227, - }, - dictWord{140, 11, 29}, - dictWord{7, 11, 1546}, - dictWord{11, 11, 299}, - dictWord{142, 11, 407}, - dictWord{5, 10, 15}, - dictWord{6, 10, 56}, - dictWord{ - 7, - 10, - 1758, - }, - dictWord{8, 10, 500}, - dictWord{9, 10, 730}, - dictWord{11, 10, 331}, - dictWord{13, 10, 150}, - dictWord{142, 10, 282}, - dictWord{7, 11, 1395}, - dictWord{8, 11, 486}, - dictWord{9, 11, 236}, - dictWord{9, 11, 878}, - dictWord{10, 11, 218}, - dictWord{11, 11, 95}, - dictWord{19, 11, 17}, - dictWord{147, 11, 31}, - dictWord{135, 11, 2043}, - dictWord{4, 0, 354}, - dictWord{146, 11, 4}, - dictWord{140, 11, 80}, - dictWord{135, 0, 1558}, - dictWord{134, 10, 1886}, - dictWord{ - 5, - 10, - 205, - }, - dictWord{6, 10, 438}, - dictWord{137, 10, 711}, - dictWord{133, 11, 522}, - dictWord{133, 10, 534}, - dictWord{7, 0, 235}, - dictWord{7, 0, 1475}, - dictWord{ - 15, - 0, - 68, - }, - dictWord{146, 0, 120}, - dictWord{137, 10, 691}, - dictWord{4, 0, 942}, - dictWord{6, 0, 1813}, - dictWord{8, 0, 917}, - dictWord{10, 0, 884}, - dictWord{ - 12, - 0, - 696, - }, - dictWord{12, 0, 717}, - dictWord{12, 0, 723}, - dictWord{12, 0, 738}, - dictWord{12, 0, 749}, - dictWord{12, 0, 780}, - dictWord{16, 0, 97}, - dictWord{146, 0, 169}, - dictWord{6, 10, 443}, - dictWord{8, 11, 562}, - dictWord{9, 10, 237}, - dictWord{9, 10, 571}, - dictWord{9, 10, 695}, - dictWord{10, 10, 139}, - dictWord{11, 10, 715}, - dictWord{12, 10, 417}, - dictWord{141, 10, 421}, - dictWord{135, 0, 957}, - dictWord{133, 0, 830}, - dictWord{134, 11, 1771}, - dictWord{146, 0, 23}, - dictWord{ - 5, - 0, - 496, - }, - dictWord{6, 0, 694}, - dictWord{7, 0, 203}, - dictWord{7, 11, 1190}, - dictWord{137, 11, 620}, - dictWord{137, 11, 132}, - dictWord{6, 0, 547}, - dictWord{ - 134, - 0, - 1549, - }, - dictWord{8, 11, 258}, - dictWord{9, 11, 208}, - dictWord{137, 11, 359}, - dictWord{4, 0, 864}, - dictWord{5, 0, 88}, - dictWord{137, 0, 239}, - dictWord{ - 135, - 11, - 493, - }, - dictWord{4, 11, 317}, - dictWord{135, 11, 1279}, - dictWord{132, 11, 477}, - dictWord{4, 10, 578}, - dictWord{5, 11, 63}, - dictWord{133, 11, 509}, - dictWord{ - 7, - 0, - 650, - }, - dictWord{135, 0, 1310}, - dictWord{7, 0, 1076}, - dictWord{9, 0, 80}, - dictWord{11, 0, 78}, - dictWord{11, 0, 421}, - dictWord{11, 0, 534}, - dictWord{ - 140, - 0, - 545, - }, - dictWord{132, 11, 288}, - dictWord{12, 0, 553}, - dictWord{14, 0, 118}, - dictWord{133, 10, 923}, - dictWord{7, 0, 274}, - dictWord{11, 0, 479}, - dictWord{ - 139, - 0, - 507, - }, - dictWord{8, 11, 89}, - dictWord{8, 11, 620}, - dictWord{9, 11, 49}, - dictWord{10, 11, 774}, - dictWord{11, 11, 628}, - dictWord{12, 11, 322}, - dictWord{ - 143, - 11, - 124, - }, - dictWord{4, 0, 497}, - dictWord{135, 0, 1584}, - dictWord{7, 0, 261}, - dictWord{7, 0, 1115}, - dictWord{7, 0, 1354}, - dictWord{7, 0, 1404}, - dictWord{ - 7, - 0, - 1588, - }, - dictWord{7, 0, 1705}, - dictWord{7, 0, 1902}, - dictWord{9, 0, 465}, - dictWord{10, 0, 248}, - dictWord{10, 0, 349}, - dictWord{10, 0, 647}, - dictWord{11, 0, 527}, - dictWord{11, 0, 660}, - dictWord{11, 0, 669}, - dictWord{12, 0, 529}, - dictWord{13, 0, 305}, - dictWord{132, 10, 924}, - dictWord{133, 10, 665}, - dictWord{ - 136, - 0, - 13, - }, - dictWord{6, 0, 791}, - dictWord{138, 11, 120}, - dictWord{7, 0, 642}, - dictWord{8, 0, 250}, - dictWord{11, 0, 123}, - dictWord{11, 0, 137}, - dictWord{13, 0, 48}, - dictWord{142, 0, 95}, - dictWord{4, 10, 265}, - dictWord{7, 10, 807}, - dictWord{135, 10, 950}, - dictWord{5, 10, 93}, - dictWord{140, 10, 267}, - dictWord{135, 0, 1429}, - dictWord{4, 0, 949}, - dictWord{10, 0, 885}, - dictWord{10, 0, 891}, - dictWord{10, 0, 900}, - dictWord{10, 0, 939}, - dictWord{12, 0, 760}, - dictWord{142, 0, 449}, - dictWord{139, 11, 366}, - dictWord{132, 0, 818}, - dictWord{134, 11, 85}, - dictWord{135, 10, 994}, - dictWord{7, 0, 330}, - dictWord{5, 10, 233}, - dictWord{5, 10, 320}, - dictWord{6, 10, 140}, - dictWord{136, 10, 295}, - dictWord{4, 0, 1004}, - dictWord{8, 0, 982}, - dictWord{136, 0, 993}, - dictWord{133, 10, 978}, - dictWord{4, 10, 905}, - dictWord{6, 10, 1701}, - dictWord{137, 10, 843}, - dictWord{10, 0, 545}, - dictWord{140, 0, 301}, - dictWord{6, 0, 947}, - dictWord{134, 0, 1062}, - dictWord{ - 134, - 0, - 1188, - }, - dictWord{4, 0, 904}, - dictWord{5, 0, 794}, - dictWord{152, 10, 6}, - dictWord{134, 0, 1372}, - dictWord{135, 11, 608}, - dictWord{5, 11, 279}, - dictWord{ - 6, - 11, - 235, - }, - dictWord{7, 11, 468}, - dictWord{8, 11, 446}, - dictWord{9, 11, 637}, - dictWord{10, 11, 717}, - dictWord{11, 11, 738}, - dictWord{140, 11, 514}, - dictWord{ - 132, - 10, - 509, - }, - dictWord{5, 11, 17}, - dictWord{6, 11, 371}, - dictWord{137, 11, 528}, - dictWord{132, 0, 693}, - dictWord{4, 11, 115}, - dictWord{5, 11, 669}, - dictWord{ - 6, - 11, - 407, - }, - dictWord{8, 11, 311}, - dictWord{11, 11, 10}, - dictWord{141, 11, 5}, - dictWord{11, 0, 377}, - dictWord{7, 10, 273}, - dictWord{137, 11, 381}, - dictWord{ - 135, - 0, - 695, - }, - dictWord{7, 0, 386}, - dictWord{138, 0, 713}, - dictWord{135, 10, 1041}, - dictWord{134, 0, 1291}, - dictWord{6, 0, 7}, - dictWord{6, 0, 35}, - dictWord{ - 7, - 0, - 147, - }, - dictWord{7, 0, 1069}, - dictWord{7, 0, 1568}, - dictWord{7, 0, 1575}, - dictWord{7, 0, 1917}, - dictWord{8, 0, 43}, - dictWord{8, 0, 208}, - dictWord{9, 0, 128}, - dictWord{ - 9, - 0, - 866, - }, - dictWord{10, 0, 20}, - dictWord{11, 0, 981}, - dictWord{147, 0, 33}, - dictWord{7, 0, 893}, - dictWord{141, 0, 424}, - dictWord{139, 10, 234}, - dictWord{ - 150, - 11, - 56, - }, - dictWord{5, 11, 779}, - dictWord{5, 11, 807}, - dictWord{6, 11, 1655}, - dictWord{134, 11, 1676}, - dictWord{5, 10, 802}, - dictWord{7, 10, 2021}, - dictWord{136, 10, 805}, - dictWord{4, 11, 196}, - dictWord{5, 10, 167}, - dictWord{5, 11, 558}, - dictWord{5, 10, 899}, - dictWord{5, 11, 949}, - dictWord{6, 10, 410}, - dictWord{137, 10, 777}, - dictWord{137, 10, 789}, - dictWord{134, 10, 1705}, - dictWord{8, 0, 904}, - dictWord{140, 0, 787}, - dictWord{6, 0, 322}, - dictWord{9, 0, 552}, - dictWord{11, 0, 274}, - dictWord{13, 0, 209}, - dictWord{13, 0, 499}, - dictWord{14, 0, 85}, - dictWord{15, 0, 126}, - dictWord{145, 0, 70}, - dictWord{135, 10, 10}, - dictWord{ - 5, - 10, - 11, - }, - dictWord{6, 10, 117}, - dictWord{6, 10, 485}, - dictWord{7, 10, 1133}, - dictWord{9, 10, 582}, - dictWord{9, 10, 594}, - dictWord{11, 10, 21}, - dictWord{ - 11, - 10, - 818, - }, - dictWord{12, 10, 535}, - dictWord{141, 10, 86}, - dictWord{4, 10, 264}, - dictWord{7, 10, 1067}, - dictWord{8, 10, 204}, - dictWord{8, 10, 385}, - dictWord{139, 10, 953}, - dictWord{132, 11, 752}, - dictWord{138, 10, 56}, - dictWord{133, 10, 470}, - dictWord{6, 0, 1808}, - dictWord{8, 0, 83}, - dictWord{8, 0, 742}, - dictWord{8, 0, 817}, - dictWord{9, 0, 28}, - dictWord{9, 0, 29}, - dictWord{9, 0, 885}, - dictWord{10, 0, 387}, - dictWord{11, 0, 633}, - dictWord{11, 0, 740}, - dictWord{13, 0, 235}, - dictWord{13, 0, 254}, - dictWord{15, 0, 143}, - dictWord{143, 0, 146}, - dictWord{140, 0, 49}, - dictWord{134, 0, 1832}, - dictWord{4, 11, 227}, - dictWord{5, 11, 159}, - dictWord{5, 11, 409}, - dictWord{7, 11, 80}, - dictWord{10, 11, 294}, - dictWord{10, 11, 479}, - dictWord{12, 11, 418}, - dictWord{14, 11, 50}, - dictWord{14, 11, 249}, - dictWord{142, 11, 295}, - dictWord{7, 11, 1470}, - dictWord{8, 11, 66}, - dictWord{8, 11, 137}, - dictWord{8, 11, 761}, - dictWord{9, 11, 638}, - dictWord{11, 11, 80}, - dictWord{11, 11, 212}, - dictWord{11, 11, 368}, - dictWord{11, 11, 418}, - dictWord{12, 11, 8}, - dictWord{13, 11, 15}, - dictWord{16, 11, 61}, - dictWord{17, 11, 59}, - dictWord{19, 11, 28}, - dictWord{148, 11, 84}, - dictWord{139, 10, 1015}, - dictWord{138, 11, 468}, - dictWord{135, 0, 421}, - dictWord{6, 0, 415}, - dictWord{ - 7, - 0, - 1049, - }, - dictWord{137, 0, 442}, - dictWord{6, 11, 38}, - dictWord{7, 11, 1220}, - dictWord{8, 11, 185}, - dictWord{8, 11, 256}, - dictWord{9, 11, 22}, - dictWord{ - 9, - 11, - 331, - }, - dictWord{10, 11, 738}, - dictWord{11, 11, 205}, - dictWord{11, 11, 540}, - dictWord{11, 11, 746}, - dictWord{13, 11, 399}, - dictWord{13, 11, 465}, - dictWord{ - 14, - 11, - 88, - }, - dictWord{142, 11, 194}, - dictWord{139, 0, 289}, - dictWord{133, 10, 715}, - dictWord{4, 0, 110}, - dictWord{10, 0, 415}, - dictWord{10, 0, 597}, - dictWord{142, 0, 206}, - dictWord{4, 11, 159}, - dictWord{6, 11, 115}, - dictWord{7, 11, 252}, - dictWord{7, 11, 257}, - dictWord{7, 11, 1928}, - dictWord{8, 11, 69}, - dictWord{ - 9, - 11, - 384, - }, - dictWord{10, 11, 91}, - dictWord{10, 11, 615}, - dictWord{12, 11, 375}, - dictWord{14, 11, 235}, - dictWord{18, 11, 117}, - dictWord{147, 11, 123}, - dictWord{5, 11, 911}, - dictWord{136, 11, 278}, - dictWord{7, 0, 205}, - dictWord{7, 0, 2000}, - dictWord{8, 10, 794}, - dictWord{9, 10, 400}, - dictWord{10, 10, 298}, - dictWord{142, 10, 228}, - dictWord{135, 11, 1774}, - dictWord{4, 11, 151}, - dictWord{7, 11, 1567}, - dictWord{8, 11, 351}, - dictWord{137, 11, 322}, - dictWord{ - 136, - 10, - 724, - }, - dictWord{133, 11, 990}, - dictWord{7, 0, 1539}, - dictWord{11, 0, 512}, - dictWord{13, 0, 205}, - dictWord{19, 0, 30}, - dictWord{22, 0, 36}, - dictWord{23, 0, 19}, - dictWord{135, 11, 1539}, - dictWord{5, 11, 194}, - dictWord{7, 11, 1662}, - dictWord{9, 11, 90}, - dictWord{140, 11, 180}, - dictWord{6, 10, 190}, - dictWord{ - 7, - 10, - 768, - }, - dictWord{135, 10, 1170}, - dictWord{134, 0, 1340}, - dictWord{4, 0, 283}, - dictWord{135, 0, 1194}, - dictWord{133, 11, 425}, - dictWord{133, 11, 971}, - dictWord{12, 0, 549}, - dictWord{14, 10, 67}, - dictWord{147, 10, 60}, - dictWord{135, 10, 1023}, - dictWord{134, 0, 1720}, - dictWord{138, 11, 587}, - dictWord{ - 5, - 11, - 72, - }, - dictWord{6, 11, 264}, - dictWord{7, 11, 21}, - dictWord{7, 11, 46}, - dictWord{7, 11, 2013}, - dictWord{8, 11, 215}, - dictWord{8, 11, 513}, - dictWord{10, 11, 266}, - dictWord{139, 11, 22}, - dictWord{5, 0, 319}, - dictWord{135, 0, 534}, - dictWord{6, 10, 137}, - dictWord{9, 10, 75}, - dictWord{9, 10, 253}, - dictWord{10, 10, 194}, - dictWord{138, 10, 444}, - dictWord{7, 0, 1180}, - dictWord{20, 0, 112}, - dictWord{6, 11, 239}, - dictWord{7, 11, 118}, - dictWord{10, 11, 95}, - dictWord{11, 11, 603}, - dictWord{13, 11, 443}, - dictWord{14, 11, 160}, - dictWord{143, 11, 4}, - dictWord{134, 11, 431}, - dictWord{5, 11, 874}, - dictWord{6, 11, 1677}, - dictWord{ - 11, - 10, - 643, - }, - dictWord{12, 10, 115}, - dictWord{143, 11, 0}, - dictWord{134, 0, 967}, - dictWord{6, 11, 65}, - dictWord{7, 11, 939}, - dictWord{7, 11, 1172}, - dictWord{ - 7, - 11, - 1671, - }, - dictWord{9, 11, 540}, - dictWord{10, 11, 696}, - dictWord{11, 11, 265}, - dictWord{11, 11, 732}, - dictWord{11, 11, 928}, - dictWord{11, 11, 937}, - dictWord{ - 12, - 11, - 399, - }, - dictWord{13, 11, 438}, - dictWord{149, 11, 19}, - dictWord{137, 11, 200}, - dictWord{135, 0, 1940}, - dictWord{5, 10, 760}, - dictWord{7, 10, 542}, - dictWord{8, 10, 135}, - dictWord{136, 10, 496}, - dictWord{140, 11, 44}, - dictWord{7, 11, 1655}, - dictWord{136, 11, 305}, - dictWord{7, 10, 319}, - dictWord{ - 7, - 10, - 355, - }, - dictWord{7, 10, 763}, - dictWord{10, 10, 389}, - dictWord{145, 10, 43}, - dictWord{136, 0, 735}, - dictWord{138, 10, 786}, - dictWord{137, 11, 19}, - dictWord{132, 11, 696}, - dictWord{5, 0, 132}, - dictWord{9, 0, 486}, - dictWord{9, 0, 715}, - dictWord{10, 0, 458}, - dictWord{11, 0, 373}, - dictWord{11, 0, 668}, - dictWord{ - 11, - 0, - 795, - }, - dictWord{11, 0, 897}, - dictWord{12, 0, 272}, - dictWord{12, 0, 424}, - dictWord{12, 0, 539}, - dictWord{12, 0, 558}, - dictWord{14, 0, 245}, - dictWord{ - 14, - 0, - 263, - }, - dictWord{14, 0, 264}, - dictWord{14, 0, 393}, - dictWord{142, 0, 403}, - dictWord{10, 0, 38}, - dictWord{139, 0, 784}, - dictWord{132, 0, 838}, - dictWord{ - 4, - 11, - 302, - }, - dictWord{135, 11, 1766}, - dictWord{133, 0, 379}, - dictWord{5, 0, 8}, - dictWord{6, 0, 89}, - dictWord{6, 0, 400}, - dictWord{7, 0, 1569}, - dictWord{7, 0, 1623}, - dictWord{7, 0, 1850}, - dictWord{8, 0, 218}, - dictWord{8, 0, 422}, - dictWord{9, 0, 570}, - dictWord{10, 0, 626}, - dictWord{4, 11, 726}, - dictWord{133, 11, 630}, - dictWord{ - 4, - 0, - 1017, - }, - dictWord{138, 0, 660}, - dictWord{6, 0, 387}, - dictWord{7, 0, 882}, - dictWord{141, 0, 111}, - dictWord{6, 0, 224}, - dictWord{7, 0, 877}, - dictWord{ - 137, - 0, - 647, - }, - dictWord{4, 10, 58}, - dictWord{5, 10, 286}, - dictWord{6, 10, 319}, - dictWord{7, 10, 402}, - dictWord{7, 10, 1254}, - dictWord{7, 10, 1903}, - dictWord{ - 8, - 10, - 356, - }, - dictWord{140, 10, 408}, - dictWord{135, 0, 790}, - dictWord{9, 0, 510}, - dictWord{10, 0, 53}, - dictWord{4, 10, 389}, - dictWord{9, 10, 181}, - dictWord{ - 10, - 10, - 29, - }, - dictWord{10, 10, 816}, - dictWord{11, 10, 311}, - dictWord{11, 10, 561}, - dictWord{12, 10, 67}, - dictWord{141, 10, 181}, - dictWord{142, 0, 458}, - dictWord{ - 6, - 11, - 118, - }, - dictWord{7, 11, 215}, - dictWord{7, 11, 1521}, - dictWord{140, 11, 11}, - dictWord{134, 0, 954}, - dictWord{135, 0, 394}, - dictWord{134, 0, 1367}, - dictWord{5, 11, 225}, - dictWord{133, 10, 373}, - dictWord{132, 0, 882}, - dictWord{7, 0, 1409}, - dictWord{135, 10, 1972}, - dictWord{135, 10, 1793}, - dictWord{ - 4, - 11, - 370, - }, - dictWord{5, 11, 756}, - dictWord{135, 11, 1326}, - dictWord{150, 11, 13}, - dictWord{7, 11, 354}, - dictWord{10, 11, 410}, - dictWord{139, 11, 815}, - dictWord{6, 11, 1662}, - dictWord{7, 11, 48}, - dictWord{8, 11, 771}, - dictWord{10, 11, 116}, - dictWord{13, 11, 104}, - dictWord{14, 11, 105}, - dictWord{14, 11, 184}, - dictWord{15, 11, 168}, - dictWord{19, 11, 92}, - dictWord{148, 11, 68}, - dictWord{7, 0, 124}, - dictWord{136, 0, 38}, - dictWord{5, 0, 261}, - dictWord{7, 0, 78}, - dictWord{ - 7, - 0, - 199, - }, - dictWord{8, 0, 815}, - dictWord{9, 0, 126}, - dictWord{10, 0, 342}, - dictWord{140, 0, 647}, - dictWord{4, 0, 628}, - dictWord{140, 0, 724}, - dictWord{7, 0, 266}, - dictWord{8, 0, 804}, - dictWord{7, 10, 1651}, - dictWord{145, 10, 89}, - dictWord{135, 0, 208}, - dictWord{134, 0, 1178}, - dictWord{6, 0, 79}, - dictWord{135, 0, 1519}, - dictWord{132, 10, 672}, - dictWord{133, 10, 737}, - dictWord{136, 0, 741}, - dictWord{132, 11, 120}, - dictWord{4, 0, 710}, - dictWord{6, 0, 376}, - dictWord{ - 134, - 0, - 606, - }, - dictWord{134, 0, 1347}, - dictWord{134, 0, 1494}, - dictWord{6, 0, 850}, - dictWord{6, 0, 1553}, - dictWord{137, 0, 821}, - dictWord{5, 10, 145}, - dictWord{ - 134, - 11, - 593, - }, - dictWord{7, 0, 1311}, - dictWord{140, 0, 135}, - dictWord{4, 0, 467}, - dictWord{5, 0, 405}, - dictWord{134, 0, 544}, - dictWord{5, 11, 820}, - dictWord{ - 135, - 11, - 931, - }, - dictWord{6, 0, 100}, - dictWord{7, 0, 244}, - dictWord{7, 0, 632}, - dictWord{7, 0, 1609}, - dictWord{8, 0, 178}, - dictWord{8, 0, 638}, - dictWord{141, 0, 58}, - dictWord{4, 10, 387}, - dictWord{135, 10, 1288}, - dictWord{6, 11, 151}, - dictWord{6, 11, 1675}, - dictWord{7, 11, 383}, - dictWord{151, 11, 10}, - dictWord{ - 132, - 0, - 481, - }, - dictWord{135, 10, 550}, - dictWord{134, 0, 1378}, - dictWord{6, 11, 1624}, - dictWord{11, 11, 11}, - dictWord{12, 11, 422}, - dictWord{13, 11, 262}, - dictWord{142, 11, 360}, - dictWord{133, 0, 791}, - dictWord{4, 11, 43}, - dictWord{5, 11, 344}, - dictWord{133, 11, 357}, - dictWord{7, 0, 1227}, - dictWord{140, 0, 978}, - dictWord{7, 0, 686}, - dictWord{8, 0, 33}, - dictWord{8, 0, 238}, - dictWord{10, 0, 616}, - dictWord{11, 0, 467}, - dictWord{11, 0, 881}, - dictWord{13, 0, 217}, - dictWord{ - 13, - 0, - 253, - }, - dictWord{142, 0, 268}, - dictWord{137, 0, 857}, - dictWord{8, 0, 467}, - dictWord{8, 0, 1006}, - dictWord{7, 11, 148}, - dictWord{8, 11, 284}, - dictWord{ - 141, - 11, - 63, - }, - dictWord{4, 10, 576}, - dictWord{135, 10, 1263}, - dictWord{133, 11, 888}, - dictWord{5, 10, 919}, - dictWord{134, 10, 1673}, - dictWord{20, 10, 37}, - dictWord{148, 11, 37}, - dictWord{132, 0, 447}, - dictWord{132, 11, 711}, - dictWord{4, 0, 128}, - dictWord{5, 0, 415}, - dictWord{6, 0, 462}, - dictWord{7, 0, 294}, - dictWord{ - 7, - 0, - 578, - }, - dictWord{10, 0, 710}, - dictWord{139, 0, 86}, - dictWord{4, 10, 82}, - dictWord{5, 10, 333}, - dictWord{5, 10, 904}, - dictWord{6, 10, 207}, - dictWord{7, 10, 325}, - dictWord{7, 10, 1726}, - dictWord{8, 10, 101}, - dictWord{10, 10, 778}, - dictWord{139, 10, 220}, - dictWord{136, 0, 587}, - dictWord{137, 11, 440}, - dictWord{ - 133, - 10, - 903, - }, - dictWord{6, 0, 427}, - dictWord{7, 0, 1018}, - dictWord{138, 0, 692}, - dictWord{4, 0, 195}, - dictWord{135, 0, 802}, - dictWord{140, 10, 147}, - dictWord{ - 134, - 0, - 1546, - }, - dictWord{134, 0, 684}, - dictWord{132, 10, 705}, - dictWord{136, 0, 345}, - dictWord{11, 11, 678}, - dictWord{140, 11, 307}, - dictWord{ - 133, - 0, - 365, - }, - dictWord{134, 0, 1683}, - dictWord{4, 11, 65}, - dictWord{5, 11, 479}, - dictWord{5, 11, 1004}, - dictWord{7, 11, 1913}, - dictWord{8, 11, 317}, - dictWord{ - 9, - 11, - 302, - }, - dictWord{10, 11, 612}, - dictWord{141, 11, 22}, - dictWord{138, 0, 472}, - dictWord{4, 11, 261}, - dictWord{135, 11, 510}, - dictWord{134, 10, 90}, - dictWord{142, 0, 433}, - dictWord{151, 0, 28}, - dictWord{4, 11, 291}, - dictWord{7, 11, 101}, - dictWord{9, 11, 515}, - dictWord{12, 11, 152}, - dictWord{12, 11, 443}, - dictWord{13, 11, 392}, - dictWord{142, 11, 357}, - dictWord{140, 0, 997}, - dictWord{5, 0, 3}, - dictWord{8, 0, 578}, - dictWord{9, 0, 118}, - dictWord{10, 0, 705}, - dictWord{ - 141, - 0, - 279, - }, - dictWord{135, 11, 1266}, - dictWord{7, 10, 813}, - dictWord{12, 10, 497}, - dictWord{141, 10, 56}, - dictWord{133, 0, 229}, - dictWord{6, 10, 125}, - dictWord{135, 10, 1277}, - dictWord{8, 0, 102}, - dictWord{10, 0, 578}, - dictWord{10, 0, 672}, - dictWord{12, 0, 496}, - dictWord{13, 0, 408}, - dictWord{14, 0, 121}, - dictWord{17, 0, 106}, - dictWord{151, 10, 12}, - dictWord{6, 0, 866}, - dictWord{134, 0, 1080}, - dictWord{136, 0, 1022}, - dictWord{4, 11, 130}, - dictWord{135, 11, 843}, - dictWord{5, 11, 42}, - dictWord{5, 11, 879}, - dictWord{7, 11, 245}, - dictWord{7, 11, 324}, - dictWord{7, 11, 1532}, - dictWord{11, 11, 463}, - dictWord{11, 11, 472}, - dictWord{13, 11, 363}, - dictWord{144, 11, 52}, - dictWord{150, 0, 55}, - dictWord{8, 0, 115}, - dictWord{8, 0, 350}, - dictWord{9, 0, 489}, - dictWord{10, 0, 128}, - dictWord{ - 11, - 0, - 306, - }, - dictWord{12, 0, 373}, - dictWord{14, 0, 30}, - dictWord{17, 0, 79}, - dictWord{19, 0, 80}, - dictWord{4, 11, 134}, - dictWord{133, 11, 372}, - dictWord{ - 134, - 0, - 657, - }, - dictWord{134, 0, 933}, - dictWord{135, 11, 1147}, - dictWord{4, 0, 230}, - dictWord{133, 0, 702}, - dictWord{134, 0, 1728}, - dictWord{4, 0, 484}, - dictWord{ - 18, - 0, - 26, - }, - dictWord{19, 0, 42}, - dictWord{20, 0, 43}, - dictWord{21, 0, 0}, - dictWord{23, 0, 27}, - dictWord{152, 0, 14}, - dictWord{7, 0, 185}, - dictWord{135, 0, 703}, - dictWord{ - 6, - 0, - 417, - }, - dictWord{10, 0, 618}, - dictWord{7, 10, 1106}, - dictWord{9, 10, 770}, - dictWord{11, 10, 112}, - dictWord{140, 10, 413}, - dictWord{134, 0, 803}, - dictWord{132, 11, 644}, - dictWord{134, 0, 1262}, - dictWord{7, 11, 540}, - dictWord{12, 10, 271}, - dictWord{145, 10, 109}, - dictWord{135, 11, 123}, - dictWord{ - 132, - 0, - 633, - }, - dictWord{134, 11, 623}, - dictWord{4, 11, 908}, - dictWord{5, 11, 359}, - dictWord{5, 11, 508}, - dictWord{6, 11, 1723}, - dictWord{7, 11, 343}, - dictWord{ - 7, - 11, - 1996, - }, - dictWord{135, 11, 2026}, - dictWord{135, 0, 479}, - dictWord{10, 0, 262}, - dictWord{7, 10, 304}, - dictWord{9, 10, 646}, - dictWord{9, 10, 862}, - dictWord{ - 11, - 10, - 696, - }, - dictWord{12, 10, 208}, - dictWord{15, 10, 79}, - dictWord{147, 10, 108}, - dictWord{4, 11, 341}, - dictWord{135, 11, 480}, - dictWord{134, 0, 830}, - dictWord{5, 0, 70}, - dictWord{5, 0, 622}, - dictWord{6, 0, 334}, - dictWord{7, 0, 1032}, - dictWord{9, 0, 171}, - dictWord{11, 0, 26}, - dictWord{11, 0, 213}, - dictWord{ - 11, - 0, - 637, - }, - dictWord{11, 0, 707}, - dictWord{12, 0, 202}, - dictWord{12, 0, 380}, - dictWord{13, 0, 226}, - dictWord{13, 0, 355}, - dictWord{14, 0, 222}, - dictWord{145, 0, 42}, - dictWord{135, 10, 981}, - dictWord{143, 0, 217}, - dictWord{137, 11, 114}, - dictWord{4, 0, 23}, - dictWord{4, 0, 141}, - dictWord{5, 0, 313}, - dictWord{5, 0, 1014}, - dictWord{6, 0, 50}, - dictWord{6, 0, 51}, - dictWord{7, 0, 142}, - dictWord{7, 0, 384}, - dictWord{7, 0, 559}, - dictWord{8, 0, 640}, - dictWord{9, 0, 460}, - dictWord{9, 0, 783}, - dictWord{11, 0, 741}, - dictWord{12, 0, 183}, - dictWord{141, 0, 488}, - dictWord{141, 0, 360}, - dictWord{7, 0, 1586}, - dictWord{7, 11, 1995}, - dictWord{8, 11, 299}, - dictWord{11, 11, 890}, - dictWord{140, 11, 674}, - dictWord{132, 10, 434}, - dictWord{7, 0, 652}, - dictWord{134, 10, 550}, - dictWord{7, 0, 766}, - dictWord{5, 10, 553}, - dictWord{138, 10, 824}, - dictWord{7, 0, 737}, - dictWord{8, 0, 298}, - dictWord{136, 10, 452}, - dictWord{4, 11, 238}, - dictWord{5, 11, 503}, - dictWord{6, 11, 179}, - dictWord{7, 11, 2003}, - dictWord{8, 11, 381}, - dictWord{8, 11, 473}, - dictWord{9, 11, 149}, - dictWord{10, 11, 183}, - dictWord{15, 11, 45}, - dictWord{143, 11, 86}, - dictWord{133, 10, 292}, - dictWord{5, 0, 222}, - dictWord{9, 0, 655}, - dictWord{138, 0, 534}, - dictWord{138, 10, 135}, - dictWord{4, 11, 121}, - dictWord{5, 11, 156}, - dictWord{5, 11, 349}, - dictWord{9, 11, 136}, - dictWord{10, 11, 605}, - dictWord{14, 11, 342}, - dictWord{147, 11, 107}, - dictWord{137, 0, 906}, - dictWord{6, 0, 1013}, - dictWord{134, 0, 1250}, - dictWord{6, 0, 1956}, - dictWord{6, 0, 2009}, - dictWord{8, 0, 991}, - dictWord{144, 0, 120}, - dictWord{135, 11, 1192}, - dictWord{ - 138, - 0, - 503, - }, - dictWord{5, 0, 154}, - dictWord{7, 0, 1491}, - dictWord{10, 0, 379}, - dictWord{138, 0, 485}, - dictWord{6, 0, 1867}, - dictWord{6, 0, 1914}, - dictWord{6, 0, 1925}, - dictWord{9, 0, 917}, - dictWord{9, 0, 925}, - dictWord{9, 0, 932}, - dictWord{9, 0, 951}, - dictWord{9, 0, 1007}, - dictWord{9, 0, 1013}, - dictWord{12, 0, 806}, - dictWord{ - 12, - 0, - 810, - }, - dictWord{12, 0, 814}, - dictWord{12, 0, 816}, - dictWord{12, 0, 824}, - dictWord{12, 0, 832}, - dictWord{12, 0, 837}, - dictWord{12, 0, 863}, - dictWord{ - 12, - 0, - 868, - }, - dictWord{12, 0, 870}, - dictWord{12, 0, 889}, - dictWord{12, 0, 892}, - dictWord{12, 0, 900}, - dictWord{12, 0, 902}, - dictWord{12, 0, 908}, - dictWord{12, 0, 933}, - dictWord{12, 0, 942}, - dictWord{12, 0, 949}, - dictWord{12, 0, 954}, - dictWord{15, 0, 175}, - dictWord{15, 0, 203}, - dictWord{15, 0, 213}, - dictWord{15, 0, 218}, - dictWord{15, 0, 225}, - dictWord{15, 0, 231}, - dictWord{15, 0, 239}, - dictWord{15, 0, 248}, - dictWord{15, 0, 252}, - dictWord{18, 0, 190}, - dictWord{18, 0, 204}, - dictWord{ - 18, - 0, - 215, - }, - dictWord{18, 0, 216}, - dictWord{18, 0, 222}, - dictWord{18, 0, 225}, - dictWord{18, 0, 230}, - dictWord{18, 0, 239}, - dictWord{18, 0, 241}, - dictWord{ - 21, - 0, - 42, - }, - dictWord{21, 0, 43}, - dictWord{21, 0, 44}, - dictWord{21, 0, 45}, - dictWord{21, 0, 46}, - dictWord{21, 0, 53}, - dictWord{24, 0, 27}, - dictWord{152, 0, 31}, - dictWord{ - 133, - 0, - 716, - }, - dictWord{135, 0, 844}, - dictWord{4, 0, 91}, - dictWord{5, 0, 388}, - dictWord{5, 0, 845}, - dictWord{6, 0, 206}, - dictWord{6, 0, 252}, - dictWord{6, 0, 365}, - dictWord{ - 7, - 0, - 136, - }, - dictWord{7, 0, 531}, - dictWord{136, 0, 621}, - dictWord{7, 10, 393}, - dictWord{10, 10, 603}, - dictWord{139, 10, 206}, - dictWord{6, 11, 80}, - dictWord{ - 6, - 11, - 1694, - }, - dictWord{7, 11, 173}, - dictWord{7, 11, 1974}, - dictWord{9, 11, 547}, - dictWord{10, 11, 730}, - dictWord{14, 11, 18}, - dictWord{150, 11, 39}, - dictWord{137, 0, 748}, - dictWord{4, 11, 923}, - dictWord{134, 11, 1711}, - dictWord{4, 10, 912}, - dictWord{137, 10, 232}, - dictWord{7, 10, 98}, - dictWord{7, 10, 1973}, - dictWord{136, 10, 716}, - dictWord{14, 0, 103}, - dictWord{133, 10, 733}, - dictWord{132, 11, 595}, - dictWord{12, 0, 158}, - dictWord{18, 0, 8}, - dictWord{19, 0, 62}, - dictWord{20, 0, 6}, - dictWord{22, 0, 4}, - dictWord{23, 0, 2}, - dictWord{23, 0, 9}, - dictWord{5, 11, 240}, - dictWord{6, 11, 459}, - dictWord{7, 11, 12}, - dictWord{7, 11, 114}, - dictWord{7, 11, 502}, - dictWord{7, 11, 1751}, - dictWord{7, 11, 1753}, - dictWord{7, 11, 1805}, - dictWord{8, 11, 658}, - dictWord{9, 11, 1}, - dictWord{11, 11, 959}, - dictWord{13, 11, 446}, - dictWord{142, 11, 211}, - dictWord{135, 0, 576}, - dictWord{5, 0, 771}, - dictWord{5, 0, 863}, - dictWord{5, 0, 898}, - dictWord{6, 0, 648}, - dictWord{ - 6, - 0, - 1632, - }, - dictWord{6, 0, 1644}, - dictWord{134, 0, 1780}, - dictWord{133, 0, 331}, - dictWord{7, 11, 633}, - dictWord{7, 11, 905}, - dictWord{7, 11, 909}, - dictWord{ - 7, - 11, - 1538, - }, - dictWord{9, 11, 767}, - dictWord{140, 11, 636}, - dictWord{140, 0, 632}, - dictWord{5, 0, 107}, - dictWord{7, 0, 201}, - dictWord{136, 0, 518}, - dictWord{ - 6, - 0, - 446, - }, - dictWord{7, 0, 1817}, - dictWord{134, 11, 490}, - dictWord{9, 0, 851}, - dictWord{141, 0, 510}, - dictWord{7, 11, 250}, - dictWord{8, 11, 506}, - dictWord{ - 136, - 11, - 507, - }, - dictWord{4, 0, 504}, - dictWord{137, 10, 72}, - dictWord{132, 11, 158}, - dictWord{4, 11, 140}, - dictWord{7, 11, 362}, - dictWord{8, 11, 209}, - dictWord{ - 9, - 11, - 10, - }, - dictWord{9, 11, 160}, - dictWord{9, 11, 503}, - dictWord{10, 11, 689}, - dictWord{11, 11, 350}, - dictWord{11, 11, 553}, - dictWord{11, 11, 725}, - dictWord{ - 12, - 11, - 252, - }, - dictWord{12, 11, 583}, - dictWord{13, 11, 192}, - dictWord{13, 11, 352}, - dictWord{14, 11, 269}, - dictWord{14, 11, 356}, - dictWord{148, 11, 50}, - dictWord{6, 11, 597}, - dictWord{135, 11, 1318}, - dictWord{135, 10, 1454}, - dictWord{5, 0, 883}, - dictWord{5, 0, 975}, - dictWord{8, 0, 392}, - dictWord{148, 0, 7}, - dictWord{6, 11, 228}, - dictWord{7, 11, 1341}, - dictWord{9, 11, 408}, - dictWord{138, 11, 343}, - dictWord{11, 11, 348}, - dictWord{11, 10, 600}, - dictWord{12, 11, 99}, - dictWord{13, 10, 245}, - dictWord{18, 11, 1}, - dictWord{18, 11, 11}, - dictWord{147, 11, 4}, - dictWord{134, 11, 296}, - dictWord{5, 0, 922}, - dictWord{134, 0, 1707}, - dictWord{132, 11, 557}, - dictWord{4, 11, 548}, - dictWord{7, 10, 164}, - dictWord{7, 10, 1571}, - dictWord{9, 10, 107}, - dictWord{140, 10, 225}, - dictWord{ - 7, - 11, - 197, - }, - dictWord{8, 11, 142}, - dictWord{8, 11, 325}, - dictWord{9, 11, 150}, - dictWord{9, 11, 596}, - dictWord{10, 11, 350}, - dictWord{10, 11, 353}, - dictWord{ - 11, - 11, - 74, - }, - dictWord{11, 11, 315}, - dictWord{14, 11, 423}, - dictWord{143, 11, 141}, - dictWord{5, 0, 993}, - dictWord{7, 0, 515}, - dictWord{137, 0, 91}, - dictWord{4, 0, 131}, - dictWord{8, 0, 200}, - dictWord{5, 10, 484}, - dictWord{5, 10, 510}, - dictWord{6, 10, 434}, - dictWord{7, 10, 1000}, - dictWord{7, 10, 1098}, - dictWord{136, 10, 2}, - dictWord{152, 0, 10}, - dictWord{4, 11, 62}, - dictWord{5, 11, 83}, - dictWord{6, 11, 399}, - dictWord{6, 11, 579}, - dictWord{7, 11, 692}, - dictWord{7, 11, 846}, - dictWord{ - 7, - 11, - 1015, - }, - dictWord{7, 11, 1799}, - dictWord{8, 11, 403}, - dictWord{9, 11, 394}, - dictWord{10, 11, 133}, - dictWord{12, 11, 4}, - dictWord{12, 11, 297}, - dictWord{ - 12, - 11, - 452, - }, - dictWord{16, 11, 81}, - dictWord{18, 11, 19}, - dictWord{18, 11, 25}, - dictWord{21, 11, 14}, - dictWord{22, 11, 12}, - dictWord{151, 11, 18}, - dictWord{ - 140, - 11, - 459, - }, - dictWord{132, 11, 177}, - dictWord{7, 0, 1433}, - dictWord{9, 0, 365}, - dictWord{137, 11, 365}, - dictWord{132, 10, 460}, - dictWord{5, 0, 103}, - dictWord{ - 6, - 0, - 2004, - }, - dictWord{7, 0, 921}, - dictWord{8, 0, 580}, - dictWord{8, 0, 593}, - dictWord{8, 0, 630}, - dictWord{10, 0, 28}, - dictWord{5, 11, 411}, - dictWord{ - 135, - 11, - 653, - }, - dictWord{4, 10, 932}, - dictWord{133, 10, 891}, - dictWord{4, 0, 911}, - dictWord{5, 0, 867}, - dictWord{5, 0, 1013}, - dictWord{7, 0, 2034}, - dictWord{8, 0, 798}, - dictWord{136, 0, 813}, - dictWord{7, 11, 439}, - dictWord{10, 11, 727}, - dictWord{11, 11, 260}, - dictWord{139, 11, 684}, - dictWord{136, 10, 625}, - dictWord{ - 5, - 11, - 208, - }, - dictWord{7, 11, 753}, - dictWord{135, 11, 1528}, - dictWord{5, 0, 461}, - dictWord{7, 0, 1925}, - dictWord{12, 0, 39}, - dictWord{13, 0, 265}, - dictWord{ - 13, - 0, - 439, - }, - dictWord{134, 10, 76}, - dictWord{6, 0, 853}, - dictWord{8, 10, 92}, - dictWord{137, 10, 221}, - dictWord{5, 0, 135}, - dictWord{6, 0, 519}, - dictWord{7, 0, 1722}, - dictWord{10, 0, 271}, - dictWord{11, 0, 261}, - dictWord{145, 0, 54}, - dictWord{139, 11, 814}, - dictWord{14, 0, 338}, - dictWord{148, 0, 81}, - dictWord{4, 0, 300}, - dictWord{133, 0, 436}, - dictWord{5, 0, 419}, - dictWord{5, 0, 687}, - dictWord{7, 0, 864}, - dictWord{9, 0, 470}, - dictWord{135, 11, 864}, - dictWord{9, 0, 836}, - dictWord{ - 133, - 11, - 242, - }, - dictWord{134, 0, 1937}, - dictWord{4, 10, 763}, - dictWord{133, 11, 953}, - dictWord{132, 10, 622}, - dictWord{132, 0, 393}, - dictWord{ - 133, - 10, - 253, - }, - dictWord{8, 0, 357}, - dictWord{10, 0, 745}, - dictWord{14, 0, 426}, - dictWord{17, 0, 94}, - dictWord{19, 0, 57}, - dictWord{135, 10, 546}, - dictWord{5, 11, 615}, - dictWord{146, 11, 37}, - dictWord{9, 10, 73}, - dictWord{10, 10, 110}, - dictWord{14, 10, 185}, - dictWord{145, 10, 119}, - dictWord{11, 0, 703}, - dictWord{7, 10, 624}, - dictWord{7, 10, 916}, - dictWord{10, 10, 256}, - dictWord{139, 10, 87}, - dictWord{133, 11, 290}, - dictWord{5, 10, 212}, - dictWord{12, 10, 35}, - dictWord{ - 141, - 10, - 382, - }, - dictWord{132, 11, 380}, - dictWord{5, 11, 52}, - dictWord{7, 11, 277}, - dictWord{9, 11, 368}, - dictWord{139, 11, 791}, - dictWord{133, 0, 387}, - dictWord{ - 10, - 11, - 138, - }, - dictWord{139, 11, 476}, - dictWord{4, 0, 6}, - dictWord{5, 0, 708}, - dictWord{136, 0, 75}, - dictWord{7, 0, 1351}, - dictWord{9, 0, 581}, - dictWord{10, 0, 639}, - dictWord{11, 0, 453}, - dictWord{140, 0, 584}, - dictWord{132, 0, 303}, - dictWord{138, 0, 772}, - dictWord{135, 10, 1175}, - dictWord{4, 0, 749}, - dictWord{ - 5, - 10, - 816, - }, - dictWord{6, 11, 256}, - dictWord{7, 11, 307}, - dictWord{7, 11, 999}, - dictWord{7, 11, 1481}, - dictWord{7, 11, 1732}, - dictWord{7, 11, 1738}, - dictWord{ - 8, - 11, - 265, - }, - dictWord{9, 11, 414}, - dictWord{11, 11, 316}, - dictWord{12, 11, 52}, - dictWord{13, 11, 420}, - dictWord{147, 11, 100}, - dictWord{135, 11, 1296}, - dictWord{ - 6, - 0, - 1065, - }, - dictWord{5, 10, 869}, - dictWord{5, 10, 968}, - dictWord{6, 10, 1626}, - dictWord{8, 10, 734}, - dictWord{136, 10, 784}, - dictWord{4, 10, 542}, - dictWord{ - 6, - 10, - 1716, - }, - dictWord{6, 10, 1727}, - dictWord{7, 10, 1082}, - dictWord{7, 10, 1545}, - dictWord{8, 10, 56}, - dictWord{8, 10, 118}, - dictWord{8, 10, 412}, - dictWord{ - 8, - 10, - 564, - }, - dictWord{9, 10, 888}, - dictWord{9, 10, 908}, - dictWord{10, 10, 50}, - dictWord{10, 10, 423}, - dictWord{11, 10, 685}, - dictWord{11, 10, 697}, - dictWord{11, 10, 933}, - dictWord{12, 10, 299}, - dictWord{13, 10, 126}, - dictWord{13, 10, 136}, - dictWord{13, 10, 170}, - dictWord{141, 10, 190}, - dictWord{ - 134, - 0, - 226, - }, - dictWord{4, 0, 106}, - dictWord{7, 0, 310}, - dictWord{11, 0, 717}, - dictWord{133, 11, 723}, - dictWord{5, 0, 890}, - dictWord{5, 0, 988}, - dictWord{4, 10, 232}, - dictWord{9, 10, 202}, - dictWord{10, 10, 474}, - dictWord{140, 10, 433}, - dictWord{6, 0, 626}, - dictWord{142, 0, 431}, - dictWord{10, 0, 706}, - dictWord{150, 0, 44}, - dictWord{13, 0, 51}, - dictWord{6, 10, 108}, - dictWord{7, 10, 1003}, - dictWord{7, 10, 1181}, - dictWord{8, 10, 111}, - dictWord{136, 10, 343}, - dictWord{132, 0, 698}, - dictWord{5, 11, 109}, - dictWord{6, 11, 1784}, - dictWord{7, 11, 1895}, - dictWord{12, 11, 296}, - dictWord{140, 11, 302}, - dictWord{134, 0, 828}, - dictWord{ - 134, - 10, - 1712, - }, - dictWord{138, 0, 17}, - dictWord{7, 0, 1929}, - dictWord{4, 10, 133}, - dictWord{5, 11, 216}, - dictWord{7, 10, 711}, - dictWord{7, 10, 1298}, - dictWord{ - 7, - 10, - 1585, - }, - dictWord{7, 11, 1879}, - dictWord{9, 11, 141}, - dictWord{9, 11, 270}, - dictWord{9, 11, 679}, - dictWord{10, 11, 159}, - dictWord{10, 11, 553}, - dictWord{ - 11, - 11, - 197, - }, - dictWord{11, 11, 438}, - dictWord{12, 11, 538}, - dictWord{12, 11, 559}, - dictWord{13, 11, 193}, - dictWord{13, 11, 423}, - dictWord{14, 11, 144}, - dictWord{14, 11, 166}, - dictWord{14, 11, 167}, - dictWord{15, 11, 67}, - dictWord{147, 11, 84}, - dictWord{141, 11, 127}, - dictWord{7, 11, 1872}, - dictWord{ - 137, - 11, - 81, - }, - dictWord{6, 10, 99}, - dictWord{7, 10, 1808}, - dictWord{145, 10, 57}, - dictWord{134, 11, 391}, - dictWord{5, 0, 689}, - dictWord{6, 0, 84}, - dictWord{7, 0, 1250}, - dictWord{6, 10, 574}, - dictWord{7, 10, 428}, - dictWord{10, 10, 669}, - dictWord{11, 10, 485}, - dictWord{11, 10, 840}, - dictWord{12, 10, 300}, - dictWord{ - 142, - 10, - 250, - }, - dictWord{7, 11, 322}, - dictWord{136, 11, 249}, - dictWord{7, 11, 432}, - dictWord{135, 11, 1649}, - dictWord{135, 10, 1871}, - dictWord{137, 10, 252}, - dictWord{6, 11, 155}, - dictWord{140, 11, 234}, - dictWord{7, 0, 871}, - dictWord{19, 0, 27}, - dictWord{147, 11, 27}, - dictWord{140, 0, 498}, - dictWord{5, 0, 986}, - dictWord{6, 0, 130}, - dictWord{138, 0, 823}, - dictWord{6, 0, 1793}, - dictWord{7, 0, 1582}, - dictWord{8, 0, 458}, - dictWord{10, 0, 101}, - dictWord{10, 0, 318}, - dictWord{ - 10, - 0, - 945, - }, - dictWord{12, 0, 734}, - dictWord{16, 0, 104}, - dictWord{18, 0, 177}, - dictWord{6, 10, 323}, - dictWord{135, 10, 1564}, - dictWord{5, 11, 632}, - dictWord{ - 138, - 11, - 526, - }, - dictWord{10, 0, 435}, - dictWord{7, 10, 461}, - dictWord{136, 10, 775}, - dictWord{6, 11, 144}, - dictWord{7, 11, 948}, - dictWord{7, 11, 1042}, - dictWord{ - 7, - 11, - 1857, - }, - dictWord{8, 11, 235}, - dictWord{8, 11, 461}, - dictWord{9, 11, 453}, - dictWord{9, 11, 530}, - dictWord{10, 11, 354}, - dictWord{17, 11, 77}, - dictWord{ - 19, - 11, - 99, - }, - dictWord{148, 11, 79}, - dictWord{138, 0, 966}, - dictWord{7, 0, 1644}, - dictWord{137, 0, 129}, - dictWord{135, 0, 997}, - dictWord{136, 0, 502}, - dictWord{ - 5, - 11, - 196, - }, - dictWord{6, 11, 486}, - dictWord{7, 11, 212}, - dictWord{8, 11, 309}, - dictWord{136, 11, 346}, - dictWord{7, 10, 727}, - dictWord{146, 10, 73}, - dictWord{132, 0, 823}, - dictWord{132, 11, 686}, - dictWord{135, 0, 1927}, - dictWord{4, 0, 762}, - dictWord{7, 0, 1756}, - dictWord{137, 0, 98}, - dictWord{136, 10, 577}, - dictWord{24, 0, 8}, - dictWord{4, 11, 30}, - dictWord{5, 11, 43}, - dictWord{152, 11, 8}, - dictWord{7, 0, 1046}, - dictWord{139, 0, 160}, - dictWord{7, 0, 492}, - dictWord{ - 4, - 10, - 413, - }, - dictWord{5, 10, 677}, - dictWord{7, 11, 492}, - dictWord{8, 10, 432}, - dictWord{140, 10, 280}, - dictWord{6, 0, 45}, - dictWord{7, 0, 433}, - dictWord{8, 0, 129}, - dictWord{9, 0, 21}, - dictWord{10, 0, 392}, - dictWord{11, 0, 79}, - dictWord{12, 0, 499}, - dictWord{13, 0, 199}, - dictWord{141, 0, 451}, - dictWord{7, 0, 558}, - dictWord{ - 136, - 0, - 353, - }, - dictWord{4, 11, 220}, - dictWord{7, 11, 1535}, - dictWord{9, 11, 93}, - dictWord{139, 11, 474}, - dictWord{7, 10, 646}, - dictWord{7, 10, 1730}, - dictWord{ - 11, - 10, - 446, - }, - dictWord{141, 10, 178}, - dictWord{133, 0, 785}, - dictWord{134, 0, 1145}, - dictWord{8, 0, 81}, - dictWord{9, 0, 189}, - dictWord{9, 0, 201}, - dictWord{ - 11, - 0, - 478, - }, - dictWord{11, 0, 712}, - dictWord{141, 0, 338}, - dictWord{5, 0, 353}, - dictWord{151, 0, 26}, - dictWord{11, 0, 762}, - dictWord{132, 10, 395}, - dictWord{ - 134, - 0, - 2024, - }, - dictWord{4, 0, 611}, - dictWord{133, 0, 606}, - dictWord{9, 10, 174}, - dictWord{10, 10, 164}, - dictWord{11, 10, 440}, - dictWord{11, 10, 841}, - dictWord{ - 143, - 10, - 98, - }, - dictWord{134, 10, 426}, - dictWord{10, 10, 608}, - dictWord{139, 10, 1002}, - dictWord{138, 10, 250}, - dictWord{6, 0, 25}, - dictWord{7, 0, 855}, - dictWord{7, 0, 1258}, - dictWord{144, 0, 32}, - dictWord{7, 11, 1725}, - dictWord{138, 11, 393}, - dictWord{5, 11, 263}, - dictWord{134, 11, 414}, - dictWord{6, 0, 2011}, - dictWord{133, 10, 476}, - dictWord{4, 0, 4}, - dictWord{7, 0, 1118}, - dictWord{7, 0, 1320}, - dictWord{7, 0, 1706}, - dictWord{8, 0, 277}, - dictWord{9, 0, 622}, - dictWord{ - 10, - 0, - 9, - }, - dictWord{11, 0, 724}, - dictWord{12, 0, 350}, - dictWord{12, 0, 397}, - dictWord{13, 0, 28}, - dictWord{13, 0, 159}, - dictWord{15, 0, 89}, - dictWord{18, 0, 5}, - dictWord{ - 19, - 0, - 9, - }, - dictWord{20, 0, 34}, - dictWord{22, 0, 47}, - dictWord{6, 11, 178}, - dictWord{6, 11, 1750}, - dictWord{8, 11, 251}, - dictWord{9, 11, 690}, - dictWord{ - 10, - 11, - 155, - }, - dictWord{10, 11, 196}, - dictWord{10, 11, 373}, - dictWord{11, 11, 698}, - dictWord{13, 11, 155}, - dictWord{148, 11, 93}, - dictWord{5, 11, 97}, - dictWord{ - 137, - 11, - 393, - }, - dictWord{7, 0, 764}, - dictWord{11, 0, 461}, - dictWord{12, 0, 172}, - dictWord{5, 10, 76}, - dictWord{6, 10, 458}, - dictWord{6, 10, 497}, - dictWord{ - 7, - 10, - 868, - }, - dictWord{9, 10, 658}, - dictWord{10, 10, 594}, - dictWord{11, 10, 566}, - dictWord{12, 10, 338}, - dictWord{141, 10, 200}, - dictWord{134, 0, 1449}, - dictWord{138, 11, 40}, - dictWord{134, 11, 1639}, - dictWord{134, 0, 1445}, - dictWord{6, 0, 1168}, - dictWord{4, 10, 526}, - dictWord{7, 10, 1029}, - dictWord{ - 135, - 10, - 1054, - }, - dictWord{4, 11, 191}, - dictWord{7, 11, 934}, - dictWord{8, 11, 647}, - dictWord{145, 11, 97}, - dictWord{132, 10, 636}, - dictWord{6, 0, 233}, - dictWord{ - 7, - 10, - 660, - }, - dictWord{7, 10, 1124}, - dictWord{17, 10, 31}, - dictWord{19, 10, 22}, - dictWord{151, 10, 14}, - dictWord{6, 10, 1699}, - dictWord{136, 11, 110}, - dictWord{ - 12, - 11, - 246, - }, - dictWord{15, 11, 162}, - dictWord{19, 11, 64}, - dictWord{20, 11, 8}, - dictWord{20, 11, 95}, - dictWord{22, 11, 24}, - dictWord{152, 11, 17}, - dictWord{ - 5, - 11, - 165, - }, - dictWord{9, 11, 346}, - dictWord{138, 11, 655}, - dictWord{5, 11, 319}, - dictWord{135, 11, 534}, - dictWord{134, 0, 255}, - dictWord{9, 0, 216}, - dictWord{ - 8, - 11, - 128, - }, - dictWord{139, 11, 179}, - dictWord{9, 0, 183}, - dictWord{139, 0, 286}, - dictWord{11, 0, 956}, - dictWord{151, 0, 3}, - dictWord{4, 0, 536}, - dictWord{ - 7, - 0, - 1141, - }, - dictWord{10, 0, 723}, - dictWord{139, 0, 371}, - dictWord{4, 10, 279}, - dictWord{7, 10, 301}, - dictWord{137, 10, 362}, - dictWord{7, 0, 285}, - dictWord{ - 5, - 11, - 57, - }, - dictWord{6, 11, 101}, - dictWord{6, 11, 1663}, - dictWord{7, 11, 132}, - dictWord{7, 11, 1048}, - dictWord{7, 11, 1154}, - dictWord{7, 11, 1415}, - dictWord{ - 7, - 11, - 1507, - }, - dictWord{12, 11, 493}, - dictWord{15, 11, 105}, - dictWord{151, 11, 15}, - dictWord{5, 11, 459}, - dictWord{7, 11, 1073}, - dictWord{7, 10, 1743}, - dictWord{ - 8, - 11, - 241, - }, - dictWord{136, 11, 334}, - dictWord{4, 10, 178}, - dictWord{133, 10, 399}, - dictWord{135, 0, 560}, - dictWord{132, 0, 690}, - dictWord{135, 0, 1246}, - dictWord{18, 0, 157}, - dictWord{147, 0, 63}, - dictWord{10, 0, 599}, - dictWord{11, 0, 33}, - dictWord{12, 0, 571}, - dictWord{149, 0, 1}, - dictWord{6, 11, 324}, - dictWord{ - 6, - 11, - 520, - }, - dictWord{7, 11, 338}, - dictWord{7, 11, 1616}, - dictWord{7, 11, 1729}, - dictWord{8, 11, 228}, - dictWord{9, 11, 69}, - dictWord{139, 11, 750}, - dictWord{ - 7, - 0, - 1862, - }, - dictWord{12, 0, 491}, - dictWord{12, 0, 520}, - dictWord{13, 0, 383}, - dictWord{142, 0, 244}, - dictWord{135, 11, 734}, - dictWord{134, 10, 1692}, - dictWord{10, 0, 448}, - dictWord{11, 0, 630}, - dictWord{17, 0, 117}, - dictWord{6, 10, 202}, - dictWord{7, 11, 705}, - dictWord{12, 10, 360}, - dictWord{17, 10, 118}, - dictWord{18, 10, 27}, - dictWord{148, 10, 67}, - dictWord{4, 11, 73}, - dictWord{6, 11, 612}, - dictWord{7, 11, 927}, - dictWord{7, 11, 1822}, - dictWord{8, 11, 217}, - dictWord{ - 9, - 11, - 472, - }, - dictWord{9, 11, 765}, - dictWord{9, 11, 766}, - dictWord{10, 11, 408}, - dictWord{11, 11, 51}, - dictWord{11, 11, 793}, - dictWord{12, 11, 266}, - dictWord{ - 15, - 11, - 158, - }, - dictWord{20, 11, 89}, - dictWord{150, 11, 32}, - dictWord{4, 0, 190}, - dictWord{133, 0, 554}, - dictWord{133, 0, 1001}, - dictWord{5, 11, 389}, - dictWord{ - 8, - 11, - 636, - }, - dictWord{137, 11, 229}, - dictWord{5, 0, 446}, - dictWord{7, 10, 872}, - dictWord{10, 10, 516}, - dictWord{139, 10, 167}, - dictWord{137, 10, 313}, - dictWord{132, 10, 224}, - dictWord{134, 0, 1313}, - dictWord{5, 10, 546}, - dictWord{7, 10, 35}, - dictWord{8, 10, 11}, - dictWord{8, 10, 12}, - dictWord{9, 10, 315}, - dictWord{9, 10, 533}, - dictWord{10, 10, 802}, - dictWord{11, 10, 166}, - dictWord{12, 10, 525}, - dictWord{142, 10, 243}, - dictWord{6, 0, 636}, - dictWord{137, 0, 837}, - dictWord{5, 10, 241}, - dictWord{8, 10, 242}, - dictWord{9, 10, 451}, - dictWord{10, 10, 667}, - dictWord{11, 10, 598}, - dictWord{140, 10, 429}, - dictWord{22, 10, 46}, - dictWord{150, 11, 46}, - dictWord{136, 11, 472}, - dictWord{11, 0, 278}, - dictWord{142, 0, 73}, - dictWord{141, 11, 185}, - dictWord{132, 0, 868}, - dictWord{ - 134, - 0, - 972, - }, - dictWord{4, 10, 366}, - dictWord{137, 10, 516}, - dictWord{138, 0, 1010}, - dictWord{5, 11, 189}, - dictWord{6, 10, 1736}, - dictWord{7, 11, 442}, - dictWord{ - 7, - 11, - 443, - }, - dictWord{8, 11, 281}, - dictWord{12, 11, 174}, - dictWord{13, 11, 83}, - dictWord{141, 11, 261}, - dictWord{139, 11, 384}, - dictWord{6, 11, 2}, - dictWord{ - 7, - 11, - 191, - }, - dictWord{7, 11, 446}, - dictWord{7, 11, 758}, - dictWord{7, 11, 1262}, - dictWord{7, 11, 1737}, - dictWord{8, 11, 22}, - dictWord{8, 11, 270}, - dictWord{ - 8, - 11, - 612, - }, - dictWord{9, 11, 4}, - dictWord{9, 11, 167}, - dictWord{9, 11, 312}, - dictWord{9, 11, 436}, - dictWord{10, 11, 156}, - dictWord{10, 11, 216}, - dictWord{ - 10, - 11, - 311, - }, - dictWord{10, 11, 623}, - dictWord{11, 11, 72}, - dictWord{11, 11, 330}, - dictWord{11, 11, 455}, - dictWord{12, 11, 101}, - dictWord{12, 11, 321}, - dictWord{ - 12, - 11, - 504, - }, - dictWord{12, 11, 530}, - dictWord{12, 11, 543}, - dictWord{13, 11, 17}, - dictWord{13, 11, 156}, - dictWord{13, 11, 334}, - dictWord{14, 11, 48}, - dictWord{15, 11, 70}, - dictWord{17, 11, 60}, - dictWord{148, 11, 64}, - dictWord{6, 10, 331}, - dictWord{136, 10, 623}, - dictWord{135, 0, 1231}, - dictWord{132, 0, 304}, - dictWord{6, 11, 60}, - dictWord{7, 11, 670}, - dictWord{7, 11, 1327}, - dictWord{8, 11, 411}, - dictWord{8, 11, 435}, - dictWord{9, 11, 653}, - dictWord{9, 11, 740}, - dictWord{10, 11, 385}, - dictWord{11, 11, 222}, - dictWord{11, 11, 324}, - dictWord{11, 11, 829}, - dictWord{140, 11, 611}, - dictWord{7, 0, 506}, - dictWord{6, 11, 166}, - dictWord{7, 11, 374}, - dictWord{135, 11, 1174}, - dictWord{14, 11, 43}, - dictWord{146, 11, 21}, - dictWord{135, 11, 1694}, - dictWord{135, 10, 1888}, - dictWord{ - 5, - 11, - 206, - }, - dictWord{134, 11, 398}, - dictWord{135, 11, 50}, - dictWord{150, 0, 26}, - dictWord{6, 0, 53}, - dictWord{6, 0, 199}, - dictWord{7, 0, 1408}, - dictWord{ - 8, - 0, - 32, - }, - dictWord{8, 0, 93}, - dictWord{10, 0, 397}, - dictWord{10, 0, 629}, - dictWord{11, 0, 593}, - dictWord{11, 0, 763}, - dictWord{13, 0, 326}, - dictWord{145, 0, 35}, - dictWord{134, 0, 105}, - dictWord{132, 10, 394}, - dictWord{4, 0, 843}, - dictWord{138, 0, 794}, - dictWord{11, 0, 704}, - dictWord{141, 0, 396}, - dictWord{5, 0, 114}, - dictWord{5, 0, 255}, - dictWord{141, 0, 285}, - dictWord{6, 0, 619}, - dictWord{7, 0, 898}, - dictWord{7, 0, 1092}, - dictWord{8, 0, 485}, - dictWord{18, 0, 28}, - dictWord{ - 19, - 0, - 116, - }, - dictWord{135, 10, 1931}, - dictWord{9, 0, 145}, - dictWord{7, 10, 574}, - dictWord{135, 10, 1719}, - dictWord{7, 0, 2035}, - dictWord{8, 0, 19}, - dictWord{ - 9, - 0, - 89, - }, - dictWord{138, 0, 831}, - dictWord{132, 10, 658}, - dictWord{6, 11, 517}, - dictWord{7, 11, 1159}, - dictWord{10, 11, 621}, - dictWord{139, 11, 192}, - dictWord{ - 7, - 0, - 1933, - }, - dictWord{7, 11, 1933}, - dictWord{9, 10, 781}, - dictWord{10, 10, 144}, - dictWord{11, 10, 385}, - dictWord{13, 10, 161}, - dictWord{13, 10, 228}, - dictWord{13, 10, 268}, - dictWord{148, 10, 107}, - dictWord{136, 10, 374}, - dictWord{10, 11, 223}, - dictWord{139, 11, 645}, - dictWord{135, 0, 1728}, - dictWord{ - 7, - 11, - 64, - }, - dictWord{7, 11, 289}, - dictWord{136, 11, 245}, - dictWord{4, 10, 344}, - dictWord{6, 10, 498}, - dictWord{139, 10, 323}, - dictWord{136, 0, 746}, - dictWord{ - 135, - 10, - 1063, - }, - dictWord{137, 10, 155}, - dictWord{4, 0, 987}, - dictWord{6, 0, 1964}, - dictWord{6, 0, 1974}, - dictWord{6, 0, 1990}, - dictWord{136, 0, 995}, - dictWord{133, 11, 609}, - dictWord{133, 10, 906}, - dictWord{134, 0, 1550}, - dictWord{134, 0, 874}, - dictWord{5, 11, 129}, - dictWord{6, 11, 61}, - dictWord{ - 135, - 11, - 947, - }, - dictWord{4, 0, 1018}, - dictWord{6, 0, 1938}, - dictWord{6, 0, 2021}, - dictWord{134, 0, 2039}, - dictWord{132, 0, 814}, - dictWord{11, 0, 126}, - dictWord{ - 139, - 0, - 287, - }, - dictWord{134, 0, 1264}, - dictWord{5, 0, 955}, - dictWord{136, 0, 814}, - dictWord{141, 11, 506}, - dictWord{132, 11, 314}, - dictWord{6, 0, 981}, - dictWord{139, 11, 1000}, - dictWord{5, 0, 56}, - dictWord{8, 0, 892}, - dictWord{8, 0, 915}, - dictWord{140, 0, 776}, - dictWord{148, 0, 100}, - dictWord{10, 0, 4}, - dictWord{ - 10, - 0, - 13, - }, - dictWord{11, 0, 638}, - dictWord{148, 0, 57}, - dictWord{148, 11, 74}, - dictWord{5, 0, 738}, - dictWord{132, 10, 616}, - dictWord{133, 11, 637}, - dictWord{ - 136, - 10, - 692, - }, - dictWord{133, 0, 758}, - dictWord{132, 10, 305}, - dictWord{137, 11, 590}, - dictWord{5, 11, 280}, - dictWord{135, 11, 1226}, - dictWord{ - 134, - 11, - 494, - }, - dictWord{135, 0, 1112}, - dictWord{133, 11, 281}, - dictWord{13, 0, 44}, - dictWord{14, 0, 214}, - dictWord{5, 10, 214}, - dictWord{7, 10, 603}, - dictWord{ - 8, - 10, - 611, - }, - dictWord{9, 10, 686}, - dictWord{10, 10, 88}, - dictWord{11, 10, 459}, - dictWord{11, 10, 496}, - dictWord{12, 10, 463}, - dictWord{140, 10, 590}, - dictWord{ - 139, - 0, - 328, - }, - dictWord{135, 11, 1064}, - dictWord{137, 0, 133}, - dictWord{7, 0, 168}, - dictWord{13, 0, 196}, - dictWord{141, 0, 237}, - dictWord{134, 10, 1703}, - dictWord{134, 0, 1152}, - dictWord{135, 0, 1245}, - dictWord{5, 0, 110}, - dictWord{6, 0, 169}, - dictWord{6, 0, 1702}, - dictWord{7, 0, 400}, - dictWord{8, 0, 538}, - dictWord{ - 9, - 0, - 184, - }, - dictWord{9, 0, 524}, - dictWord{140, 0, 218}, - dictWord{6, 0, 1816}, - dictWord{10, 0, 871}, - dictWord{12, 0, 769}, - dictWord{140, 0, 785}, - dictWord{ - 132, - 11, - 630, - }, - dictWord{7, 11, 33}, - dictWord{7, 11, 120}, - dictWord{8, 11, 489}, - dictWord{9, 11, 319}, - dictWord{10, 11, 820}, - dictWord{11, 11, 1004}, - dictWord{ - 12, - 11, - 379, - }, - dictWord{13, 11, 117}, - dictWord{13, 11, 412}, - dictWord{14, 11, 25}, - dictWord{15, 11, 52}, - dictWord{15, 11, 161}, - dictWord{16, 11, 47}, - dictWord{149, 11, 2}, - dictWord{6, 0, 133}, - dictWord{8, 0, 413}, - dictWord{9, 0, 353}, - dictWord{139, 0, 993}, - dictWord{145, 10, 19}, - dictWord{4, 11, 937}, - dictWord{ - 133, - 11, - 801, - }, - dictWord{134, 0, 978}, - dictWord{6, 0, 93}, - dictWord{6, 0, 1508}, - dictWord{7, 0, 1422}, - dictWord{7, 0, 1851}, - dictWord{8, 0, 673}, - dictWord{9, 0, 529}, - dictWord{140, 0, 43}, - dictWord{6, 0, 317}, - dictWord{10, 0, 512}, - dictWord{4, 10, 737}, - dictWord{11, 10, 294}, - dictWord{12, 10, 60}, - dictWord{12, 10, 437}, - dictWord{13, 10, 64}, - dictWord{13, 10, 380}, - dictWord{142, 10, 430}, - dictWord{9, 0, 371}, - dictWord{7, 11, 1591}, - dictWord{144, 11, 43}, - dictWord{6, 10, 1758}, - dictWord{8, 10, 520}, - dictWord{9, 10, 345}, - dictWord{9, 10, 403}, - dictWord{142, 10, 350}, - dictWord{5, 0, 526}, - dictWord{10, 10, 242}, - dictWord{ - 138, - 10, - 579, - }, - dictWord{9, 0, 25}, - dictWord{10, 0, 467}, - dictWord{138, 0, 559}, - dictWord{5, 10, 139}, - dictWord{7, 10, 1168}, - dictWord{138, 10, 539}, - dictWord{ - 4, - 0, - 335, - }, - dictWord{135, 0, 942}, - dictWord{140, 0, 754}, - dictWord{132, 11, 365}, - dictWord{11, 0, 182}, - dictWord{142, 0, 195}, - dictWord{142, 11, 29}, - dictWord{ - 5, - 11, - 7, - }, - dictWord{139, 11, 774}, - dictWord{4, 11, 746}, - dictWord{135, 11, 1090}, - dictWord{8, 0, 39}, - dictWord{10, 0, 773}, - dictWord{11, 0, 84}, - dictWord{ - 12, - 0, - 205, - }, - dictWord{142, 0, 1}, - dictWord{5, 0, 601}, - dictWord{5, 0, 870}, - dictWord{5, 11, 360}, - dictWord{136, 11, 237}, - dictWord{132, 0, 181}, - dictWord{ - 136, - 0, - 370, - }, - dictWord{134, 0, 1652}, - dictWord{8, 0, 358}, - dictWord{4, 10, 107}, - dictWord{7, 10, 613}, - dictWord{8, 10, 439}, - dictWord{8, 10, 504}, - dictWord{ - 9, - 10, - 501, - }, - dictWord{10, 10, 383}, - dictWord{139, 10, 477}, - dictWord{132, 10, 229}, - dictWord{137, 11, 785}, - dictWord{4, 0, 97}, - dictWord{5, 0, 147}, - dictWord{ - 6, - 0, - 286, - }, - dictWord{7, 0, 1362}, - dictWord{141, 0, 176}, - dictWord{6, 0, 537}, - dictWord{7, 0, 788}, - dictWord{7, 0, 1816}, - dictWord{132, 10, 903}, - dictWord{ - 140, - 10, - 71, - }, - dictWord{6, 0, 743}, - dictWord{134, 0, 1223}, - dictWord{6, 0, 375}, - dictWord{7, 0, 169}, - dictWord{7, 0, 254}, - dictWord{8, 0, 780}, - dictWord{135, 11, 1493}, - dictWord{7, 0, 1714}, - dictWord{4, 10, 47}, - dictWord{6, 10, 373}, - dictWord{7, 10, 452}, - dictWord{7, 10, 543}, - dictWord{7, 10, 1856}, - dictWord{9, 10, 6}, - dictWord{ - 11, - 10, - 257, - }, - dictWord{139, 10, 391}, - dictWord{6, 0, 896}, - dictWord{136, 0, 1003}, - dictWord{135, 0, 1447}, - dictWord{137, 11, 341}, - dictWord{5, 10, 980}, - dictWord{134, 10, 1754}, - dictWord{145, 11, 22}, - dictWord{4, 11, 277}, - dictWord{5, 11, 608}, - dictWord{6, 11, 493}, - dictWord{7, 11, 457}, - dictWord{ - 140, - 11, - 384, - }, - dictWord{7, 10, 536}, - dictWord{7, 10, 1331}, - dictWord{136, 10, 143}, - dictWord{140, 0, 744}, - dictWord{7, 11, 27}, - dictWord{135, 11, 316}, - dictWord{ - 18, - 0, - 126, - }, - dictWord{5, 10, 19}, - dictWord{134, 10, 533}, - dictWord{4, 0, 788}, - dictWord{11, 0, 41}, - dictWord{5, 11, 552}, - dictWord{5, 11, 586}, - dictWord{ - 5, - 11, - 676, - }, - dictWord{6, 11, 448}, - dictWord{8, 11, 244}, - dictWord{11, 11, 1}, - dictWord{11, 11, 41}, - dictWord{13, 11, 3}, - dictWord{16, 11, 54}, - dictWord{17, 11, 4}, - dictWord{146, 11, 13}, - dictWord{4, 0, 985}, - dictWord{6, 0, 1801}, - dictWord{4, 11, 401}, - dictWord{137, 11, 264}, - dictWord{5, 10, 395}, - dictWord{5, 10, 951}, - dictWord{134, 10, 1776}, - dictWord{5, 0, 629}, - dictWord{135, 0, 1549}, - dictWord{11, 10, 663}, - dictWord{12, 10, 210}, - dictWord{13, 10, 166}, - dictWord{ - 13, - 10, - 310, - }, - dictWord{14, 10, 373}, - dictWord{147, 10, 43}, - dictWord{9, 11, 543}, - dictWord{10, 11, 524}, - dictWord{11, 11, 30}, - dictWord{12, 11, 524}, - dictWord{ - 14, - 11, - 315, - }, - dictWord{16, 11, 18}, - dictWord{20, 11, 26}, - dictWord{148, 11, 65}, - dictWord{4, 11, 205}, - dictWord{5, 11, 623}, - dictWord{7, 11, 104}, - dictWord{ - 136, - 11, - 519, - }, - dictWord{5, 0, 293}, - dictWord{134, 0, 601}, - dictWord{7, 11, 579}, - dictWord{9, 11, 41}, - dictWord{9, 11, 244}, - dictWord{9, 11, 669}, - dictWord{ - 10, - 11, - 5, - }, - dictWord{11, 11, 861}, - dictWord{11, 11, 951}, - dictWord{139, 11, 980}, - dictWord{132, 11, 717}, - dictWord{132, 10, 695}, - dictWord{7, 10, 497}, - dictWord{ - 9, - 10, - 387, - }, - dictWord{147, 10, 81}, - dictWord{132, 0, 420}, - dictWord{142, 0, 37}, - dictWord{6, 0, 1134}, - dictWord{6, 0, 1900}, - dictWord{12, 0, 830}, - dictWord{ - 12, - 0, - 878, - }, - dictWord{12, 0, 894}, - dictWord{15, 0, 221}, - dictWord{143, 0, 245}, - dictWord{132, 11, 489}, - dictWord{7, 0, 1570}, - dictWord{140, 0, 542}, - dictWord{ - 8, - 0, - 933, - }, - dictWord{136, 0, 957}, - dictWord{6, 0, 1371}, - dictWord{7, 0, 31}, - dictWord{8, 0, 373}, - dictWord{5, 10, 284}, - dictWord{6, 10, 49}, - dictWord{6, 10, 350}, - dictWord{7, 10, 377}, - dictWord{7, 10, 1693}, - dictWord{8, 10, 678}, - dictWord{9, 10, 161}, - dictWord{9, 10, 585}, - dictWord{9, 10, 671}, - dictWord{9, 10, 839}, - dictWord{11, 10, 912}, - dictWord{141, 10, 427}, - dictWord{135, 11, 892}, - dictWord{4, 0, 325}, - dictWord{138, 0, 125}, - dictWord{139, 11, 47}, - dictWord{ - 132, - 10, - 597, - }, - dictWord{138, 0, 323}, - dictWord{6, 0, 1547}, - dictWord{7, 11, 1605}, - dictWord{9, 11, 473}, - dictWord{11, 11, 962}, - dictWord{146, 11, 139}, - dictWord{ - 139, - 10, - 908, - }, - dictWord{7, 11, 819}, - dictWord{9, 11, 26}, - dictWord{9, 11, 392}, - dictWord{10, 11, 152}, - dictWord{10, 11, 226}, - dictWord{11, 11, 19}, - dictWord{ - 12, - 11, - 276, - }, - dictWord{12, 11, 426}, - dictWord{12, 11, 589}, - dictWord{13, 11, 460}, - dictWord{15, 11, 97}, - dictWord{19, 11, 48}, - dictWord{148, 11, 104}, - dictWord{135, 11, 51}, - dictWord{4, 0, 718}, - dictWord{135, 0, 1216}, - dictWord{6, 0, 1896}, - dictWord{6, 0, 1905}, - dictWord{6, 0, 1912}, - dictWord{9, 0, 947}, - dictWord{ - 9, - 0, - 974, - }, - dictWord{12, 0, 809}, - dictWord{12, 0, 850}, - dictWord{12, 0, 858}, - dictWord{12, 0, 874}, - dictWord{12, 0, 887}, - dictWord{12, 0, 904}, - dictWord{ - 12, - 0, - 929, - }, - dictWord{12, 0, 948}, - dictWord{12, 0, 952}, - dictWord{15, 0, 198}, - dictWord{15, 0, 206}, - dictWord{15, 0, 220}, - dictWord{15, 0, 227}, - dictWord{15, 0, 247}, - dictWord{18, 0, 188}, - dictWord{21, 0, 48}, - dictWord{21, 0, 50}, - dictWord{24, 0, 25}, - dictWord{24, 0, 29}, - dictWord{7, 11, 761}, - dictWord{7, 11, 1051}, - dictWord{ - 137, - 11, - 545, - }, - dictWord{5, 0, 124}, - dictWord{5, 0, 144}, - dictWord{6, 0, 548}, - dictWord{7, 0, 15}, - dictWord{7, 0, 153}, - dictWord{137, 0, 629}, - dictWord{ - 135, - 11, - 606, - }, - dictWord{135, 10, 2014}, - dictWord{7, 10, 2007}, - dictWord{9, 11, 46}, - dictWord{9, 10, 101}, - dictWord{9, 10, 450}, - dictWord{10, 10, 66}, - dictWord{ - 10, - 10, - 842, - }, - dictWord{11, 10, 536}, - dictWord{140, 10, 587}, - dictWord{6, 0, 75}, - dictWord{7, 0, 1531}, - dictWord{8, 0, 416}, - dictWord{9, 0, 240}, - dictWord{9, 0, 275}, - dictWord{10, 0, 100}, - dictWord{11, 0, 658}, - dictWord{11, 0, 979}, - dictWord{12, 0, 86}, - dictWord{14, 0, 207}, - dictWord{15, 0, 20}, - dictWord{143, 0, 25}, - dictWord{ - 5, - 0, - 141, - }, - dictWord{5, 0, 915}, - dictWord{6, 0, 1783}, - dictWord{7, 0, 211}, - dictWord{7, 0, 698}, - dictWord{7, 0, 1353}, - dictWord{9, 0, 83}, - dictWord{9, 0, 281}, - dictWord{ - 10, - 0, - 376, - }, - dictWord{10, 0, 431}, - dictWord{11, 0, 543}, - dictWord{12, 0, 664}, - dictWord{13, 0, 280}, - dictWord{13, 0, 428}, - dictWord{14, 0, 61}, - dictWord{ - 14, - 0, - 128, - }, - dictWord{17, 0, 52}, - dictWord{145, 0, 81}, - dictWord{132, 11, 674}, - dictWord{135, 0, 533}, - dictWord{149, 0, 6}, - dictWord{132, 11, 770}, - dictWord{ - 133, - 0, - 538, - }, - dictWord{5, 11, 79}, - dictWord{7, 11, 1027}, - dictWord{7, 11, 1477}, - dictWord{139, 11, 52}, - dictWord{139, 10, 62}, - dictWord{4, 0, 338}, - dictWord{ - 133, - 0, - 400, - }, - dictWord{5, 11, 789}, - dictWord{134, 11, 195}, - dictWord{4, 11, 251}, - dictWord{4, 11, 688}, - dictWord{7, 11, 513}, - dictWord{7, 11, 1284}, - dictWord{ - 9, - 11, - 87, - }, - dictWord{138, 11, 365}, - dictWord{134, 10, 1766}, - dictWord{6, 0, 0}, - dictWord{7, 0, 84}, - dictWord{11, 0, 895}, - dictWord{145, 0, 11}, - dictWord{ - 139, - 0, - 892, - }, - dictWord{4, 0, 221}, - dictWord{5, 0, 659}, - dictWord{7, 0, 697}, - dictWord{7, 0, 1211}, - dictWord{138, 0, 284}, - dictWord{133, 0, 989}, - dictWord{ - 133, - 11, - 889, - }, - dictWord{4, 11, 160}, - dictWord{5, 11, 330}, - dictWord{7, 11, 1434}, - dictWord{136, 11, 174}, - dictWord{6, 10, 1665}, - dictWord{7, 10, 256}, - dictWord{ - 7, - 10, - 1388, - }, - dictWord{10, 10, 499}, - dictWord{139, 10, 670}, - dictWord{7, 0, 848}, - dictWord{4, 10, 22}, - dictWord{5, 10, 10}, - dictWord{136, 10, 97}, - dictWord{ - 138, - 0, - 507, - }, - dictWord{133, 10, 481}, - dictWord{4, 0, 188}, - dictWord{135, 0, 805}, - dictWord{5, 0, 884}, - dictWord{6, 0, 732}, - dictWord{139, 0, 991}, - dictWord{ - 135, - 11, - 968, - }, - dictWord{11, 11, 636}, - dictWord{15, 11, 145}, - dictWord{17, 11, 34}, - dictWord{19, 11, 50}, - dictWord{151, 11, 20}, - dictWord{7, 0, 959}, - dictWord{ - 16, - 0, - 60, - }, - dictWord{6, 10, 134}, - dictWord{7, 10, 437}, - dictWord{9, 10, 37}, - dictWord{14, 10, 285}, - dictWord{142, 10, 371}, - dictWord{7, 10, 486}, - dictWord{ - 8, - 10, - 155, - }, - dictWord{11, 10, 93}, - dictWord{140, 10, 164}, - dictWord{134, 0, 1653}, - dictWord{7, 0, 337}, - dictWord{133, 10, 591}, - dictWord{6, 0, 1989}, - dictWord{ - 8, - 0, - 922, - }, - dictWord{8, 0, 978}, - dictWord{133, 11, 374}, - dictWord{132, 0, 638}, - dictWord{138, 0, 500}, - dictWord{133, 11, 731}, - dictWord{5, 10, 380}, - dictWord{ - 5, - 10, - 650, - }, - dictWord{136, 10, 310}, - dictWord{138, 11, 381}, - dictWord{4, 10, 364}, - dictWord{7, 10, 1156}, - dictWord{7, 10, 1187}, - dictWord{137, 10, 409}, - dictWord{137, 11, 224}, - dictWord{140, 0, 166}, - dictWord{134, 10, 482}, - dictWord{4, 11, 626}, - dictWord{5, 11, 642}, - dictWord{6, 11, 425}, - dictWord{ - 10, - 11, - 202, - }, - dictWord{139, 11, 141}, - dictWord{4, 10, 781}, - dictWord{6, 10, 487}, - dictWord{7, 10, 926}, - dictWord{8, 10, 263}, - dictWord{139, 10, 500}, - dictWord{ - 135, - 0, - 418, - }, - dictWord{4, 10, 94}, - dictWord{135, 10, 1265}, - dictWord{136, 0, 760}, - dictWord{132, 10, 417}, - dictWord{136, 11, 835}, - dictWord{5, 10, 348}, - dictWord{134, 10, 522}, - dictWord{6, 0, 1277}, - dictWord{134, 0, 1538}, - dictWord{139, 11, 541}, - dictWord{135, 11, 1597}, - dictWord{5, 11, 384}, - dictWord{ - 8, - 11, - 455, - }, - dictWord{140, 11, 48}, - dictWord{136, 0, 770}, - dictWord{5, 11, 264}, - dictWord{134, 11, 184}, - dictWord{4, 0, 89}, - dictWord{5, 0, 489}, - dictWord{ - 6, - 0, - 315, - }, - dictWord{7, 0, 553}, - dictWord{7, 0, 1745}, - dictWord{138, 0, 243}, - dictWord{4, 10, 408}, - dictWord{4, 10, 741}, - dictWord{135, 10, 500}, - dictWord{ - 134, - 0, - 1396, - }, - dictWord{133, 0, 560}, - dictWord{6, 0, 1658}, - dictWord{9, 0, 3}, - dictWord{10, 0, 154}, - dictWord{11, 0, 641}, - dictWord{13, 0, 85}, - dictWord{13, 0, 201}, - dictWord{141, 0, 346}, - dictWord{135, 11, 1595}, - dictWord{5, 11, 633}, - dictWord{6, 11, 28}, - dictWord{7, 11, 219}, - dictWord{135, 11, 1323}, - dictWord{ - 9, - 11, - 769, - }, - dictWord{140, 11, 185}, - dictWord{135, 11, 785}, - dictWord{7, 11, 359}, - dictWord{8, 11, 243}, - dictWord{140, 11, 175}, - dictWord{138, 0, 586}, - dictWord{ - 7, - 0, - 1271, - }, - dictWord{134, 10, 73}, - dictWord{132, 11, 105}, - dictWord{4, 0, 166}, - dictWord{5, 0, 505}, - dictWord{134, 0, 1670}, - dictWord{133, 10, 576}, - dictWord{4, 11, 324}, - dictWord{138, 11, 104}, - dictWord{142, 10, 231}, - dictWord{6, 0, 637}, - dictWord{7, 10, 1264}, - dictWord{7, 10, 1678}, - dictWord{ - 11, - 10, - 945, - }, - dictWord{12, 10, 341}, - dictWord{12, 10, 471}, - dictWord{12, 10, 569}, - dictWord{23, 11, 21}, - dictWord{151, 11, 23}, - dictWord{8, 11, 559}, - dictWord{ - 141, - 11, - 109, - }, - dictWord{134, 0, 1947}, - dictWord{7, 0, 445}, - dictWord{8, 0, 307}, - dictWord{8, 0, 704}, - dictWord{10, 0, 41}, - dictWord{10, 0, 439}, - dictWord{ - 11, - 0, - 237, - }, - dictWord{11, 0, 622}, - dictWord{140, 0, 201}, - dictWord{135, 11, 963}, - dictWord{135, 0, 1977}, - dictWord{4, 0, 189}, - dictWord{5, 0, 713}, - dictWord{ - 136, - 0, - 57, - }, - dictWord{138, 0, 371}, - dictWord{135, 10, 538}, - dictWord{132, 0, 552}, - dictWord{6, 0, 883}, - dictWord{133, 10, 413}, - dictWord{6, 0, 923}, - dictWord{ - 132, - 11, - 758, - }, - dictWord{138, 11, 215}, - dictWord{136, 10, 495}, - dictWord{7, 10, 54}, - dictWord{8, 10, 312}, - dictWord{10, 10, 191}, - dictWord{10, 10, 614}, - dictWord{140, 10, 567}, - dictWord{7, 11, 351}, - dictWord{139, 11, 128}, - dictWord{7, 0, 875}, - dictWord{6, 10, 468}, - dictWord{7, 10, 1478}, - dictWord{8, 10, 530}, - dictWord{142, 10, 290}, - dictWord{135, 0, 1788}, - dictWord{17, 0, 49}, - dictWord{133, 11, 918}, - dictWord{12, 11, 398}, - dictWord{20, 11, 39}, - dictWord{ - 21, - 11, - 11, - }, - dictWord{150, 11, 41}, - dictWord{10, 0, 661}, - dictWord{6, 10, 484}, - dictWord{135, 10, 822}, - dictWord{135, 0, 1945}, - dictWord{134, 0, 794}, - dictWord{ - 137, - 10, - 900, - }, - dictWord{135, 10, 1335}, - dictWord{6, 10, 1724}, - dictWord{135, 10, 2022}, - dictWord{132, 11, 340}, - dictWord{134, 0, 1135}, - dictWord{ - 4, - 0, - 784, - }, - dictWord{133, 0, 745}, - dictWord{5, 0, 84}, - dictWord{134, 0, 163}, - dictWord{133, 0, 410}, - dictWord{4, 0, 976}, - dictWord{5, 11, 985}, - dictWord{7, 11, 509}, - dictWord{7, 11, 529}, - dictWord{145, 11, 96}, - dictWord{132, 10, 474}, - dictWord{134, 0, 703}, - dictWord{135, 11, 1919}, - dictWord{5, 0, 322}, - dictWord{ - 8, - 0, - 186, - }, - dictWord{9, 0, 262}, - dictWord{10, 0, 187}, - dictWord{142, 0, 208}, - dictWord{135, 10, 1504}, - dictWord{133, 0, 227}, - dictWord{9, 0, 560}, - dictWord{ - 13, - 0, - 208, - }, - dictWord{133, 10, 305}, - dictWord{132, 11, 247}, - dictWord{7, 0, 1395}, - dictWord{8, 0, 486}, - dictWord{9, 0, 236}, - dictWord{9, 0, 878}, - dictWord{ - 10, - 0, - 218, - }, - dictWord{11, 0, 95}, - dictWord{19, 0, 17}, - dictWord{147, 0, 31}, - dictWord{7, 0, 2043}, - dictWord{8, 0, 672}, - dictWord{141, 0, 448}, - dictWord{4, 11, 184}, - dictWord{5, 11, 390}, - dictWord{6, 11, 337}, - dictWord{7, 11, 23}, - dictWord{7, 11, 494}, - dictWord{7, 11, 618}, - dictWord{7, 11, 1456}, - dictWord{8, 11, 27}, - dictWord{ - 8, - 11, - 599, - }, - dictWord{10, 11, 153}, - dictWord{139, 11, 710}, - dictWord{135, 0, 466}, - dictWord{135, 10, 1236}, - dictWord{6, 0, 167}, - dictWord{7, 0, 186}, - dictWord{7, 0, 656}, - dictWord{10, 0, 643}, - dictWord{4, 10, 480}, - dictWord{6, 10, 302}, - dictWord{6, 10, 1642}, - dictWord{7, 10, 837}, - dictWord{7, 10, 1547}, - dictWord{ - 7, - 10, - 1657, - }, - dictWord{8, 10, 429}, - dictWord{9, 10, 228}, - dictWord{13, 10, 289}, - dictWord{13, 10, 343}, - dictWord{147, 10, 101}, - dictWord{134, 0, 1428}, - dictWord{134, 0, 1440}, - dictWord{5, 0, 412}, - dictWord{7, 10, 278}, - dictWord{10, 10, 739}, - dictWord{11, 10, 708}, - dictWord{141, 10, 348}, - dictWord{ - 134, - 0, - 1118, - }, - dictWord{136, 0, 562}, - dictWord{148, 11, 46}, - dictWord{9, 0, 316}, - dictWord{139, 0, 256}, - dictWord{134, 0, 1771}, - dictWord{135, 0, 1190}, - dictWord{137, 0, 132}, - dictWord{10, 11, 227}, - dictWord{11, 11, 497}, - dictWord{11, 11, 709}, - dictWord{140, 11, 415}, - dictWord{143, 0, 66}, - dictWord{6, 11, 360}, - dictWord{7, 11, 1664}, - dictWord{136, 11, 478}, - dictWord{144, 10, 28}, - dictWord{4, 0, 317}, - dictWord{135, 0, 1279}, - dictWord{5, 0, 63}, - dictWord{ - 133, - 0, - 509, - }, - dictWord{136, 11, 699}, - dictWord{145, 10, 36}, - dictWord{134, 0, 1475}, - dictWord{11, 11, 343}, - dictWord{142, 11, 127}, - dictWord{132, 11, 739}, - dictWord{132, 0, 288}, - dictWord{135, 11, 1757}, - dictWord{8, 0, 89}, - dictWord{8, 0, 620}, - dictWord{9, 0, 608}, - dictWord{11, 0, 628}, - dictWord{12, 0, 322}, - dictWord{143, 0, 124}, - dictWord{134, 0, 1225}, - dictWord{7, 0, 1189}, - dictWord{4, 11, 67}, - dictWord{5, 11, 422}, - dictWord{6, 10, 363}, - dictWord{7, 11, 1037}, - dictWord{7, 11, 1289}, - dictWord{7, 11, 1555}, - dictWord{7, 10, 1955}, - dictWord{8, 10, 725}, - dictWord{9, 11, 741}, - dictWord{145, 11, 108}, - dictWord{ - 134, - 0, - 1468, - }, - dictWord{6, 0, 689}, - dictWord{134, 0, 1451}, - dictWord{138, 0, 120}, - dictWord{151, 0, 1}, - dictWord{137, 10, 805}, - dictWord{142, 0, 329}, - dictWord{ - 5, - 10, - 813, - }, - dictWord{135, 10, 2046}, - dictWord{135, 0, 226}, - dictWord{138, 11, 96}, - dictWord{7, 0, 1855}, - dictWord{5, 10, 712}, - dictWord{11, 10, 17}, - dictWord{13, 10, 321}, - dictWord{144, 10, 67}, - dictWord{9, 0, 461}, - dictWord{6, 10, 320}, - dictWord{7, 10, 781}, - dictWord{7, 10, 1921}, - dictWord{9, 10, 55}, - dictWord{ - 10, - 10, - 186, - }, - dictWord{10, 10, 273}, - dictWord{10, 10, 664}, - dictWord{10, 10, 801}, - dictWord{11, 10, 996}, - dictWord{11, 10, 997}, - dictWord{13, 10, 157}, - dictWord{142, 10, 170}, - dictWord{8, 11, 203}, - dictWord{8, 10, 271}, - dictWord{11, 11, 823}, - dictWord{11, 11, 846}, - dictWord{12, 11, 482}, - dictWord{ - 13, - 11, - 133, - }, - dictWord{13, 11, 277}, - dictWord{13, 11, 302}, - dictWord{13, 11, 464}, - dictWord{14, 11, 205}, - dictWord{142, 11, 221}, - dictWord{135, 0, 1346}, - dictWord{4, 11, 449}, - dictWord{133, 11, 718}, - dictWord{134, 0, 85}, - dictWord{14, 0, 299}, - dictWord{7, 10, 103}, - dictWord{7, 10, 863}, - dictWord{11, 10, 184}, - dictWord{145, 10, 62}, - dictWord{4, 11, 355}, - dictWord{6, 11, 311}, - dictWord{9, 11, 256}, - dictWord{138, 11, 404}, - dictWord{137, 10, 659}, - dictWord{ - 138, - 11, - 758, - }, - dictWord{133, 11, 827}, - dictWord{5, 11, 64}, - dictWord{140, 11, 581}, - dictWord{134, 0, 1171}, - dictWord{4, 11, 442}, - dictWord{7, 11, 1047}, - dictWord{ - 7, - 11, - 1352, - }, - dictWord{135, 11, 1643}, - dictWord{132, 0, 980}, - dictWord{5, 11, 977}, - dictWord{6, 11, 288}, - dictWord{7, 11, 528}, - dictWord{135, 11, 1065}, - dictWord{5, 0, 279}, - dictWord{6, 0, 235}, - dictWord{7, 0, 468}, - dictWord{8, 0, 446}, - dictWord{9, 0, 637}, - dictWord{10, 0, 717}, - dictWord{11, 0, 738}, - dictWord{ - 140, - 0, - 514, - }, - dictWord{132, 0, 293}, - dictWord{11, 10, 337}, - dictWord{142, 10, 303}, - dictWord{136, 11, 285}, - dictWord{5, 0, 17}, - dictWord{6, 0, 371}, - dictWord{ - 9, - 0, - 528, - }, - dictWord{12, 0, 364}, - dictWord{132, 11, 254}, - dictWord{5, 10, 77}, - dictWord{7, 10, 1455}, - dictWord{10, 10, 843}, - dictWord{147, 10, 73}, - dictWord{ - 150, - 0, - 5, - }, - dictWord{132, 10, 458}, - dictWord{6, 11, 12}, - dictWord{7, 11, 1219}, - dictWord{145, 11, 73}, - dictWord{135, 10, 1420}, - dictWord{6, 10, 109}, - dictWord{138, 10, 382}, - dictWord{135, 11, 125}, - dictWord{6, 10, 330}, - dictWord{7, 10, 1084}, - dictWord{139, 10, 142}, - dictWord{6, 11, 369}, - dictWord{ - 6, - 11, - 502, - }, - dictWord{7, 11, 1036}, - dictWord{8, 11, 348}, - dictWord{9, 11, 452}, - dictWord{10, 11, 26}, - dictWord{11, 11, 224}, - dictWord{11, 11, 387}, - dictWord{ - 11, - 11, - 772, - }, - dictWord{12, 11, 95}, - dictWord{12, 11, 629}, - dictWord{13, 11, 195}, - dictWord{13, 11, 207}, - dictWord{13, 11, 241}, - dictWord{14, 11, 260}, - dictWord{ - 14, - 11, - 270, - }, - dictWord{143, 11, 140}, - dictWord{132, 11, 269}, - dictWord{5, 11, 480}, - dictWord{7, 11, 532}, - dictWord{7, 11, 1197}, - dictWord{7, 11, 1358}, - dictWord{8, 11, 291}, - dictWord{11, 11, 349}, - dictWord{142, 11, 396}, - dictWord{150, 0, 48}, - dictWord{10, 0, 601}, - dictWord{13, 0, 353}, - dictWord{141, 0, 376}, - dictWord{5, 0, 779}, - dictWord{5, 0, 807}, - dictWord{6, 0, 1655}, - dictWord{134, 0, 1676}, - dictWord{142, 11, 223}, - dictWord{4, 0, 196}, - dictWord{5, 0, 558}, - dictWord{133, 0, 949}, - dictWord{148, 11, 15}, - dictWord{135, 11, 1764}, - dictWord{134, 0, 1322}, - dictWord{132, 0, 752}, - dictWord{139, 0, 737}, - dictWord{ - 135, - 11, - 657, - }, - dictWord{136, 11, 533}, - dictWord{135, 0, 412}, - dictWord{4, 0, 227}, - dictWord{5, 0, 159}, - dictWord{5, 0, 409}, - dictWord{7, 0, 80}, - dictWord{8, 0, 556}, - dictWord{10, 0, 479}, - dictWord{12, 0, 418}, - dictWord{14, 0, 50}, - dictWord{14, 0, 123}, - dictWord{14, 0, 192}, - dictWord{14, 0, 249}, - dictWord{14, 0, 295}, - dictWord{143, 0, 27}, - dictWord{7, 0, 1470}, - dictWord{8, 0, 66}, - dictWord{8, 0, 137}, - dictWord{8, 0, 761}, - dictWord{9, 0, 638}, - dictWord{11, 0, 80}, - dictWord{11, 0, 212}, - dictWord{11, 0, 368}, - dictWord{11, 0, 418}, - dictWord{12, 0, 8}, - dictWord{13, 0, 15}, - dictWord{16, 0, 61}, - dictWord{17, 0, 59}, - dictWord{19, 0, 28}, - dictWord{ - 148, - 0, - 84, - }, - dictWord{135, 10, 1985}, - dictWord{4, 11, 211}, - dictWord{4, 11, 332}, - dictWord{5, 11, 335}, - dictWord{6, 11, 238}, - dictWord{7, 11, 269}, - dictWord{ - 7, - 11, - 811, - }, - dictWord{7, 11, 1797}, - dictWord{8, 10, 122}, - dictWord{8, 11, 836}, - dictWord{9, 11, 507}, - dictWord{141, 11, 242}, - dictWord{6, 0, 683}, - dictWord{ - 134, - 0, - 1252, - }, - dictWord{4, 0, 873}, - dictWord{132, 10, 234}, - dictWord{134, 0, 835}, - dictWord{6, 0, 38}, - dictWord{7, 0, 1220}, - dictWord{8, 0, 185}, - dictWord{8, 0, 256}, - dictWord{9, 0, 22}, - dictWord{9, 0, 331}, - dictWord{10, 0, 738}, - dictWord{11, 0, 205}, - dictWord{11, 0, 540}, - dictWord{11, 0, 746}, - dictWord{13, 0, 465}, - dictWord{ - 14, - 0, - 88, - }, - dictWord{142, 0, 194}, - dictWord{138, 0, 986}, - dictWord{5, 11, 1009}, - dictWord{12, 11, 582}, - dictWord{146, 11, 131}, - dictWord{4, 0, 159}, - dictWord{ - 6, - 0, - 115, - }, - dictWord{7, 0, 252}, - dictWord{7, 0, 257}, - dictWord{7, 0, 1928}, - dictWord{8, 0, 69}, - dictWord{9, 0, 384}, - dictWord{10, 0, 91}, - dictWord{10, 0, 615}, - dictWord{ - 12, - 0, - 375, - }, - dictWord{14, 0, 235}, - dictWord{18, 0, 117}, - dictWord{147, 0, 123}, - dictWord{133, 0, 911}, - dictWord{136, 0, 278}, - dictWord{5, 10, 430}, - dictWord{ - 5, - 10, - 932, - }, - dictWord{6, 10, 131}, - dictWord{7, 10, 417}, - dictWord{9, 10, 522}, - dictWord{11, 10, 314}, - dictWord{141, 10, 390}, - dictWord{14, 10, 149}, - dictWord{14, 10, 399}, - dictWord{143, 10, 57}, - dictWord{4, 0, 151}, - dictWord{7, 0, 1567}, - dictWord{136, 0, 749}, - dictWord{5, 11, 228}, - dictWord{6, 11, 203}, - dictWord{ - 7, - 11, - 156, - }, - dictWord{8, 11, 347}, - dictWord{137, 11, 265}, - dictWord{132, 10, 507}, - dictWord{10, 0, 989}, - dictWord{140, 0, 956}, - dictWord{133, 0, 990}, - dictWord{5, 0, 194}, - dictWord{6, 0, 927}, - dictWord{7, 0, 1662}, - dictWord{9, 0, 90}, - dictWord{140, 0, 564}, - dictWord{4, 10, 343}, - dictWord{133, 10, 511}, - dictWord{133, 0, 425}, - dictWord{7, 10, 455}, - dictWord{138, 10, 591}, - dictWord{4, 0, 774}, - dictWord{7, 11, 476}, - dictWord{7, 11, 1592}, - dictWord{138, 11, 87}, - dictWord{5, 0, 971}, - dictWord{135, 10, 1381}, - dictWord{5, 11, 318}, - dictWord{147, 11, 121}, - dictWord{5, 11, 291}, - dictWord{7, 11, 765}, - dictWord{9, 11, 389}, - dictWord{140, 11, 548}, - dictWord{134, 10, 575}, - dictWord{4, 0, 827}, - dictWord{12, 0, 646}, - dictWord{12, 0, 705}, - dictWord{12, 0, 712}, - dictWord{140, 0, 714}, - dictWord{139, 0, 752}, - dictWord{137, 0, 662}, - dictWord{5, 0, 72}, - dictWord{6, 0, 264}, - dictWord{7, 0, 21}, - dictWord{7, 0, 46}, - dictWord{7, 0, 2013}, - dictWord{ - 8, - 0, - 215, - }, - dictWord{8, 0, 513}, - dictWord{10, 0, 266}, - dictWord{139, 0, 22}, - dictWord{139, 11, 522}, - dictWord{6, 0, 239}, - dictWord{7, 0, 118}, - dictWord{10, 0, 95}, - dictWord{11, 0, 603}, - dictWord{13, 0, 443}, - dictWord{14, 0, 160}, - dictWord{143, 0, 4}, - dictWord{6, 0, 431}, - dictWord{134, 0, 669}, - dictWord{7, 10, 1127}, - dictWord{ - 7, - 10, - 1572, - }, - dictWord{10, 10, 297}, - dictWord{10, 10, 422}, - dictWord{11, 10, 764}, - dictWord{11, 10, 810}, - dictWord{12, 10, 264}, - dictWord{13, 10, 102}, - dictWord{13, 10, 300}, - dictWord{13, 10, 484}, - dictWord{14, 10, 147}, - dictWord{14, 10, 229}, - dictWord{17, 10, 71}, - dictWord{18, 10, 118}, - dictWord{ - 147, - 10, - 120, - }, - dictWord{5, 0, 874}, - dictWord{6, 0, 1677}, - dictWord{15, 0, 0}, - dictWord{10, 11, 525}, - dictWord{139, 11, 82}, - dictWord{6, 0, 65}, - dictWord{7, 0, 939}, - dictWord{ - 7, - 0, - 1172, - }, - dictWord{7, 0, 1671}, - dictWord{9, 0, 540}, - dictWord{10, 0, 696}, - dictWord{11, 0, 265}, - dictWord{11, 0, 732}, - dictWord{11, 0, 928}, - dictWord{ - 11, - 0, - 937, - }, - dictWord{141, 0, 438}, - dictWord{134, 0, 1350}, - dictWord{136, 11, 547}, - dictWord{132, 11, 422}, - dictWord{5, 11, 355}, - dictWord{145, 11, 0}, - dictWord{137, 11, 905}, - dictWord{5, 0, 682}, - dictWord{135, 0, 1887}, - dictWord{132, 0, 809}, - dictWord{4, 0, 696}, - dictWord{133, 11, 865}, - dictWord{6, 0, 1074}, - dictWord{6, 0, 1472}, - dictWord{14, 10, 35}, - dictWord{142, 10, 191}, - dictWord{5, 11, 914}, - dictWord{134, 11, 1625}, - dictWord{133, 11, 234}, - dictWord{ - 135, - 11, - 1383, - }, - dictWord{137, 11, 780}, - dictWord{132, 10, 125}, - dictWord{4, 0, 726}, - dictWord{133, 0, 630}, - dictWord{8, 0, 802}, - dictWord{136, 0, 838}, - dictWord{132, 10, 721}, - dictWord{6, 0, 1337}, - dictWord{7, 0, 776}, - dictWord{19, 0, 56}, - dictWord{136, 10, 145}, - dictWord{132, 0, 970}, - dictWord{7, 10, 792}, - dictWord{8, 10, 147}, - dictWord{10, 10, 821}, - dictWord{139, 10, 1021}, - dictWord{139, 10, 970}, - dictWord{8, 0, 940}, - dictWord{137, 0, 797}, - dictWord{ - 135, - 11, - 1312, - }, - dictWord{9, 0, 248}, - dictWord{10, 0, 400}, - dictWord{7, 11, 816}, - dictWord{7, 11, 1241}, - dictWord{7, 10, 1999}, - dictWord{9, 11, 283}, - dictWord{ - 9, - 11, - 520, - }, - dictWord{10, 11, 213}, - dictWord{10, 11, 307}, - dictWord{10, 11, 463}, - dictWord{10, 11, 671}, - dictWord{10, 11, 746}, - dictWord{11, 11, 401}, - dictWord{ - 11, - 11, - 794, - }, - dictWord{12, 11, 517}, - dictWord{18, 11, 107}, - dictWord{147, 11, 115}, - dictWord{6, 0, 1951}, - dictWord{134, 0, 2040}, - dictWord{ - 135, - 11, - 339, - }, - dictWord{13, 0, 41}, - dictWord{15, 0, 93}, - dictWord{5, 10, 168}, - dictWord{5, 10, 930}, - dictWord{8, 10, 74}, - dictWord{9, 10, 623}, - dictWord{12, 10, 500}, - dictWord{140, 10, 579}, - dictWord{6, 0, 118}, - dictWord{7, 0, 215}, - dictWord{7, 0, 1521}, - dictWord{140, 0, 11}, - dictWord{6, 10, 220}, - dictWord{7, 10, 1101}, - dictWord{141, 10, 105}, - dictWord{6, 11, 421}, - dictWord{7, 11, 61}, - dictWord{7, 11, 1540}, - dictWord{10, 11, 11}, - dictWord{138, 11, 501}, - dictWord{7, 0, 615}, - dictWord{138, 0, 251}, - dictWord{140, 11, 631}, - dictWord{135, 0, 1044}, - dictWord{6, 10, 19}, - dictWord{7, 10, 1413}, - dictWord{139, 10, 428}, - dictWord{ - 133, - 0, - 225, - }, - dictWord{7, 10, 96}, - dictWord{8, 10, 401}, - dictWord{8, 10, 703}, - dictWord{137, 10, 896}, - dictWord{145, 10, 116}, - dictWord{6, 11, 102}, - dictWord{ - 7, - 11, - 72, - }, - dictWord{15, 11, 142}, - dictWord{147, 11, 67}, - dictWord{7, 10, 1961}, - dictWord{7, 10, 1965}, - dictWord{8, 10, 702}, - dictWord{136, 10, 750}, - dictWord{ - 7, - 10, - 2030, - }, - dictWord{8, 10, 150}, - dictWord{8, 10, 737}, - dictWord{12, 10, 366}, - dictWord{151, 11, 30}, - dictWord{4, 0, 370}, - dictWord{5, 0, 756}, - dictWord{ - 7, - 0, - 1326, - }, - dictWord{135, 11, 823}, - dictWord{8, 10, 800}, - dictWord{9, 10, 148}, - dictWord{9, 10, 872}, - dictWord{9, 10, 890}, - dictWord{11, 10, 309}, - dictWord{ - 11, - 10, - 1001, - }, - dictWord{13, 10, 267}, - dictWord{141, 10, 323}, - dictWord{6, 0, 1662}, - dictWord{7, 0, 48}, - dictWord{8, 0, 771}, - dictWord{10, 0, 116}, - dictWord{ - 13, - 0, - 104, - }, - dictWord{14, 0, 105}, - dictWord{14, 0, 184}, - dictWord{15, 0, 168}, - dictWord{19, 0, 92}, - dictWord{148, 0, 68}, - dictWord{10, 0, 209}, - dictWord{ - 135, - 11, - 1870, - }, - dictWord{7, 11, 68}, - dictWord{8, 11, 48}, - dictWord{8, 11, 88}, - dictWord{8, 11, 582}, - dictWord{8, 11, 681}, - dictWord{9, 11, 373}, - dictWord{9, 11, 864}, - dictWord{11, 11, 157}, - dictWord{11, 11, 336}, - dictWord{11, 11, 843}, - dictWord{148, 11, 27}, - dictWord{134, 0, 930}, - dictWord{4, 11, 88}, - dictWord{5, 11, 137}, - dictWord{5, 11, 174}, - dictWord{5, 11, 777}, - dictWord{6, 11, 1664}, - dictWord{6, 11, 1725}, - dictWord{7, 11, 77}, - dictWord{7, 11, 426}, - dictWord{7, 11, 1317}, - dictWord{7, 11, 1355}, - dictWord{8, 11, 126}, - dictWord{8, 11, 563}, - dictWord{9, 11, 523}, - dictWord{9, 11, 750}, - dictWord{10, 11, 310}, - dictWord{10, 11, 836}, - dictWord{11, 11, 42}, - dictWord{11, 11, 318}, - dictWord{11, 11, 731}, - dictWord{12, 11, 68}, - dictWord{12, 11, 92}, - dictWord{12, 11, 507}, - dictWord{12, 11, 692}, - dictWord{13, 11, 81}, - dictWord{13, 11, 238}, - dictWord{13, 11, 374}, - dictWord{18, 11, 138}, - dictWord{19, 11, 78}, - dictWord{19, 11, 111}, - dictWord{20, 11, 55}, - dictWord{20, 11, 77}, - dictWord{148, 11, 92}, - dictWord{4, 11, 938}, - dictWord{135, 11, 1831}, - dictWord{5, 10, 547}, - dictWord{7, 10, 424}, - dictWord{ - 8, - 11, - 617, - }, - dictWord{138, 11, 351}, - dictWord{6, 0, 1286}, - dictWord{6, 11, 1668}, - dictWord{7, 11, 1499}, - dictWord{8, 11, 117}, - dictWord{9, 11, 314}, - dictWord{ - 138, - 11, - 174, - }, - dictWord{6, 0, 759}, - dictWord{6, 0, 894}, - dictWord{7, 11, 707}, - dictWord{139, 11, 563}, - dictWord{4, 0, 120}, - dictWord{135, 0, 1894}, - dictWord{ - 9, - 0, - 385, - }, - dictWord{149, 0, 17}, - dictWord{138, 0, 429}, - dictWord{133, 11, 403}, - dictWord{5, 0, 820}, - dictWord{135, 0, 931}, - dictWord{10, 0, 199}, - dictWord{ - 133, - 10, - 133, - }, - dictWord{6, 0, 151}, - dictWord{6, 0, 1675}, - dictWord{7, 0, 383}, - dictWord{151, 0, 10}, - dictWord{6, 0, 761}, - dictWord{136, 10, 187}, - dictWord{ - 8, - 0, - 365, - }, - dictWord{10, 10, 0}, - dictWord{10, 10, 818}, - dictWord{139, 10, 988}, - dictWord{4, 11, 44}, - dictWord{5, 11, 311}, - dictWord{6, 11, 156}, - dictWord{ - 7, - 11, - 639, - }, - dictWord{7, 11, 762}, - dictWord{7, 11, 1827}, - dictWord{9, 11, 8}, - dictWord{9, 11, 462}, - dictWord{148, 11, 83}, - dictWord{4, 11, 346}, - dictWord{7, 11, 115}, - dictWord{9, 11, 180}, - dictWord{9, 11, 456}, - dictWord{138, 11, 363}, - dictWord{136, 10, 685}, - dictWord{7, 0, 1086}, - dictWord{145, 0, 46}, - dictWord{ - 6, - 0, - 1624, - }, - dictWord{11, 0, 11}, - dictWord{12, 0, 422}, - dictWord{13, 0, 444}, - dictWord{142, 0, 360}, - dictWord{6, 0, 1020}, - dictWord{6, 0, 1260}, - dictWord{ - 134, - 0, - 1589, - }, - dictWord{4, 0, 43}, - dictWord{5, 0, 344}, - dictWord{5, 0, 357}, - dictWord{14, 0, 472}, - dictWord{150, 0, 58}, - dictWord{6, 0, 1864}, - dictWord{6, 0, 1866}, - dictWord{6, 0, 1868}, - dictWord{6, 0, 1869}, - dictWord{6, 0, 1874}, - dictWord{6, 0, 1877}, - dictWord{6, 0, 1903}, - dictWord{6, 0, 1911}, - dictWord{9, 0, 920}, - dictWord{ - 9, - 0, - 921, - }, - dictWord{9, 0, 924}, - dictWord{9, 0, 946}, - dictWord{9, 0, 959}, - dictWord{9, 0, 963}, - dictWord{9, 0, 970}, - dictWord{9, 0, 997}, - dictWord{9, 0, 1008}, - dictWord{ - 9, - 0, - 1017, - }, - dictWord{12, 0, 795}, - dictWord{12, 0, 797}, - dictWord{12, 0, 798}, - dictWord{12, 0, 800}, - dictWord{12, 0, 803}, - dictWord{12, 0, 811}, - dictWord{ - 12, - 0, - 820, - }, - dictWord{12, 0, 821}, - dictWord{12, 0, 839}, - dictWord{12, 0, 841}, - dictWord{12, 0, 848}, - dictWord{12, 0, 911}, - dictWord{12, 0, 921}, - dictWord{12, 0, 922}, - dictWord{12, 0, 925}, - dictWord{12, 0, 937}, - dictWord{12, 0, 944}, - dictWord{12, 0, 945}, - dictWord{12, 0, 953}, - dictWord{15, 0, 184}, - dictWord{15, 0, 191}, - dictWord{15, 0, 199}, - dictWord{15, 0, 237}, - dictWord{15, 0, 240}, - dictWord{15, 0, 243}, - dictWord{15, 0, 246}, - dictWord{18, 0, 203}, - dictWord{21, 0, 40}, - dictWord{ - 21, - 0, - 52, - }, - dictWord{21, 0, 57}, - dictWord{24, 0, 23}, - dictWord{24, 0, 28}, - dictWord{152, 0, 30}, - dictWord{134, 0, 725}, - dictWord{145, 11, 58}, - dictWord{133, 0, 888}, - dictWord{137, 10, 874}, - dictWord{4, 0, 711}, - dictWord{8, 10, 774}, - dictWord{10, 10, 670}, - dictWord{140, 10, 51}, - dictWord{144, 11, 40}, - dictWord{ - 6, - 11, - 185, - }, - dictWord{7, 11, 1899}, - dictWord{139, 11, 673}, - dictWord{137, 10, 701}, - dictWord{137, 0, 440}, - dictWord{4, 11, 327}, - dictWord{5, 11, 478}, - dictWord{ - 7, - 11, - 1332, - }, - dictWord{8, 11, 753}, - dictWord{140, 11, 227}, - dictWord{4, 10, 127}, - dictWord{5, 10, 350}, - dictWord{6, 10, 356}, - dictWord{8, 10, 426}, - dictWord{ - 9, - 10, - 572, - }, - dictWord{10, 10, 247}, - dictWord{139, 10, 312}, - dictWord{5, 11, 1020}, - dictWord{133, 11, 1022}, - dictWord{4, 11, 103}, - dictWord{ - 133, - 11, - 401, - }, - dictWord{6, 0, 1913}, - dictWord{6, 0, 1926}, - dictWord{6, 0, 1959}, - dictWord{9, 0, 914}, - dictWord{9, 0, 939}, - dictWord{9, 0, 952}, - dictWord{9, 0, 979}, - dictWord{ - 9, - 0, - 990, - }, - dictWord{9, 0, 998}, - dictWord{9, 0, 1003}, - dictWord{9, 0, 1023}, - dictWord{12, 0, 827}, - dictWord{12, 0, 834}, - dictWord{12, 0, 845}, - dictWord{ - 12, - 0, - 912, - }, - dictWord{12, 0, 935}, - dictWord{12, 0, 951}, - dictWord{15, 0, 172}, - dictWord{15, 0, 174}, - dictWord{18, 0, 198}, - dictWord{149, 0, 63}, - dictWord{5, 0, 958}, - dictWord{5, 0, 987}, - dictWord{4, 11, 499}, - dictWord{135, 11, 1421}, - dictWord{7, 0, 885}, - dictWord{6, 10, 59}, - dictWord{6, 10, 1762}, - dictWord{9, 10, 603}, - dictWord{141, 10, 397}, - dictWord{10, 11, 62}, - dictWord{141, 11, 164}, - dictWord{4, 0, 847}, - dictWord{135, 0, 326}, - dictWord{11, 0, 276}, - dictWord{142, 0, 293}, - dictWord{4, 0, 65}, - dictWord{5, 0, 479}, - dictWord{5, 0, 1004}, - dictWord{7, 0, 1913}, - dictWord{8, 0, 317}, - dictWord{9, 0, 302}, - dictWord{10, 0, 612}, - dictWord{ - 13, - 0, - 22, - }, - dictWord{132, 11, 96}, - dictWord{4, 0, 261}, - dictWord{135, 0, 510}, - dictWord{135, 0, 1514}, - dictWord{6, 10, 111}, - dictWord{7, 10, 4}, - dictWord{8, 10, 163}, - dictWord{8, 10, 776}, - dictWord{138, 10, 566}, - dictWord{4, 0, 291}, - dictWord{9, 0, 515}, - dictWord{12, 0, 152}, - dictWord{12, 0, 443}, - dictWord{13, 0, 392}, - dictWord{142, 0, 357}, - dictWord{7, 11, 399}, - dictWord{135, 11, 1492}, - dictWord{4, 0, 589}, - dictWord{139, 0, 282}, - dictWord{6, 11, 563}, - dictWord{ - 135, - 10, - 1994, - }, - dictWord{5, 10, 297}, - dictWord{135, 10, 1038}, - dictWord{4, 0, 130}, - dictWord{7, 0, 843}, - dictWord{135, 0, 1562}, - dictWord{5, 0, 42}, - dictWord{ - 5, - 0, - 879, - }, - dictWord{7, 0, 245}, - dictWord{7, 0, 324}, - dictWord{7, 0, 1532}, - dictWord{11, 0, 463}, - dictWord{11, 0, 472}, - dictWord{13, 0, 363}, - dictWord{144, 0, 52}, - dictWord{4, 0, 134}, - dictWord{133, 0, 372}, - dictWord{133, 0, 680}, - dictWord{136, 10, 363}, - dictWord{6, 0, 1997}, - dictWord{8, 0, 935}, - dictWord{136, 0, 977}, - dictWord{4, 0, 810}, - dictWord{135, 0, 1634}, - dictWord{135, 10, 1675}, - dictWord{7, 0, 1390}, - dictWord{4, 11, 910}, - dictWord{133, 11, 832}, - dictWord{ - 7, - 10, - 808, - }, - dictWord{8, 11, 266}, - dictWord{139, 11, 578}, - dictWord{132, 0, 644}, - dictWord{4, 0, 982}, - dictWord{138, 0, 867}, - dictWord{132, 10, 280}, - dictWord{ - 135, - 0, - 540, - }, - dictWord{140, 10, 54}, - dictWord{135, 0, 123}, - dictWord{134, 0, 1978}, - dictWord{4, 10, 421}, - dictWord{133, 10, 548}, - dictWord{6, 0, 623}, - dictWord{136, 0, 789}, - dictWord{4, 0, 908}, - dictWord{5, 0, 359}, - dictWord{5, 0, 508}, - dictWord{6, 0, 1723}, - dictWord{7, 0, 343}, - dictWord{7, 0, 1996}, - dictWord{ - 135, - 0, - 2026, - }, - dictWord{134, 0, 1220}, - dictWord{4, 0, 341}, - dictWord{135, 0, 480}, - dictWord{6, 10, 254}, - dictWord{9, 10, 109}, - dictWord{138, 10, 103}, - dictWord{ - 134, - 0, - 888, - }, - dictWord{8, 11, 528}, - dictWord{137, 11, 348}, - dictWord{7, 0, 1995}, - dictWord{8, 0, 299}, - dictWord{11, 0, 890}, - dictWord{12, 0, 674}, - dictWord{ - 4, - 11, - 20, - }, - dictWord{133, 11, 616}, - dictWord{135, 11, 1094}, - dictWord{134, 10, 1630}, - dictWord{4, 0, 238}, - dictWord{5, 0, 503}, - dictWord{6, 0, 179}, - dictWord{ - 7, - 0, - 2003, - }, - dictWord{8, 0, 381}, - dictWord{8, 0, 473}, - dictWord{9, 0, 149}, - dictWord{10, 0, 788}, - dictWord{15, 0, 45}, - dictWord{15, 0, 86}, - dictWord{20, 0, 110}, - dictWord{150, 0, 57}, - dictWord{133, 10, 671}, - dictWord{4, 11, 26}, - dictWord{5, 11, 429}, - dictWord{6, 11, 245}, - dictWord{7, 11, 704}, - dictWord{7, 11, 1379}, - dictWord{135, 11, 1474}, - dictWord{4, 0, 121}, - dictWord{5, 0, 156}, - dictWord{5, 0, 349}, - dictWord{9, 0, 431}, - dictWord{10, 0, 605}, - dictWord{142, 0, 342}, - dictWord{ - 7, - 11, - 943, - }, - dictWord{139, 11, 614}, - dictWord{132, 10, 889}, - dictWord{132, 11, 621}, - dictWord{7, 10, 1382}, - dictWord{7, 11, 1382}, - dictWord{ - 135, - 10, - 1910, - }, - dictWord{132, 10, 627}, - dictWord{133, 10, 775}, - dictWord{133, 11, 542}, - dictWord{133, 11, 868}, - dictWord{136, 11, 433}, - dictWord{6, 0, 1373}, - dictWord{7, 0, 1011}, - dictWord{11, 10, 362}, - dictWord{11, 10, 948}, - dictWord{140, 10, 388}, - dictWord{6, 0, 80}, - dictWord{7, 0, 173}, - dictWord{9, 0, 547}, - dictWord{10, 0, 730}, - dictWord{14, 0, 18}, - dictWord{22, 0, 39}, - dictWord{135, 11, 1495}, - dictWord{6, 0, 1694}, - dictWord{135, 0, 1974}, - dictWord{140, 0, 196}, - dictWord{4, 0, 923}, - dictWord{6, 0, 507}, - dictWord{6, 0, 1711}, - dictWord{7, 10, 451}, - dictWord{8, 10, 389}, - dictWord{12, 10, 490}, - dictWord{13, 10, 16}, - dictWord{ - 13, - 10, - 215, - }, - dictWord{13, 10, 351}, - dictWord{18, 10, 132}, - dictWord{147, 10, 125}, - dictWord{6, 0, 646}, - dictWord{134, 0, 1047}, - dictWord{135, 10, 841}, - dictWord{136, 10, 566}, - dictWord{6, 0, 1611}, - dictWord{135, 0, 1214}, - dictWord{139, 0, 926}, - dictWord{132, 11, 525}, - dictWord{132, 0, 595}, - dictWord{ - 5, - 0, - 240, - }, - dictWord{6, 0, 459}, - dictWord{7, 0, 12}, - dictWord{7, 0, 114}, - dictWord{7, 0, 949}, - dictWord{7, 0, 1753}, - dictWord{7, 0, 1805}, - dictWord{8, 0, 658}, - dictWord{ - 9, - 0, - 1, - }, - dictWord{11, 0, 959}, - dictWord{141, 0, 446}, - dictWord{5, 10, 912}, - dictWord{134, 10, 1695}, - dictWord{132, 0, 446}, - dictWord{7, 11, 62}, - dictWord{ - 12, - 11, - 45, - }, - dictWord{147, 11, 112}, - dictWord{5, 10, 236}, - dictWord{6, 10, 572}, - dictWord{8, 10, 492}, - dictWord{11, 10, 618}, - dictWord{144, 10, 56}, - dictWord{ - 5, - 10, - 190, - }, - dictWord{136, 10, 318}, - dictWord{135, 10, 1376}, - dictWord{4, 11, 223}, - dictWord{6, 11, 359}, - dictWord{11, 11, 3}, - dictWord{13, 11, 108}, - dictWord{ - 14, - 11, - 89, - }, - dictWord{144, 11, 22}, - dictWord{132, 11, 647}, - dictWord{134, 0, 490}, - dictWord{134, 0, 491}, - dictWord{134, 0, 1584}, - dictWord{ - 135, - 11, - 685, - }, - dictWord{138, 11, 220}, - dictWord{7, 0, 250}, - dictWord{136, 0, 507}, - dictWord{132, 0, 158}, - dictWord{4, 0, 140}, - dictWord{7, 0, 362}, - dictWord{8, 0, 209}, - dictWord{9, 0, 10}, - dictWord{9, 0, 160}, - dictWord{9, 0, 503}, - dictWord{9, 0, 614}, - dictWord{10, 0, 689}, - dictWord{11, 0, 327}, - dictWord{11, 0, 553}, - dictWord{ - 11, - 0, - 725, - }, - dictWord{11, 0, 767}, - dictWord{12, 0, 252}, - dictWord{12, 0, 583}, - dictWord{13, 0, 192}, - dictWord{14, 0, 269}, - dictWord{14, 0, 356}, - dictWord{148, 0, 50}, - dictWord{19, 0, 1}, - dictWord{19, 0, 26}, - dictWord{150, 0, 9}, - dictWord{132, 11, 109}, - dictWord{6, 0, 228}, - dictWord{7, 0, 1341}, - dictWord{9, 0, 408}, - dictWord{ - 138, - 0, - 343, - }, - dictWord{4, 0, 373}, - dictWord{5, 0, 283}, - dictWord{6, 0, 480}, - dictWord{7, 0, 609}, - dictWord{10, 0, 860}, - dictWord{138, 0, 878}, - dictWord{6, 0, 779}, - dictWord{134, 0, 1209}, - dictWord{4, 0, 557}, - dictWord{7, 11, 263}, - dictWord{7, 11, 628}, - dictWord{136, 11, 349}, - dictWord{132, 0, 548}, - dictWord{7, 0, 197}, - dictWord{8, 0, 142}, - dictWord{8, 0, 325}, - dictWord{9, 0, 150}, - dictWord{9, 0, 596}, - dictWord{10, 0, 350}, - dictWord{10, 0, 353}, - dictWord{11, 0, 74}, - dictWord{ - 11, - 0, - 315, - }, - dictWord{12, 0, 662}, - dictWord{12, 0, 681}, - dictWord{14, 0, 423}, - dictWord{143, 0, 141}, - dictWord{4, 11, 40}, - dictWord{10, 11, 67}, - dictWord{ - 11, - 11, - 117, - }, - dictWord{11, 11, 768}, - dictWord{139, 11, 935}, - dictWord{7, 11, 992}, - dictWord{8, 11, 301}, - dictWord{9, 11, 722}, - dictWord{12, 11, 63}, - dictWord{ - 13, - 11, - 29, - }, - dictWord{14, 11, 161}, - dictWord{143, 11, 18}, - dictWord{6, 0, 1490}, - dictWord{138, 11, 532}, - dictWord{5, 0, 580}, - dictWord{7, 0, 378}, - dictWord{ - 7, - 0, - 674, - }, - dictWord{7, 0, 1424}, - dictWord{15, 0, 83}, - dictWord{16, 0, 11}, - dictWord{15, 11, 83}, - dictWord{144, 11, 11}, - dictWord{6, 0, 1057}, - dictWord{6, 0, 1335}, - dictWord{10, 0, 316}, - dictWord{7, 10, 85}, - dictWord{7, 10, 247}, - dictWord{8, 10, 585}, - dictWord{138, 10, 163}, - dictWord{4, 0, 169}, - dictWord{5, 0, 83}, - dictWord{ - 6, - 0, - 399, - }, - dictWord{6, 0, 579}, - dictWord{6, 0, 1513}, - dictWord{7, 0, 692}, - dictWord{7, 0, 846}, - dictWord{7, 0, 1015}, - dictWord{7, 0, 1799}, - dictWord{8, 0, 403}, - dictWord{9, 0, 394}, - dictWord{10, 0, 133}, - dictWord{12, 0, 4}, - dictWord{12, 0, 297}, - dictWord{12, 0, 452}, - dictWord{16, 0, 81}, - dictWord{18, 0, 25}, - dictWord{21, 0, 14}, - dictWord{22, 0, 12}, - dictWord{151, 0, 18}, - dictWord{134, 0, 1106}, - dictWord{7, 0, 1546}, - dictWord{11, 0, 299}, - dictWord{142, 0, 407}, - dictWord{134, 0, 1192}, - dictWord{132, 0, 177}, - dictWord{5, 0, 411}, - dictWord{135, 0, 653}, - dictWord{7, 0, 439}, - dictWord{10, 0, 727}, - dictWord{11, 0, 260}, - dictWord{139, 0, 684}, - dictWord{138, 10, 145}, - dictWord{147, 10, 83}, - dictWord{5, 0, 208}, - dictWord{7, 0, 753}, - dictWord{135, 0, 1528}, - dictWord{137, 11, 617}, - dictWord{ - 135, - 10, - 1922, - }, - dictWord{135, 11, 825}, - dictWord{11, 0, 422}, - dictWord{13, 0, 389}, - dictWord{4, 10, 124}, - dictWord{10, 10, 457}, - dictWord{11, 10, 121}, - dictWord{ - 11, - 10, - 169, - }, - dictWord{11, 10, 870}, - dictWord{12, 10, 214}, - dictWord{14, 10, 187}, - dictWord{143, 10, 77}, - dictWord{11, 0, 615}, - dictWord{15, 0, 58}, - dictWord{ - 11, - 11, - 615, - }, - dictWord{143, 11, 58}, - dictWord{9, 0, 618}, - dictWord{138, 0, 482}, - dictWord{6, 0, 1952}, - dictWord{6, 0, 1970}, - dictWord{142, 0, 505}, - dictWord{ - 7, - 10, - 1193, - }, - dictWord{135, 11, 1838}, - dictWord{133, 0, 242}, - dictWord{135, 10, 1333}, - dictWord{6, 10, 107}, - dictWord{7, 10, 638}, - dictWord{ - 7, - 10, - 1632, - }, - dictWord{137, 10, 396}, - dictWord{133, 0, 953}, - dictWord{5, 10, 370}, - dictWord{134, 10, 1756}, - dictWord{5, 11, 28}, - dictWord{6, 11, 204}, - dictWord{ - 10, - 11, - 320, - }, - dictWord{10, 11, 583}, - dictWord{13, 11, 502}, - dictWord{14, 11, 72}, - dictWord{14, 11, 274}, - dictWord{14, 11, 312}, - dictWord{14, 11, 344}, - dictWord{15, 11, 159}, - dictWord{16, 11, 62}, - dictWord{16, 11, 69}, - dictWord{17, 11, 30}, - dictWord{18, 11, 42}, - dictWord{18, 11, 53}, - dictWord{18, 11, 84}, - dictWord{18, 11, 140}, - dictWord{19, 11, 68}, - dictWord{19, 11, 85}, - dictWord{20, 11, 5}, - dictWord{20, 11, 45}, - dictWord{20, 11, 101}, - dictWord{22, 11, 7}, - dictWord{ - 150, - 11, - 20, - }, - dictWord{4, 11, 558}, - dictWord{6, 11, 390}, - dictWord{7, 11, 162}, - dictWord{7, 11, 689}, - dictWord{9, 11, 360}, - dictWord{138, 11, 653}, - dictWord{ - 11, - 0, - 802, - }, - dictWord{141, 0, 67}, - dictWord{133, 10, 204}, - dictWord{133, 0, 290}, - dictWord{5, 10, 970}, - dictWord{134, 10, 1706}, - dictWord{132, 0, 380}, - dictWord{5, 0, 52}, - dictWord{7, 0, 277}, - dictWord{9, 0, 368}, - dictWord{139, 0, 791}, - dictWord{5, 11, 856}, - dictWord{6, 11, 1672}, - dictWord{6, 11, 1757}, - dictWord{ - 6, - 11, - 1781, - }, - dictWord{7, 11, 1150}, - dictWord{7, 11, 1425}, - dictWord{7, 11, 1453}, - dictWord{140, 11, 513}, - dictWord{5, 11, 92}, - dictWord{7, 10, 3}, - dictWord{ - 10, - 11, - 736, - }, - dictWord{140, 11, 102}, - dictWord{4, 0, 112}, - dictWord{5, 0, 653}, - dictWord{5, 10, 483}, - dictWord{5, 10, 685}, - dictWord{6, 10, 489}, - dictWord{ - 7, - 10, - 1204, - }, - dictWord{136, 10, 394}, - dictWord{132, 10, 921}, - dictWord{6, 0, 1028}, - dictWord{133, 10, 1007}, - dictWord{5, 11, 590}, - dictWord{9, 11, 213}, - dictWord{145, 11, 91}, - dictWord{135, 10, 1696}, - dictWord{10, 0, 138}, - dictWord{139, 0, 476}, - dictWord{5, 0, 725}, - dictWord{5, 0, 727}, - dictWord{135, 0, 1811}, - dictWord{4, 0, 979}, - dictWord{6, 0, 1821}, - dictWord{6, 0, 1838}, - dictWord{8, 0, 876}, - dictWord{8, 0, 883}, - dictWord{8, 0, 889}, - dictWord{8, 0, 893}, - dictWord{ - 8, - 0, - 895, - }, - dictWord{10, 0, 934}, - dictWord{12, 0, 720}, - dictWord{14, 0, 459}, - dictWord{148, 0, 123}, - dictWord{135, 11, 551}, - dictWord{4, 0, 38}, - dictWord{6, 0, 435}, - dictWord{7, 0, 307}, - dictWord{7, 0, 999}, - dictWord{7, 0, 1481}, - dictWord{7, 0, 1732}, - dictWord{7, 0, 1738}, - dictWord{8, 0, 371}, - dictWord{9, 0, 414}, - dictWord{ - 11, - 0, - 316, - }, - dictWord{12, 0, 52}, - dictWord{13, 0, 420}, - dictWord{147, 0, 100}, - dictWord{135, 0, 1296}, - dictWord{132, 10, 712}, - dictWord{134, 10, 1629}, - dictWord{133, 0, 723}, - dictWord{134, 0, 651}, - dictWord{136, 11, 191}, - dictWord{9, 11, 791}, - dictWord{10, 11, 93}, - dictWord{11, 11, 301}, - dictWord{16, 11, 13}, - dictWord{17, 11, 23}, - dictWord{18, 11, 135}, - dictWord{19, 11, 12}, - dictWord{20, 11, 1}, - dictWord{20, 11, 12}, - dictWord{148, 11, 14}, - dictWord{136, 11, 503}, - dictWord{6, 11, 466}, - dictWord{135, 11, 671}, - dictWord{6, 0, 1200}, - dictWord{134, 0, 1330}, - dictWord{135, 0, 1255}, - dictWord{134, 0, 986}, - dictWord{ - 5, - 0, - 109, - }, - dictWord{6, 0, 1784}, - dictWord{7, 0, 1895}, - dictWord{12, 0, 296}, - dictWord{140, 0, 302}, - dictWord{135, 11, 983}, - dictWord{133, 10, 485}, - dictWord{ - 134, - 0, - 660, - }, - dictWord{134, 0, 800}, - dictWord{5, 0, 216}, - dictWord{5, 0, 294}, - dictWord{6, 0, 591}, - dictWord{7, 0, 1879}, - dictWord{9, 0, 141}, - dictWord{9, 0, 270}, - dictWord{9, 0, 679}, - dictWord{10, 0, 159}, - dictWord{11, 0, 197}, - dictWord{11, 0, 438}, - dictWord{12, 0, 538}, - dictWord{12, 0, 559}, - dictWord{14, 0, 144}, - dictWord{ - 14, - 0, - 167, - }, - dictWord{15, 0, 67}, - dictWord{4, 10, 285}, - dictWord{5, 10, 317}, - dictWord{6, 10, 301}, - dictWord{7, 10, 7}, - dictWord{8, 10, 153}, - dictWord{ - 10, - 10, - 766, - }, - dictWord{11, 10, 468}, - dictWord{12, 10, 467}, - dictWord{141, 10, 143}, - dictWord{136, 0, 945}, - dictWord{134, 0, 1090}, - dictWord{137, 0, 81}, - dictWord{12, 11, 468}, - dictWord{19, 11, 96}, - dictWord{148, 11, 24}, - dictWord{134, 0, 391}, - dictWord{138, 11, 241}, - dictWord{7, 0, 322}, - dictWord{136, 0, 249}, - dictWord{134, 0, 1412}, - dictWord{135, 11, 795}, - dictWord{5, 0, 632}, - dictWord{138, 0, 526}, - dictWord{136, 10, 819}, - dictWord{6, 0, 144}, - dictWord{7, 0, 948}, - dictWord{7, 0, 1042}, - dictWord{8, 0, 235}, - dictWord{8, 0, 461}, - dictWord{9, 0, 453}, - dictWord{9, 0, 796}, - dictWord{10, 0, 354}, - dictWord{17, 0, 77}, - dictWord{ - 135, - 11, - 954, - }, - dictWord{139, 10, 917}, - dictWord{6, 0, 940}, - dictWord{134, 0, 1228}, - dictWord{4, 0, 362}, - dictWord{7, 0, 52}, - dictWord{135, 0, 303}, - dictWord{ - 6, - 11, - 549, - }, - dictWord{8, 11, 34}, - dictWord{8, 11, 283}, - dictWord{9, 11, 165}, - dictWord{138, 11, 475}, - dictWord{7, 11, 370}, - dictWord{7, 11, 1007}, - dictWord{ - 7, - 11, - 1177, - }, - dictWord{135, 11, 1565}, - dictWord{5, 11, 652}, - dictWord{5, 11, 701}, - dictWord{135, 11, 449}, - dictWord{5, 0, 196}, - dictWord{6, 0, 486}, - dictWord{ - 7, - 0, - 212, - }, - dictWord{8, 0, 309}, - dictWord{136, 0, 346}, - dictWord{6, 10, 1719}, - dictWord{6, 10, 1735}, - dictWord{7, 10, 2016}, - dictWord{7, 10, 2020}, - dictWord{ - 8, - 10, - 837, - }, - dictWord{137, 10, 852}, - dictWord{6, 11, 159}, - dictWord{6, 11, 364}, - dictWord{7, 11, 516}, - dictWord{7, 11, 1439}, - dictWord{137, 11, 518}, - dictWord{135, 0, 1912}, - dictWord{135, 0, 1290}, - dictWord{132, 0, 686}, - dictWord{141, 11, 151}, - dictWord{138, 0, 625}, - dictWord{136, 0, 706}, - dictWord{ - 138, - 10, - 568, - }, - dictWord{139, 0, 412}, - dictWord{4, 0, 30}, - dictWord{133, 0, 43}, - dictWord{8, 10, 67}, - dictWord{138, 10, 419}, - dictWord{7, 0, 967}, - dictWord{ - 141, - 0, - 11, - }, - dictWord{12, 0, 758}, - dictWord{14, 0, 441}, - dictWord{142, 0, 462}, - dictWord{10, 10, 657}, - dictWord{14, 10, 297}, - dictWord{142, 10, 361}, - dictWord{ - 139, - 10, - 729, - }, - dictWord{4, 0, 220}, - dictWord{135, 0, 1535}, - dictWord{7, 11, 501}, - dictWord{9, 11, 111}, - dictWord{10, 11, 141}, - dictWord{11, 11, 332}, - dictWord{ - 13, - 11, - 43, - }, - dictWord{13, 11, 429}, - dictWord{14, 11, 130}, - dictWord{14, 11, 415}, - dictWord{145, 11, 102}, - dictWord{4, 0, 950}, - dictWord{6, 0, 1859}, - dictWord{ - 7, - 0, - 11, - }, - dictWord{8, 0, 873}, - dictWord{12, 0, 710}, - dictWord{12, 0, 718}, - dictWord{12, 0, 748}, - dictWord{12, 0, 765}, - dictWord{148, 0, 124}, - dictWord{ - 5, - 11, - 149, - }, - dictWord{5, 11, 935}, - dictWord{136, 11, 233}, - dictWord{142, 11, 291}, - dictWord{134, 0, 1579}, - dictWord{7, 0, 890}, - dictWord{8, 10, 51}, - dictWord{ - 9, - 10, - 868, - }, - dictWord{10, 10, 833}, - dictWord{12, 10, 481}, - dictWord{12, 10, 570}, - dictWord{148, 10, 106}, - dictWord{141, 0, 2}, - dictWord{132, 10, 445}, - dictWord{136, 11, 801}, - dictWord{135, 0, 1774}, - dictWord{7, 0, 1725}, - dictWord{138, 0, 393}, - dictWord{5, 0, 263}, - dictWord{134, 0, 414}, - dictWord{ - 132, - 11, - 322, - }, - dictWord{133, 10, 239}, - dictWord{7, 0, 456}, - dictWord{7, 10, 1990}, - dictWord{8, 10, 130}, - dictWord{139, 10, 720}, - dictWord{137, 0, 818}, - dictWord{ - 5, - 10, - 123, - }, - dictWord{6, 10, 530}, - dictWord{7, 10, 348}, - dictWord{135, 10, 1419}, - dictWord{135, 10, 2024}, - dictWord{6, 0, 178}, - dictWord{6, 0, 1750}, - dictWord{8, 0, 251}, - dictWord{9, 0, 690}, - dictWord{10, 0, 155}, - dictWord{10, 0, 196}, - dictWord{10, 0, 373}, - dictWord{11, 0, 698}, - dictWord{13, 0, 155}, - dictWord{ - 148, - 0, - 93, - }, - dictWord{5, 0, 97}, - dictWord{137, 0, 393}, - dictWord{134, 0, 674}, - dictWord{11, 0, 223}, - dictWord{140, 0, 168}, - dictWord{132, 10, 210}, - dictWord{ - 139, - 11, - 464, - }, - dictWord{6, 0, 1639}, - dictWord{146, 0, 159}, - dictWord{139, 11, 2}, - dictWord{7, 0, 934}, - dictWord{8, 0, 647}, - dictWord{17, 0, 97}, - dictWord{19, 0, 59}, - dictWord{150, 0, 2}, - dictWord{132, 0, 191}, - dictWord{5, 0, 165}, - dictWord{9, 0, 346}, - dictWord{10, 0, 655}, - dictWord{11, 0, 885}, - dictWord{4, 10, 430}, - dictWord{135, 11, 357}, - dictWord{133, 0, 877}, - dictWord{5, 10, 213}, - dictWord{133, 11, 406}, - dictWord{8, 0, 128}, - dictWord{139, 0, 179}, - dictWord{6, 11, 69}, - dictWord{135, 11, 117}, - dictWord{135, 0, 1297}, - dictWord{11, 11, 43}, - dictWord{13, 11, 72}, - dictWord{141, 11, 142}, - dictWord{135, 11, 1830}, - dictWord{ - 142, - 0, - 164, - }, - dictWord{5, 0, 57}, - dictWord{6, 0, 101}, - dictWord{6, 0, 586}, - dictWord{6, 0, 1663}, - dictWord{7, 0, 132}, - dictWord{7, 0, 1154}, - dictWord{7, 0, 1415}, - dictWord{7, 0, 1507}, - dictWord{12, 0, 493}, - dictWord{15, 0, 105}, - dictWord{151, 0, 15}, - dictWord{5, 0, 459}, - dictWord{7, 0, 1073}, - dictWord{8, 0, 241}, - dictWord{ - 136, - 0, - 334, - }, - dictWord{133, 11, 826}, - dictWord{133, 10, 108}, - dictWord{5, 10, 219}, - dictWord{10, 11, 132}, - dictWord{11, 11, 191}, - dictWord{11, 11, 358}, - dictWord{139, 11, 460}, - dictWord{6, 0, 324}, - dictWord{6, 0, 520}, - dictWord{7, 0, 338}, - dictWord{7, 0, 1729}, - dictWord{8, 0, 228}, - dictWord{139, 0, 750}, - dictWord{ - 21, - 0, - 30, - }, - dictWord{22, 0, 53}, - dictWord{4, 10, 193}, - dictWord{5, 10, 916}, - dictWord{7, 10, 364}, - dictWord{10, 10, 398}, - dictWord{10, 10, 726}, - dictWord{ - 11, - 10, - 317, - }, - dictWord{11, 10, 626}, - dictWord{12, 10, 142}, - dictWord{12, 10, 288}, - dictWord{12, 10, 678}, - dictWord{13, 10, 313}, - dictWord{15, 10, 113}, - dictWord{146, 10, 114}, - dictWord{6, 11, 110}, - dictWord{135, 11, 1681}, - dictWord{135, 0, 910}, - dictWord{6, 10, 241}, - dictWord{7, 10, 907}, - dictWord{8, 10, 832}, - dictWord{9, 10, 342}, - dictWord{10, 10, 729}, - dictWord{11, 10, 284}, - dictWord{11, 10, 445}, - dictWord{11, 10, 651}, - dictWord{11, 10, 863}, - dictWord{ - 13, - 10, - 398, - }, - dictWord{146, 10, 99}, - dictWord{7, 0, 705}, - dictWord{9, 0, 734}, - dictWord{5, 11, 1000}, - dictWord{7, 11, 733}, - dictWord{137, 11, 583}, - dictWord{4, 0, 73}, - dictWord{6, 0, 612}, - dictWord{7, 0, 927}, - dictWord{7, 0, 1822}, - dictWord{8, 0, 217}, - dictWord{9, 0, 765}, - dictWord{9, 0, 766}, - dictWord{10, 0, 408}, - dictWord{ - 11, - 0, - 51, - }, - dictWord{11, 0, 793}, - dictWord{12, 0, 266}, - dictWord{15, 0, 158}, - dictWord{20, 0, 89}, - dictWord{150, 0, 32}, - dictWord{7, 0, 1330}, - dictWord{4, 11, 297}, - dictWord{6, 11, 529}, - dictWord{7, 11, 152}, - dictWord{7, 11, 713}, - dictWord{7, 11, 1845}, - dictWord{8, 11, 710}, - dictWord{8, 11, 717}, - dictWord{140, 11, 639}, - dictWord{5, 0, 389}, - dictWord{136, 0, 636}, - dictWord{134, 0, 1409}, - dictWord{4, 10, 562}, - dictWord{9, 10, 254}, - dictWord{139, 10, 879}, - dictWord{134, 0, 893}, - dictWord{132, 10, 786}, - dictWord{4, 11, 520}, - dictWord{135, 11, 575}, - dictWord{136, 0, 21}, - dictWord{140, 0, 721}, - dictWord{136, 0, 959}, - dictWord{ - 7, - 11, - 1428, - }, - dictWord{7, 11, 1640}, - dictWord{9, 11, 169}, - dictWord{9, 11, 182}, - dictWord{9, 11, 367}, - dictWord{9, 11, 478}, - dictWord{9, 11, 506}, - dictWord{ - 9, - 11, - 551, - }, - dictWord{9, 11, 648}, - dictWord{9, 11, 651}, - dictWord{9, 11, 697}, - dictWord{9, 11, 705}, - dictWord{9, 11, 725}, - dictWord{9, 11, 787}, - dictWord{9, 11, 794}, - dictWord{10, 11, 198}, - dictWord{10, 11, 214}, - dictWord{10, 11, 267}, - dictWord{10, 11, 275}, - dictWord{10, 11, 456}, - dictWord{10, 11, 551}, - dictWord{ - 10, - 11, - 561, - }, - dictWord{10, 11, 613}, - dictWord{10, 11, 627}, - dictWord{10, 11, 668}, - dictWord{10, 11, 675}, - dictWord{10, 11, 691}, - dictWord{10, 11, 695}, - dictWord{10, 11, 707}, - dictWord{10, 11, 715}, - dictWord{11, 11, 183}, - dictWord{11, 11, 201}, - dictWord{11, 11, 244}, - dictWord{11, 11, 262}, - dictWord{ - 11, - 11, - 352, - }, - dictWord{11, 11, 439}, - dictWord{11, 11, 493}, - dictWord{11, 11, 572}, - dictWord{11, 11, 591}, - dictWord{11, 11, 608}, - dictWord{11, 11, 611}, - dictWord{ - 11, - 11, - 646, - }, - dictWord{11, 11, 674}, - dictWord{11, 11, 711}, - dictWord{11, 11, 751}, - dictWord{11, 11, 761}, - dictWord{11, 11, 776}, - dictWord{11, 11, 785}, - dictWord{11, 11, 850}, - dictWord{11, 11, 853}, - dictWord{11, 11, 862}, - dictWord{11, 11, 865}, - dictWord{11, 11, 868}, - dictWord{11, 11, 898}, - dictWord{ - 11, - 11, - 902, - }, - dictWord{11, 11, 903}, - dictWord{11, 11, 910}, - dictWord{11, 11, 932}, - dictWord{11, 11, 942}, - dictWord{11, 11, 957}, - dictWord{11, 11, 967}, - dictWord{ - 11, - 11, - 972, - }, - dictWord{12, 11, 148}, - dictWord{12, 11, 195}, - dictWord{12, 11, 220}, - dictWord{12, 11, 237}, - dictWord{12, 11, 318}, - dictWord{12, 11, 339}, - dictWord{12, 11, 393}, - dictWord{12, 11, 445}, - dictWord{12, 11, 450}, - dictWord{12, 11, 474}, - dictWord{12, 11, 509}, - dictWord{12, 11, 533}, - dictWord{ - 12, - 11, - 591, - }, - dictWord{12, 11, 594}, - dictWord{12, 11, 597}, - dictWord{12, 11, 621}, - dictWord{12, 11, 633}, - dictWord{12, 11, 642}, - dictWord{13, 11, 59}, - dictWord{ - 13, - 11, - 60, - }, - dictWord{13, 11, 145}, - dictWord{13, 11, 239}, - dictWord{13, 11, 250}, - dictWord{13, 11, 273}, - dictWord{13, 11, 329}, - dictWord{13, 11, 344}, - dictWord{13, 11, 365}, - dictWord{13, 11, 372}, - dictWord{13, 11, 387}, - dictWord{13, 11, 403}, - dictWord{13, 11, 414}, - dictWord{13, 11, 456}, - dictWord{ - 13, - 11, - 478, - }, - dictWord{13, 11, 483}, - dictWord{13, 11, 489}, - dictWord{14, 11, 55}, - dictWord{14, 11, 57}, - dictWord{14, 11, 81}, - dictWord{14, 11, 90}, - dictWord{ - 14, - 11, - 148, - }, - dictWord{14, 11, 239}, - dictWord{14, 11, 266}, - dictWord{14, 11, 321}, - dictWord{14, 11, 326}, - dictWord{14, 11, 327}, - dictWord{14, 11, 330}, - dictWord{ - 14, - 11, - 347, - }, - dictWord{14, 11, 355}, - dictWord{14, 11, 401}, - dictWord{14, 11, 411}, - dictWord{14, 11, 414}, - dictWord{14, 11, 416}, - dictWord{14, 11, 420}, - dictWord{15, 11, 61}, - dictWord{15, 11, 74}, - dictWord{15, 11, 87}, - dictWord{15, 11, 88}, - dictWord{15, 11, 94}, - dictWord{15, 11, 96}, - dictWord{15, 11, 116}, - dictWord{15, 11, 149}, - dictWord{15, 11, 154}, - dictWord{16, 11, 50}, - dictWord{16, 11, 63}, - dictWord{16, 11, 73}, - dictWord{17, 11, 2}, - dictWord{17, 11, 66}, - dictWord{ - 17, - 11, - 92, - }, - dictWord{17, 11, 103}, - dictWord{17, 11, 112}, - dictWord{18, 11, 50}, - dictWord{18, 11, 54}, - dictWord{18, 11, 82}, - dictWord{18, 11, 86}, - dictWord{ - 18, - 11, - 90, - }, - dictWord{18, 11, 111}, - dictWord{18, 11, 115}, - dictWord{18, 11, 156}, - dictWord{19, 11, 40}, - dictWord{19, 11, 79}, - dictWord{20, 11, 78}, - dictWord{ - 149, - 11, - 22, - }, - dictWord{137, 11, 170}, - dictWord{134, 0, 1433}, - dictWord{135, 11, 1307}, - dictWord{139, 11, 411}, - dictWord{5, 0, 189}, - dictWord{7, 0, 442}, - dictWord{7, 0, 443}, - dictWord{8, 0, 281}, - dictWord{12, 0, 174}, - dictWord{141, 0, 261}, - dictWord{6, 10, 216}, - dictWord{7, 10, 901}, - dictWord{7, 10, 1343}, - dictWord{136, 10, 493}, - dictWord{5, 11, 397}, - dictWord{6, 11, 154}, - dictWord{7, 10, 341}, - dictWord{7, 11, 676}, - dictWord{8, 11, 443}, - dictWord{8, 11, 609}, - dictWord{ - 9, - 11, - 24, - }, - dictWord{9, 11, 325}, - dictWord{10, 11, 35}, - dictWord{11, 10, 219}, - dictWord{11, 11, 535}, - dictWord{11, 11, 672}, - dictWord{11, 11, 1018}, - dictWord{12, 11, 637}, - dictWord{144, 11, 30}, - dictWord{6, 0, 2}, - dictWord{7, 0, 191}, - dictWord{7, 0, 446}, - dictWord{7, 0, 1262}, - dictWord{7, 0, 1737}, - dictWord{8, 0, 22}, - dictWord{8, 0, 270}, - dictWord{8, 0, 612}, - dictWord{9, 0, 4}, - dictWord{9, 0, 312}, - dictWord{9, 0, 436}, - dictWord{9, 0, 626}, - dictWord{10, 0, 216}, - dictWord{10, 0, 311}, - dictWord{10, 0, 521}, - dictWord{10, 0, 623}, - dictWord{11, 0, 72}, - dictWord{11, 0, 330}, - dictWord{11, 0, 455}, - dictWord{12, 0, 321}, - dictWord{12, 0, 504}, - dictWord{12, 0, 530}, - dictWord{12, 0, 543}, - dictWord{13, 0, 17}, - dictWord{13, 0, 156}, - dictWord{13, 0, 334}, - dictWord{14, 0, 131}, - dictWord{17, 0, 60}, - dictWord{ - 148, - 0, - 64, - }, - dictWord{7, 0, 354}, - dictWord{10, 0, 410}, - dictWord{139, 0, 815}, - dictWord{139, 10, 130}, - dictWord{7, 10, 1734}, - dictWord{137, 11, 631}, - dictWord{ - 12, - 0, - 425, - }, - dictWord{15, 0, 112}, - dictWord{10, 10, 115}, - dictWord{11, 10, 420}, - dictWord{13, 10, 404}, - dictWord{14, 10, 346}, - dictWord{143, 10, 54}, - dictWord{ - 6, - 0, - 60, - }, - dictWord{6, 0, 166}, - dictWord{7, 0, 374}, - dictWord{7, 0, 670}, - dictWord{7, 0, 1327}, - dictWord{8, 0, 411}, - dictWord{8, 0, 435}, - dictWord{9, 0, 653}, - dictWord{ - 9, - 0, - 740, - }, - dictWord{10, 0, 385}, - dictWord{11, 0, 222}, - dictWord{11, 0, 324}, - dictWord{11, 0, 829}, - dictWord{140, 0, 611}, - dictWord{7, 0, 1611}, - dictWord{ - 13, - 0, - 14, - }, - dictWord{15, 0, 44}, - dictWord{19, 0, 13}, - dictWord{148, 0, 76}, - dictWord{133, 11, 981}, - dictWord{4, 11, 56}, - dictWord{7, 11, 1791}, - dictWord{8, 11, 607}, - dictWord{8, 11, 651}, - dictWord{11, 11, 465}, - dictWord{11, 11, 835}, - dictWord{12, 11, 337}, - dictWord{141, 11, 480}, - dictWord{6, 0, 1478}, - dictWord{ - 5, - 10, - 1011, - }, - dictWord{136, 10, 701}, - dictWord{139, 0, 596}, - dictWord{5, 0, 206}, - dictWord{134, 0, 398}, - dictWord{4, 10, 54}, - dictWord{5, 10, 666}, - dictWord{ - 7, - 10, - 1039, - }, - dictWord{7, 10, 1130}, - dictWord{9, 10, 195}, - dictWord{138, 10, 302}, - dictWord{7, 0, 50}, - dictWord{9, 11, 158}, - dictWord{138, 11, 411}, - dictWord{ - 135, - 11, - 1120, - }, - dictWord{6, 0, 517}, - dictWord{7, 0, 1159}, - dictWord{10, 0, 621}, - dictWord{11, 0, 192}, - dictWord{134, 10, 1669}, - dictWord{4, 0, 592}, - dictWord{ - 6, - 0, - 600, - }, - dictWord{135, 0, 1653}, - dictWord{10, 0, 223}, - dictWord{139, 0, 645}, - dictWord{136, 11, 139}, - dictWord{7, 0, 64}, - dictWord{136, 0, 245}, - dictWord{ - 142, - 0, - 278, - }, - dictWord{6, 11, 622}, - dictWord{135, 11, 1030}, - dictWord{136, 0, 604}, - dictWord{134, 0, 1502}, - dictWord{138, 0, 265}, - dictWord{ - 141, - 11, - 168, - }, - dictWord{7, 0, 1763}, - dictWord{140, 0, 310}, - dictWord{7, 10, 798}, - dictWord{139, 11, 719}, - dictWord{7, 11, 160}, - dictWord{10, 11, 624}, - dictWord{ - 142, - 11, - 279, - }, - dictWord{132, 11, 363}, - dictWord{7, 10, 122}, - dictWord{9, 10, 259}, - dictWord{10, 10, 84}, - dictWord{11, 10, 470}, - dictWord{12, 10, 541}, - dictWord{141, 10, 379}, - dictWord{5, 0, 129}, - dictWord{6, 0, 61}, - dictWord{135, 0, 947}, - dictWord{134, 0, 1356}, - dictWord{135, 11, 1191}, - dictWord{13, 0, 505}, - dictWord{141, 0, 506}, - dictWord{11, 0, 1000}, - dictWord{5, 10, 82}, - dictWord{5, 10, 131}, - dictWord{7, 10, 1755}, - dictWord{8, 10, 31}, - dictWord{9, 10, 168}, - dictWord{9, 10, 764}, - dictWord{139, 10, 869}, - dictWord{134, 0, 966}, - dictWord{134, 10, 605}, - dictWord{134, 11, 292}, - dictWord{5, 11, 177}, - dictWord{ - 6, - 11, - 616, - }, - dictWord{7, 11, 827}, - dictWord{9, 11, 525}, - dictWord{138, 11, 656}, - dictWord{135, 11, 1486}, - dictWord{138, 11, 31}, - dictWord{5, 10, 278}, - dictWord{137, 10, 68}, - dictWord{4, 10, 163}, - dictWord{5, 10, 201}, - dictWord{5, 10, 307}, - dictWord{5, 10, 310}, - dictWord{6, 10, 335}, - dictWord{7, 10, 284}, - dictWord{136, 10, 165}, - dictWord{6, 0, 839}, - dictWord{135, 10, 1660}, - dictWord{136, 10, 781}, - dictWord{6, 10, 33}, - dictWord{135, 10, 1244}, - dictWord{ - 133, - 0, - 637, - }, - dictWord{4, 11, 161}, - dictWord{133, 11, 631}, - dictWord{137, 0, 590}, - dictWord{7, 10, 1953}, - dictWord{136, 10, 720}, - dictWord{5, 0, 280}, - dictWord{ - 7, - 0, - 1226, - }, - dictWord{138, 10, 203}, - dictWord{134, 0, 1386}, - dictWord{5, 0, 281}, - dictWord{6, 0, 1026}, - dictWord{6, 10, 326}, - dictWord{7, 10, 677}, - dictWord{ - 137, - 10, - 425, - }, - dictWord{7, 11, 1557}, - dictWord{135, 11, 1684}, - dictWord{135, 0, 1064}, - dictWord{9, 11, 469}, - dictWord{9, 11, 709}, - dictWord{12, 11, 512}, - dictWord{14, 11, 65}, - dictWord{145, 11, 12}, - dictWord{134, 0, 917}, - dictWord{10, 11, 229}, - dictWord{11, 11, 73}, - dictWord{11, 11, 376}, - dictWord{ - 139, - 11, - 433, - }, - dictWord{7, 0, 555}, - dictWord{9, 0, 192}, - dictWord{13, 0, 30}, - dictWord{13, 0, 49}, - dictWord{15, 0, 150}, - dictWord{16, 0, 76}, - dictWord{20, 0, 52}, - dictWord{ - 7, - 10, - 1316, - }, - dictWord{7, 10, 1412}, - dictWord{7, 10, 1839}, - dictWord{9, 10, 589}, - dictWord{11, 10, 241}, - dictWord{11, 10, 676}, - dictWord{11, 10, 811}, - dictWord{11, 10, 891}, - dictWord{12, 10, 140}, - dictWord{12, 10, 346}, - dictWord{12, 10, 479}, - dictWord{13, 10, 381}, - dictWord{14, 10, 188}, - dictWord{ - 146, - 10, - 30, - }, - dictWord{149, 0, 15}, - dictWord{6, 0, 1882}, - dictWord{6, 0, 1883}, - dictWord{6, 0, 1897}, - dictWord{9, 0, 945}, - dictWord{9, 0, 1014}, - dictWord{9, 0, 1020}, - dictWord{12, 0, 823}, - dictWord{12, 0, 842}, - dictWord{12, 0, 866}, - dictWord{12, 0, 934}, - dictWord{15, 0, 242}, - dictWord{146, 0, 208}, - dictWord{6, 0, 965}, - dictWord{134, 0, 1499}, - dictWord{7, 0, 33}, - dictWord{7, 0, 120}, - dictWord{8, 0, 489}, - dictWord{9, 0, 319}, - dictWord{10, 0, 820}, - dictWord{11, 0, 1004}, - dictWord{ - 12, - 0, - 379, - }, - dictWord{12, 0, 679}, - dictWord{13, 0, 117}, - dictWord{13, 0, 412}, - dictWord{14, 0, 25}, - dictWord{15, 0, 52}, - dictWord{15, 0, 161}, - dictWord{16, 0, 47}, - dictWord{149, 0, 2}, - dictWord{6, 11, 558}, - dictWord{7, 11, 651}, - dictWord{8, 11, 421}, - dictWord{9, 11, 0}, - dictWord{138, 11, 34}, - dictWord{4, 0, 937}, - dictWord{ - 5, - 0, - 801, - }, - dictWord{7, 0, 473}, - dictWord{5, 10, 358}, - dictWord{7, 10, 1184}, - dictWord{10, 10, 662}, - dictWord{13, 10, 212}, - dictWord{13, 10, 304}, - dictWord{ - 13, - 10, - 333, - }, - dictWord{145, 10, 98}, - dictWord{132, 0, 877}, - dictWord{6, 0, 693}, - dictWord{134, 0, 824}, - dictWord{132, 0, 365}, - dictWord{7, 11, 1832}, - dictWord{ - 138, - 11, - 374, - }, - dictWord{5, 0, 7}, - dictWord{139, 0, 774}, - dictWord{4, 0, 734}, - dictWord{5, 0, 662}, - dictWord{134, 0, 430}, - dictWord{4, 0, 746}, - dictWord{ - 135, - 0, - 1090, - }, - dictWord{5, 0, 360}, - dictWord{8, 0, 237}, - dictWord{10, 0, 231}, - dictWord{147, 0, 124}, - dictWord{138, 11, 348}, - dictWord{6, 11, 6}, - dictWord{7, 11, 81}, - dictWord{7, 11, 771}, - dictWord{7, 11, 1731}, - dictWord{9, 11, 405}, - dictWord{138, 11, 421}, - dictWord{6, 0, 740}, - dictWord{137, 0, 822}, - dictWord{ - 133, - 10, - 946, - }, - dictWord{7, 0, 1485}, - dictWord{136, 0, 929}, - dictWord{7, 10, 411}, - dictWord{8, 10, 631}, - dictWord{9, 10, 323}, - dictWord{10, 10, 355}, - dictWord{ - 11, - 10, - 491, - }, - dictWord{12, 10, 143}, - dictWord{12, 10, 402}, - dictWord{13, 10, 73}, - dictWord{14, 10, 408}, - dictWord{15, 10, 107}, - dictWord{146, 10, 71}, - dictWord{ - 135, - 10, - 590, - }, - dictWord{5, 11, 881}, - dictWord{133, 11, 885}, - dictWord{150, 11, 25}, - dictWord{4, 0, 852}, - dictWord{5, 11, 142}, - dictWord{134, 11, 546}, - dictWord{7, 10, 1467}, - dictWord{8, 10, 328}, - dictWord{10, 10, 544}, - dictWord{11, 10, 955}, - dictWord{13, 10, 320}, - dictWord{145, 10, 83}, - dictWord{9, 0, 17}, - dictWord{10, 0, 291}, - dictWord{11, 10, 511}, - dictWord{13, 10, 394}, - dictWord{14, 10, 298}, - dictWord{14, 10, 318}, - dictWord{146, 10, 103}, - dictWord{5, 11, 466}, - dictWord{11, 11, 571}, - dictWord{12, 11, 198}, - dictWord{13, 11, 283}, - dictWord{14, 11, 186}, - dictWord{15, 11, 21}, - dictWord{143, 11, 103}, - dictWord{ - 134, - 0, - 1001, - }, - dictWord{4, 11, 185}, - dictWord{5, 11, 257}, - dictWord{5, 11, 839}, - dictWord{5, 11, 936}, - dictWord{7, 11, 171}, - dictWord{9, 11, 399}, - dictWord{ - 10, - 11, - 258, - }, - dictWord{10, 11, 395}, - dictWord{10, 11, 734}, - dictWord{11, 11, 1014}, - dictWord{12, 11, 23}, - dictWord{13, 11, 350}, - dictWord{14, 11, 150}, - dictWord{147, 11, 6}, - dictWord{143, 0, 35}, - dictWord{132, 0, 831}, - dictWord{5, 10, 835}, - dictWord{134, 10, 483}, - dictWord{4, 0, 277}, - dictWord{5, 0, 608}, - dictWord{ - 6, - 0, - 493, - }, - dictWord{7, 0, 457}, - dictWord{12, 0, 384}, - dictWord{7, 11, 404}, - dictWord{7, 11, 1377}, - dictWord{7, 11, 1430}, - dictWord{7, 11, 2017}, - dictWord{ - 8, - 11, - 149, - }, - dictWord{8, 11, 239}, - dictWord{8, 11, 512}, - dictWord{8, 11, 793}, - dictWord{8, 11, 818}, - dictWord{9, 11, 474}, - dictWord{9, 11, 595}, - dictWord{ - 10, - 11, - 122, - }, - dictWord{10, 11, 565}, - dictWord{10, 11, 649}, - dictWord{10, 11, 783}, - dictWord{11, 11, 239}, - dictWord{11, 11, 295}, - dictWord{11, 11, 447}, - dictWord{ - 11, - 11, - 528, - }, - dictWord{11, 11, 639}, - dictWord{11, 11, 800}, - dictWord{11, 11, 936}, - dictWord{12, 11, 25}, - dictWord{12, 11, 73}, - dictWord{12, 11, 77}, - dictWord{12, 11, 157}, - dictWord{12, 11, 316}, - dictWord{12, 11, 390}, - dictWord{12, 11, 391}, - dictWord{12, 11, 394}, - dictWord{12, 11, 395}, - dictWord{ - 12, - 11, - 478, - }, - dictWord{12, 11, 503}, - dictWord{12, 11, 592}, - dictWord{12, 11, 680}, - dictWord{13, 11, 50}, - dictWord{13, 11, 53}, - dictWord{13, 11, 132}, - dictWord{ - 13, - 11, - 198, - }, - dictWord{13, 11, 275}, - dictWord{13, 11, 322}, - dictWord{13, 11, 415}, - dictWord{14, 11, 71}, - dictWord{14, 11, 257}, - dictWord{14, 11, 395}, - dictWord{15, 11, 71}, - dictWord{15, 11, 136}, - dictWord{17, 11, 123}, - dictWord{18, 11, 93}, - dictWord{147, 11, 58}, - dictWord{134, 0, 1351}, - dictWord{7, 0, 27}, - dictWord{135, 0, 316}, - dictWord{136, 11, 712}, - dictWord{136, 0, 984}, - dictWord{133, 0, 552}, - dictWord{137, 0, 264}, - dictWord{132, 0, 401}, - dictWord{6, 0, 710}, - dictWord{6, 0, 1111}, - dictWord{134, 0, 1343}, - dictWord{134, 0, 1211}, - dictWord{9, 0, 543}, - dictWord{10, 0, 524}, - dictWord{11, 0, 108}, - dictWord{11, 0, 653}, - dictWord{12, 0, 524}, - dictWord{13, 0, 123}, - dictWord{14, 0, 252}, - dictWord{16, 0, 18}, - dictWord{19, 0, 38}, - dictWord{20, 0, 26}, - dictWord{20, 0, 65}, - dictWord{ - 21, - 0, - 3, - }, - dictWord{151, 0, 11}, - dictWord{4, 0, 205}, - dictWord{5, 0, 623}, - dictWord{7, 0, 104}, - dictWord{8, 0, 519}, - dictWord{137, 0, 716}, - dictWord{132, 10, 677}, - dictWord{4, 11, 377}, - dictWord{152, 11, 13}, - dictWord{135, 11, 1673}, - dictWord{7, 0, 579}, - dictWord{9, 0, 41}, - dictWord{9, 0, 244}, - dictWord{9, 0, 669}, - dictWord{ - 10, - 0, - 5, - }, - dictWord{11, 0, 861}, - dictWord{11, 0, 951}, - dictWord{139, 0, 980}, - dictWord{132, 0, 717}, - dictWord{136, 0, 1011}, - dictWord{132, 0, 805}, - dictWord{ - 4, - 11, - 180, - }, - dictWord{135, 11, 1906}, - dictWord{132, 10, 777}, - dictWord{132, 10, 331}, - dictWord{132, 0, 489}, - dictWord{6, 0, 1024}, - dictWord{4, 11, 491}, - dictWord{133, 10, 747}, - dictWord{135, 11, 1182}, - dictWord{4, 11, 171}, - dictWord{138, 11, 234}, - dictWord{4, 11, 586}, - dictWord{7, 11, 1186}, - dictWord{ - 138, - 11, - 631, - }, - dictWord{135, 0, 892}, - dictWord{135, 11, 336}, - dictWord{9, 11, 931}, - dictWord{10, 11, 334}, - dictWord{148, 11, 71}, - dictWord{137, 0, 473}, - dictWord{6, 0, 864}, - dictWord{12, 0, 659}, - dictWord{139, 11, 926}, - dictWord{7, 0, 819}, - dictWord{9, 0, 26}, - dictWord{9, 0, 392}, - dictWord{10, 0, 152}, - dictWord{ - 10, - 0, - 226, - }, - dictWord{11, 0, 19}, - dictWord{12, 0, 276}, - dictWord{12, 0, 426}, - dictWord{12, 0, 589}, - dictWord{13, 0, 460}, - dictWord{15, 0, 97}, - dictWord{19, 0, 48}, - dictWord{148, 0, 104}, - dictWord{135, 0, 51}, - dictWord{133, 10, 326}, - dictWord{4, 10, 691}, - dictWord{146, 10, 16}, - dictWord{9, 0, 130}, - dictWord{11, 0, 765}, - dictWord{10, 10, 680}, - dictWord{10, 10, 793}, - dictWord{141, 10, 357}, - dictWord{133, 11, 765}, - dictWord{8, 0, 229}, - dictWord{6, 10, 32}, - dictWord{7, 10, 385}, - dictWord{7, 10, 757}, - dictWord{7, 10, 1916}, - dictWord{8, 10, 94}, - dictWord{8, 10, 711}, - dictWord{9, 10, 541}, - dictWord{10, 10, 162}, - dictWord{10, 10, 795}, - dictWord{11, 10, 989}, - dictWord{11, 10, 1010}, - dictWord{12, 10, 14}, - dictWord{142, 10, 308}, - dictWord{7, 11, 474}, - dictWord{137, 11, 578}, - dictWord{ - 132, - 0, - 674, - }, - dictWord{132, 0, 770}, - dictWord{5, 0, 79}, - dictWord{7, 0, 1027}, - dictWord{7, 0, 1477}, - dictWord{139, 0, 52}, - dictWord{133, 11, 424}, - dictWord{ - 134, - 0, - 1666, - }, - dictWord{6, 0, 409}, - dictWord{6, 10, 349}, - dictWord{6, 10, 1682}, - dictWord{7, 10, 1252}, - dictWord{8, 10, 112}, - dictWord{8, 11, 714}, - dictWord{ - 9, - 10, - 435, - }, - dictWord{9, 10, 668}, - dictWord{10, 10, 290}, - dictWord{10, 10, 319}, - dictWord{10, 10, 815}, - dictWord{11, 10, 180}, - dictWord{11, 10, 837}, - dictWord{ - 12, - 10, - 240, - }, - dictWord{13, 10, 152}, - dictWord{13, 10, 219}, - dictWord{142, 10, 158}, - dictWord{5, 0, 789}, - dictWord{134, 0, 195}, - dictWord{4, 0, 251}, - dictWord{ - 4, - 0, - 688, - }, - dictWord{7, 0, 513}, - dictWord{135, 0, 1284}, - dictWord{132, 10, 581}, - dictWord{9, 11, 420}, - dictWord{10, 11, 269}, - dictWord{10, 11, 285}, - dictWord{10, 11, 576}, - dictWord{11, 11, 397}, - dictWord{13, 11, 175}, - dictWord{145, 11, 90}, - dictWord{6, 10, 126}, - dictWord{7, 10, 573}, - dictWord{8, 10, 397}, - dictWord{142, 10, 44}, - dictWord{132, 11, 429}, - dictWord{133, 0, 889}, - dictWord{4, 0, 160}, - dictWord{5, 0, 330}, - dictWord{7, 0, 1434}, - dictWord{136, 0, 174}, - dictWord{7, 11, 18}, - dictWord{7, 11, 699}, - dictWord{7, 11, 1966}, - dictWord{8, 11, 752}, - dictWord{9, 11, 273}, - dictWord{9, 11, 412}, - dictWord{9, 11, 703}, - dictWord{ - 10, - 11, - 71, - }, - dictWord{10, 11, 427}, - dictWord{10, 11, 508}, - dictWord{146, 11, 97}, - dictWord{6, 0, 872}, - dictWord{134, 0, 899}, - dictWord{133, 10, 926}, - dictWord{134, 0, 1126}, - dictWord{134, 0, 918}, - dictWord{4, 11, 53}, - dictWord{5, 11, 186}, - dictWord{135, 11, 752}, - dictWord{7, 0, 268}, - dictWord{136, 0, 569}, - dictWord{134, 0, 1224}, - dictWord{6, 0, 1361}, - dictWord{7, 10, 1232}, - dictWord{137, 10, 531}, - dictWord{8, 11, 575}, - dictWord{10, 11, 289}, - dictWord{ - 139, - 11, - 319, - }, - dictWord{133, 10, 670}, - dictWord{132, 11, 675}, - dictWord{133, 0, 374}, - dictWord{135, 10, 1957}, - dictWord{133, 0, 731}, - dictWord{11, 0, 190}, - dictWord{15, 0, 49}, - dictWord{11, 11, 190}, - dictWord{143, 11, 49}, - dictWord{4, 0, 626}, - dictWord{5, 0, 506}, - dictWord{5, 0, 642}, - dictWord{6, 0, 425}, - dictWord{ - 10, - 0, - 202, - }, - dictWord{139, 0, 141}, - dictWord{137, 0, 444}, - dictWord{7, 10, 242}, - dictWord{135, 10, 1942}, - dictWord{6, 11, 209}, - dictWord{8, 11, 468}, - dictWord{ - 9, - 11, - 210, - }, - dictWord{11, 11, 36}, - dictWord{12, 11, 28}, - dictWord{12, 11, 630}, - dictWord{13, 11, 21}, - dictWord{13, 11, 349}, - dictWord{14, 11, 7}, - dictWord{ - 145, - 11, - 13, - }, - dictWord{4, 11, 342}, - dictWord{135, 11, 1179}, - dictWord{5, 10, 834}, - dictWord{7, 10, 1202}, - dictWord{8, 10, 14}, - dictWord{9, 10, 481}, - dictWord{ - 137, - 10, - 880, - }, - dictWord{4, 11, 928}, - dictWord{133, 11, 910}, - dictWord{4, 11, 318}, - dictWord{4, 11, 496}, - dictWord{7, 11, 856}, - dictWord{139, 11, 654}, - dictWord{136, 0, 835}, - dictWord{7, 0, 1526}, - dictWord{138, 10, 465}, - dictWord{151, 0, 17}, - dictWord{135, 0, 477}, - dictWord{4, 10, 357}, - dictWord{6, 10, 172}, - dictWord{7, 10, 143}, - dictWord{137, 10, 413}, - dictWord{6, 0, 1374}, - dictWord{138, 0, 994}, - dictWord{18, 0, 76}, - dictWord{132, 10, 590}, - dictWord{7, 0, 287}, - dictWord{8, 0, 355}, - dictWord{9, 0, 293}, - dictWord{137, 0, 743}, - dictWord{134, 0, 1389}, - dictWord{7, 11, 915}, - dictWord{8, 11, 247}, - dictWord{147, 11, 0}, - dictWord{ - 4, - 11, - 202, - }, - dictWord{5, 11, 382}, - dictWord{6, 11, 454}, - dictWord{7, 11, 936}, - dictWord{7, 11, 1803}, - dictWord{8, 11, 758}, - dictWord{9, 11, 375}, - dictWord{ - 9, - 11, - 895, - }, - dictWord{10, 11, 743}, - dictWord{10, 11, 792}, - dictWord{11, 11, 978}, - dictWord{11, 11, 1012}, - dictWord{142, 11, 109}, - dictWord{5, 0, 384}, - dictWord{8, 0, 455}, - dictWord{140, 0, 48}, - dictWord{132, 11, 390}, - dictWord{5, 10, 169}, - dictWord{7, 10, 333}, - dictWord{136, 10, 45}, - dictWord{5, 0, 264}, - dictWord{134, 0, 184}, - dictWord{138, 11, 791}, - dictWord{133, 11, 717}, - dictWord{132, 10, 198}, - dictWord{6, 11, 445}, - dictWord{7, 11, 332}, - dictWord{ - 137, - 11, - 909, - }, - dictWord{136, 0, 1001}, - dictWord{4, 10, 24}, - dictWord{5, 10, 140}, - dictWord{5, 10, 185}, - dictWord{7, 10, 1500}, - dictWord{11, 10, 565}, - dictWord{ - 139, - 10, - 838, - }, - dictWord{134, 11, 578}, - dictWord{5, 0, 633}, - dictWord{6, 0, 28}, - dictWord{135, 0, 1323}, - dictWord{132, 0, 851}, - dictWord{136, 11, 267}, - dictWord{ - 7, - 0, - 359, - }, - dictWord{8, 0, 243}, - dictWord{140, 0, 175}, - dictWord{4, 10, 334}, - dictWord{133, 10, 593}, - dictWord{141, 11, 87}, - dictWord{136, 11, 766}, - dictWord{10, 0, 287}, - dictWord{12, 0, 138}, - dictWord{10, 11, 287}, - dictWord{140, 11, 138}, - dictWord{4, 0, 105}, - dictWord{132, 0, 740}, - dictWord{140, 10, 116}, - dictWord{134, 0, 857}, - dictWord{135, 11, 1841}, - dictWord{6, 0, 1402}, - dictWord{137, 0, 819}, - dictWord{132, 11, 584}, - dictWord{132, 10, 709}, - dictWord{ - 133, - 10, - 897, - }, - dictWord{5, 0, 224}, - dictWord{13, 0, 174}, - dictWord{146, 0, 52}, - dictWord{135, 10, 1840}, - dictWord{4, 10, 608}, - dictWord{133, 10, 497}, - dictWord{139, 11, 60}, - dictWord{4, 0, 758}, - dictWord{135, 0, 1649}, - dictWord{4, 11, 226}, - dictWord{4, 11, 326}, - dictWord{135, 11, 1770}, - dictWord{5, 11, 426}, - dictWord{8, 11, 30}, - dictWord{9, 11, 2}, - dictWord{11, 11, 549}, - dictWord{147, 11, 122}, - dictWord{135, 10, 2039}, - dictWord{6, 10, 540}, - dictWord{ - 136, - 10, - 136, - }, - dictWord{4, 0, 573}, - dictWord{8, 0, 655}, - dictWord{4, 10, 897}, - dictWord{133, 10, 786}, - dictWord{7, 0, 351}, - dictWord{139, 0, 128}, - dictWord{ - 133, - 10, - 999, - }, - dictWord{4, 10, 299}, - dictWord{135, 10, 1004}, - dictWord{133, 0, 918}, - dictWord{132, 11, 345}, - dictWord{4, 11, 385}, - dictWord{7, 11, 265}, - dictWord{135, 11, 587}, - dictWord{133, 10, 456}, - dictWord{136, 10, 180}, - dictWord{6, 0, 687}, - dictWord{134, 0, 1537}, - dictWord{4, 11, 347}, - dictWord{ - 5, - 11, - 423, - }, - dictWord{5, 11, 996}, - dictWord{135, 11, 1329}, - dictWord{132, 10, 755}, - dictWord{7, 11, 1259}, - dictWord{9, 11, 125}, - dictWord{11, 11, 65}, - dictWord{140, 11, 285}, - dictWord{5, 11, 136}, - dictWord{6, 11, 136}, - dictWord{136, 11, 644}, - dictWord{134, 0, 1525}, - dictWord{4, 0, 1009}, - dictWord{ - 135, - 0, - 1139, - }, - dictWord{139, 10, 338}, - dictWord{132, 0, 340}, - dictWord{135, 10, 1464}, - dictWord{8, 0, 847}, - dictWord{10, 0, 861}, - dictWord{10, 0, 876}, - dictWord{ - 10, - 0, - 889, - }, - dictWord{10, 0, 922}, - dictWord{10, 0, 929}, - dictWord{10, 0, 933}, - dictWord{12, 0, 784}, - dictWord{140, 0, 791}, - dictWord{139, 0, 176}, - dictWord{ - 9, - 11, - 134, - }, - dictWord{10, 11, 2}, - dictWord{10, 11, 27}, - dictWord{10, 11, 333}, - dictWord{11, 11, 722}, - dictWord{143, 11, 1}, - dictWord{4, 11, 433}, - dictWord{ - 133, - 11, - 719, - }, - dictWord{5, 0, 985}, - dictWord{7, 0, 509}, - dictWord{7, 0, 529}, - dictWord{145, 0, 96}, - dictWord{132, 0, 615}, - dictWord{4, 10, 890}, - dictWord{ - 5, - 10, - 805, - }, - dictWord{5, 10, 819}, - dictWord{5, 10, 961}, - dictWord{6, 10, 396}, - dictWord{6, 10, 1631}, - dictWord{6, 10, 1678}, - dictWord{7, 10, 1967}, - dictWord{ - 7, - 10, - 2041, - }, - dictWord{9, 10, 630}, - dictWord{11, 10, 8}, - dictWord{11, 10, 1019}, - dictWord{12, 10, 176}, - dictWord{13, 10, 225}, - dictWord{14, 10, 292}, - dictWord{ - 149, - 10, - 24, - }, - dictWord{135, 0, 1919}, - dictWord{134, 0, 1131}, - dictWord{144, 11, 21}, - dictWord{144, 11, 51}, - dictWord{135, 10, 1815}, - dictWord{4, 0, 247}, - dictWord{7, 10, 1505}, - dictWord{10, 10, 190}, - dictWord{10, 10, 634}, - dictWord{11, 10, 792}, - dictWord{12, 10, 358}, - dictWord{140, 10, 447}, - dictWord{ - 5, - 10, - 0, - }, - dictWord{6, 10, 536}, - dictWord{7, 10, 604}, - dictWord{13, 10, 445}, - dictWord{145, 10, 126}, - dictWord{4, 0, 184}, - dictWord{5, 0, 390}, - dictWord{6, 0, 337}, - dictWord{7, 0, 23}, - dictWord{7, 0, 494}, - dictWord{7, 0, 618}, - dictWord{7, 0, 1456}, - dictWord{8, 0, 27}, - dictWord{8, 0, 599}, - dictWord{10, 0, 153}, - dictWord{ - 139, - 0, - 710, - }, - dictWord{6, 10, 232}, - dictWord{6, 10, 412}, - dictWord{7, 10, 1074}, - dictWord{8, 10, 9}, - dictWord{8, 10, 157}, - dictWord{8, 10, 786}, - dictWord{9, 10, 196}, - dictWord{9, 10, 352}, - dictWord{9, 10, 457}, - dictWord{10, 10, 337}, - dictWord{11, 10, 232}, - dictWord{11, 10, 877}, - dictWord{12, 10, 480}, - dictWord{ - 140, - 10, - 546, - }, - dictWord{13, 0, 38}, - dictWord{135, 10, 958}, - dictWord{4, 10, 382}, - dictWord{136, 10, 579}, - dictWord{4, 10, 212}, - dictWord{135, 10, 1206}, - dictWord{ - 4, - 11, - 555, - }, - dictWord{8, 11, 536}, - dictWord{138, 11, 288}, - dictWord{11, 11, 139}, - dictWord{139, 11, 171}, - dictWord{9, 11, 370}, - dictWord{138, 11, 90}, - dictWord{132, 0, 1015}, - dictWord{134, 0, 1088}, - dictWord{5, 10, 655}, - dictWord{135, 11, 977}, - dictWord{134, 0, 1585}, - dictWord{17, 10, 67}, - dictWord{ - 147, - 10, - 74, - }, - dictWord{10, 0, 227}, - dictWord{11, 0, 497}, - dictWord{11, 0, 709}, - dictWord{140, 0, 415}, - dictWord{6, 0, 360}, - dictWord{7, 0, 1664}, - dictWord{ - 136, - 0, - 478, - }, - dictWord{7, 0, 95}, - dictWord{6, 10, 231}, - dictWord{136, 10, 423}, - dictWord{140, 11, 65}, - dictWord{4, 11, 257}, - dictWord{135, 11, 2031}, - dictWord{ - 135, - 11, - 1768, - }, - dictWord{133, 10, 300}, - dictWord{139, 11, 211}, - dictWord{136, 0, 699}, - dictWord{6, 10, 237}, - dictWord{7, 10, 611}, - dictWord{8, 10, 100}, - dictWord{9, 10, 416}, - dictWord{11, 10, 335}, - dictWord{12, 10, 173}, - dictWord{146, 10, 101}, - dictWord{14, 0, 26}, - dictWord{146, 0, 150}, - dictWord{6, 0, 581}, - dictWord{135, 0, 1119}, - dictWord{135, 10, 1208}, - dictWord{132, 0, 739}, - dictWord{6, 11, 83}, - dictWord{6, 11, 1733}, - dictWord{135, 11, 1389}, - dictWord{ - 137, - 0, - 869, - }, - dictWord{4, 0, 67}, - dictWord{5, 0, 422}, - dictWord{7, 0, 1037}, - dictWord{7, 0, 1289}, - dictWord{7, 0, 1555}, - dictWord{9, 0, 741}, - dictWord{145, 0, 108}, - dictWord{133, 10, 199}, - dictWord{12, 10, 427}, - dictWord{146, 10, 38}, - dictWord{136, 0, 464}, - dictWord{142, 0, 42}, - dictWord{10, 0, 96}, - dictWord{8, 11, 501}, - dictWord{137, 11, 696}, - dictWord{134, 11, 592}, - dictWord{4, 0, 512}, - dictWord{4, 0, 966}, - dictWord{5, 0, 342}, - dictWord{6, 0, 1855}, - dictWord{8, 0, 869}, - dictWord{8, 0, 875}, - dictWord{8, 0, 901}, - dictWord{144, 0, 26}, - dictWord{8, 0, 203}, - dictWord{11, 0, 823}, - dictWord{11, 0, 846}, - dictWord{12, 0, 482}, - dictWord{ - 13, - 0, - 277, - }, - dictWord{13, 0, 302}, - dictWord{13, 0, 464}, - dictWord{14, 0, 205}, - dictWord{142, 0, 221}, - dictWord{4, 0, 449}, - dictWord{133, 0, 718}, - dictWord{ - 7, - 11, - 1718, - }, - dictWord{9, 11, 95}, - dictWord{9, 11, 274}, - dictWord{10, 11, 279}, - dictWord{10, 11, 317}, - dictWord{10, 11, 420}, - dictWord{11, 11, 303}, - dictWord{ - 11, - 11, - 808, - }, - dictWord{12, 11, 134}, - dictWord{12, 11, 367}, - dictWord{13, 11, 149}, - dictWord{13, 11, 347}, - dictWord{14, 11, 349}, - dictWord{14, 11, 406}, - dictWord{18, 11, 22}, - dictWord{18, 11, 89}, - dictWord{18, 11, 122}, - dictWord{147, 11, 47}, - dictWord{133, 11, 26}, - dictWord{4, 0, 355}, - dictWord{6, 0, 311}, - dictWord{ - 9, - 0, - 256, - }, - dictWord{138, 0, 404}, - dictWord{132, 11, 550}, - dictWord{10, 0, 758}, - dictWord{6, 10, 312}, - dictWord{6, 10, 1715}, - dictWord{10, 10, 584}, - dictWord{11, 10, 546}, - dictWord{11, 10, 692}, - dictWord{12, 10, 259}, - dictWord{12, 10, 295}, - dictWord{13, 10, 46}, - dictWord{141, 10, 154}, - dictWord{ - 136, - 11, - 822, - }, - dictWord{5, 0, 827}, - dictWord{4, 11, 902}, - dictWord{5, 11, 809}, - dictWord{6, 11, 122}, - dictWord{135, 11, 896}, - dictWord{5, 0, 64}, - dictWord{140, 0, 581}, - dictWord{4, 0, 442}, - dictWord{6, 0, 739}, - dictWord{7, 0, 1047}, - dictWord{7, 0, 1352}, - dictWord{7, 0, 1643}, - dictWord{7, 11, 1911}, - dictWord{9, 11, 449}, - dictWord{10, 11, 192}, - dictWord{138, 11, 740}, - dictWord{135, 11, 262}, - dictWord{132, 10, 588}, - dictWord{133, 11, 620}, - dictWord{5, 0, 977}, - dictWord{ - 6, - 0, - 288, - }, - dictWord{7, 0, 528}, - dictWord{4, 11, 34}, - dictWord{5, 11, 574}, - dictWord{7, 11, 279}, - dictWord{7, 11, 1624}, - dictWord{136, 11, 601}, - dictWord{ - 6, - 0, - 1375, - }, - dictWord{4, 10, 231}, - dictWord{5, 10, 61}, - dictWord{6, 10, 104}, - dictWord{7, 10, 729}, - dictWord{7, 10, 964}, - dictWord{7, 10, 1658}, - dictWord{ - 140, - 10, - 414, - }, - dictWord{6, 10, 263}, - dictWord{138, 10, 757}, - dictWord{132, 10, 320}, - dictWord{4, 0, 254}, - dictWord{7, 0, 1309}, - dictWord{5, 11, 332}, - dictWord{ - 135, - 11, - 1309, - }, - dictWord{6, 11, 261}, - dictWord{8, 11, 182}, - dictWord{139, 11, 943}, - dictWord{132, 10, 225}, - dictWord{6, 0, 12}, - dictWord{135, 0, 1219}, - dictWord{4, 0, 275}, - dictWord{12, 0, 376}, - dictWord{6, 11, 1721}, - dictWord{141, 11, 490}, - dictWord{4, 11, 933}, - dictWord{133, 11, 880}, - dictWord{6, 0, 951}, - dictWord{6, 0, 1109}, - dictWord{6, 0, 1181}, - dictWord{7, 0, 154}, - dictWord{4, 10, 405}, - dictWord{7, 10, 817}, - dictWord{14, 10, 58}, - dictWord{17, 10, 37}, - dictWord{ - 146, - 10, - 124, - }, - dictWord{6, 0, 1520}, - dictWord{133, 10, 974}, - dictWord{134, 0, 1753}, - dictWord{6, 0, 369}, - dictWord{6, 0, 502}, - dictWord{7, 0, 1036}, - dictWord{ - 8, - 0, - 348, - }, - dictWord{9, 0, 452}, - dictWord{10, 0, 26}, - dictWord{11, 0, 224}, - dictWord{11, 0, 387}, - dictWord{11, 0, 772}, - dictWord{12, 0, 95}, - dictWord{12, 0, 629}, - dictWord{13, 0, 195}, - dictWord{13, 0, 207}, - dictWord{13, 0, 241}, - dictWord{14, 0, 260}, - dictWord{14, 0, 270}, - dictWord{143, 0, 140}, - dictWord{132, 0, 269}, - dictWord{5, 0, 480}, - dictWord{7, 0, 532}, - dictWord{7, 0, 1197}, - dictWord{7, 0, 1358}, - dictWord{8, 0, 291}, - dictWord{11, 0, 349}, - dictWord{142, 0, 396}, - dictWord{ - 5, - 10, - 235, - }, - dictWord{7, 10, 1239}, - dictWord{11, 10, 131}, - dictWord{140, 10, 370}, - dictWord{7, 10, 956}, - dictWord{7, 10, 1157}, - dictWord{7, 10, 1506}, - dictWord{ - 7, - 10, - 1606, - }, - dictWord{7, 10, 1615}, - dictWord{7, 10, 1619}, - dictWord{7, 10, 1736}, - dictWord{7, 10, 1775}, - dictWord{8, 10, 590}, - dictWord{9, 10, 324}, - dictWord{9, 10, 736}, - dictWord{9, 10, 774}, - dictWord{9, 10, 776}, - dictWord{9, 10, 784}, - dictWord{10, 10, 567}, - dictWord{10, 10, 708}, - dictWord{11, 10, 518}, - dictWord{11, 10, 613}, - dictWord{11, 10, 695}, - dictWord{11, 10, 716}, - dictWord{11, 10, 739}, - dictWord{11, 10, 770}, - dictWord{11, 10, 771}, - dictWord{ - 11, - 10, - 848, - }, - dictWord{11, 10, 857}, - dictWord{11, 10, 931}, - dictWord{11, 10, 947}, - dictWord{12, 10, 326}, - dictWord{12, 10, 387}, - dictWord{12, 10, 484}, - dictWord{ - 12, - 10, - 528, - }, - dictWord{12, 10, 552}, - dictWord{12, 10, 613}, - dictWord{13, 10, 189}, - dictWord{13, 10, 256}, - dictWord{13, 10, 340}, - dictWord{13, 10, 432}, - dictWord{13, 10, 436}, - dictWord{13, 10, 440}, - dictWord{13, 10, 454}, - dictWord{14, 10, 174}, - dictWord{14, 10, 220}, - dictWord{14, 10, 284}, - dictWord{ - 14, - 10, - 390, - }, - dictWord{145, 10, 121}, - dictWord{8, 11, 598}, - dictWord{9, 11, 664}, - dictWord{138, 11, 441}, - dictWord{9, 10, 137}, - dictWord{138, 10, 221}, - dictWord{133, 11, 812}, - dictWord{148, 0, 15}, - dictWord{134, 0, 1341}, - dictWord{6, 0, 1017}, - dictWord{4, 11, 137}, - dictWord{7, 11, 1178}, - dictWord{ - 135, - 11, - 1520, - }, - dictWord{7, 10, 390}, - dictWord{138, 10, 140}, - dictWord{7, 11, 1260}, - dictWord{135, 11, 1790}, - dictWord{137, 11, 191}, - dictWord{ - 135, - 10, - 1144, - }, - dictWord{6, 0, 1810}, - dictWord{7, 0, 657}, - dictWord{8, 0, 886}, - dictWord{10, 0, 857}, - dictWord{14, 0, 440}, - dictWord{144, 0, 96}, - dictWord{8, 0, 533}, - dictWord{6, 11, 1661}, - dictWord{7, 11, 1975}, - dictWord{7, 11, 2009}, - dictWord{135, 11, 2011}, - dictWord{6, 0, 1453}, - dictWord{134, 10, 464}, - dictWord{ - 132, - 11, - 715, - }, - dictWord{5, 10, 407}, - dictWord{11, 10, 204}, - dictWord{11, 10, 243}, - dictWord{11, 10, 489}, - dictWord{12, 10, 293}, - dictWord{19, 10, 37}, - dictWord{20, 10, 73}, - dictWord{150, 10, 38}, - dictWord{133, 11, 703}, - dictWord{4, 0, 211}, - dictWord{7, 0, 1483}, - dictWord{5, 10, 325}, - dictWord{8, 10, 5}, - dictWord{ - 8, - 10, - 227, - }, - dictWord{9, 10, 105}, - dictWord{10, 10, 585}, - dictWord{140, 10, 614}, - dictWord{4, 0, 332}, - dictWord{5, 0, 335}, - dictWord{6, 0, 238}, - dictWord{ - 7, - 0, - 269, - }, - dictWord{7, 0, 811}, - dictWord{7, 0, 1797}, - dictWord{8, 0, 836}, - dictWord{9, 0, 507}, - dictWord{141, 0, 242}, - dictWord{5, 11, 89}, - dictWord{7, 11, 1915}, - dictWord{9, 11, 185}, - dictWord{9, 11, 235}, - dictWord{9, 11, 496}, - dictWord{10, 11, 64}, - dictWord{10, 11, 270}, - dictWord{10, 11, 403}, - dictWord{10, 11, 469}, - dictWord{10, 11, 529}, - dictWord{10, 11, 590}, - dictWord{11, 11, 140}, - dictWord{11, 11, 860}, - dictWord{13, 11, 1}, - dictWord{13, 11, 422}, - dictWord{14, 11, 341}, - dictWord{14, 11, 364}, - dictWord{17, 11, 93}, - dictWord{18, 11, 113}, - dictWord{19, 11, 97}, - dictWord{147, 11, 113}, - dictWord{133, 11, 695}, - dictWord{ - 16, - 0, - 19, - }, - dictWord{5, 11, 6}, - dictWord{6, 11, 183}, - dictWord{6, 10, 621}, - dictWord{7, 11, 680}, - dictWord{7, 11, 978}, - dictWord{7, 11, 1013}, - dictWord{7, 11, 1055}, - dictWord{12, 11, 230}, - dictWord{13, 11, 172}, - dictWord{13, 10, 504}, - dictWord{146, 11, 29}, - dictWord{136, 0, 156}, - dictWord{133, 0, 1009}, - dictWord{ - 6, - 11, - 29, - }, - dictWord{139, 11, 63}, - dictWord{134, 0, 820}, - dictWord{134, 10, 218}, - dictWord{7, 10, 454}, - dictWord{7, 10, 782}, - dictWord{8, 10, 768}, - dictWord{ - 140, - 10, - 686, - }, - dictWord{5, 0, 228}, - dictWord{6, 0, 203}, - dictWord{7, 0, 156}, - dictWord{8, 0, 347}, - dictWord{9, 0, 265}, - dictWord{18, 0, 39}, - dictWord{20, 0, 54}, - dictWord{21, 0, 31}, - dictWord{22, 0, 3}, - dictWord{23, 0, 0}, - dictWord{15, 11, 8}, - dictWord{18, 11, 39}, - dictWord{20, 11, 54}, - dictWord{21, 11, 31}, - dictWord{22, 11, 3}, - dictWord{151, 11, 0}, - dictWord{7, 0, 1131}, - dictWord{135, 0, 1468}, - dictWord{144, 10, 0}, - dictWord{134, 0, 1276}, - dictWord{10, 10, 676}, - dictWord{ - 140, - 10, - 462, - }, - dictWord{132, 11, 311}, - dictWord{134, 11, 1740}, - dictWord{7, 11, 170}, - dictWord{8, 11, 90}, - dictWord{8, 11, 177}, - dictWord{8, 11, 415}, - dictWord{ - 11, - 11, - 714, - }, - dictWord{142, 11, 281}, - dictWord{134, 10, 164}, - dictWord{6, 0, 1792}, - dictWord{138, 0, 849}, - dictWord{150, 10, 50}, - dictWord{5, 0, 291}, - dictWord{5, 0, 318}, - dictWord{7, 0, 765}, - dictWord{9, 0, 389}, - dictWord{12, 0, 548}, - dictWord{8, 11, 522}, - dictWord{142, 11, 328}, - dictWord{11, 11, 91}, - dictWord{ - 13, - 11, - 129, - }, - dictWord{15, 11, 101}, - dictWord{145, 11, 125}, - dictWord{4, 11, 494}, - dictWord{6, 11, 74}, - dictWord{7, 11, 44}, - dictWord{7, 11, 407}, - dictWord{ - 8, - 11, - 551, - }, - dictWord{12, 11, 17}, - dictWord{15, 11, 5}, - dictWord{148, 11, 11}, - dictWord{4, 11, 276}, - dictWord{133, 11, 296}, - dictWord{6, 10, 343}, - dictWord{ - 7, - 10, - 195, - }, - dictWord{7, 11, 1777}, - dictWord{9, 10, 226}, - dictWord{10, 10, 197}, - dictWord{10, 10, 575}, - dictWord{11, 10, 502}, - dictWord{139, 10, 899}, - dictWord{ - 10, - 0, - 525, - }, - dictWord{139, 0, 82}, - dictWord{14, 0, 453}, - dictWord{4, 11, 7}, - dictWord{5, 11, 90}, - dictWord{5, 11, 158}, - dictWord{6, 11, 542}, - dictWord{7, 11, 221}, - dictWord{7, 11, 1574}, - dictWord{9, 11, 490}, - dictWord{10, 11, 540}, - dictWord{11, 11, 443}, - dictWord{139, 11, 757}, - dictWord{135, 0, 666}, - dictWord{ - 22, - 10, - 29, - }, - dictWord{150, 11, 29}, - dictWord{4, 0, 422}, - dictWord{147, 10, 8}, - dictWord{5, 0, 355}, - dictWord{145, 0, 0}, - dictWord{6, 0, 1873}, - dictWord{9, 0, 918}, - dictWord{7, 11, 588}, - dictWord{9, 11, 175}, - dictWord{138, 11, 530}, - dictWord{143, 11, 31}, - dictWord{11, 0, 165}, - dictWord{7, 10, 1125}, - dictWord{9, 10, 143}, - dictWord{14, 10, 405}, - dictWord{150, 10, 21}, - dictWord{9, 0, 260}, - dictWord{137, 0, 905}, - dictWord{5, 11, 872}, - dictWord{6, 11, 57}, - dictWord{6, 11, 479}, - dictWord{ - 6, - 11, - 562, - }, - dictWord{7, 11, 471}, - dictWord{7, 11, 1060}, - dictWord{9, 11, 447}, - dictWord{9, 11, 454}, - dictWord{141, 11, 6}, - dictWord{138, 11, 704}, - dictWord{133, 0, 865}, - dictWord{5, 0, 914}, - dictWord{134, 0, 1625}, - dictWord{133, 0, 234}, - dictWord{7, 0, 1383}, - dictWord{5, 11, 31}, - dictWord{6, 11, 614}, - dictWord{145, 11, 61}, - dictWord{7, 11, 1200}, - dictWord{138, 11, 460}, - dictWord{6, 11, 424}, - dictWord{135, 11, 1866}, - dictWord{136, 0, 306}, - dictWord{ - 5, - 10, - 959, - }, - dictWord{12, 11, 30}, - dictWord{13, 11, 148}, - dictWord{14, 11, 87}, - dictWord{14, 11, 182}, - dictWord{16, 11, 42}, - dictWord{18, 11, 92}, - dictWord{ - 148, - 11, - 70, - }, - dictWord{6, 0, 1919}, - dictWord{6, 0, 1921}, - dictWord{9, 0, 923}, - dictWord{9, 0, 930}, - dictWord{9, 0, 941}, - dictWord{9, 0, 949}, - dictWord{9, 0, 987}, - dictWord{ - 9, - 0, - 988, - }, - dictWord{9, 0, 992}, - dictWord{12, 0, 802}, - dictWord{12, 0, 815}, - dictWord{12, 0, 856}, - dictWord{12, 0, 885}, - dictWord{12, 0, 893}, - dictWord{ - 12, - 0, - 898, - }, - dictWord{12, 0, 919}, - dictWord{12, 0, 920}, - dictWord{12, 0, 941}, - dictWord{12, 0, 947}, - dictWord{15, 0, 183}, - dictWord{15, 0, 185}, - dictWord{15, 0, 189}, - dictWord{15, 0, 197}, - dictWord{15, 0, 202}, - dictWord{15, 0, 233}, - dictWord{18, 0, 218}, - dictWord{18, 0, 219}, - dictWord{18, 0, 233}, - dictWord{143, 11, 156}, - dictWord{135, 10, 1759}, - dictWord{136, 10, 173}, - dictWord{13, 0, 163}, - dictWord{13, 0, 180}, - dictWord{18, 0, 78}, - dictWord{20, 0, 35}, - dictWord{5, 11, 13}, - dictWord{134, 11, 142}, - dictWord{134, 10, 266}, - dictWord{6, 11, 97}, - dictWord{7, 11, 116}, - dictWord{8, 11, 322}, - dictWord{8, 11, 755}, - dictWord{9, 11, 548}, - dictWord{10, 11, 714}, - dictWord{11, 11, 884}, - dictWord{141, 11, 324}, - dictWord{135, 0, 1312}, - dictWord{9, 0, 814}, - dictWord{137, 11, 676}, - dictWord{ - 133, - 0, - 707, - }, - dictWord{135, 0, 1493}, - dictWord{6, 0, 421}, - dictWord{7, 0, 61}, - dictWord{7, 0, 1540}, - dictWord{10, 0, 11}, - dictWord{138, 0, 501}, - dictWord{12, 0, 733}, - dictWord{12, 0, 766}, - dictWord{7, 11, 866}, - dictWord{135, 11, 1163}, - dictWord{137, 0, 341}, - dictWord{142, 0, 98}, - dictWord{145, 11, 115}, - dictWord{ - 135, - 11, - 1111, - }, - dictWord{136, 10, 300}, - dictWord{136, 0, 1014}, - dictWord{8, 11, 1}, - dictWord{9, 11, 112}, - dictWord{138, 11, 326}, - dictWord{132, 11, 730}, - dictWord{5, 11, 488}, - dictWord{6, 11, 527}, - dictWord{7, 11, 489}, - dictWord{7, 11, 1636}, - dictWord{8, 11, 121}, - dictWord{8, 11, 144}, - dictWord{8, 11, 359}, - dictWord{ - 9, - 11, - 193, - }, - dictWord{9, 11, 241}, - dictWord{9, 11, 336}, - dictWord{9, 11, 882}, - dictWord{11, 11, 266}, - dictWord{11, 11, 372}, - dictWord{11, 11, 944}, - dictWord{ - 12, - 11, - 401, - }, - dictWord{140, 11, 641}, - dictWord{6, 0, 971}, - dictWord{134, 0, 1121}, - dictWord{6, 0, 102}, - dictWord{7, 0, 72}, - dictWord{15, 0, 142}, - dictWord{ - 147, - 0, - 67, - }, - dictWord{151, 0, 30}, - dictWord{135, 0, 823}, - dictWord{134, 0, 1045}, - dictWord{5, 10, 427}, - dictWord{5, 10, 734}, - dictWord{7, 10, 478}, - dictWord{ - 136, - 10, - 52, - }, - dictWord{7, 0, 1930}, - dictWord{11, 10, 217}, - dictWord{142, 10, 165}, - dictWord{6, 0, 1512}, - dictWord{135, 0, 1870}, - dictWord{9, 11, 31}, - dictWord{ - 10, - 11, - 244, - }, - dictWord{10, 11, 699}, - dictWord{12, 11, 149}, - dictWord{141, 11, 497}, - dictWord{133, 11, 377}, - dictWord{145, 11, 101}, - dictWord{ - 10, - 11, - 158, - }, - dictWord{13, 11, 13}, - dictWord{13, 11, 137}, - dictWord{13, 11, 258}, - dictWord{14, 11, 111}, - dictWord{14, 11, 225}, - dictWord{14, 11, 253}, - dictWord{ - 14, - 11, - 304, - }, - dictWord{14, 11, 339}, - dictWord{14, 11, 417}, - dictWord{146, 11, 33}, - dictWord{6, 0, 87}, - dictWord{6, 10, 1734}, - dictWord{7, 10, 20}, - dictWord{ - 7, - 10, - 1056, - }, - dictWord{8, 10, 732}, - dictWord{9, 10, 406}, - dictWord{9, 10, 911}, - dictWord{138, 10, 694}, - dictWord{134, 0, 1243}, - dictWord{137, 0, 245}, - dictWord{ - 7, - 0, - 68, - }, - dictWord{8, 0, 48}, - dictWord{8, 0, 88}, - dictWord{8, 0, 582}, - dictWord{8, 0, 681}, - dictWord{9, 0, 373}, - dictWord{9, 0, 864}, - dictWord{11, 0, 157}, - dictWord{ - 11, - 0, - 336, - }, - dictWord{11, 0, 843}, - dictWord{148, 0, 27}, - dictWord{8, 11, 663}, - dictWord{144, 11, 8}, - dictWord{133, 10, 613}, - dictWord{4, 0, 88}, - dictWord{ - 5, - 0, - 137, - }, - dictWord{5, 0, 174}, - dictWord{5, 0, 777}, - dictWord{6, 0, 1664}, - dictWord{6, 0, 1725}, - dictWord{7, 0, 77}, - dictWord{7, 0, 426}, - dictWord{7, 0, 1317}, - dictWord{ - 7, - 0, - 1355, - }, - dictWord{8, 0, 126}, - dictWord{8, 0, 563}, - dictWord{9, 0, 523}, - dictWord{9, 0, 750}, - dictWord{10, 0, 310}, - dictWord{10, 0, 836}, - dictWord{11, 0, 42}, - dictWord{11, 0, 318}, - dictWord{11, 0, 731}, - dictWord{12, 0, 68}, - dictWord{12, 0, 92}, - dictWord{12, 0, 507}, - dictWord{12, 0, 692}, - dictWord{13, 0, 81}, - dictWord{ - 13, - 0, - 238, - }, - dictWord{13, 0, 374}, - dictWord{14, 0, 436}, - dictWord{18, 0, 138}, - dictWord{19, 0, 78}, - dictWord{19, 0, 111}, - dictWord{20, 0, 55}, - dictWord{20, 0, 77}, - dictWord{148, 0, 92}, - dictWord{141, 0, 418}, - dictWord{4, 0, 938}, - dictWord{137, 0, 625}, - dictWord{138, 0, 351}, - dictWord{5, 11, 843}, - dictWord{7, 10, 32}, - dictWord{ - 7, - 10, - 984, - }, - dictWord{8, 10, 85}, - dictWord{8, 10, 709}, - dictWord{9, 10, 579}, - dictWord{9, 10, 847}, - dictWord{9, 10, 856}, - dictWord{10, 10, 799}, - dictWord{ - 11, - 10, - 258, - }, - dictWord{11, 10, 1007}, - dictWord{12, 10, 331}, - dictWord{12, 10, 615}, - dictWord{13, 10, 188}, - dictWord{13, 10, 435}, - dictWord{14, 10, 8}, - dictWord{ - 15, - 10, - 165, - }, - dictWord{16, 10, 27}, - dictWord{148, 10, 40}, - dictWord{6, 0, 1668}, - dictWord{7, 0, 1499}, - dictWord{8, 0, 117}, - dictWord{9, 0, 314}, - dictWord{ - 138, - 0, - 174, - }, - dictWord{135, 0, 707}, - dictWord{132, 11, 554}, - dictWord{133, 11, 536}, - dictWord{5, 0, 403}, - dictWord{5, 11, 207}, - dictWord{9, 11, 79}, - dictWord{ - 11, - 11, - 625, - }, - dictWord{145, 11, 7}, - dictWord{132, 11, 424}, - dictWord{136, 11, 785}, - dictWord{4, 10, 167}, - dictWord{135, 10, 82}, - dictWord{9, 0, 7}, - dictWord{ - 23, - 0, - 6, - }, - dictWord{9, 11, 7}, - dictWord{151, 11, 6}, - dictWord{6, 0, 282}, - dictWord{5, 10, 62}, - dictWord{6, 10, 534}, - dictWord{7, 10, 74}, - dictWord{7, 10, 678}, - dictWord{ - 7, - 10, - 684, - }, - dictWord{7, 10, 1043}, - dictWord{7, 10, 1072}, - dictWord{8, 10, 280}, - dictWord{8, 10, 541}, - dictWord{8, 10, 686}, - dictWord{9, 10, 258}, - dictWord{ - 10, - 10, - 519, - }, - dictWord{11, 10, 252}, - dictWord{140, 10, 282}, - dictWord{138, 10, 33}, - dictWord{132, 10, 359}, - dictWord{4, 0, 44}, - dictWord{5, 0, 311}, - dictWord{ - 6, - 0, - 156, - }, - dictWord{7, 0, 639}, - dictWord{7, 0, 762}, - dictWord{7, 0, 1827}, - dictWord{9, 0, 8}, - dictWord{9, 0, 462}, - dictWord{148, 0, 83}, - dictWord{7, 11, 769}, - dictWord{ - 9, - 11, - 18, - }, - dictWord{138, 11, 358}, - dictWord{4, 0, 346}, - dictWord{7, 0, 115}, - dictWord{9, 0, 180}, - dictWord{9, 0, 456}, - dictWord{10, 0, 363}, - dictWord{ - 4, - 11, - 896, - }, - dictWord{134, 11, 1777}, - dictWord{133, 10, 211}, - dictWord{7, 0, 761}, - dictWord{7, 0, 1051}, - dictWord{137, 0, 545}, - dictWord{6, 10, 145}, - dictWord{ - 141, - 10, - 336, - }, - dictWord{7, 11, 750}, - dictWord{9, 11, 223}, - dictWord{11, 11, 27}, - dictWord{11, 11, 466}, - dictWord{12, 11, 624}, - dictWord{14, 11, 265}, - dictWord{146, 11, 61}, - dictWord{6, 0, 752}, - dictWord{6, 0, 768}, - dictWord{6, 0, 1195}, - dictWord{6, 0, 1254}, - dictWord{6, 0, 1619}, - dictWord{137, 0, 835}, - dictWord{ - 6, - 0, - 1936, - }, - dictWord{8, 0, 930}, - dictWord{136, 0, 960}, - dictWord{132, 10, 263}, - dictWord{132, 11, 249}, - dictWord{12, 0, 653}, - dictWord{132, 10, 916}, - dictWord{4, 11, 603}, - dictWord{133, 11, 661}, - dictWord{8, 0, 344}, - dictWord{4, 11, 11}, - dictWord{6, 11, 128}, - dictWord{7, 11, 231}, - dictWord{7, 11, 1533}, - dictWord{138, 11, 725}, - dictWord{134, 0, 1483}, - dictWord{134, 0, 875}, - dictWord{6, 0, 185}, - dictWord{7, 0, 1899}, - dictWord{9, 0, 875}, - dictWord{139, 0, 673}, - dictWord{15, 10, 155}, - dictWord{144, 10, 79}, - dictWord{7, 0, 93}, - dictWord{7, 0, 210}, - dictWord{7, 0, 1223}, - dictWord{8, 0, 451}, - dictWord{8, 0, 460}, - dictWord{ - 11, - 0, - 353, - }, - dictWord{11, 0, 475}, - dictWord{4, 10, 599}, - dictWord{6, 10, 1634}, - dictWord{7, 10, 67}, - dictWord{7, 10, 691}, - dictWord{7, 10, 979}, - dictWord{ - 7, - 10, - 1697, - }, - dictWord{8, 10, 207}, - dictWord{8, 10, 214}, - dictWord{8, 10, 231}, - dictWord{8, 10, 294}, - dictWord{8, 10, 336}, - dictWord{8, 10, 428}, - dictWord{ - 8, - 10, - 471, - }, - dictWord{8, 10, 622}, - dictWord{8, 10, 626}, - dictWord{8, 10, 679}, - dictWord{8, 10, 759}, - dictWord{8, 10, 829}, - dictWord{9, 10, 11}, - dictWord{9, 10, 246}, - dictWord{9, 10, 484}, - dictWord{9, 10, 573}, - dictWord{9, 10, 706}, - dictWord{9, 10, 762}, - dictWord{9, 10, 798}, - dictWord{9, 10, 855}, - dictWord{9, 10, 870}, - dictWord{ - 9, - 10, - 912, - }, - dictWord{10, 10, 303}, - dictWord{10, 10, 335}, - dictWord{10, 10, 424}, - dictWord{10, 10, 461}, - dictWord{10, 10, 543}, - dictWord{10, 10, 759}, - dictWord{10, 10, 814}, - dictWord{11, 10, 59}, - dictWord{11, 10, 235}, - dictWord{11, 10, 590}, - dictWord{11, 10, 929}, - dictWord{11, 10, 963}, - dictWord{ - 11, - 10, - 987, - }, - dictWord{12, 10, 114}, - dictWord{12, 10, 182}, - dictWord{12, 10, 226}, - dictWord{12, 10, 332}, - dictWord{12, 10, 439}, - dictWord{12, 10, 575}, - dictWord{ - 12, - 10, - 598, - }, - dictWord{12, 10, 675}, - dictWord{13, 10, 8}, - dictWord{13, 10, 125}, - dictWord{13, 10, 194}, - dictWord{13, 10, 287}, - dictWord{14, 10, 197}, - dictWord{14, 10, 383}, - dictWord{15, 10, 53}, - dictWord{17, 10, 63}, - dictWord{19, 10, 46}, - dictWord{19, 10, 98}, - dictWord{19, 10, 106}, - dictWord{148, 10, 85}, - dictWord{132, 11, 476}, - dictWord{4, 0, 327}, - dictWord{5, 0, 478}, - dictWord{7, 0, 1332}, - dictWord{136, 0, 753}, - dictWord{5, 0, 1020}, - dictWord{133, 0, 1022}, - dictWord{135, 11, 1807}, - dictWord{4, 0, 103}, - dictWord{133, 0, 401}, - dictWord{4, 0, 499}, - dictWord{135, 0, 1421}, - dictWord{10, 0, 207}, - dictWord{13, 0, 164}, - dictWord{147, 10, 126}, - dictWord{9, 11, 20}, - dictWord{10, 11, 324}, - dictWord{139, 11, 488}, - dictWord{132, 0, 96}, - dictWord{9, 11, 280}, - dictWord{ - 138, - 11, - 134, - }, - dictWord{135, 0, 968}, - dictWord{133, 10, 187}, - dictWord{135, 10, 1286}, - dictWord{5, 11, 112}, - dictWord{6, 11, 103}, - dictWord{134, 11, 150}, - dictWord{8, 0, 914}, - dictWord{10, 0, 3}, - dictWord{4, 10, 215}, - dictWord{9, 10, 38}, - dictWord{11, 10, 23}, - dictWord{11, 10, 127}, - dictWord{139, 10, 796}, - dictWord{ - 135, - 0, - 399, - }, - dictWord{6, 0, 563}, - dictWord{137, 0, 224}, - dictWord{6, 0, 704}, - dictWord{134, 0, 1214}, - dictWord{4, 11, 708}, - dictWord{8, 11, 15}, - dictWord{ - 9, - 11, - 50, - }, - dictWord{9, 11, 386}, - dictWord{11, 11, 18}, - dictWord{11, 11, 529}, - dictWord{140, 11, 228}, - dictWord{4, 11, 563}, - dictWord{7, 11, 109}, - dictWord{ - 7, - 11, - 592, - }, - dictWord{7, 11, 637}, - dictWord{7, 11, 770}, - dictWord{7, 11, 1701}, - dictWord{8, 11, 436}, - dictWord{8, 11, 463}, - dictWord{9, 11, 60}, - dictWord{9, 11, 335}, - dictWord{9, 11, 904}, - dictWord{10, 11, 73}, - dictWord{11, 11, 434}, - dictWord{12, 11, 585}, - dictWord{13, 11, 331}, - dictWord{18, 11, 110}, - dictWord{ - 148, - 11, - 60, - }, - dictWord{134, 0, 1559}, - dictWord{132, 11, 502}, - dictWord{6, 11, 347}, - dictWord{138, 11, 161}, - dictWord{4, 11, 33}, - dictWord{5, 11, 102}, - dictWord{ - 5, - 11, - 500, - }, - dictWord{6, 11, 284}, - dictWord{7, 11, 1079}, - dictWord{7, 11, 1423}, - dictWord{7, 11, 1702}, - dictWord{8, 11, 470}, - dictWord{9, 11, 554}, - dictWord{ - 9, - 11, - 723, - }, - dictWord{139, 11, 333}, - dictWord{7, 11, 246}, - dictWord{135, 11, 840}, - dictWord{6, 11, 10}, - dictWord{8, 11, 571}, - dictWord{9, 11, 739}, - dictWord{ - 143, - 11, - 91, - }, - dictWord{8, 0, 861}, - dictWord{10, 0, 905}, - dictWord{12, 0, 730}, - dictWord{12, 0, 789}, - dictWord{133, 11, 626}, - dictWord{134, 0, 946}, - dictWord{ - 5, - 0, - 746, - }, - dictWord{12, 0, 333}, - dictWord{14, 0, 332}, - dictWord{12, 11, 333}, - dictWord{142, 11, 332}, - dictWord{5, 11, 18}, - dictWord{6, 11, 526}, - dictWord{ - 13, - 11, - 24, - }, - dictWord{13, 11, 110}, - dictWord{19, 11, 5}, - dictWord{147, 11, 44}, - dictWord{4, 0, 910}, - dictWord{5, 0, 832}, - dictWord{135, 10, 2002}, - dictWord{ - 10, - 11, - 768, - }, - dictWord{139, 11, 787}, - dictWord{4, 11, 309}, - dictWord{5, 11, 462}, - dictWord{7, 11, 970}, - dictWord{135, 11, 1097}, - dictWord{4, 10, 28}, - dictWord{ - 5, - 10, - 440, - }, - dictWord{7, 10, 248}, - dictWord{11, 10, 833}, - dictWord{140, 10, 344}, - dictWord{134, 10, 1654}, - dictWord{6, 0, 632}, - dictWord{6, 0, 652}, - dictWord{ - 6, - 0, - 1272, - }, - dictWord{6, 0, 1384}, - dictWord{134, 0, 1560}, - dictWord{134, 11, 1704}, - dictWord{6, 0, 1393}, - dictWord{133, 10, 853}, - dictWord{6, 10, 249}, - dictWord{7, 10, 1234}, - dictWord{139, 10, 573}, - dictWord{5, 11, 86}, - dictWord{7, 11, 743}, - dictWord{9, 11, 85}, - dictWord{10, 11, 281}, - dictWord{10, 11, 432}, - dictWord{11, 11, 490}, - dictWord{12, 11, 251}, - dictWord{13, 11, 118}, - dictWord{14, 11, 378}, - dictWord{146, 11, 143}, - dictWord{5, 11, 524}, - dictWord{ - 133, - 11, - 744, - }, - dictWord{134, 0, 1514}, - dictWord{10, 0, 201}, - dictWord{142, 0, 319}, - dictWord{7, 0, 717}, - dictWord{10, 0, 510}, - dictWord{7, 10, 392}, - dictWord{ - 8, - 10, - 20, - }, - dictWord{8, 10, 172}, - dictWord{8, 10, 690}, - dictWord{9, 10, 383}, - dictWord{9, 10, 845}, - dictWord{11, 10, 293}, - dictWord{11, 10, 832}, - dictWord{ - 11, - 10, - 920, - }, - dictWord{11, 10, 984}, - dictWord{141, 10, 221}, - dictWord{134, 0, 1381}, - dictWord{5, 10, 858}, - dictWord{133, 10, 992}, - dictWord{8, 0, 528}, - dictWord{137, 0, 348}, - dictWord{10, 11, 107}, - dictWord{140, 11, 436}, - dictWord{4, 0, 20}, - dictWord{133, 0, 616}, - dictWord{134, 0, 1251}, - dictWord{ - 132, - 11, - 927, - }, - dictWord{10, 11, 123}, - dictWord{12, 11, 670}, - dictWord{13, 11, 371}, - dictWord{14, 11, 142}, - dictWord{146, 11, 94}, - dictWord{134, 0, 1163}, - dictWord{ - 7, - 11, - 1149, - }, - dictWord{137, 11, 156}, - dictWord{134, 0, 307}, - dictWord{133, 11, 778}, - dictWord{7, 0, 1091}, - dictWord{135, 0, 1765}, - dictWord{ - 5, - 11, - 502, - }, - dictWord{6, 10, 268}, - dictWord{137, 10, 62}, - dictWord{8, 11, 196}, - dictWord{10, 11, 283}, - dictWord{139, 11, 406}, - dictWord{4, 0, 26}, - dictWord{ - 5, - 0, - 429, - }, - dictWord{6, 0, 245}, - dictWord{7, 0, 704}, - dictWord{7, 0, 1379}, - dictWord{135, 0, 1474}, - dictWord{133, 11, 855}, - dictWord{132, 0, 881}, - dictWord{ - 4, - 0, - 621, - }, - dictWord{135, 11, 1596}, - dictWord{7, 11, 1400}, - dictWord{9, 11, 446}, - dictWord{138, 11, 45}, - dictWord{6, 0, 736}, - dictWord{138, 10, 106}, - dictWord{133, 0, 542}, - dictWord{134, 0, 348}, - dictWord{133, 0, 868}, - dictWord{136, 0, 433}, - dictWord{135, 0, 1495}, - dictWord{138, 0, 771}, - dictWord{ - 6, - 10, - 613, - }, - dictWord{136, 10, 223}, - dictWord{138, 0, 215}, - dictWord{141, 0, 124}, - dictWord{136, 11, 391}, - dictWord{135, 11, 172}, - dictWord{132, 10, 670}, - dictWord{140, 0, 55}, - dictWord{9, 10, 40}, - dictWord{139, 10, 136}, - dictWord{7, 0, 62}, - dictWord{147, 0, 112}, - dictWord{132, 0, 856}, - dictWord{132, 11, 568}, - dictWord{12, 0, 270}, - dictWord{139, 10, 259}, - dictWord{8, 0, 572}, - dictWord{137, 0, 698}, - dictWord{4, 11, 732}, - dictWord{9, 10, 310}, - dictWord{137, 10, 682}, - dictWord{142, 10, 296}, - dictWord{134, 0, 939}, - dictWord{136, 11, 733}, - dictWord{135, 11, 1435}, - dictWord{7, 10, 1401}, - dictWord{135, 10, 1476}, - dictWord{6, 0, 352}, - dictWord{4, 10, 296}, - dictWord{7, 10, 401}, - dictWord{7, 10, 1410}, - dictWord{7, 10, 1594}, - dictWord{7, 10, 1674}, - dictWord{8, 10, 63}, - dictWord{ - 8, - 10, - 660, - }, - dictWord{137, 10, 74}, - dictWord{4, 11, 428}, - dictWord{133, 11, 668}, - dictWord{4, 10, 139}, - dictWord{4, 10, 388}, - dictWord{140, 10, 188}, - dictWord{7, 11, 2015}, - dictWord{140, 11, 665}, - dictWord{132, 0, 647}, - dictWord{146, 0, 10}, - dictWord{138, 0, 220}, - dictWord{142, 0, 464}, - dictWord{ - 132, - 0, - 109, - }, - dictWord{134, 0, 1746}, - dictWord{6, 0, 515}, - dictWord{4, 10, 747}, - dictWord{6, 11, 1623}, - dictWord{6, 11, 1681}, - dictWord{7, 10, 649}, - dictWord{ - 7, - 10, - 1479, - }, - dictWord{135, 10, 1583}, - dictWord{133, 10, 232}, - dictWord{135, 0, 566}, - dictWord{137, 10, 887}, - dictWord{4, 0, 40}, - dictWord{10, 0, 67}, - dictWord{ - 11, - 0, - 117, - }, - dictWord{11, 0, 768}, - dictWord{139, 0, 935}, - dictWord{132, 0, 801}, - dictWord{7, 0, 992}, - dictWord{8, 0, 301}, - dictWord{9, 0, 722}, - dictWord{ - 12, - 0, - 63, - }, - dictWord{13, 0, 29}, - dictWord{14, 0, 161}, - dictWord{143, 0, 18}, - dictWord{139, 0, 923}, - dictWord{6, 11, 1748}, - dictWord{8, 11, 715}, - dictWord{9, 11, 802}, - dictWord{10, 11, 46}, - dictWord{10, 11, 819}, - dictWord{13, 11, 308}, - dictWord{14, 11, 351}, - dictWord{14, 11, 363}, - dictWord{146, 11, 67}, - dictWord{ - 137, - 11, - 745, - }, - dictWord{7, 0, 1145}, - dictWord{4, 10, 14}, - dictWord{7, 10, 1801}, - dictWord{10, 10, 748}, - dictWord{141, 10, 458}, - dictWord{4, 11, 63}, - dictWord{ - 5, - 11, - 347, - }, - dictWord{134, 11, 474}, - dictWord{135, 0, 568}, - dictWord{4, 10, 425}, - dictWord{7, 11, 577}, - dictWord{7, 11, 1432}, - dictWord{9, 11, 475}, - dictWord{ - 9, - 11, - 505, - }, - dictWord{9, 11, 526}, - dictWord{9, 11, 609}, - dictWord{9, 11, 689}, - dictWord{9, 11, 726}, - dictWord{9, 11, 735}, - dictWord{9, 11, 738}, - dictWord{ - 10, - 11, - 556, - }, - dictWord{10, 11, 674}, - dictWord{10, 11, 684}, - dictWord{11, 11, 89}, - dictWord{11, 11, 202}, - dictWord{11, 11, 272}, - dictWord{11, 11, 380}, - dictWord{ - 11, - 11, - 415, - }, - dictWord{11, 11, 505}, - dictWord{11, 11, 537}, - dictWord{11, 11, 550}, - dictWord{11, 11, 562}, - dictWord{11, 11, 640}, - dictWord{11, 11, 667}, - dictWord{11, 11, 688}, - dictWord{11, 11, 847}, - dictWord{11, 11, 927}, - dictWord{11, 11, 930}, - dictWord{11, 11, 940}, - dictWord{12, 11, 144}, - dictWord{ - 12, - 11, - 325, - }, - dictWord{12, 11, 329}, - dictWord{12, 11, 389}, - dictWord{12, 11, 403}, - dictWord{12, 11, 451}, - dictWord{12, 11, 515}, - dictWord{12, 11, 604}, - dictWord{ - 12, - 11, - 616, - }, - dictWord{12, 11, 626}, - dictWord{13, 11, 66}, - dictWord{13, 11, 131}, - dictWord{13, 11, 167}, - dictWord{13, 11, 236}, - dictWord{13, 11, 368}, - dictWord{13, 11, 411}, - dictWord{13, 11, 434}, - dictWord{13, 11, 453}, - dictWord{13, 11, 461}, - dictWord{13, 11, 474}, - dictWord{14, 11, 59}, - dictWord{14, 11, 60}, - dictWord{14, 11, 139}, - dictWord{14, 11, 152}, - dictWord{14, 11, 276}, - dictWord{14, 11, 353}, - dictWord{14, 11, 402}, - dictWord{15, 11, 28}, - dictWord{ - 15, - 11, - 81, - }, - dictWord{15, 11, 123}, - dictWord{15, 11, 152}, - dictWord{18, 11, 136}, - dictWord{148, 11, 88}, - dictWord{137, 0, 247}, - dictWord{135, 11, 1622}, - dictWord{ - 9, - 11, - 544, - }, - dictWord{11, 11, 413}, - dictWord{144, 11, 25}, - dictWord{4, 0, 645}, - dictWord{7, 0, 825}, - dictWord{6, 10, 1768}, - dictWord{135, 11, 89}, - dictWord{140, 0, 328}, - dictWord{5, 10, 943}, - dictWord{134, 10, 1779}, - dictWord{134, 0, 1363}, - dictWord{5, 10, 245}, - dictWord{6, 10, 576}, - dictWord{7, 10, 582}, - dictWord{136, 10, 225}, - dictWord{134, 0, 1280}, - dictWord{5, 11, 824}, - dictWord{133, 11, 941}, - dictWord{7, 11, 440}, - dictWord{8, 11, 230}, - dictWord{ - 139, - 11, - 106, - }, - dictWord{5, 0, 28}, - dictWord{6, 0, 204}, - dictWord{10, 0, 320}, - dictWord{10, 0, 583}, - dictWord{13, 0, 502}, - dictWord{14, 0, 72}, - dictWord{14, 0, 274}, - dictWord{14, 0, 312}, - dictWord{14, 0, 344}, - dictWord{15, 0, 159}, - dictWord{16, 0, 62}, - dictWord{16, 0, 69}, - dictWord{17, 0, 30}, - dictWord{18, 0, 42}, - dictWord{ - 18, - 0, - 53, - }, - dictWord{18, 0, 84}, - dictWord{18, 0, 140}, - dictWord{19, 0, 68}, - dictWord{19, 0, 85}, - dictWord{20, 0, 5}, - dictWord{20, 0, 45}, - dictWord{20, 0, 101}, - dictWord{ - 22, - 0, - 7, - }, - dictWord{150, 0, 20}, - dictWord{4, 0, 558}, - dictWord{6, 0, 390}, - dictWord{7, 0, 162}, - dictWord{7, 0, 689}, - dictWord{9, 0, 360}, - dictWord{138, 0, 653}, - dictWord{134, 0, 764}, - dictWord{6, 0, 862}, - dictWord{137, 0, 833}, - dictWord{5, 0, 856}, - dictWord{6, 0, 1672}, - dictWord{6, 0, 1757}, - dictWord{134, 0, 1781}, - dictWord{ - 5, - 0, - 92, - }, - dictWord{10, 0, 736}, - dictWord{140, 0, 102}, - dictWord{6, 0, 1927}, - dictWord{6, 0, 1944}, - dictWord{8, 0, 924}, - dictWord{8, 0, 948}, - dictWord{ - 10, - 0, - 967, - }, - dictWord{138, 0, 978}, - dictWord{134, 0, 1479}, - dictWord{5, 0, 590}, - dictWord{8, 0, 360}, - dictWord{9, 0, 213}, - dictWord{138, 0, 63}, - dictWord{ - 134, - 0, - 1521, - }, - dictWord{6, 0, 709}, - dictWord{134, 0, 891}, - dictWord{132, 10, 443}, - dictWord{13, 0, 477}, - dictWord{14, 0, 120}, - dictWord{148, 0, 61}, - dictWord{ - 4, - 11, - 914, - }, - dictWord{5, 11, 800}, - dictWord{133, 11, 852}, - dictWord{10, 11, 54}, - dictWord{141, 11, 115}, - dictWord{4, 11, 918}, - dictWord{133, 11, 876}, - dictWord{139, 11, 152}, - dictWord{4, 11, 92}, - dictWord{133, 11, 274}, - dictWord{135, 11, 1901}, - dictWord{9, 11, 800}, - dictWord{10, 11, 693}, - dictWord{ - 11, - 11, - 482, - }, - dictWord{11, 11, 734}, - dictWord{139, 11, 789}, - dictWord{9, 0, 483}, - dictWord{132, 10, 298}, - dictWord{6, 0, 1213}, - dictWord{141, 11, 498}, - dictWord{135, 11, 1451}, - dictWord{133, 11, 743}, - dictWord{4, 0, 1022}, - dictWord{10, 0, 1000}, - dictWord{12, 0, 957}, - dictWord{12, 0, 980}, - dictWord{ - 12, - 0, - 1013, - }, - dictWord{14, 0, 481}, - dictWord{144, 0, 116}, - dictWord{8, 0, 503}, - dictWord{17, 0, 29}, - dictWord{4, 11, 49}, - dictWord{7, 11, 280}, - dictWord{ - 135, - 11, - 1633, - }, - dictWord{135, 0, 1712}, - dictWord{134, 0, 466}, - dictWord{136, 11, 47}, - dictWord{5, 10, 164}, - dictWord{7, 10, 121}, - dictWord{142, 10, 189}, - dictWord{ - 7, - 10, - 812, - }, - dictWord{7, 10, 1261}, - dictWord{7, 10, 1360}, - dictWord{9, 10, 632}, - dictWord{140, 10, 352}, - dictWord{139, 10, 556}, - dictWord{132, 0, 731}, - dictWord{5, 11, 272}, - dictWord{5, 11, 908}, - dictWord{5, 11, 942}, - dictWord{7, 11, 1008}, - dictWord{7, 11, 1560}, - dictWord{8, 11, 197}, - dictWord{9, 11, 47}, - dictWord{11, 11, 538}, - dictWord{139, 11, 742}, - dictWord{4, 10, 172}, - dictWord{9, 10, 611}, - dictWord{10, 10, 436}, - dictWord{12, 10, 673}, - dictWord{ - 141, - 10, - 255, - }, - dictWord{133, 10, 844}, - dictWord{10, 0, 484}, - dictWord{11, 0, 754}, - dictWord{12, 0, 457}, - dictWord{14, 0, 171}, - dictWord{14, 0, 389}, - dictWord{ - 146, - 0, - 153, - }, - dictWord{9, 10, 263}, - dictWord{10, 10, 147}, - dictWord{138, 10, 492}, - dictWord{137, 11, 891}, - dictWord{138, 0, 241}, - dictWord{133, 10, 537}, - dictWord{6, 0, 2005}, - dictWord{136, 0, 964}, - dictWord{137, 10, 842}, - dictWord{151, 11, 8}, - dictWord{4, 11, 407}, - dictWord{132, 11, 560}, - dictWord{ - 135, - 11, - 1884, - }, - dictWord{6, 0, 1100}, - dictWord{134, 0, 1242}, - dictWord{135, 0, 954}, - dictWord{5, 10, 230}, - dictWord{5, 10, 392}, - dictWord{6, 10, 420}, - dictWord{ - 9, - 10, - 568, - }, - dictWord{140, 10, 612}, - dictWord{4, 11, 475}, - dictWord{11, 11, 35}, - dictWord{11, 11, 90}, - dictWord{13, 11, 7}, - dictWord{13, 11, 71}, - dictWord{ - 13, - 11, - 177, - }, - dictWord{142, 11, 422}, - dictWord{136, 11, 332}, - dictWord{135, 0, 1958}, - dictWord{6, 0, 549}, - dictWord{8, 0, 34}, - dictWord{8, 0, 283}, - dictWord{ - 9, - 0, - 165, - }, - dictWord{138, 0, 475}, - dictWord{10, 0, 952}, - dictWord{12, 0, 966}, - dictWord{140, 0, 994}, - dictWord{5, 0, 652}, - dictWord{5, 0, 701}, - dictWord{ - 135, - 0, - 449, - }, - dictWord{4, 0, 655}, - dictWord{7, 0, 850}, - dictWord{17, 0, 75}, - dictWord{146, 0, 137}, - dictWord{4, 0, 146}, - dictWord{7, 0, 1618}, - dictWord{8, 0, 670}, - dictWord{ - 5, - 10, - 41, - }, - dictWord{7, 10, 1459}, - dictWord{7, 10, 1469}, - dictWord{7, 10, 1859}, - dictWord{9, 10, 549}, - dictWord{139, 10, 905}, - dictWord{133, 10, 696}, - dictWord{6, 0, 159}, - dictWord{6, 0, 364}, - dictWord{7, 0, 516}, - dictWord{137, 0, 518}, - dictWord{135, 0, 1439}, - dictWord{6, 11, 222}, - dictWord{7, 11, 636}, - dictWord{ - 7, - 11, - 1620, - }, - dictWord{8, 11, 409}, - dictWord{9, 11, 693}, - dictWord{139, 11, 77}, - dictWord{13, 0, 151}, - dictWord{141, 11, 45}, - dictWord{6, 0, 1027}, - dictWord{ - 4, - 11, - 336, - }, - dictWord{132, 10, 771}, - dictWord{139, 11, 392}, - dictWord{10, 11, 121}, - dictWord{11, 11, 175}, - dictWord{149, 11, 16}, - dictWord{8, 0, 950}, - dictWord{138, 0, 983}, - dictWord{133, 10, 921}, - dictWord{135, 0, 993}, - dictWord{6, 10, 180}, - dictWord{7, 10, 1137}, - dictWord{8, 10, 751}, - dictWord{ - 139, - 10, - 805, - }, - dictWord{7, 0, 501}, - dictWord{9, 0, 111}, - dictWord{10, 0, 141}, - dictWord{11, 0, 332}, - dictWord{13, 0, 43}, - dictWord{13, 0, 429}, - dictWord{14, 0, 130}, - dictWord{14, 0, 415}, - dictWord{145, 0, 102}, - dictWord{4, 10, 183}, - dictWord{5, 11, 882}, - dictWord{7, 10, 271}, - dictWord{11, 10, 824}, - dictWord{11, 10, 952}, - dictWord{13, 10, 278}, - dictWord{13, 10, 339}, - dictWord{13, 10, 482}, - dictWord{14, 10, 424}, - dictWord{148, 10, 99}, - dictWord{4, 10, 19}, - dictWord{5, 10, 477}, - dictWord{5, 10, 596}, - dictWord{6, 10, 505}, - dictWord{7, 10, 1221}, - dictWord{11, 10, 907}, - dictWord{12, 10, 209}, - dictWord{141, 10, 214}, - dictWord{ - 135, - 10, - 1215, - }, - dictWord{133, 0, 452}, - dictWord{132, 11, 426}, - dictWord{5, 0, 149}, - dictWord{136, 0, 233}, - dictWord{133, 0, 935}, - dictWord{6, 11, 58}, - dictWord{ - 7, - 11, - 654, - }, - dictWord{7, 11, 745}, - dictWord{7, 11, 1969}, - dictWord{8, 11, 240}, - dictWord{8, 11, 675}, - dictWord{9, 11, 479}, - dictWord{9, 11, 731}, - dictWord{ - 10, - 11, - 330, - }, - dictWord{10, 11, 593}, - dictWord{10, 11, 817}, - dictWord{11, 11, 32}, - dictWord{11, 11, 133}, - dictWord{11, 11, 221}, - dictWord{145, 11, 68}, - dictWord{ - 12, - 0, - 582, - }, - dictWord{18, 0, 131}, - dictWord{7, 11, 102}, - dictWord{137, 11, 538}, - dictWord{136, 0, 801}, - dictWord{134, 10, 1645}, - dictWord{132, 0, 70}, - dictWord{6, 10, 92}, - dictWord{6, 10, 188}, - dictWord{7, 10, 1269}, - dictWord{7, 10, 1524}, - dictWord{7, 10, 1876}, - dictWord{10, 10, 228}, - dictWord{139, 10, 1020}, - dictWord{4, 10, 459}, - dictWord{133, 10, 966}, - dictWord{138, 0, 369}, - dictWord{16, 0, 36}, - dictWord{140, 10, 330}, - dictWord{141, 11, 366}, - dictWord{ - 7, - 0, - 721, - }, - dictWord{10, 0, 236}, - dictWord{12, 0, 204}, - dictWord{6, 10, 18}, - dictWord{7, 10, 932}, - dictWord{8, 10, 757}, - dictWord{9, 10, 54}, - dictWord{9, 10, 65}, - dictWord{9, 10, 844}, - dictWord{10, 10, 113}, - dictWord{10, 10, 315}, - dictWord{10, 10, 798}, - dictWord{11, 10, 153}, - dictWord{12, 10, 151}, - dictWord{12, 10, 392}, - dictWord{12, 10, 666}, - dictWord{142, 10, 248}, - dictWord{7, 0, 241}, - dictWord{10, 0, 430}, - dictWord{8, 10, 548}, - dictWord{9, 10, 532}, - dictWord{10, 10, 117}, - dictWord{11, 10, 351}, - dictWord{11, 10, 375}, - dictWord{143, 10, 23}, - dictWord{134, 10, 1742}, - dictWord{133, 10, 965}, - dictWord{133, 11, 566}, - dictWord{ - 6, - 11, - 48, - }, - dictWord{135, 11, 63}, - dictWord{134, 10, 182}, - dictWord{10, 10, 65}, - dictWord{10, 10, 488}, - dictWord{138, 10, 497}, - dictWord{6, 11, 114}, - dictWord{7, 11, 1224}, - dictWord{7, 11, 1556}, - dictWord{136, 11, 3}, - dictWord{134, 0, 1817}, - dictWord{8, 11, 576}, - dictWord{137, 11, 267}, - dictWord{ - 6, - 0, - 1078, - }, - dictWord{144, 0, 16}, - dictWord{9, 10, 588}, - dictWord{138, 10, 260}, - dictWord{138, 0, 1021}, - dictWord{5, 0, 406}, - dictWord{134, 0, 2022}, - dictWord{133, 11, 933}, - dictWord{6, 0, 69}, - dictWord{135, 0, 117}, - dictWord{7, 0, 1830}, - dictWord{136, 11, 427}, - dictWord{4, 0, 432}, - dictWord{135, 0, 824}, - dictWord{134, 10, 1786}, - dictWord{133, 0, 826}, - dictWord{139, 11, 67}, - dictWord{133, 11, 759}, - dictWord{135, 10, 308}, - dictWord{137, 0, 816}, - dictWord{ - 133, - 0, - 1000, - }, - dictWord{4, 0, 297}, - dictWord{6, 0, 529}, - dictWord{7, 0, 152}, - dictWord{7, 0, 713}, - dictWord{7, 0, 1845}, - dictWord{8, 0, 710}, - dictWord{8, 0, 717}, - dictWord{12, 0, 639}, - dictWord{140, 0, 685}, - dictWord{7, 0, 423}, - dictWord{136, 10, 588}, - dictWord{136, 10, 287}, - dictWord{136, 0, 510}, - dictWord{ - 134, - 0, - 1048, - }, - dictWord{6, 0, 618}, - dictWord{7, 11, 56}, - dictWord{7, 11, 1989}, - dictWord{8, 11, 337}, - dictWord{8, 11, 738}, - dictWord{9, 11, 600}, - dictWord{ - 10, - 11, - 483, - }, - dictWord{12, 11, 37}, - dictWord{13, 11, 447}, - dictWord{142, 11, 92}, - dictWord{4, 0, 520}, - dictWord{135, 0, 575}, - dictWord{8, 0, 990}, - dictWord{ - 138, - 0, - 977, - }, - dictWord{135, 11, 774}, - dictWord{9, 11, 347}, - dictWord{11, 11, 24}, - dictWord{140, 11, 170}, - dictWord{136, 11, 379}, - dictWord{140, 10, 290}, - dictWord{132, 11, 328}, - dictWord{4, 0, 321}, - dictWord{134, 0, 569}, - dictWord{4, 11, 101}, - dictWord{135, 11, 1171}, - dictWord{7, 0, 723}, - dictWord{7, 0, 1135}, - dictWord{5, 11, 833}, - dictWord{136, 11, 744}, - dictWord{7, 10, 719}, - dictWord{8, 10, 809}, - dictWord{136, 10, 834}, - dictWord{8, 0, 921}, - dictWord{136, 10, 796}, - dictWord{5, 10, 210}, - dictWord{6, 10, 213}, - dictWord{7, 10, 60}, - dictWord{10, 10, 364}, - dictWord{139, 10, 135}, - dictWord{5, 0, 397}, - dictWord{6, 0, 154}, - dictWord{7, 0, 676}, - dictWord{8, 0, 443}, - dictWord{8, 0, 609}, - dictWord{9, 0, 24}, - dictWord{9, 0, 325}, - dictWord{10, 0, 35}, - dictWord{11, 0, 535}, - dictWord{11, 0, 672}, - dictWord{11, 0, 1018}, - dictWord{12, 0, 637}, - dictWord{16, 0, 30}, - dictWord{5, 10, 607}, - dictWord{8, 10, 326}, - dictWord{136, 10, 490}, - dictWord{4, 10, 701}, - dictWord{5, 10, 472}, - dictWord{6, 11, 9}, - dictWord{6, 11, 397}, - dictWord{7, 11, 53}, - dictWord{7, 11, 1742}, - dictWord{9, 10, 758}, - dictWord{10, 11, 632}, - dictWord{ - 11, - 11, - 828, - }, - dictWord{140, 11, 146}, - dictWord{135, 10, 380}, - dictWord{135, 10, 1947}, - dictWord{148, 11, 109}, - dictWord{10, 10, 278}, - dictWord{ - 138, - 11, - 278, - }, - dictWord{134, 0, 856}, - dictWord{7, 0, 139}, - dictWord{4, 10, 386}, - dictWord{8, 10, 405}, - dictWord{8, 10, 728}, - dictWord{9, 10, 497}, - dictWord{ - 11, - 10, - 110, - }, - dictWord{11, 10, 360}, - dictWord{15, 10, 37}, - dictWord{144, 10, 84}, - dictWord{141, 0, 282}, - dictWord{133, 0, 981}, - dictWord{5, 0, 288}, - dictWord{ - 7, - 10, - 1452, - }, - dictWord{7, 10, 1480}, - dictWord{8, 10, 634}, - dictWord{140, 10, 472}, - dictWord{7, 0, 1890}, - dictWord{8, 11, 367}, - dictWord{10, 11, 760}, - dictWord{ - 14, - 11, - 79, - }, - dictWord{20, 11, 17}, - dictWord{152, 11, 0}, - dictWord{4, 10, 524}, - dictWord{136, 10, 810}, - dictWord{4, 0, 56}, - dictWord{7, 0, 1791}, - dictWord{ - 8, - 0, - 607, - }, - dictWord{8, 0, 651}, - dictWord{11, 0, 465}, - dictWord{11, 0, 835}, - dictWord{12, 0, 337}, - dictWord{141, 0, 480}, - dictWord{10, 10, 238}, - dictWord{ - 141, - 10, - 33, - }, - dictWord{11, 11, 417}, - dictWord{12, 11, 223}, - dictWord{140, 11, 265}, - dictWord{9, 0, 158}, - dictWord{10, 0, 411}, - dictWord{140, 0, 261}, - dictWord{ - 133, - 10, - 532, - }, - dictWord{133, 10, 997}, - dictWord{12, 11, 186}, - dictWord{12, 11, 292}, - dictWord{14, 11, 100}, - dictWord{146, 11, 70}, - dictWord{6, 0, 1403}, - dictWord{136, 0, 617}, - dictWord{134, 0, 1205}, - dictWord{139, 0, 563}, - dictWord{4, 0, 242}, - dictWord{134, 0, 333}, - dictWord{4, 11, 186}, - dictWord{5, 11, 157}, - dictWord{8, 11, 168}, - dictWord{138, 11, 6}, - dictWord{132, 0, 369}, - dictWord{133, 11, 875}, - dictWord{5, 10, 782}, - dictWord{5, 10, 829}, - dictWord{ - 134, - 10, - 1738, - }, - dictWord{134, 0, 622}, - dictWord{135, 11, 1272}, - dictWord{6, 0, 1407}, - dictWord{7, 11, 111}, - dictWord{136, 11, 581}, - dictWord{7, 10, 1823}, - dictWord{139, 10, 693}, - dictWord{7, 0, 160}, - dictWord{10, 0, 624}, - dictWord{142, 0, 279}, - dictWord{132, 0, 363}, - dictWord{10, 11, 589}, - dictWord{12, 11, 111}, - dictWord{13, 11, 260}, - dictWord{14, 11, 82}, - dictWord{18, 11, 63}, - dictWord{147, 11, 45}, - dictWord{7, 11, 1364}, - dictWord{7, 11, 1907}, - dictWord{ - 141, - 11, - 158, - }, - dictWord{4, 11, 404}, - dictWord{4, 11, 659}, - dictWord{135, 11, 675}, - dictWord{13, 11, 211}, - dictWord{14, 11, 133}, - dictWord{14, 11, 204}, - dictWord{ - 15, - 11, - 64, - }, - dictWord{15, 11, 69}, - dictWord{15, 11, 114}, - dictWord{16, 11, 10}, - dictWord{19, 11, 23}, - dictWord{19, 11, 35}, - dictWord{19, 11, 39}, - dictWord{ - 19, - 11, - 51, - }, - dictWord{19, 11, 71}, - dictWord{19, 11, 75}, - dictWord{152, 11, 15}, - dictWord{4, 10, 78}, - dictWord{5, 10, 96}, - dictWord{5, 10, 182}, - dictWord{7, 10, 1724}, - dictWord{7, 10, 1825}, - dictWord{10, 10, 394}, - dictWord{10, 10, 471}, - dictWord{11, 10, 532}, - dictWord{14, 10, 340}, - dictWord{145, 10, 88}, - dictWord{ - 135, - 10, - 1964, - }, - dictWord{133, 11, 391}, - dictWord{11, 11, 887}, - dictWord{14, 11, 365}, - dictWord{142, 11, 375}, - dictWord{5, 11, 540}, - dictWord{6, 11, 1697}, - dictWord{7, 11, 222}, - dictWord{136, 11, 341}, - dictWord{134, 11, 78}, - dictWord{9, 0, 601}, - dictWord{9, 0, 619}, - dictWord{10, 0, 505}, - dictWord{10, 0, 732}, - dictWord{11, 0, 355}, - dictWord{140, 0, 139}, - dictWord{134, 0, 292}, - dictWord{139, 0, 174}, - dictWord{5, 0, 177}, - dictWord{6, 0, 616}, - dictWord{7, 0, 827}, - dictWord{ - 9, - 0, - 525, - }, - dictWord{138, 0, 656}, - dictWord{10, 0, 31}, - dictWord{6, 10, 215}, - dictWord{7, 10, 1028}, - dictWord{7, 10, 1473}, - dictWord{7, 10, 1721}, - dictWord{ - 9, - 10, - 424, - }, - dictWord{138, 10, 779}, - dictWord{135, 10, 584}, - dictWord{136, 11, 293}, - dictWord{134, 0, 685}, - dictWord{135, 11, 1868}, - dictWord{ - 133, - 11, - 460, - }, - dictWord{7, 0, 647}, - dictWord{6, 10, 67}, - dictWord{7, 10, 1630}, - dictWord{9, 10, 354}, - dictWord{9, 10, 675}, - dictWord{10, 10, 830}, - dictWord{ - 14, - 10, - 80, - }, - dictWord{145, 10, 80}, - dictWord{4, 0, 161}, - dictWord{133, 0, 631}, - dictWord{6, 10, 141}, - dictWord{7, 10, 225}, - dictWord{9, 10, 59}, - dictWord{9, 10, 607}, - dictWord{10, 10, 312}, - dictWord{11, 10, 687}, - dictWord{12, 10, 555}, - dictWord{13, 10, 373}, - dictWord{13, 10, 494}, - dictWord{148, 10, 58}, - dictWord{ - 7, - 11, - 965, - }, - dictWord{7, 11, 1460}, - dictWord{135, 11, 1604}, - dictWord{136, 10, 783}, - dictWord{134, 11, 388}, - dictWord{6, 0, 722}, - dictWord{6, 0, 1267}, - dictWord{ - 4, - 11, - 511, - }, - dictWord{9, 11, 333}, - dictWord{9, 11, 379}, - dictWord{10, 11, 602}, - dictWord{11, 11, 441}, - dictWord{11, 11, 723}, - dictWord{11, 11, 976}, - dictWord{140, 11, 357}, - dictWord{134, 0, 1797}, - dictWord{135, 0, 1684}, - dictWord{9, 0, 469}, - dictWord{9, 0, 709}, - dictWord{12, 0, 512}, - dictWord{14, 0, 65}, - dictWord{17, 0, 12}, - dictWord{5, 11, 938}, - dictWord{136, 11, 707}, - dictWord{7, 0, 1230}, - dictWord{136, 0, 531}, - dictWord{10, 0, 229}, - dictWord{11, 0, 73}, - dictWord{ - 11, - 0, - 376, - }, - dictWord{139, 0, 433}, - dictWord{12, 0, 268}, - dictWord{12, 0, 640}, - dictWord{142, 0, 119}, - dictWord{7, 10, 430}, - dictWord{139, 10, 46}, - dictWord{ - 6, - 0, - 558, - }, - dictWord{7, 0, 651}, - dictWord{8, 0, 421}, - dictWord{9, 0, 0}, - dictWord{10, 0, 34}, - dictWord{139, 0, 1008}, - dictWord{6, 0, 106}, - dictWord{7, 0, 1786}, - dictWord{7, 0, 1821}, - dictWord{9, 0, 102}, - dictWord{9, 0, 763}, - dictWord{5, 10, 602}, - dictWord{7, 10, 2018}, - dictWord{137, 10, 418}, - dictWord{5, 0, 65}, - dictWord{ - 6, - 0, - 416, - }, - dictWord{7, 0, 1720}, - dictWord{7, 0, 1924}, - dictWord{10, 0, 109}, - dictWord{11, 0, 14}, - dictWord{11, 0, 70}, - dictWord{11, 0, 569}, - dictWord{11, 0, 735}, - dictWord{15, 0, 153}, - dictWord{20, 0, 80}, - dictWord{136, 10, 677}, - dictWord{135, 11, 1625}, - dictWord{137, 11, 772}, - dictWord{136, 0, 595}, - dictWord{ - 6, - 11, - 469, - }, - dictWord{7, 11, 1709}, - dictWord{138, 11, 515}, - dictWord{7, 0, 1832}, - dictWord{138, 0, 374}, - dictWord{9, 0, 106}, - dictWord{9, 0, 163}, - dictWord{ - 9, - 0, - 296, - }, - dictWord{10, 0, 167}, - dictWord{10, 0, 172}, - dictWord{10, 0, 777}, - dictWord{139, 0, 16}, - dictWord{6, 0, 6}, - dictWord{7, 0, 81}, - dictWord{7, 0, 771}, - dictWord{ - 7, - 0, - 1731, - }, - dictWord{9, 0, 405}, - dictWord{138, 0, 421}, - dictWord{4, 11, 500}, - dictWord{135, 11, 938}, - dictWord{5, 11, 68}, - dictWord{134, 11, 383}, - dictWord{ - 5, - 0, - 881, - }, - dictWord{133, 0, 885}, - dictWord{6, 0, 854}, - dictWord{6, 0, 1132}, - dictWord{6, 0, 1495}, - dictWord{6, 0, 1526}, - dictWord{6, 0, 1533}, - dictWord{ - 134, - 0, - 1577, - }, - dictWord{4, 11, 337}, - dictWord{6, 11, 353}, - dictWord{7, 11, 1934}, - dictWord{8, 11, 488}, - dictWord{137, 11, 429}, - dictWord{7, 11, 236}, - dictWord{ - 7, - 11, - 1795, - }, - dictWord{8, 11, 259}, - dictWord{9, 11, 135}, - dictWord{9, 11, 177}, - dictWord{10, 11, 825}, - dictWord{11, 11, 115}, - dictWord{11, 11, 370}, - dictWord{ - 11, - 11, - 405, - }, - dictWord{11, 11, 604}, - dictWord{12, 11, 10}, - dictWord{12, 11, 667}, - dictWord{12, 11, 669}, - dictWord{13, 11, 76}, - dictWord{14, 11, 310}, - dictWord{15, 11, 76}, - dictWord{15, 11, 147}, - dictWord{148, 11, 23}, - dictWord{5, 0, 142}, - dictWord{134, 0, 546}, - dictWord{4, 11, 15}, - dictWord{5, 11, 22}, - dictWord{ - 6, - 11, - 244, - }, - dictWord{7, 11, 40}, - dictWord{7, 11, 200}, - dictWord{7, 11, 906}, - dictWord{7, 11, 1199}, - dictWord{9, 11, 616}, - dictWord{10, 11, 716}, - dictWord{ - 11, - 11, - 635, - }, - dictWord{11, 11, 801}, - dictWord{140, 11, 458}, - dictWord{5, 0, 466}, - dictWord{11, 0, 571}, - dictWord{12, 0, 198}, - dictWord{13, 0, 283}, - dictWord{ - 14, - 0, - 186, - }, - dictWord{15, 0, 21}, - dictWord{15, 0, 103}, - dictWord{135, 10, 329}, - dictWord{4, 0, 185}, - dictWord{5, 0, 257}, - dictWord{5, 0, 839}, - dictWord{5, 0, 936}, - dictWord{9, 0, 399}, - dictWord{10, 0, 258}, - dictWord{10, 0, 395}, - dictWord{10, 0, 734}, - dictWord{11, 0, 1014}, - dictWord{12, 0, 23}, - dictWord{13, 0, 350}, - dictWord{ - 14, - 0, - 150, - }, - dictWord{19, 0, 6}, - dictWord{135, 11, 1735}, - dictWord{12, 11, 36}, - dictWord{141, 11, 337}, - dictWord{5, 11, 598}, - dictWord{7, 11, 791}, - dictWord{ - 8, - 11, - 108, - }, - dictWord{137, 11, 123}, - dictWord{132, 10, 469}, - dictWord{7, 0, 404}, - dictWord{7, 0, 1377}, - dictWord{7, 0, 1430}, - dictWord{7, 0, 2017}, - dictWord{ - 8, - 0, - 149, - }, - dictWord{8, 0, 239}, - dictWord{8, 0, 512}, - dictWord{8, 0, 793}, - dictWord{8, 0, 818}, - dictWord{9, 0, 474}, - dictWord{9, 0, 595}, - dictWord{10, 0, 122}, - dictWord{10, 0, 565}, - dictWord{10, 0, 649}, - dictWord{10, 0, 783}, - dictWord{11, 0, 239}, - dictWord{11, 0, 295}, - dictWord{11, 0, 447}, - dictWord{11, 0, 528}, - dictWord{ - 11, - 0, - 639, - }, - dictWord{11, 0, 800}, - dictWord{12, 0, 25}, - dictWord{12, 0, 77}, - dictWord{12, 0, 157}, - dictWord{12, 0, 256}, - dictWord{12, 0, 316}, - dictWord{12, 0, 390}, - dictWord{12, 0, 391}, - dictWord{12, 0, 395}, - dictWord{12, 0, 478}, - dictWord{12, 0, 503}, - dictWord{12, 0, 592}, - dictWord{12, 0, 680}, - dictWord{13, 0, 50}, - dictWord{13, 0, 53}, - dictWord{13, 0, 132}, - dictWord{13, 0, 198}, - dictWord{13, 0, 322}, - dictWord{13, 0, 415}, - dictWord{13, 0, 511}, - dictWord{14, 0, 71}, - dictWord{ - 14, - 0, - 395, - }, - dictWord{15, 0, 71}, - dictWord{15, 0, 136}, - dictWord{17, 0, 123}, - dictWord{18, 0, 93}, - dictWord{147, 0, 58}, - dictWord{136, 0, 712}, - dictWord{ - 134, - 10, - 1743, - }, - dictWord{5, 10, 929}, - dictWord{6, 10, 340}, - dictWord{8, 10, 376}, - dictWord{136, 10, 807}, - dictWord{6, 0, 1848}, - dictWord{8, 0, 860}, - dictWord{ - 10, - 0, - 856, - }, - dictWord{10, 0, 859}, - dictWord{10, 0, 925}, - dictWord{10, 0, 941}, - dictWord{140, 0, 762}, - dictWord{6, 0, 629}, - dictWord{6, 0, 906}, - dictWord{9, 0, 810}, - dictWord{140, 0, 652}, - dictWord{5, 10, 218}, - dictWord{7, 10, 1610}, - dictWord{138, 10, 83}, - dictWord{7, 10, 1512}, - dictWord{135, 10, 1794}, - dictWord{ - 4, - 0, - 377, - }, - dictWord{24, 0, 13}, - dictWord{4, 11, 155}, - dictWord{7, 11, 1689}, - dictWord{11, 10, 0}, - dictWord{144, 10, 78}, - dictWord{4, 11, 164}, - dictWord{5, 11, 151}, - dictWord{5, 11, 730}, - dictWord{5, 11, 741}, - dictWord{7, 11, 498}, - dictWord{7, 11, 870}, - dictWord{7, 11, 1542}, - dictWord{12, 11, 213}, - dictWord{14, 11, 36}, - dictWord{14, 11, 391}, - dictWord{17, 11, 111}, - dictWord{18, 11, 6}, - dictWord{18, 11, 46}, - dictWord{18, 11, 151}, - dictWord{19, 11, 36}, - dictWord{20, 11, 32}, - dictWord{20, 11, 56}, - dictWord{20, 11, 69}, - dictWord{20, 11, 102}, - dictWord{21, 11, 4}, - dictWord{22, 11, 8}, - dictWord{22, 11, 10}, - dictWord{22, 11, 14}, - dictWord{ - 150, - 11, - 31, - }, - dictWord{7, 0, 1842}, - dictWord{133, 10, 571}, - dictWord{4, 10, 455}, - dictWord{4, 11, 624}, - dictWord{135, 11, 1752}, - dictWord{134, 0, 1501}, - dictWord{4, 11, 492}, - dictWord{5, 11, 451}, - dictWord{6, 10, 161}, - dictWord{7, 10, 372}, - dictWord{137, 10, 597}, - dictWord{132, 10, 349}, - dictWord{4, 0, 180}, - dictWord{135, 0, 1906}, - dictWord{135, 11, 835}, - dictWord{141, 11, 70}, - dictWord{132, 0, 491}, - dictWord{137, 10, 751}, - dictWord{6, 10, 432}, - dictWord{ - 139, - 10, - 322, - }, - dictWord{4, 0, 171}, - dictWord{138, 0, 234}, - dictWord{6, 11, 113}, - dictWord{135, 11, 436}, - dictWord{4, 0, 586}, - dictWord{7, 0, 1186}, - dictWord{ - 138, - 0, - 631, - }, - dictWord{5, 10, 468}, - dictWord{10, 10, 325}, - dictWord{11, 10, 856}, - dictWord{12, 10, 345}, - dictWord{143, 10, 104}, - dictWord{5, 10, 223}, - dictWord{10, 11, 592}, - dictWord{10, 11, 753}, - dictWord{12, 11, 317}, - dictWord{12, 11, 355}, - dictWord{12, 11, 465}, - dictWord{12, 11, 469}, - dictWord{ - 12, - 11, - 560, - }, - dictWord{12, 11, 578}, - dictWord{141, 11, 243}, - dictWord{132, 10, 566}, - dictWord{135, 11, 520}, - dictWord{4, 10, 59}, - dictWord{135, 10, 1394}, - dictWord{6, 10, 436}, - dictWord{139, 10, 481}, - dictWord{9, 0, 931}, - dictWord{10, 0, 334}, - dictWord{20, 0, 71}, - dictWord{4, 10, 48}, - dictWord{5, 10, 271}, - dictWord{ - 7, - 10, - 953, - }, - dictWord{135, 11, 1878}, - dictWord{11, 0, 170}, - dictWord{5, 10, 610}, - dictWord{136, 10, 457}, - dictWord{133, 10, 755}, - dictWord{6, 0, 1587}, - dictWord{135, 10, 1217}, - dictWord{4, 10, 197}, - dictWord{149, 11, 26}, - dictWord{133, 11, 585}, - dictWord{137, 11, 521}, - dictWord{133, 0, 765}, - dictWord{ - 133, - 10, - 217, - }, - dictWord{139, 11, 586}, - dictWord{133, 0, 424}, - dictWord{9, 11, 752}, - dictWord{12, 11, 610}, - dictWord{13, 11, 431}, - dictWord{16, 11, 59}, - dictWord{146, 11, 109}, - dictWord{136, 0, 714}, - dictWord{7, 0, 685}, - dictWord{132, 11, 307}, - dictWord{9, 0, 420}, - dictWord{10, 0, 269}, - dictWord{10, 0, 285}, - dictWord{10, 0, 576}, - dictWord{11, 0, 397}, - dictWord{13, 0, 175}, - dictWord{145, 0, 90}, - dictWord{132, 0, 429}, - dictWord{133, 11, 964}, - dictWord{9, 11, 463}, - dictWord{138, 11, 595}, - dictWord{7, 0, 18}, - dictWord{7, 0, 699}, - dictWord{7, 0, 1966}, - dictWord{8, 0, 752}, - dictWord{9, 0, 273}, - dictWord{9, 0, 412}, - dictWord{ - 9, - 0, - 703, - }, - dictWord{10, 0, 71}, - dictWord{10, 0, 427}, - dictWord{138, 0, 508}, - dictWord{4, 10, 165}, - dictWord{7, 10, 1398}, - dictWord{135, 10, 1829}, - dictWord{ - 4, - 0, - 53, - }, - dictWord{5, 0, 186}, - dictWord{7, 0, 752}, - dictWord{7, 0, 828}, - dictWord{142, 0, 116}, - dictWord{8, 0, 575}, - dictWord{10, 0, 289}, - dictWord{139, 0, 319}, - dictWord{132, 0, 675}, - dictWord{134, 0, 1424}, - dictWord{4, 11, 75}, - dictWord{5, 11, 180}, - dictWord{6, 11, 500}, - dictWord{7, 11, 58}, - dictWord{7, 11, 710}, - dictWord{138, 11, 645}, - dictWord{133, 11, 649}, - dictWord{6, 11, 276}, - dictWord{7, 11, 282}, - dictWord{7, 11, 879}, - dictWord{7, 11, 924}, - dictWord{8, 11, 459}, - dictWord{9, 11, 599}, - dictWord{9, 11, 754}, - dictWord{11, 11, 574}, - dictWord{12, 11, 128}, - dictWord{12, 11, 494}, - dictWord{13, 11, 52}, - dictWord{13, 11, 301}, - dictWord{15, 11, 30}, - dictWord{143, 11, 132}, - dictWord{6, 0, 647}, - dictWord{134, 0, 1095}, - dictWord{5, 10, 9}, - dictWord{7, 10, 297}, - dictWord{7, 10, 966}, - dictWord{140, 10, 306}, - dictWord{132, 11, 200}, - dictWord{134, 0, 1334}, - dictWord{5, 10, 146}, - dictWord{6, 10, 411}, - dictWord{138, 10, 721}, - dictWord{ - 6, - 0, - 209, - }, - dictWord{6, 0, 1141}, - dictWord{6, 0, 1288}, - dictWord{8, 0, 468}, - dictWord{9, 0, 210}, - dictWord{11, 0, 36}, - dictWord{12, 0, 28}, - dictWord{12, 0, 630}, - dictWord{13, 0, 21}, - dictWord{13, 0, 349}, - dictWord{14, 0, 7}, - dictWord{145, 0, 13}, - dictWord{6, 10, 177}, - dictWord{135, 10, 467}, - dictWord{4, 0, 342}, - dictWord{ - 135, - 0, - 1179, - }, - dictWord{10, 11, 454}, - dictWord{140, 11, 324}, - dictWord{4, 0, 928}, - dictWord{133, 0, 910}, - dictWord{7, 0, 1838}, - dictWord{6, 11, 225}, - dictWord{ - 137, - 11, - 211, - }, - dictWord{16, 0, 101}, - dictWord{20, 0, 115}, - dictWord{20, 0, 118}, - dictWord{148, 0, 122}, - dictWord{4, 0, 496}, - dictWord{135, 0, 856}, - dictWord{ - 4, - 0, - 318, - }, - dictWord{11, 0, 654}, - dictWord{7, 11, 718}, - dictWord{139, 11, 102}, - dictWord{8, 11, 58}, - dictWord{9, 11, 724}, - dictWord{11, 11, 809}, - dictWord{ - 13, - 11, - 113, - }, - dictWord{145, 11, 72}, - dictWord{5, 10, 200}, - dictWord{6, 11, 345}, - dictWord{135, 11, 1247}, - dictWord{8, 11, 767}, - dictWord{8, 11, 803}, - dictWord{ - 9, - 11, - 301, - }, - dictWord{137, 11, 903}, - dictWord{7, 0, 915}, - dictWord{8, 0, 247}, - dictWord{19, 0, 0}, - dictWord{7, 11, 1949}, - dictWord{136, 11, 674}, - dictWord{ - 4, - 0, - 202, - }, - dictWord{5, 0, 382}, - dictWord{6, 0, 454}, - dictWord{7, 0, 936}, - dictWord{7, 0, 1803}, - dictWord{8, 0, 758}, - dictWord{9, 0, 375}, - dictWord{9, 0, 895}, - dictWord{ - 10, - 0, - 743, - }, - dictWord{10, 0, 792}, - dictWord{11, 0, 978}, - dictWord{11, 0, 1012}, - dictWord{142, 0, 109}, - dictWord{7, 0, 1150}, - dictWord{7, 0, 1425}, - dictWord{ - 7, - 0, - 1453, - }, - dictWord{140, 0, 513}, - dictWord{134, 11, 259}, - dictWord{138, 0, 791}, - dictWord{11, 0, 821}, - dictWord{12, 0, 110}, - dictWord{12, 0, 153}, - dictWord{ - 18, - 0, - 41, - }, - dictWord{150, 0, 19}, - dictWord{134, 10, 481}, - dictWord{132, 0, 796}, - dictWord{6, 0, 445}, - dictWord{9, 0, 909}, - dictWord{136, 11, 254}, - dictWord{ - 10, - 0, - 776, - }, - dictWord{13, 0, 345}, - dictWord{142, 0, 425}, - dictWord{4, 10, 84}, - dictWord{7, 10, 1482}, - dictWord{10, 10, 76}, - dictWord{138, 10, 142}, - dictWord{ - 135, - 11, - 742, - }, - dictWord{6, 0, 578}, - dictWord{133, 10, 1015}, - dictWord{6, 0, 1387}, - dictWord{4, 10, 315}, - dictWord{5, 10, 507}, - dictWord{135, 10, 1370}, - dictWord{4, 0, 438}, - dictWord{133, 0, 555}, - dictWord{136, 0, 766}, - dictWord{133, 11, 248}, - dictWord{134, 10, 1722}, - dictWord{4, 11, 116}, - dictWord{5, 11, 95}, - dictWord{5, 11, 445}, - dictWord{7, 11, 1688}, - dictWord{8, 11, 29}, - dictWord{9, 11, 272}, - dictWord{11, 11, 509}, - dictWord{139, 11, 915}, - dictWord{135, 0, 541}, - dictWord{133, 11, 543}, - dictWord{8, 10, 222}, - dictWord{8, 10, 476}, - dictWord{9, 10, 238}, - dictWord{11, 10, 516}, - dictWord{11, 10, 575}, - dictWord{ - 15, - 10, - 109, - }, - dictWord{146, 10, 100}, - dictWord{6, 0, 880}, - dictWord{134, 0, 1191}, - dictWord{5, 11, 181}, - dictWord{136, 11, 41}, - dictWord{134, 0, 1506}, - dictWord{132, 11, 681}, - dictWord{7, 11, 25}, - dictWord{8, 11, 202}, - dictWord{138, 11, 536}, - dictWord{139, 0, 983}, - dictWord{137, 0, 768}, - dictWord{132, 0, 584}, - dictWord{9, 11, 423}, - dictWord{140, 11, 89}, - dictWord{8, 11, 113}, - dictWord{9, 11, 877}, - dictWord{10, 11, 554}, - dictWord{11, 11, 83}, - dictWord{12, 11, 136}, - dictWord{147, 11, 109}, - dictWord{7, 10, 706}, - dictWord{7, 10, 1058}, - dictWord{138, 10, 538}, - dictWord{133, 11, 976}, - dictWord{4, 11, 206}, - dictWord{ - 135, - 11, - 746, - }, - dictWord{136, 11, 526}, - dictWord{140, 0, 737}, - dictWord{11, 10, 92}, - dictWord{11, 10, 196}, - dictWord{11, 10, 409}, - dictWord{11, 10, 450}, - dictWord{11, 10, 666}, - dictWord{11, 10, 777}, - dictWord{12, 10, 262}, - dictWord{13, 10, 385}, - dictWord{13, 10, 393}, - dictWord{15, 10, 115}, - dictWord{ - 16, - 10, - 45, - }, - dictWord{145, 10, 82}, - dictWord{4, 0, 226}, - dictWord{4, 0, 326}, - dictWord{7, 0, 1770}, - dictWord{4, 11, 319}, - dictWord{5, 11, 699}, - dictWord{138, 11, 673}, - dictWord{6, 10, 40}, - dictWord{135, 10, 1781}, - dictWord{5, 0, 426}, - dictWord{8, 0, 30}, - dictWord{9, 0, 2}, - dictWord{11, 0, 549}, - dictWord{147, 0, 122}, - dictWord{ - 6, - 0, - 1161, - }, - dictWord{134, 0, 1329}, - dictWord{138, 10, 97}, - dictWord{6, 10, 423}, - dictWord{7, 10, 665}, - dictWord{135, 10, 1210}, - dictWord{7, 11, 13}, - dictWord{ - 8, - 11, - 226, - }, - dictWord{10, 11, 537}, - dictWord{11, 11, 570}, - dictWord{11, 11, 605}, - dictWord{11, 11, 799}, - dictWord{11, 11, 804}, - dictWord{12, 11, 85}, - dictWord{12, 11, 516}, - dictWord{12, 11, 623}, - dictWord{13, 11, 112}, - dictWord{13, 11, 361}, - dictWord{14, 11, 77}, - dictWord{14, 11, 78}, - dictWord{17, 11, 28}, - dictWord{147, 11, 110}, - dictWord{132, 11, 769}, - dictWord{132, 11, 551}, - dictWord{132, 11, 728}, - dictWord{147, 0, 117}, - dictWord{9, 11, 57}, - dictWord{ - 9, - 11, - 459, - }, - dictWord{10, 11, 425}, - dictWord{11, 11, 119}, - dictWord{12, 11, 184}, - dictWord{12, 11, 371}, - dictWord{13, 11, 358}, - dictWord{145, 11, 51}, - dictWord{ - 5, - 11, - 188, - }, - dictWord{5, 11, 814}, - dictWord{8, 11, 10}, - dictWord{9, 11, 421}, - dictWord{9, 11, 729}, - dictWord{10, 11, 609}, - dictWord{139, 11, 689}, - dictWord{134, 11, 624}, - dictWord{135, 11, 298}, - dictWord{135, 0, 462}, - dictWord{4, 0, 345}, - dictWord{139, 10, 624}, - dictWord{136, 10, 574}, - dictWord{ - 4, - 0, - 385, - }, - dictWord{7, 0, 265}, - dictWord{135, 0, 587}, - dictWord{6, 0, 808}, - dictWord{132, 11, 528}, - dictWord{133, 0, 398}, - dictWord{132, 10, 354}, - dictWord{ - 4, - 0, - 347, - }, - dictWord{5, 0, 423}, - dictWord{5, 0, 996}, - dictWord{135, 0, 1329}, - dictWord{135, 10, 1558}, - dictWord{7, 0, 1259}, - dictWord{9, 0, 125}, - dictWord{ - 139, - 0, - 65, - }, - dictWord{5, 0, 136}, - dictWord{6, 0, 136}, - dictWord{136, 0, 644}, - dictWord{5, 11, 104}, - dictWord{6, 11, 173}, - dictWord{135, 11, 1631}, - dictWord{ - 135, - 0, - 469, - }, - dictWord{133, 10, 830}, - dictWord{4, 0, 278}, - dictWord{5, 0, 465}, - dictWord{135, 0, 1367}, - dictWord{7, 11, 810}, - dictWord{8, 11, 138}, - dictWord{ - 8, - 11, - 342, - }, - dictWord{9, 11, 84}, - dictWord{10, 11, 193}, - dictWord{11, 11, 883}, - dictWord{140, 11, 359}, - dictWord{5, 10, 496}, - dictWord{135, 10, 203}, - dictWord{ - 4, - 0, - 433, - }, - dictWord{133, 0, 719}, - dictWord{6, 11, 95}, - dictWord{134, 10, 547}, - dictWord{5, 10, 88}, - dictWord{137, 10, 239}, - dictWord{6, 11, 406}, - dictWord{ - 10, - 11, - 409, - }, - dictWord{10, 11, 447}, - dictWord{11, 11, 44}, - dictWord{140, 11, 100}, - dictWord{134, 0, 1423}, - dictWord{7, 10, 650}, - dictWord{135, 10, 1310}, - dictWord{134, 0, 749}, - dictWord{135, 11, 1243}, - dictWord{135, 0, 1363}, - dictWord{6, 0, 381}, - dictWord{7, 0, 645}, - dictWord{7, 0, 694}, - dictWord{8, 0, 546}, - dictWord{7, 10, 1076}, - dictWord{9, 10, 80}, - dictWord{11, 10, 78}, - dictWord{11, 10, 421}, - dictWord{11, 10, 534}, - dictWord{140, 10, 545}, - dictWord{ - 134, - 11, - 1636, - }, - dictWord{135, 11, 1344}, - dictWord{12, 0, 277}, - dictWord{7, 10, 274}, - dictWord{11, 10, 479}, - dictWord{139, 10, 507}, - dictWord{6, 0, 705}, - dictWord{ - 6, - 0, - 783, - }, - dictWord{6, 0, 1275}, - dictWord{6, 0, 1481}, - dictWord{4, 11, 282}, - dictWord{7, 11, 1034}, - dictWord{11, 11, 398}, - dictWord{11, 11, 634}, - dictWord{ - 12, - 11, - 1, - }, - dictWord{12, 11, 79}, - dictWord{12, 11, 544}, - dictWord{14, 11, 237}, - dictWord{17, 11, 10}, - dictWord{146, 11, 20}, - dictWord{134, 0, 453}, - dictWord{ - 4, - 0, - 555, - }, - dictWord{8, 0, 536}, - dictWord{10, 0, 288}, - dictWord{11, 0, 1005}, - dictWord{4, 10, 497}, - dictWord{135, 10, 1584}, - dictWord{5, 11, 118}, - dictWord{ - 5, - 11, - 499, - }, - dictWord{6, 11, 476}, - dictWord{7, 11, 600}, - dictWord{7, 11, 888}, - dictWord{135, 11, 1096}, - dictWord{138, 0, 987}, - dictWord{7, 0, 1107}, - dictWord{ - 7, - 10, - 261, - }, - dictWord{7, 10, 1115}, - dictWord{7, 10, 1354}, - dictWord{7, 10, 1588}, - dictWord{7, 10, 1705}, - dictWord{7, 10, 1902}, - dictWord{9, 10, 465}, - dictWord{10, 10, 248}, - dictWord{10, 10, 349}, - dictWord{10, 10, 647}, - dictWord{11, 10, 527}, - dictWord{11, 10, 660}, - dictWord{11, 10, 669}, - dictWord{ - 12, - 10, - 529, - }, - dictWord{141, 10, 305}, - dictWord{7, 11, 296}, - dictWord{7, 11, 596}, - dictWord{8, 11, 560}, - dictWord{8, 11, 586}, - dictWord{9, 11, 612}, - dictWord{ - 11, - 11, - 100, - }, - dictWord{11, 11, 304}, - dictWord{12, 11, 46}, - dictWord{13, 11, 89}, - dictWord{14, 11, 112}, - dictWord{145, 11, 122}, - dictWord{9, 0, 370}, - dictWord{ - 138, - 0, - 90, - }, - dictWord{136, 10, 13}, - dictWord{132, 0, 860}, - dictWord{7, 10, 642}, - dictWord{8, 10, 250}, - dictWord{11, 10, 123}, - dictWord{11, 10, 137}, - dictWord{ - 13, - 10, - 48, - }, - dictWord{142, 10, 95}, - dictWord{135, 10, 1429}, - dictWord{137, 11, 321}, - dictWord{132, 0, 257}, - dictWord{135, 0, 2031}, - dictWord{7, 0, 1768}, - dictWord{7, 11, 1599}, - dictWord{7, 11, 1723}, - dictWord{8, 11, 79}, - dictWord{8, 11, 106}, - dictWord{8, 11, 190}, - dictWord{8, 11, 302}, - dictWord{8, 11, 383}, - dictWord{9, 11, 119}, - dictWord{9, 11, 233}, - dictWord{9, 11, 298}, - dictWord{9, 11, 419}, - dictWord{9, 11, 471}, - dictWord{10, 11, 181}, - dictWord{10, 11, 406}, - dictWord{11, 11, 57}, - dictWord{11, 11, 85}, - dictWord{11, 11, 120}, - dictWord{11, 11, 177}, - dictWord{11, 11, 296}, - dictWord{11, 11, 382}, - dictWord{11, 11, 454}, - dictWord{11, 11, 758}, - dictWord{11, 11, 999}, - dictWord{12, 11, 27}, - dictWord{12, 11, 98}, - dictWord{12, 11, 131}, - dictWord{12, 11, 245}, - dictWord{ - 12, - 11, - 312, - }, - dictWord{12, 11, 446}, - dictWord{12, 11, 454}, - dictWord{13, 11, 25}, - dictWord{13, 11, 98}, - dictWord{13, 11, 426}, - dictWord{13, 11, 508}, - dictWord{ - 14, - 11, - 6, - }, - dictWord{14, 11, 163}, - dictWord{14, 11, 272}, - dictWord{14, 11, 277}, - dictWord{14, 11, 370}, - dictWord{15, 11, 95}, - dictWord{15, 11, 138}, - dictWord{ - 15, - 11, - 167, - }, - dictWord{17, 11, 18}, - dictWord{17, 11, 38}, - dictWord{20, 11, 96}, - dictWord{149, 11, 32}, - dictWord{5, 11, 722}, - dictWord{134, 11, 1759}, - dictWord{145, 11, 16}, - dictWord{6, 0, 1071}, - dictWord{134, 0, 1561}, - dictWord{10, 10, 545}, - dictWord{140, 10, 301}, - dictWord{6, 0, 83}, - dictWord{6, 0, 1733}, - dictWord{135, 0, 1389}, - dictWord{4, 0, 835}, - dictWord{135, 0, 1818}, - dictWord{133, 11, 258}, - dictWord{4, 10, 904}, - dictWord{133, 10, 794}, - dictWord{ - 134, - 0, - 2006, - }, - dictWord{5, 11, 30}, - dictWord{7, 11, 495}, - dictWord{8, 11, 134}, - dictWord{9, 11, 788}, - dictWord{140, 11, 438}, - dictWord{135, 11, 2004}, - dictWord{ - 137, - 0, - 696, - }, - dictWord{5, 11, 50}, - dictWord{6, 11, 439}, - dictWord{7, 11, 780}, - dictWord{135, 11, 1040}, - dictWord{7, 11, 772}, - dictWord{7, 11, 1104}, - dictWord{ - 7, - 11, - 1647, - }, - dictWord{11, 11, 269}, - dictWord{11, 11, 539}, - dictWord{11, 11, 607}, - dictWord{11, 11, 627}, - dictWord{11, 11, 706}, - dictWord{11, 11, 975}, - dictWord{12, 11, 248}, - dictWord{12, 11, 311}, - dictWord{12, 11, 434}, - dictWord{12, 11, 600}, - dictWord{12, 11, 622}, - dictWord{13, 11, 297}, - dictWord{ - 13, - 11, - 367, - }, - dictWord{13, 11, 485}, - dictWord{14, 11, 69}, - dictWord{14, 11, 409}, - dictWord{143, 11, 108}, - dictWord{5, 11, 1}, - dictWord{6, 11, 81}, - dictWord{ - 138, - 11, - 520, - }, - dictWord{7, 0, 1718}, - dictWord{9, 0, 95}, - dictWord{9, 0, 274}, - dictWord{10, 0, 279}, - dictWord{10, 0, 317}, - dictWord{10, 0, 420}, - dictWord{11, 0, 303}, - dictWord{11, 0, 808}, - dictWord{12, 0, 134}, - dictWord{12, 0, 367}, - dictWord{13, 0, 149}, - dictWord{13, 0, 347}, - dictWord{14, 0, 349}, - dictWord{14, 0, 406}, - dictWord{ - 18, - 0, - 22, - }, - dictWord{18, 0, 89}, - dictWord{18, 0, 122}, - dictWord{147, 0, 47}, - dictWord{5, 11, 482}, - dictWord{8, 11, 98}, - dictWord{9, 11, 172}, - dictWord{10, 11, 222}, - dictWord{10, 11, 700}, - dictWord{10, 11, 822}, - dictWord{11, 11, 302}, - dictWord{11, 11, 778}, - dictWord{12, 11, 50}, - dictWord{12, 11, 127}, - dictWord{ - 12, - 11, - 396, - }, - dictWord{13, 11, 62}, - dictWord{13, 11, 328}, - dictWord{14, 11, 122}, - dictWord{147, 11, 72}, - dictWord{7, 10, 386}, - dictWord{138, 10, 713}, - dictWord{ - 6, - 10, - 7, - }, - dictWord{6, 10, 35}, - dictWord{7, 10, 147}, - dictWord{7, 10, 1069}, - dictWord{7, 10, 1568}, - dictWord{7, 10, 1575}, - dictWord{7, 10, 1917}, - dictWord{ - 8, - 10, - 43, - }, - dictWord{8, 10, 208}, - dictWord{9, 10, 128}, - dictWord{9, 10, 866}, - dictWord{10, 10, 20}, - dictWord{11, 10, 981}, - dictWord{147, 10, 33}, - dictWord{ - 133, - 0, - 26, - }, - dictWord{132, 0, 550}, - dictWord{5, 11, 2}, - dictWord{7, 11, 1494}, - dictWord{136, 11, 589}, - dictWord{6, 11, 512}, - dictWord{7, 11, 797}, - dictWord{ - 8, - 11, - 253, - }, - dictWord{9, 11, 77}, - dictWord{10, 11, 1}, - dictWord{10, 11, 129}, - dictWord{10, 11, 225}, - dictWord{11, 11, 118}, - dictWord{11, 11, 226}, - dictWord{ - 11, - 11, - 251, - }, - dictWord{11, 11, 430}, - dictWord{11, 11, 701}, - dictWord{11, 11, 974}, - dictWord{11, 11, 982}, - dictWord{12, 11, 64}, - dictWord{12, 11, 260}, - dictWord{ - 12, - 11, - 488, - }, - dictWord{140, 11, 690}, - dictWord{7, 10, 893}, - dictWord{141, 10, 424}, - dictWord{134, 0, 901}, - dictWord{136, 0, 822}, - dictWord{4, 0, 902}, - dictWord{5, 0, 809}, - dictWord{134, 0, 122}, - dictWord{6, 0, 807}, - dictWord{134, 0, 1366}, - dictWord{7, 0, 262}, - dictWord{5, 11, 748}, - dictWord{134, 11, 553}, - dictWord{133, 0, 620}, - dictWord{4, 0, 34}, - dictWord{5, 0, 574}, - dictWord{7, 0, 279}, - dictWord{7, 0, 1624}, - dictWord{136, 0, 601}, - dictWord{9, 0, 170}, - dictWord{ - 6, - 10, - 322, - }, - dictWord{9, 10, 552}, - dictWord{11, 10, 274}, - dictWord{13, 10, 209}, - dictWord{13, 10, 499}, - dictWord{14, 10, 85}, - dictWord{15, 10, 126}, - dictWord{ - 145, - 10, - 70, - }, - dictWord{132, 0, 537}, - dictWord{4, 11, 12}, - dictWord{7, 11, 420}, - dictWord{7, 11, 522}, - dictWord{7, 11, 809}, - dictWord{8, 11, 797}, - dictWord{ - 141, - 11, - 88, - }, - dictWord{133, 0, 332}, - dictWord{8, 10, 83}, - dictWord{8, 10, 742}, - dictWord{8, 10, 817}, - dictWord{9, 10, 28}, - dictWord{9, 10, 29}, - dictWord{9, 10, 885}, - dictWord{10, 10, 387}, - dictWord{11, 10, 633}, - dictWord{11, 10, 740}, - dictWord{13, 10, 235}, - dictWord{13, 10, 254}, - dictWord{15, 10, 143}, - dictWord{ - 143, - 10, - 146, - }, - dictWord{6, 0, 1909}, - dictWord{9, 0, 964}, - dictWord{12, 0, 822}, - dictWord{12, 0, 854}, - dictWord{12, 0, 865}, - dictWord{12, 0, 910}, - dictWord{12, 0, 938}, - dictWord{15, 0, 169}, - dictWord{15, 0, 208}, - dictWord{15, 0, 211}, - dictWord{18, 0, 205}, - dictWord{18, 0, 206}, - dictWord{18, 0, 220}, - dictWord{18, 0, 223}, - dictWord{152, 0, 24}, - dictWord{140, 10, 49}, - dictWord{5, 11, 528}, - dictWord{135, 11, 1580}, - dictWord{6, 0, 261}, - dictWord{8, 0, 182}, - dictWord{139, 0, 943}, - dictWord{134, 0, 1721}, - dictWord{4, 0, 933}, - dictWord{133, 0, 880}, - dictWord{136, 11, 321}, - dictWord{5, 11, 266}, - dictWord{9, 11, 290}, - dictWord{9, 11, 364}, - dictWord{10, 11, 293}, - dictWord{11, 11, 606}, - dictWord{142, 11, 45}, - dictWord{6, 0, 1609}, - dictWord{4, 11, 50}, - dictWord{6, 11, 510}, - dictWord{6, 11, 594}, - dictWord{9, 11, 121}, - dictWord{10, 11, 49}, - dictWord{10, 11, 412}, - dictWord{139, 11, 834}, - dictWord{7, 0, 895}, - dictWord{136, 11, 748}, - dictWord{132, 11, 466}, - dictWord{4, 10, 110}, - dictWord{10, 10, 415}, - dictWord{10, 10, 597}, - dictWord{142, 10, 206}, - dictWord{133, 0, 812}, - dictWord{135, 11, 281}, - dictWord{ - 6, - 0, - 1890, - }, - dictWord{6, 0, 1902}, - dictWord{6, 0, 1916}, - dictWord{9, 0, 929}, - dictWord{9, 0, 942}, - dictWord{9, 0, 975}, - dictWord{9, 0, 984}, - dictWord{9, 0, 986}, - dictWord{ - 9, - 0, - 1011, - }, - dictWord{9, 0, 1019}, - dictWord{12, 0, 804}, - dictWord{12, 0, 851}, - dictWord{12, 0, 867}, - dictWord{12, 0, 916}, - dictWord{12, 0, 923}, - dictWord{ - 15, - 0, - 194, - }, - dictWord{15, 0, 204}, - dictWord{15, 0, 210}, - dictWord{15, 0, 222}, - dictWord{15, 0, 223}, - dictWord{15, 0, 229}, - dictWord{15, 0, 250}, - dictWord{ - 18, - 0, - 179, - }, - dictWord{18, 0, 186}, - dictWord{18, 0, 192}, - dictWord{7, 10, 205}, - dictWord{135, 10, 2000}, - dictWord{132, 11, 667}, - dictWord{135, 0, 778}, - dictWord{ - 4, - 0, - 137, - }, - dictWord{7, 0, 1178}, - dictWord{135, 0, 1520}, - dictWord{134, 0, 1314}, - dictWord{4, 11, 242}, - dictWord{134, 11, 333}, - dictWord{6, 0, 1661}, - dictWord{7, 0, 1975}, - dictWord{7, 0, 2009}, - dictWord{135, 0, 2011}, - dictWord{134, 0, 1591}, - dictWord{4, 10, 283}, - dictWord{135, 10, 1194}, - dictWord{ - 11, - 0, - 820, - }, - dictWord{150, 0, 51}, - dictWord{4, 11, 39}, - dictWord{5, 11, 36}, - dictWord{7, 11, 1843}, - dictWord{8, 11, 407}, - dictWord{11, 11, 144}, - dictWord{ - 140, - 11, - 523, - }, - dictWord{134, 10, 1720}, - dictWord{4, 11, 510}, - dictWord{7, 11, 29}, - dictWord{7, 11, 66}, - dictWord{7, 11, 1980}, - dictWord{10, 11, 487}, - dictWord{ - 10, - 11, - 809, - }, - dictWord{146, 11, 9}, - dictWord{5, 0, 89}, - dictWord{7, 0, 1915}, - dictWord{9, 0, 185}, - dictWord{9, 0, 235}, - dictWord{10, 0, 64}, - dictWord{10, 0, 270}, - dictWord{10, 0, 403}, - dictWord{10, 0, 469}, - dictWord{10, 0, 529}, - dictWord{10, 0, 590}, - dictWord{11, 0, 140}, - dictWord{11, 0, 860}, - dictWord{13, 0, 1}, - dictWord{ - 13, - 0, - 422, - }, - dictWord{14, 0, 341}, - dictWord{14, 0, 364}, - dictWord{17, 0, 93}, - dictWord{18, 0, 113}, - dictWord{19, 0, 97}, - dictWord{147, 0, 113}, - dictWord{133, 0, 695}, - dictWord{6, 0, 987}, - dictWord{134, 0, 1160}, - dictWord{5, 0, 6}, - dictWord{6, 0, 183}, - dictWord{7, 0, 680}, - dictWord{7, 0, 978}, - dictWord{7, 0, 1013}, - dictWord{ - 7, - 0, - 1055, - }, - dictWord{12, 0, 230}, - dictWord{13, 0, 172}, - dictWord{146, 0, 29}, - dictWord{134, 11, 570}, - dictWord{132, 11, 787}, - dictWord{134, 11, 518}, - dictWord{ - 6, - 0, - 29, - }, - dictWord{139, 0, 63}, - dictWord{132, 11, 516}, - dictWord{136, 11, 821}, - dictWord{132, 0, 311}, - dictWord{134, 0, 1740}, - dictWord{7, 0, 170}, - dictWord{8, 0, 90}, - dictWord{8, 0, 177}, - dictWord{8, 0, 415}, - dictWord{11, 0, 714}, - dictWord{14, 0, 281}, - dictWord{136, 10, 735}, - dictWord{134, 0, 1961}, - dictWord{ - 135, - 11, - 1405, - }, - dictWord{4, 11, 10}, - dictWord{7, 11, 917}, - dictWord{139, 11, 786}, - dictWord{5, 10, 132}, - dictWord{9, 10, 486}, - dictWord{9, 10, 715}, - dictWord{ - 10, - 10, - 458, - }, - dictWord{11, 10, 373}, - dictWord{11, 10, 668}, - dictWord{11, 10, 795}, - dictWord{11, 10, 897}, - dictWord{12, 10, 272}, - dictWord{12, 10, 424}, - dictWord{12, 10, 539}, - dictWord{12, 10, 558}, - dictWord{14, 10, 245}, - dictWord{14, 10, 263}, - dictWord{14, 10, 264}, - dictWord{14, 10, 393}, - dictWord{ - 142, - 10, - 403, - }, - dictWord{11, 0, 91}, - dictWord{13, 0, 129}, - dictWord{15, 0, 101}, - dictWord{145, 0, 125}, - dictWord{135, 0, 1132}, - dictWord{4, 0, 494}, - dictWord{6, 0, 74}, - dictWord{7, 0, 44}, - dictWord{7, 0, 407}, - dictWord{12, 0, 17}, - dictWord{15, 0, 5}, - dictWord{148, 0, 11}, - dictWord{133, 10, 379}, - dictWord{5, 0, 270}, - dictWord{ - 5, - 11, - 684, - }, - dictWord{6, 10, 89}, - dictWord{6, 10, 400}, - dictWord{7, 10, 1569}, - dictWord{7, 10, 1623}, - dictWord{7, 10, 1850}, - dictWord{8, 10, 218}, - dictWord{ - 8, - 10, - 422, - }, - dictWord{9, 10, 570}, - dictWord{138, 10, 626}, - dictWord{4, 0, 276}, - dictWord{133, 0, 296}, - dictWord{6, 0, 1523}, - dictWord{134, 11, 27}, - dictWord{ - 6, - 10, - 387, - }, - dictWord{7, 10, 882}, - dictWord{141, 10, 111}, - dictWord{6, 10, 224}, - dictWord{7, 10, 877}, - dictWord{137, 10, 647}, - dictWord{135, 10, 790}, - dictWord{ - 4, - 0, - 7, - }, - dictWord{5, 0, 90}, - dictWord{5, 0, 158}, - dictWord{6, 0, 542}, - dictWord{7, 0, 221}, - dictWord{7, 0, 1574}, - dictWord{9, 0, 490}, - dictWord{10, 0, 540}, - dictWord{ - 11, - 0, - 443, - }, - dictWord{139, 0, 757}, - dictWord{7, 0, 588}, - dictWord{9, 0, 175}, - dictWord{138, 0, 530}, - dictWord{135, 10, 394}, - dictWord{142, 11, 23}, - dictWord{ - 134, - 0, - 786, - }, - dictWord{135, 0, 580}, - dictWord{7, 0, 88}, - dictWord{136, 0, 627}, - dictWord{5, 0, 872}, - dictWord{6, 0, 57}, - dictWord{7, 0, 471}, - dictWord{9, 0, 447}, - dictWord{137, 0, 454}, - dictWord{6, 11, 342}, - dictWord{6, 11, 496}, - dictWord{8, 11, 275}, - dictWord{137, 11, 206}, - dictWord{4, 11, 909}, - dictWord{133, 11, 940}, - dictWord{6, 0, 735}, - dictWord{132, 11, 891}, - dictWord{8, 0, 845}, - dictWord{8, 0, 916}, - dictWord{135, 10, 1409}, - dictWord{5, 0, 31}, - dictWord{134, 0, 614}, - dictWord{11, 0, 458}, - dictWord{12, 0, 15}, - dictWord{140, 0, 432}, - dictWord{8, 0, 330}, - dictWord{140, 0, 477}, - dictWord{4, 0, 530}, - dictWord{5, 0, 521}, - dictWord{ - 7, - 0, - 1200, - }, - dictWord{10, 0, 460}, - dictWord{132, 11, 687}, - dictWord{6, 0, 424}, - dictWord{135, 0, 1866}, - dictWord{9, 0, 569}, - dictWord{12, 0, 12}, - dictWord{ - 12, - 0, - 81, - }, - dictWord{12, 0, 319}, - dictWord{13, 0, 69}, - dictWord{14, 0, 259}, - dictWord{16, 0, 87}, - dictWord{17, 0, 1}, - dictWord{17, 0, 21}, - dictWord{17, 0, 24}, - dictWord{ - 18, - 0, - 15, - }, - dictWord{18, 0, 56}, - dictWord{18, 0, 59}, - dictWord{18, 0, 127}, - dictWord{18, 0, 154}, - dictWord{19, 0, 19}, - dictWord{148, 0, 31}, - dictWord{7, 0, 1302}, - dictWord{136, 10, 38}, - dictWord{134, 11, 253}, - dictWord{5, 10, 261}, - dictWord{7, 10, 78}, - dictWord{7, 10, 199}, - dictWord{8, 10, 815}, - dictWord{9, 10, 126}, - dictWord{138, 10, 342}, - dictWord{5, 0, 595}, - dictWord{135, 0, 1863}, - dictWord{6, 11, 41}, - dictWord{141, 11, 160}, - dictWord{5, 0, 13}, - dictWord{134, 0, 142}, - dictWord{6, 0, 97}, - dictWord{7, 0, 116}, - dictWord{8, 0, 322}, - dictWord{8, 0, 755}, - dictWord{9, 0, 548}, - dictWord{10, 0, 714}, - dictWord{11, 0, 884}, - dictWord{13, 0, 324}, - dictWord{7, 11, 1304}, - dictWord{138, 11, 477}, - dictWord{132, 10, 628}, - dictWord{134, 11, 1718}, - dictWord{7, 10, 266}, - dictWord{136, 10, 804}, - dictWord{135, 10, 208}, - dictWord{7, 0, 1021}, - dictWord{6, 10, 79}, - dictWord{135, 10, 1519}, - dictWord{7, 0, 1472}, - dictWord{135, 0, 1554}, - dictWord{6, 11, 362}, - dictWord{146, 11, 51}, - dictWord{7, 0, 1071}, - dictWord{7, 0, 1541}, - dictWord{7, 0, 1767}, - dictWord{7, 0, 1806}, - dictWord{11, 0, 162}, - dictWord{11, 0, 242}, - dictWord{11, 0, 452}, - dictWord{12, 0, 605}, - dictWord{15, 0, 26}, - dictWord{144, 0, 44}, - dictWord{136, 10, 741}, - dictWord{133, 11, 115}, - dictWord{145, 0, 115}, - dictWord{134, 10, 376}, - dictWord{6, 0, 1406}, - dictWord{134, 0, 1543}, - dictWord{5, 11, 193}, - dictWord{12, 11, 178}, - dictWord{13, 11, 130}, - dictWord{ - 145, - 11, - 84, - }, - dictWord{135, 0, 1111}, - dictWord{8, 0, 1}, - dictWord{9, 0, 650}, - dictWord{10, 0, 326}, - dictWord{5, 11, 705}, - dictWord{137, 11, 606}, - dictWord{5, 0, 488}, - dictWord{6, 0, 527}, - dictWord{7, 0, 489}, - dictWord{7, 0, 1636}, - dictWord{8, 0, 121}, - dictWord{8, 0, 144}, - dictWord{8, 0, 359}, - dictWord{9, 0, 193}, - dictWord{9, 0, 241}, - dictWord{9, 0, 336}, - dictWord{9, 0, 882}, - dictWord{11, 0, 266}, - dictWord{11, 0, 372}, - dictWord{11, 0, 944}, - dictWord{12, 0, 401}, - dictWord{140, 0, 641}, - dictWord{135, 11, 174}, - dictWord{6, 0, 267}, - dictWord{7, 10, 244}, - dictWord{7, 10, 632}, - dictWord{7, 10, 1609}, - dictWord{8, 10, 178}, - dictWord{8, 10, 638}, - dictWord{141, 10, 58}, - dictWord{134, 0, 1983}, - dictWord{134, 0, 1155}, - dictWord{134, 0, 1575}, - dictWord{134, 0, 1438}, - dictWord{9, 0, 31}, - dictWord{ - 10, - 0, - 244, - }, - dictWord{10, 0, 699}, - dictWord{12, 0, 149}, - dictWord{141, 0, 497}, - dictWord{133, 0, 377}, - dictWord{4, 11, 122}, - dictWord{5, 11, 796}, - dictWord{ - 5, - 11, - 952, - }, - dictWord{6, 11, 1660}, - dictWord{6, 11, 1671}, - dictWord{8, 11, 567}, - dictWord{9, 11, 687}, - dictWord{9, 11, 742}, - dictWord{10, 11, 686}, - dictWord{ - 11, - 11, - 356, - }, - dictWord{11, 11, 682}, - dictWord{140, 11, 281}, - dictWord{145, 0, 101}, - dictWord{11, 11, 0}, - dictWord{144, 11, 78}, - dictWord{5, 11, 179}, - dictWord{ - 5, - 10, - 791, - }, - dictWord{7, 11, 1095}, - dictWord{135, 11, 1213}, - dictWord{8, 11, 372}, - dictWord{9, 11, 122}, - dictWord{138, 11, 175}, - dictWord{7, 10, 686}, - dictWord{8, 10, 33}, - dictWord{8, 10, 238}, - dictWord{10, 10, 616}, - dictWord{11, 10, 467}, - dictWord{11, 10, 881}, - dictWord{13, 10, 217}, - dictWord{13, 10, 253}, - dictWord{142, 10, 268}, - dictWord{9, 0, 476}, - dictWord{4, 11, 66}, - dictWord{7, 11, 722}, - dictWord{135, 11, 904}, - dictWord{7, 11, 352}, - dictWord{137, 11, 684}, - dictWord{135, 0, 2023}, - dictWord{135, 0, 1836}, - dictWord{132, 10, 447}, - dictWord{5, 0, 843}, - dictWord{144, 0, 35}, - dictWord{137, 11, 779}, - dictWord{ - 141, - 11, - 35, - }, - dictWord{4, 10, 128}, - dictWord{5, 10, 415}, - dictWord{6, 10, 462}, - dictWord{7, 10, 294}, - dictWord{7, 10, 578}, - dictWord{10, 10, 710}, - dictWord{ - 139, - 10, - 86, - }, - dictWord{132, 0, 554}, - dictWord{133, 0, 536}, - dictWord{136, 10, 587}, - dictWord{5, 0, 207}, - dictWord{9, 0, 79}, - dictWord{11, 0, 625}, - dictWord{ - 145, - 0, - 7, - }, - dictWord{7, 0, 1371}, - dictWord{6, 10, 427}, - dictWord{138, 10, 692}, - dictWord{4, 0, 424}, - dictWord{4, 10, 195}, - dictWord{135, 10, 802}, - dictWord{ - 8, - 0, - 785, - }, - dictWord{133, 11, 564}, - dictWord{135, 0, 336}, - dictWord{4, 0, 896}, - dictWord{6, 0, 1777}, - dictWord{134, 11, 556}, - dictWord{137, 11, 103}, - dictWord{134, 10, 1683}, - dictWord{7, 11, 544}, - dictWord{8, 11, 719}, - dictWord{138, 11, 61}, - dictWord{138, 10, 472}, - dictWord{4, 11, 5}, - dictWord{5, 11, 498}, - dictWord{136, 11, 637}, - dictWord{7, 0, 750}, - dictWord{9, 0, 223}, - dictWord{11, 0, 27}, - dictWord{11, 0, 466}, - dictWord{12, 0, 624}, - dictWord{14, 0, 265}, - dictWord{ - 146, - 0, - 61, - }, - dictWord{12, 0, 238}, - dictWord{18, 0, 155}, - dictWord{12, 11, 238}, - dictWord{146, 11, 155}, - dictWord{151, 10, 28}, - dictWord{133, 11, 927}, - dictWord{12, 0, 383}, - dictWord{5, 10, 3}, - dictWord{8, 10, 578}, - dictWord{9, 10, 118}, - dictWord{10, 10, 705}, - dictWord{141, 10, 279}, - dictWord{4, 11, 893}, - dictWord{ - 5, - 11, - 780, - }, - dictWord{133, 11, 893}, - dictWord{4, 0, 603}, - dictWord{133, 0, 661}, - dictWord{4, 0, 11}, - dictWord{6, 0, 128}, - dictWord{7, 0, 231}, - dictWord{ - 7, - 0, - 1533, - }, - dictWord{10, 0, 725}, - dictWord{5, 10, 229}, - dictWord{5, 11, 238}, - dictWord{135, 11, 1350}, - dictWord{8, 10, 102}, - dictWord{10, 10, 578}, - dictWord{ - 10, - 10, - 672, - }, - dictWord{12, 10, 496}, - dictWord{13, 10, 408}, - dictWord{14, 10, 121}, - dictWord{145, 10, 106}, - dictWord{132, 0, 476}, - dictWord{134, 0, 1552}, - dictWord{134, 11, 1729}, - dictWord{8, 10, 115}, - dictWord{8, 10, 350}, - dictWord{9, 10, 489}, - dictWord{10, 10, 128}, - dictWord{11, 10, 306}, - dictWord{ - 12, - 10, - 373, - }, - dictWord{14, 10, 30}, - dictWord{17, 10, 79}, - dictWord{19, 10, 80}, - dictWord{150, 10, 55}, - dictWord{135, 0, 1807}, - dictWord{4, 0, 680}, - dictWord{ - 4, - 11, - 60, - }, - dictWord{7, 11, 760}, - dictWord{7, 11, 1800}, - dictWord{8, 11, 314}, - dictWord{9, 11, 700}, - dictWord{139, 11, 487}, - dictWord{4, 10, 230}, - dictWord{ - 5, - 10, - 702, - }, - dictWord{148, 11, 94}, - dictWord{132, 11, 228}, - dictWord{139, 0, 435}, - dictWord{9, 0, 20}, - dictWord{10, 0, 324}, - dictWord{10, 0, 807}, - dictWord{ - 139, - 0, - 488, - }, - dictWord{6, 10, 1728}, - dictWord{136, 11, 419}, - dictWord{4, 10, 484}, - dictWord{18, 10, 26}, - dictWord{19, 10, 42}, - dictWord{20, 10, 43}, - dictWord{ - 21, - 10, - 0, - }, - dictWord{23, 10, 27}, - dictWord{152, 10, 14}, - dictWord{135, 0, 1431}, - dictWord{133, 11, 828}, - dictWord{5, 0, 112}, - dictWord{6, 0, 103}, - dictWord{ - 6, - 0, - 150, - }, - dictWord{7, 0, 1303}, - dictWord{9, 0, 292}, - dictWord{10, 0, 481}, - dictWord{20, 0, 13}, - dictWord{7, 11, 176}, - dictWord{7, 11, 178}, - dictWord{7, 11, 1110}, - dictWord{10, 11, 481}, - dictWord{148, 11, 13}, - dictWord{138, 0, 356}, - dictWord{4, 11, 51}, - dictWord{5, 11, 39}, - dictWord{6, 11, 4}, - dictWord{7, 11, 591}, - dictWord{ - 7, - 11, - 849, - }, - dictWord{7, 11, 951}, - dictWord{7, 11, 1129}, - dictWord{7, 11, 1613}, - dictWord{7, 11, 1760}, - dictWord{7, 11, 1988}, - dictWord{9, 11, 434}, - dictWord{10, 11, 754}, - dictWord{11, 11, 25}, - dictWord{11, 11, 37}, - dictWord{139, 11, 414}, - dictWord{6, 0, 1963}, - dictWord{134, 0, 2000}, - dictWord{ - 132, - 10, - 633, - }, - dictWord{6, 0, 1244}, - dictWord{133, 11, 902}, - dictWord{135, 11, 928}, - dictWord{140, 0, 18}, - dictWord{138, 0, 204}, - dictWord{135, 11, 1173}, - dictWord{134, 0, 867}, - dictWord{4, 0, 708}, - dictWord{8, 0, 15}, - dictWord{9, 0, 50}, - dictWord{9, 0, 386}, - dictWord{11, 0, 18}, - dictWord{11, 0, 529}, - dictWord{140, 0, 228}, - dictWord{134, 11, 270}, - dictWord{4, 0, 563}, - dictWord{7, 0, 109}, - dictWord{7, 0, 592}, - dictWord{7, 0, 637}, - dictWord{7, 0, 770}, - dictWord{8, 0, 463}, - dictWord{ - 9, - 0, - 60, - }, - dictWord{9, 0, 335}, - dictWord{9, 0, 904}, - dictWord{10, 0, 73}, - dictWord{11, 0, 434}, - dictWord{12, 0, 585}, - dictWord{13, 0, 331}, - dictWord{18, 0, 110}, - dictWord{148, 0, 60}, - dictWord{132, 0, 502}, - dictWord{14, 11, 359}, - dictWord{19, 11, 52}, - dictWord{148, 11, 47}, - dictWord{6, 11, 377}, - dictWord{7, 11, 1025}, - dictWord{9, 11, 613}, - dictWord{145, 11, 104}, - dictWord{6, 0, 347}, - dictWord{10, 0, 161}, - dictWord{5, 10, 70}, - dictWord{5, 10, 622}, - dictWord{6, 10, 334}, - dictWord{ - 7, - 10, - 1032, - }, - dictWord{9, 10, 171}, - dictWord{11, 10, 26}, - dictWord{11, 10, 213}, - dictWord{11, 10, 637}, - dictWord{11, 10, 707}, - dictWord{12, 10, 202}, - dictWord{12, 10, 380}, - dictWord{13, 10, 226}, - dictWord{13, 10, 355}, - dictWord{14, 10, 222}, - dictWord{145, 10, 42}, - dictWord{132, 11, 416}, - dictWord{4, 0, 33}, - dictWord{5, 0, 102}, - dictWord{6, 0, 284}, - dictWord{7, 0, 1079}, - dictWord{7, 0, 1423}, - dictWord{7, 0, 1702}, - dictWord{8, 0, 470}, - dictWord{9, 0, 554}, - dictWord{ - 9, - 0, - 723, - }, - dictWord{11, 0, 333}, - dictWord{142, 11, 372}, - dictWord{5, 11, 152}, - dictWord{5, 11, 197}, - dictWord{7, 11, 340}, - dictWord{7, 11, 867}, - dictWord{ - 10, - 11, - 548, - }, - dictWord{10, 11, 581}, - dictWord{11, 11, 6}, - dictWord{12, 11, 3}, - dictWord{12, 11, 19}, - dictWord{14, 11, 110}, - dictWord{142, 11, 289}, - dictWord{ - 7, - 0, - 246, - }, - dictWord{135, 0, 840}, - dictWord{6, 0, 10}, - dictWord{8, 0, 571}, - dictWord{9, 0, 739}, - dictWord{143, 0, 91}, - dictWord{6, 0, 465}, - dictWord{7, 0, 1465}, - dictWord{ - 4, - 10, - 23, - }, - dictWord{4, 10, 141}, - dictWord{5, 10, 313}, - dictWord{5, 10, 1014}, - dictWord{6, 10, 50}, - dictWord{7, 10, 142}, - dictWord{7, 10, 559}, - dictWord{ - 8, - 10, - 640, - }, - dictWord{9, 10, 460}, - dictWord{9, 10, 783}, - dictWord{11, 10, 741}, - dictWord{12, 10, 183}, - dictWord{141, 10, 488}, - dictWord{133, 0, 626}, - dictWord{ - 136, - 0, - 614, - }, - dictWord{138, 0, 237}, - dictWord{7, 11, 34}, - dictWord{7, 11, 190}, - dictWord{8, 11, 28}, - dictWord{8, 11, 141}, - dictWord{8, 11, 444}, - dictWord{ - 8, - 11, - 811, - }, - dictWord{9, 11, 468}, - dictWord{11, 11, 334}, - dictWord{12, 11, 24}, - dictWord{12, 11, 386}, - dictWord{140, 11, 576}, - dictWord{133, 11, 757}, - dictWord{ - 5, - 0, - 18, - }, - dictWord{6, 0, 526}, - dictWord{13, 0, 24}, - dictWord{13, 0, 110}, - dictWord{19, 0, 5}, - dictWord{147, 0, 44}, - dictWord{6, 0, 506}, - dictWord{134, 11, 506}, - dictWord{135, 11, 1553}, - dictWord{4, 0, 309}, - dictWord{5, 0, 462}, - dictWord{7, 0, 970}, - dictWord{7, 0, 1097}, - dictWord{22, 0, 30}, - dictWord{22, 0, 33}, - dictWord{ - 7, - 11, - 1385, - }, - dictWord{11, 11, 582}, - dictWord{11, 11, 650}, - dictWord{11, 11, 901}, - dictWord{11, 11, 949}, - dictWord{12, 11, 232}, - dictWord{12, 11, 236}, - dictWord{13, 11, 413}, - dictWord{13, 11, 501}, - dictWord{146, 11, 116}, - dictWord{9, 0, 140}, - dictWord{5, 10, 222}, - dictWord{138, 10, 534}, - dictWord{6, 0, 1056}, - dictWord{137, 10, 906}, - dictWord{134, 0, 1704}, - dictWord{138, 10, 503}, - dictWord{134, 0, 1036}, - dictWord{5, 10, 154}, - dictWord{7, 10, 1491}, - dictWord{ - 10, - 10, - 379, - }, - dictWord{138, 10, 485}, - dictWord{4, 11, 383}, - dictWord{133, 10, 716}, - dictWord{134, 0, 1315}, - dictWord{5, 0, 86}, - dictWord{7, 0, 743}, - dictWord{ - 9, - 0, - 85, - }, - dictWord{10, 0, 281}, - dictWord{10, 0, 432}, - dictWord{11, 0, 825}, - dictWord{12, 0, 251}, - dictWord{13, 0, 118}, - dictWord{142, 0, 378}, - dictWord{ - 8, - 0, - 264, - }, - dictWord{4, 10, 91}, - dictWord{5, 10, 388}, - dictWord{5, 10, 845}, - dictWord{6, 10, 206}, - dictWord{6, 10, 252}, - dictWord{6, 10, 365}, - dictWord{7, 10, 136}, - dictWord{7, 10, 531}, - dictWord{136, 10, 621}, - dictWord{5, 0, 524}, - dictWord{133, 0, 744}, - dictWord{5, 11, 277}, - dictWord{141, 11, 247}, - dictWord{ - 132, - 11, - 435, - }, - dictWord{10, 0, 107}, - dictWord{140, 0, 436}, - dictWord{132, 0, 927}, - dictWord{10, 0, 123}, - dictWord{12, 0, 670}, - dictWord{146, 0, 94}, - dictWord{ - 7, - 0, - 1149, - }, - dictWord{9, 0, 156}, - dictWord{138, 0, 957}, - dictWord{5, 11, 265}, - dictWord{6, 11, 212}, - dictWord{135, 11, 28}, - dictWord{133, 0, 778}, - dictWord{ - 133, - 0, - 502, - }, - dictWord{8, 0, 196}, - dictWord{10, 0, 283}, - dictWord{139, 0, 406}, - dictWord{135, 10, 576}, - dictWord{136, 11, 535}, - dictWord{134, 0, 1312}, - dictWord{ - 5, - 10, - 771, - }, - dictWord{5, 10, 863}, - dictWord{5, 10, 898}, - dictWord{6, 10, 1632}, - dictWord{6, 10, 1644}, - dictWord{134, 10, 1780}, - dictWord{5, 0, 855}, - dictWord{5, 10, 331}, - dictWord{135, 11, 1487}, - dictWord{132, 11, 702}, - dictWord{5, 11, 808}, - dictWord{135, 11, 2045}, - dictWord{7, 0, 1400}, - dictWord{ - 9, - 0, - 446, - }, - dictWord{138, 0, 45}, - dictWord{140, 10, 632}, - dictWord{132, 0, 1003}, - dictWord{5, 11, 166}, - dictWord{8, 11, 739}, - dictWord{140, 11, 511}, - dictWord{ - 5, - 10, - 107, - }, - dictWord{7, 10, 201}, - dictWord{136, 10, 518}, - dictWord{6, 10, 446}, - dictWord{135, 10, 1817}, - dictWord{134, 0, 1532}, - dictWord{ - 134, - 0, - 1097, - }, - dictWord{4, 11, 119}, - dictWord{5, 11, 170}, - dictWord{5, 11, 447}, - dictWord{7, 11, 1708}, - dictWord{7, 11, 1889}, - dictWord{9, 11, 357}, - dictWord{ - 9, - 11, - 719, - }, - dictWord{12, 11, 486}, - dictWord{140, 11, 596}, - dictWord{9, 10, 851}, - dictWord{141, 10, 510}, - dictWord{7, 0, 612}, - dictWord{8, 0, 545}, - dictWord{ - 8, - 0, - 568, - }, - dictWord{8, 0, 642}, - dictWord{9, 0, 717}, - dictWord{10, 0, 541}, - dictWord{10, 0, 763}, - dictWord{11, 0, 449}, - dictWord{12, 0, 489}, - dictWord{13, 0, 153}, - dictWord{13, 0, 296}, - dictWord{14, 0, 138}, - dictWord{14, 0, 392}, - dictWord{15, 0, 50}, - dictWord{16, 0, 6}, - dictWord{16, 0, 12}, - dictWord{20, 0, 9}, - dictWord{ - 132, - 10, - 504, - }, - dictWord{4, 11, 450}, - dictWord{135, 11, 1158}, - dictWord{11, 0, 54}, - dictWord{13, 0, 173}, - dictWord{13, 0, 294}, - dictWord{5, 10, 883}, - dictWord{ - 5, - 10, - 975, - }, - dictWord{8, 10, 392}, - dictWord{148, 10, 7}, - dictWord{13, 0, 455}, - dictWord{15, 0, 99}, - dictWord{15, 0, 129}, - dictWord{144, 0, 68}, - dictWord{135, 0, 172}, - dictWord{132, 11, 754}, - dictWord{5, 10, 922}, - dictWord{134, 10, 1707}, - dictWord{134, 0, 1029}, - dictWord{17, 11, 39}, - dictWord{148, 11, 36}, - dictWord{ - 4, - 0, - 568, - }, - dictWord{5, 10, 993}, - dictWord{7, 10, 515}, - dictWord{137, 10, 91}, - dictWord{132, 0, 732}, - dictWord{10, 0, 617}, - dictWord{138, 11, 617}, - dictWord{ - 134, - 0, - 974, - }, - dictWord{7, 0, 989}, - dictWord{10, 0, 377}, - dictWord{12, 0, 363}, - dictWord{13, 0, 68}, - dictWord{13, 0, 94}, - dictWord{14, 0, 108}, - dictWord{ - 142, - 0, - 306, - }, - dictWord{136, 0, 733}, - dictWord{132, 0, 428}, - dictWord{7, 0, 1789}, - dictWord{135, 11, 1062}, - dictWord{7, 0, 2015}, - dictWord{140, 0, 665}, - dictWord{135, 10, 1433}, - dictWord{5, 0, 287}, - dictWord{7, 10, 921}, - dictWord{8, 10, 580}, - dictWord{8, 10, 593}, - dictWord{8, 10, 630}, - dictWord{138, 10, 28}, - dictWord{138, 0, 806}, - dictWord{4, 10, 911}, - dictWord{5, 10, 867}, - dictWord{5, 10, 1013}, - dictWord{7, 10, 2034}, - dictWord{8, 10, 798}, - dictWord{136, 10, 813}, - dictWord{134, 0, 1539}, - dictWord{8, 11, 523}, - dictWord{150, 11, 34}, - dictWord{135, 11, 740}, - dictWord{7, 11, 238}, - dictWord{7, 11, 2033}, - dictWord{ - 8, - 11, - 120, - }, - dictWord{8, 11, 188}, - dictWord{8, 11, 659}, - dictWord{9, 11, 598}, - dictWord{10, 11, 466}, - dictWord{12, 11, 342}, - dictWord{12, 11, 588}, - dictWord{ - 13, - 11, - 503, - }, - dictWord{14, 11, 246}, - dictWord{143, 11, 92}, - dictWord{7, 0, 1563}, - dictWord{141, 0, 182}, - dictWord{5, 10, 135}, - dictWord{6, 10, 519}, - dictWord{ - 7, - 10, - 1722, - }, - dictWord{10, 10, 271}, - dictWord{11, 10, 261}, - dictWord{145, 10, 54}, - dictWord{14, 10, 338}, - dictWord{148, 10, 81}, - dictWord{7, 0, 484}, - dictWord{ - 4, - 10, - 300, - }, - dictWord{133, 10, 436}, - dictWord{145, 11, 114}, - dictWord{6, 0, 1623}, - dictWord{134, 0, 1681}, - dictWord{133, 11, 640}, - dictWord{4, 11, 201}, - dictWord{7, 11, 1744}, - dictWord{8, 11, 602}, - dictWord{11, 11, 247}, - dictWord{11, 11, 826}, - dictWord{145, 11, 65}, - dictWord{8, 11, 164}, - dictWord{ - 146, - 11, - 62, - }, - dictWord{6, 0, 1833}, - dictWord{6, 0, 1861}, - dictWord{136, 0, 878}, - dictWord{134, 0, 1569}, - dictWord{8, 10, 357}, - dictWord{10, 10, 745}, - dictWord{ - 14, - 10, - 426, - }, - dictWord{17, 10, 94}, - dictWord{147, 10, 57}, - dictWord{12, 0, 93}, - dictWord{12, 0, 501}, - dictWord{13, 0, 362}, - dictWord{14, 0, 151}, - dictWord{15, 0, 40}, - dictWord{15, 0, 59}, - dictWord{16, 0, 46}, - dictWord{17, 0, 25}, - dictWord{18, 0, 14}, - dictWord{18, 0, 134}, - dictWord{19, 0, 25}, - dictWord{19, 0, 69}, - dictWord{ - 20, - 0, - 16, - }, - dictWord{20, 0, 19}, - dictWord{20, 0, 66}, - dictWord{21, 0, 23}, - dictWord{21, 0, 25}, - dictWord{150, 0, 42}, - dictWord{6, 0, 1748}, - dictWord{8, 0, 715}, - dictWord{ - 9, - 0, - 802, - }, - dictWord{10, 0, 46}, - dictWord{10, 0, 819}, - dictWord{13, 0, 308}, - dictWord{14, 0, 351}, - dictWord{14, 0, 363}, - dictWord{146, 0, 67}, - dictWord{ - 132, - 0, - 994, - }, - dictWord{4, 0, 63}, - dictWord{133, 0, 347}, - dictWord{132, 0, 591}, - dictWord{133, 0, 749}, - dictWord{7, 11, 1577}, - dictWord{10, 11, 304}, - dictWord{ - 10, - 11, - 549, - }, - dictWord{11, 11, 424}, - dictWord{12, 11, 365}, - dictWord{13, 11, 220}, - dictWord{13, 11, 240}, - dictWord{142, 11, 33}, - dictWord{133, 0, 366}, - dictWord{ - 7, - 0, - 557, - }, - dictWord{12, 0, 547}, - dictWord{14, 0, 86}, - dictWord{133, 10, 387}, - dictWord{135, 0, 1747}, - dictWord{132, 11, 907}, - dictWord{5, 11, 100}, - dictWord{10, 11, 329}, - dictWord{12, 11, 416}, - dictWord{149, 11, 29}, - dictWord{4, 10, 6}, - dictWord{5, 10, 708}, - dictWord{136, 10, 75}, - dictWord{7, 10, 1351}, - dictWord{9, 10, 581}, - dictWord{10, 10, 639}, - dictWord{11, 10, 453}, - dictWord{140, 10, 584}, - dictWord{7, 0, 89}, - dictWord{132, 10, 303}, - dictWord{138, 10, 772}, - dictWord{132, 11, 176}, - dictWord{5, 11, 636}, - dictWord{5, 11, 998}, - dictWord{8, 11, 26}, - dictWord{137, 11, 358}, - dictWord{7, 11, 9}, - dictWord{7, 11, 1508}, - dictWord{9, 11, 317}, - dictWord{10, 11, 210}, - dictWord{10, 11, 292}, - dictWord{10, 11, 533}, - dictWord{11, 11, 555}, - dictWord{12, 11, 526}, - dictWord{ - 12, - 11, - 607, - }, - dictWord{13, 11, 263}, - dictWord{13, 11, 459}, - dictWord{142, 11, 271}, - dictWord{134, 0, 1463}, - dictWord{6, 0, 772}, - dictWord{6, 0, 1137}, - dictWord{ - 139, - 11, - 595, - }, - dictWord{7, 0, 977}, - dictWord{139, 11, 66}, - dictWord{138, 0, 893}, - dictWord{20, 0, 48}, - dictWord{148, 11, 48}, - dictWord{5, 0, 824}, - dictWord{ - 133, - 0, - 941, - }, - dictWord{134, 11, 295}, - dictWord{7, 0, 1543}, - dictWord{7, 0, 1785}, - dictWord{10, 0, 690}, - dictWord{4, 10, 106}, - dictWord{139, 10, 717}, - dictWord{ - 7, - 0, - 440, - }, - dictWord{8, 0, 230}, - dictWord{139, 0, 106}, - dictWord{5, 10, 890}, - dictWord{133, 10, 988}, - dictWord{6, 10, 626}, - dictWord{142, 10, 431}, - dictWord{ - 10, - 11, - 127, - }, - dictWord{141, 11, 27}, - dictWord{17, 0, 32}, - dictWord{10, 10, 706}, - dictWord{150, 10, 44}, - dictWord{132, 0, 216}, - dictWord{137, 0, 332}, - dictWord{4, 10, 698}, - dictWord{136, 11, 119}, - dictWord{139, 11, 267}, - dictWord{138, 10, 17}, - dictWord{11, 11, 526}, - dictWord{11, 11, 939}, - dictWord{ - 141, - 11, - 290, - }, - dictWord{7, 11, 1167}, - dictWord{11, 11, 934}, - dictWord{13, 11, 391}, - dictWord{145, 11, 76}, - dictWord{139, 11, 39}, - dictWord{134, 10, 84}, - dictWord{ - 4, - 0, - 914, - }, - dictWord{5, 0, 800}, - dictWord{133, 0, 852}, - dictWord{10, 0, 416}, - dictWord{141, 0, 115}, - dictWord{7, 0, 564}, - dictWord{142, 0, 168}, - dictWord{ - 4, - 0, - 918, - }, - dictWord{133, 0, 876}, - dictWord{134, 0, 1764}, - dictWord{152, 0, 3}, - dictWord{4, 0, 92}, - dictWord{5, 0, 274}, - dictWord{7, 11, 126}, - dictWord{136, 11, 84}, - dictWord{140, 10, 498}, - dictWord{136, 11, 790}, - dictWord{8, 0, 501}, - dictWord{5, 10, 986}, - dictWord{6, 10, 130}, - dictWord{7, 10, 1582}, - dictWord{ - 8, - 10, - 458, - }, - dictWord{10, 10, 101}, - dictWord{10, 10, 318}, - dictWord{138, 10, 823}, - dictWord{6, 11, 64}, - dictWord{12, 11, 377}, - dictWord{141, 11, 309}, - dictWord{ - 5, - 0, - 743, - }, - dictWord{138, 0, 851}, - dictWord{4, 0, 49}, - dictWord{7, 0, 280}, - dictWord{135, 0, 1633}, - dictWord{134, 0, 879}, - dictWord{136, 0, 47}, - dictWord{ - 7, - 10, - 1644, - }, - dictWord{137, 10, 129}, - dictWord{132, 0, 865}, - dictWord{134, 0, 1202}, - dictWord{9, 11, 34}, - dictWord{139, 11, 484}, - dictWord{135, 10, 997}, - dictWord{5, 0, 272}, - dictWord{5, 0, 908}, - dictWord{5, 0, 942}, - dictWord{8, 0, 197}, - dictWord{9, 0, 47}, - dictWord{11, 0, 538}, - dictWord{139, 0, 742}, - dictWord{ - 6, - 11, - 1700, - }, - dictWord{7, 11, 26}, - dictWord{7, 11, 293}, - dictWord{7, 11, 382}, - dictWord{7, 11, 1026}, - dictWord{7, 11, 1087}, - dictWord{7, 11, 2027}, - dictWord{ - 8, - 11, - 24, - }, - dictWord{8, 11, 114}, - dictWord{8, 11, 252}, - dictWord{8, 11, 727}, - dictWord{8, 11, 729}, - dictWord{9, 11, 30}, - dictWord{9, 11, 199}, - dictWord{9, 11, 231}, - dictWord{9, 11, 251}, - dictWord{9, 11, 334}, - dictWord{9, 11, 361}, - dictWord{9, 11, 488}, - dictWord{9, 11, 712}, - dictWord{10, 11, 55}, - dictWord{10, 11, 60}, - dictWord{ - 10, - 11, - 232, - }, - dictWord{10, 11, 332}, - dictWord{10, 11, 384}, - dictWord{10, 11, 396}, - dictWord{10, 11, 504}, - dictWord{10, 11, 542}, - dictWord{10, 11, 652}, - dictWord{11, 11, 20}, - dictWord{11, 11, 48}, - dictWord{11, 11, 207}, - dictWord{11, 11, 291}, - dictWord{11, 11, 298}, - dictWord{11, 11, 342}, - dictWord{ - 11, - 11, - 365, - }, - dictWord{11, 11, 394}, - dictWord{11, 11, 620}, - dictWord{11, 11, 705}, - dictWord{11, 11, 1017}, - dictWord{12, 11, 123}, - dictWord{12, 11, 340}, - dictWord{12, 11, 406}, - dictWord{12, 11, 643}, - dictWord{13, 11, 61}, - dictWord{13, 11, 269}, - dictWord{13, 11, 311}, - dictWord{13, 11, 319}, - dictWord{13, 11, 486}, - dictWord{14, 11, 234}, - dictWord{15, 11, 62}, - dictWord{15, 11, 85}, - dictWord{16, 11, 71}, - dictWord{18, 11, 119}, - dictWord{148, 11, 105}, - dictWord{ - 6, - 0, - 1455, - }, - dictWord{150, 11, 37}, - dictWord{135, 10, 1927}, - dictWord{135, 0, 1911}, - dictWord{137, 0, 891}, - dictWord{7, 10, 1756}, - dictWord{137, 10, 98}, - dictWord{7, 10, 1046}, - dictWord{139, 10, 160}, - dictWord{132, 0, 761}, - dictWord{6, 11, 379}, - dictWord{7, 11, 270}, - dictWord{7, 11, 1116}, - dictWord{ - 8, - 11, - 176, - }, - dictWord{8, 11, 183}, - dictWord{9, 11, 432}, - dictWord{9, 11, 661}, - dictWord{12, 11, 247}, - dictWord{12, 11, 617}, - dictWord{146, 11, 125}, - dictWord{ - 6, - 10, - 45, - }, - dictWord{7, 10, 433}, - dictWord{8, 10, 129}, - dictWord{9, 10, 21}, - dictWord{10, 10, 392}, - dictWord{11, 10, 79}, - dictWord{12, 10, 499}, - dictWord{ - 13, - 10, - 199, - }, - dictWord{141, 10, 451}, - dictWord{4, 0, 407}, - dictWord{5, 11, 792}, - dictWord{133, 11, 900}, - dictWord{132, 0, 560}, - dictWord{135, 0, 183}, - dictWord{ - 13, - 0, - 490, - }, - dictWord{7, 10, 558}, - dictWord{136, 10, 353}, - dictWord{4, 0, 475}, - dictWord{6, 0, 731}, - dictWord{11, 0, 35}, - dictWord{13, 0, 71}, - dictWord{13, 0, 177}, - dictWord{14, 0, 422}, - dictWord{133, 10, 785}, - dictWord{8, 10, 81}, - dictWord{9, 10, 189}, - dictWord{9, 10, 201}, - dictWord{11, 10, 478}, - dictWord{11, 10, 712}, - dictWord{141, 10, 338}, - dictWord{4, 0, 418}, - dictWord{4, 0, 819}, - dictWord{133, 10, 353}, - dictWord{151, 10, 26}, - dictWord{4, 11, 901}, - dictWord{ - 133, - 11, - 776, - }, - dictWord{132, 0, 575}, - dictWord{7, 0, 818}, - dictWord{16, 0, 92}, - dictWord{17, 0, 14}, - dictWord{17, 0, 45}, - dictWord{18, 0, 75}, - dictWord{148, 0, 18}, - dictWord{ - 6, - 0, - 222, - }, - dictWord{7, 0, 636}, - dictWord{7, 0, 1620}, - dictWord{8, 0, 409}, - dictWord{9, 0, 693}, - dictWord{139, 0, 77}, - dictWord{6, 10, 25}, - dictWord{7, 10, 855}, - dictWord{7, 10, 1258}, - dictWord{144, 10, 32}, - dictWord{6, 0, 1880}, - dictWord{6, 0, 1887}, - dictWord{6, 0, 1918}, - dictWord{6, 0, 1924}, - dictWord{9, 0, 967}, - dictWord{9, 0, 995}, - dictWord{9, 0, 1015}, - dictWord{12, 0, 826}, - dictWord{12, 0, 849}, - dictWord{12, 0, 857}, - dictWord{12, 0, 860}, - dictWord{12, 0, 886}, - dictWord{ - 12, - 0, - 932, - }, - dictWord{18, 0, 228}, - dictWord{18, 0, 231}, - dictWord{146, 0, 240}, - dictWord{134, 0, 633}, - dictWord{134, 0, 1308}, - dictWord{4, 11, 37}, - dictWord{ - 5, - 11, - 334, - }, - dictWord{135, 11, 1253}, - dictWord{10, 0, 86}, - dictWord{4, 10, 4}, - dictWord{7, 10, 1118}, - dictWord{7, 10, 1320}, - dictWord{7, 10, 1706}, - dictWord{ - 8, - 10, - 277, - }, - dictWord{9, 10, 622}, - dictWord{11, 10, 724}, - dictWord{12, 10, 350}, - dictWord{12, 10, 397}, - dictWord{13, 10, 28}, - dictWord{13, 10, 159}, - dictWord{ - 15, - 10, - 89, - }, - dictWord{18, 10, 5}, - dictWord{19, 10, 9}, - dictWord{20, 10, 34}, - dictWord{150, 10, 47}, - dictWord{132, 11, 508}, - dictWord{137, 11, 448}, - dictWord{ - 12, - 11, - 107, - }, - dictWord{146, 11, 31}, - dictWord{132, 0, 817}, - dictWord{134, 0, 663}, - dictWord{133, 0, 882}, - dictWord{134, 0, 914}, - dictWord{132, 11, 540}, - dictWord{132, 11, 533}, - dictWord{136, 11, 608}, - dictWord{8, 0, 885}, - dictWord{138, 0, 865}, - dictWord{132, 0, 426}, - dictWord{6, 0, 58}, - dictWord{7, 0, 745}, - dictWord{7, 0, 1969}, - dictWord{8, 0, 399}, - dictWord{8, 0, 675}, - dictWord{9, 0, 479}, - dictWord{9, 0, 731}, - dictWord{10, 0, 330}, - dictWord{10, 0, 593}, - dictWord{ - 10, - 0, - 817, - }, - dictWord{11, 0, 32}, - dictWord{11, 0, 133}, - dictWord{11, 0, 221}, - dictWord{145, 0, 68}, - dictWord{134, 10, 255}, - dictWord{7, 0, 102}, - dictWord{ - 137, - 0, - 538, - }, - dictWord{137, 10, 216}, - dictWord{7, 11, 253}, - dictWord{136, 11, 549}, - dictWord{135, 11, 912}, - dictWord{9, 10, 183}, - dictWord{139, 10, 286}, - dictWord{11, 10, 956}, - dictWord{151, 10, 3}, - dictWord{8, 11, 527}, - dictWord{18, 11, 60}, - dictWord{147, 11, 24}, - dictWord{4, 10, 536}, - dictWord{7, 10, 1141}, - dictWord{10, 10, 723}, - dictWord{139, 10, 371}, - dictWord{133, 11, 920}, - dictWord{7, 0, 876}, - dictWord{135, 10, 285}, - dictWord{135, 10, 560}, - dictWord{ - 132, - 10, - 690, - }, - dictWord{142, 11, 126}, - dictWord{11, 10, 33}, - dictWord{12, 10, 571}, - dictWord{149, 10, 1}, - dictWord{133, 0, 566}, - dictWord{9, 0, 139}, - dictWord{ - 10, - 0, - 399, - }, - dictWord{11, 0, 469}, - dictWord{12, 0, 634}, - dictWord{13, 0, 223}, - dictWord{132, 11, 483}, - dictWord{6, 0, 48}, - dictWord{135, 0, 63}, - dictWord{18, 0, 12}, - dictWord{7, 10, 1862}, - dictWord{12, 10, 491}, - dictWord{12, 10, 520}, - dictWord{13, 10, 383}, - dictWord{142, 10, 244}, - dictWord{135, 11, 1665}, - dictWord{132, 11, 448}, - dictWord{9, 11, 495}, - dictWord{146, 11, 104}, - dictWord{6, 0, 114}, - dictWord{7, 0, 1224}, - dictWord{7, 0, 1556}, - dictWord{136, 0, 3}, - dictWord{ - 4, - 10, - 190, - }, - dictWord{133, 10, 554}, - dictWord{8, 0, 576}, - dictWord{9, 0, 267}, - dictWord{133, 10, 1001}, - dictWord{133, 10, 446}, - dictWord{133, 0, 933}, - dictWord{139, 11, 1009}, - dictWord{8, 11, 653}, - dictWord{13, 11, 93}, - dictWord{147, 11, 14}, - dictWord{6, 0, 692}, - dictWord{6, 0, 821}, - dictWord{134, 0, 1077}, - dictWord{5, 11, 172}, - dictWord{135, 11, 801}, - dictWord{138, 0, 752}, - dictWord{4, 0, 375}, - dictWord{134, 0, 638}, - dictWord{134, 0, 1011}, - dictWord{ - 140, - 11, - 540, - }, - dictWord{9, 0, 96}, - dictWord{133, 11, 260}, - dictWord{139, 11, 587}, - dictWord{135, 10, 1231}, - dictWord{12, 0, 30}, - dictWord{13, 0, 148}, - dictWord{ - 14, - 0, - 87, - }, - dictWord{14, 0, 182}, - dictWord{16, 0, 42}, - dictWord{20, 0, 70}, - dictWord{132, 10, 304}, - dictWord{6, 0, 1398}, - dictWord{7, 0, 56}, - dictWord{7, 0, 1989}, - dictWord{8, 0, 337}, - dictWord{8, 0, 738}, - dictWord{9, 0, 600}, - dictWord{12, 0, 37}, - dictWord{13, 0, 447}, - dictWord{142, 0, 92}, - dictWord{138, 0, 666}, - dictWord{ - 5, - 0, - 394, - }, - dictWord{7, 0, 487}, - dictWord{136, 0, 246}, - dictWord{9, 0, 437}, - dictWord{6, 10, 53}, - dictWord{6, 10, 199}, - dictWord{7, 10, 1408}, - dictWord{8, 10, 32}, - dictWord{8, 10, 93}, - dictWord{10, 10, 397}, - dictWord{10, 10, 629}, - dictWord{11, 10, 593}, - dictWord{11, 10, 763}, - dictWord{13, 10, 326}, - dictWord{145, 10, 35}, - dictWord{134, 10, 105}, - dictWord{9, 0, 320}, - dictWord{10, 0, 506}, - dictWord{138, 10, 794}, - dictWord{7, 11, 57}, - dictWord{8, 11, 167}, - dictWord{8, 11, 375}, - dictWord{9, 11, 82}, - dictWord{9, 11, 561}, - dictWord{10, 11, 620}, - dictWord{10, 11, 770}, - dictWord{11, 10, 704}, - dictWord{141, 10, 396}, - dictWord{6, 0, 1003}, - dictWord{5, 10, 114}, - dictWord{5, 10, 255}, - dictWord{141, 10, 285}, - dictWord{7, 0, 866}, - dictWord{135, 0, 1163}, - dictWord{133, 11, 531}, - dictWord{ - 132, - 0, - 328, - }, - dictWord{7, 10, 2035}, - dictWord{8, 10, 19}, - dictWord{9, 10, 89}, - dictWord{138, 10, 831}, - dictWord{8, 11, 194}, - dictWord{136, 11, 756}, - dictWord{ - 136, - 0, - 1000, - }, - dictWord{5, 11, 453}, - dictWord{134, 11, 441}, - dictWord{4, 0, 101}, - dictWord{5, 0, 833}, - dictWord{7, 0, 1171}, - dictWord{136, 0, 744}, - dictWord{ - 133, - 0, - 726, - }, - dictWord{136, 10, 746}, - dictWord{138, 0, 176}, - dictWord{6, 0, 9}, - dictWord{6, 0, 397}, - dictWord{7, 0, 53}, - dictWord{7, 0, 1742}, - dictWord{10, 0, 632}, - dictWord{11, 0, 828}, - dictWord{140, 0, 146}, - dictWord{135, 11, 22}, - dictWord{145, 11, 64}, - dictWord{132, 0, 839}, - dictWord{11, 0, 417}, - dictWord{12, 0, 223}, - dictWord{140, 0, 265}, - dictWord{4, 11, 102}, - dictWord{7, 11, 815}, - dictWord{7, 11, 1699}, - dictWord{139, 11, 964}, - dictWord{5, 10, 955}, - dictWord{ - 136, - 10, - 814, - }, - dictWord{6, 0, 1931}, - dictWord{6, 0, 2007}, - dictWord{18, 0, 246}, - dictWord{146, 0, 247}, - dictWord{8, 0, 198}, - dictWord{11, 0, 29}, - dictWord{140, 0, 534}, - dictWord{135, 0, 1771}, - dictWord{6, 0, 846}, - dictWord{7, 11, 1010}, - dictWord{11, 11, 733}, - dictWord{11, 11, 759}, - dictWord{12, 11, 563}, - dictWord{ - 13, - 11, - 34, - }, - dictWord{14, 11, 101}, - dictWord{18, 11, 45}, - dictWord{146, 11, 129}, - dictWord{4, 0, 186}, - dictWord{5, 0, 157}, - dictWord{8, 0, 168}, - dictWord{138, 0, 6}, - dictWord{132, 11, 899}, - dictWord{133, 10, 56}, - dictWord{148, 10, 100}, - dictWord{133, 0, 875}, - dictWord{5, 0, 773}, - dictWord{5, 0, 991}, - dictWord{6, 0, 1635}, - dictWord{134, 0, 1788}, - dictWord{6, 0, 1274}, - dictWord{9, 0, 477}, - dictWord{141, 0, 78}, - dictWord{4, 0, 639}, - dictWord{7, 0, 111}, - dictWord{8, 0, 581}, - dictWord{ - 12, - 0, - 177, - }, - dictWord{6, 11, 52}, - dictWord{9, 11, 104}, - dictWord{9, 11, 559}, - dictWord{10, 10, 4}, - dictWord{10, 10, 13}, - dictWord{11, 10, 638}, - dictWord{ - 12, - 11, - 308, - }, - dictWord{19, 11, 87}, - dictWord{148, 10, 57}, - dictWord{132, 11, 604}, - dictWord{4, 11, 301}, - dictWord{133, 10, 738}, - dictWord{133, 10, 758}, - dictWord{134, 0, 1747}, - dictWord{7, 11, 1440}, - dictWord{11, 11, 854}, - dictWord{11, 11, 872}, - dictWord{11, 11, 921}, - dictWord{12, 11, 551}, - dictWord{ - 13, - 11, - 472, - }, - dictWord{142, 11, 367}, - dictWord{7, 0, 1364}, - dictWord{7, 0, 1907}, - dictWord{141, 0, 158}, - dictWord{134, 0, 873}, - dictWord{4, 0, 404}, - dictWord{ - 4, - 0, - 659, - }, - dictWord{7, 0, 552}, - dictWord{135, 0, 675}, - dictWord{135, 10, 1112}, - dictWord{139, 10, 328}, - dictWord{7, 11, 508}, - dictWord{137, 10, 133}, - dictWord{133, 0, 391}, - dictWord{5, 10, 110}, - dictWord{6, 10, 169}, - dictWord{6, 10, 1702}, - dictWord{7, 10, 400}, - dictWord{8, 10, 538}, - dictWord{9, 10, 184}, - dictWord{ - 9, - 10, - 524, - }, - dictWord{140, 10, 218}, - dictWord{6, 11, 310}, - dictWord{7, 11, 1849}, - dictWord{8, 11, 72}, - dictWord{8, 11, 272}, - dictWord{8, 11, 431}, - dictWord{ - 9, - 11, - 12, - }, - dictWord{9, 11, 351}, - dictWord{10, 11, 563}, - dictWord{10, 11, 630}, - dictWord{10, 11, 810}, - dictWord{11, 11, 367}, - dictWord{11, 11, 599}, - dictWord{11, 11, 686}, - dictWord{140, 11, 672}, - dictWord{5, 0, 540}, - dictWord{6, 0, 1697}, - dictWord{136, 0, 668}, - dictWord{132, 0, 883}, - dictWord{134, 0, 78}, - dictWord{12, 0, 628}, - dictWord{18, 0, 79}, - dictWord{6, 10, 133}, - dictWord{9, 10, 353}, - dictWord{139, 10, 993}, - dictWord{6, 11, 181}, - dictWord{7, 11, 537}, - dictWord{ - 8, - 11, - 64, - }, - dictWord{9, 11, 127}, - dictWord{10, 11, 496}, - dictWord{12, 11, 510}, - dictWord{141, 11, 384}, - dictWord{6, 10, 93}, - dictWord{7, 10, 1422}, - dictWord{ - 7, - 10, - 1851, - }, - dictWord{8, 10, 673}, - dictWord{9, 10, 529}, - dictWord{140, 10, 43}, - dictWord{137, 10, 371}, - dictWord{134, 0, 1460}, - dictWord{134, 0, 962}, - dictWord{4, 11, 244}, - dictWord{135, 11, 233}, - dictWord{9, 10, 25}, - dictWord{10, 10, 467}, - dictWord{138, 10, 559}, - dictWord{4, 10, 335}, - dictWord{ - 135, - 10, - 942, - }, - dictWord{133, 0, 460}, - dictWord{135, 11, 334}, - dictWord{134, 11, 1650}, - dictWord{4, 0, 199}, - dictWord{139, 0, 34}, - dictWord{5, 10, 601}, - dictWord{ - 8, - 10, - 39, - }, - dictWord{10, 10, 773}, - dictWord{11, 10, 84}, - dictWord{12, 10, 205}, - dictWord{142, 10, 1}, - dictWord{133, 10, 870}, - dictWord{134, 0, 388}, - dictWord{14, 0, 474}, - dictWord{148, 0, 120}, - dictWord{133, 11, 369}, - dictWord{139, 0, 271}, - dictWord{4, 0, 511}, - dictWord{9, 0, 333}, - dictWord{9, 0, 379}, - dictWord{ - 10, - 0, - 602, - }, - dictWord{11, 0, 441}, - dictWord{11, 0, 723}, - dictWord{11, 0, 976}, - dictWord{12, 0, 357}, - dictWord{132, 10, 181}, - dictWord{134, 0, 608}, - dictWord{134, 10, 1652}, - dictWord{22, 0, 49}, - dictWord{137, 11, 338}, - dictWord{140, 0, 988}, - dictWord{134, 0, 617}, - dictWord{5, 0, 938}, - dictWord{136, 0, 707}, - dictWord{132, 10, 97}, - dictWord{5, 10, 147}, - dictWord{6, 10, 286}, - dictWord{7, 10, 1362}, - dictWord{141, 10, 176}, - dictWord{6, 0, 756}, - dictWord{ - 134, - 0, - 1149, - }, - dictWord{133, 11, 896}, - dictWord{6, 10, 375}, - dictWord{7, 10, 169}, - dictWord{7, 10, 254}, - dictWord{136, 10, 780}, - dictWord{134, 0, 1583}, - dictWord{135, 10, 1447}, - dictWord{139, 0, 285}, - dictWord{7, 11, 1117}, - dictWord{8, 11, 393}, - dictWord{136, 11, 539}, - dictWord{135, 0, 344}, - dictWord{ - 6, - 0, - 469, - }, - dictWord{7, 0, 1709}, - dictWord{138, 0, 515}, - dictWord{5, 10, 629}, - dictWord{135, 10, 1549}, - dictWord{5, 11, 4}, - dictWord{5, 11, 810}, - dictWord{ - 6, - 11, - 13, - }, - dictWord{6, 11, 538}, - dictWord{6, 11, 1690}, - dictWord{6, 11, 1726}, - dictWord{7, 11, 499}, - dictWord{7, 11, 1819}, - dictWord{8, 11, 148}, - dictWord{ - 8, - 11, - 696, - }, - dictWord{8, 11, 791}, - dictWord{12, 11, 125}, - dictWord{13, 11, 54}, - dictWord{143, 11, 9}, - dictWord{135, 11, 1268}, - dictWord{137, 0, 404}, - dictWord{ - 132, - 0, - 500, - }, - dictWord{5, 0, 68}, - dictWord{134, 0, 383}, - dictWord{11, 0, 216}, - dictWord{139, 0, 340}, - dictWord{4, 11, 925}, - dictWord{5, 11, 803}, - dictWord{ - 8, - 11, - 698, - }, - dictWord{138, 11, 828}, - dictWord{4, 0, 337}, - dictWord{6, 0, 353}, - dictWord{7, 0, 1934}, - dictWord{8, 0, 488}, - dictWord{137, 0, 429}, - dictWord{7, 0, 236}, - dictWord{7, 0, 1795}, - dictWord{8, 0, 259}, - dictWord{9, 0, 135}, - dictWord{9, 0, 177}, - dictWord{9, 0, 860}, - dictWord{10, 0, 825}, - dictWord{11, 0, 115}, - dictWord{ - 11, - 0, - 370, - }, - dictWord{11, 0, 405}, - dictWord{11, 0, 604}, - dictWord{12, 0, 10}, - dictWord{12, 0, 667}, - dictWord{12, 0, 669}, - dictWord{13, 0, 76}, - dictWord{14, 0, 310}, - dictWord{15, 0, 76}, - dictWord{15, 0, 147}, - dictWord{148, 0, 23}, - dictWord{4, 0, 15}, - dictWord{4, 0, 490}, - dictWord{5, 0, 22}, - dictWord{6, 0, 244}, - dictWord{7, 0, 40}, - dictWord{7, 0, 200}, - dictWord{7, 0, 906}, - dictWord{7, 0, 1199}, - dictWord{9, 0, 616}, - dictWord{10, 0, 716}, - dictWord{11, 0, 635}, - dictWord{11, 0, 801}, - dictWord{ - 140, - 0, - 458, - }, - dictWord{12, 0, 756}, - dictWord{132, 10, 420}, - dictWord{134, 0, 1504}, - dictWord{6, 0, 757}, - dictWord{133, 11, 383}, - dictWord{6, 0, 1266}, - dictWord{ - 135, - 0, - 1735, - }, - dictWord{5, 0, 598}, - dictWord{7, 0, 791}, - dictWord{8, 0, 108}, - dictWord{9, 0, 123}, - dictWord{7, 10, 1570}, - dictWord{140, 10, 542}, - dictWord{ - 142, - 11, - 410, - }, - dictWord{9, 11, 660}, - dictWord{138, 11, 347}, -} diff --git a/src/vendor/github.com/andybalholm/brotli/symbol_list.go b/src/vendor/github.com/andybalholm/brotli/symbol_list.go deleted file mode 100644 index c5cb49e5..00000000 --- a/src/vendor/github.com/andybalholm/brotli/symbol_list.go +++ /dev/null @@ -1,22 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Utilities for building Huffman decoding tables. */ - -type symbolList struct { - storage []uint16 - offset int -} - -func symbolListGet(sl symbolList, i int) uint16 { - return sl.storage[i+sl.offset] -} - -func symbolListPut(sl symbolList, i int, val uint16) { - sl.storage[i+sl.offset] = val -} diff --git a/src/vendor/github.com/andybalholm/brotli/transform.go b/src/vendor/github.com/andybalholm/brotli/transform.go deleted file mode 100644 index d2c043a6..00000000 --- a/src/vendor/github.com/andybalholm/brotli/transform.go +++ /dev/null @@ -1,641 +0,0 @@ -package brotli - -const ( - transformIdentity = 0 - transformOmitLast1 = 1 - transformOmitLast2 = 2 - transformOmitLast3 = 3 - transformOmitLast4 = 4 - transformOmitLast5 = 5 - transformOmitLast6 = 6 - transformOmitLast7 = 7 - transformOmitLast8 = 8 - transformOmitLast9 = 9 - transformUppercaseFirst = 10 - transformUppercaseAll = 11 - transformOmitFirst1 = 12 - transformOmitFirst2 = 13 - transformOmitFirst3 = 14 - transformOmitFirst4 = 15 - transformOmitFirst5 = 16 - transformOmitFirst6 = 17 - transformOmitFirst7 = 18 - transformOmitFirst8 = 19 - transformOmitFirst9 = 20 - transformShiftFirst = 21 - transformShiftAll = 22 + iota - 22 - numTransformTypes -) - -const transformsMaxCutOff = transformOmitLast9 - -type transforms struct { - prefix_suffix_size uint16 - prefix_suffix []byte - prefix_suffix_map []uint16 - num_transforms uint32 - transforms []byte - params []byte - cutOffTransforms [transformsMaxCutOff + 1]int16 -} - -func transformPrefixId(t *transforms, I int) byte { - return t.transforms[(I*3)+0] -} - -func transformType(t *transforms, I int) byte { - return t.transforms[(I*3)+1] -} - -func transformSuffixId(t *transforms, I int) byte { - return t.transforms[(I*3)+2] -} - -func transformPrefix(t *transforms, I int) []byte { - return t.prefix_suffix[t.prefix_suffix_map[transformPrefixId(t, I)]:] -} - -func transformSuffix(t *transforms, I int) []byte { - return t.prefix_suffix[t.prefix_suffix_map[transformSuffixId(t, I)]:] -} - -/* RFC 7932 transforms string data */ -const kPrefixSuffix string = "\001 \002, \010 of the \004 of \002s \001.\005 and \004 " + "in \001\"\004 to \002\">\001\n\002. \001]\005 for \003 a \006 " + "that \001'\006 with \006 from \004 by \001(\006. T" + "he \004 on \004 as \004 is \004ing \002\n\t\001:\003ed " + "\002=\"\004 at \003ly \001,\002='\005.com/\007. This \005" + " not \003er \003al \004ful \004ive \005less \004es" + "t \004ize \002\xc2\xa0\004ous \005 the \002e \000" - -var kPrefixSuffixMap = [50]uint16{ - 0x00, - 0x02, - 0x05, - 0x0E, - 0x13, - 0x16, - 0x18, - 0x1E, - 0x23, - 0x25, - 0x2A, - 0x2D, - 0x2F, - 0x32, - 0x34, - 0x3A, - 0x3E, - 0x45, - 0x47, - 0x4E, - 0x55, - 0x5A, - 0x5C, - 0x63, - 0x68, - 0x6D, - 0x72, - 0x77, - 0x7A, - 0x7C, - 0x80, - 0x83, - 0x88, - 0x8C, - 0x8E, - 0x91, - 0x97, - 0x9F, - 0xA5, - 0xA9, - 0xAD, - 0xB2, - 0xB7, - 0xBD, - 0xC2, - 0xC7, - 0xCA, - 0xCF, - 0xD5, - 0xD8, -} - -/* RFC 7932 transforms */ -var kTransformsData = []byte{ - 49, - transformIdentity, - 49, - 49, - transformIdentity, - 0, - 0, - transformIdentity, - 0, - 49, - transformOmitFirst1, - 49, - 49, - transformUppercaseFirst, - 0, - 49, - transformIdentity, - 47, - 0, - transformIdentity, - 49, - 4, - transformIdentity, - 0, - 49, - transformIdentity, - 3, - 49, - transformUppercaseFirst, - 49, - 49, - transformIdentity, - 6, - 49, - transformOmitFirst2, - 49, - 49, - transformOmitLast1, - 49, - 1, - transformIdentity, - 0, - 49, - transformIdentity, - 1, - 0, - transformUppercaseFirst, - 0, - 49, - transformIdentity, - 7, - 49, - transformIdentity, - 9, - 48, - transformIdentity, - 0, - 49, - transformIdentity, - 8, - 49, - transformIdentity, - 5, - 49, - transformIdentity, - 10, - 49, - transformIdentity, - 11, - 49, - transformOmitLast3, - 49, - 49, - transformIdentity, - 13, - 49, - transformIdentity, - 14, - 49, - transformOmitFirst3, - 49, - 49, - transformOmitLast2, - 49, - 49, - transformIdentity, - 15, - 49, - transformIdentity, - 16, - 0, - transformUppercaseFirst, - 49, - 49, - transformIdentity, - 12, - 5, - transformIdentity, - 49, - 0, - transformIdentity, - 1, - 49, - transformOmitFirst4, - 49, - 49, - transformIdentity, - 18, - 49, - transformIdentity, - 17, - 49, - transformIdentity, - 19, - 49, - transformIdentity, - 20, - 49, - transformOmitFirst5, - 49, - 49, - transformOmitFirst6, - 49, - 47, - transformIdentity, - 49, - 49, - transformOmitLast4, - 49, - 49, - transformIdentity, - 22, - 49, - transformUppercaseAll, - 49, - 49, - transformIdentity, - 23, - 49, - transformIdentity, - 24, - 49, - transformIdentity, - 25, - 49, - transformOmitLast7, - 49, - 49, - transformOmitLast1, - 26, - 49, - transformIdentity, - 27, - 49, - transformIdentity, - 28, - 0, - transformIdentity, - 12, - 49, - transformIdentity, - 29, - 49, - transformOmitFirst9, - 49, - 49, - transformOmitFirst7, - 49, - 49, - transformOmitLast6, - 49, - 49, - transformIdentity, - 21, - 49, - transformUppercaseFirst, - 1, - 49, - transformOmitLast8, - 49, - 49, - transformIdentity, - 31, - 49, - transformIdentity, - 32, - 47, - transformIdentity, - 3, - 49, - transformOmitLast5, - 49, - 49, - transformOmitLast9, - 49, - 0, - transformUppercaseFirst, - 1, - 49, - transformUppercaseFirst, - 8, - 5, - transformIdentity, - 21, - 49, - transformUppercaseAll, - 0, - 49, - transformUppercaseFirst, - 10, - 49, - transformIdentity, - 30, - 0, - transformIdentity, - 5, - 35, - transformIdentity, - 49, - 47, - transformIdentity, - 2, - 49, - transformUppercaseFirst, - 17, - 49, - transformIdentity, - 36, - 49, - transformIdentity, - 33, - 5, - transformIdentity, - 0, - 49, - transformUppercaseFirst, - 21, - 49, - transformUppercaseFirst, - 5, - 49, - transformIdentity, - 37, - 0, - transformIdentity, - 30, - 49, - transformIdentity, - 38, - 0, - transformUppercaseAll, - 0, - 49, - transformIdentity, - 39, - 0, - transformUppercaseAll, - 49, - 49, - transformIdentity, - 34, - 49, - transformUppercaseAll, - 8, - 49, - transformUppercaseFirst, - 12, - 0, - transformIdentity, - 21, - 49, - transformIdentity, - 40, - 0, - transformUppercaseFirst, - 12, - 49, - transformIdentity, - 41, - 49, - transformIdentity, - 42, - 49, - transformUppercaseAll, - 17, - 49, - transformIdentity, - 43, - 0, - transformUppercaseFirst, - 5, - 49, - transformUppercaseAll, - 10, - 0, - transformIdentity, - 34, - 49, - transformUppercaseFirst, - 33, - 49, - transformIdentity, - 44, - 49, - transformUppercaseAll, - 5, - 45, - transformIdentity, - 49, - 0, - transformIdentity, - 33, - 49, - transformUppercaseFirst, - 30, - 49, - transformUppercaseAll, - 30, - 49, - transformIdentity, - 46, - 49, - transformUppercaseAll, - 1, - 49, - transformUppercaseFirst, - 34, - 0, - transformUppercaseFirst, - 33, - 0, - transformUppercaseAll, - 30, - 0, - transformUppercaseAll, - 1, - 49, - transformUppercaseAll, - 33, - 49, - transformUppercaseAll, - 21, - 49, - transformUppercaseAll, - 12, - 0, - transformUppercaseAll, - 5, - 49, - transformUppercaseAll, - 34, - 0, - transformUppercaseAll, - 12, - 0, - transformUppercaseFirst, - 30, - 0, - transformUppercaseAll, - 34, - 0, - transformUppercaseFirst, - 34, -} - -var kBrotliTransforms = transforms{ - 217, - []byte(kPrefixSuffix), - kPrefixSuffixMap[:], - 121, - kTransformsData, - nil, /* no extra parameters */ - [transformsMaxCutOff + 1]int16{0, 12, 27, 23, 42, 63, 56, 48, 59, 64}, -} - -func getTransforms() *transforms { - return &kBrotliTransforms -} - -func toUpperCase(p []byte) int { - if p[0] < 0xC0 { - if p[0] >= 'a' && p[0] <= 'z' { - p[0] ^= 32 - } - - return 1 - } - - /* An overly simplified uppercasing model for UTF-8. */ - if p[0] < 0xE0 { - p[1] ^= 32 - return 2 - } - - /* An arbitrary transform for three byte characters. */ - p[2] ^= 5 - - return 3 -} - -func shiftTransform(word []byte, word_len int, parameter uint16) int { - /* Limited sign extension: scalar < (1 << 24). */ - var scalar uint32 = (uint32(parameter) & 0x7FFF) + (0x1000000 - (uint32(parameter) & 0x8000)) - if word[0] < 0x80 { - /* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */ - scalar += uint32(word[0]) - - word[0] = byte(scalar & 0x7F) - return 1 - } else if word[0] < 0xC0 { - /* Continuation / 10AAAAAA. */ - return 1 - } else if word[0] < 0xE0 { - /* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */ - if word_len < 2 { - return 1 - } - scalar += uint32(word[1]&0x3F | (word[0]&0x1F)<<6) - word[0] = byte(0xC0 | (scalar>>6)&0x1F) - word[1] = byte(uint32(word[1]&0xC0) | scalar&0x3F) - return 2 - } else if word[0] < 0xF0 { - /* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */ - if word_len < 3 { - return word_len - } - scalar += uint32(word[2])&0x3F | uint32(word[1]&0x3F)<<6 | uint32(word[0]&0x0F)<<12 - word[0] = byte(0xE0 | (scalar>>12)&0x0F) - word[1] = byte(uint32(word[1]&0xC0) | (scalar>>6)&0x3F) - word[2] = byte(uint32(word[2]&0xC0) | scalar&0x3F) - return 3 - } else if word[0] < 0xF8 { - /* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */ - if word_len < 4 { - return word_len - } - scalar += uint32(word[3])&0x3F | uint32(word[2]&0x3F)<<6 | uint32(word[1]&0x3F)<<12 | uint32(word[0]&0x07)<<18 - word[0] = byte(0xF0 | (scalar>>18)&0x07) - word[1] = byte(uint32(word[1]&0xC0) | (scalar>>12)&0x3F) - word[2] = byte(uint32(word[2]&0xC0) | (scalar>>6)&0x3F) - word[3] = byte(uint32(word[3]&0xC0) | scalar&0x3F) - return 4 - } - - return 1 -} - -func transformDictionaryWord(dst []byte, word []byte, len int, trans *transforms, transform_idx int) int { - var idx int = 0 - var prefix []byte = transformPrefix(trans, transform_idx) - var type_ byte = transformType(trans, transform_idx) - var suffix []byte = transformSuffix(trans, transform_idx) - { - var prefix_len int = int(prefix[0]) - prefix = prefix[1:] - for { - tmp1 := prefix_len - prefix_len-- - if tmp1 == 0 { - break - } - dst[idx] = prefix[0] - idx++ - prefix = prefix[1:] - } - } - { - var t int = int(type_) - var i int = 0 - if t <= transformOmitLast9 { - len -= t - } else if t >= transformOmitFirst1 && t <= transformOmitFirst9 { - var skip int = t - (transformOmitFirst1 - 1) - word = word[skip:] - len -= skip - } - - for i < len { - dst[idx] = word[i] - idx++ - i++ - } - if t == transformUppercaseFirst { - toUpperCase(dst[idx-len:]) - } else if t == transformUppercaseAll { - var uppercase []byte = dst - uppercase = uppercase[idx-len:] - for len > 0 { - var step int = toUpperCase(uppercase) - uppercase = uppercase[step:] - len -= step - } - } else if t == transformShiftFirst { - var param uint16 = uint16(trans.params[transform_idx*2]) + uint16(trans.params[transform_idx*2+1])<<8 - shiftTransform(dst[idx-len:], int(len), param) - } else if t == transformShiftAll { - var param uint16 = uint16(trans.params[transform_idx*2]) + uint16(trans.params[transform_idx*2+1])<<8 - var shift []byte = dst - shift = shift[idx-len:] - for len > 0 { - var step int = shiftTransform(shift, int(len), param) - shift = shift[step:] - len -= step - } - } - } - { - var suffix_len int = int(suffix[0]) - suffix = suffix[1:] - for { - tmp2 := suffix_len - suffix_len-- - if tmp2 == 0 { - break - } - dst[idx] = suffix[0] - idx++ - suffix = suffix[1:] - } - return idx - } -} diff --git a/src/vendor/github.com/andybalholm/brotli/utf8_util.go b/src/vendor/github.com/andybalholm/brotli/utf8_util.go deleted file mode 100644 index 3244247e..00000000 --- a/src/vendor/github.com/andybalholm/brotli/utf8_util.go +++ /dev/null @@ -1,70 +0,0 @@ -package brotli - -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Heuristics for deciding about the UTF8-ness of strings. */ - -const kMinUTF8Ratio float64 = 0.75 - -/* Returns 1 if at least min_fraction of the bytes between pos and - pos + length in the (data, mask) ring-buffer is UTF8-encoded, otherwise - returns 0. */ -func parseAsUTF8(symbol *int, input []byte, size uint) uint { - /* ASCII */ - if input[0]&0x80 == 0 { - *symbol = int(input[0]) - if *symbol > 0 { - return 1 - } - } - - /* 2-byte UTF8 */ - if size > 1 && input[0]&0xE0 == 0xC0 && input[1]&0xC0 == 0x80 { - *symbol = (int(input[0])&0x1F)<<6 | int(input[1])&0x3F - if *symbol > 0x7F { - return 2 - } - } - - /* 3-byte UFT8 */ - if size > 2 && input[0]&0xF0 == 0xE0 && input[1]&0xC0 == 0x80 && input[2]&0xC0 == 0x80 { - *symbol = (int(input[0])&0x0F)<<12 | (int(input[1])&0x3F)<<6 | int(input[2])&0x3F - if *symbol > 0x7FF { - return 3 - } - } - - /* 4-byte UFT8 */ - if size > 3 && input[0]&0xF8 == 0xF0 && input[1]&0xC0 == 0x80 && input[2]&0xC0 == 0x80 && input[3]&0xC0 == 0x80 { - *symbol = (int(input[0])&0x07)<<18 | (int(input[1])&0x3F)<<12 | (int(input[2])&0x3F)<<6 | int(input[3])&0x3F - if *symbol > 0xFFFF && *symbol <= 0x10FFFF { - return 4 - } - } - - /* Not UTF8, emit a special symbol above the UTF8-code space */ - *symbol = 0x110000 | int(input[0]) - - return 1 -} - -/* Returns 1 if at least min_fraction of the data is UTF8-encoded.*/ -func isMostlyUTF8(data []byte, pos uint, mask uint, length uint, min_fraction float64) bool { - var size_utf8 uint = 0 - var i uint = 0 - for i < length { - var symbol int - current_data := data[(pos+i)&mask:] - var bytes_read uint = parseAsUTF8(&symbol, current_data, length-i) - i += bytes_read - if symbol < 0x110000 { - size_utf8 += bytes_read - } - } - - return float64(size_utf8) > min_fraction*float64(length) -} diff --git a/src/vendor/github.com/andybalholm/brotli/write_bits.go b/src/vendor/github.com/andybalholm/brotli/write_bits.go deleted file mode 100644 index 87299011..00000000 --- a/src/vendor/github.com/andybalholm/brotli/write_bits.go +++ /dev/null @@ -1,52 +0,0 @@ -package brotli - -import "encoding/binary" - -/* Copyright 2010 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Write bits into a byte array. */ - -/* This function writes bits into bytes in increasing addresses, and within - a byte least-significant-bit first. - - The function can write up to 56 bits in one go with WriteBits - Example: let's assume that 3 bits (Rs below) have been written already: - - BYTE-0 BYTE+1 BYTE+2 - - 0000 0RRR 0000 0000 0000 0000 - - Now, we could write 5 or less bits in MSB by just sifting by 3 - and OR'ing to BYTE-0. - - For n bits, we take the last 5 bits, OR that with high bits in BYTE-0, - and locate the rest in BYTE+1, BYTE+2, etc. */ -func writeBits(n_bits uint, bits uint64, pos *uint, array []byte) { - /* This branch of the code can write up to 56 bits at a time, - 7 bits are lost by being perhaps already in *p and at least - 1 bit is needed to initialize the bit-stream ahead (i.e. if 7 - bits are in *p and we write 57 bits, then the next write will - access a byte that was never initialized). */ - p := array[*pos>>3:] - v := uint64(p[0]) - v |= bits << (*pos & 7) - binary.LittleEndian.PutUint64(p, v) - *pos += n_bits -} - -func writeSingleBit(bit bool, pos *uint, array []byte) { - if bit { - writeBits(1, 1, pos, array) - } else { - writeBits(1, 0, pos, array) - } -} - -func writeBitsPrepareStorage(pos uint, array []byte) { - assert(pos&7 == 0) - array[pos>>3] = 0 -} diff --git a/src/vendor/github.com/andybalholm/brotli/writer.go b/src/vendor/github.com/andybalholm/brotli/writer.go deleted file mode 100644 index ce8b80fd..00000000 --- a/src/vendor/github.com/andybalholm/brotli/writer.go +++ /dev/null @@ -1,162 +0,0 @@ -package brotli - -import ( - "errors" - "io" - - "github.com/andybalholm/brotli/matchfinder" -) - -const ( - BestSpeed = 0 - BestCompression = 11 - DefaultCompression = 6 -) - -// WriterOptions configures Writer. -type WriterOptions struct { - // Quality controls the compression-speed vs compression-density trade-offs. - // The higher the quality, the slower the compression. Range is 0 to 11. - Quality int - // LGWin is the base 2 logarithm of the sliding window size. - // Range is 10 to 24. 0 indicates automatic configuration based on Quality. - LGWin int -} - -var ( - errEncode = errors.New("brotli: encode error") - errWriterClosed = errors.New("brotli: Writer is closed") -) - -// Writes to the returned writer are compressed and written to dst. -// It is the caller's responsibility to call Close on the Writer when done. -// Writes may be buffered and not flushed until Close. -func NewWriter(dst io.Writer) *Writer { - return NewWriterLevel(dst, DefaultCompression) -} - -// NewWriterLevel is like NewWriter but specifies the compression level instead -// of assuming DefaultCompression. -// The compression level can be DefaultCompression or any integer value between -// BestSpeed and BestCompression inclusive. -func NewWriterLevel(dst io.Writer, level int) *Writer { - return NewWriterOptions(dst, WriterOptions{ - Quality: level, - }) -} - -// NewWriterOptions is like NewWriter but specifies WriterOptions -func NewWriterOptions(dst io.Writer, options WriterOptions) *Writer { - w := new(Writer) - w.options = options - w.Reset(dst) - return w -} - -// Reset discards the Writer's state and makes it equivalent to the result of -// its original state from NewWriter or NewWriterLevel, but writing to dst -// instead. This permits reusing a Writer rather than allocating a new one. -func (w *Writer) Reset(dst io.Writer) { - encoderInitState(w) - w.params.quality = w.options.Quality - if w.options.LGWin > 0 { - w.params.lgwin = uint(w.options.LGWin) - } - w.dst = dst - w.err = nil -} - -func (w *Writer) writeChunk(p []byte, op int) (n int, err error) { - if w.dst == nil { - return 0, errWriterClosed - } - if w.err != nil { - return 0, w.err - } - - for { - availableIn := uint(len(p)) - nextIn := p - success := encoderCompressStream(w, op, &availableIn, &nextIn) - bytesConsumed := len(p) - int(availableIn) - p = p[bytesConsumed:] - n += bytesConsumed - if !success { - return n, errEncode - } - - if len(p) == 0 || w.err != nil { - return n, w.err - } - } -} - -// Flush outputs encoded data for all input provided to Write. The resulting -// output can be decoded to match all input before Flush, but the stream is -// not yet complete until after Close. -// Flush has a negative impact on compression. -func (w *Writer) Flush() error { - _, err := w.writeChunk(nil, operationFlush) - return err -} - -// Close flushes remaining data to the decorated writer. -func (w *Writer) Close() error { - // If stream is already closed, it is reported by `writeChunk`. - _, err := w.writeChunk(nil, operationFinish) - w.dst = nil - return err -} - -// Write implements io.Writer. Flush or Close must be called to ensure that the -// encoded bytes are actually flushed to the underlying Writer. -func (w *Writer) Write(p []byte) (n int, err error) { - return w.writeChunk(p, operationProcess) -} - -type nopCloser struct { - io.Writer -} - -func (nopCloser) Close() error { return nil } - -// NewWriterV2 is like NewWriterLevel, but it uses the new implementation -// based on the matchfinder package. It currently supports up to level 9; -// if a higher level is specified, level 9 will be used. -func NewWriterV2(dst io.Writer, level int) *matchfinder.Writer { - if level < 0 { - level = 0 - } else if level > 9 { - level = 9 - } - var mf matchfinder.MatchFinder - switch level { - case 0, 1: - mf = &matchfinder.ZFast{MaxDistance: 1 << 20} - case 2: - mf = &matchfinder.ZDFast{MaxDistance: 1 << 20} - case 3: - mf = &matchfinder.ZM{MaxDistance: 1 << 20} - case 4: - mf = &matchfinder.Trio{MaxDistance: 1 << 20} - case 5, 6: - mf = &matchfinder.Bargain1{MaxDistance: 1 << 20} - case 7: - mf = &matchfinder.Bargain2{MaxDistance: 1 << 20, Skip: true} - case 8: - mf = &matchfinder.Bargain2{MaxDistance: 1 << 20} - case 9: - mf = &matchfinder.Bargain3{MaxDistance: 1 << 20} - } - - w := &matchfinder.Writer{ - Dest: dst, - MatchFinder: mf, - Encoder: &Encoder{}, - BlockSize: 1 << 16, - } - if level < 1 { - w.Encoder = &FastEncoder{} - } - return w -} diff --git a/src/vendor/github.com/fxamacker/cbor/v2/decode.go b/src/vendor/github.com/fxamacker/cbor/v2/decode.go index 1d3e63d0..a430eccb 100644 --- a/src/vendor/github.com/fxamacker/cbor/v2/decode.go +++ b/src/vendor/github.com/fxamacker/cbor/v2/decode.go @@ -1769,6 +1769,7 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { } return t, true, nil } + d.skip() return time.Time{}, false, &UnmarshalTypeError{CBORType: t.String(), GoType: typeTime.String()} case cborTypeTextString: @@ -1845,6 +1846,7 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { return time.Unix(int64(seconds), int64(fractional*1e9)), true, nil default: + d.skip() return time.Time{}, false, &UnmarshalTypeError{CBORType: t.String(), GoType: typeTime.String()} } } diff --git a/src/vendor/github.com/gofiber/contrib/v3/websocket/README.md b/src/vendor/github.com/gofiber/contrib/v3/websocket/README.md index 8ba4d5c6..1f6e9808 100644 --- a/src/vendor/github.com/gofiber/contrib/v3/websocket/README.md +++ b/src/vendor/github.com/gofiber/contrib/v3/websocket/README.md @@ -36,9 +36,9 @@ func New(handler func(*websocket.Conn), config ...websocket.Config) fiber.Handle | Property | Type | Description | Default | |:--------------------|:-----------------------------|:------------------------------------------------------------------------------------------------------------------------------|:-----------------------| | Next | `func(fiber.Ctx) bool` | Defines a function to skip this middleware when it returns true. | `nil` | -| HandshakeTimeout | `time.Duration` | HandshakeTimeout specifies the duration for the handshake to complete. | `0` (No timeout) | -| Subprotocols | `[]string` | Subprotocols specifies the client's requested subprotocols. | `nil` | -| Origins | `[]string` | Allowed Origins based on the Origin header. If empty, everything is allowed. | `nil` | +| HandshakeTimeout | `time.Duration` | Bounds sending the 101 response, which fasthttp writes once the handler chain returns. The server's `WriteTimeout`, when set, applies instead. | `0` (No timeout) | +| Subprotocols | `[]string` | Subprotocols this server supports, in order of preference. The first entry the client also offers is negotiated. | `nil` | +| Origins | `[]string` | Allowed Origins based on the Origin header, compared case-insensitively. If empty, everything is allowed. | `nil` | | AllowEmptyOrigin | `bool` | Allows connections without an Origin header when Origins is configured. Useful for non-browser clients. | `false` | | ReadBufferSize | `int` | ReadBufferSize specifies the I/O buffer size in bytes for incoming messages. | `0` (Use default size) | | WriteBufferSize | `int` | WriteBufferSize specifies the I/O buffer size in bytes for outgoing messages. | `0` (Use default size) | @@ -106,6 +106,46 @@ func main() { ``` +## Handshake rejections + +A request that carries neither an `Upgrade` header nor an `upgrade` token in +`Connection` never asked to switch protocols and is answered with `426 Upgrade Required`. + +A request that *does* ask to upgrade but whose handshake is rejected is returned as a +`*fiber.Error` carrying the status RFC 6455 defines for that failure, so it reaches +the app's `ErrorHandler` like any other error and takes its body and format from +there: + +| Reason | Status | +|:-----------------------------------------------------------|:--------------------------| +| Origin not in `Origins` (RFC 6455 section 4.2.2) | `403 Forbidden` | +| Missing/blank `Sec-WebSocket-Key`, unsupported version, or only one of the `Upgrade`/`Connection` signals | `400 Bad Request` | +| Request method is not `GET` | `405 Method Not Allowed` | + +Rejected handshakes also carry `Sec-WebSocket-Version: 13` so a client that asked for +another version learns which one the server speaks (RFC 6455 section 4.4). Headers set +by earlier middleware are left in place. + +## Reads and writes + +`c.ReadMessage()` reads messages up to 64 KiB into a pooled buffer and returns an exact-size +copy; a larger message comes back in its own buffer, as from the library's `ReadMessage`. +Bound message size with `SetReadLimit`; for zero-copy reads use `NextReader` with your own +buffer. + +Replies to a burst of pipelined frames leave in one write instead of one per frame: writes +made while the handler still has unread frames wait until it asks for the next one, at most +64 KiB or 1 ms. Writes made while nothing is waiting to be read go out immediately, so +push-only handlers are unaffected, and frames are never reordered. With 5-byte frames and +16 in flight per connection, server CPU per frame goes from 5.7 µs to 1.0 µs. + +To own the connection the upgrade runs through the library's `net/http` `Upgrader` on a +fasthttp-backed hijack. fasthttp still sends the 101, so middleware running after `c.Next()` +sees the status and headers and can add its own, and `Sec-WebSocket-Key` is validated as +RFC 6455 requires. `c.NetConn()` returns the middleware's connection; its `UnsafeConn()` +is the socket underneath. `Close` sends what is pending, waiting at most 100 ms for a peer +that is not reading, and interrupts a write stalled on that peer. + ## Note with cache middleware If you get the error `websocket: bad handshake` when using the [cache middleware](https://github.com/gofiber/fiber/tree/master/middleware/cache), please use `config.Next` to skip websocket path. @@ -124,7 +164,22 @@ app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {})) ## Note with recover middleware For internal implementation reasons, currently recover middleware does not work with websocket middleware, please use `config.RecoverHandler` to add recover handler to websocket endpoints. -By default, config `RecoverHandler` recovers from panic and writes stack trace to stderr, also returns a response that contains panic message in **error** field. +By default, config `RecoverHandler` recovers from panic, writes the value and stack trace to stderr, and sends the peer a fixed `{"error":"internal error"}`. + +Nothing derived from the panic reaches the client: the operator already has the +full detail on stderr, and a panic value can carry internal paths, connection +strings or schema names. If you want the peer told more than that, supply your +own `RecoverHandler` — it receives the `*websocket.Conn` and calls `recover()` +itself, so it can write whatever the application considers safe. + +Once the recover handler returns, the connection is closed: a handler that panicked +cannot be assumed to still own it, and nothing else closes a hijacked connection. + +A handler that returns normally leaves the socket open, so it may hand the +connection to another goroutine before returning and keep writing after. The +`*websocket.Conn` it receives is allocated for that upgrade alone and never reused, +so `Locals`, `Params`, `Query`, `Cookies`, `Headers` and `IP` keep answering with +that connection's own data for as long as anything holds it. ```go app := fiber.New() diff --git a/src/vendor/github.com/gofiber/contrib/v3/websocket/coalesce.go b/src/vendor/github.com/gofiber/contrib/v3/websocket/coalesce.go new file mode 100644 index 00000000..7b7cf85c --- /dev/null +++ b/src/vendor/github.com/gofiber/contrib/v3/websocket/coalesce.go @@ -0,0 +1,455 @@ +package websocket + +import ( + "bufio" + "bytes" + "io" + "net" + "net/http" + "slices" + "sync" + "sync/atomic" + "time" + + "github.com/fasthttp/websocket" + "github.com/gofiber/fiber/v3" + "github.com/valyala/fasthttp" +) + +// The handshake runs through the library's net/http Upgrader on a +// fasthttp-backed Hijacker, so the middleware owns the net.Conn the library +// writes to and can answer a burst of pipelined frames with one write. +// fasthttp still sends the 101: the headers the library composed are mirrored +// onto the response before the hijack, where later middleware sees them. + +const ( + coalesceLimit = 64 << 10 // a write that would push pending past this goes out + coalesceMaxDelay = time.Millisecond // flush if the reader has not returned by then + closeFlushGrace = 100 * time.Millisecond // how long Close waits to send what is pending + // minCoalesceFill is the smallest fill that can hold two client frames, each + // at least 6 bytes of header and mask; a smaller one has nothing to + // coalesce a reply with, so the reply goes straight out. + minCoalesceFill = 12 +) + +var handshakeHeaders = [...]string{ + http.CanonicalHeaderKey(fiber.HeaderConnection), + http.CanonicalHeaderKey(fiber.HeaderUpgrade), + http.CanonicalHeaderKey(fiber.HeaderSecWebSocketVersion), + http.CanonicalHeaderKey(fiber.HeaderSecWebSocketKey), + http.CanonicalHeaderKey(fiber.HeaderSecWebSocketExtensions), + http.CanonicalHeaderKey(fiber.HeaderSecWebSocketProtocol), + http.CanonicalHeaderKey(fiber.HeaderOrigin), +} + +// hijackReadWriter is handed to the library on hijack. It only inspects the +// pair and, at these sizes, allocates its own buffers from Config. +var hijackReadWriter = bufio.NewReadWriter(bufio.NewReaderSize(bytes.NewReader(nil), 16), bufio.NewWriterSize(io.Discard, 16)) + +var scratchPool = sync.Pool{New: func() any { b := make([]byte, 4096); return &b }} + +// coalescingConn defers a write only while batch is set: the reader's last +// fill could hold more than one frame and it has not come back for more. Pending bytes +// leave before the reader blocks, when a write would not fit, on Close, or +// after coalesceMaxDelay. +// +// mu guards pending and the flags; wmu orders socket writes and is never +// taken under mu, so Close and the reader never wait behind a stalled writer. +type coalescingConn struct { + src net.Conn // fasthttp's hijacked conn; its Close is the one fasthttp expects + raw net.Conn // the socket underneath, nil until attach + rd io.Reader // raw once fasthttp's buffer is in stash, else src + stash []byte // bytes fasthttp had read past the handshake + + batch atomic.Bool + + mu sync.Mutex + pending []byte + timer *time.Timer + maxDelay time.Duration + armed bool + closed bool + err error + + wmu sync.Mutex +} + +func newCoalescingConn() *coalescingConn { + return &coalescingConn{maxDelay: coalesceMaxDelay} +} + +// takeHandshake returns what the library wrote during Upgrade, the 101 that +// fasthttp sends instead. +func (c *coalescingConn) takeHandshake() []byte { + c.mu.Lock() + defer c.mu.Unlock() + p := c.pending + c.pending = nil + return p +} + +// attach binds the hijacked conn. Whatever fasthttp buffered past the +// handshake is stashed so reads can go straight to the socket; with that +// buffer empty the expired deadline fails before any syscall. A conn that +// refuses the deadline would block the drain instead, so it keeps reading +// through fasthttp's buffer. +func (c *coalescingConn) attach(src net.Conn) { + raw := src + var rd io.Reader = src + var stash []byte + if u, ok := src.(interface{ UnsafeConn() net.Conn }); ok { + raw = u.UnsafeConn() + if src.SetReadDeadline(time.Unix(1, 0)) == nil { + scratch := scratchPool.Get().(*[]byte) + for { + n, err := src.Read(*scratch) + stash = append(stash, (*scratch)[:n]...) + if err != nil { + break + } + } + scratchPool.Put(scratch) + _ = raw.SetReadDeadline(time.Time{}) + rd = raw + } + } + c.mu.Lock() + c.src, c.raw, c.rd, c.stash = src, raw, rd, stash + c.mu.Unlock() +} + +func (c *coalescingConn) Read(p []byte) (int, error) { + c.batch.Store(false) + if err := c.flush(); err != nil { + return 0, err + } + if len(c.stash) > 0 { + n := copy(p, c.stash) + c.stash = c.stash[n:] + c.batch.Store(n >= minCoalesceFill) + return n, nil + } + n, err := c.rd.Read(p) + c.batch.Store(n >= minCoalesceFill) + return n, err +} + +func (c *coalescingConn) Write(p []byte) (int, error) { + c.mu.Lock() + if c.err != nil { + err := c.err + c.mu.Unlock() + return 0, err + } + if c.closed { + c.mu.Unlock() + return 0, net.ErrClosed + } + if c.raw == nil || (c.batch.Load() && len(c.pending)+len(p) <= coalesceLimit) { + c.pending = append(c.pending, p...) + if c.raw != nil && !c.armed { + c.arm() + } + c.mu.Unlock() + return len(p), nil + } + c.mu.Unlock() + + c.wmu.Lock() + var err error + if pending := c.take(); len(pending) > 0 { + bufs := net.Buffers{pending, p} // one writev on a TCP socket + _, err = bufs.WriteTo(c.raw) + c.recycle(pending) + } else { + _, err = c.raw.Write(p) + } + if err != nil { + c.fail(err) + c.wmu.Unlock() + return 0, err + } + _ = c.drainAndRelease() + return len(p), nil +} + +// flush sends what is pending unless a writer holds the socket, which then +// drains it before releasing. +func (c *coalescingConn) flush() error { + c.mu.Lock() + empty, err := len(c.pending) == 0, c.err + c.mu.Unlock() + if err != nil || empty { + return err + } + if !c.wmu.TryLock() { + return nil + } + return c.drainAndRelease() +} + +// drainAndRelease writes pending until it is empty, then releases wmu. Caller +// holds wmu. The release happens under mu, after the last look at pending, so +// a write that lands later arms a timer that finds the socket free: a holder +// never leaves bytes behind that nothing would send. +func (c *coalescingConn) drainAndRelease() error { + for { + c.mu.Lock() + if c.armed { + c.timer.Stop() + c.armed = false + } + if len(c.pending) == 0 || c.err != nil { + err := c.err + c.wmu.Unlock() + c.mu.Unlock() + return err + } + pending := c.pending + c.pending = nil + c.mu.Unlock() + _, err := c.raw.Write(pending) + c.recycle(pending) + if err != nil { + c.fail(err) + c.wmu.Unlock() + return err + } + } +} + +// take removes the pending bytes, or returns nil when there are none or the +// connection has already failed. +func (c *coalescingConn) take() []byte { + c.mu.Lock() + defer c.mu.Unlock() + if c.armed { + c.timer.Stop() + c.armed = false + } + if len(c.pending) == 0 || c.err != nil { + return nil + } + p := c.pending + c.pending = nil + return p +} + +// recycle keeps a written buffer for the next batch. +func (c *coalescingConn) recycle(p []byte) { + c.mu.Lock() + if c.pending == nil && cap(p) <= coalesceLimit { + c.pending = p[:0] + } + c.mu.Unlock() +} + +func (c *coalescingConn) fail(err error) { + c.mu.Lock() + if c.err == nil { + c.err = err + } + c.mu.Unlock() +} + +// arm starts the safety timer. Caller holds mu. +func (c *coalescingConn) arm() { + if c.timer == nil { + c.timer = time.AfterFunc(c.maxDelay, c.onTimer) + } else { + c.timer.Reset(c.maxDelay) + } + c.armed = true +} + +// onTimer sends what a reader that did not come back left pending, and stops +// deferring until the next fill proves the reader is still consuming. A +// writer that holds the socket sends it instead, before letting go. +func (c *coalescingConn) onTimer() { + c.mu.Lock() + c.armed = false + empty := len(c.pending) == 0 + if !empty { + c.batch.Store(false) + } + c.mu.Unlock() + if empty || !c.wmu.TryLock() { + return + } + _ = c.drainAndRelease() +} + +// Close sends what is pending, within closeFlushGrace, and closes the socket. +// A writer stalled on a full window is expired first so it cannot hold the +// close up. A conn that refuses deadlines is closed under such a writer +// instead, and pending bytes are dropped rather than sent without a bound on +// the wait. A second Close is a no-op. +func (c *coalescingConn) Close() error { + c.mu.Lock() + if c.closed { + c.mu.Unlock() + return nil + } + c.closed = true + src, raw := c.src, c.raw + c.mu.Unlock() + if raw == nil { + return nil + } + if !c.wmu.TryLock() { + if raw.SetWriteDeadline(time.Unix(1, 0)) != nil { + _ = raw.Close() + } + c.wmu.Lock() + } + if raw.SetWriteDeadline(time.Now().Add(closeFlushGrace)) == nil { + _ = c.drainAndRelease() + } else { + c.wmu.Unlock() + } + return src.Close() +} + +// UnsafeConn returns the socket underneath, as fasthttp's hijacked conn does. +func (c *coalescingConn) UnsafeConn() net.Conn { return c.raw } + +func (c *coalescingConn) LocalAddr() net.Addr { return c.raw.LocalAddr() } +func (c *coalescingConn) RemoteAddr() net.Addr { return c.raw.RemoteAddr() } + +// The deadline setters tolerate a nil raw: the library clears the deadlines +// during Upgrade, before fasthttp has handed the socket over. + +func (c *coalescingConn) SetDeadline(t time.Time) error { + if c.raw == nil { + return nil + } + return c.raw.SetDeadline(t) +} + +func (c *coalescingConn) SetReadDeadline(t time.Time) error { + if c.raw == nil { + return nil + } + return c.raw.SetReadDeadline(t) +} + +func (c *coalescingConn) SetWriteDeadline(t time.Time) error { + if c.raw == nil { + return nil + } + return c.raw.SetWriteDeadline(t) +} + +// upgradeResponseWriter never writes a response: a rejection records its +// status for Fiber to answer, an accepted handshake is hijacked into conn. +type upgradeResponseWriter struct { + conn *coalescingConn + header http.Header + status int +} + +func (w *upgradeResponseWriter) Header() http.Header { + if w.header == nil { + w.header = http.Header{} + } + return w.header +} + +func (w *upgradeResponseWriter) Write([]byte) (int, error) { return 0, http.ErrHijacked } +func (w *upgradeResponseWriter) WriteHeader(code int) { w.status = code } + +func (w *upgradeResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return w.conn, hijackReadWriter, nil +} + +func upgradeRequest(fctx *fasthttp.RequestCtx) *http.Request { + h := &fctx.Request.Header + header := make(http.Header, len(handshakeHeaders)) + for _, name := range handshakeHeaders { + for _, v := range h.PeekAll(name) { + header[name] = append(header[name], string(v)) + } + } + method := http.MethodGet + if !fctx.IsGet() { + method = string(fctx.Method()) + } + return &http.Request{Method: method, Header: header} +} + +// subprotocolHeader hands the library the negotiated subprotocol, chosen in +// the server's order of preference, which the library's own selection would +// not keep. With no Subprotocols configured, one set on the response by +// earlier middleware stands. +func subprotocolHeader(fctx *fasthttp.RequestCtx, req *http.Request, subprotocols []string) http.Header { + var chosen string + if subprotocols == nil { + chosen = string(fctx.Response.Header.Peek(fiber.HeaderSecWebSocketProtocol)) + } else { + offered := websocket.Subprotocols(req) + for _, s := range subprotocols { + if slices.Contains(offered, s) { + chosen = s + break + } + } + } + if chosen == "" { + return nil + } + return http.Header{http.CanonicalHeaderKey(fiber.HeaderSecWebSocketProtocol): {chosen}} +} + +func newUpgrader(cfg *Config, originAllowed func(origin string) bool) websocket.Upgrader { + return websocket.Upgrader{ + ReadBufferSize: cfg.ReadBufferSize, + WriteBufferSize: cfg.WriteBufferSize, + WriteBufferPool: cfg.WriteBufferPool, + EnableCompression: cfg.EnableCompression, + CheckOrigin: func(r *http.Request) bool { + return originAllowed(r.Header.Get(fiber.HeaderOrigin)) + }, + } +} + +func upgrade(c fiber.Ctx, upgrader *websocket.Upgrader, conn *Conn, cfg *Config, handler func(*Conn)) error { + fctx := c.RequestCtx() + if len(fctx.Response.Header.Peek(fiber.HeaderSecWebSocketExtensions)) > 0 { + // Application extensions are unsupported, as on the fasthttp upgrader. + fctx.SetStatusCode(fiber.StatusInternalServerError) + return rejectHandshake(c, fiber.StatusInternalServerError) + } + cc := newCoalescingConn() + w := &upgradeResponseWriter{conn: cc} + req := upgradeRequest(fctx) + fconn, err := upgrader.Upgrade(w, req, subprotocolHeader(fctx, req, cfg.Subprotocols)) + if err != nil { + status := w.status + switch status { + case 0: + status = fiber.StatusInternalServerError + case fiber.StatusUpgradeRequired: // a Connection header without its Upgrade counterpart: 400, as documented + status = fiber.StatusBadRequest + } + fctx.SetStatusCode(status) + return rejectHandshake(c, status) + } + // The library wrote the 101 into cc. fasthttp sends the response once the + // chain has unwound, so mirror those headers onto it. + fctx.SetStatusCode(fiber.StatusSwitchingProtocols) + for line := range bytes.SplitSeq(cc.takeHandshake(), []byte("\r\n")) { + if key, value, ok := bytes.Cut(line, []byte(": ")); ok { + fctx.Response.Header.SetBytesKV(key, value) + } + } + if netConn := fctx.Conn(); netConn != nil && cfg.HandshakeTimeout > 0 { + // Bounds fasthttp's write of the 101; fasthttp clears it before the + // hijack, and replaces it with its own when the server has a WriteTimeout. + _ = netConn.SetWriteDeadline(time.Now().Add(cfg.HandshakeTimeout)) + } + fctx.Hijack(func(netConn net.Conn) { + cc.attach(netConn) + runHandler(conn, fconn, cfg.RecoverHandler, handler) + }) + return nil +} diff --git a/src/vendor/github.com/gofiber/contrib/v3/websocket/read.go b/src/vendor/github.com/gofiber/contrib/v3/websocket/read.go new file mode 100644 index 00000000..711f01c2 --- /dev/null +++ b/src/vendor/github.com/gofiber/contrib/v3/websocket/read.go @@ -0,0 +1,106 @@ +package websocket + +import ( + "errors" + "io" + "sync" + + "github.com/gofiber/utils/v2" +) + +const ( + frameBufferInitial = 512 + frameBufferRetained = 64 << 10 +) + +var framePool = sync.Pool{New: func() any { return new(frameReader) }} + +type frameReader struct { + buf []byte + probe [1]byte +} + +// ReadMessage reads the next data message and returns a buffer the caller +// owns. A message up to frameBufferRetained is read into a pooled buffer and +// returned as an exact-size copy; a larger one is returned in the buffer it +// was read into, grown by at most a quarter past its size, as the library's +// ReadMessage grows its own. Bound message size with SetReadLimit. On error p +// is nil. +func (conn *Conn) ReadMessage() (messageType int, p []byte, err error) { + messageType, r, err := conn.NextReader() + if err != nil { + return messageType, nil, err + } + fr := framePool.Get().(*frameReader) + p, err = fr.readAll(r) + fr.release() + return messageType, p, err +} + +func (fr *frameReader) readAll(r io.Reader) ([]byte, error) { + buf := fr.buf[:0] + if cap(buf) == 0 { + buf = make([]byte, 0, frameBufferInitial) + } + for { + if len(buf) == cap(buf) { + // Probe one byte so a message that exactly fills the buffer does not double it. + n, err := r.Read(fr.probe[:]) + if n > 0 { + buf = append(grow(buf), fr.probe[0]) + } + if errors.Is(err, io.EOF) { + break + } + if err != nil { + fr.buf = buf + return nil, err + } + continue + } + n, err := r.Read(buf[len(buf):cap(buf)]) + buf = buf[:len(buf)+n] + if errors.Is(err, io.EOF) { + break + } + if err != nil { + fr.buf = buf + return nil, err + } + } + if cap(buf) > frameBufferRetained { + // Too big for the pool: the caller takes it as it is, rather than + // paying for a second copy of a large message. + fr.buf = nil + return buf, nil + } + fr.buf = buf + return utils.CopyBytes(buf), nil +} + +// grow makes room for at least one more byte: doubling up to the size the +// pool retains, then by a quarter, as append would, so a large message ends +// in a buffer at most 25% bigger than itself. +func grow(buf []byte) []byte { + c := cap(buf) + if c < frameBufferRetained { + c = min(2*c, frameBufferRetained) + } else { + c += c / 4 + } + grown := make([]byte, len(buf), c) + copy(grown, buf) + return grown +} + +func (fr *frameReader) release() { + fr.trim() + framePool.Put(fr) +} + +// trim drops a buffer that grew past frameBufferRetained. +func (fr *frameReader) trim() { + if cap(fr.buf) > frameBufferRetained { + fr.buf = nil + } +} diff --git a/src/vendor/github.com/gofiber/contrib/v3/websocket/websocket.go b/src/vendor/github.com/gofiber/contrib/v3/websocket/websocket.go index 240a2574..598a5640 100644 --- a/src/vendor/github.com/gofiber/contrib/v3/websocket/websocket.go +++ b/src/vendor/github.com/gofiber/contrib/v3/websocket/websocket.go @@ -10,6 +10,7 @@ import ( "io" "os" "runtime/debug" + "slices" "sync" "time" @@ -25,14 +26,20 @@ type Config struct { // Optional. Default: nil Next func(fiber.Ctx) bool - // HandshakeTimeout specifies the duration for the handshake to complete. + // HandshakeTimeout bounds sending the 101 response, which fasthttp writes + // once the handler chain returns. The server's WriteTimeout, when set, + // applies instead. + // Optional. Default: 0 (no deadline) HandshakeTimeout time.Duration - // Subprotocols specifies the client's requested subprotocols. + // Subprotocols lists the subprotocols the server supports in order of + // preference. The first one the client also offers is negotiated; with no + // match none is (RFC 6455 section 4.2.2). Subprotocols []string // Allowed Origin's based on the Origin header, this validate the request origin to // prevent cross-site request forgery. Everything is allowed if left empty. + // Matching is case-insensitive (RFC 6454 section 4). Origins []string // AllowEmptyOrigin allows WebSocket connections when the Origin header is absent. @@ -70,49 +77,59 @@ type Config struct { RecoverHandler func(*Conn) } +// supportedVersion is the only WebSocket protocol version defined by RFC 6455. +const supportedVersion = "13" + +// defaultRecoverWriteTimeout bounds the error frame defaultRecover sends after +// a panic, so a peer that stopped reading cannot park the goroutine. +const defaultRecoverWriteTimeout = 5 * time.Second + +// defaultRecoverMessage is what defaultRecover tells the peer. It is +// deliberately constant and carries nothing derived from the panic. +const defaultRecoverMessage = "internal error" + +// defaultRecover is the default RecoverHandler: it logs the panic and stack to +// stderr and sends the peer a fixed error. func defaultRecover(c *Conn) { if err := recover(); err != nil { _, _ = fmt.Fprintf(os.Stderr, "panic: %v\n%s\n", err, debug.Stack()) //nolint:errcheck // This will never fail - if err := c.WriteJSON(fiber.Map{"error": err}); err != nil { + _ = c.SetWriteDeadline(time.Now().Add(defaultRecoverWriteTimeout)) + // Fixed payload: the panic value may carry internal detail and is already on + // stderr. + if err := c.WriteJSON(fiber.Map{"error": defaultRecoverMessage}); err != nil { _, _ = fmt.Fprintf(os.Stderr, "could not write error response: %v\n", err) } } } -var ( - keepHijackedConnsMu sync.Mutex - keepHijackedConnsServers = make(map[*fasthttp.Server]struct{}) -) +// keepHijackedConnsServers holds one sync.Once per fasthttp server, so the +// steady state per upgrade is a lock-free Load. +var keepHijackedConnsServers sync.Map // map[*fasthttp.Server]*sync.Once +// ensureKeepHijackedConns makes fasthttp leave upgraded connections open after +// the handler returns. It runs once per server. func ensureKeepHijackedConns(server *fasthttp.Server) { - keepHijackedConnsMu.Lock() - defer keepHijackedConnsMu.Unlock() - if _, ok := keepHijackedConnsServers[server]; ok { - return + once, ok := keepHijackedConnsServers.Load(server) + if !ok { + once, _ = keepHijackedConnsServers.LoadOrStore(server, new(sync.Once)) } - server.KeepHijackedConns = true - keepHijackedConnsServers[server] = struct{}{} + once.(*sync.Once).Do(func() { + server.KeepHijackedConns = true + }) } // New returns a new `handler func(*Conn)` that upgrades a client to the // websocket protocol, you can pass an optional config. func New(handler func(*Conn), config ...Config) fiber.Handler { + if handler == nil { + panic("websocket: handler must not be nil") + } + // Init config var cfg Config if len(config) > 0 { cfg = config[0] } - if len(cfg.Origins) == 0 { - cfg.Origins = []string{"*"} - } - // Check if wildcard is present in the Origins list during initialization - hasWildcard := false - for _, origin := range cfg.Origins { - if origin == "*" { - hasWildcard = true - break - } - } if cfg.ReadBufferSize == 0 { cfg.ReadBufferSize = 1024 } @@ -122,87 +139,81 @@ func New(handler func(*Conn), config ...Config) fiber.Handler { if cfg.RecoverHandler == nil { cfg.RecoverHandler = defaultRecover } - var upgrader = websocket.FastHTTPUpgrader{ - HandshakeTimeout: cfg.HandshakeTimeout, - Subprotocols: cfg.Subprotocols, - ReadBufferSize: cfg.ReadBufferSize, - WriteBufferSize: cfg.WriteBufferSize, - EnableCompression: cfg.EnableCompression, - WriteBufferPool: cfg.WriteBufferPool, - CheckOrigin: func(fctx *fasthttp.RequestCtx) bool { - // Fast path: if Origins is just wildcard (the default), allow all without checking header - if len(cfg.Origins) == 1 && cfg.Origins[0] == "*" { - return true - } - origin := utils.UnsafeString(fctx.Request.Header.Peek("Origin")) - if origin == "" { - // Allow empty Origin if wildcard is in list or explicitly configured - return hasWildcard || cfg.AllowEmptyOrigin - } - // If wildcard is present, allow any non-empty origin - if hasWildcard { + + // Resolved once: no wildcard search per request, and the clone keeps a later + // mutation of cfg.Origins from changing a mounted handler. + allowAllOrigins := len(cfg.Origins) == 0 || slices.Contains(cfg.Origins, "*") + allowedOrigins := slices.Clone(cfg.Origins) + originAllowed := func(origin string) bool { + if allowAllOrigins { + return true + } + if origin == "" { + return cfg.AllowEmptyOrigin + } + // Scheme and host of an origin are case-insensitive (RFC 6454 section 4). + for i := range allowedOrigins { + if utils.EqualFold(allowedOrigins[i], origin) { return true } - // No wildcard present, check if origin matches any specific origin in the list - for i := range cfg.Origins { - if cfg.Origins[i] == origin { - return true - } - } - return false - }, + } + return false } + + upgrader := newUpgrader(&cfg, originAllowed) + return func(c fiber.Ctx) error { if cfg.Next != nil && cfg.Next(c) { return c.Next() } - ensureKeepHijackedConns(c.App().Server()) - - conn := acquireConn() - // locals - c.RequestCtx().VisitUserValues(func(key []byte, value interface{}) { - conn.locals[string(key)] = value - }) - - // params - params := c.Route().Params - for i := 0; i < len(params); i++ { - conn.params[utils.CopyString(params[i])] = utils.CopyString(c.Params(params[i])) + fctx := c.RequestCtx() + // No upgrade signal at all: answer 426 before copying the request. A partial + // handshake goes on to the upgrader for its 400. + if !asksToUpgrade(fctx) { + return fiber.ErrUpgradeRequired } + ensureKeepHijackedConns(c.App().Server()) - // queries - queries := c.RequestCtx().QueryArgs().All() - for key, value := range queries { - conn.queries[string(key)] = string(value) - } + conn := &Conn{} - // cookies - cookies := c.RequestCtx().Request.Header.Cookies() - for key, value := range cookies { - conn.cookies[string(key)] = string(value) + // Route params and the IP come from the Fiber context, which is recycled + // before the hijack callback runs. Param names outlive the request; only the + // values are copied. + for _, name := range c.Route().Params { + setEntry(&conn.params, name, utils.CopyString(c.Params(name))) } + conn.ip = utils.CopyString(c.IP()) + // Copied while the middleware chain is still on the stack: the hijack + // callback runs only after it has unwound. + conn.capture(fctx) - // headers - headers := c.RequestCtx().Request.Header.All() - for key, value := range headers { - conn.headers[string(key)] = string(value) - } + return upgrade(c, &upgrader, conn, &cfg, handler) + } +} - // ip address - conn.ip = utils.CopyString(c.IP()) +func runHandler(conn *Conn, fconn *websocket.Conn, recoverHandler, handler func(*Conn)) { + conn.Conn = fconn - if err := upgrader.Upgrade(c.RequestCtx(), func(fconn *websocket.Conn) { - conn.Conn = fconn - defer releaseConn(conn) - defer cfg.RecoverHandler(conn) - handler(conn) - }); err != nil { // Upgrading required - releaseConn(conn) - return fiber.ErrUpgradeRequired + returned := false + // Runs after RecoverHandler. A handler that panicked cannot be trusted with + // the socket and nothing else closes a hijacked connection; a normal return + // leaves it open. + defer func() { + if !returned { + _ = fconn.Close() } + }() + defer recoverHandler(conn) + handler(conn) + returned = true +} - return nil - } +// The upgrader chose the RFC 6455 status: 403 for a bad Origin, 400 for a +// malformed handshake, 405 for a non-GET; section 4.4 asks for the supported +// version on rejection. A *fiber.Error keeps it on the ErrorHandler path. +func rejectHandshake(c fiber.Ctx, status int) error { + c.Set(fiber.HeaderSecWebSocketVersion, supportedVersion) + return fiber.NewError(status, utils.StatusMessage(status)) } // Conn https://godoc.org/github.com/gorilla/websocket#pkg-index @@ -216,28 +227,40 @@ type Conn struct { ip string } -// Conn pool -var poolConn = sync.Pool{ - New: func() interface{} { - return new(Conn) - }, -} - -// Acquire Conn from pool -func acquireConn() *Conn { - conn := poolConn.Get().(*Conn) - conn.locals = make(map[string]interface{}) - conn.params = make(map[string]string) - conn.queries = make(map[string]string) - conn.cookies = make(map[string]string) - conn.headers = make(map[string]string) - return conn +// A Conn is allocated per upgrade and never reused: the event helper reads +// these maps from listeners on other goroutines after the handler returns, so +// pooling them is unsafe. Each map is allocated only when the request carries +// that kind of data. + +// capture copies the request's locals, query arguments, cookies and headers +// into the Conn before fasthttp recycles the RequestCtx. +func (conn *Conn) capture(fctx *fasthttp.RequestCtx) { + fctx.VisitUserValues(func(key []byte, value interface{}) { + setEntry(&conn.locals, string(key), value) + }) + // No size hint: Args.Len counts repeated keys that collapse into one entry. + for key, value := range fctx.QueryArgs().All() { + setEntry(&conn.queries, string(key), string(value)) + } + for key, value := range fctx.Request.Header.Cookies() { + setEntry(&conn.cookies, string(key), string(value)) + } + // Names are stored canonical so Headers is one probe. fasthttp delivers them + // that way unless normalizing was disabled, server-wide or per request, which + // is not observable here, so every name is checked; a canonical name comes + // back without allocating. + for key, value := range fctx.Request.Header.All() { + setEntry(&conn.headers, string(utils.CanonicalHeaderKey(key)), string(value)) + } } -// Return Conn to pool -func releaseConn(conn *Conn) { - conn.Conn = nil - poolConn.Put(conn) +// setEntry stores value under key in *m, allocating the map on first use so a +// connection that carries no entries of a kind never allocates one. +func setEntry[V any](m *map[string]V, key string, value V) { + if *m == nil { + *m = make(map[string]V) + } + (*m)[key] = value } // Locals makes it possible to pass interface{} values under string keys scoped to the request @@ -246,7 +269,7 @@ func (conn *Conn) Locals(key string, value ...interface{}) interface{} { if len(value) == 0 { return conn.locals[key] } - conn.locals[key] = value[0] + setEntry(&conn.locals, key, value[0]) return value[0] } @@ -288,10 +311,10 @@ func (conn *Conn) Cookies(key string, defaultValue ...string) string { // If a default value is given, it will return that value if the header doesn't exist. // Header lookups are case-insensitive. func (conn *Conn) Headers(key string, defaultValue ...string) string { - for k, v := range conn.headers { - if utils.EqualFold(k, key) { - return v - } + // Names are canonical in the map; CanonicalHeaderKey returns key unchanged + // when it already is. + if v, ok := conn.headers[utils.CanonicalHeaderKey(key)]; ok { + return v } if len(defaultValue) > 0 { return defaultValue[0] @@ -306,7 +329,12 @@ func (conn *Conn) IP() string { // Constants are taken from https://github.com/fasthttp/websocket/blob/master/conn.go#L43 -// Close codes defined in RFC 6455, section 11.7. +// Close codes 1000-1011 and 1015 are defined in RFC 6455 section 11.7; 1012 +// and 1013 come from the IANA registry. 1014 is not exported because the +// underlying library rejects it in both directions. Not every code may be +// sent: section 7.4.1 forbids 1005, 1006 and 1015, and the library accepts +// only 1000-1003, 1007-1013 and 3000-4999 on receive; the event package's +// sanitizeCloseCode applies that rule. const ( CloseNormalClosure = 1000 CloseGoingAway = 1001 @@ -377,6 +405,14 @@ func IsUnexpectedCloseError(err error, expectedCodes ...int) bool { return websocket.IsUnexpectedCloseError(err, expectedCodes...) } +// asksToUpgrade reports whether the request carries any upgrade signal: an +// Upgrade header or an upgrade token in Connection. Unlike IsWebSocketUpgrade +// it accepts a partial handshake, so the upgrader can answer it with 400. +func asksToUpgrade(fctx *fasthttp.RequestCtx) bool { + h := &fctx.Request.Header + return h.ConnectionUpgrade() || len(h.Peek(fiber.HeaderUpgrade)) > 0 +} + // IsWebSocketUpgrade returns true if the client requested upgrade to the // WebSocket protocol. func IsWebSocketUpgrade(c fiber.Ctx) bool { diff --git a/src/vendor/github.com/gofiber/fiber/v3/.golangci.yml b/src/vendor/github.com/gofiber/fiber/v3/.golangci.yml index 1f9ec94e..6523f7d6 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/.golangci.yml +++ b/src/vendor/github.com/gofiber/fiber/v3/.golangci.yml @@ -260,6 +260,17 @@ linters: - linters: - nolintlint text: directive `.*` is unused for linter "revive" + # helpers.go deliberately calls fasthttp's deprecated VisitAll (not the + # replacement All) to stay zero-alloc: All returns an iterator closure + # that escapes to the heap on every call. An inline //nolint:staticcheck + # cannot police this reliably because the golangci-lint CI cache can carry + # staticcheck facts from before these calls existed, surfacing no SA1019 + # finding and making nolintlint report the directive as unused. Exclude the + # finding at report time instead so it is robust to cache state. + - path: helpers\.go + linters: + - staticcheck + text: 'SA1019: .*VisitAll' paths: - _msgp\.go - _msgp_test\.go diff --git a/src/vendor/github.com/gofiber/fiber/v3/README.md b/src/vendor/github.com/gofiber/fiber/v3/README.md new file mode 100644 index 00000000..2a3f5293 --- /dev/null +++ b/src/vendor/github.com/gofiber/fiber/v3/README.md @@ -0,0 +1,879 @@ +

+ + + + Fiber + + +
+ + + + + + + + Codecov + + + + + + + + + + + + + + + + +

+ +

+ Fiber is an Express inspired web framework built on top of Fasthttp, the fastest HTTP engine for Go. Designed to ease things up for fast development with zero memory allocation and performance in mind. +

+ +--- + +

+ + + + Official Sponsors + + +

+

+ + + + CodeRabbit + + +

+

+ + Blacksmith + +

+

+ Tool Sponsors - supporting Fiber with free IDE licenses and AI credits +

+

+ JetBrains +   + OpenAI +   + Anthropic +

+ +--- + +## ⚙️ Installation + +Fiber requires **Go version `1.25` or higher** to run. If you need to install or upgrade Go, visit the [official Go download page](https://go.dev/dl/). To start setting up your project, create a new directory for your project and navigate into it. Then, initialize your project with Go modules by executing the following command in your terminal: + +```bash +go mod init github.com/your/repo +``` + +To learn more about Go modules and how they work, you can check out the [Using Go Modules](https://go.dev/blog/using-go-modules) blog post. + +After setting up your project, you can install Fiber with the `go get` command: + +```bash +go get -u github.com/gofiber/fiber/v3 +``` + +This command fetches the Fiber package and adds it to your project's dependencies, allowing you to start building your web applications with Fiber. + +## ⚡️ Quickstart + +Getting started with Fiber is easy. Here's a basic example to create a simple web server that responds with "Hello, World 👋!" on the root path. This example demonstrates initializing a new Fiber app, setting up a route, and starting the server. + +```go title="Example" +package main + +import ( + "log" + + "github.com/gofiber/fiber/v3" +) + +func main() { + // Initialize a new Fiber app + app := fiber.New() + + // Define a route for the GET method on the root path '/' + app.Get("/", func(c fiber.Ctx) error { + // Send a string response to the client + return c.SendString("Hello, World 👋!") + }) + + // Start the server on port 3000 + log.Fatal(app.Listen(":3000")) +} +``` + +This simple server is easy to set up and run. It introduces the core concepts of Fiber: app initialization, route definition, and starting the server. Just run this Go program, and visit `http://localhost:3000` in your browser to see the message. + +## Zero Allocation + +Fiber is optimized for **high-performance**, meaning values returned from **fiber.Ctx** are **not** immutable by default and **will** be reused across requests. As a rule of thumb, you **must** only use context values within the handler and **must not** keep any references. Once you return from the handler, any values obtained from the context will be reused in future requests. Visit our [documentation](https://docs.gofiber.io/#zero-allocation) to learn more. + +## 🤖 Benchmarks + +These tests are performed by [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext). If you want to see all the results, please visit our [Wiki](https://docs.gofiber.io/extra/benchmarks). + +

+ + +

+ +## 🎯 Features + +- Robust [Routing](https://docs.gofiber.io/guide/routing) +- Serve [Static Files](https://docs.gofiber.io/api/app#static) +- Extreme [Performance](https://docs.gofiber.io/extra/benchmarks) +- [Low Memory](https://docs.gofiber.io/extra/benchmarks) footprint +- [API Endpoints](https://docs.gofiber.io/api/ctx) +- [Middleware](https://docs.gofiber.io/category/-middleware) & [Next](https://docs.gofiber.io/api/ctx#next) support +- [Rapid](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) server-side programming +- [Template Engines](https://github.com/gofiber/template) +- [WebSocket Support](https://github.com/gofiber/contrib/tree/main/websocket) +- [Socket.io Support](https://github.com/gofiber/contrib/tree/main/socketio) +- [Server-Sent Events](https://github.com/gofiber/recipes/tree/master/sse) +- [Rate Limiter](https://docs.gofiber.io/api/middleware/limiter) +- And much more, [explore Fiber](https://docs.gofiber.io/) + +## 💡 Philosophy + +New gophers that make the switch from [Node.js](https://nodejs.org/en/about/) to [Go](https://go.dev/doc/) are dealing with a learning curve before they can start building their web applications or microservices. Fiber, as a **web framework**, was created with the idea of **minimalism** and follows the **UNIX way**, so that new gophers can quickly enter the world of Go with a warm and trusted welcome. + +Fiber is **inspired** by Express, the most popular web framework on the Internet. We combined the **ease** of Express and **raw performance** of Go. If you have ever implemented a web application in Node.js (_using Express or similar_), then many methods and principles will seem **very common** to you. + +We **listen** to our users in [issues](https://github.com/gofiber/fiber/issues), Discord [channel](https://gofiber.io/discord) _and all over the Internet_ to create a **fast**, **flexible** and **friendly** Go web framework for **any** task, **deadline** and developer **skill**! Just like Express does in the JavaScript world. + +## ⚠️ Limitations + +- Due to Fiber's usage of unsafe, the library may not always be compatible with the latest Go version. Fiber v3 has been tested with Go version 1.25 or higher. +- Fiber automatically adapts common `net/http` handler shapes when you register them on the router, and you can still use the [adaptor middleware](https://docs.gofiber.io/next/middleware/adaptor/) when you need to bridge entire apps or `net/http` middleware. + +### net/http compatibility + +Fiber can run side by side with the standard library. The router accepts existing `net/http` handlers directly and even works with native `fasthttp.RequestHandler` callbacks, so you can plug in legacy endpoints without wrapping them manually: + +```go +package main + +import ( + "log" + "net/http" + + "github.com/gofiber/fiber/v3" +) + +func main() { + httpHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if _, err := w.Write([]byte("served by net/http")); err != nil { + panic(err) + } + }) + + app := fiber.New() + app.Get("/", httpHandler) + + // Start the server on port 3000 + log.Fatal(app.Listen(":3000")) +} +``` + +When you need to convert entire applications or reuse `net/http` middleware chains, rely on the [adaptor middleware](https://docs.gofiber.io/next/middleware/adaptor/). It converts handlers and middlewares in both directions and even lets you mount a Fiber app in a `net/http` server. + +### Express-style handlers + +Fiber also adapts Express-style callbacks that operate on the lightweight `fiber.Req` and `fiber.Res` helper interfaces. This lets you port middleware and route handlers from Express-inspired codebases while keeping Fiber's router features: + +```go +// Request/response handlers (2-argument) +app.Get("/", func(req fiber.Req, res fiber.Res) error { + return res.SendString("Hello from Express-style handlers!") +}) + +// Middleware with an error-returning next callback (3-argument) +app.Use(func(req fiber.Req, res fiber.Res, next func() error) error { + if req.IP() == "192.168.1.254" { + return res.SendStatus(fiber.StatusForbidden) + } + return next() +}) + +// Middleware with a no-arg next callback (3-argument) +app.Use(func(req fiber.Req, res fiber.Res, next func()) { + if req.Get("X-Skip") == "true" { + return // stop the chain without calling next + } + next() +}) +``` + +> **Note:** Adapted `net/http` handlers continue to operate with the standard-library semantics. They don't get access to `fiber.Ctx` features and incur the overhead of the compatibility layer, so native `fiber.Handler` callbacks still provide the best performance. + +## 👀 Examples + +Listed below are some of the common examples. If you want to see more code examples, please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io). + +### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing) + +```go title="Example" +package main + +import ( + "fmt" + "log" + + "github.com/gofiber/fiber/v3" +) + +func main() { + app := fiber.New() + + // GET /api/register + app.Get("/api/*", func(c fiber.Ctx) error { + msg := fmt.Sprintf("✋ %s", c.Params("*")) + return c.SendString(msg) // => ✋ register + }) + + // GET /flights/LAX-SFO + app.Get("/flights/:from-:to", func(c fiber.Ctx) error { + msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to")) + return c.SendString(msg) // => 💸 From: LAX, To: SFO + }) + + // GET /dictionary.txt + app.Get("/:file.:ext", func(c fiber.Ctx) error { + msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext")) + return c.SendString(msg) // => 📃 dictionary.txt + }) + + // GET /john/75 + app.Get("/:name/:age/:gender?", func(c fiber.Ctx) error { + msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age")) + return c.SendString(msg) // => 👴 john is 75 years old + }) + + // GET /john + app.Get("/:name", func(c fiber.Ctx) error { + msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name")) + return c.SendString(msg) // => Hello john 👋! + }) + + log.Fatal(app.Listen(":3000")) +} +``` + +#### 📖 [**Route Naming**](https://docs.gofiber.io/api/app#name) + +```go title="Example" +package main + +import ( + "encoding/json" + "fmt" + "log" + + "github.com/gofiber/fiber/v3" +) + +func main() { + app := fiber.New() + + app.Get("/api/*", func(c fiber.Ctx) error { + msg := fmt.Sprintf("✋ %s", c.Params("*")) + return c.SendString(msg) // => ✋ register + }).Name("api") + + route := app.GetRoute("api") + + data, _ := json.MarshalIndent(route, "", " ") + fmt.Println(string(data)) + // Prints: + // { + // "method": "GET", + // "name": "api", + // "path": "/api/*", + // "params": [ + // "*1" + // ] + // } + + log.Fatal(app.Listen(":3000")) +} +``` + +#### 📖 [**Serving Static Files**](https://docs.gofiber.io/api/app#static) + +```go title="Example" +package main + +import ( + "log" + + "github.com/gofiber/fiber/v3" + "github.com/gofiber/fiber/v3/middleware/static" +) + +func main() { + app := fiber.New() + + // Serve static files from the "./public" directory + app.Get("/*", static.New("./public")) + // => http://localhost:3000/js/script.js + // => http://localhost:3000/css/style.css + + app.Get("/prefix*", static.New("./public")) + // => http://localhost:3000/prefix/js/script.js + // => http://localhost:3000/prefix/css/style.css + + // Serve a single file for any unmatched routes + app.Get("*", static.New("./public/index.html")) + // => http://localhost:3000/any/path/shows/index.html + + log.Fatal(app.Listen(":3000")) +} +``` + +#### 📖 [**Middleware & Next**](https://docs.gofiber.io/api/ctx#next) + +```go title="Example" +package main + +import ( + "fmt" + "log" + + "github.com/gofiber/fiber/v3" +) + +func main() { + app := fiber.New() + + // Middleware that matches any route + app.Use(func(c fiber.Ctx) error { + fmt.Println("🥇 First handler") + return c.Next() + }) + + // Middleware that matches all routes starting with /api + app.Use("/api", func(c fiber.Ctx) error { + fmt.Println("🥈 Second handler") + return c.Next() + }) + + // GET /api/list + app.Get("/api/list", func(c fiber.Ctx) error { + fmt.Println("🥉 Last handler") + return c.SendString("Hello, World 👋!") + }) + + log.Fatal(app.Listen(":3000")) +} +``` + +
+ 📚 Show more code examples + +### Views Engines + +📖 [Config](https://docs.gofiber.io/api/fiber#config) +📖 [Engines](https://github.com/gofiber/template) +📖 [Render](https://docs.gofiber.io/api/ctx#render) + +Fiber defaults to the [html/template](https://pkg.go.dev/html/template/) when no view engine is set. + +If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache), or [pug](https://github.com/Joker/jade), etc., check out our [Template](https://github.com/gofiber/template) package that supports multiple view engines. + +```go title="Example" +package main + +import ( + "log" + + "github.com/gofiber/fiber/v3" + "github.com/gofiber/template/pug" +) + +func main() { + // Initialize a new Fiber app with Pug template engine + app := fiber.New(fiber.Config{ + Views: pug.New("./views", ".pug"), + }) + + // Define a route that renders the "home.pug" template + app.Get("/", func(c fiber.Ctx) error { + return c.Render("home", fiber.Map{ + "title": "Homepage", + "year": 1999, + }) + }) + + log.Fatal(app.Listen(":3000")) +} +``` + +### Grouping Routes into Chains + +📖 [Group](https://docs.gofiber.io/api/app#group) + +```go title="Example" +package main + +import ( + "log" + + "github.com/gofiber/fiber/v3" +) + +func middleware(c fiber.Ctx) error { + log.Println("Middleware executed") + return c.Next() +} + +func handler(c fiber.Ctx) error { + return c.SendString("Handler response") +} + +func main() { + app := fiber.New() + + // Root API group with middleware + api := app.Group("/api", middleware) // /api + + // API v1 routes + v1 := api.Group("/v1", middleware) // /api/v1 + v1.Get("/list", handler) // /api/v1/list + v1.Get("/user", handler) // /api/v1/user + + // API v2 routes + v2 := api.Group("/v2", middleware) // /api/v2 + v2.Get("/list", handler) // /api/v2/list + v2.Get("/user", handler) // /api/v2/user + + log.Fatal(app.Listen(":3000")) +} +``` + +### Middleware Logger + +📖 [Logger](https://docs.gofiber.io/api/middleware/logger) + +```go title="Example" +package main + +import ( + "log" + + "github.com/gofiber/fiber/v3" + "github.com/gofiber/fiber/v3/middleware/logger" +) + +func main() { + app := fiber.New() + + // Use Logger middleware + app.Use(logger.New()) + + // Define routes + app.Get("/", func(c fiber.Ctx) error { + return c.SendString("Hello, Logger!") + }) + + log.Fatal(app.Listen(":3000")) +} +``` + +### Cross-Origin Resource Sharing (CORS) + +📖 [CORS](https://docs.gofiber.io/api/middleware/cors) + +```go title="Example" +package main + +import ( + "log" + + "github.com/gofiber/fiber/v3" + "github.com/gofiber/fiber/v3/middleware/cors" +) + +func main() { + app := fiber.New() + + // Use CORS middleware with default settings + app.Use(cors.New()) + + // Define routes + app.Get("/", func(c fiber.Ctx) error { + return c.SendString("CORS enabled!") + }) + + log.Fatal(app.Listen(":3000")) +} +``` + +Check CORS by passing any domain in `Origin` header: + +```bash +curl -H "Origin: http://example.com" --verbose http://localhost:3000 +``` + +### Custom 404 Response + +📖 [HTTP Methods](https://docs.gofiber.io/api/ctx#status) + +```go title="Example" +package main + +import ( + "log" + + "github.com/gofiber/fiber/v3" +) + +func main() { + app := fiber.New() + + // Define routes + app.Get("/", static.New("./public")) + + app.Get("/demo", func(c fiber.Ctx) error { + return c.SendString("This is a demo page!") + }) + + app.Post("/register", func(c fiber.Ctx) error { + return c.SendString("Registration successful!") + }) + + // Middleware to handle 404 Not Found + app.Use(func(c fiber.Ctx) error { + return c.SendStatus(fiber.StatusNotFound) // => 404 "Not Found" + }) + + log.Fatal(app.Listen(":3000")) +} +``` + +### JSON Response + +📖 [JSON](https://docs.gofiber.io/api/ctx#json) + +```go title="Example" +package main + +import ( + "log" + + "github.com/gofiber/fiber/v3" +) + +type User struct { + Name string `json:"name"` + Age int `json:"age"` +} + +func main() { + app := fiber.New() + + // Route that returns a JSON object + app.Get("/user", func(c fiber.Ctx) error { + return c.JSON(&User{"John", 20}) + // => {"name":"John", "age":20} + }) + + // Route that returns a JSON map + app.Get("/json", func(c fiber.Ctx) error { + return c.JSON(fiber.Map{ + "success": true, + "message": "Hi John!", + }) + // => {"success":true, "message":"Hi John!"} + }) + + log.Fatal(app.Listen(":3000")) +} +``` + +### WebSocket Upgrade + +📖 [Websocket](https://github.com/gofiber/websocket) + +```go title="Example" +package main + +import ( + "log" + + "github.com/gofiber/fiber/v3" + "github.com/gofiber/fiber/v3/middleware/websocket" +) + +func main() { + app := fiber.New() + + // WebSocket route + app.Get("/ws", websocket.New(func(c *websocket.Conn) { + defer c.Close() + for { + // Read message from client + mt, msg, err := c.ReadMessage() + if err != nil { + log.Println("read:", err) + break + } + log.Printf("recv: %s", msg) + + // Write message back to client + err = c.WriteMessage(mt, msg) + if err != nil { + log.Println("write:", err) + break + } + } + })) + + log.Fatal(app.Listen(":3000")) + // Connect via WebSocket at ws://localhost:3000/ws +} +``` + +### Server-Sent Events + +📖 [More Info](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) + +```go title="Example" +package main + +import ( + "bufio" + "fmt" + "log" + "time" + + "github.com/gofiber/fiber/v3" + "github.com/valyala/fasthttp" +) + +func main() { + app := fiber.New() + + // Server-Sent Events route + app.Get("/sse", func(c fiber.Ctx) error { + c.Set("Content-Type", "text/event-stream") + c.Set("Cache-Control", "no-cache") + c.Set("Connection", "keep-alive") + c.Set("Transfer-Encoding", "chunked") + + c.Context().SetBodyStreamWriter(func(w *bufio.Writer) { + var i int + for { + i++ + msg := fmt.Sprintf("%d - the time is %v", i, time.Now()) + fmt.Fprintf(w, "data: Message: %s\n\n", msg) + fmt.Println(msg) + + w.Flush() + time.Sleep(5 * time.Second) + } + }) + + return nil + }) + + log.Fatal(app.Listen(":3000")) +} +``` + +### Recover Middleware + +📖 [Recover](https://docs.gofiber.io/api/middleware/recover) + +```go title="Example" +package main + +import ( + "log" + + "github.com/gofiber/fiber/v3" + "github.com/gofiber/fiber/v3/middleware/recover" +) + +func main() { + app := fiber.New() + + // Use Recover middleware to handle panics gracefully + app.Use(recover.New()) + + // Route that intentionally panics + app.Get("/", func(c fiber.Ctx) error { + panic("normally this would crash your app") + }) + + log.Fatal(app.Listen(":3000")) +} +``` + +### Using Trusted Proxy + +📖 [Config](https://docs.gofiber.io/api/fiber#config) + +```go title="Example" +package main + +import ( + "log" + + "github.com/gofiber/fiber/v3" +) + +func main() { + app := fiber.New(fiber.Config{ + // Configure trusted proxies - WARNING: Only trust proxies you control + // Using TrustProxy: true with unrestricted IPs can lead to IP spoofing + TrustProxy: true, + TrustProxyConfig: fiber.TrustProxyConfig{ + Proxies: []string{"10.0.0.0/8", "172.16.0.0/12"}, // Example: Internal network ranges only + }, + ProxyHeader: fiber.HeaderXForwardedFor, + }) + + // Define routes + app.Get("/", func(c fiber.Ctx) error { + return c.SendString("Trusted Proxy Configured!") + }) + + log.Fatal(app.Listen(":3000")) +} +``` + +
+ +## 🧬 Internal Middleware + +Here is a list of middleware that are included within the Fiber framework. + +| Middleware | Description | +|--------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [adaptor](https://github.com/gofiber/fiber/tree/main/middleware/adaptor) | Converter for net/http handlers to/from Fiber request handlers. | +| [basicauth](https://github.com/gofiber/fiber/tree/main/middleware/basicauth) | Provides HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | +| [cache](https://github.com/gofiber/fiber/tree/main/middleware/cache) | Intercept and cache HTTP responses. | +| [compress](https://github.com/gofiber/fiber/tree/main/middleware/compress) | Compression middleware for Fiber, with support for `deflate`, `gzip`, `brotli` and `zstd`. | +| [cors](https://github.com/gofiber/fiber/tree/main/middleware/cors) | Enable cross-origin resource sharing (CORS) with various options. | +| [csrf](https://github.com/gofiber/fiber/tree/main/middleware/csrf) | Protect from CSRF exploits. | +| [earlydata](https://github.com/gofiber/fiber/tree/main/middleware/earlydata) | Adds support for TLS 1.3's early data ("0-RTT") feature. | +| [encryptcookie](https://github.com/gofiber/fiber/tree/main/middleware/encryptcookie) | Encrypt middleware which encrypts cookie values. | +| [envvar](https://github.com/gofiber/fiber/tree/main/middleware/envvar) | Expose environment variables with providing an optional config. | +| [etag](https://github.com/gofiber/fiber/tree/main/middleware/etag) | Allows for caches to be more efficient and save bandwidth, as a web server does not need to resend a full response if the content has not changed. | +| [expvar](https://github.com/gofiber/fiber/tree/main/middleware/expvar) | Serves via its HTTP server runtime exposed variables in the JSON format. | +| [favicon](https://github.com/gofiber/fiber/tree/main/middleware/favicon) | Ignore favicon from logs or serve from memory if a file path is provided. | +| [healthcheck](https://github.com/gofiber/fiber/tree/main/middleware/healthcheck) | Liveness and Readiness probes for Fiber. | +| [helmet](https://github.com/gofiber/fiber/tree/main/middleware/helmet) | Helps secure your apps by setting various HTTP headers. | +| [hostauthorization](https://github.com/gofiber/fiber/tree/main/middleware/hostauthorization) | Validates the Host header against a configurable allowlist, protecting against DNS rebinding attacks. | +| [idempotency](https://github.com/gofiber/fiber/tree/main/middleware/idempotency) | Allows for fault-tolerant APIs where duplicate requests do not erroneously cause the same action performed multiple times on the server-side. | +| [keyauth](https://github.com/gofiber/fiber/tree/main/middleware/keyauth) | Adds support for key based authentication. | +| [limiter](https://github.com/gofiber/fiber/tree/main/middleware/limiter) | Adds Rate-limiting support to Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | +| [logger](https://github.com/gofiber/fiber/tree/main/middleware/logger) | HTTP request/response logger. | +| [paginate](https://github.com/gofiber/fiber/tree/main/middleware/paginate) | Extracts pagination parameters from query strings. Supports page-based, offset-based, and cursor-based pagination with multi-field sorting. | +| [pprof](https://github.com/gofiber/fiber/tree/main/middleware/pprof) | Serves runtime profiling data in pprof format. | +| [proxy](https://github.com/gofiber/fiber/tree/main/middleware/proxy) | Allows you to proxy requests to multiple servers. | +| [recover](https://github.com/gofiber/fiber/tree/main/middleware/recover) | Recovers from panics anywhere in the stack chain and handles the control to the centralized ErrorHandler. | +| [redirect](https://github.com/gofiber/fiber/tree/main/middleware/redirect) | Redirect middleware. | +| [requestid](https://github.com/gofiber/fiber/tree/main/middleware/requestid) | Adds a request ID to every request. | +| [responsetime](https://github.com/gofiber/fiber/tree/main/middleware/responsetime) | Measures request handling duration and writes it to a configurable response header. | +| [rewrite](https://github.com/gofiber/fiber/tree/main/middleware/rewrite) | Rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | +| [session](https://github.com/gofiber/fiber/tree/main/middleware/session) | Session middleware. NOTE: This middleware uses our Storage package. | +| [skip](https://github.com/gofiber/fiber/tree/main/middleware/skip) | Skip middleware that skips a wrapped handler if a predicate is true. | +| [static](https://github.com/gofiber/fiber/tree/main/middleware/static) | Static middleware for Fiber that serves static files such as **images**, **CSS**, and **JavaScript**. | +| [timeout](https://github.com/gofiber/fiber/tree/main/middleware/timeout) | Adds a max time for a request and forwards to ErrorHandler if it is exceeded. | + +## 🧬 External Middleware + +List of externally hosted middleware modules and maintained by the [Fiber team](https://github.com/orgs/gofiber/people). + +| Middleware | Description | +| :------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------- | +| [contrib](https://github.com/gofiber/contrib) | Third-party middlewares | +| [storage](https://github.com/gofiber/storage) | Premade storage drivers that implement the Storage interface, designed to be used with various Fiber middlewares. | +| [template](https://github.com/gofiber/template) | This package contains 9 template engines that can be used with Fiber. | + +## 🕶️ Awesome List + +For more articles, middlewares, examples, or tools, check our [awesome list](https://github.com/gofiber/awesome-fiber). + +## 👍 Contribute + +If you want to say **Thank You** and/or support the active development of `Fiber`: + +1. Add a [GitHub Star](https://github.com/gofiber/fiber/stargazers) to the project. +2. Tweet about the project [on your 𝕏 (Twitter)](https://x.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber). +3. Write a review or tutorial on [Medium](https://medium.com/), [Dev.to](https://dev.to/) or your personal blog. +4. Support the project by becoming a [GitHub Sponsor](https://github.com/sponsors/gofiber). + +## 💻 Development + +To ensure your contributions are ready for a Pull Request, please use the following `Makefile` commands. These tools help maintain code quality and consistency. + +- **make help**: Display available commands. +- **make audit**: Conduct quality checks. +- **make benchmark**: Benchmark code performance. +- **make coverage**: Generate test coverage report. +- **make format**: Automatically format code. +- **make lint**: Run lint checks. +- **make test**: Execute all tests. +- **make tidy**: Tidy dependencies. + +Run these commands to ensure your code adheres to project standards and best practices. + + +## ☕ Supporters + +Fiber is an open-source project that runs on donations to pay the bills, e.g., our domain name, GitBook, Netlify, and serverless hosting. If you want to support Fiber, please sponsor the organization via ⭐ [**GitHub Sponsors**](https://github.com/sponsors/gofiber). + + + +### 📅 Monthly Sponsors + + + + + +
🔥 Fiber Guardian@coderabbitai
☕ Fiber Supporter@NdoleStudio @petercool
🪴 Fiber Friend@simonheisstpeter
+ +### 🎁 One-time Sponsors + + + + +
🚀 Fiber Hero@thnxdev
🪴 Fiber Friend@Gl1tchedPixzl
+ + + +## 💻 Code Contributors + + + Code Contributors + + +## ⭐️ Stargazers + + + + + Stargazers over time + + +## 🧾 License + +Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/main/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International). diff --git a/src/vendor/github.com/gofiber/fiber/v3/app.go b/src/vendor/github.com/gofiber/fiber/v3/app.go index 77423ae1..cb325b77 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/app.go +++ b/src/vendor/github.com/gofiber/fiber/v3/app.go @@ -35,7 +35,7 @@ import ( ) // Version of current fiber package -const Version = "3.4.0" +const Version = "3.5.0" // Handler defines a function to serve HTTP requests. type Handler = func(Ctx) error @@ -82,8 +82,6 @@ type App struct { pool sync.Pool // Fasthttp server server *fasthttp.Server - // Converts string to a byte slice - toBytes func(s string) (b []byte) // Converts byte slice to a string toString func(b []byte) string // Hooks @@ -108,8 +106,18 @@ type App struct { sendfiles []*sendFileStore // custom binders customBinders []CustomBinder - // Route stack divided by HTTP methods and route prefixes + // Route stack divided by HTTP methods and route prefixes. Build-time only: + // requests go through treeIndex. Each build replaces it with freshly + // allocated buckets rather than refilling the previous ones, so a published + // tree stays immutable; it is retained as a field because buildLookahead + // reads it to index the same buckets next() will scan. treeStack []map[int][]*Route + // Request-time view of treeStack: one flat, open-addressed index per HTTP + // method, rebuilt with the tree (see routeTree in router.go). Held by + // pointer so a rebuild publishes each method's tree in one store. + treeIndex []*routeTree + // Precomputed unmatched-route indexes, rebuilt with the tree (router_skip.go) + skip skipRouteIndex // sendfilesMutex is a mutex used for sendfile operations sendfilesMutex sync.RWMutex mutex sync.Mutex @@ -119,6 +127,9 @@ type App struct { hasRoutesRefreshed bool // hasCustomCtx tracks whether app uses a custom context implementation hasCustomCtx bool + // hasParamRoutes tracks whether any route consults the per-request slash + // count (rebuilt with the tree); when false the count is skipped entirely + hasParamRoutes bool } type viewsLockKey struct { @@ -191,6 +202,24 @@ type Config struct { //nolint:govet // Aligning the struct fields is not necessa // Default: false CaseSensitive bool `json:"case_sensitive"` + // When set to true, requests whose path and method match no registered route + // are answered with 404 (or 405 when the path exists for other methods) + // before the middleware chain runs, so no work is spent on bots, scanners, + // and bad URLs. + // + // Warning: middleware never runs for skipped requests. This breaks Use-based + // responders on unregistered paths (catch-all 404 pages, static, proxy, + // healthcheck, rewrite and redirect middleware); loggers and metrics will not + // see the skipped requests either, and a rate limiter neither counts nor + // throttles them. CORS preflight requests are exempt, so cors middleware + // keeps working. Customize the 404/405 responses via ErrorHandler. + // + // Note: with more than 64 entries in RequestMethods the fast path is disabled + // and requests fall through to the normal router. + // + // Default: false + SkipUnmatchedRoutes bool `json:"skip_unmatched_routes"` + // When set to true, disables automatic registration of HEAD routes for // every GET route. // @@ -668,7 +697,6 @@ func New(config ...Config) *App { app := &App{ // Create config config: Config{}, - toBytes: utils.UnsafeBytes, toString: utils.UnsafeString, latestRoute: &Route{}, customBinders: []CustomBinder{}, @@ -730,7 +758,7 @@ func New(config ...Config) *App { } if app.config.Immutable { - app.toBytes, app.toString = toBytesImmutable, toStringImmutable + app.toString = toStringImmutable } if app.config.ErrorHandler == nil { @@ -776,6 +804,11 @@ func New(config ...Config) *App { // Create router stack app.stack = make([][]*Route, len(app.config.RequestMethods)) app.treeStack = make([]map[int][]*Route, len(app.config.RequestMethods)) + app.treeIndex = make([]*routeTree, len(app.config.RequestMethods)) + for i := range app.treeIndex { + // Never nil: next() may run before the tree is first built. + app.treeIndex[i] = &routeTree{} + } // Override colors app.config.ColorScheme = defaultColors(&app.config.ColorScheme) @@ -1221,8 +1254,9 @@ func NewErrorf(code int, message ...any) *Error { if format, ok := message[0].(string); ok { msg = fmt.Sprintf(format, message[1:]...) } else { - // If the first arg isn’t a string, fall back. - msg = fmt.Sprint(message[0]) + // If the first arg isn’t a format string, stringify all of them + // instead of dropping everything after the first. + msg = fmt.Sprint(message...) } } @@ -1305,7 +1339,9 @@ func (app *App) ShutdownWithContext(ctx context.Context) error { // Execute the Shutdown hook app.hooks.executeOnPreShutdownHooks() - defer app.hooks.executeOnPostShutdownHooks(err) + // Use a closure so the hooks receive the final error; a plain + // `defer ...(err)` would capture the nil value at registration time. + defer func() { app.hooks.executeOnPostShutdownHooks(err) }() err = app.server.ShutdownWithContext(ctx) return err diff --git a/src/vendor/github.com/gofiber/fiber/v3/bind.go b/src/vendor/github.com/gofiber/fiber/v3/bind.go index cacf7c4a..629f12a7 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/bind.go +++ b/src/vendor/github.com/gofiber/fiber/v3/bind.go @@ -6,13 +6,12 @@ import ( "fmt" "reflect" "slices" + "strings" "sync" "github.com/gofiber/fiber/v3/binder" "github.com/gofiber/fiber/v3/internal/nilerror" "github.com/gofiber/schema" - "github.com/gofiber/utils/v2" - utilsbytes "github.com/gofiber/utils/v2/bytes" ) // CustomBinder An interface to register custom binders. @@ -346,6 +345,9 @@ func (b *Bind) XML(out any) error { // If Content-Type is "application/x-www-form-urlencoded" or "multipart/form-data", it will bind the form values. // Multipart file fields are supported using *multipart.FileHeader, []*multipart.FileHeader, or *[]*multipart.FileHeader. func (b *Bind) Form(out any) error { + // The Content-Type is deliberately not normalized here: FormBinding.Bind opens + // by doing it itself, so a fold here would be a second pass over the same + // header. Body still folds, because it must read the media type to dispatch. bind := binder.GetFromThePool[*binder.FormBinding](&binder.FormBinderPool) bind.EnableSplitting = b.ctx.App().config.EnableSplittingOnParsers bind.MaxBodySize = b.ctx.App().config.BodyLimit @@ -395,9 +397,7 @@ func (b *Bind) MsgPack(out any) error { // If none of the content types above are matched, it'll take a look custom binders by checking the MIMETypes() method of custom binder. // If there is no custom binder for mime type of body, it will return a ErrUnprocessableEntity error. func (b *Bind) Body(out any) error { - // Get content-type - ctype := utils.UnsafeString(utilsbytes.UnsafeToLower(b.ctx.RequestCtx().Request.Header.ContentType())) - ctype = binder.FilterFlags(utils.ParseVendorSpecificContentType(ctype)) + ctype := bindMediaType(&b.ctx.RequestCtx().Request.Header) // Check custom binders binders := b.ctx.App().customBinders @@ -428,6 +428,75 @@ func (b *Bind) Body(out any) error { return ErrUnprocessableEntity } +type bindSource int + +const ( + sourceURI bindSource = iota + sourceBody + sourceQuery + sourceHeader + sourceCookie +) + +type cachedPrecedence struct { + err error + sources []bindSource +} + +var bindingPrecedenceCache sync.Map // map[reflect.Type]cachedPrecedence + +func getBindingPrecedence(t reflect.Type) ([]bindSource, error) { + if cached, ok := bindingPrecedenceCache.Load(t); ok { + if cp, ok := cached.(cachedPrecedence); ok { + return cp.sources, cp.err + } + } + var precedence []bindSource + var tagFound bool + for i := range t.NumField() { + if tag := t.Field(i).Tag.Get("binding_source"); tag != "" { + if tagFound { + err := fmt.Errorf("multiple binding_source tags found on struct %s", t.Name()) + bindingPrecedenceCache.Store(t, cachedPrecedence{err: err, sources: nil}) + return nil, err + } + tagFound = true + + parts := strings.SplitSeq(tag, ",") + for p := range parts { + sourceName := strings.TrimSpace(p) + if sourceName == "" { + continue + } + var source bindSource + switch sourceName { + case "uri": + source = sourceURI + case "body": + source = sourceBody + case "query": + source = sourceQuery + case "header": + source = sourceHeader + case "cookie": + source = sourceCookie + default: + err := fmt.Errorf("unknown binding_source %q", sourceName) + bindingPrecedenceCache.Store(t, cachedPrecedence{err: err, sources: nil}) + return nil, err + } + + // check for duplicates + if !slices.Contains(precedence, source) { + precedence = append(precedence, source) + } + } + } + } + bindingPrecedenceCache.Store(t, cachedPrecedence{err: nil, sources: precedence}) + return precedence, nil +} + // All binds values from URI params, the request body, the query string, // headers, and cookies into the provided struct in precedence order. // Returns *BindError on parse failure (manual mode) or *Error with status 400 (auto-handling mode). @@ -439,18 +508,46 @@ func (b *Bind) All(out any) error { outElem := outVal.Elem() - // Precedence: URL Params -> Body -> Query -> Headers -> Cookies - sources := []func(any) error{b.URI} + sources := make([]func(any) error, 0, 5) + customPrecedence, err := getBindingPrecedence(outElem.Type()) + if err != nil { + // Note: A malformed binding_source tag is a programmer error, not a client error. + // Returning the raw error here bypasses b.returnErr, intentionally resulting in a 500 + // rather than a 400 even in auto-handling mode. + return err + } - // Check if both Body and Content-Type are set - if len(b.ctx.Request().Body()) > 0 && len(b.ctx.RequestCtx().Request.Header.ContentType()) > 0 { - sources = append(sources, b.Body) + if len(customPrecedence) > 0 { + for _, source := range customPrecedence { + switch source { + case sourceURI: + sources = append(sources, b.URI) + case sourceBody: + if len(b.ctx.Request().Body()) > 0 && len(b.ctx.RequestCtx().Request.Header.ContentType()) > 0 { + sources = append(sources, b.Body) + } + case sourceQuery: + sources = append(sources, b.Query) + case sourceHeader: + sources = append(sources, b.Header) + case sourceCookie: + sources = append(sources, b.Cookie) + } + } + } else { + // Precedence: URL Params -> Body -> Query -> Headers -> Cookies + sources = append(sources, b.URI) + + // Check if both Body and Content-Type are set + if len(b.ctx.Request().Body()) > 0 && len(b.ctx.RequestCtx().Request.Header.ContentType()) > 0 { + sources = append(sources, b.Body) + } + sources = append(sources, b.Query, b.Header, b.Cookie) } - sources = append(sources, b.Query, b.Header, b.Cookie) + prevSkip := b.shouldSkipValidation b.shouldSkipValidation = true - // TODO: Support custom precedence with an optional binding_source tag // TODO: Create WithOverrideEmptyValues // Bind from each source, but only update unset fields for _, bindFunc := range sources { diff --git a/src/vendor/github.com/gofiber/fiber/v3/binder/form.go b/src/vendor/github.com/gofiber/fiber/v3/binder/form.go index fb846b66..7f142f2f 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/binder/form.go +++ b/src/vendor/github.com/gofiber/fiber/v3/binder/form.go @@ -4,6 +4,7 @@ import ( "mime/multipart" "sync" + "github.com/gofiber/fiber/v3/internal/mediatype" "github.com/gofiber/utils/v2" "github.com/valyala/fasthttp" ) @@ -40,8 +41,16 @@ func (*FormBinding) Name() string { // Bind parses the request body and returns the result. func (b *FormBinding) Bind(req *fasthttp.Request, out any) error { - // Handle multipart form - if FilterFlags(utils.UnsafeString(req.Header.ContentType())) == MIMEMultipartForm { + // Callers reaching the binder directly skip Fiber's normalization, and + // comparing case-insensitively is not enough: PostArgs and MultipartForm match + // the media type and "boundary=" case-sensitively. Guarded — the fold writes. + if mediatype.IsForm(req.Header.ContentType()) { + mediatype.NormalizeRequestContentType(&req.Header) + } + + // Handle multipart form. Media types are case-insensitive + // (RFC 9110 Section 8.3.1), so compare accordingly. + if utils.EqualFold(FilterFlags(utils.UnsafeString(req.Header.ContentType())), MIMEMultipartForm) { return b.bindMultipart(req, out) } diff --git a/src/vendor/github.com/gofiber/fiber/v3/binder/mapping.go b/src/vendor/github.com/gofiber/fiber/v3/binder/mapping.go index fdc6f91a..24e342f7 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/binder/mapping.go +++ b/src/vendor/github.com/gofiber/fiber/v3/binder/mapping.go @@ -8,6 +8,7 @@ import ( "strings" "sync" + "github.com/gofiber/utils/v2" utilsstrings "github.com/gofiber/utils/v2/strings" "github.com/valyala/bytebufferpool" @@ -313,7 +314,6 @@ func buildFieldInfo(t reflect.Type, aliasTag string) fieldInfo { func equalFieldType(out any, kind reflect.Kind, key, aliasTag string) bool { typ := reflect.TypeOf(out).Elem() - key = utilsstrings.ToLower(key) if isStringKeyMap(typ) { return true @@ -323,6 +323,10 @@ func equalFieldType(out any, kind reflect.Kind, key, aliasTag string) bool { return false } + // Lower the key only once a struct lookup is actually needed; the early + // returns above never use it. + key = utilsstrings.ToLower(key) + cache := getFieldCache(aliasTag) val, ok := cache.Load(typ) if !ok { @@ -347,7 +351,7 @@ func equalFieldType(out any, kind reflect.Kind, key, aliasTag string) bool { // FilterFlags returns the media type value by trimming any parameters from a Content-Type header. func FilterFlags(content string) string { - if i := strings.IndexAny(content, " ;"); i >= 0 { + if i := utils.IndexAny2(content, ' ', ';'); i >= 0 { return content[:i] } return content diff --git a/src/vendor/github.com/gofiber/fiber/v3/constraint.go b/src/vendor/github.com/gofiber/fiber/v3/constraint.go index bd326a6c..f8052e2a 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/constraint.go +++ b/src/vendor/github.com/gofiber/fiber/v3/constraint.go @@ -10,6 +10,7 @@ import ( "time" "unicode" + "github.com/gofiber/utils/v2/swar" "github.com/google/uuid" ) @@ -227,6 +228,10 @@ func (c *Constraint) matchConstraint(param string) bool { type intConstraintType struct{} func (intConstraintType) Name() string { return ConstraintInt } + +// The int-family constraints (int, min, max, range) deliberately stay on +// strconv.Atoi: utils.ParseNativeInt benchmarked slower for the short +// (1-14 digit) params routes actually see, winning only near 19 digits. func (intConstraintType) Execute(param string, _ []any) bool { _, err := strconv.Atoi(param) return err == nil @@ -244,7 +249,7 @@ type floatConstraintType struct{} func (floatConstraintType) Name() string { return ConstraintFloat } func (floatConstraintType) Execute(param string, _ []any) bool { - _, err := strconv.ParseFloat(param, 32) + _, err := strconv.ParseFloat(param, 64) return err == nil } @@ -252,8 +257,40 @@ type alphaConstraintType struct{} func (alphaConstraintType) Name() string { return ConstraintAlpha } func (alphaConstraintType) Execute(param string, _ []any) bool { - for _, c := range param { - if !unicode.IsLetter(c) { + // SWAR fast path for the ASCII-common case; the first word containing a + // non-ASCII byte defers the rest to the Unicode rune loop, and so does + // the sub-word tail. The handoff happens only where every preceding + // byte is ASCII, i.e. on a rune boundary. + n := len(param) + i := 0 + for ; i+swar.WordLen <= n; i += swar.WordLen { + w := swar.Load8(param, i) + if w&swar.HighBits != 0 { + return isUnicodeAlpha(param[i:]) + } + if swar.MatchRangeMask(w, 'A', 'Z')|swar.MatchRangeMask(w, 'a', 'z') != swar.HighBits { + return false + } + } + // Scalar tail rather than isUnicodeAlpha(param[i:]): short params are + // the common case and skipping the rune decoding measures ~12% faster + // on Benchmark_ConstraintExecution/alpha. + for ; i < n; i++ { + c := param[i] + if c >= 0x80 { + return isUnicodeAlpha(param[i:]) + } + if lc := c | 0x20; lc < 'a' || lc > 'z' { + return false + } + } + return true +} + +// isUnicodeAlpha reports whether s consists only of Unicode letters. +func isUnicodeAlpha(s string) bool { + for _, r := range s { + if !unicode.IsLetter(r) { return false } } @@ -526,6 +563,8 @@ func (regexConstraintType) Execute(param string, data []any) bool { // resolveConstraintName handles case-insensitive and alias matching for constraint names. func resolveConstraintName(name string) string { + // strings.ToLower (not the ASCII-only utils variant) so aliases keep + // Unicode simple case folding, e.g. Turkish-locale "MİNLEN" -> "minlen". switch strings.ToLower(name) { case "minlen": return ConstraintMinLen diff --git a/src/vendor/github.com/gofiber/fiber/v3/ctx.go b/src/vendor/github.com/gofiber/fiber/v3/ctx.go index 551a9d40..f0a25bdc 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/ctx.go +++ b/src/vendor/github.com/gofiber/fiber/v3/ctx.go @@ -5,6 +5,7 @@ package fiber import ( + "bytes" "context" "crypto/tls" "fmt" @@ -17,7 +18,6 @@ import ( "time" "github.com/gofiber/utils/v2" - utilsbytes "github.com/gofiber/utils/v2/bytes" "github.com/valyala/bytebufferpool" "github.com/valyala/fasthttp" ) @@ -72,8 +72,10 @@ type DefaultCtx struct { path []byte // HTTP path with the modifications by the configuration detectionPath []byte // Route detection path treePathHash int // Hash of the path for the search in the tree + pathSlashes int // Number of '/' in the detection path, used to quick-reject routes indexRoute int // Index of the current route indexHandler int // Index of the current handler + firstMatchIndex int // Pre-resolved endpoint index from the SkipUnmatchedRoutes lookahead; -1 when unused methodInt int // HTTP method INT equivalent isAbandoned atomic.Bool // If true, ctx won't be pooled until ForceRelease is called isMatched bool // Non use route matched @@ -153,31 +155,25 @@ func (c *DefaultCtx) SetContext(ctx context.Context) { } // Deadline returns the time when work done on behalf of this context -// should be canceled. Deadline returns ok==false when no deadline is -// set. Successive calls to Deadline return the same results. +// should be canceled. Ctx carries no deadline, so ok is always false. // -// Due to current limitations in how fasthttp works, Deadline operates as a nop. -// See: https://github.com/valyala/fasthttp/issues/965#issuecomment-777268945 +// Ctx satisfies context.Context as a context that can never be canceled: it is +// pooled and reused, so it cannot honor the stability and concurrency the +// interface requires. Pass Context() to anything that is cancellation-aware or +// that outlives the handler. func (*DefaultCtx) Deadline() (time.Time, bool) { return time.Time{}, false } // Done returns a channel that's closed when work done on behalf of this -// context should be canceled. Done may return nil if this context can -// never be canceled. Successive calls to Done return the same value. -// The close of the Done channel may happen asynchronously, -// after the cancel function returns. -// -// Due to current limitations in how fasthttp works, Done operates as a nop. -// See: https://github.com/valyala/fasthttp/issues/965#issuecomment-777268945 +// context should be canceled. Ctx can never be canceled, so Done always +// returns nil, which context.Context explicitly permits. See Deadline. func (*DefaultCtx) Done() <-chan struct{} { return nil } -// Err mirrors context.Err, returning nil until cancellation and then the terminal error value. -// -// Due to current limitations in how fasthttp works, Err operates as a nop. -// See: https://github.com/valyala/fasthttp/issues/965#issuecomment-777268945 +// Err returns nil until the Done channel is closed. Done is always nil here, +// so Err always returns nil. See Deadline. func (*DefaultCtx) Err() error { return nil } @@ -275,6 +271,8 @@ func (c *DefaultCtx) Next() error { // changing the request path. Note that handlers might be executed again. func (c *DefaultCtx) RestartRouting() error { c.indexRoute = -1 + // Path may have changed; invalidate the lookahead index + c.firstMatchIndex = -1 if c.handlerCtx != nil { _, err := c.app.nextCustom(c.handlerCtx) return err @@ -314,6 +312,8 @@ func (c *DefaultCtx) Path(override ...string) string { c.fasthttp.Request.URI().SetPath(c.pathOriginal) // Prettify path c.configDependentPaths() + // The detection path/tree hash changed; invalidate the lookahead index. + c.firstMatchIndex = -1 } return c.app.toString(c.path) } @@ -365,19 +365,28 @@ func (c *DefaultCtx) ViewBind(vars Map) error { // Route returns the matched Route struct. func (c *DefaultCtx) Route() *Route { if c.route == nil { - // Fallback for fasthttp error handler; equals c.Method() without - // the variadic call so Route stays within the inlining budget - return &Route{ - path: c.pathOriginal, - Path: c.pathOriginal, - Method: c.app.method(c.methodInt), - Handlers: emptyRouteHandlers[:], - Params: emptyRouteParams[:], - } + // Cold path kept out of line so Route stays within the inlining budget. + return c.routeFallback() } return c.route } +// routeFallback builds the synthetic route for the fasthttp error handler. +// Its Method field is resolved like c.Method() (including the raw-header +// fallback for unregistered methods) so Route and Method always agree. +// Never inlined: inlining it would push Route over the inlining budget. +// +//go:noinline +func (c *DefaultCtx) routeFallback() *Route { + return &Route{ + path: c.pathOriginal, + Path: c.pathOriginal, + Method: currentMethod(c), + Handlers: emptyRouteHandlers[:], + Params: emptyRouteParams[:], + } +} + // FullPath returns the matched route path, including any group prefixes. func (c *DefaultCtx) FullPath() string { return c.Route().Path @@ -453,26 +462,33 @@ func (c *DefaultCtx) OverrideParam(name, value string) { } func hasTransferEncodingBody(hdr *fasthttp.RequestHeader) bool { - teBytes := hdr.Peek(HeaderTransferEncoding) - var te string - - if len(teBytes) > 0 { - te = utils.UnsafeString(teBytes) - } else { - for key, value := range hdr.All() { - if !utils.EqualFold(utils.UnsafeString(key), HeaderTransferEncoding) { - continue + // Repeated field lines form one combined list (RFC 9110 Section 5.2), + // so every Transfer-Encoding line must be inspected, not just the first. + if lines := hdr.PeekAll(HeaderTransferEncoding); len(lines) > 0 { + for _, line := range lines { + if transferEncodingLineHasBody(utils.UnsafeString(line)) { + return true } - te = utils.UnsafeString(value) - break } + return false } - if te == "" { - return false + // Fallback scan for non-normalized header keys. + for key, value := range hdr.All() { + if !utils.EqualFold(utils.UnsafeString(key), HeaderTransferEncoding) { + continue + } + if transferEncodingLineHasBody(utils.UnsafeString(value)) { + return true + } } - hasEncoding := false + return false +} + +// transferEncodingLineHasBody reports whether a single Transfer-Encoding +// field line contains a transfer coding other than "identity". +func transferEncodingLineHasBody(te string) bool { for raw := range strings.SplitSeq(te, ",") { token := utils.TrimSpace(raw) if token == "" { @@ -487,26 +503,42 @@ func hasTransferEncodingBody(hdr *fasthttp.RequestHeader) bool { if utils.EqualFold(token, "identity") { continue } - hasEncoding = true + return true } - - return hasEncoding + return false } // IsWebSocket returns true if the request includes a WebSocket upgrade handshake. func (c *DefaultCtx) IsWebSocket() bool { - conn := c.fasthttp.Request.Header.Peek(HeaderConnection) - var isUpgrade bool - for v := range strings.SplitSeq(utils.UnsafeString(conn), ",") { - if utils.EqualFold(utils.TrimSpace(v), "upgrade") { - isUpgrade = true - break - } - } - if !isUpgrade { + // Repeated field lines are equivalent to one combined comma-separated + // list (RFC 9110 Section 5.2), so inspect every Connection and Upgrade + // field line, not just the first. + if !headerListContainsToken(c.fasthttp.Request.Header.PeekAll(HeaderConnection), "upgrade") { return false } - return utils.EqualFold(c.fasthttp.Request.Header.Peek(HeaderUpgrade), websocketBytes) + // Upgrade is a list of protocols, each optionally carrying a "/version" + // suffix (RFC 9110 Section 7.8), e.g. "Upgrade: websocket, h2c". + return headerListContainsToken(c.fasthttp.Request.Header.PeekAll(HeaderUpgrade), "websocket") +} + +// headerListContainsToken reports whether any comma-separated element across +// the given field lines equals token case-insensitively. An optional +// "/version" suffix (Upgrade protocol syntax, RFC 9110 Section 7.8) is +// ignored when comparing; valid Connection members never contain "/", so +// this is safe for both headers. +func headerListContainsToken(lines [][]byte, token string) bool { + for _, line := range lines { + for v := range strings.SplitSeq(utils.UnsafeString(line), ",") { + element := utils.TrimSpace(v) + if i := strings.IndexByte(element, '/'); i >= 0 { + element = element[:i] + } + if utils.EqualFold(element, token) { + return true + } + } + } + return false } // IsPreflight returns true if the request is a CORS preflight. @@ -633,12 +665,8 @@ func (c *DefaultCtx) Value(key any) any { return c.fasthttp.UserValue(key) } -var ( - // xmlHTTPRequestBytes is precomputed for XHR detection - xmlHTTPRequestBytes = []byte("xmlhttprequest") - // websocketBytes is precomputed for WebSocket upgrade detection - websocketBytes = []byte("websocket") -) +// xmlHTTPRequestBytes is precomputed for XHR detection +var xmlHTTPRequestBytes = []byte("xmlhttprequest") // XHR returns a Boolean property, that is true, if the request's X-Requested-With header field is XMLHttpRequest, // indicating that the request was issued by a client library (such as jQuery). @@ -657,10 +685,12 @@ func (c *DefaultCtx) configDependentPaths() { // another path is specified which is for routing recognition only // use the path that was changed by the previous configuration flags - // If CaseSensitive is disabled, we lowercase the original path - c.detectionPath = append(c.detectionPath[:0], c.path...) + // If CaseSensitive is disabled, we lowercase the original path while + // copying it, fusing the copy and the case fold into a single pass. if !c.app.config.CaseSensitive { - utilsbytes.UnsafeToLower(c.detectionPath) + c.detectionPath = appendLowerASCII(c.detectionPath[:0], c.path) + } else { + c.detectionPath = append(c.detectionPath[:0], c.path...) } // If StrictRouting is disabled, we strip all trailing slashes if !c.app.config.StrictRouting && len(c.detectionPath) > 1 && c.detectionPath[len(c.detectionPath)-1] == '/' { @@ -675,6 +705,10 @@ func (c *DefaultCtx) configDependentPaths() { int(c.detectionPath[1])<<8 | int(c.detectionPath[2]) } + + // Invalidate the cached slash count of the detection path; pathSlashCount + // recomputes it lazily when route matching first needs it. + c.pathSlashes = 0 } // Reset is a method to reset context fields by given request when to use server handlers. @@ -685,6 +719,7 @@ func (c *DefaultCtx) Reset(fctx *fasthttp.RequestCtx) { // Reset matched flag c.isMatched = false c.shouldSkipNonUseRoutes = false + c.firstMatchIndex = -1 // Set paths c.pathOriginal = c.app.toString(fctx.URI().PathOriginal()) // Set method @@ -714,6 +749,10 @@ func (c *DefaultCtx) release() { ReleaseBind(c.bind) c.bind = nil } + // Zero the whole backing array before pooling: what lives here is the previous + // request's flash data, which for WithInput is its entire form. + // parseAndClearFlashMessages clears too, since UnmarshalMsg re-slices this. + clear(c.flashMessages[:cap(c.flashMessages)]) c.flashMessages = c.flashMessages[:0] // Clear viewBindMap by deleting all keys (reuse underlying map if possible) if c.viewBindMap != nil { @@ -859,6 +898,20 @@ func (c *DefaultCtx) getTreePathHash() int { return c.treePathHash } +// pathSlashCount lazily counts the '/' bytes of the detection path and caches +// the result for the request; matching uses it to reject route candidates +// without walking their segments. app is the serving App, which can differ +// from c.app when an App value was copied. When it registers no route that +// consults the count, counting is skipped and 0 is returned — a real detection +// path always contains a '/', so 0 doubles as the "unknown" state that makes +// Route.match skip the quick-reject entirely. +func (c *DefaultCtx) pathSlashCount(app *App) int { + if c.pathSlashes == 0 && app.hasParamRoutes { + c.pathSlashes = bytes.Count(c.detectionPath, slashDelimiterBytes) + } + return c.pathSlashes +} + func (c *DefaultCtx) getDetectionPath() string { return c.app.toString(c.detectionPath) } @@ -875,6 +928,10 @@ func (c *DefaultCtx) getSkipNonUseRoutes() bool { return c.shouldSkipNonUseRoutes } +func (c *DefaultCtx) getFirstMatchIndex() int { + return c.firstMatchIndex +} + func (c *DefaultCtx) setIndexHandler(handler int) { c.indexHandler = handler } @@ -891,6 +948,10 @@ func (c *DefaultCtx) setSkipNonUseRoutes(skip bool) { c.shouldSkipNonUseRoutes = skip } +func (c *DefaultCtx) setFirstMatchIndex(index int) { + c.firstMatchIndex = index +} + func (c *DefaultCtx) setRoute(route *Route) { c.route = route } diff --git a/src/vendor/github.com/gofiber/fiber/v3/ctx_interface.go b/src/vendor/github.com/gofiber/fiber/v3/ctx_interface.go index 5f2f4e65..b812c8fc 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/ctx_interface.go +++ b/src/vendor/github.com/gofiber/fiber/v3/ctx_interface.go @@ -36,15 +36,18 @@ type CustomCtx interface { getMethodInt() int getIndexRoute() int getTreePathHash() int + pathSlashCount(app *App) int getDetectionPath() string getPathOriginal() string getValues() *[maxParams]string getMatched() bool getSkipNonUseRoutes() bool + getFirstMatchIndex() int setIndexHandler(handler int) setIndexRoute(route int) setMatched(matched bool) setSkipNonUseRoutes(skip bool) + setFirstMatchIndex(index int) setRoute(route *Route) } diff --git a/src/vendor/github.com/gofiber/fiber/v3/ctx_interface_gen.go b/src/vendor/github.com/gofiber/fiber/v3/ctx_interface_gen.go index 694a0efd..95ecded0 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/ctx_interface_gen.go +++ b/src/vendor/github.com/gofiber/fiber/v3/ctx_interface_gen.go @@ -29,25 +29,19 @@ type Ctx interface { // SetContext sets a context implementation by user. SetContext(ctx context.Context) // Deadline returns the time when work done on behalf of this context - // should be canceled. Deadline returns ok==false when no deadline is - // set. Successive calls to Deadline return the same results. + // should be canceled. Ctx carries no deadline, so ok is always false. // - // Due to current limitations in how fasthttp works, Deadline operates as a nop. - // See: https://github.com/valyala/fasthttp/issues/965#issuecomment-777268945 + // Ctx satisfies context.Context as a context that can never be canceled: it is + // pooled and reused, so it cannot honor the stability and concurrency the + // interface requires. Pass Context() to anything that is cancellation-aware or + // that outlives the handler. Deadline() (time.Time, bool) // Done returns a channel that's closed when work done on behalf of this - // context should be canceled. Done may return nil if this context can - // never be canceled. Successive calls to Done return the same value. - // The close of the Done channel may happen asynchronously, - // after the cancel function returns. - // - // Due to current limitations in how fasthttp works, Done operates as a nop. - // See: https://github.com/valyala/fasthttp/issues/965#issuecomment-777268945 + // context should be canceled. Ctx can never be canceled, so Done always + // returns nil, which context.Context explicitly permits. See Deadline. Done() <-chan struct{} - // Err mirrors context.Err, returning nil until cancellation and then the terminal error value. - // - // Due to current limitations in how fasthttp works, Err operates as a nop. - // See: https://github.com/valyala/fasthttp/issues/965#issuecomment-777268945 + // Err returns nil until the Done channel is closed. Done is always nil here, + // so Err always returns nil. See Deadline. Err() error // Request return the *fasthttp.Request object // This allows you to use all fasthttp request methods @@ -115,6 +109,11 @@ type Ctx interface { ViewBind(vars Map) error // Route returns the matched Route struct. Route() *Route + // routeFallback builds the synthetic route for the fasthttp error handler. + // Its Method field is resolved like c.Method() (including the raw-header + // fallback for unregistered methods) so Route and Method always agree. + // Never inlined: inlining it would push Route over the inlining budget. + routeFallback() *Route // FullPath returns the matched route path, including any group prefixes. FullPath() string // Matched returns true if the current request path was matched by the router. @@ -206,14 +205,24 @@ type Ctx interface { getMethodInt() int getIndexRoute() int getTreePathHash() int + // pathSlashCount lazily counts the '/' bytes of the detection path and caches + // the result for the request; matching uses it to reject route candidates + // without walking their segments. app is the serving App, which can differ + // from c.app when an App value was copied. When it registers no route that + // consults the count, counting is skipped and 0 is returned — a real detection + // path always contains a '/', so 0 doubles as the "unknown" state that makes + // Route.match skip the quick-reject entirely. + pathSlashCount(app *App) int getDetectionPath() string getValues() *[maxParams]string getMatched() bool getSkipNonUseRoutes() bool + getFirstMatchIndex() int setIndexHandler(handler int) setIndexRoute(route int) setMatched(matched bool) setSkipNonUseRoutes(skip bool) + setFirstMatchIndex(index int) setRoute(route *Route) getPathOriginal() string // FullURL returns the full request URL (protocol + host + original URL). @@ -223,8 +232,12 @@ type Ctx interface { // Referer returns the Referer request header. Referer() string // AcceptLanguage returns the Accept-Language request header. + // Repeated field lines are combined into one comma-joined list + // (RFC 9110 Section 5.2), matching what AcceptsLanguages negotiates on. AcceptLanguage() string // AcceptEncoding returns the Accept-Encoding request header. + // Repeated field lines are combined into one comma-joined list + // (RFC 9110 Section 5.2), matching what AcceptsEncodings negotiates on. AcceptEncoding() string // HasHeader reports whether the request includes a header with the given key. HasHeader(key string) bool @@ -288,10 +301,18 @@ type Ctx interface { // Make copies or use the Immutable setting instead. // When the request is a multipart form, it is parsed using the application's // BodyLimit so the configured limit is consistently enforced. + // + // On a form request this lowercases the case-insensitive parts of the request's + // own Content-Type, so a value obtained earlier from Get(HeaderContentType) — + // which aliases those bytes unless Immutable is set — can change during the + // call. Copy it first if you need it to outlive one. FormValue(key string, defaultValue ...string) string // Fresh returns true when the response is still “fresh” in the client's cache, // otherwise false is returned to indicate that the client cache is now stale // and the full response should be sent. + // Freshness only applies to GET and HEAD requests; for any other method false is + // returned, as RFC 9110 defines 304 Not Modified only for those methods and + // requires If-Modified-Since to be ignored otherwise. // When a client sends the Cache-Control: no-cache request header to indicate an end-to-end // reload request, this module will return false to make handling these requests transparent. // https://github.com/jshttp/fresh/blob/master/index.js#L33 @@ -350,6 +371,11 @@ type Ctx interface { Method(override ...string) string // MultipartForm parse form entries from binary. // This returns a map[string][]string, so given a key, the value will be a string slice. + // + // On a form request this lowercases the case-insensitive parts of the request's + // own Content-Type, so a value obtained earlier from Get(HeaderContentType) — + // which aliases those bytes unless Immutable is set — can change during the + // call. Copy it first if you need it to outlive one. MultipartForm() (*multipart.Form, error) // Params is used to get the route parameters. // Defaults to empty string "" if the param doesn't exist. @@ -409,6 +435,8 @@ type Ctx interface { getBody() []byte // Append the specified value to the HTTP response header field. // If the header is not already set, it creates the header with the specified value. + // Empty values are skipped: a sender must not generate empty list elements + // (RFC 9110 Section 5.6.1.2). Append(field string, values ...string) // Attachment sets the HTTP response Content-Disposition header field to attachment. Attachment(filename ...string) @@ -416,6 +444,11 @@ type Ctx interface { // If no key is provided it expires all cookies that came with the request. ClearCookie(key ...string) // Cookie sets a cookie by passing a cookie struct. + // + // The argument is treated as read-only: the normalization this method applies + // (default Path, SessionOnly, and the Secure implied by SameSite=None or + // Partitioned) happens on a local copy, so a caller may reuse the same *Cookie + // template across requests. Cookie(cookie *Cookie) // Download transfers the file from path as an attachment. // Typically, browsers will prompt the user for download. @@ -457,6 +490,12 @@ type Ctx interface { // JSONP sends a JSON response with JSONP support. // This method is identical to JSON, except that it opts-in to JSONP callback support. // By default, the callback name is simply callback. + // + // The callback name is reduced to a JavaScript member expression: everything + // outside [A-Za-z0-9_$.[]] is dropped. Callers routinely take the name straight + // from the query string, which is what JSONP is for, and the name lands + // verbatim in a same-origin text/javascript body — so an unfiltered one would + // let a request supply arbitrary script for the app's own origin. JSONP(data any, callback ...string) error // XML converts any interface or string to XML. // This method also sets the content header to application/xml; charset=utf-8. @@ -509,6 +548,8 @@ type Ctx interface { Type(extension string, charset ...string) Ctx // Vary adds the given header field to the Vary response header. // This will append the header, if not already listed; otherwise, leaves it listed in the current location. + // Per RFC 9110 Section 12.5.5 the wildcard "*" only has meaning as the sole member of the field: + // once "*" is added (or already present), the header is collapsed to a single "*". Vary(fields ...string) // Write appends p into response body. Write(p []byte) (int, error) diff --git a/src/vendor/github.com/gofiber/fiber/v3/error.go b/src/vendor/github.com/gofiber/fiber/v3/error.go index 327771cd..3060104c 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/error.go +++ b/src/vendor/github.com/gofiber/fiber/v3/error.go @@ -22,6 +22,11 @@ var ( ErrNoViewEngineConfigured = errors.New("fiber: no view engine configured") // ErrAutoCertWithCertFile indicates AutoCertManager cannot be used with CertFile/CertKeyFile. ErrAutoCertWithCertFile = errors.New("tls: AutoCertManager cannot be combined with CertFile/CertKeyFile") + // ErrRouteNotRepresentable indicates a route whose path no relative URL can + // name, so Route.URL, GetRouteURL and Redirect().Route cannot compose one. + // A path starting with two or more slashes is such a route: the URL that + // would reach it opens an authority instead. + ErrRouteNotRepresentable = errors.New("router: route path cannot be expressed as a relative URL") ) // Fiber redirection errors @@ -31,11 +36,20 @@ var ( // Range errors var ( - ErrRangeMalformed = errors.New("range: malformed range header string") + // ErrRangeMalformed is returned for a syntactically invalid Range header, + // which RFC 9110 Section 14.2 allows a server to reject; it carries a + // 400 Bad Request status so propagating it does not surface as a 500. + ErrRangeMalformed = NewError(StatusBadRequest, "range: malformed range header string") + // ErrRangeUnsupported is returned for a Range header whose range unit is + // not "bytes". RFC 9110 Section 14.2 requires an origin server to IGNORE + // a Range header field with a range unit it does not understand, so + // callers receiving this error should serve the full representation + // instead of returning an error response. It still carries a + // 400 Bad Request status as a safety net, so blind propagation does not + // surface as a 500. + ErrRangeUnsupported = NewError(StatusBadRequest, "range: unsupported range unit") ErrRangeTooLarge = NewError(StatusRequestedRangeNotSatisfiable, "range: too many ranges") ErrRangeUnsatisfiable = errors.New("range: unsatisfiable range") - // errRangeBound: empty/non-numeric range bound; control-flow only, never surfaced. - errRangeBound = errors.New("range: bound not parsable") ) // Binder errors diff --git a/src/vendor/github.com/gofiber/fiber/v3/helpers.go b/src/vendor/github.com/gofiber/fiber/v3/helpers.go index d8a1b76e..654535f8 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/helpers.go +++ b/src/vendor/github.com/gofiber/fiber/v3/helpers.go @@ -24,8 +24,12 @@ import ( "github.com/gofiber/utils/v2" utilsbytes "github.com/gofiber/utils/v2/bytes" + utilsstrings "github.com/gofiber/utils/v2/strings" + "github.com/gofiber/utils/v2/swar" + "github.com/gofiber/fiber/v3/binder" "github.com/gofiber/fiber/v3/internal/contextvalue" + "github.com/gofiber/fiber/v3/internal/mediatype" "github.com/gofiber/fiber/v3/log" "github.com/valyala/bytebufferpool" @@ -165,24 +169,65 @@ func readContent(rf io.ReaderFrom, name string) (int64, error) { return n, nil } -// quoteString escapes special characters using percent-encoding. -// Non-ASCII bytes are encoded as well so the result is always ASCII. -func (app *App) quoteString(raw string) string { - bb := bytebufferpool.Get() - quoted := string(fasthttp.AppendQuotedArg(bb.B, app.toBytes(raw))) - bytebufferpool.Put(bb) - return quoted +// quoteEscapeMask marks the lanes of w holding bytes quoteRawString must +// escape: '\\', '"', any C0 control (including HTAB), or DEL. Lanes >= 0x80 +// are never marked; non-ASCII bytes pass through verbatim. This is +// utils.IndexNonQuotable's RFC 9110 set widened by HTAB, which the RFC +// permits as qdtext but this function has always percent-encoded. +func quoteEscapeMask(w uint64) uint64 { + return swar.MatchByteMask(w, '\\') | swar.MatchByteMask(w, '"') | + swar.MatchRangeMask(w, 0x00, 0x1f) | swar.MatchByteMask(w, 0x7f) +} + +// indexQuoteEscape returns the index of the first byte quoteEscapeMask +// matches, or -1 if raw needs no escaping. It scans eight bytes at a time, +// finishing inputs of 8+ bytes with one overlapping word; shorter inputs +// are checked byte-wise. +func indexQuoteEscape(raw string) int { + n := len(raw) + i := 0 + for ; i+swar.WordLen <= n; i += swar.WordLen { + if m := quoteEscapeMask(swar.Load8(raw, i)); m != 0 { + return i + swar.FirstLane(m) + } + } + if i == n { + return -1 + } + if n >= swar.WordLen { + if m := quoteEscapeMask(swar.Load8(raw, n-swar.WordLen)); m != 0 { + return n - swar.WordLen + swar.FirstLane(m) + } + return -1 + } + for ; i < n; i++ { + if c := raw[i]; c == '\\' || c == '"' || c < 0x20 || c == 0x7f { + return i + } + } + return -1 } -// quoteRawString escapes only characters that need quoting according to -// https://www.rfc-editor.org/rfc/rfc9110#section-5.6.4 so the result may -// contain non-ASCII bytes. +// quoteRawString escapes the characters that need quoting inside an RFC 9110 +// quoted-string (https://www.rfc-editor.org/rfc/rfc9110#section-5.6.4), plus +// HTAB, which the RFC permits as qdtext but this function has always +// percent-encoded. The result may contain non-ASCII bytes. func (*App) quoteRawString(raw string) string { + // Fast path: most values need no escaping at all; avoid the pooled + // buffer and the string allocation entirely. + end := indexQuoteEscape(raw) + if end == -1 { + return raw + } + const hex = "0123456789ABCDEF" bb := bytebufferpool.Get() defer bytebufferpool.Put(bb) - for i := 0; i < len(raw); i++ { + // Every byte before end is quotable and tab-free, so it hits the + // verbatim case of the switch below; copy it in one append. + bb.B = append(bb.B, raw[:end]...) + for i := end; i < len(raw); i++ { c := raw[i] switch { case c == '\\' || c == '"': @@ -208,15 +253,36 @@ func (*App) quoteRawString(raw string) string { return string(bb.B) } -// isASCII reports whether the provided string contains only ASCII characters. -// See: https://www.rfc-editor.org/rfc/rfc0020 -func (*App) isASCII(s string) bool { - for i := 0; i < len(s); i++ { - if s[i] > 127 { - return false +// appendLowerASCII writes the ASCII-lowercased bytes of src into dst[:0], +// growing dst as needed, in a single pass over src (instead of a copy +// followed by an in-place case fold). Bytes outside 'A'..'Z', including +// non-ASCII, are copied unchanged. src and dst must not overlap. +func appendLowerASCII(dst, src []byte) []byte { + n := len(src) + // Amortized growth like append: every byte of dst[:n] is overwritten + // below, so the grown slice's contents don't matter. + dst = slices.Grow(dst[:0], n)[:n] + i := 0 + for ; i+swar.WordLen <= n; i += swar.WordLen { + swar.Store8(dst, i, swar.ToLowerWord(swar.Load8(src, i))) + } + if i == n { + return dst + } + if n >= swar.WordLen { + // Finish with one overlapping word; the overlapped bytes are + // rewritten with the same values. + swar.Store8(dst, n-swar.WordLen, swar.ToLowerWord(swar.Load8(src, n-swar.WordLen))) + return dst + } + for ; i < n; i++ { + c := src[i] + if c-'A' <= 'Z'-'A' { + c |= 0x20 } + dst[i] = c } - return true + return dst } // defaultString returns the value or a default value if it is set @@ -239,19 +305,43 @@ func getGroupPath(prefix, path string) string { return utils.TrimRight(prefix, '/') + path } +// Match specificity levels returned by the acceptsX helpers. A higher value +// means the range matched the offer more specifically. They only need to be +// ordered consistently within a single helper (each getOffer call uses one +// helper), so an explicit q=0 rejection can override a positive match of the +// same or lower specificity per RFC 9110 §12.5.1. +const ( + matchWildcard = 1 // "*" / trailing-"*" prefix / language "*" + matchPrefix = 2 // language subtag prefix, e.g. "en" matching "en-US" + matchExact = 3 // exact, case-insensitive match + + // Media ranges rank by their coarse class first and by the number of + // matched media-type parameters second, so "text/html;level=1" outranks + // "text/html", which outranks "text/*", which outranks "*/*". + matchMediaAny = 1 // "*/*" + matchMediaTypeAny = 2 // "type/*" + matchMediaTypeSubtype = 3 // "type/subtype" + mediaSpecificityScale = 100 +) + // acceptsOffer determines if an offer matches a given specification. // It supports a trailing '*' wildcard and performs case-insensitive exact matching. -// Returns true if the offer matches the specification, false otherwise. -func acceptsOffer(spec, offer string, _ headerParams) bool { +// It returns the match specificity (0 = no match, higher = more specific): a +// wildcard/prefix match is less specific than an exact match. The specificity is +// used to let an explicit q=0 rejection override a less specific positive match +// of the same coarse class (RFC 9110 §12.5.1). +func acceptsOffer(spec, offer string, _ headerParams) int { if len(spec) >= 1 && spec[len(spec)-1] == '*' { - prefix := spec[:len(spec)-1] - if len(offer) < len(prefix) { - return false + if utils.HasPrefixFold(offer, spec[:len(spec)-1]) { + return matchWildcard } - return utils.EqualFold(prefix, offer[:len(prefix)]) + return 0 } - return utils.EqualFold(spec, offer) + if utils.EqualFold(spec, offer) { + return matchExact + } + return 0 } // acceptsLanguageOfferBasic determines if a language tag offer matches a range @@ -260,19 +350,25 @@ func acceptsOffer(spec, offer string, _ headerParams) bool { // followed by a hyphen. The comparison is case-insensitive. Only a single "*" // as the entire range is allowed. Any "*" appearing after a hyphen renders the // range invalid and will not match. -func acceptsLanguageOfferBasic(spec, offer string, _ headerParams) bool { +// It returns the match specificity (0 = no match): "*" is least specific, a +// prefix match ("en" for "en-US") is more specific, and an exact match is most +// specific — so an explicit "en-US;q=0" can override a positive "en". +func acceptsLanguageOfferBasic(spec, offer string, _ headerParams) int { if spec == "*" { - return true + return matchWildcard } if strings.IndexByte(spec, '*') >= 0 { - return false + return 0 } if utils.EqualFold(spec, offer) { - return true + return matchExact + } + if len(offer) > len(spec) && + utils.HasPrefixFold(offer, spec) && + offer[len(spec)] == '-' { + return matchPrefix } - return len(offer) > len(spec) && - utils.EqualFold(offer[:len(spec)], spec) && - offer[len(spec)] == '-' + return 0 } // acceptsLanguageOfferExtended determines if a language tag offer matches a @@ -281,12 +377,16 @@ func acceptsLanguageOfferBasic(spec, offer string, _ headerParams) bool { // - '*' matches zero or more subtags (can "slide") // - Unspecified subtags are treated like '*' (so trailing/extraneous tag subtags are fine) // - Matching fails if sliding encounters a singleton (incl. 'x') -func acceptsLanguageOfferExtended(spec, offer string, _ headerParams) bool { +// It returns the match specificity (0 = no match): a bare "*" is least specific, +// and otherwise the specificity grows with the number of concrete range subtags +// that had to match, so a deeper range (e.g. "en-US") outranks a shorter one +// ("en") and an explicit "en-US;q=0" can override a positive "en". +func acceptsLanguageOfferExtended(spec, offer string, _ headerParams) int { if spec == "*" { - return true + return matchWildcard } if spec == "" || offer == "" { - return false + return 0 } // Use stack-allocated arrays to avoid heap allocations for typical language tags @@ -305,7 +405,7 @@ func acceptsLanguageOfferExtended(spec, offer string, _ headerParams) bool { // Step 2: first subtag must match (or be '*') if rs[0] != "*" && !utils.EqualFold(rs[0], ts[0]) { - return false + return 0 } i, j := 1, 1 // i = range index, j = tag index @@ -315,7 +415,7 @@ func acceptsLanguageOfferExtended(spec, offer string, _ headerParams) bool { continue } if j >= len(ts) { // 3.B: ran out of tag subtags - return false + return 0 } if utils.EqualFold(rs[i], ts[j]) { // 3.C: exact subtag match i++ @@ -324,13 +424,21 @@ func acceptsLanguageOfferExtended(spec, offer string, _ headerParams) bool { } // 3.D: singleton barrier (one letter or digit, incl. 'x') if len(ts[j]) == 1 { - return false + return 0 } // 3.E: slide forward in the tag and try again j++ } - // 4: matched all range subtags - return true + + // 4: matched all range subtags. Rank by the number of concrete (non-"*") + // range subtags so a more specific range wins the specificity comparison. + specificity := matchWildcard + for _, sub := range rs { + if sub != "*" { + specificity++ + } + } + return specificity } // acceptsOfferType This function determines if an offer type matches a given specification. @@ -338,8 +446,11 @@ func acceptsLanguageOfferExtended(spec, offer string, _ headerParams) bool { // It gets the MIME type of the offer (either from the offer itself or by its file extension). // It checks if the offer MIME type matches the specification MIME type or if the specification is of the form /* and the offer MIME type has the same MIME type. // It checks if the offer contains every parameter present in the specification. -// Returns true if the offer type matches the specification, false otherwise. -func acceptsOfferType(spec, offerType string, specParams headerParams) bool { +// It returns the match specificity (0 = no match): "*/*" is least specific, +// then "type/*", then "type/subtype", and matched media-type parameters break +// ties so "text/html;level=1" outranks "text/html" (letting "text/html;level=1;q=0" +// override a positive "text/html"). +func acceptsOfferType(spec, offerType string, specParams headerParams) int { var offerMime, offerParams string if i := strings.IndexByte(offerType, ';'); i == -1 { @@ -351,7 +462,7 @@ func acceptsOfferType(spec, offerType string, specParams headerParams) bool { // Accept: */* if spec == "*/*" { - return paramsMatch(specParams, offerParams) + return mediaMatchSpecificity(matchMediaAny, specParams, offerParams) } var mimetype string @@ -361,9 +472,9 @@ func acceptsOfferType(spec, offerType string, specParams headerParams) bool { mimetype = utils.GetMIME(offerMime) // extension } - if spec == mimetype { + if utils.EqualFold(spec, mimetype) { // Accept: / - return paramsMatch(specParams, offerParams) + return mediaMatchSpecificity(matchMediaTypeSubtype, specParams, offerParams) } s := strings.IndexByte(mimetype, '/') @@ -371,11 +482,21 @@ func acceptsOfferType(spec, offerType string, specParams headerParams) bool { // Accept: /* if s != -1 && specSlash != -1 { if utils.EqualFold(spec[:specSlash], mimetype[:s]) && (spec[specSlash:] == "/*" || mimetype[s:] == "/*") { - return paramsMatch(specParams, offerParams) + return mediaMatchSpecificity(matchMediaTypeAny, specParams, offerParams) } } - return false + return 0 +} + +// mediaMatchSpecificity returns the specificity of a media range that matched an +// offer's type/subtype, or 0 when the media-type parameters don't match. The +// coarse class dominates; the count of matched parameters breaks ties. +func mediaMatchSpecificity(base int, specParams headerParams, offerParams string) int { + if !paramsMatch(specParams, offerParams) { + return 0 + } + return base*mediaSpecificityScale + len(specParams) } // paramsMatch returns whether offerParams contains all parameters present in specParams. @@ -421,6 +542,9 @@ func paramsMatch(specParamStr headerParams, offerParams string) bool { // elements divided by ',' and stores these elements in the string slice. // It returns the populated string slice as an output. // +// Empty list elements are parsed and ignored, as required by +// RFC 9110 Section 5.6.1.2 for all comma-separated field values. +// // If the given slice hasn't enough space, it will allocate more and return. func getSplicedStrList(headerValue string, dst []string) []string { if headerValue == "" { @@ -431,11 +555,15 @@ func getSplicedStrList(headerValue string, dst []string) []string { segmentStart := 0 for i := 0; i < len(headerValue); i++ { if headerValue[i] == ',' { - dst = append(dst, utils.TrimSpace(headerValue[segmentStart:i])) + if segment := utils.TrimSpace(headerValue[segmentStart:i]); segment != "" { + dst = append(dst, segment) + } segmentStart = i + 1 } } - dst = append(dst, utils.TrimSpace(headerValue[segmentStart:])) + if segment := utils.TrimSpace(headerValue[segmentStart:]); segment != "" { + dst = append(dst, segment) + } return dst } @@ -451,6 +579,64 @@ func joinHeaderValues(headers [][]byte) []byte { } } +// joinedHeaderValue accumulates the combined value of a header's field lines +// (RFC 9110 Section 5.2). It allocates only in the rare multi-line case; the +// single-line result aliases the header storage. +type joinedHeaderValue struct { + key string + combined []byte + multi bool +} + +func (j *joinedHeaderValue) visit(k, v []byte) { + if len(k) != len(j.key) || !utils.EqualFold(utils.UnsafeString(k), j.key) { + return + } + switch { + case j.combined == nil: + j.combined = v + case !j.multi: + joined := make([]byte, 0, len(j.combined)+1+len(v)) + joined = append(joined, j.combined...) + joined = append(joined, ',') + joined = append(joined, v...) + j.combined = joined + j.multi = true + default: + j.combined = append(j.combined, ',') + j.combined = append(j.combined, v...) + } +} + +// peekJoinedRequestHeader returns the combined value of every field line for +// key in a single pass over the request headers. Unlike PeekAll it performs no +// per-call key normalization. Concrete (non-generic) so the visitor stays on +// the stack. +func peekJoinedRequestHeader(h *fasthttp.RequestHeader, key string) []byte { + j := joinedHeaderValue{key: key} + // VisitAll (not the replacement All) keeps this zero-alloc: All returns + // an iterator closure that escapes to the heap on every call. The SA1019 + // deprecation is suppressed for helpers.go in .golangci.yml. + // + // VisitAllInOrder is deliberately not used: it reparses rawHeaders, which + // only holds headers read off the wire, so headers set programmatically + // (e.g. by net/http adaptors) would be missed entirely. VisitAll already + // preserves the relative order of repeated field lines sharing a key, + // which is all this helper needs; it only reorders across distinct keys. + h.VisitAll(j.visit) + return j.combined +} + +// peekJoinedResponseHeader is peekJoinedRequestHeader for response headers. +func peekJoinedResponseHeader(h *fasthttp.ResponseHeader, key string) ([]byte, bool) { + j := joinedHeaderValue{key: key} + // VisitAll (not the replacement All) keeps this zero-alloc: All returns + // an iterator closure that escapes to the heap on every call. The SA1019 + // deprecation is suppressed for helpers.go in .golangci.yml. + h.VisitAll(j.visit) + return j.combined, j.multi +} + func unescapeHeaderValue(v []byte) ([]byte, error) { if bytes.IndexByte(v, '\\') == -1 { return v, nil @@ -489,27 +675,33 @@ func forEachMediaRange(header []byte, functor func([]byte)) { n := 0 header = utils.TrimLeft(header, ' ') quotes := 0 - escaping := false if hasDQuote { // Complex case. We need to keep track of quotes and quoted-pairs (i.e., characters escaped with \ ) + // Only ',', '"' and '\\' can change state, so jump between them + // instead of visiting every byte. loop: for n < len(header) { + i := utils.IndexAny3(header[n:], ',', '"', '\\') + if i == -1 { + n = len(header) + break + } + n += i switch header[n] { case ',': if quotes%2 == 0 { break loop } case '"': - if !escaping { - quotes++ + quotes++ + default: // '\\' + if quotes%2 == 1 && n+1 < len(header) { + // A quoted-pair escapes exactly the next byte + // (RFC 9110 §5.6.4); consume it so an escaped + // quote is not mistaken for a closing quote. + n++ } - case '\\': - if quotes%2 == 1 { - escaping = !escaping - } - default: - // all other characters are ignored } n++ } @@ -538,7 +730,7 @@ var headerParamPool = sync.Pool{ } // getOffer return valid offer for header negotiation. -func getOffer(header []byte, isAccepted func(spec, offer string, specParams headerParams) bool, offers ...string) string { +func getOffer(header []byte, isAccepted func(spec, offer string, specParams headerParams) int, offers ...string) string { if len(offers) == 0 { return "" } @@ -548,6 +740,9 @@ func getOffer(header []byte, isAccepted func(spec, offer string, specParams head acceptedTypes := make([]acceptedType, 0, 8) order := 0 + // Whether any range carries an explicit q=0 rejection. When none do, the + // more-specific-rejection scan can be skipped entirely on the hot path. + hasRejections := false // Parse header and get accepted types with their quality and specificity // See: https://www.rfc-editor.org/rfc/rfc9110#name-content-negotiation-fields @@ -562,7 +757,12 @@ func getOffer(header []byte, isAccepted func(spec, offer string, specParams head // Optimized quality parsing qIndex := i + 3 if bytes.HasPrefix(accept[i:], semicolonQEquals) && bytes.IndexByte(accept[qIndex:], ';') == -1 { - if q, err := fasthttp.ParseUfloat(accept[qIndex:]); err == nil { + // A list element may be followed by optional whitespace before + // the comma (RFC 9110 §5.6.1.2), and forEachMediaRange only + // trims the leading side. Trim the trailing side here so the + // weight still parses; otherwise the error below is swallowed + // and an explicit q=0 rejection silently becomes q=1. + if q, err := fasthttp.ParseUfloat(utils.TrimSpace(accept[qIndex:])); err == nil { quality = q } } else { @@ -571,7 +771,9 @@ func getOffer(header []byte, isAccepted func(spec, offer string, specParams head delete(params, k) } fasthttp.VisitHeaderParams(accept[i:], func(key, value []byte) bool { - if len(key) == 1 && key[0] == 'q' { + // The weight parameter name "q" is case-insensitive + // (RFC 9110 §12.4.2). + if len(key) == 1 && (key[0] == 'q' || key[0] == 'Q') { if q, err := fasthttp.ParseUfloat(value); err == nil { quality = q } @@ -586,12 +788,6 @@ func getOffer(header []byte, isAccepted func(spec, offer string, specParams head return true }) } - - // Skip this accept type if quality is 0.0 - // See: https://www.rfc-editor.org/rfc/rfc9110#quality.values - if quality == 0.0 { - return - } } spec = utils.TrimSpace(spec) @@ -613,6 +809,10 @@ func getOffer(header []byte, isAccepted func(spec, offer string, specParams head specificity = 4 } + if quality == 0 { + hasRejections = true + } + // Add to accepted types acceptedTypes = append(acceptedTypes, acceptedType{ spec: utils.UnsafeString(spec), @@ -628,25 +828,78 @@ func getOffer(header []byte, isAccepted func(spec, offer string, specParams head sortAcceptedTypes(acceptedTypes) } - // Find the first offer that matches the accepted types - for _, acceptedType := range acceptedTypes { - for _, offer := range offers { - if offer == "" { + // Find the best offer that matches the accepted types. + // + // Per RFC 9110 §12.5.1 the most specific matching media range determines an + // offer's acceptability, and a quality of 0 means the client explicitly + // rejects that range. An offer is therefore only acceptable if its most + // specific matching range has a quality greater than 0 — a broader range + // with a higher quality (e.g. "*" or "text/*") must not override a more + // specific q=0 rejection. + // See: https://www.rfc-editor.org/rfc/rfc9110#section-12.5.1 + result := "" + if !hasRejections { + // Fast path: without any q=0 rejection this is the plain "first matching + // range in preference order wins" selection, identical to the algorithm + // before q=0 handling, so there is no need to compute or compare match + // specificity. + selectFast: + for _, acceptedType := range acceptedTypes { + for _, offer := range offers { + if offer != "" && isAccepted(acceptedType.spec, offer, acceptedType.params) > 0 { + result = offer + break selectFast + } + } + } + } else { + // Rejection-aware path: an offer is only acceptable if its matching range + // is not overridden by a q=0 range that matches it at least as + // specifically (RFC 9110 §12.5.1). + selectWithRejections: + for _, acceptedType := range acceptedTypes { + if acceptedType.quality == 0 { + // A q=0 range never selects an offer; it can only reject one. continue } - if isAccepted(acceptedType.spec, offer, acceptedType.params) { - if acceptedType.params != nil { - headerParamPool.Put(acceptedType.params) + for _, offer := range offers { + if offer == "" { + continue + } + matchSpecificity := isAccepted(acceptedType.spec, offer, acceptedType.params) + if matchSpecificity > 0 && + !rejectedByMoreSpecificRange(acceptedTypes, isAccepted, offer, matchSpecificity) { + result = offer + break selectWithRejections } - return offer } } - if acceptedType.params != nil { - headerParamPool.Put(acceptedType.params) + } + + for i := range acceptedTypes { + if acceptedTypes[i].params != nil { + headerParamPool.Put(acceptedTypes[i].params) } } - return "" + return result +} + +// rejectedByMoreSpecificRange reports whether a q=0 range matches the offer at +// least as specifically as the positive match at baseSpecificity, i.e. the +// client explicitly rejected the offer per RFC 9110 §12.5.1. Comparing the +// effective match specificity (rather than the coarse parsed bucket) lets a +// same-class rejection win — e.g. "en-US;q=0" over "en", "utf-8;q=0" over an +// earlier "utf-8", or "text/html;level=1;q=0" over "text/html" — while a less +// specific rejection such as "text/*;q=0" still does not override "text/html". +func rejectedByMoreSpecificRange(types []acceptedType, isAccepted func(spec, offer string, specParams headerParams) int, offer string, baseSpecificity int) bool { + for i := range types { + if types[i].quality == 0 && + isAccepted(types[i].spec, offer, types[i].params) >= baseSpecificity { + return true + } + } + return false } // sortAcceptedTypes sorts accepted types by quality and specificity, preserving order of equal elements @@ -717,7 +970,6 @@ func matchEtagStrong(s, etag string) bool { // stale when presented with the raw If-None-Match header value. Comparison is // weak as defined by RFC 9110 §8.8.3.2. func (app *App) isEtagStale(etag string, noneMatchBytes []byte) bool { - var start, end int header := utils.TrimSpace(app.toString(noneMatchBytes)) // Short-circuit the wildcard case: "*" never counts as stale. @@ -725,27 +977,31 @@ func (app *App) isEtagStale(etag string, noneMatchBytes []byte) bool { return false } - // Adapted from: - // https://github.com/jshttp/fresh/blob/master/index.js#L110 - for i := range noneMatchBytes { - switch noneMatchBytes[i] { - case 0x20: - if start == end { - start = i + 1 - end = i + 1 - } - case 0x2c: - if matchEtag(app.toString(noneMatchBytes[start:end]), etag) { + // Split the header on commas that sit outside DQUOTE-delimited opaque-tags: + // etagc permits "," inside the quoted tag (RFC 9110 §8.8.3), so `"v1,v2"` + // is a single entity tag, not two list elements. Only '"' and ',' + // affect the split, so jump between them instead of visiting every byte. + start := 0 + pos := 0 + inQuotes := false + for { + i := utils.IndexAny2(header[pos:], '"', ',') + if i == -1 { + break + } + i += pos + pos = i + 1 + if header[i] == '"' { + inQuotes = !inQuotes + } else if !inQuotes { + if matchEtag(utils.TrimSpace(header[start:i]), etag) { return false } start = i + 1 - end = i + 1 - default: - end = i + 1 } } - return !matchEtag(app.toString(noneMatchBytes[start:end]), etag) + return !matchEtag(utils.TrimSpace(header[start:]), etag) } func parseAddr(raw string) (host, port string) { //nolint:nonamedreturns // gocritic unnamedResult requires naming host and port parts for clarity @@ -894,10 +1150,6 @@ func toStringImmutable(b []byte) string { return string(b) } -func toBytesImmutable(s string) []byte { - return []byte(s) -} - // HTTP methods and their unique INTs func (app *App) methodInt(s string) int { // For better performance @@ -932,6 +1184,12 @@ func (app *App) methodInt(s string) int { } func (app *App) method(methodInt int) string { + // methodInt is -1 for methods not registered in RequestMethods (the + // router responds 501 before dispatch, but contexts acquired directly + // via AcquireCtx can still carry one); never index with it. + if methodInt < 0 || methodInt >= len(app.config.RequestMethods) { + return "" + } return app.config.RequestMethods[methodInt] } @@ -1111,3 +1369,18 @@ type GenericTypeIntegerUnsigned interface { type GenericTypeFloat interface { float32 | float64 } + +// bindMediaType returns the request's media type, lowered for comparison against +// the MIME constants. The request's own bytes are folded only for a form, the +// one case needing it in place; anything else is compared on a copy. +func bindMediaType(h *fasthttp.RequestHeader) string { + if mediatype.IsForm(h.ContentType()) { + raw := utils.UnsafeString(mediatype.NormalizeRequestContentType(h)) + return binder.FilterFlags(utils.ParseVendorSpecificContentType(raw)) + } + + // ToLower returns its input unchanged when there is nothing to fold, so the + // common path costs no allocation. + lowered := utilsstrings.ToLower(utils.UnsafeString(h.ContentType())) + return binder.FilterFlags(utils.ParseVendorSpecificContentType(lowered)) +} diff --git a/src/vendor/github.com/gofiber/fiber/v3/internal/fieldname/fieldname.go b/src/vendor/github.com/gofiber/fiber/v3/internal/fieldname/fieldname.go new file mode 100644 index 00000000..e5d80cc0 --- /dev/null +++ b/src/vendor/github.com/gofiber/fiber/v3/internal/fieldname/fieldname.go @@ -0,0 +1,228 @@ +// Package fieldname reads and removes HTTP header fields by name +// case-insensitively (RFC 9110 §5.1). +// +// fasthttp's Peek, PeekAll and Del are byte-exact, which finds every line only +// while it canonicalizes the key; under DisableHeaderNormalizing the store keeps +// the spelling the peer sent, which for HTTP/2 and 3 is lower case. +// +// canonical says whether the caller knows the keys to be canonical — fasthttp +// keeps that private, so it is passed in; see headerlookup.Canonical. +package fieldname + +import ( + "iter" + + "github.com/gofiber/utils/v2" + "github.com/valyala/fasthttp" +) + +// Peeker is the part of fasthttp's headers needed to read field lines by name. +type Peeker interface { + Peek(key string) []byte + PeekAll(key string) [][]byte + All() iter.Seq2[[]byte, []byte] + // VisitAll is deprecated in fasthttp in favor of All, but All builds an + // iterator per call while this walks the store directly. Kept for the reads + // that run per request and do not need to stop early. + VisitAll(f func(key, value []byte)) +} + +// Deleter is the part of fasthttp's headers needed to remove a field by name. +type Deleter interface { + Del(key string) + PeekAll(key string) [][]byte + All() iter.Seq2[[]byte, []byte] +} + +// Lines returns every field line stored under name. The walk replaces the +// byte-exact lookup rather than backing it up: a message can carry both +// spellings, and an empty canonical line would hide the value beside it. +// +//nolint:revive // flag-parameter: canonical is a property of the header store, not a mode of operation +func Lines(h Peeker, name string, canonical bool) [][]byte { + if canonical { + // PeekAll hands back the header's own slice without allocating. + return h.PeekAll(name) + } + + // Walked rather than ranged: this runs per key header on every cacheable + // request, and All's iterator costs more than the match itself does. + var values [][]byte + h.VisitAll(func(k, v []byte) { + if utils.EqualFold(utils.UnsafeString(k), name) { + values = append(values, v) + } + }) + return values +} + +// First returns the first field line stored under name that holds anything, or +// nil if there is none. The names fasthttp keeps in a slot of their own are +// unaffected either way: every spelling is routed into the slot on the way in. +// +// Empty lines are stepped over rather than answered with, because a message can +// carry the name more than once and Peek reports the first line whether or not +// it holds a value: an empty "Cache-Control:" ahead of "Cache-Control: private" +// read as a response saying nothing about caching. A field line that is present +// and empty says nothing a caller can act on, so nothing is lost by looking past +// it for one that does. +// +// Repetition itself is left to the caller to judge, because what it means +// depends on the field: a response may carry Cache-Control twice and mean the +// list, while a second Origin or Authorization line is malformed and cannot be +// resolved by picking one. headerlookup.Value refuses that case for the request +// fields where it arises. +// +//nolint:revive // flag-parameter: canonical is a property of the header store +func First(h Peeker, name string, canonical bool) []byte { + if canonical { + v := h.Peek(name) + if len(v) > 0 { + return v + } + if v == nil { + // Nothing is stored under the name, so there is nothing beside it + // to find and the walk below is skipped: a nil answer means absent, + // a non-nil empty one means a line that is present and empty. That + // distinction is fasthttp's to keep, so Test_First_EmptyLineIsNotNil + // pins it — if it ever stops holding, that test says so rather than + // this quietly reverting to reading only the first line. + return nil + } + + // Reached only for a field that is present and empty, which is the shape + // being guarded against rather than one anything sends by accident. + // PeekAll costs no allocation and resolves the slotted names. + for _, v := range h.PeekAll(name) { + if len(v) > 0 { + return v + } + } + return nil + } + + // Split out rather than written below: All's iterator is heap-allocated + // where the compiler cannot see the branch is dead, so holding it in this + // function cost the canonical path an allocation it never used. + return firstFold(h, name) +} + +// firstFold answers First for a store whose field names are spelled however the +// peer sent them. +func firstFold(h Peeker, name string) []byte { + for k, v := range h.All() { + if len(v) > 0 && utils.EqualFold(utils.UnsafeString(k), name) { + return v + } + } + return nil +} + +// Canonical reports whether every field name in h is spelled the way fasthttp +// normalizes it, so the byte-exact Peek and Del find them all. +// +// Ask this of a response rather than reading the app config: a proxied response +// is parsed by an outbound fasthttp.Client carrying its own normalizing setting, +// so a default-normalizing app can hold a response of lower-case names. It is +// one walk, against one per field for the case-insensitive reads it saves. +func Canonical(h *fasthttp.ResponseHeader) bool { + canonical := true + //nolint:staticcheck // All allocates an iterator per call; this runs per response + h.VisitAll(func(k, _ []byte) { + if canonical && !isCanonicalName(k) { + canonical = false + } + }) + return canonical +} + +// isCanonicalName reports whether name is upper case at the start of each +// "-"-separated token and lower case everywhere else, which is what fasthttp's +// normalization produces. +func isCanonicalName(name []byte) bool { + upper := true + for _, c := range name { + if upper { + if c >= 'a' && c <= 'z' { + return false + } + } else if c >= 'A' && c <= 'Z' { + return false + } + upper = c == '-' + } + return true +} + +// Del removes every field line named name, whatever case it is stored under. +// +//nolint:revive // flag-parameter: canonical is a property of the header store +func Del(h Deleter, name string, canonical bool) { + h.Del(name) + if canonical { + // The scan below would only confirm Del found everything, at the cost + // of an iterator allocation per name on an otherwise alloc-free path. + return + } + + // Restart after each removal rather than deleting while ranging over the + // store being modified. A field arrives under one spelling essentially + // always, so this repeats only for a peer that sent several. + for { + other := "" + for k := range h.All() { + if utils.EqualFold(utils.UnsafeString(k), name) { + other = string(k) + break + } + } + if other == "" { + return + } + h.Del(other) + } +} + +// DelOthers removes every stored spelling of name except name itself, which the +// caller is about to write or delete under that key. Every other one, not just +// the first: stopping early leaves the rest beside the value the caller writes. +func DelOthers(h Deleter, name string) { + // Collected before deleting: removing while ranging over the store is not safe. + var others []string + for k := range h.All() { + if ks := utils.UnsafeString(k); ks != name && utils.EqualFold(ks, name) { + others = append(others, string(k)) + } + } + + for _, k := range others { + h.Del(k) + } +} + +// DelSet removes every field line matching any of names in a single pass, which +// beats Del's per-name scan when the whole set is known up front. +func DelSet(h Deleter, names []string) { + var removed []string + for k := range h.All() { + if ContainsFold(names, utils.UnsafeString(k)) { + removed = append(removed, string(k)) + } + } + + // A repeated name is deleted twice; Del removes every line at once, so + // scanning to avoid that costs more than making the call. + for _, name := range removed { + h.Del(name) + } +} + +// ContainsFold reports whether needle equals any of haystack, case-insensitively. +func ContainsFold(haystack []string, needle string) bool { + for _, h := range haystack { + if utils.EqualFold(h, needle) { + return true + } + } + return false +} diff --git a/src/vendor/github.com/gofiber/fiber/v3/internal/logtemplate/sanitize.go b/src/vendor/github.com/gofiber/fiber/v3/internal/logtemplate/sanitize.go new file mode 100644 index 00000000..f332e3cf --- /dev/null +++ b/src/vendor/github.com/gofiber/fiber/v3/internal/logtemplate/sanitize.go @@ -0,0 +1,94 @@ +package logtemplate + +import ( + "github.com/gofiber/utils/v2/swar" +) + +// WriteSanitized writes p to output with ASCII control bytes replaced by +// spaces. Tabs are preserved. Clean inputs (the common case) forward +// directly to output.Write with no allocation; dirty inputs are scrubbed +// into a copy starting at the first control byte. +func WriteSanitized(output Buffer, p []byte) (int, error) { + idx := IndexControlByte(p) + if idx == -1 { + return output.Write(p) + } + return output.Write(ScrubControls(p, idx)) +} + +// WriteSanitizedString is WriteSanitized for strings, keeping the clean +// fast path on output.WriteString. +func WriteSanitizedString(output Buffer, s string) (int, error) { + idx := IndexControlByte(s) + if idx == -1 { + return output.WriteString(s) + } + return output.Write(ScrubControls(s, idx)) +} + +// ScrubControls returns a copy of s with every byte IsControlByte matches +// replaced by a space. idx is the index of the first such byte, so the scan +// starts there and the clean prefix is copied untouched. +// +// A negative idx — what IndexControlByte returns for clean input — is clamped +// to 0 rather than panicking, so ScrubControls(s, IndexControlByte(s)) is +// safe even though the callers here take the clean fast path instead. +func ScrubControls[S ~string | ~[]byte](s S, idx int) []byte { + if idx < 0 { + idx = 0 + } + scrubbed := make([]byte, len(s)) + copy(scrubbed, s) + for i := idx; i < len(scrubbed); i++ { + if IsControlByte(scrubbed[i]) { + scrubbed[i] = ' ' + } + } + return scrubbed +} + +// IndexControlByte returns the index of the first byte IsControlByte matches, +// or -1 if none is present. It scans eight bytes at a time; inputs of 8+ +// bytes finish with one overlapping word, shorter ones byte-wise. +func IndexControlByte[S ~string | ~[]byte](s S) int { + n := len(s) + i := 0 + for ; i+swar.WordLen <= n; i += swar.WordLen { + if m := controlScrubMask(swar.Load8(s, i)); m != 0 { + return i + swar.FirstLane(m) + } + } + if i == n { + return -1 + } + if n >= swar.WordLen { + if m := controlScrubMask(swar.Load8(s, n-swar.WordLen)); m != 0 { + return n - swar.WordLen + swar.FirstLane(m) + } + return -1 + } + for ; i < n; i++ { + if IsControlByte(s[i]) { + return i + } + } + return -1 +} + +// controlScrubMask marks the lanes of w holding bytes IsControlByte matches: +// C0 controls except HTAB, plus DEL. Bytes >= 0x80 are never marked. +func controlScrubMask(w uint64) uint64 { + return (swar.MatchRangeMask(w, 0x00, 0x1f) &^ swar.MatchByteMask(w, '\t')) | swar.MatchByteMask(w, 0x7f) +} + +// IsControlByte reports whether b is an ASCII control byte that must not pass +// through to a log line. Tab is preserved because operators frequently use it +// for delimiting structured fields. CR, LF, NUL, and the other C0/DEL bytes +// are replaced — they are the bytes attackers use to forge log lines or +// corrupt terminal output via ANSI escape sequences. +func IsControlByte(b byte) bool { + if b == '\t' { + return false + } + return b < 0x20 || b == 0x7f +} diff --git a/src/vendor/github.com/gofiber/fiber/v3/internal/mediatype/mediatype.go b/src/vendor/github.com/gofiber/fiber/v3/internal/mediatype/mediatype.go new file mode 100644 index 00000000..268d0be0 --- /dev/null +++ b/src/vendor/github.com/gofiber/fiber/v3/internal/mediatype/mediatype.go @@ -0,0 +1,104 @@ +// Package mediatype canonicalizes the case-insensitive parts of a request's +// Content-Type, so the case-sensitive parsers downstream — fasthttp's form and +// multipart readers above all — see the value they expect. +package mediatype + +import ( + "bytes" + + "github.com/gofiber/utils/v2" + utilsbytes "github.com/gofiber/utils/v2/bytes" + "github.com/valyala/fasthttp" +) + +// NormalizeRequestContentType lowercases the case-insensitive parts of a +// request's Content-Type in place. The fold must land on the request's own +// bytes: fasthttp locates the boundary and the urlencoded body case-sensitively. +func NormalizeRequestContentType(h *fasthttp.RequestHeader) []byte { + ct := h.ContentType() + + // Nothing to fold is both the common and the repeat case: after the first + // FormValue the header is already lowercase. Uppercase confined to a parameter + // value still takes the full walk, which leaves it alone. + if !hasUpper(ct) { + return ct + } + + i := bytes.IndexByte(ct, ';') + if i == -1 { + utilsbytes.UnsafeToLower(ct) + return ct + } + utilsbytes.UnsafeToLower(ct[:i]) + + for i < len(ct) { + i++ // step over the ';' + for i < len(ct) && (ct[i] == ' ' || ct[i] == '\t') { + i++ + } + + nameStart := i + for i < len(ct) && ct[i] != '=' && ct[i] != ';' { + i++ + } + utilsbytes.UnsafeToLower(ct[nameStart:i]) + if i >= len(ct) || ct[i] == ';' { + continue + } + + // Step over the value untouched: a quoted-string may contain ';' (RFC 9110 + // §5.6.6), and a quoted-pair may contain '"'. Ending the string at an + // escaped quote would fold the rest as parameters, and fasthttp matches + // "boundary" case-sensitively, so lowercasing a decoy inside a value is + // what makes it the one fasthttp picks: on + // `X="\"; BOUNDARY=bogus"; BOUNDARY=Real` it took bogus over Real. + i++ // step over the '=' + if i < len(ct) && ct[i] == '"' { + i++ + for i < len(ct) && ct[i] != '"' { + if ct[i] == '\\' && i+1 < len(ct) { + i++ // the escaped byte cannot close the string + } + i++ + } + if i < len(ct) { + i++ // closing quote + } + } + for i < len(ct) && ct[i] != ';' { + i++ + } + } + + return ct +} + +// Form media types, duplicated from package fiber because that package imports +// this one. +const ( + applicationForm = "application/x-www-form-urlencoded" + multipartForm = "multipart/form-data" +) + +// IsForm reports whether ct names one of the two media types fasthttp's form +// parsers handle. Callers gate NormalizeRequestContentType on it, since the fold +// lands on the request's own bytes. Compared folded, parameters ignored. +func IsForm(ct []byte) bool { + if i := bytes.IndexByte(ct, ';'); i >= 0 { + ct = ct[:i] + } + ct = bytes.TrimRight(ct, " \t") + + name := utils.UnsafeString(ct) + return utils.EqualFold(name, applicationForm) || utils.EqualFold(name, multipartForm) +} + +// hasUpper reports whether b holds an ASCII uppercase byte. +func hasUpper(b []byte) bool { + for _, c := range b { + if c >= 'A' && c <= 'Z' { + return true + } + } + return false +} diff --git a/src/vendor/github.com/gofiber/fiber/v3/internal/schemehost/schemehost.go b/src/vendor/github.com/gofiber/fiber/v3/internal/schemehost/schemehost.go index 512bdbbf..be3074fa 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/internal/schemehost/schemehost.go +++ b/src/vendor/github.com/gofiber/fiber/v3/internal/schemehost/schemehost.go @@ -7,6 +7,7 @@ import ( "net/url" "strings" + "github.com/gofiber/utils/v2" utilsstrings "github.com/gofiber/utils/v2/strings" ) @@ -15,76 +16,120 @@ const ( schemeHTTPS = "https" ) +// schemePorts is the single source of truth for the schemes whose default +// port is normalized away during origin comparison. +var schemePorts = [...]struct { + scheme string + port string +}{ + {schemeHTTP, "80"}, + {schemeHTTPS, "443"}, +} + +// foldSchemePort resolves scheme against schemePorts, ASCII +// case-insensitively, returning the canonical lowercase scheme and its +// default port. +func foldSchemePort(scheme string) (canonical, port string, known bool) { //nolint:nonamedreturns // names document the three results + for _, e := range schemePorts { + if utils.EqualFold(scheme, e.scheme) { + return e.scheme, e.port, true + } + } + return "", "", false +} + // Match reports whether (schemeA, hostA) and (schemeB, hostB) denote the same // origin. Scheme comparison is case-insensitive and default ports (http:80, // https:443) are normalized so "example.com" and "example.com:443" match. func Match(schemeA, hostA, schemeB, hostB string) bool { - normalizedSchemeA := utilsstrings.ToLower(schemeA) - normalizedSchemeB := utilsstrings.ToLower(schemeB) + if !utils.EqualFold(schemeA, schemeB) { + return false + } + + // Identical host strings always normalize identically, so they denote the + // same origin once the schemes match. This is the dominant same-origin + // input (e.g. Origin-vs-Host on non-CORS requests). + if hostA == hostB { + return true + } - normalizedHostA := normalizeSchemeHost(normalizedSchemeA, hostA) - normalizedHostB := normalizeSchemeHost(normalizedSchemeB, hostB) + scheme, defaultPort, known := foldSchemePort(schemeA) + if !known { + // Unknown schemes get no port normalization: the hosts must simply be + // equal, ASCII case-insensitively. + return utils.EqualFold(hostA, hostB) + } + + // Fast path for two clean "host" or "host:port" values (the common case): + // compare the host parts case-insensitively and the effective ports + // exactly, without allocating lowered or port-normalized copies. + if hostOnlyA, portA, cleanA := splitCleanHostPort(hostA); cleanA { + if hostOnlyB, portB, cleanB := splitCleanHostPort(hostB); cleanB { + if portA == "" { + portA = defaultPort + } + if portB == "" { + portB = defaultPort + } + return portA == portB && utils.EqualFold(hostOnlyA, hostOnlyB) + } + } - return normalizedSchemeA == normalizedSchemeB && normalizedHostA == normalizedHostB + // Anything unusual (userinfo, percent-encoding, bracketed IPv6, control + // chars, invalid port, ...) takes the legacy normalize-and-compare path. + return normalizeHostPort(scheme, hostA, defaultPort) == normalizeHostPort(scheme, hostB, defaultPort) } -func normalizeSchemeHost(scheme, host string) string { +// normalizeHostPort lowercases host and appends defaultPort when no explicit +// port is present. scheme is only used by the url.Parse fallback. +func normalizeHostPort(scheme, host, defaultPort string) string { host = utilsstrings.ToLower(host) - var defaultPort string - switch scheme { - case schemeHTTP: - defaultPort = "80" - case schemeHTTPS: - defaultPort = "443" - default: - return host - } - - // Fast path for a clean "host" or "host:port" value (the common case), - // avoiding the url.Parse allocation. Anything unusual (userinfo, path, - // percent-encoding, bracketed IPv6, control chars, empty/invalid port, ...) - // falls back to the url.Parse path, which preserves the exact legacy behavior. - if hasPort, clean := classifyHostPort(host); clean { - if hasPort { + // Clean "host" or "host:port" values (e.g. the clean side of a mixed + // clean/unclean pair; Match handles the clean/clean case itself) avoid the + // url.Parse allocation. Anything unusual (userinfo, path, percent-encoding, + // bracketed IPv6, control chars, empty/invalid port, ...) falls back to the + // url.Parse path, which preserves the exact legacy behavior. + if _, port, clean := splitCleanHostPort(host); clean { + if port != "" { return host } return host + ":" + defaultPort } - return normalizeSchemeHostViaParse(scheme, host, defaultPort) + return normalizeHostPortViaParse(scheme, host, defaultPort) } -// classifyHostPort reports whether host is a plain "" or -// ":" value (clean) and, if so, whether it carries an -// explicit numeric port. The accepted character set is deliberately narrow -// (lowercase ASCII letters, digits, '.', '-', and a single ':'); anything else, -// including bracketed IPv6 literals, returns clean=false and is handled by the +// splitCleanHostPort splits a plain "" or +// ":" value (clean) into its host and port parts. The +// accepted character set is deliberately narrow (ASCII letters, digits, '.', +// '-', and a single ':' followed by digits); anything else, including +// bracketed IPv6 literals, returns clean=false and is handled by the // url.Parse fallback so behavior stays identical to the legacy implementation. -func classifyHostPort(host string) (hasPort, clean bool) { //nolint:nonamedreturns // names document the two booleans +func splitCleanHostPort(s string) (host, port string, clean bool) { //nolint:nonamedreturns // names document the three results colon := -1 - for i := 0; i < len(host); i++ { - c := host[i] + for i := 0; i < len(s); i++ { + c := s[i] switch { - case c >= 'a' && c <= 'z', c >= '0' && c <= '9', c == '.', c == '-': + case c >= 'a' && c <= 'z', c >= 'A' && c <= 'Z', c >= '0' && c <= '9', c == '.', c == '-': // safe reg-name / IPv4 character case c == ':': if colon >= 0 { - return false, false // more than one colon -> not a clean host:port + return "", "", false // more than one colon -> not a clean host:port } colon = i default: - return false, false // brackets, control chars, anything else + return "", "", false // brackets, control chars, anything else } } if colon < 0 { - return false, host != "" // no port; empty host falls back to url.Parse + return s, "", s != "" // no port; empty host falls back to url.Parse } - if !allDigits(host[colon+1:]) { - return false, false // "host:" or "host:abc" -> let url.Parse decide + if !allDigits(s[colon+1:]) { + return "", "", false // "host:" or "host:abc" -> let url.Parse decide } - return true, true + return s[:colon], s[colon+1:], true } // allDigits reports whether s is non-empty and all ASCII digits. @@ -100,9 +145,9 @@ func allDigits(s string) bool { return true } -// normalizeSchemeHostViaParse is the url.Parse-based fallback. host is already +// normalizeHostPortViaParse is the url.Parse-based fallback. host is already // lowercased and scheme is known to be http or https. -func normalizeSchemeHostViaParse(scheme, host, defaultPort string) string { +func normalizeHostPortViaParse(scheme, host, defaultPort string) string { parsedHost, err := url.Parse(scheme + "://" + host) if err != nil { return host diff --git a/src/vendor/github.com/gofiber/fiber/v3/internal/urlnorm/urlnorm.go b/src/vendor/github.com/gofiber/fiber/v3/internal/urlnorm/urlnorm.go new file mode 100644 index 00000000..ea7a12a9 --- /dev/null +++ b/src/vendor/github.com/gofiber/fiber/v3/internal/urlnorm/urlnorm.go @@ -0,0 +1,67 @@ +// Package urlnorm applies the parts of the WHATWG URL parser's input handling a +// guard must apply before judging a URL Fiber is about to emit. Nothing +// normalizes an outbound URL; the parser deciding it runs in the client after. +package urlnorm + +import ( + "strings" +) + +// StripTabCRLF removes every ASCII tab, LF and CR, as the WHATWG URL parser does +// before parsing. Leaving them in lets "\t/evil.com" hide behind a leading slash. +// Returns the input unchanged, without copying, when it holds none of them. +func StripTabCRLF(s string) string { + var b []byte + for i := 0; i < len(s); i++ { + switch c := s[i]; c { + case '\t', '\n', '\r': + if b == nil { + b = append(make([]byte, 0, len(s)), s[:i]...) + } + default: + if b != nil { + b = append(b, c) + } + } + } + if b == nil { + return s + } + return string(b) +} + +// RootedPath returns location as what a URL composed from a named route can only +// be: a path on the origin now being served. A parameter is spliced in raw, so +// on "/*" "/evil.com" composed "//evil.com" and "\evil.com" folded to the same. +// +// Exactly one leading slash, never two: "//evil.com" is a network-path reference +// whose host is whatever follows, so it resolves against "https://good.example" +// as "https://evil.com". That is true of author text as much as of a value, +// which is why NamesAuthority refuses such a route rather than composing it. +func RootedPath(location string) string { + location = StripTabCRLF(location) + + n := LeadingSlashes(location) + if n == 1 && location[0] == '/' { + return location + } + // Backslashes count as slashes here because the parser folds them. + return "/" + location[n:] +} + +// LeadingSlashes returns the length of the run of slashes starting s, counting +// backslashes among them because the parser folds the two. +func LeadingSlashes(s string) int { + n := 0 + for n < len(s) && (s[n] == '/' || s[n] == '\\') { + n++ + } + return n +} + +// AsBrowserReads returns location with the handling a client applies before +// parsing: tab, LF and CR removed, then surrounding C0 controls and spaces +// trimmed (RFC 9110 §5.5). Interior spaces are percent-encoded, not removed. +func AsBrowserReads(location string) string { + return strings.TrimFunc(StripTabCRLF(location), func(r rune) bool { return r <= ' ' }) +} diff --git a/src/vendor/github.com/gofiber/fiber/v3/listen.go b/src/vendor/github.com/gofiber/fiber/v3/listen.go index dbe71938..511adcbf 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/listen.go +++ b/src/vendor/github.com/gofiber/fiber/v3/listen.go @@ -55,11 +55,14 @@ type ListenConfig struct { // TLSConfigFunc allows customizing tls.Config as you want. // + // Ignored when TLSConfig is set: configure that tls.Config directly instead. + // // Default: nil TLSConfigFunc func(tlsConfig *tls.Config) `json:"tls_config_func"` - // TLSConfig allows providing a tls.Config used as the base for TLS settings. - // This enables external certificate providers via GetCertificate. + // TLSConfig is cloned and served as supplied, enabling external certificate + // providers via GetCertificate. It replaces the other TLS settings rather than + // seeding them, so there is no mutual TLS unless its ClientAuth requires it. // // Default: nil TLSConfig *tls.Config `json:"tls_config"` @@ -98,8 +101,9 @@ type ListenConfig struct { // Default : "" CertKeyFile string `json:"cert_key_file"` - // CertClientFile is a path of client certificate. - // If you want to use mTLS, you have to enter this field. + // CertClientFile is a path of the CA bundle used to verify client + // certificates, which is how ListenConfig asks for mTLS. Ignored when + // TLSConfig is set: its ClientAuth decides instead, against its ClientCAs. // // Default : "" CertClientFile string `json:"cert_client_file"` @@ -132,6 +136,8 @@ type ListenConfig struct { // TLSMinVersion allows to set TLS minimum version. // + // Ignored when TLSConfig is set: set MinVersion on that tls.Config instead. + // // Default: tls.VersionTLS12 // WARNING: TLS1.0 and TLS1.1 versions are not supported. TLSMinVersion uint16 `json:"tls_min_version"` @@ -183,11 +189,18 @@ func listenConfigDefault(config ...ListenConfig) ListenConfig { cfg.TLSMinVersion = tls.VersionTLS12 } + return cfg +} + +// validateTLSMinVersion rejects a version this package will not build a +// tls.Config from. Asked only where the field is read: rejecting it in the +// defaults panicked before warnSupersededTLSFields or +// warnIgnoredTLSFieldsOnListener could say the value was being ignored anyway, +// which is the diagnostic a stale TLS 1.1 most needs. +func validateTLSMinVersion(cfg *ListenConfig) { if cfg.TLSMinVersion != tls.VersionTLS12 && cfg.TLSMinVersion != tls.VersionTLS13 { panic("unsupported TLS version, please use tls.VersionTLS12 or tls.VersionTLS13") } - - return cfg } // Listen serves HTTP requests from the given addr. @@ -204,7 +217,10 @@ func (app *App) Listen(addr string, config ...ListenConfig) error { var tlsHandler *TLSHandler if cfg.TLSConfig != nil { tlsConfig = cfg.TLSConfig.Clone() + warnSupersededTLSFields(&cfg) } else { + validateTLSMinVersion(&cfg) + switch { case cfg.AutoCertManager != nil && (cfg.CertFile != "" || cfg.CertKeyFile != ""): return ErrAutoCertWithCertFile @@ -267,6 +283,16 @@ func (app *App) Listen(addr string, config ...ListenConfig) error { return fmt.Errorf("failed to listen: %w", err) } + // Close the listener on any path that doesn't reach Serve (which otherwise + // takes ownership of it) — an early error return or a panicking hook — so + // the bound socket isn't leaked. + served := false + defer func() { + if !served { + _ = ln.Close() //nolint:errcheck // best-effort cleanup on the error path + } + }() + // prepare the server for the start app.startupProcess() @@ -285,9 +311,84 @@ func (app *App) Listen(addr string, config ...ListenConfig) error { } } + served = true return app.server.Serve(ln) } +// warnSupersededTLSFields logs the ListenConfig TLS fields a supplied TLSConfig +// supersedes. CertClientFile is where silence is dangerous: it is the only way +// ListenConfig asks for mTLS, and a TLSConfig says nothing about it by default. +func warnSupersededTLSFields(cfg *ListenConfig) { + if cfg.CertClientFile != "" { + log.Warn("[Listen] TLSConfig supersedes CertClientFile: a client certificate is required only if " + + "TLSConfig sets ClientAuth to a Require mode, with ClientCAs as the roots it verifies against.") + } + + var ignored []string + if cfg.CertFile != "" || cfg.CertKeyFile != "" { + ignored = append(ignored, "CertFile/CertKeyFile") + } + // Zero is unset and listenConfigDefault fills in TLS 1.2, so only a caller who + // asked for something else is losing anything here. + if cfg.TLSMinVersion != 0 && cfg.TLSMinVersion != tls.VersionTLS12 { + ignored = append(ignored, "TLSMinVersion") + } + if cfg.AutoCertManager != nil { + ignored = append(ignored, "AutoCertManager") + } + if cfg.TLSConfigFunc != nil { + ignored = append(ignored, "TLSConfigFunc") + } + if len(ignored) > 0 { + log.Warnf("[Listen] TLSConfig supersedes %s.", strings.Join(ignored, ", ")) + } +} + +// warnIgnoredTLSFieldsOnListener reports TLS settings App.Listener cannot honor. +// It serves the listener it is handed, so CertClientFile buys no client- +// certificate verification — and unless the caller wrapped it, no TLS either. +func warnIgnoredTLSFieldsOnListener(cfg *ListenConfig, ln net.Listener) { + if cfg.CertClientFile != "" { + log.Warn("[Listener] CertClientFile is ignored: a client certificate is required only if the supplied " + + "listener already asks for one. Wrap it with tls.NewListener using a tls.Config whose ClientAuth " + + "is a Require mode.") + } + + var ignored []string + if cfg.TLSConfig != nil { + ignored = append(ignored, "TLSConfig") + } + if cfg.CertFile != "" || cfg.CertKeyFile != "" { + ignored = append(ignored, "CertFile/CertKeyFile") + } + if cfg.TLSMinVersion != 0 && cfg.TLSMinVersion != tls.VersionTLS12 { + ignored = append(ignored, "TLSMinVersion") + } + if cfg.AutoCertManager != nil { + ignored = append(ignored, "AutoCertManager") + } + if cfg.TLSConfigFunc != nil { + ignored = append(ignored, "TLSConfigFunc") + } + if len(ignored) == 0 { + return + } + + suffix := "." + if getTLSConfig(ln) == nil { + suffix = "; this listener is not serving TLS." + } + log.Warnf("[Listener] serves the supplied listener as-is, so %s %s ignored%s", + strings.Join(ignored, ", "), pluralIsAre(len(ignored)), suffix) +} + +func pluralIsAre(n int) string { + if n == 1 { + return "is" + } + return "are" +} + func applyClientCert(tlsConfig *tls.Config, certClientFile string) error { if certClientFile == "" { return nil @@ -311,8 +412,13 @@ func applyClientCert(tlsConfig *tls.Config, certClientFile string) error { // Listener serves HTTP requests from the given listener. // You should enter custom ListenConfig to customize startup. (prefork, startup message, graceful shutdown...) +// +// The listener is served exactly as supplied, so every TLS field of the config +// is ignored — including CertClientFile. Wrap it with tls.NewListener yourself +// to serve TLS or require a client certificate. func (app *App) Listener(ln net.Listener, config ...ListenConfig) error { cfg := listenConfigDefault(config...) + warnIgnoredTLSFieldsOnListener(&cfg, ln) // Graceful shutdown if cfg.GracefulContext != nil { @@ -377,6 +483,7 @@ func (*App) createListener(addr string, tlsConfig *tls.Config, cfg *ListenConfig if cfg.ListenerNetwork == NetworkUnix { if err = os.Chmod(addr, cfg.UnixSocketFileMode); err != nil { + _ = listener.Close() //nolint:errcheck // best-effort cleanup on the error path return nil, fmt.Errorf("cannot chmod %#o for %q: %w", cfg.UnixSocketFileMode, addr, err) } } @@ -606,18 +713,13 @@ func (app *App) printRoutesMessage() { func (app *App) gracefulShutdown(ctx context.Context, cfg *ListenConfig) { <-ctx.Done() - var err error - + // The OnPostShutdown hooks are fired by ShutdownWithContext (via + // Shutdown/ShutdownWithTimeout) with the real error, so we must not fire + // them again here or they would run twice. That error is already delivered + // to those hooks, so it is intentionally ignored here. if cfg != nil && cfg.ShutdownTimeout != 0 { - err = app.ShutdownWithTimeout(cfg.ShutdownTimeout) //nolint:contextcheck // TODO: Implement it + _ = app.ShutdownWithTimeout(cfg.ShutdownTimeout) //nolint:errcheck,contextcheck // error is delivered to OnPostShutdown hooks } else { - err = app.Shutdown() //nolint:contextcheck // TODO: Implement it + _ = app.Shutdown() //nolint:errcheck,contextcheck // error is delivered to OnPostShutdown hooks } - - if err != nil { - app.hooks.executeOnPostShutdownHooks(err) - return - } - - app.hooks.executeOnPostShutdownHooks(nil) } diff --git a/src/vendor/github.com/gofiber/fiber/v3/log/context.go b/src/vendor/github.com/gofiber/fiber/v3/log/context.go index 46dd6ca7..339eda37 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/log/context.go +++ b/src/vendor/github.com/gofiber/fiber/v3/log/context.go @@ -4,8 +4,6 @@ import ( "errors" "fmt" "maps" - "slices" - "strings" "sync" "sync/atomic" @@ -208,60 +206,14 @@ func defaultContextValueTag(output Buffer, ctx any, _ *ContextData, extraParam s } // writeSanitized writes p to output with ASCII control bytes replaced by -// spaces. Tabs are preserved. The replacement is done in-place on a single -// pass so the hot path stays alloc-free for inputs that are already clean -// (the common case): clean inputs forward directly to output.Write. +// spaces. Tabs are preserved. See logtemplate.WriteSanitized. func writeSanitized(output Buffer, p []byte) (int, error) { - if !needsControlSanitize(p) { - return output.Write(p) - } - scrubbed := make([]byte, len(p)) - for i, b := range p { - if isControlByte(b) { - scrubbed[i] = ' ' - } else { - scrubbed[i] = b - } - } - return output.Write(scrubbed) + return logtemplate.WriteSanitized(output, p) } +// writeSanitizedString is writeSanitized for strings. func writeSanitizedString(output Buffer, s string) (int, error) { - if !needsControlSanitizeString(s) { - return output.WriteString(s) - } - scrubbed := make([]byte, len(s)) - for i := 0; i < len(s); i++ { - b := s[i] - if isControlByte(b) { - scrubbed[i] = ' ' - } else { - scrubbed[i] = b - } - } - return output.Write(scrubbed) -} - -func needsControlSanitize(p []byte) bool { - return slices.ContainsFunc(p, isControlByte) -} - -func needsControlSanitizeString(s string) bool { - return strings.IndexFunc(s, func(r rune) bool { - return r < 0x80 && isControlByte(byte(r)) //nolint:gosec // G115: integer overflow conversion rune -> byte - }) >= 0 -} - -// isControlByte reports whether b is an ASCII control byte that must not pass -// through to a log line. Tab is preserved because operators frequently use it -// for delimiting structured fields. CR, LF, NUL, and the other C0/DEL bytes -// are replaced — they are the bytes attackers use to forge log lines or -// corrupt terminal output via ANSI escape sequences. -func isControlByte(b byte) bool { - if b == '\t' { - return false - } - return b < 0x20 || b == 0x7f + return logtemplate.WriteSanitizedString(output, s) } func emptyContextTag(_ Buffer, _ any, _ *ContextData, _ string) (int, error) { diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/cors/cors.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/cors/cors.go index 6baf146c..aaf9fc5e 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/cors/cors.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/cors/cors.go @@ -175,15 +175,15 @@ func New(config ...Config) fiber.Handler { // Response to OPTIONS request should not be cached but, // some caching can be configured to cache such responses. - // To Avoid poisoning the cache, we include the Vary header - // of preflight responses: - c.Vary(fiber.HeaderAccessControlRequestMethod) - c.Vary(fiber.HeaderAccessControlRequestHeaders) + // To avoid poisoning the cache, we include the Vary header + // of preflight responses, set in a single variadic Vary call + // per branch since every Vary call scans all response headers. if cfg.AllowPrivateNetwork && c.Get(fiber.HeaderAccessControlRequestPrivateNetwork) == "true" { - c.Vary(fiber.HeaderAccessControlRequestPrivateNetwork) + c.Vary(fiber.HeaderAccessControlRequestMethod, fiber.HeaderAccessControlRequestHeaders, fiber.HeaderAccessControlRequestPrivateNetwork, fiber.HeaderOrigin) c.Set(fiber.HeaderAccessControlAllowPrivateNetwork, "true") + } else { + c.Vary(fiber.HeaderAccessControlRequestMethod, fiber.HeaderAccessControlRequestHeaders, fiber.HeaderOrigin) } - c.Vary(fiber.HeaderOrigin) setPreflightHeaders(c, allowOrigin, maxAge, &cfg) diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/config.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/config.go index e2f53707..e82ef9b7 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/config.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/config.go @@ -32,7 +32,9 @@ type Config struct { // } MaxFunc func(c fiber.Ctx) int - // A function to dynamically calculate the expiration time for rate limiter entries + // A function to dynamically calculate the expiration time for rate limiter entries. + // Window accounting is whole-second, so a positive value below one second is floored to + // one second. A zero or negative value falls back to the default expiration. // // Default: A function that returns the static `Expiration` value from the config. ExpirationFunc func(c fiber.Ctx) time.Duration @@ -152,6 +154,19 @@ func configDefault(config ...Config) Config { return cfg } +// windowSeconds turns a per-request expiration into the whole-second window used +// for accounting. A positive sub-second value floors to 1s instead of truncating +// to a 0-second window (NaN rate in sliding, no limiting at all in fixed). +func windowSeconds(d time.Duration) uint64 { + if d <= 0 { + d = ConfigDefault.Expiration + } + if sec := uint64(d.Seconds()); sec > 0 { + return sec + } + return 1 +} + // currentSecond returns the current Unix time in whole seconds used for window // accounting. Production reads the cached utils.Timestamp() (refreshed by a 1s // ticker) to keep the hot path allocation- and syscall-free; tests can inject a diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/limiter_fixed.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/limiter_fixed.go index 36ccf446..d6c83593 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/limiter_fixed.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/limiter_fixed.go @@ -2,7 +2,6 @@ package limiter import ( "fmt" - "strconv" "sync" "github.com/gofiber/fiber/v3" @@ -38,12 +37,10 @@ func (FixedWindow) New(cfg *Config) fiber.Handler { return c.Next() } - // Generate expiration from generator - expirationDuration := cfg.ExpirationFunc(c) - if expirationDuration <= 0 { - expirationDuration = ConfigDefault.Expiration - } - expiration := uint64(expirationDuration.Seconds()) + // Generate expiration from generator. The storage TTL is derived from the + // window so a sub-second value cannot expire the entry mid-window. + expiration := windowSeconds(cfg.ExpirationFunc(c)) + expirationDuration, _ := secondsToDuration(expiration) // Get key from request key := cfg.KeyGenerator(c) @@ -96,7 +93,7 @@ func (FixedWindow) New(cfg *Config) fiber.Handler { // Return response with Retry-After header // https://tools.ietf.org/html/rfc6584 if !cfg.DisableHeaders { - c.Set(fiber.HeaderRetryAfter, strconv.FormatUint(resetInSec, 10)) + c.Set(fiber.HeaderRetryAfter, utils.FormatUint(resetInSec)) } // Call LimitReached handler @@ -143,9 +140,9 @@ func (FixedWindow) New(cfg *Config) fiber.Handler { // We can continue, update RateLimit headers if !cfg.DisableHeaders { - c.Set(xRateLimitLimit, strconv.Itoa(maxRequests)) - c.Set(xRateLimitRemaining, strconv.Itoa(remaining)) - c.Set(xRateLimitReset, strconv.FormatUint(resetInSec, 10)) + c.Set(xRateLimitLimit, utils.FormatInt(int64(maxRequests))) + c.Set(xRateLimitRemaining, utils.FormatInt(int64(remaining))) + c.Set(xRateLimitReset, utils.FormatUint(resetInSec)) } return err diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/limiter_sliding.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/limiter_sliding.go index dbe514b7..bf59495f 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/limiter_sliding.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/limiter/limiter_sliding.go @@ -3,7 +3,6 @@ package limiter import ( "fmt" "math" - "strconv" "sync" "time" @@ -41,11 +40,7 @@ func (SlidingWindow) New(cfg *Config) fiber.Handler { } // Generate expiration from generator - expirationDuration := cfg.ExpirationFunc(c) - if expirationDuration <= 0 { - expirationDuration = ConfigDefault.Expiration - } - expiration := uint64(expirationDuration.Seconds()) + expiration := windowSeconds(cfg.ExpirationFunc(c)) // Get key from request key := cfg.KeyGenerator(c) @@ -106,7 +101,7 @@ func (SlidingWindow) New(cfg *Config) fiber.Handler { // Return response with Retry-After header // https://tools.ietf.org/html/rfc6584 if !cfg.DisableHeaders { - c.Set(fiber.HeaderRetryAfter, strconv.FormatUint(resetInSec, 10)) + c.Set(fiber.HeaderRetryAfter, utils.FormatUint(resetInSec)) } // Call LimitReached handler @@ -160,9 +155,9 @@ func (SlidingWindow) New(cfg *Config) fiber.Handler { // We can continue, update RateLimit headers if !cfg.DisableHeaders { - c.Set(xRateLimitLimit, strconv.Itoa(maxRequests)) - c.Set(xRateLimitRemaining, strconv.Itoa(remaining)) - c.Set(xRateLimitReset, strconv.FormatUint(resetInSec, 10)) + c.Set(xRateLimitLimit, utils.FormatInt(int64(maxRequests))) + c.Set(xRateLimitRemaining, utils.FormatInt(int64(remaining))) + c.Set(xRateLimitReset, utils.FormatUint(resetInSec)) } } diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/context_tag.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/context_tag.go index 87017ecd..86a50007 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/context_tag.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/context_tag.go @@ -2,6 +2,7 @@ package logger import ( "github.com/gofiber/fiber/v3" + "github.com/gofiber/fiber/v3/internal/logtemplate" fiberlog "github.com/gofiber/fiber/v3/log" ) @@ -49,12 +50,15 @@ func RegisterContextTag(name string, extract func(ctx any) string) { panic("logger: RegisterContextTag requires a non-empty name and extractor") } + // Sanitized like every built-in tag: what extract returns is whatever the + // application pulled out of the context, in practice request data, so writing + // it raw lets a CR or LF close the line and start another. fiberlog.MustRegisterContextTag(name, func(output fiberlog.Buffer, ctx any, _ *fiberlog.ContextData, _ string) (int, error) { v := extract(ctx) if v == "" { return 0, nil } - return output.WriteString(v) + return logtemplate.WriteSanitizedString(output, v) }) MustRegisterTag(name, func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { @@ -62,6 +66,6 @@ func RegisterContextTag(name string, extract func(ctx any) string) { if v == "" { return 0, nil } - return output.WriteString(v) + return writeSanitizedString(output, v) }) } diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/default_logger.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/default_logger.go index 4e3882b2..be786dba 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/default_logger.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/default_logger.go @@ -8,6 +8,7 @@ import ( "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/internal/logtemplate" + "github.com/gofiber/utils/v2" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" "github.com/valyala/bytebufferpool" @@ -37,10 +38,16 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg *Config) error { // Default output when no custom Format or io.Writer is given if cfg.Format == DefaultFormat { // Format error if exist + // The request-derived values below (IP, path, and the chain error, + // which routinely embeds decoded request data) are scrubbed of control + // bytes for the same reason the template tags are: raw CR/LF lets a + // client forge additional access-log lines. See #4341. The method is + // not scrubbed — fasthttp rejects a request line whose method token + // holds one — which keeps this path consistent with ${method}. formatErr := "" if cfg.areColorsEnabled { if data.ChainErr != nil { - formatErr = colors.Red + " | " + data.ChainErr.Error() + colors.Reset + formatErr = colors.Red + " | " + sanitizeLogValue(data.ChainErr.Error()) + colors.Reset } fmt.Fprintf( buf, @@ -48,14 +55,14 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg *Config) error { data.Timestamp, statusColor(c.Response().StatusCode(), &colors), c.Response().StatusCode(), colors.Reset, data.Stop.Sub(data.Start), - c.IP(), + sanitizeLogValue(c.IP()), methodColor(c.Method(), &colors), c.Method(), colors.Reset, - c.Path(), + sanitizeLogValue(c.Path()), formatErr, ) } else { if data.ChainErr != nil { - formatErr = " | " + data.ChainErr.Error() + formatErr = " | " + sanitizeLogValue(data.ChainErr.Error()) } // Helper function to append fixed-width string with padding @@ -77,8 +84,9 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg *Config) error { buf.WriteString(data.Timestamp) buf.WriteString(" | ") - // Status Code with 3 fixed width, right aligned - fixedWidth(strconv.Itoa(c.Response().StatusCode()), 3, true) + // Status Code with 3 fixed width, right aligned; appended digit-wise + // to avoid the per-request Itoa string. + appendIntPadded(buf, c.Response().StatusCode(), 3) buf.WriteString(" | ") // Duration with 13 fixed width, right aligned @@ -86,7 +94,7 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg *Config) error { buf.WriteString(" | ") // Client IP with 15 fixed width, right aligned - fixedWidth(c.IP(), 15, true) + fixedWidth(sanitizeLogValue(c.IP()), 15, true) buf.WriteString(" | ") // HTTP Method with 7 fixed width, left aligned @@ -95,7 +103,7 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg *Config) error { // Path with dynamic padding for error message, left aligned errPadding, _ := strconv.Atoi(data.ErrPaddingStr) //nolint:errcheck // It is fine to ignore the error - fixedWidth(c.Path(), errPadding, false) + fixedWidth(sanitizeLogValue(c.Path()), errPadding, false) // Error message buf.WriteString(" ") @@ -151,12 +159,23 @@ func beforeHandlerFunc(cfg *Config) { } // appendInt writes the decimal form of v into output without going through -// fmt boxing. The 20-byte stack scratch fits any int64; strconv.AppendInt +// fmt boxing. The fixed 20-byte scratch fits any int64; utils.AppendInt // only grows the slice when the formatted value exceeds that capacity, which // cannot happen for a fixed-width int. func appendInt(output Buffer, v int) (int, error) { var scratch [20]byte - return output.Write(strconv.AppendInt(scratch[:0], int64(v), 10)) + return output.Write(utils.AppendInt(scratch[:0], int64(v))) +} + +// appendIntPadded appends the decimal form of v to buf, right-aligned to +// width with spaces, without allocating an intermediate string. +func appendIntPadded(buf *bytebufferpool.ByteBuffer, v, width int) { + var scratch [20]byte + s := utils.AppendInt(scratch[:0], int64(v)) + for i := len(s); i < width; i++ { + buf.WriteByte(' ') + } + buf.Write(s) } // writeLog writes a msg to w, printing a warning to stderr if the log fails. diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/logger.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/logger.go index bcaa76c7..3a3bc881 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/logger.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/logger.go @@ -120,9 +120,11 @@ func New(config ...Config) fiber.Handler { } else { data.Timestamp = "" } - // These compiled chains are shared across requests. The default logger and - // custom LoggerFunc implementations must only read them, for example via - // logtemplate.ExecuteChains. + // These compiled chains are shared across requests, so a custom + // LoggerFunc must only read them — never append to or reorder them. + // Walk Data.TemplateChain and Data.LogFuncChain in step; the helper the + // default logger uses for this lives in internal/ and is not importable + // from outside the module. data.TemplateChain = templateChain data.LogFuncChain = logFuncChain // put data back in the pool diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/tags.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/tags.go index 199dd312..fda09d43 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/tags.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/tags.go @@ -91,37 +91,58 @@ func createTagMap(cfg *Config) map[string]LogFunc { // Set default tags tagFunctions := map[string]LogFunc{ TagReferer: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.WriteString(c.Get(fiber.HeaderReferer)) + return writeSanitizedString(output, c.Get(fiber.HeaderReferer)) }, TagProtocol: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { return output.WriteString(c.Protocol()) }, TagScheme: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.WriteString(c.Scheme()) + // Scheme echoes X-Forwarded-Proto / X-Url-Scheme once the proxy is + // trusted, so it is request-derived like ${ips} and ${ua}. + return writeSanitizedString(output, c.Scheme()) }, TagPort: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { return output.WriteString(c.Port()) }, TagIP: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.WriteString(c.IP()) + return writeSanitizedString(output, c.IP()) }, TagIPs: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.WriteString(c.Get(fiber.HeaderXForwardedFor)) + // Ask the framework for the chain rather than read the header a second way: + // a lower-case "x-forwarded-for:" logged an empty chain while the trust + // decisions used it. c.IPs() splits and trims, so both wire forms match. + ips := c.IPs() + n := 0 + for i, ip := range ips { + if i > 0 { + m, err := output.WriteString(",") + n += m + if err != nil { + return n, err + } + } + m, err := writeSanitizedString(output, ip) + n += m + if err != nil { + return n, err + } + } + return n, nil }, TagHost: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.WriteString(c.Hostname()) + return writeSanitizedString(output, c.Hostname()) }, TagPath: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.WriteString(c.Path()) + return writeSanitizedString(output, c.Path()) }, TagURL: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.WriteString(c.OriginalURL()) + return writeSanitizedString(output, c.OriginalURL()) }, TagUA: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.WriteString(c.Get(fiber.HeaderUserAgent)) + return writeSanitizedString(output, c.Get(fiber.HeaderUserAgent)) }, TagBody: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.Write(c.Body()) + return writeSanitized(output, c.Body()) }, TagBytesReceived: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { return appendInt(output, c.Request().Header.ContentLength()) @@ -130,10 +151,13 @@ func createTagMap(cfg *Config) map[string]LogFunc { return appendInt(output, c.Response().Header.ContentLength()) }, TagRoute: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.WriteString(c.Route().Path) + // Normally the registered pattern, but Ctx.Route falls back to a + // synthetic route carrying the raw request path when no route + // matched, so this can be request-derived too. + return writeSanitizedString(output, c.Route().Path) }, TagResBody: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.Write(c.Response().Body()) + return writeSanitized(output, c.Response().Body()) }, TagReqHeaders: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { out := make(map[string][]string) @@ -145,10 +169,10 @@ func createTagMap(cfg *Config) map[string]LogFunc { for k, v := range out { reqHeaders = append(reqHeaders, k+"="+strings.Join(v, ",")) } - return output.WriteString(strings.Join(reqHeaders, "&")) + return writeSanitizedString(output, strings.Join(reqHeaders, "&")) }, TagQueryStringParams: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { - return output.WriteString(c.Request().URI().QueryArgs().String()) + return writeSanitizedString(output, c.Request().URI().QueryArgs().String()) }, TagBlack: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { @@ -182,37 +206,39 @@ func createTagMap(cfg *Config) map[string]LogFunc { if data.ChainErr != nil { if cfg.areColorsEnabled { colors := c.App().Config().ColorScheme - return fmt.Fprintf(output, "%s%s%s", colors.Red, data.ChainErr.Error(), colors.Reset) + return writeSanitizedColored(output, colors.Red, data.ChainErr.Error(), colors.Reset) } - return output.WriteString(data.ChainErr.Error()) + return writeSanitizedString(output, data.ChainErr.Error()) } return output.WriteString("-") }, TagReqHeader: func(output Buffer, c fiber.Ctx, _ *Data, extraParam string) (int, error) { - return output.WriteString(c.Get(extraParam)) + return writeSanitizedString(output, c.Get(extraParam)) }, TagRespHeader: func(output Buffer, c fiber.Ctx, _ *Data, extraParam string) (int, error) { - return output.WriteString(c.GetRespHeader(extraParam)) + return writeSanitizedString(output, c.GetRespHeader(extraParam)) }, TagQuery: func(output Buffer, c fiber.Ctx, _ *Data, extraParam string) (int, error) { - return output.WriteString(fiber.Query[string](c, extraParam)) + return writeSanitizedString(output, fiber.Query[string](c, extraParam)) }, TagForm: func(output Buffer, c fiber.Ctx, _ *Data, extraParam string) (int, error) { - return output.WriteString(c.FormValue(extraParam)) + return writeSanitizedString(output, c.FormValue(extraParam)) }, TagCookie: func(output Buffer, c fiber.Ctx, _ *Data, extraParam string) (int, error) { - return output.WriteString(c.Cookies(extraParam)) + return writeSanitizedString(output, c.Cookies(extraParam)) }, TagLocals: func(output Buffer, c fiber.Ctx, _ *Data, extraParam string) (int, error) { switch v := c.Locals(extraParam).(type) { case []byte: - return output.Write(v) + return writeSanitized(output, v) case string: - return output.WriteString(v) + return writeSanitizedString(output, v) case nil: return 0, nil default: - return fmt.Fprintf(output, "%v", v) + // %v can render arbitrary text (e.g. a struct holding request + // data), so it goes through the same scrubbing. + return writeSanitizedValue(output, v) } }, TagStatus: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) { diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/utils.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/utils.go index cd8e6eac..613f1db0 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/utils.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/logger/utils.go @@ -1,11 +1,14 @@ package logger import ( + "fmt" "io" "github.com/gofiber/fiber/v3" + "github.com/gofiber/fiber/v3/internal/logtemplate" fiberlog "github.com/gofiber/fiber/v3/log" "github.com/gofiber/utils/v2" + "github.com/valyala/bytebufferpool" ) func methodColor(method string, colors *fiber.Colors) string { @@ -93,3 +96,87 @@ func LoggerToWriter[T any](logger fiberlog.AllLogger[T], level fiberlog.Level) i loggerInstance: logger, } } + +// writeSanitized writes p to output with ASCII control bytes replaced by +// spaces (tabs are preserved), so user-controlled values such as a request +// body or a decoded query parameter cannot inject CR/LF and forge log lines. +func writeSanitized(output Buffer, p []byte) (int, error) { + return logtemplate.WriteSanitized(output, p) +} + +// writeSanitizedString is writeSanitized for strings. +func writeSanitizedString(output Buffer, s string) (int, error) { + return logtemplate.WriteSanitizedString(output, s) +} + +// writeSanitizedColored writes value between the two color escapes, scrubbing +// only value. The color sequences are library-controlled and must reach the +// output verbatim. +func writeSanitizedColored(output Buffer, color, value, reset string) (int, error) { + n, err := output.WriteString(color) + if err != nil { + return n, err + } + m, err := writeSanitizedString(output, value) + n += m + if err != nil { + return n, err + } + m, err = output.WriteString(reset) + return n + m, err +} + +// SanitizeValue returns s with ASCII control bytes replaced by spaces, +// preserving horizontal tab. It is the same scrubbing the built-in tags apply +// to request-derived values, exported so that code taking one of the paths +// that bypasses those tags can apply it too: +// +// - a tag registered with RegisterTag, MustRegisterTag or RegisterContextTag +// - an entry in Config.CustomTags +// - a Config.LoggerFunc, which replaces the whole rendering pipeline +// +// Any of those can write a value that reached the handler percent-decoded — a +// query parameter, a form field, a header — and an unscrubbed CR/LF there +// forges an extra access-log line. +// +// Clean input, the overwhelmingly common case, is returned unchanged with no +// allocation. Only ASCII controls are replaced; bytes at or above 0x80 pass +// through, so a value that may carry C1 controls (U+0080–U+009F, including +// NEL U+0085) needs its own handling. +func SanitizeValue(s string) string { + return sanitizeLogValue(s) +} + +// sanitizeLogValue returns s with ASCII control bytes replaced by spaces +// (tabs preserved). It is the string-returning counterpart of +// writeSanitizedString, for the default-format writer, which composes its line +// with fmt.Fprintf and fixed-width padding rather than by writing tags into +// the buffer. Clean input — the overwhelmingly common case — is returned +// unchanged with no allocation. +func sanitizeLogValue(s string) string { + idx := logtemplate.IndexControlByte(s) + if idx == -1 { + return s + } + return string(logtemplate.ScrubControls(s, idx)) +} + +// writeSanitizedValue renders v with %v and writes the scrubbed result. +// +// The rendering goes through a pooled scratch buffer because the bytes have to +// be scrubbed before they reach output, and scrubbing in place afterwards is +// not an option: Buffer is an interface, and an implementation whose Bytes() +// returns a copy would silently skip the scrub. The pool keeps that +// indirection allocation-free; it costs roughly 30ns over writing straight to +// output, paid only by ${locals:} values that are neither string nor []byte. +func writeSanitizedValue(output Buffer, v any) (int, error) { + b := bytebufferpool.Get() + defer bytebufferpool.Put(b) + + // Called without assignment deliberately: the only error Fprintf can report + // is one from the writer, and bytebufferpool.ByteBuffer.Write always returns + // a nil error. The error that matters — a failed write to output — is the + // one returned below. + fmt.Fprintf(b, "%v", v) + return writeSanitized(output, b.B) +} diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/recover/recover.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/recover/recover.go index 8be5df10..5c0db9d7 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/recover/recover.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/recover/recover.go @@ -8,8 +8,10 @@ import ( "github.com/gofiber/fiber/v3" ) +// Must not start with "panic: ": the panic was recovered, and that exact prefix +// makes gotestsum treat the whole run as crashed and skip --rerun-fails. func defaultStackTraceHandler(_ fiber.Ctx, e any) { - fmt.Fprintf(os.Stderr, "panic: %v\n\n%s\n", e, debug.Stack()) + fmt.Fprintf(os.Stderr, "recovered panic: %v\n\n%s\n", e, debug.Stack()) } // DefaultPanicHandler returns r directly if it's an error, and creates a new one with the %v verb otherwise. diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/requestid/requestid.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/requestid/requestid.go index 5b6d86fa..fc1b287f 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/requestid/requestid.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/requestid/requestid.go @@ -6,6 +6,7 @@ import ( "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/middleware/logger" "github.com/gofiber/utils/v2" + "github.com/gofiber/utils/v2/swar" ) // The contextKey type is unexported to prevent collisions with context keys defined in @@ -68,6 +69,13 @@ func sanitizeRequestID(rid string, generator func() string) string { return utils.SecureToken() } +// visibleASCIIMask marks the lanes of w inside [0x20, 0x7E]; bytes >= 0x80 +// are never marked. A word is all visible ASCII iff the mask equals +// swar.HighBits. +func visibleASCIIMask(w uint64) uint64 { + return swar.MatchRangeMask(w, 0x20, 0x7e) +} + // isValidRequestID reports whether the request ID contains only visible ASCII // characters (0x20–0x7E) and is non-empty. func isValidRequestID(rid string) bool { @@ -75,9 +83,23 @@ func isValidRequestID(rid string) bool { return false } - for i := 0; i < len(rid); i++ { - c := rid[i] - if c < 0x20 || c > 0x7e { + // Check eight bytes per iteration, finishing inputs of 8+ bytes with + // one overlapping word; shorter ones are checked byte-wise. + n := len(rid) + i := 0 + for ; i+swar.WordLen <= n; i += swar.WordLen { + if visibleASCIIMask(swar.Load8(rid, i)) != swar.HighBits { + return false + } + } + if i == n { + return true + } + if n >= swar.WordLen { + return visibleASCIIMask(swar.Load8(rid, n-swar.WordLen)) == swar.HighBits + } + for ; i < n; i++ { + if c := rid[i]; c < 0x20 || c > 0x7e { return false } } diff --git a/src/vendor/github.com/gofiber/fiber/v3/middleware/static/static.go b/src/vendor/github.com/gofiber/fiber/v3/middleware/static/static.go index c8236471..ee20b59f 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/middleware/static/static.go +++ b/src/vendor/github.com/gofiber/fiber/v3/middleware/static/static.go @@ -85,12 +85,8 @@ func sanitizePath(p []byte, filesystem fs.FS) ([]byte, error) { return nil, err } - if strings.IndexByte(s, '\\') >= 0 { - return nil, ErrInvalidPath - } - - // reject any null bytes - if strings.IndexByte(s, '\x00') >= 0 { + // reject backslashes and null bytes in a single scan + if utils.IndexAny2(s, '\\', '\x00') >= 0 { return nil, ErrInvalidPath } @@ -158,9 +154,15 @@ func New(root string, cfg ...Config) fiber.Handler { var rootCheckErr error var rootIsFile bool - // adjustments for io/fs compatibility - if config.FS != nil && root == "" { - root = "." + // adjustments for io/fs compatibility: io/fs paths are always relative and + // slash-separated, so a leading slash (e.g. "/" or "/dist") is never a valid + // fs path and makes isFile's fs.FS.Open fail, which sends every request to + // the PathNotFound handler. Strip it and treat an empty result as the fs root ".". + if config.FS != nil { + root = strings.TrimLeft(root, "/") + if root == "" { + root = "." + } } return func(c fiber.Ctx) error { diff --git a/src/vendor/github.com/gofiber/fiber/v3/path.go b/src/vendor/github.com/gofiber/fiber/v3/path.go index e5a9d6fd..e41f0734 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/path.go +++ b/src/vendor/github.com/gofiber/fiber/v3/path.go @@ -17,10 +17,22 @@ import ( "github.com/gofiber/utils/v2" utilsbytes "github.com/gofiber/utils/v2/bytes" utilsstrings "github.com/gofiber/utils/v2/strings" + "github.com/valyala/fasthttp" ) -// routeParser holds the path segments and param names +// routeParser holds the path segments and param names. +// +// The slash bounds lead the struct on purpose: Route.match consults them for +// every parametric candidate it rejects, and Route embeds routeParser so that +// they share a cache line with the other fields the router reads while +// scanning. Keep them first when adding fields. +// +//nolint:govet // fieldalignment: the slash bounds lead deliberately, see above type routeParser struct { + minSlashes int32 // minimum number of '/' a matching detection path can contain + maxSlashes int32 // maximum number of '/' a matching detection path can contain; only valid when maxBounded is true + maxBounded bool // false when a parameter can swallow '/', making the maximum unknowable; false also disables the max check + constParam bool // route is exactly one const segment + one plain trailing param; see matchConstParam segs []*routeSegment // the parsed segments of the route params []string // that parameter names the parsed route wildCardCount int // number of wildcard parameters, used internally to give the wildcard parameter its number @@ -145,6 +157,8 @@ var constraintNameToID = map[string]TypeConstraint{ var ( // slash has a special role, unlike the other parameters it must not be interpreted as a parameter routeDelimiter = []byte{slashDelimiter, '-', '.'} + // slashDelimiterBytes is the byte-slice form of slashDelimiter for bytes.Count + slashDelimiterBytes = []byte{slashDelimiter} // list of chars for the parameter recognizing parameterStartChars = [256]bool{ wildcardParam: true, @@ -196,15 +210,28 @@ func RoutePatternMatch(path, pattern string, cfg ...Config) bool { patternPretty := []byte(pattern) - // Case-sensitive routing, all to lowercase + // Mirror DefaultCtx.configDependentPaths: the router derives a separate + // detection path (percent-decoded when UnescapePath is set, lowercased when + // CaseSensitive is off, trailing slashes stripped when StrictRouting is + // off) and keeps c.path untouched. getMatch takes both — the detection path + // to match against and the untouched path to slice parameter values out of + // — so constraints see the same bytes here as they do in the router. + if config.UnescapePath { + path = utils.UnsafeString(fasthttp.AppendUnquotedArg(nil, utils.UnsafeBytes(path))) + } + + detectionPath := path if !config.CaseSensitive { patternPretty = utilsbytes.UnsafeToLower(patternPretty) - path = utilsstrings.ToLower(path) + detectionPath = utilsstrings.ToLower(detectionPath) } // Strict routing, remove trailing slashes if !config.StrictRouting && len(patternPretty) > 1 { patternPretty = utils.TrimRight(patternPretty, '/') } + if !config.StrictRouting && len(detectionPath) > 1 { + detectionPath = utils.TrimRight(detectionPath, '/') + } parser, _ := routerParserPool.Get().(*routeParser) //nolint:errcheck // only contains routeParser parser.reset() @@ -212,21 +239,24 @@ func RoutePatternMatch(path, pattern string, cfg ...Config) bool { parser.parseRoute(patternStr, config.RegexHandler) defer routerParserPool.Put(parser) - // '*' wildcard matches any path - if (patternStr == "/" && path == "/") || patternStr == "/*" { + // '*' wildcard matches any path. App.register derives the root/star flags + // from the escape-stripped pattern, so compare against that form: "/\*" is + // an escaped literal here but registers as a star route. + patternClean := RemoveEscapeChar(patternStr) + if (patternClean == "/" && detectionPath == "/") || patternClean == "/*" { return true } // Does this route have parameters if len(parser.params) > 0 { - if match := parser.getMatch(path, path, &ctxParams, false); match { + if match := parser.getMatch(detectionPath, path, &ctxParams, false); match { return true } } // Check for a simple match patternPretty = RemoveEscapeCharBytes(patternPretty) - return string(patternPretty) == path + return string(patternPretty) == detectionPath } func (parser *routeParser) reset() { @@ -234,6 +264,10 @@ func (parser *routeParser) reset() { parser.params = parser.params[:0] parser.wildCardCount = 0 parser.plusCount = 0 + parser.minSlashes = 0 + parser.maxSlashes = 0 + parser.maxBounded = false + parser.constParam = false } // parseRoute analyzes the route and divides it into segments for constant areas and parameters, @@ -258,6 +292,62 @@ func (parser *routeParser) parseRoute(pattern string, regexHandler any, customCo parser.segs[len(parser.segs)-1].IsLast = true } parser.segs = addParameterMetaInfo(parser.segs) + parser.constParam = isConstParamShape(parser.segs) +} + +// isConstParamShape reports whether segs is the "/const/:param" shape that +// matchConstParam specializes: exactly one constant segment followed by one +// plain trailing parameter. Every condition here is one the specialized body +// assumes rather than re-checks, so keep the two in step. +func isConstParamShape(segs []*routeSegment) bool { + if len(segs) != 2 { + return false + } + c, p := segs[0], segs[1] + return !c.IsParam && !c.HasOptionalSlash && + p.IsParam && p.IsLast && !p.IsGreedy && !p.IsOptional && len(p.Constraints) == 0 +} + +// computeSlashBounds precomputes the minimum and maximum number of '/' bytes a +// detection path can contain and still match this pattern, so the router can +// reject candidates with an integer compare before walking their segments. +// The unbounded cases mirror the findParamLen branches that let a parameter +// swallow '/'; Test_Route_Match_SlashBoundsDifferential guards the pairing. +func (parser *routeParser) computeSlashBounds() { + minSlashes := 0 + maxSlashes := 0 + bounded := true + for _, seg := range parser.segs { + if seg.IsParam { + switch { + case seg.IsGreedy: + // '*' and '+' match across '/' + bounded = false + case !seg.IsLast && seg.Length == 1: + // adjacent parameters consume one byte each, possibly a '/' + bounded = false + case !seg.IsLast && len(seg.ComparePart) == 1 && seg.ComparePart[0] != slashDelimiter: + // findParamLen's single-byte IndexByte search has no slash guard + bounded = false + } + // otherwise a non-greedy parameter never contains '/': the last + // segment stops at the next '/', and the multi-byte ComparePart + // branch rejects parameters that would span one + continue + } + n := strings.Count(seg.Const, string(slashDelimiter)) + minSlashes += n + maxSlashes += n + if seg.HasOptionalSlash { + // getMatch may drop the trailing '/' of this const part + minSlashes-- + } + } + parser.minSlashes = int32(minSlashes) + if bounded { + parser.maxSlashes = int32(maxSlashes) + parser.maxBounded = true + } } // parseRoute analyzes the route and divides it into segments for constant areas and parameters, @@ -265,6 +355,9 @@ func (parser *routeParser) parseRoute(pattern string, regexHandler any, customCo func parseRoute(pattern string, regexHandler any, customConstraints ...CustomConstraint) routeParser { parser := routeParser{} parser.parseRoute(pattern, regexHandler, customConstraints...) + // The slash bounds only speed up the router's candidate scan; computing them + // here keeps them off RoutePatternMatch's per-call path, which never reads them. + parser.computeSlashBounds() // Check if the route has too many parameters if len(parser.params) > maxParams { @@ -511,8 +604,14 @@ func hasPartialMatchBoundary(path string, matchedLength int) bool { // getMatch parses the passed url and tries to match it against the route segments and determine the parameter positions func (parser *routeParser) getMatch(detectionPath, path string, params *[maxParams]string, partialCheck bool) bool { //nolint:revive // Accepting a bool param is fine here + if parser.constParam { + return parser.matchConstParam(detectionPath, path, params, partialCheck) + } + originalDetectionPath := detectionPath - var i, paramsIterator, partLen int + // offset indexes into the never-resliced path; it only advances by bytes consumed + // from detectionPath (never longer than path), so offset+i stays in bounds. + var i, paramsIterator, partLen, offset int for _, segment := range parser.segs { partLen = len(detectionPath) // check const segment @@ -521,6 +620,7 @@ func (parser *routeParser) getMatch(detectionPath, path string, params *[maxPara // is optional part or the const part must match with the given string // check if the end of the segment is an optional slash // the unsigned compare proves 0 <= i <= len(detectionPath), keeping detectionPath[:i] bounds-check free + // NOTE: computeSlashBounds' minSlashes accounts for this optional-slash drop if segment.HasOptionalSlash && partLen == i-1 && detectionPath == segment.Const[:i-1] { i-- } else if uint(i) > uint(len(detectionPath)) || detectionPath[:i] != segment.Const { @@ -533,7 +633,7 @@ func (parser *routeParser) getMatch(detectionPath, path string, params *[maxPara return false } // take over the params positions - params[paramsIterator] = path[:i] + params[paramsIterator] = path[offset : offset+i] if !segment.IsOptional || i != 0 { // check constraint @@ -549,7 +649,8 @@ func (parser *routeParser) getMatch(detectionPath, path string, params *[maxPara // reduce founded part from the string if partLen > 0 { - detectionPath, path = detectionPath[i:], path[i:] + detectionPath = detectionPath[i:] + offset += i } } if detectionPath != "" { @@ -565,8 +666,58 @@ func (parser *routeParser) getMatch(detectionPath, path string, params *[maxPara return true } +// matchConstParam is getMatch specialized to the "/const/:param" shape, which +// is what most REST endpoints look like ("/user/keys/:key_id"). It is a +// straight-line rewrite of the generic segment walk for that shape, not a +// different matcher: isConstParamShape gates on exactly the properties that +// let each step below collapse. +// +// Walking the generic loop for two segments costs a pointer chase per segment, +// the IsParam/IsOptional/IsLast branches, the constraint loop and the reslice +// bookkeeping, all to reach the same three operations this does directly. +func (parser *routeParser) matchConstParam(detectionPath, path string, params *[maxParams]string, partialCheck bool) bool { //nolint:revive // mirrors getMatch's signature + constSeg := parser.segs[0] + + // Same guard as the generic const branch; HasOptionalSlash is excluded by + // the gate, so the trailing-slash-drop case cannot arise here. + n := constSeg.Length + if uint(n) > uint(len(detectionPath)) || detectionPath[:n] != constSeg.Const { + return false + } + + // The parameter is last and non-greedy, so findParamLenForLastSegment would + // stop it at the next '/', or take the remainder when there is none. + rest := detectionPath[n:] + i := len(rest) + if idx := strings.IndexByte(rest, slashDelimiter); idx != -1 { + i = idx + } + // The gate excludes optional parameters, so an empty one is no match. + if i == 0 { + return false + } + + // offset into path, never resliced, exactly as the generic loop tracks it + params[0] = path[n : n+i] + + if i == len(rest) { + return true + } + // Leftover detection path: only prefix (use) routes may stop short, and + // only on a segment boundary. + if !partialCheck { + return false + } + return hasPartialMatchBoundary(detectionPath, n+i) +} + // findParamLen for the expressjs wildcard behavior (right to left greedy) // look at the other segments and take what is left for the wildcard from right to left +// +// NOTE: computeSlashBounds mirrors which branches here let a parameter consume +// '/' (greedy, adjacent Length==1, single-byte ComparePart). When changing how +// parameters consume '/', update computeSlashBounds or the router's slash-count +// quick-reject will wrongly filter routes. func findParamLen(s string, segment *routeSegment) int { if segment.IsLast { return findParamLenForLastSegment(s, segment) diff --git a/src/vendor/github.com/gofiber/fiber/v3/redirect.go b/src/vendor/github.com/gofiber/fiber/v3/redirect.go index eb4dbf0b..7d267ff5 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/redirect.go +++ b/src/vendor/github.com/gofiber/fiber/v3/redirect.go @@ -12,11 +12,10 @@ import ( "sync" "github.com/gofiber/utils/v2" - utilsbytes "github.com/gofiber/utils/v2/bytes" "github.com/valyala/bytebufferpool" "github.com/valyala/fasthttp" - "github.com/gofiber/fiber/v3/binder" + "github.com/gofiber/fiber/v3/internal/fieldname" "github.com/gofiber/fiber/v3/internal/schemehost" ) @@ -127,6 +126,10 @@ func ReleaseRedirect(r *Redirect) { func (r *Redirect) release() { r.status = StatusSeeOther + // Zero before truncating: WithInput copies the whole request body into these + // entries, and a bare [:0] leaves those strings reachable from the backing + // array for as long as the pooled *Redirect lives. + clear(r.messages[:cap(r.messages)]) r.messages = r.messages[:0] r.c = nil } @@ -192,9 +195,7 @@ func (r *Redirect) With(key, value string, level ...uint8) *Redirect { // This method can send form, multipart form, query data to redirected route. // You can get them by using: Redirect().OldInputs(), Redirect().OldInput() func (r *Redirect) WithInput() *Redirect { - // Get content-type - ctype := utils.UnsafeString(utilsbytes.UnsafeToLower(r.c.RequestCtx().Request.Header.ContentType())) - ctype = binder.FilterFlags(utils.ParseVendorSpecificContentType(ctype)) + ctype := bindMediaType(&r.c.RequestCtx().Request.Header) oldInput := acquireOldInput() defer releaseOldInput(oldInput) @@ -346,7 +347,8 @@ func (r *Redirect) Route(name string, config ...RedirectConfig) error { cfg = config[0] } - // Get location from route name + // Get location from route name. The composed path is already held to this + // origin — see asRoutePath — so only the query is left to place. route := r.c.App().GetRoute(name) location, err := r.c.getLocationFromRoute(&route, cfg.Params) if err != nil { @@ -366,27 +368,56 @@ func (r *Redirect) Route(name string, config ...RedirectConfig) error { first = false queryText.WriteString(k) queryText.WriteByte('=') - queryText.WriteString(v) + // Escape the value so characters like &, =, # or + don't break the + // query string. Keys are left as-is to preserve the nested-key + // convention (e.g. `data[0][name]`) used elsewhere. + queryText.B = utils.AppendQueryEscape(queryText.B, v) } - return r.To(location + "?" + r.c.app.toString(queryText.Bytes())) + // Concatenated here rather than in a helper: the result goes straight to + // To, so escape analysis can build it on the stack. Returning it from a + // function cost an allocation per redirect. + query := r.c.app.toString(queryText.Bytes()) + separator, fragment := queryMergePoint(location) + if fragment < 0 { + return r.To(location + separator + query) + } + return r.To(location[:fragment] + separator + query + location[fragment:]) } return r.To(location) } +// queryMergePoint says where a query belongs in location: the separator that +// introduces it, and where the fragment starts, or -1. A parameter spliced into +// a route path may hold both, and appending "?" folded them into one value. +func queryMergePoint(location string) (separator string, fragment int) { //nolint:nonamedreturns // the two results are easy to swap without names + fragment = strings.IndexByte(location, '#') + + query := location + if fragment >= 0 { + query = location[:fragment] + } + if strings.IndexByte(query, '?') >= 0 { + return "&", fragment + } + return "?", fragment +} + // Back redirect to the URL to referer. // It validates that the Referer is same-origin to prevent open redirect attacks. // If the Referer is missing, invalid, or cross-origin, the fallback URL is used. func (r *Redirect) Back(fallback ...string) error { - location := r.c.Get(HeaderReferer) + location := r.refererHeader() if location != "" { - if !strings.HasPrefix(location, "/") || strings.HasPrefix(location, "//") { - parsed, err := url.Parse(location) - if err != nil || (parsed.Scheme != "" && parsed.Host == "") || (parsed.Host != "" && !schemehost.Match(parsed.Scheme, parsed.Host, r.c.Scheme(), r.c.Host())) { - location = "" // Reject invalid or cross-origin referrers - } + // Reject invalid or cross-origin referrers, and redirect to the + // normalized form so every client resolves it the same way the + // same-origin check did. + normalized, ok := r.sameOriginReferer(location) + if !ok { + normalized = "" } + location = normalized } if location == "" { @@ -403,29 +434,136 @@ func (r *Redirect) Back(fallback ...string) error { return r.To(location) } -// parseAndClearFlashMessages is a method to get flash messages before they are getting removed -func (r *Redirect) parseAndClearFlashMessages() { - // parse flash messages - cookieValue, err := hex.DecodeString(r.c.Cookies(FlashCookieName)) - if err != nil { - return +// refererHeader returns the Referer, matching the field name the way a recipient +// must (RFC 9110 §5.1). Ctx.Get is byte-exact, so under DisableHeaderNormalizing +// a lower-case "referer:" read as absent and Back always took the fallback. +func (r *Redirect) refererHeader() string { + if v := r.c.Get(HeaderReferer); v != "" { + return v + } + if !r.c.app.config.DisableHeaderNormalizing { + return "" + } + + return r.c.app.toString(fieldname.First(&r.c.fasthttp.Request.Header, HeaderReferer, false)) +} + +// sameOriginReferer reports whether the Referer resolves back to the origin now +// being served, returning the normalized form safe to echo. A browser's +// normalization decides that, not net/url: " //evil.com", "/\evil.com", "///x". +func (r *Redirect) sameOriginReferer(location string) (string, bool) { + // The normalized value is what gets redirected to, so a client that does + // not apply these rules itself cannot resolve a different origin than the + // one validated here. + location = normalizeRefererURL(location) + if location == "" { + return "", false } - _, err = r.c.flashMessages.UnmarshalMsg(cookieValue) + // An absolute path stays on the current origin, but "//host" is a + // network-path reference that switches to another one. + if location[0] == '/' && !strings.HasPrefix(location, "//") { + return location, true + } + + parsed, err := url.Parse(location) if err != nil { - return + return "", false } + if parsed.Host == "" { + // A scheme with no authority ("javascript:", "mailto:") is no same-origin + // reference; anything else is a relative path — except an empty authority + // ("//?x", "//#f", "//@"), which names no origin and resolves nowhere. + return location, parsed.Scheme == "" && !strings.HasPrefix(location, "//") + } + + return location, schemehost.Match(parsed.Scheme, parsed.Host, r.c.Scheme(), r.c.Host()) +} +// normalizeRefererURL applies the parts of the WHATWG parser that decide which +// origin a Referer resolves to: strip surrounding C0 controls, drop tab and +// newline, fold backslashes, collapse a leading slash run to two. +func normalizeRefererURL(location string) string { + location = strings.TrimFunc(location, func(c rune) bool { return c <= ' ' }) + + var b []byte + inPath := true + for i := 0; i < len(location); i++ { + c := location[i] + switch { + case c == '\t' || c == '\n' || c == '\r': + if b == nil { + b = append(make([]byte, 0, len(location)), location[:i]...) + } + continue + case c == '?' || c == '#': + inPath = false + case c == '\\' && inPath: + if b == nil { + b = append(make([]byte, 0, len(location)), location[:i]...) + } + b = append(b, '/') + continue + } + if b != nil { + b = append(b, c) + } + } + if b != nil { + location = string(b) + } + + // "///evil.com" reaches the same authority state as "//evil.com", so keep + // at most the two slashes that introduce it. + if strings.HasPrefix(location, "//") { + n := 0 + for n < len(location) && location[n] == '/' { + n++ + } + if n == len(location) { + return "/" + } + location = location[n-2:] + } + + return location +} + +// parseAndClearFlashMessages is a method to get flash messages before they are getting removed +func (r *Redirect) parseAndClearFlashMessages() { + // UnmarshalMsg re-slices this capacity rather than allocating, and the + // generated decoder assigns only the fields the message carries — so an empty + // map keeps whatever the slot held, and the destination must arrive zeroed. + clear(r.c.flashMessages[:cap(r.c.flashMessages)]) + r.c.flashMessages = r.c.flashMessages[:0] + + // parse flash messages + if cookieValue, err := hex.DecodeString(r.c.Cookies(FlashCookieName)); err == nil { + if _, err := r.c.flashMessages.UnmarshalMsg(cookieValue); err != nil { + // UnmarshalMsg re-slices to the length the payload declared before + // it decodes any element, so a failure partway leaves the slice + // holding zero-valued entries. Drop them. + r.c.flashMessages = r.c.flashMessages[:0] + } + } + + // Expire the cookie whatever the payload turned out to be, including the + // hex-decode failure above. A value this application cannot decode it never + // will, so leaving it means re-running hex and msgp on every later request. r.c.Cookie(&Cookie{ - Name: FlashCookieName, - Value: "", - Path: "/", - MaxAge: -1, + Name: FlashCookieName, + Value: "", + Path: "/", + MaxAge: -1, + HTTPOnly: true, + Secure: r.c.Secure(), }) } -// processFlashMessages is a helper function to process flash messages and old input data -// and set them as cookies +// processFlashMessages sets the flash messages and old input data as cookies. +// +// The payload is hex-encoded, not signed, and WithInput copies the whole form +// into it — so the cookie is HTTPOnly, and Secure whenever the request was TLS. func (r *Redirect) processFlashMessages() { if len(r.messages) == 0 { return @@ -443,5 +581,7 @@ func (r *Redirect) processFlashMessages() { Name: FlashCookieName, Value: r.c.app.toString(dst), SessionOnly: true, + HTTPOnly: true, + Secure: r.c.Secure(), }) } diff --git a/src/vendor/github.com/gofiber/fiber/v3/req.go b/src/vendor/github.com/gofiber/fiber/v3/req.go index 870b1886..2bbbcdb1 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/req.go +++ b/src/vendor/github.com/gofiber/fiber/v3/req.go @@ -6,16 +6,16 @@ import ( "math" "mime/multipart" "net" - "net/netip" - "strconv" "strings" + "time" "github.com/gofiber/utils/v2" - utilsbytes "github.com/gofiber/utils/v2/bytes" utilsstrings "github.com/gofiber/utils/v2/strings" "github.com/valyala/bytebufferpool" "github.com/valyala/fasthttp" "golang.org/x/net/idna" + + "github.com/gofiber/fiber/v3/internal/mediatype" ) // Pre-allocated byte slices for common header comparisons to avoid allocations @@ -157,20 +157,25 @@ func (r *DefaultReq) Body() []byte { request := &r.c.fasthttp.Request - // Get Content-Encoding header - headerEncoding = utils.UnsafeString(utilsbytes.UnsafeToLower(request.Header.ContentEncoding())) - - // If no encoding is provided, return the original body - if headerEncoding == "" { + // Fast path: no Content-Encoding header at all. ContentEncoding uses the + // pre-normalized key constant, so absence costs a single cheap lookup. + // An empty value is still a present field line and must be joined with + // duplicates below before RFC 9110 empty-list elements are ignored. + if request.Header.ContentEncoding() == nil { return r.getBody() } + // Multiple field lines form one list (RFC 9110 §5.2), so join before splitting. + // The result aliases the header storage, so fold into a new string; ToLower + // returns its input unchanged without an uppercase byte, so this stays free. + encodedBytes := peekJoinedRequestHeader(&request.Header, HeaderContentEncoding) + headerEncoding = utilsstrings.ToLower(utils.UnsafeString(encodedBytes)) + // Split and get the encodings list, in order to attend the // rule defined at: https://www.rfc-editor.org/rfc/rfc9110#section-8.4-5 + // The splitter drops empty list elements (RFC 9110 Section 5.6.1.2), and + // headerEncoding was already lowercased wholesale above. encodingOrder = getSplicedStrList(headerEncoding, encodingOrder) - for i := range encodingOrder { - encodingOrder[i] = utilsstrings.UnsafeToLower(encodingOrder[i]) - } if len(encodingOrder) == 0 { return r.getBody() } @@ -229,13 +234,17 @@ func (c *DefaultCtx) Referer() string { } // AcceptLanguage returns the Accept-Language request header. +// Repeated field lines are combined into one comma-joined list +// (RFC 9110 Section 5.2), matching what AcceptsLanguages negotiates on. func (c *DefaultCtx) AcceptLanguage() string { - return c.app.toString(c.fasthttp.Request.Header.Peek(HeaderAcceptLanguage)) + return c.app.toString(joinHeaderValues(c.fasthttp.Request.Header.PeekAll(HeaderAcceptLanguage))) } // AcceptEncoding returns the Accept-Encoding request header. +// Repeated field lines are combined into one comma-joined list +// (RFC 9110 Section 5.2), matching what AcceptsEncodings negotiates on. func (c *DefaultCtx) AcceptEncoding() string { - return c.app.toString(c.fasthttp.Request.Header.Peek(HeaderAcceptEncoding)) + return c.app.toString(joinHeaderValues(c.fasthttp.Request.Header.PeekAll(HeaderAcceptEncoding))) } // HasHeader reports whether the request includes a header with the given key. @@ -259,44 +268,78 @@ func (c *DefaultCtx) MediaType() string { // Charset returns the charset parameter from the Content-Type header. func (c *DefaultCtx) Charset() string { contentType := c.fasthttp.Request.Header.ContentType() - if len(contentType) == 0 { - return "" - } - _, after, ok := bytes.Cut(contentType, []byte{';'}) + _, params, ok := bytes.Cut(contentType, []byte{';'}) if !ok { return "" } - params := after for len(params) > 0 { - params = utils.TrimSpace(params) - if len(params) == 0 { - return "" - } + // Slice off the next parameter at the next ";" that sits outside a + // quoted-string: parameter values may be quoted and contain ";" + // (RFC 9110 Section 5.6.6). A DQUOTE only opens a quoted-string at + // the start of a value (after an "=" plus optional whitespace), so a + // stray quote later in an unquoted value cannot swallow the rest of + // the header. param := params - if idx := bytes.IndexByte(params, ';'); idx != -1 { - param = params[:idx] - params = params[idx+1:] + end := -1 + inQuotes := false + escaped := false + expectValue := false + scan: + for i := 0; i < len(params); i++ { + ch := params[i] + switch { + case escaped: + escaped = false + case inQuotes: + switch ch { + case '\\': + escaped = true + case '"': + inQuotes = false + } + case ch == '=': + expectValue = true + case ch == '"' && expectValue: + inQuotes = true + expectValue = false + case ch == ';': + end = i + break scan + case ch != ' ' && ch != '\t': + expectValue = false + } + } + if end >= 0 { + param = params[:end] + params = params[end+1:] } else { params = nil } - param = utils.TrimSpace(param) - if len(param) == 0 { + name, value, ok := bytes.Cut(param, []byte{'='}) + if !ok || !utils.EqualFold(utils.TrimSpace(name), []byte("charset")) { continue } - before, after, ok := bytes.Cut(param, []byte{'='}) - if !ok { - continue - } - name := utils.TrimSpace(before) - if !bytes.EqualFold(name, []byte("charset")) { + v := utils.TrimSpace(value) + if len(v) > 0 && v[0] == '"' { + // A quoted value must be a complete quoted-string, and its + // quoted-pairs must be replaced with the escaped octet + // (RFC 9110 Section 5.6.4). + if len(v) < 2 || v[len(v)-1] != '"' { + return "" + } + unescaped, err := unescapeHeaderValue(v[1 : len(v)-1]) + if err != nil { + return "" + } + v = unescaped + } else if bytes.IndexByte(v, '"') >= 0 { + // A bare token must not contain DQUOTE; skip the invalid + // parameter instead of surfacing garbage, so a well-formed + // charset parameter later in the header can still be found. continue } - value := utils.TrimSpace(after) - if len(value) >= 2 && value[0] == '"' && value[len(value)-1] == '"' { - value = value[1 : len(value)-1] - } - return c.app.toString(value) + return c.app.toString(v) } return "" } @@ -370,7 +413,19 @@ func (r *DefaultReq) FormFile(key string) (*multipart.FileHeader, error) { // Make copies or use the Immutable setting instead. // When the request is a multipart form, it is parsed using the application's // BodyLimit so the configured limit is consistently enforced. +// +// On a form request this lowercases the case-insensitive parts of the request's +// own Content-Type, so a value obtained earlier from Get(HeaderContentType) — +// which aliases those bytes unless Immutable is set — can change during the +// call. Copy it first if you need it to outlive one. func (r *DefaultReq) FormValue(key string, defaultValue ...string) string { + // fasthttp locates the urlencoded body and multipart boundary + // case-sensitively, so a legal "Multipart/Form-Data" yielded nothing here. + // Guarded, because the fold rewrites the request's own bytes. + if mediatype.IsForm(r.c.fasthttp.Request.Header.ContentType()) { + mediatype.NormalizeRequestContentType(&r.c.fasthttp.Request.Header) + } + if r.c.IsMultipart() { // For multipart requests, parse the form using the application's BodyLimit. // fasthttp's FormValue would otherwise re-parse with its default 8 MiB limit, @@ -398,15 +453,32 @@ func (r *DefaultReq) FormValue(key string, defaultValue ...string) string { // Fresh returns true when the response is still “fresh” in the client's cache, // otherwise false is returned to indicate that the client cache is now stale // and the full response should be sent. +// Freshness only applies to GET and HEAD requests; for any other method false is +// returned, as RFC 9110 defines 304 Not Modified only for those methods and +// requires If-Modified-Since to be ignored otherwise. // When a client sends the Cache-Control: no-cache request header to indicate an end-to-end // reload request, this module will return false to make handling these requests transparent. // https://github.com/jshttp/fresh/blob/master/index.js#L33 func (r *DefaultReq) Fresh() bool { + // Freshness only applies to GET and HEAD requests: a 304 Not Modified + // response is defined for those methods only, and RFC 9110 Section 13.1.3 + // requires If-Modified-Since to be ignored for any other method. + // A negative methodInt means the method is not registered at all, so it + // cannot be GET or HEAD (and must not be used to index RequestMethods). + if r.c.methodInt < 0 { + return false + } + if method := r.c.app.method(r.c.methodInt); method != MethodGet && method != MethodHead { + return false + } + header := &r.c.fasthttp.Request.Header // fields + // List-based fields may be split across multiple field lines, which are + // semantically one comma-joined list (RFC 9110 Section 5.2). modifiedSince := header.Peek(HeaderIfModifiedSince) - noneMatch := header.Peek(HeaderIfNoneMatch) + noneMatch := joinHeaderValues(header.PeekAll(HeaderIfNoneMatch)) // unconditional request if len(modifiedSince) == 0 && len(noneMatch) == 0 { @@ -416,7 +488,7 @@ func (r *DefaultReq) Fresh() bool { // Always return stale when Cache-Control: no-cache // to support end-to-end reload requests // https://www.rfc-editor.org/rfc/rfc9111#section-5.2.1.4 - cacheControl := header.Peek(HeaderCacheControl) + cacheControl := joinHeaderValues(header.PeekAll(HeaderCacheControl)) if len(cacheControl) > 0 && isNoCache(utils.UnsafeString(cacheControl)) { return false } @@ -445,7 +517,7 @@ func (r *DefaultReq) Fresh() bool { if len(lastModified) == 0 { return false } - lastModifiedTime, err := fasthttp.ParseHTTPDate(lastModified) + lastModifiedTime, err := parseHTTPDate(lastModified) if err != nil { return false } @@ -453,7 +525,7 @@ func (r *DefaultReq) Fresh() bool { // Last-Modified it was given. Identical, already-validated dates are // equal, so skip the second parse and comparison. if !bytes.Equal(lastModified, modifiedSince) { - modifiedSinceTime, err := fasthttp.ParseHTTPDate(modifiedSince) + modifiedSinceTime, err := parseHTTPDate(modifiedSince) if err != nil { return false } @@ -465,6 +537,24 @@ func (r *DefaultReq) Fresh() bool { return true } +// parseHTTPDate parses an HTTP-date field value. RFC 9110 Section 5.6.7 +// requires recipients to accept the obsolete RFC 850 and ANSI C asctime() +// formats in addition to the preferred IMF-fixdate; utils.ParseHTTPDate +// covers all three with net/http.ParseTime semantics, taking an +// allocation-free fast path for canonical IMF-fixdate input. Unlike +// net/http.ParseTime it also tolerates surrounding ASCII whitespace — +// deliberate here, matching RFC 9110 §5.5's exclusion of leading and +// trailing OWS from field values. +func parseHTTPDate(date []byte) (time.Time, error) { + t, err := utils.ParseHTTPDate(date) + if err != nil { + // Callers only nil-check the error; skip wrapping to avoid an + // allocation for every malformed client-supplied date. + return time.Time{}, err //nolint:wrapcheck // see above + } + return t, nil +} + // Get returns the HTTP request header specified by field. // Field names are case-insensitive // Returned value is only valid within the handler. Do not store any references. @@ -538,7 +628,7 @@ func (r *DefaultReq) Port() string { } switch typedAddr := addr.(type) { case *net.TCPAddr: - return strconv.Itoa(typedAddr.Port) + return utils.FormatInt(int64(typedAddr.Port)) case *net.UnixAddr: return "" } @@ -573,7 +663,7 @@ func (r *DefaultReq) IP() string { func (r *DefaultReq) extractIPsFromHeader(header string) []string { // TODO: Reuse the c.extractIPFromHeader func somehow in here - headerValue := r.Get(header) + headerValue := proxyHeaderValue(r, header) // We can't know how many IPs we will return, but we will try to guess with this constant division. // Counting ',' makes function slower for about 50ns in general case. @@ -637,10 +727,10 @@ func (r *DefaultReq) extractIPFromHeader(header string) string { app := r.c.app if !app.config.EnableIPValidation { - return r.Get(header) + return proxyHeaderValue(r, header) } - headerValue := r.Get(header) + headerValue := proxyHeaderValue(r, header) hasTrustedProxyConfig := r.hasTrustedProxyConfig() if !hasTrustedProxyConfig { start := 0 @@ -692,6 +782,14 @@ func (r *DefaultReq) extractIPFromHeader(header string) string { return "" } +// proxyHeaderValue combines repeated proxy header field lines as required by +// RFC 9110 Section 5.2. This ensures security-sensitive IP extraction sees the +// complete chain when an adapter or proxy preserves separate field lines. +func proxyHeaderValue(r *DefaultReq, header string) string { + value := peekJoinedRequestHeader(&r.c.fasthttp.Request.Header, header) + return r.c.app.toString(value) +} + func isValidProxyIP(ipStr string) bool { hasIPv4Separator := strings.IndexByte(ipStr, '.') >= 0 hasIPv6Separator := strings.IndexByte(ipStr, ':') >= 0 @@ -710,9 +808,13 @@ func (r *DefaultReq) hasTrustedProxyConfig() bool { func (r *DefaultReq) isTrustedProxyIP(ipStr string) bool { cfg := r.c.app.config.TrustProxyConfig - ip, err := netip.ParseAddr(ipStr) - if err != nil { - return false + // utils.ParseIPv4/ParseIPv6 together accept exactly the strings + // netip.ParseAddr does, without allocating an error for invalid input. + ip, ok := utils.ParseIPv4(ipStr) + if !ok { + if ip, ok = utils.ParseIPv6(ipStr); !ok { + return false + } } if cfg.Loopback && ip.IsLoopback() { @@ -822,22 +924,64 @@ func (r *DefaultReq) Method(override ...string) string { app := r.c.app if len(override) == 0 { // Nothing to override, just return current method from context - return app.method(r.c.methodInt) + return currentMethod(r.c) } - method := utilsstrings.ToUpper(override[0]) + // Method tokens are case-sensitive (RFC 9110 Section 9.1), so try the + // override exactly as given first — this is what keeps mixed-case custom + // methods registered via Config.RequestMethods working. + method := override[0] methodInt := app.methodInt(method) if methodInt == -1 { - // Provided override does not valid HTTP method, no override, return current method - return app.method(r.c.methodInt) + // Fall back to the conventional uppercase form as a convenience for + // the standard methods (e.g. "get" -> "GET"). + method = utilsstrings.ToUpper(method) + methodInt = app.methodInt(method) + } + if methodInt == -1 { + // Provided override is not a registered HTTP method; no override, + // return current method + return currentMethod(r.c) } r.c.methodInt = methodInt + // Method changed; invalidate the lookahead index + r.c.firstMatchIndex = -1 return method } +// currentMethod resolves the context's method, falling back to the raw +// request header value when the method is not registered in RequestMethods, +// so unregistered methods are reported instead of panicking. +// It is a package-level function (not a method) to stay off the generated +// Req/Ctx interfaces. +func currentMethod(c *DefaultCtx) string { + // app.method owns the definition of "unregistered" (it bounds-checks + // methodInt and returns "" for anything out of range). + if m := c.app.method(c.methodInt); m != "" { + return m + } + // Copy the raw header bytes: every other return path yields a stable + // string from RequestMethods, so callers may retain the result beyond + // the handler; an unsafe alias into the request buffer would be + // silently corrupted on connection reuse. + return string(c.fasthttp.Request.Header.Method()) +} + // MultipartForm parse form entries from binary. // This returns a map[string][]string, so given a key, the value will be a string slice. +// +// On a form request this lowercases the case-insensitive parts of the request's +// own Content-Type, so a value obtained earlier from Get(HeaderContentType) — +// which aliases those bytes unless Immutable is set — can change during the +// call. Copy it first if you need it to outlive one. func (r *DefaultReq) MultipartForm() (*multipart.Form, error) { + // fasthttp matches both "multipart/form-data" and the "boundary=" parameter + // name case-sensitively, so fold first. FormFile and SaveFile come through + // here too. Guarded like FormValue: the fold writes. + if mediatype.IsForm(r.c.fasthttp.Request.Header.ContentType()) { + mediatype.NormalizeRequestContentType(&r.c.fasthttp.Request.Header) + } + return r.c.fasthttp.MultipartFormWithLimit(r.c.app.config.BodyLimit) } @@ -924,21 +1068,39 @@ func (r *DefaultReq) Scheme() string { utils.EqualFold(key, xForwardedProtocolBytes) { v := app.toString(val) if before, _, found := strings.Cut(v, ","); found { - scheme = utils.TrimSpace(before) - } else { - scheme = utils.TrimSpace(v) + v = before + } + if forwarded, ok := forwardedScheme(v); ok { + scheme = forwarded } } else if utils.EqualFold(key, xForwardedSslBytes) && utils.EqualFold(val, onBytes) { scheme = schemeHTTPS } case utils.EqualFold(key, xURLSchemeBytes): - scheme = utils.TrimSpace(app.toString(val)) + if forwarded, ok := forwardedScheme(app.toString(val)); ok { + scheme = forwarded + } default: continue } } - return utilsstrings.ToLower(utils.TrimSpace(scheme)) + return scheme +} + +// forwardedScheme canonicalizes a scheme announced by a proxy header. Only +// "http" and "https": the value is spliced into a URL (BaseURL) and compared for +// origin equality (CSRF, Redirect.Back). Rejecting leaves the prior scheme. +func forwardedScheme(value string) (string, bool) { + value = utils.TrimSpace(value) + switch { + case utils.EqualFold(value, schemeHTTPS): + return schemeHTTPS, true + case utils.EqualFold(value, schemeHTTP): + return schemeHTTP, true + default: + return "", false + } } // Protocol returns the HTTP protocol of request: HTTP/1.1 and HTTP/2. @@ -1031,13 +1193,13 @@ func (r *DefaultReq) Range(size int64) (Range, error) { rangeData.Ranges = make([]RangeSet, 0, prealloc) } + // parseBound parses a present (non-empty) range bound. A bound that is + // not a valid integer makes the range-spec, and therefore the whole + // ranges-specifier, invalid (RFC 9110 Section 14.1.1). parseBound := func(value string) (int64, error) { - if value == "" { // empty bound (suffix/prefix range); skip the parser's error alloc - return 0, errRangeBound - } parsed, err := utils.ParseUint(value) if err != nil { - return 0, errRangeBound // sentinel: never surfaced, avoids per-request alloc + return 0, ErrRangeMalformed } if parsed > (math.MaxUint64 >> 1) { return 0, ErrRangeMalformed @@ -1046,27 +1208,39 @@ func (r *DefaultReq) Range(size int64) (Range, error) { } before, after, found := strings.Cut(rangeStr, "=") - if !found || strings.IndexByte(after, '=') >= 0 { - return rangeData, ErrRangeMalformed + if !found { + return Range{}, ErrRangeMalformed } - rangeData.Type = utilsstrings.ToLower(utils.TrimSpace(before)) - if rangeData.Type != "bytes" { - return rangeData, ErrRangeMalformed + if !utils.EqualFold(utils.TrimSpace(before), "bytes") { + // A range unit the server does not understand is not malformed: it + // must be ignored (RFC 9110 Section 14.2), which only the caller can + // do, so signal it distinctly. This check runs before any syntax + // checks on the range-set, since the other-range grammar permits + // characters (such as "=") that byte ranges do not. + return Range{}, ErrRangeUnsupported + } + rangeData.Type = "bytes" + if strings.IndexByte(after, '=') >= 0 { + return Range{}, ErrRangeMalformed } ranges = utils.TrimSpace(after) var ( - singleRange string - moreRanges = ranges - rangeCount int + singleRange string + moreRanges = ranges + elementCount int // every list element, including empty ones (MaxRanges bound) + sawRangeSpec bool // at least one non-empty range-spec was present ) for moreRanges != "" { - rangeCount++ - if rangeCount > maxRanges { + // Empty elements count toward MaxRanges too, so the cap bounds the + // total parsing work per header, not just the accepted range-specs. + elementCount++ + if elementCount > maxRanges { r.c.DefaultRes.Status(StatusRequestedRangeNotSatisfiable) r.c.DefaultRes.Set(HeaderContentRange, "bytes */"+utils.FormatInt(size)) //nolint:staticcheck // It is fine to ignore the static check - return rangeData, ErrRangeTooLarge + return Range{}, ErrRangeTooLarge } + singleRange = moreRanges if i := strings.IndexByte(moreRanges, ','); i >= 0 { singleRange = moreRanges[:i] @@ -1077,31 +1251,62 @@ func (r *DefaultReq) Range(size int64) (Range, error) { singleRange = utils.TrimSpace(singleRange) + // RFC 9110 Section 5.6.1.2: recipients must parse and ignore a + // reasonable number of empty list elements, e.g. "bytes=,0-5" is + // equivalent to "bytes=0-5". + if singleRange == "" { + continue + } + sawRangeSpec = true + var ( startStr, endStr string i int ) if i = strings.IndexByte(singleRange, '-'); i == -1 { - return rangeData, ErrRangeMalformed + return Range{}, ErrRangeMalformed } startStr = utils.TrimSpace(singleRange[:i]) endStr = utils.TrimSpace(singleRange[i+1:]) - start, startErr := parseBound(startStr) - end, endErr := parseBound(endStr) - if errors.Is(startErr, ErrRangeMalformed) || errors.Is(endErr, ErrRangeMalformed) { - return rangeData, ErrRangeMalformed + var ( + start, end int64 + err error + ) + if startStr != "" { + if start, err = parseBound(startStr); err != nil { + return Range{}, err + } + } + if endStr != "" { + if end, err = parseBound(endStr); err != nil { + return Range{}, err + } } - if startErr != nil { // -nnn + switch { + case startStr == "" && endStr == "": + // "-" carries neither a first-byte-pos nor a suffix-length and is + // not a valid range-spec (RFC 9110 Section 14.1.1). + return Range{}, ErrRangeMalformed + case startStr == "": // -nnn (suffix range) start = max(size-end, 0) end = size - 1 - } else if endErr != nil { // nnn- - end = size - 1 - } - if end > size-1 { // limit last-byte-pos to current length + case endStr == "": // nnn- (open-ended range) end = size - 1 + default: // nnn-mmm + // An int-range with a last-byte-pos less than its first-byte-pos + // invalidates the whole ranges-specifier (RFC 9110 Section 14.1.1). + if end < start { + return Range{}, ErrRangeMalformed + } + if end > size-1 { // limit last-byte-pos to current length + end = size - 1 + } } - if start > end || start < 0 { + if start > end { + // Syntactically valid but does not overlap the representation + // (e.g. first-byte-pos beyond EOF or a zero-length suffix); skip + // it and let the satisfiability check below decide. continue } rangeData.Ranges = append(rangeData.Ranges, RangeSet{ @@ -1110,6 +1315,11 @@ func (r *DefaultReq) Range(size int64) (Range, error) { }) } if len(rangeData.Ranges) < 1 { + if !sawRangeSpec { + // Only empty list elements: there was no range-spec at all, so + // the ranges-specifier is invalid rather than unsatisfiable. + return Range{}, ErrRangeMalformed + } r.c.DefaultRes.Status(StatusRequestedRangeNotSatisfiable) r.c.DefaultRes.Set(HeaderContentRange, "bytes */"+utils.FormatInt(size)) //nolint:staticcheck // It is fine to ignore the static check return rangeData, ErrRequestedRangeNotSatisfiable @@ -1225,8 +1435,12 @@ func (r *DefaultReq) IsProxyTrusted() bool { return true } - if _, trusted := config.TrustProxyConfig.ips[ip.String()]; trusted { - return true + // Only stringify the IP when there is an exact-match map to look it up in; + // ip.String() heap-allocates and is wasted work for CIDR-only configs. + if len(config.TrustProxyConfig.ips) > 0 { + if _, trusted := config.TrustProxyConfig.ips[ip.String()]; trusted { + return true + } } for _, ipNet := range config.TrustProxyConfig.ranges { diff --git a/src/vendor/github.com/gofiber/fiber/v3/req_interface_gen.go b/src/vendor/github.com/gofiber/fiber/v3/req_interface_gen.go index fba9b6df..d2b58fb3 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/req_interface_gen.go +++ b/src/vendor/github.com/gofiber/fiber/v3/req_interface_gen.go @@ -63,10 +63,18 @@ type Req interface { // Make copies or use the Immutable setting instead. // When the request is a multipart form, it is parsed using the application's // BodyLimit so the configured limit is consistently enforced. + // + // On a form request this lowercases the case-insensitive parts of the request's + // own Content-Type, so a value obtained earlier from Get(HeaderContentType) — + // which aliases those bytes unless Immutable is set — can change during the + // call. Copy it first if you need it to outlive one. FormValue(key string, defaultValue ...string) string // Fresh returns true when the response is still “fresh” in the client's cache, // otherwise false is returned to indicate that the client cache is now stale // and the full response should be sent. + // Freshness only applies to GET and HEAD requests; for any other method false is + // returned, as RFC 9110 defines 304 Not Modified only for those methods and + // requires If-Modified-Since to be ignored otherwise. // When a client sends the Cache-Control: no-cache request header to indicate an end-to-end // reload request, this module will return false to make handling these requests transparent. // https://github.com/jshttp/fresh/blob/master/index.js#L33 @@ -134,6 +142,11 @@ type Req interface { Method(override ...string) string // MultipartForm parse form entries from binary. // This returns a map[string][]string, so given a key, the value will be a string slice. + // + // On a form request this lowercases the case-insensitive parts of the request's + // own Content-Type, so a value obtained earlier from Get(HeaderContentType) — + // which aliases those bytes unless Immutable is set — can change during the + // call. Copy it first if you need it to outlive one. MultipartForm() (*multipart.Form, error) // OriginalURL contains the original request URL. // Returned value is only valid within the handler. Do not store any references. diff --git a/src/vendor/github.com/gofiber/fiber/v3/res.go b/src/vendor/github.com/gofiber/fiber/v3/res.go index 7f14505c..c147abd9 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/res.go +++ b/src/vendor/github.com/gofiber/fiber/v3/res.go @@ -7,12 +7,10 @@ import ( "io" "io/fs" "net/http" - "net/url" "os" pathpkg "path" "path/filepath" "slices" - "strconv" "strings" "time" "unicode" @@ -137,22 +135,46 @@ func (r *DefaultRes) App() *App { // Append the specified value to the HTTP response header field. // If the header is not already set, it creates the header with the specified value. +// Empty values are skipped: a sender must not generate empty list elements +// (RFC 9110 Section 5.6.1.2). func (r *DefaultRes) Append(field string, values ...string) { if len(values) == 0 { return } - h := r.c.app.toString(r.c.fasthttp.Response.Header.Peek(field)) + // Consider all existing field lines combined (RFC 9110 Section 5.2) so + // the dedup check sees members added on later lines via Header.Add. + existing, multiLine := peekJoinedResponseHeader(&r.c.fasthttp.Response.Header, field) + updated := appendUniqueValues(utils.UnsafeString(existing), values) + if updated == "" { + return + } + if multiLine { + // Set only rewrites the first field line; drop the extras that are + // now folded into the combined value. + r.c.fasthttp.Response.Header.Del(field) + } + r.Set(field, updated) +} + +// appendUniqueValues returns h extended with the non-empty values that are +// not already listed in it, or "" when nothing was added (h only ever grows, +// so a changed result is never empty). +func appendUniqueValues(h string, values []string) string { originalH := h for _, value := range values { + if value == "" { + continue + } if h == "" { h = value } else if !headerContainsValue(h, value) { h += ", " + value } } - if originalH != h { - r.Set(field, h) + if originalH == h { + return "" } + return h } // headerContainsValue checks if a header value already contains the given value @@ -203,6 +225,51 @@ func fallbackFilenameIfInvalid(filename string) string { return filename } +// isExtValueAttrChar reports whether c is an attr-char per RFC 8187 §3.2: +// ALPHA / DIGIT / "!" / "#" / "$" / "&" / "+" / "-" / "." / "^" / "_" / +// "`" / "|" / "~". Every other byte of an ext-value must be pct-encoded. +func isExtValueAttrChar(c byte) bool { + switch { + case c >= 'a' && c <= 'z', c >= 'A' && c <= 'Z', c >= '0' && c <= '9': + return true + } + switch c { + case '!', '#', '$', '&', '+', '-', '.', '^', '_', '`', '|', '~': + return true + default: + return false + } +} + +// encodeExtValue percent-encodes s as the value-chars of an RFC 8187 +// ext-value. URL path/query escaping is not sufficient here: it leaves +// bytes such as ':', '=', and '@' bare, which the ext-value grammar forbids. +func encodeExtValue(s string) string { + const hex = "0123456789ABCDEF" + b := make([]byte, 0, len(s)) + for i := 0; i < len(s); i++ { + c := s[i] + if isExtValueAttrChar(c) { + b = append(b, c) + } else { + b = append(b, '%', hex[c>>4], hex[c&0x0F]) + } + } + return string(b) +} + +// contentDispositionAttachment builds an RFC 6266 Content-Disposition value +// for a sanitized filename: the filename parameter is a quoted-string with +// RFC 9110 §5.6.4 escaping, and non-ASCII names additionally carry an +// RFC 8187 filename* ext-value for interoperability. +func contentDispositionAttachment(app *App, fname string) string { + disp := `attachment; filename="` + app.quoteRawString(fname) + `"` + if !utils.IsASCII(fname) { + disp += `; filename*=UTF-8''` + encodeExtValue(fname) + } + return disp +} + // Attachment sets the HTTP response Content-Disposition header field to attachment. func (r *DefaultRes) Attachment(filename ...string) { if len(filename) > 0 { @@ -210,18 +277,7 @@ func (r *DefaultRes) Attachment(filename ...string) { fname = sanitizeFilename(fname) fname = fallbackFilenameIfInvalid(fname) r.Type(filepath.Ext(fname)) - app := r.c.app - var quoted string - if app.isASCII(fname) { - quoted = app.quoteString(fname) - } else { - quoted = app.quoteRawString(fname) - } - disp := `attachment; filename="` + quoted + `"` - if !app.isASCII(fname) { - disp += `; filename*=UTF-8''` + url.PathEscape(fname) - } - r.setCanonical(HeaderContentDisposition, disp) + r.setCanonical(HeaderContentDisposition, contentDispositionAttachment(r.c.app, fname)) return } r.setCanonical(HeaderContentDisposition, "attachment") @@ -250,50 +306,57 @@ func (r *DefaultRes) RequestCtx() *fasthttp.RequestCtx { } // Cookie sets a cookie by passing a cookie struct. +// +// The argument is treated as read-only: the normalization this method applies +// (default Path, SessionOnly, and the Secure implied by SameSite=None or +// Partitioned) happens on a local copy, so a caller may reuse the same *Cookie +// template across requests. func (r *DefaultRes) Cookie(cookie *Cookie) { - if cookie.Path == "" { - cookie.Path = "/" + c := *cookie + + if c.Path == "" { + c.Path = "/" } - if cookie.SessionOnly { - cookie.MaxAge = 0 - cookie.Expires = time.Time{} + if c.SessionOnly { + c.MaxAge = 0 + c.Expires = time.Time{} } var sameSite http.SameSite switch { - case utils.EqualFold(cookie.SameSite, CookieSameSiteStrictMode): + case utils.EqualFold(c.SameSite, CookieSameSiteStrictMode): sameSite = http.SameSiteStrictMode - case utils.EqualFold(cookie.SameSite, CookieSameSiteNoneMode): + case utils.EqualFold(c.SameSite, CookieSameSiteNoneMode): sameSite = http.SameSiteNoneMode // SameSite=None requires Secure=true per RFC and browser requirements - cookie.Secure = true - case utils.EqualFold(cookie.SameSite, CookieSameSiteDisabled): + c.Secure = true + case utils.EqualFold(c.SameSite, CookieSameSiteDisabled): sameSite = 0 - case utils.EqualFold(cookie.SameSite, CookieSameSiteLaxMode): + case utils.EqualFold(c.SameSite, CookieSameSiteLaxMode): sameSite = http.SameSiteLaxMode default: sameSite = http.SameSiteLaxMode } // Partitioned requires Secure=true per CHIPS spec - if cookie.Partitioned { - cookie.Secure = true + if c.Partitioned { + c.Secure = true } // create/validate cookie using net/http hc := &http.Cookie{ //nolint:gosec // G124: http.Cookie missing or has insecure Secure, HttpOnly, or SameSite attribute - Name: cookie.Name, - Value: cookie.Value, - Path: cookie.Path, - Domain: cookie.Domain, - Expires: cookie.Expires, - MaxAge: cookie.MaxAge, - Secure: cookie.Secure, - HttpOnly: cookie.HTTPOnly, + Name: c.Name, + Value: c.Value, + Path: c.Path, + Domain: c.Domain, + Expires: c.Expires, + MaxAge: c.MaxAge, + Secure: c.Secure, + HttpOnly: c.HTTPOnly, SameSite: sameSite, - Partitioned: cookie.Partitioned, + Partitioned: c.Partitioned, } if err := hc.Valid(); err != nil { @@ -308,7 +371,7 @@ func (r *DefaultRes) Cookie(cookie *Cookie) { fcookie.SetPath(hc.Path) fcookie.SetDomain(hc.Domain) - if !cookie.SessionOnly { + if !c.SessionOnly { fcookie.SetMaxAge(hc.MaxAge) fcookie.SetExpire(hc.Expires) } @@ -347,18 +410,7 @@ func (r *DefaultRes) Download(file string, filename ...string) error { } fname = sanitizeFilename(fname) fname = fallbackFilenameIfInvalid(fname) - app := r.c.app - var quoted string - if app.isASCII(fname) { - quoted = app.quoteString(fname) - } else { - quoted = app.quoteRawString(fname) - } - disp := `attachment; filename="` + quoted + `"` - if !app.isASCII(fname) { - disp += `; filename*=UTF-8''` + url.PathEscape(fname) - } - r.setCanonical(HeaderContentDisposition, disp) + r.setCanonical(HeaderContentDisposition, contentDispositionAttachment(r.c.app, fname)) return r.SendFile(file) } @@ -369,6 +421,10 @@ func (r *DefaultRes) Response() *fasthttp.Response { return &r.c.fasthttp.Response } +// formatDefaultMediaType is the sentinel MediaType marking a Format handler as +// the fallback. It is not a media type and is never emitted as a Content-Type. +const formatDefaultMediaType = "default" + // Format performs content-negotiation on the Accept HTTP header. // It uses Accepts to select a proper format and calls the matching // user-provided handler function. @@ -388,8 +444,21 @@ func (r *DefaultRes) Format(handlers ...ResFmt) error { r.Vary(HeaderAccept) - if r.c.DefaultReq.Get(HeaderAccept) == "" { - r.c.fasthttp.Response.Header.SetContentType(handlers[0].MediaType) + // Absent means the combined Accept view (RFC 9110 Section 5.2) is empty: + // no field line, or a single empty one. Checked on the raw lines to skip + // the join allocation that multi-line headers would pay. + accepts := r.c.fasthttp.Request.Header.PeekAll(HeaderAccept) + if len(accepts) == 0 || (len(accepts) == 1 && len(accepts[0]) == 0) { + // Without an Accept header the client accepts any media type + // (RFC 9110 Section 12.5.1), so pick the first non-default handler and + // use its media type. The literal "default" is not a media type and + // must not be emitted as a Content-Type value. + for _, h := range handlers { + if h.MediaType != formatDefaultMediaType { + r.c.fasthttp.Response.Header.SetContentType(h.MediaType) + return h.Handler(r.c) + } + } return handlers[0].Handler(r.c) } @@ -400,7 +469,7 @@ func (r *DefaultRes) Format(handlers ...ResFmt) error { types := make([]string, 0, 8) var defaultHandler Handler for _, h := range handlers { - if h.MediaType == "default" { + if h.MediaType == formatDefaultMediaType { defaultHandler = h.Handler continue } @@ -432,6 +501,10 @@ func (r *DefaultRes) Format(handlers ...ResFmt) error { // For more flexible content negotiation, use Format. // If the header is not specified or there is no proper format, text/plain is used. func (r *DefaultRes) AutoFormat(body any) error { + // The response is selected based on the Accept header, so let caches know + // (RFC 9110 Section 12.5.5). + r.Vary(HeaderAccept) + // Get accepted content type accept := r.c.DefaultReq.Accepts("html", "json", "txt", "xml", "msgpack", "cbor") //nolint:staticcheck // It is fine to ignore the static check @@ -557,15 +630,23 @@ func (r *DefaultRes) CBOR(data any, ctype ...string) error { // JSONP sends a JSON response with JSONP support. // This method is identical to JSON, except that it opts-in to JSONP callback support. // By default, the callback name is simply callback. +// +// The callback name is reduced to a JavaScript member expression: everything +// outside [A-Za-z0-9_$.[]] is dropped. Callers routinely take the name straight +// from the query string, which is what JSONP is for, and the name lands +// verbatim in a same-origin text/javascript body — so an unfiltered one would +// let a request supply arbitrary script for the app's own origin. func (r *DefaultRes) JSONP(data any, callback ...string) error { raw, err := r.c.app.config.JSONEncoder(data) if err != nil { return err } - cb := "callback" + cb := defaultJSONPCallback if len(callback) > 0 { - cb = callback[0] + if sanitized := sanitizeJSONPCallback(callback[0]); sanitized != "" { + cb = sanitized + } } // Build JSONP response: callback(data); @@ -584,6 +665,146 @@ func (r *DefaultRes) JSONP(data any, callback ...string) error { return nil } +const defaultJSONPCallback = "callback" + +// isJSONPCallbackByte reports whether b may appear in a JSONP callback name. The +// set spells a JavaScript member expression and admits nothing that could open a +// string, comment or statement. +func isJSONPCallbackByte(b byte) bool { + return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || + (b >= '0' && b <= '9') || + b == '_' || b == '$' || b == '.' || b == '[' || b == ']' +} + +// sanitizeJSONPCallback drops every byte isJSONPCallbackByte rejects, as Express +// and Django do, then requires a member expression, returning "" otherwise. +// Filtering is enough for safety, not correctness: "1.2.3" and "a[" only throw. +func sanitizeJSONPCallback(cb string) string { + i := 0 + for ; i < len(cb); i++ { + if !isJSONPCallbackByte(cb[i]) { + break + } + } + + if i != len(cb) { + out := make([]byte, i, len(cb)) + copy(out, cb[:i]) + for ; i < len(cb); i++ { + if isJSONPCallbackByte(cb[i]) { + out = append(out, cb[i]) + } + } + cb = utils.UnsafeString(out) + } + + if !isJSONPMemberExpression(cb) { + return "" + } + return cb +} + +// isJSONPMemberExpression reports whether cb is a dotted chain of identifiers +// with optional bracket indexing — the shape a JSONP body may legally call. +func isJSONPMemberExpression(cb string) bool { + if cb == "" { + return false + } + // "let" is a keyword only where a "[" follows it, and only at the head: an + // expression statement may not begin "let [", so the body "let[a](…);" is + // read as a destructuring declaration and is a syntax error. "let(…)", + // "let.a(…)" and an inner "cb[let[a]]" are all calls and stay allowed. + if strings.HasPrefix(cb, "let[") { + return false + } + + depth := 0 + atStart := true // expecting the first byte of an identifier + inIndex := false // that first byte follows '[', so a number may stand there + afterClose := false // a ']' just closed an index + numeric := false // the open index began with a digit, so it is a number + isRef := true // the open token is read as a name, not written as a property + start := 0 // first byte of the open token + for i := 0; i < len(cb); i++ { + switch c := cb[i]; c { + case '.': + if atStart || numeric || (isRef && isJSReservedWord(cb[start:i])) { + return false + } + atStart, inIndex, afterClose, isRef = true, false, false, false + case '[': + if atStart || numeric || (isRef && isJSReservedWord(cb[start:i])) { + return false + } + depth++ + atStart, inIndex, afterClose, isRef = true, true, false, true + start = i + 1 + case ']': + if atStart || depth == 0 { + return false + } + if isRef && !numeric && isJSReservedWord(cb[start:i]) { + return false + } + depth-- + afterClose, numeric, isRef = true, false, false + default: + // Only '.', '[' or another ']' may follow a closing bracket, so "cb[0]x" + // is no member expression. Without this the machine would accept it and + // emit a body that does not parse. + if afterClose { + return false + } + if atStart { + // An identifier may not start with a digit. A bracket index may, and + // then it is that number alone: "cb[0]" parses, "cb[0x]" does not. + // Only a token opened by '[' counts — "cb[a.0]" is a property named + // after a dot, where a digit is as illegal as it is at the top level. + if c >= '0' && c <= '9' { + if !inIndex { + return false + } + numeric = true + } + atStart, inIndex = false, false + } else if numeric && (c < '0' || c > '9') { + return false + } + } + } + if isRef && !numeric && isJSReservedWord(cb[start:]) { + return false + } + return depth == 0 && !atStart +} + +// isJSReservedWord reports whether tok is a word JavaScript will not read as a +// name. Only the positions that are read matter — the head of the expression and +// the head inside each index — since "a.for" and "a[b.class]" name properties, +// which any word may do. Emitting "for({…})" instead just ships a syntax error to +// the browser, so those spellings fall back to the default callback. +func isJSReservedWord(tok string) bool { + // Only the words a classic script rejects wherever they stand. A JSONP body + // is loaded by a script tag, so it is parsed under the script goal in sloppy + // mode, and several words that look reserved are ordinary identifiers there. + // + // Absent on purpose: "this", "true", "false" and "null" are keywords, but + // each is a complete expression, so "this.cb" and "cb[true]" parse. "await" + // is reserved only in a module or an async function, and "yield" only in + // strict mode or a generator, so both name a callback here. "let" is + // contextual in a third way and handled where it is read. + switch tok { + case "break", "case", "catch", "class", "const", "continue", + "debugger", "default", "delete", "do", "else", "enum", "export", + "extends", "finally", "for", "function", "if", "import", "in", + "instanceof", "new", "return", "super", "switch", + "throw", "try", "typeof", "var", "void", "while", "with": + return true + default: + return false + } +} + // XML converts any interface or string to XML. // This method also sets the content header to application/xml; charset=utf-8. func (r *DefaultRes) XML(data any) error { @@ -611,7 +832,9 @@ func (r *DefaultRes) Links(link ...string) { bb.WriteByte('>') } else { bb.WriteString(`; rel="`) - bb.WriteString(link[i]) + // The rel value sits inside a quoted-string, so quotes and + // backslashes must be escaped (RFC 9110 Section 5.6.4). + bb.WriteString(r.c.app.quoteRawString(link[i])) bb.WriteString(`",`) } } @@ -766,6 +989,14 @@ func (r *DefaultRes) SendEarlyHints(hints []string) error { for _, h := range hints { r.c.fasthttp.Response.Header.Add("Link", h) } + // A server MUST NOT send a 1xx response to an HTTP/1.0 (or earlier) + // client (RFC 9110 Section 15.2), and fasthttp can only write interim + // responses on real HTTP/1.1 connections, so send the 103 exclusively + // for HTTP/1.1 requests. The Link headers above still go out on the + // final response; only the interim 103 is skipped. + if !r.c.fasthttp.Request.Header.IsHTTP11() { + return nil + } return r.c.fasthttp.EarlyHints() } @@ -826,7 +1057,7 @@ func (r *DefaultRes) SendFile(file string, config ...SendFile) error { maxAge := cfg.MaxAge if maxAge > 0 { - sf.cacheControlValue = "public, max-age=" + strconv.Itoa(maxAge) + sf.cacheControlValue = "public, max-age=" + utils.FormatInt(int64(maxAge)) } // set vars @@ -920,7 +1151,7 @@ func (r *DefaultRes) SendFile(file string, config ...SendFile) error { // Apply cache control header if status != StatusNotFound && status != StatusForbidden { if cfg.ByteRange && hasSendFileSize && response.StatusCode() == StatusRequestedRangeNotSatisfiable && len(response.Header.Peek(HeaderContentRange)) == 0 { - response.Header.Set(HeaderContentRange, "bytes */"+strconv.FormatInt(sendFileSize, 10)) + response.Header.Set(HeaderContentRange, "bytes */"+utils.FormatInt(sendFileSize)) } if cacheControlValue != "" { @@ -1070,8 +1301,34 @@ func shouldIncludeCharset(mimeType string) bool { // Vary adds the given header field to the Vary response header. // This will append the header, if not already listed; otherwise, leaves it listed in the current location. +// Per RFC 9110 Section 12.5.5 the wildcard "*" only has meaning as the sole member of the field: +// once "*" is added (or already present), the header is collapsed to a single "*". func (r *DefaultRes) Vary(fields ...string) { - r.Append(HeaderVary, fields...) + if len(fields) == 0 { + return + } + // Peek without copying: the value is only inspected before any write. + // All field lines are combined (RFC 9110 Section 5.2) so a wildcard on a + // later line added via Header.Add is still honored. + existing, multiLine := peekJoinedResponseHeader(&r.c.fasthttp.Response.Header, HeaderVary) + existingStr := utils.UnsafeString(existing) + if slices.Contains(fields, "*") || headerContainsValue(existingStr, "*") { + if multiLine { + // setCanonical only rewrites the first field line. + r.c.fasthttp.Response.Header.Del(HeaderVary) + } + r.setCanonical(HeaderVary, "*") + return + } + updated := appendUniqueValues(existingStr, fields) + if updated == "" { + return + } + if multiLine { + // Set only rewrites the first field line; fold the extras into one. + r.c.fasthttp.Response.Header.Del(HeaderVary) + } + r.Set(HeaderVary, updated) } // Write appends p into response body. diff --git a/src/vendor/github.com/gofiber/fiber/v3/res_interface_gen.go b/src/vendor/github.com/gofiber/fiber/v3/res_interface_gen.go index 63947e8e..910b06f6 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/res_interface_gen.go +++ b/src/vendor/github.com/gofiber/fiber/v3/res_interface_gen.go @@ -15,6 +15,8 @@ type Res interface { App() *App // Append the specified value to the HTTP response header field. // If the header is not already set, it creates the header with the specified value. + // Empty values are skipped: a sender must not generate empty list elements + // (RFC 9110 Section 5.6.1.2). Append(field string, values ...string) // Attachment sets the HTTP response Content-Disposition header field to attachment. Attachment(filename ...string) @@ -25,6 +27,11 @@ type Res interface { // a cancellation signal, and other values across API boundaries. RequestCtx() *fasthttp.RequestCtx // Cookie sets a cookie by passing a cookie struct. + // + // The argument is treated as read-only: the normalization this method applies + // (default Path, SessionOnly, and the Secure implied by SameSite=None or + // Partitioned) happens on a local copy, so a caller may reuse the same *Cookie + // template across requests. Cookie(cookie *Cookie) // Download transfers the file from path as an attachment. // Typically, browsers will prompt the user for download. @@ -79,6 +86,12 @@ type Res interface { // JSONP sends a JSON response with JSONP support. // This method is identical to JSON, except that it opts-in to JSONP callback support. // By default, the callback name is simply callback. + // + // The callback name is reduced to a JavaScript member expression: everything + // outside [A-Za-z0-9_$.[]] is dropped. Callers routinely take the name straight + // from the query string, which is what JSONP is for, and the name lands + // verbatim in a same-origin text/javascript body — so an unfiltered one would + // let a request supply arbitrary script for the app's own origin. JSONP(data any, callback ...string) error // XML converts any interface or string to XML. // This method also sets the content header to application/xml; charset=utf-8. @@ -147,6 +160,8 @@ type Res interface { Type(extension string, charset ...string) Ctx // Vary adds the given header field to the Vary response header. // This will append the header, if not already listed; otherwise, leaves it listed in the current location. + // Per RFC 9110 Section 12.5.5 the wildcard "*" only has meaning as the sole member of the field: + // once "*" is added (or already present), the header is collapsed to a single "*". Vary(fields ...string) // Write appends p into response body. Write(p []byte) (int, error) diff --git a/src/vendor/github.com/gofiber/fiber/v3/router.go b/src/vendor/github.com/gofiber/fiber/v3/router.go index c18a7bef..757606b6 100644 --- a/src/vendor/github.com/gofiber/fiber/v3/router.go +++ b/src/vendor/github.com/gofiber/fiber/v3/router.go @@ -6,11 +6,14 @@ package fiber import ( "fmt" + "math/bits" "slices" "sync/atomic" + "github.com/gofiber/fiber/v3/internal/urlnorm" "github.com/gofiber/utils/v2" utilsstrings "github.com/gofiber/utils/v2/strings" + "github.com/gofiber/utils/v2/swar" "github.com/valyala/bytebufferpool" "github.com/valyala/fasthttp" ) @@ -44,20 +47,25 @@ type Router interface { } // Route is a struct that holds all metadata for each registered handler. +// +//nolint:govet // fieldalignment: the router's scan dictates this order, see below type Route struct { // ### important: always keep in sync with the copy method "app.copyRoute" and all creations of Route struct ### - group *Group // Group instance. used for routes in groups + // + // Field order is load-bearing. App.next scans a bucket of routes and + // discards most of them, so the fields it needs to do that lead the struct + // and a rejected candidate costs one cache line instead of touching the + // whole thing. prefix/prefixMask come first because they alone reject the + // common case; path, Params' length, the routing flags and routeParser's + // slash bounds follow for the candidates that survive. Keep new routing + // state up here and everything else below routeParser. + + prefix uint64 // leading path bytes packed little-endian, see buildPrefixFilter + prefixMask uint64 // covers the bytes of prefix that are known constants; 0 disables the filter path string // Prettified path - // Public fields - Method string `json:"method"` // HTTP method - Name string `json:"name"` // Route's name - //nolint:revive // Having both a Path (uppercase) and a path (lowercase) is fine - Path string `json:"path"` // Original registered route path - Params []string `json:"params"` // Case-sensitive param keys - Handlers []Handler `json:"-"` // Ctx handlers - routeParser routeParser // Parameter parser + Params []string `json:"params"` // Case-sensitive param keys // Data for routing use bool // USE matches path prefixes @@ -66,6 +74,18 @@ type Route struct { root bool // Path equals '/' autoHead bool // Automatically generated HEAD route caseSensitive bool // Whether parameter matching is case-sensitive + + routeParser routeParser // Parameter parser + + Handlers []Handler `json:"-"` // Ctx handlers + + group *Group // Group instance. used for routes in groups + + // Public fields + Method string `json:"method"` // HTTP method + Name string `json:"name"` // Route's name + //nolint:revive // Having both a Path (uppercase) and a path (lowercase) is fine + Path string `json:"path"` // Original registered route path } var ( @@ -73,6 +93,117 @@ var ( preferredPlusGreedyParameters = []string{"+", "*"} ) +// routeTree is a flat, open-addressed index from a tree-path hash to the route +// bucket of a single HTTP method. It serves the request-time lookup that used +// to go through treeStack's map[int][]*Route, where hashing the key and walking +// the bucket group accounted for ~14% of a routed request in CPU profiles. +// Here the lookup is a multiply-shift plus a short linear probe, and a miss +// resolves to the globals bucket inline instead of costing a second lookup. +type routeTree struct { + // hashes is a power-of-two sized probe table holding the tree-path hash of + // each slot, 0 meaning free. It is kept apart from the buckets so a probe + // walks 4 bytes per slot (16 per cache line) instead of a slice header. + // nil when the method has no prefixed bucket and every request hits globals. + hashes []int32 + // buckets is parallel to hashes and holds the routes of each occupied slot + buckets [][]*Route + // globals is the bucket for tree hash 0, which is also where misses go + globals []*Route + // mask is len(hashes)-1, used to wrap the probe + mask uint32 + // shift is 32-log2(len(hashes)), so slot keeps the high bits of the + // multiply. A fixed shift would cap the index at whatever it exposes and + // leave larger tables with an unreachable upper half. + shift uint32 +} + +// routeTreeHashMul is the golden-ratio constant used to spread tree hashes, +// whose low bits are just the third path byte, across the probe table. +const routeTreeHashMul = 0x9E3779B1 + +// buildRouteTree converts one method's tree-path buckets into a routeTree. +// +// It returns a pointer, and allocates rather than recycling the previous +// tables, so that publishing a rebuilt tree is a single pointer store. Holding +// the tree by value instead cost a five-word store, which let a reader pair the +// new hash table with the old buckets; recycling the tables let a reader see a +// cleared one and fall through to globals. Both were measurable — 24 wrong +// answers in 20k requests served across a RebuildTree loop, against 0 before +// the index existed — so this restores the parity that assigning treeStack's +// map pointer used to provide. +// +// The buckets are freshly allocated for each build so a published tree remains +// immutable while a request scans it. Publishing is still an unsynchronized +// store, however, so this does not make RebuildTree safe for concurrent use; +// RebuildTree's own doc states the contract. +func buildRouteTree(buckets map[int][]*Route) *routeTree { + tree := &routeTree{globals: buckets[0]} + + prefixed := len(buckets) + if _, ok := buckets[0]; ok { + prefixed-- + } + if prefixed == 0 { + return tree + } + + // Keep the table at most half full: probes stay short, and a free slot is + // always reachable, which is what terminates the loop in lookup. + size := 8 + for size < prefixed*2 { + size *= 2 + } + + tree.hashes = make([]int32, size) + tree.buckets = make([][]*Route, size) + tree.mask = uint32(size - 1) //nolint:gosec // G115 - size is a small power of two + // size is a power of two, so its trailing-zero count is log2(size). + tree.shift = uint32(32 - bits.TrailingZeros32(uint32(size))) //nolint:gosec // G115 - size is a small power of two + + for hash, routes := range buckets { + if hash == 0 { + continue + } + i := tree.slot(hash) + for tree.hashes[i] != 0 { + i = (i + 1) & tree.mask + } + tree.hashes[i] = int32(hash) //nolint:gosec // G115 - tree hashes are 24-bit, built from three path bytes + tree.buckets[i] = routes + } + + return tree +} + +// slot returns the probe start index for a tree-path hash. +// +// Fibonacci hashing: the multiply pushes the entropy of the low bytes up into +// the high bits, so the index has to be taken from the top. Shifting by a fixed +// amount and masking cannot do that -- it bounds the index by whatever the +// shift leaves, which for a table bigger than that bound makes the upper half +// unreachable as a probe start and collapses the lower half into a linear scan. +func (t *routeTree) slot(hash int) uint32 { + return uint32(hash) * routeTreeHashMul >> t.shift //nolint:gosec // G115 - tree hashes are 24-bit, built from three path bytes +} + +// lookup returns the route bucket for a tree-path hash, falling back to the +// globals bucket when that hash has no bucket of its own. +func (t *routeTree) lookup(hash int) []*Route { + if hash == 0 || t.hashes == nil { + return t.globals + } + + want := int32(hash) //nolint:gosec // G115 - tree hashes are 24-bit, built from three path bytes + for i := t.slot(hash); ; i = (i + 1) & t.mask { + switch t.hashes[i] { + case want: + return t.buckets[i] + case 0: + return t.globals + } + } +} + // URL generates a URL from the route path and parameters. // This method fills in the route parameters with the provided values. // Parameter matching respects the app's CaseSensitive configuration: @@ -102,8 +233,24 @@ func (r Route) URL(params Map) (string, error) { // 2. Case-insensitive fallback picking the lexicographically-smallest matching key (when !caseSensitive) // 3. Greedy parameter fallback for wildcard (*) and plus (+) parameters func buildRouteURL(route *Route, params Map) (string, error) { + // No relative URL names such a route. Two leading slashes open an authority, + // so "//internal" resolves to the host "internal" rather than a path here, + // and one leading slash reaches a different route. Say so instead of + // composing either. + // + // Judged after the parser's own input handling, since that is what a client + // applies to whatever is composed: a tab, CR or LF is deleted anywhere in the + // URL, and a run of controls or spaces is stripped from either end. So a + // route registered at "/\t/internal" reads as "//internal", and one at + // "/internal " — reachable through "/internal%20" under UnescapePath — reads + // as "/internal", a different route. No URL names either. + normalized := urlnorm.AsBrowserReads(route.Path) + if normalized != route.Path || urlnorm.LeadingSlashes(normalized) > 1 { + return "", ErrRouteNotRepresentable + } + if len(route.routeParser.segs) == 0 { - return route.Path, nil + return urlnorm.RootedPath(route.Path), nil } buf := bytebufferpool.Get() @@ -157,7 +304,7 @@ func buildRouteURL(route *Route, params Map) (string, error) { } } - return buf.String(), nil + return urlnorm.RootedPath(buf.String()), nil } // preferredGreedyParameters returns the generic greedy fallback lookup order @@ -177,7 +324,104 @@ func preferredGreedyParameters(paramName string) []string { return defaultGreedyParameterKeys } -func (r *Route) match(detectionPath, path string, params *[maxParams]string) bool { +// pathHeadWord packs the first swar.WordLen bytes of a detection path into a +// little-endian word, zero-padded when the path is shorter, so a route's +// precomputed prefix can be tested with a single masked compare. +func pathHeadWord(s string) uint64 { + if len(s) >= swar.WordLen { + return swar.Load8(s, 0) + } + + var word uint64 + for i := range len(s) { + word |= uint64(s[i]) << (8 * i) + } + return word +} + +// buildPrefixFilter precomputes the leading-byte filter that App.next uses to +// discard routes before paying for Route.match. +// +// The filter mirrors the first comparison each branch of match would make, so +// it can only reject what match would reject: +// - a route without parameters is compared against r.path in full (exact for +// an endpoint, as a prefix for middleware), so r.path leads it +// - a parametric route enters getMatch, which requires the constant part of +// the first segment; an optional trailing slash may be dropped there, so +// that byte is left out +// - '*' matches every path, and a first segment that is itself a parameter +// constrains nothing, so both disable the filter +// +// The star check has to come first, before the parametric branch. star is +// derived from the unescaped path (isStar in register), while Params comes from +// parsing the escaped one, so a route registered as `/\*` arrives here with +// star set and no params — and match returns true for it unconditionally. +// +// Anything that changes a route's path, params or parser must run this again. +// The three places that can are register, which builds the route, copyRoute, +// which carries the fields over, and addPrefixToRoute, which rewrites them. +// Test_Route_PrefixFilter_NotStale pins that the set is complete. +// +// It is deliberately not recomputed in buildTree. buildTree runs from +// RebuildTree, whose whole purpose is registering routes on a live app, and the +// routes it would write to are the ones in-flight requests are reading: a +// reader that caught this function between setting prefix and narrowing +// prefixMask compared a short prefix under an all-ones mask and rejected a +// route it matches. That measured 178 spurious misses in 22.8M requests served +// across a rebuild loop, against 0 before the filter existed. +func (r *Route) buildPrefixFilter() { + r.prefix, r.prefixMask = computePrefixFilter(r) +} + +// computePrefixFilter derives a route's leading-byte filter without publishing +// it, so the two words can be installed in one assignment and the result can be +// recomputed and compared in tests. It returns the packed prefix word and the +// mask covering its known bytes. +// +//nolint:nonamedreturns // the pair is easier to read named than by position +func computePrefixFilter(r *Route) (word, mask uint64) { + if r.star { + return 0, 0 + } + + prefix := r.path + if len(r.Params) > 0 { + segs := r.routeParser.segs + if len(segs) == 0 || segs[0].IsParam { + return 0, 0 + } + prefix = segs[0].Const + if segs[0].HasOptionalSlash { + prefix = prefix[:len(prefix)-1] + } + } + + if len(prefix) > swar.WordLen { + prefix = prefix[:swar.WordLen] + } + if prefix == "" { + return 0, 0 + } + + mask = ^uint64(0) + if n := len(prefix); n < swar.WordLen { + mask = uint64(1)<<(8*n) - 1 + } + return pathHeadWord(prefix), mask +} + +// prefixRejects reports whether the leading bytes of a detection path, packed +// by pathHeadWord, already rule this route out. +// +// This is the whole of the leading-byte filter, and it lives here rather than +// inline at the scan sites so there is one copy to change and one copy for the +// differential tests to guard. Six hand-written copies could drift from each +// other, and a test asserting against a seventh would not notice. +func (r *Route) prefixRejects(head uint64) bool { + return (head^r.prefix)&r.prefixMask != 0 +} + +func (r *Route) match(detectionPath, path string, params *[maxParams]string, pathSlashes int) bool { // root detectionPath check if r.root && len(detectionPath) == 1 && detectionPath[0] == '/' { return true @@ -195,8 +439,16 @@ func (r *Route) match(detectionPath, path string, params *[maxParams]string) boo // Does this route have parameters? if len(r.Params) > 0 { + // Quick-reject on the precomputed slash-count bounds before walking segments. + // pathSlashes 0 means the count is unknown and the filter must stay out of + // the way; prefix (use) routes may extend past the pattern, so only the + // lower bound applies to them. + p := &r.routeParser + if pathSlashes > 0 && (pathSlashes < int(p.minSlashes) || (!r.use && p.maxBounded && pathSlashes > int(p.maxSlashes))) { + return false + } // Match params using precomputed routeParser - return r.routeParser.getMatch(detectionPath, path, params, r.use) + return p.getMatch(detectionPath, path, params, r.use) } // Middleware route? @@ -227,12 +479,15 @@ func (app *App) next(c *DefaultCtx) (bool, error) { treeHash := c.treePathHash detectionPath := utils.UnsafeString(c.detectionPath) path := utils.UnsafeString(c.path) - // Get stack length - tree, ok := app.treeStack[methodInt][treeHash] - if !ok { - tree = app.treeStack[methodInt][0] - } + // Get the route bucket for this method and tree path + tree := app.treeIndex[methodInt].lookup(treeHash) + head := pathHeadWord(detectionPath) indexRoute := max(c.indexRoute+1, 0) + // Hoist loop invariants: route.match takes &c.values, so these would reload each iteration. + pathSlashes := c.pathSlashCount(app) + firstMatchIndex := c.firstMatchIndex + skipNonUse := c.shouldSkipNonUseRoutes + skipHasParamUse := app.skip.hasParamUse // Loop over the route stack starting from previous index; // the clamp above plus the len(tree) guard keep tree[indexRoute] bounds-check free @@ -240,16 +495,39 @@ func (app *App) next(c *DefaultCtx) (bool, error) { // Get *Route route := tree[indexRoute] + // Reject on the leading path bytes before touching the rest of the route + if route.prefixRejects(head) { + continue + } + if route.mount { continue } + // Lookahead pre-resolved the endpoint: skip endpoints already ruled out; middleware still runs. + if firstMatchIndex >= 0 && !route.use { + if indexRoute < firstMatchIndex { + continue + } + // Reuse the lookahead's params unless param/wildcard middleware may have clobbered them. + if indexRoute == firstMatchIndex && !skipHasParamUse && !skipNonUse { + c.route = route + c.isMatched = true + if len(route.Handlers) > 0 { + c.indexHandler = 0 + c.indexRoute = indexRoute + return true, route.Handlers[0](c) + } + return true, nil + } + } + // Check if it matches the request path - if !route.match(detectionPath, path, &c.values) { + if !route.match(detectionPath, path, &c.values, pathSlashes) { continue } - if c.shouldSkipNonUseRoutes && !route.use { + if skipNonUse && !route.use { continue } @@ -282,18 +560,21 @@ func (app *App) next(c *DefaultCtx) (bool, error) { exists := false methods := app.config.RequestMethods + prune := app.skip.methodMaskValid + routeMethods := app.skip.routeMethods for i := range methods { // Skip original method if methodInt == i { continue } + // Methods with no non-use route can never add an Allow entry. + if prune && routeMethods&(uint64(1)<= 0 && !route.use { + if indexRoute < firstMatchIndex { + continue + } + // Reuse the lookahead's params unless param/wildcard middleware may have clobbered them. + if indexRoute == firstMatchIndex && !skipHasParamUse && !skipNonUse { + c.setRoute(route) + c.setMatched(true) + if len(route.Handlers) > 0 { + c.setIndexHandler(0) + c.setIndexRoute(indexRoute) + return true, route.Handlers[0](c) + } + return true, nil + } + } + // Check if it matches the request path - if !route.match(c.getDetectionPath(), c.Path(), c.getValues()) { + if !route.match(detectionPath, path, values, pathSlashes) { continue } - if c.getSkipNonUseRoutes() && !route.use { + if skipNonUse && !route.use { continue } @@ -381,18 +691,21 @@ func (app *App) nextCustom(c CustomCtx) (bool, error) { exists := false methods := app.config.RequestMethods + prune := app.skip.methodMaskValid + routeMethods := app.skip.routeMethods for i := range methods { // Skip original method if methodInt == i { continue } + // Methods with no non-use route can never add an Allow entry. + if prune && routeMethods&(uint64(1)< 0 && len(route.routeParser.segs[0].Const) >= maxDetectionPaths { + // The leading-byte filter is deliberately not rebuilt here; see + // buildPrefixFilter. These routes are live for in-flight requests. + + // Star routes resolve before the slash-count quick-reject in + // Route.match, so only non-star parametric routes consult it. + if len(route.Params) > 0 && !route.star { + hasParamRoutes = true + } + + if len(route.routeParser.segs) > 0 && len(route.routeParser.segs[0].Const) >= maxDetectionPaths && + !dropsOptionalSlashBelowTreeHash(route.routeParser.segs[0]) { treePaths[i] = int(route.routeParser.segs[0].Const[0])<<16 | int(route.routeParser.segs[0].Const[1])<<8 | int(route.routeParser.segs[0].Const[2]) @@ -855,11 +1226,28 @@ func (app *App) buildTree() *App { prefixCounts[treePaths[i]]++ } - prevBuckets := app.treeStack[method] + // Carve this build's buckets out of one allocation. The arena is fresh + // per build, so a published bucket is never written through; a bucket + // per make() would give the same guarantee, but one allocation keeps a + // rebuild's alloc count flat as routes are added. + // + // Each bucket is a three-index slice whose cap is exactly what the + // append loop below puts in it, so a bucket cannot reach its + // neighbor: appending past that cap reallocates instead of writing + // into the next window. + total := globalCount + for _, count := range prefixCounts { + total += count + globalCount + } + arena := make([]*Route, total) + tsMap := make(map[int][]*Route, len(prefixCounts)+1) - tsMap[0] = reuseRouteBucket(prevBuckets, 0, globalCount) + tsMap[0] = arena[0:0:globalCount] + off := globalCount for treePath, count := range prefixCounts { - tsMap[treePath] = reuseRouteBucket(prevBuckets, treePath, count+globalCount) + end := off + count + globalCount + tsMap[treePath] = arena[off:off:end] + off = end } for i, route := range routes { @@ -876,16 +1264,27 @@ func (app *App) buildTree() *App { } app.treeStack[method] = tsMap + app.treeIndex[method] = buildRouteTree(tsMap) } + app.hasParamRoutes = hasParamRoutes + + app.buildSkipIndexes() // reset the flag and return app.hasRoutesRefreshed = false return app } -func reuseRouteBucket(prev map[int][]*Route, key, capHint int) []*Route { - if bucket, ok := prev[key]; ok && cap(bucket) >= capHint { - return bucket[:0] - } - return make([]*Route, 0, capHint) +// dropsOptionalSlashBelowTreeHash reports whether a route's leading constant +// segment can match a detection path too short to carry a tree hash. +// +// getMatch lets a segment with HasOptionalSlash match one byte less than its +// Const (the trailing '/' is optional), so "/a/" also matches "/a". A +// detection path shorter than maxDetectionPaths always hashes to 0, so a route +// bucketed under the hash of its full Const would be invisible to that +// request: next() would scan bucket 0 and never see it. Consts longer than +// maxDetectionPaths are unaffected — dropping the final '/' leaves the first +// three bytes, and therefore the hash, unchanged. +func dropsOptionalSlashBelowTreeHash(seg *routeSegment) bool { + return seg.HasOptionalSlash && len(seg.Const) == maxDetectionPaths } diff --git a/src/vendor/github.com/gofiber/fiber/v3/router_skip.go b/src/vendor/github.com/gofiber/fiber/v3/router_skip.go new file mode 100644 index 00000000..e86a1578 --- /dev/null +++ b/src/vendor/github.com/gofiber/fiber/v3/router_skip.go @@ -0,0 +1,278 @@ +// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️ +// 🤖 GitHub Repository: https://github.com/gofiber/fiber +// 📌 API Documentation: https://docs.gofiber.io + +package fiber + +import ( + "strings" +) + +// skipRouteIndex holds precomputed unmatched-route indexes, rebuilt by buildSkipIndexes with the route tree. +type skipRouteIndex struct { + // staticMethods maps a static endpoint's path to a method bitmask; nil unless SkipUnmatchedRoutes is on + staticMethods map[string]uint64 + // buckets holds the per-tree-bucket lookahead state, one entry per treeStack bucket key (union across methods) + buckets map[int]*skipBucket + // zeroBucket serves tree hashes with no bucket at all, mirroring next()'s treeStack miss + zeroBucket *skipBucket + // routeMethods is a method bitmask with at least one non-use route; only valid when methodMaskValid + routeMethods uint64 + // staticSlashes has a bit per '/' count present among staticMethods' keys, so + // resolveSkip can skip hashing the path when no static route could match it. + // Counts >= 64 set no bit; requests that long take the unconditional path. + staticSlashes uint64 + // enabled gates the fast path: SkipUnmatchedRoutes is on and middleware is registered + // (without middleware next() already answers 404/405 cheaply) + enabled bool + // hasParamUse is true when any param/wildcard middleware exists; when false next() can reuse the lookahead's params + hasParamUse bool + // methodMaskValid is true when routeMethods is trustworthy (len(RequestMethods) <= 64) + methodMaskValid bool +} + +// skipBucket holds one tree bucket's param/root/star candidates per method, with the +// bucket-0 fallback materialized at build time so a lookup never needs a second map access. +type skipBucket struct { + // cands is indexed by method int + cands [][]indexedRoute + // paramMask has a bit per method with at least one candidate in cands + paramMask uint64 +} + +// indexedRoute pairs a candidate route with its position in its tree bucket. +type indexedRoute struct { + route *Route + idx int +} + +// skipDecision is the outcome kind of the SkipUnmatchedRoutes lookahead. +type skipDecision int + +const ( + skipRunChain skipDecision = iota // run the normal chain + skipNotFound // 404 without running the chain + skipNotAllowed // 405; allowMask holds the methods +) + +// skipResult is the outcome of the SkipUnmatchedRoutes lookahead. +type skipResult struct { + decision skipDecision + allowMask uint64 // methods for the Allow header (skipNotAllowed only) + matchIndex int // pre-resolved endpoint index for next()/nextCustom(), or -1 +} + +// buildSkipIndexes rebuilds app.skip from the route tree; called from buildTree. +func (app *App) buildSkipIndexes() { + idx := skipRouteIndex{} + + // Masks are 64-bit; with more methods leave everything disabled, next() answers as usual. + idx.methodMaskValid = len(app.config.RequestMethods) <= 64 + if !idx.methodMaskValid { + app.skip = idx + return + } + + // 405-fallback prune mask; maintained even when SkipUnmatchedRoutes is off. + for method := range app.config.RequestMethods { + for _, route := range app.stack[method] { + if !route.use { + idx.routeMethods |= uint64(1) << method + break + } + } + } + + if app.config.SkipUnmatchedRoutes { + idx.buildLookahead(app) + } + + app.skip = idx +} + +// buildLookahead fills the SkipUnmatchedRoutes lookahead indexes. +func (idx *skipRouteIndex) buildLookahead(app *App) { + nMethods := len(app.config.RequestMethods) + static := make(map[string]uint64) + buckets := make(map[int]*skipBucket) + hasUse := false + hasParamUse := false + + getBucket := func(treeHash int) *skipBucket { + b := buckets[treeHash] + if b == nil { + b = &skipBucket{cands: make([][]indexedRoute, nMethods)} + buckets[treeHash] = b + } + return b + } + + for method := range app.config.RequestMethods { + bit := uint64(1) << method + + // Static endpoints match by exact compare against route.path, so keying by route.path is exact. + for _, route := range app.stack[method] { + if route.use { + hasUse = true + // param/wildcard middleware clobbers c.values on match + if route.star || len(route.Params) > 0 { + hasParamUse = true + } + continue + } + if route.mount || route.star || route.root || len(route.Params) > 0 { + continue + } + static[route.path] |= bit + // These routes match by exact string compare, so a candidate + // detection path necessarily carries the same number of '/'. + if n := strings.Count(route.path, "/"); n < 64 { + idx.staticSlashes |= uint64(1) << n + } + } + + // Candidates come from the final buckets (post bucket-0 replication) so idx lines up with next()'s scan. + for treeHash, bucket := range app.treeStack[method] { + sb := getBucket(treeHash) + for i, route := range bucket { + if route.use || route.mount { + continue + } + if route.root || route.star || len(route.Params) > 0 { + sb.cands[method] = append(sb.cands[method], indexedRoute{route: route, idx: i}) + sb.paramMask |= bit + } + } + } + } + + zero := buckets[0] + if zero == nil { + zero = &skipBucket{cands: make([][]indexedRoute, nMethods)} + buckets[0] = zero + } + + // Materialize the per-method bucket-0 fallback: a method without a treeStack + // bucket at this hash scans its bucket 0 in next(), so mirror that here. + for treeHash, sb := range buckets { + if treeHash == 0 { + continue + } + for method := range app.config.RequestMethods { + if _, ok := app.treeStack[method][treeHash]; ok { + continue + } + sb.cands[method] = zero.cands[method] + if len(zero.cands[method]) > 0 { + sb.paramMask |= uint64(1) << method + } + } + } + + idx.staticMethods = static + idx.buckets = buckets + idx.zeroBucket = zero + idx.enabled = hasUse + idx.hasParamUse = hasParamUse +} + +// resolveSkip decides 404/405/run-chain. values is scratch: param/wildcard +// middleware may overwrite it before the endpoint runs, so next() re-matches then. +func (app *App) resolveSkip(methodInt, treeHash, pathSlashes int, detectionPath, path string, values *[maxParams]string) skipResult { + skip := &app.skip + methodBit := uint64(1) << methodInt + + // Hashing detectionPath for the static index costs a pass over the whole + // path, and static endpoints match by exact compare, so a differing '/' + // count rules them all out before the map is touched. pathSlashes 0 means + // the count was never computed, which stands the filter down. + var staticMask uint64 + if pathSlashes == 0 || pathSlashes >= 64 || skip.staticSlashes&(uint64(1)< [!NOTE] > Because primitive types like int, float, bool, unint and their variants have their default (or zero) values set by Golang, it is not possible to distinguish them from a provided value when decoding/encoding form values. In this case, the value provided by the `default` option tag will be always applied. For example, let's assume that the value submitted in the form for `balance` is `0.0` then the default of `10.0` will be applied, even if `0.0` is part of the form data for the `balance` field. In such cases, it is highly recommended to use pointers to allow schema to distinguish between when a form field has no provided value and when a form has a value equal to the corresponding default set by Golang for a particular type. If the type of the `Balance` field above is changed to `*float64`, then the zero value would be `nil`. In this case, if the form data value for `balance` is `0.0`, then the default will not be applied. + ## ☕ Supporters Fiber is an open-source project that runs on donations to pay the bills, e.g., our domain name, hosting, and serverless infrastructure. If you want to support Fiber, please become a [GitHub Sponsor](https://github.com/sponsors/gofiber). +

+ + + + CodeRabbit + + +

+

+ + Blacksmith + +

+

+ Tool Sponsors - supporting Fiber with free IDE licenses and AI credits +

+

+ JetBrains +   + OpenAI +   + Anthropic +

+ ### 📅 Monthly Sponsors - +
🔥 Fiber Guardian@coderabbitai
☕ Fiber Supporter@NdoleStudio @petercool
☕ Fiber Supporter@NdoleStudio
🪴 Fiber Friend@simonheisstpeter
@@ -126,8 +151,10 @@ Fiber is an open-source project that runs on donations to pay the bills, e.g., o +
🚀 Fiber Hero@thnxdev
🪴 Fiber Friend@Gl1tchedPixzl
+ ## License diff --git a/src/vendor/github.com/gofiber/schema/cache.go b/src/vendor/github.com/gofiber/schema/cache.go index 82866999..f18cf1b4 100644 --- a/src/vendor/github.com/gofiber/schema/cache.go +++ b/src/vendor/github.com/gofiber/schema/cache.go @@ -19,6 +19,22 @@ import ( const maxParserIndex = 1000 +// maxDirectKeyLen bounds the stack buffer used to case-fold keys probed +// against the direct-path map; longer keys take the generic path. +const maxDirectKeyLen = 64 + +// maxDirectPaths caps the nested entries precomputed per struct type: deep +// fan-out nesting multiplies dotted chains, and without a cap build time and +// retained memory grow exponentially. Excess keys use the generic parser. +const maxDirectPaths = 512 + +// maxPathReserve caps the hop and part slices the parser reserves from a +// path's separator count. That count comes from a key nothing has validated +// yet, so an unbounded reservation lets a key of mostly separators claim +// megabytes before its first segment is rejected. Appending past the +// reservation still works, and real paths are a few segments deep. +const maxPathReserve = 16 + var ( errInvalidPath = errors.New("schema: invalid path") errIndexTooLarge = errors.New("schema: index exceeds parser limit") @@ -88,16 +104,45 @@ func (c *cache) parsePath(p string, t reflect.Type) ([]pathPart, error) { // parsed-path cache lives on that structInfo, keyed by the plain path // string, which hashes much cheaper than a composite key. func (c *cache) parsePathInfo(p string, rootInfo *structInfo) ([]pathPart, error) { - if cached, ok := rootInfo.paths.Load(p); ok { - return cached.([]pathPart), nil + // Fast path: probe the precomputed direct-path map with the raw key + // (keys are usually already lowercase); on a miss, case-fold the key + // word-at-a-time (SWAR) into a stack buffer and probe once more. + if len(rootInfo.direct) > 0 { + if parts, ok := rootInfo.direct[p]; ok { + return parts, nil + } + if n := len(p); n <= maxDirectKeyLen { + var buf [maxDirectKeyLen]byte + if foldASCIILower(buf[:], p) { + if parts, ok := rootInfo.direct[string(buf[:n])]; ok { + return parts, nil + } + } + // Every field a bare alias can reach is in the direct map + // (buildDirectPaths adds the flat aliases before the cap can + // truncate anything), and both probes have now seen the key + // folded, so a dotless miss names no field. + if strings.IndexByte(p, '.') < 0 { + return nil, errInvalidPath + } + } + } + + if cached, ok := rootInfo.paths.load(p); ok { + return cached, nil } struc := rootInfo var t reflect.Type var field *fieldInfo var index64 int64 - var parts []pathPart - var hops []pathHop + // A path yields at most one hop and one part per segment. The hops of + // every part share one backing array, cut into capped slices as the + // parts are emitted. + segments := min(strings.Count(p, ".")+1, maxPathReserve) + parts := make([]pathPart, 0, segments) + hopBuf := make([]pathHop, 0, segments) + hopStart := 0 for keyStart := 0; ; { keyEnd, segment, err := nextPathSegment(p, keyStart) if err != nil { @@ -109,8 +154,8 @@ func (c *cache) parsePathInfo(p string, rootInfo *structInfo) ([]pathPart, error // Valid field. Append the hop; the field's index chain was resolved // when the structInfo was built, so the decoder walks plain indices // instead of repeating FieldByName lookups on every Decode call. - hops = append(hops, pathHop{index: field.index, ensure: struc.anonymousPtrFields}) - if field.isSliceOfStructs && !field.isMultipart && (!field.unmarshalerInfo.IsValid || (field.unmarshalerInfo.IsValid && field.unmarshalerInfo.IsSliceElement)) { + hopBuf = append(hopBuf, pathHop{index: field.index, ensure: struc.anonymousPtrFields}) + if field.takesIndex() { // Parse a special case: slices of structs. // i+1 must be the slice index. // @@ -132,12 +177,14 @@ func (c *cache) parsePathInfo(p string, rootInfo *structInfo) ([]pathPart, error if index64 > maxParserIndex { return nil, errIndexTooLarge } + hops := hopBuf[hopStart:len(hopBuf):len(hopBuf)] + hopStart = len(hopBuf) parts = append(parts, pathPart{ - hops: hops, - field: field, - index: int(index64), + hops: hops, + field: field, + index: int(index64), + soleIndex: soleHopIndex(hops), }) - hops = nil // Get the next struct type, dropping ptrs. if field.typ.Kind() == reflect.Ptr { @@ -171,19 +218,120 @@ func (c *cache) parsePathInfo(p string, rootInfo *structInfo) ([]pathPart, error } // Add the remaining. A part without hops means the path terminated at a // slice index ("a.0"), so the decoder receives a slice element there. + hops := hopBuf[hopStart:len(hopBuf):len(hopBuf)] parts = append(parts, pathPart{ - hops: hops, - field: field, - index: -1, - elem: len(hops) == 0, + hops: hops, + field: field, + index: -1, + soleIndex: soleHopIndex(hops), + elem: len(hops) == 0, }) // Detach the key: callers may pass strings aliasing reused request buffers. - if cached, loaded := rootInfo.paths.LoadOrStore(strings.Clone(p), parts); loaded { - return cached.([]pathPart), nil + cached, _ := rootInfo.paths.loadOrStore(strings.Clone(p), parts) + return cached, nil +} + +// maxFastPaths bounds pathCache's copy-on-write map: each publish copies the +// whole map, so past this many paths further entries spill instead. Real +// structs stay well inside it. +const maxFastPaths = 512 + +// pathCache caches parsed paths for one struct type, keyed by the raw source +// key. Lookups run against a plain string-keyed map published atomically — +// sync.Map's interface keys cost a type hash and a trie walk, and +// parsePathInfo probes once per source key. Writes copy the map under the +// lock, so a reader only ever sees a complete one. +type pathCache struct { + fast atomic.Pointer[map[string][]pathPart] + // spill holds paths seen after fast was sealed, so a key space larger + // than maxFastPaths keeps its cache. + spill sync.Map // map[string][]pathPart + mu sync.Mutex + sealed atomic.Bool +} + +func (c *pathCache) load(key string) ([]pathPart, bool) { + if m := c.fast.Load(); m != nil { + if parts, ok := (*m)[key]; ok { + return parts, true + } } + // spill only ever receives entries once fast is sealed. + if c.sealed.Load() { + if v, ok := c.spill.Load(key); ok { + return v.([]pathPart), true + } + } + return nil, false +} - return parts, nil +// loadOrStore caches parts under key, or returns what a concurrent call +// cached there first. +func (c *pathCache) loadOrStore(key string, parts []pathPart) ([]pathPart, bool) { + if !c.sealed.Load() { + c.mu.Lock() + old := c.fast.Load() + if old != nil { + if existing, ok := (*old)[key]; ok { + c.mu.Unlock() + return existing, true + } + } + if old == nil || len(*old) < maxFastPaths { + var next map[string][]pathPart + if old == nil { + next = make(map[string][]pathPart, 1) + } else { + next = make(map[string][]pathPart, len(*old)+1) + maps.Copy(next, *old) + } + next[key] = parts + c.fast.Store(&next) + c.mu.Unlock() + return parts, false + } + c.sealed.Store(true) + c.mu.Unlock() + } + v, loaded := c.spill.LoadOrStore(key, parts) + return v.([]pathPart), loaded +} + +func (c *pathCache) clear() { + c.mu.Lock() + c.fast.Store(nil) + // Nothing reaches spill before the seal, so an unsealed cache has none. + if c.sealed.Load() { + c.spill.Clear() + c.sealed.Store(false) + } + c.mu.Unlock() +} + +// foldASCIILower writes the ASCII-lowercased form of s into buf and reports +// whether any byte changed. Folding into a caller-owned stack buffer lets the +// case-insensitive map probes below skip the allocation utilstrings.ToLower +// makes for a mixed-case key. The caller guarantees len(buf) >= len(s). +func foldASCIILower(buf []byte, s string) bool { + n := len(s) + changed := false + i := 0 + for ; i+swar.WordLen <= n; i += swar.WordLen { + w := swar.Load8(s, i) + lw := swar.ToLowerWord(w) + changed = changed || lw != w + swar.Store8(buf, i, lw) + } + for ; i < n; i++ { + ch := s[i] + if ch >= 'A' && ch <= 'Z' { + ch += 'a' - 'A' + changed = true + } + buf[i] = ch + } + return changed } // dotBroadcast is the SWAR needle for '.'; hoisted so the word loop in @@ -297,7 +445,18 @@ func (c *cache) create(t reflect.Type, parentAlias string) *structInfo { info.fieldsByName[field.aliasLower] = field } } - info.requiredFields = c.buildRequiredFields(info) + for _, f := range info.fields { + if f.takesIndex() { + info.hasIndexedSlice = true + } + if k := f.typ.Kind(); f.def != nil || k == reflect.Struct || + (k == reflect.Ptr && f.typ.Elem().Kind() == reflect.Struct) { + info.defaultFields = append(info.defaultFields, f) + } + } + info.requiredGroups = c.buildRequiredFields(info) + info.requiredPrefixes = buildRequiredPrefixes(info.requiredGroups) + info.direct = c.buildDirectPaths(info) // The setDefaults walk also allocates nil anonymous embedded pointers, // so it can only be skipped when neither defaults nor such pointers // exist anywhere in the tree. @@ -305,6 +464,73 @@ func (c *cache) create(t reflect.Type, parentAlias string) *structInfo { return info } +// buildDirectPaths precomputes, keyed by lowercase path, the parsed paths for +// every key resolvable without runtime state: flat aliases plus dotted chains +// through non-pointer nested struct fields. +func (c *cache) buildDirectPaths(info *structInfo) map[string][]pathPart { + direct := make(map[string][]pathPart, len(info.fieldsByName)) + // Flat aliases first (linear in field count) so the cap below can never + // crowd them out; iterate fields in declaration order, honoring + // fieldsByName's first-wins rule. + for _, f := range info.fields { + if !directEligible(info, f) { + continue + } + hops := []pathHop{{index: f.index, ensure: info.anonymousPtrFields}} + direct[f.aliasLower] = []pathPart{{ + hops: hops, + field: f, + index: -1, + soleIndex: soleHopIndex(hops), + }} + } + for _, f := range info.fields { + if len(direct) >= maxDirectPaths { + break + } + if !directEligible(info, f) || f.typ.Kind() != reflect.Struct { + continue + } + // Non-pointer struct nesting cannot recurse (the type would be + // illegal), so the child's info is always buildable here. + hop := pathHop{index: f.index, ensure: info.anonymousPtrFields} + for childKey, childParts := range c.get(f.typ).direct { + if len(direct) >= maxDirectPaths { + break + } + cp := childParts[0] + hops := make([]pathHop, 0, len(cp.hops)+1) + hops = append(hops, hop) + hops = append(hops, cp.hops...) + direct[f.aliasLower+"."+childKey] = []pathPart{{ + hops: hops, + field: cp.field, + index: -1, + soleIndex: soleHopIndex(hops), + }} + } + } + return direct +} + +// directEligible reports whether f can serve as a direct-path terminal: it is +// its alias's first-wins winner, the alias has no dot, and a bare alias is a +// valid path (slice-of-structs fields require a following slice index). +func directEligible(info *structInfo, f *fieldInfo) bool { + if info.fieldsByName[f.aliasLower] != f || strings.IndexByte(f.aliasLower, '.') >= 0 { + return false + } + return !f.takesIndex() +} + +// takesIndex reports whether a path through f must carry a slice element +// index: f is a slice of structs walked element by element, not one handed to +// a multipart binder or a TextUnmarshaler whole. +func (f *fieldInfo) takesIndex() bool { + return f.isSliceOfStructs && !f.isMultipart && + (!f.unmarshalerInfo.IsValid || f.unmarshalerInfo.IsSliceElement) +} + // needsDefaultsWalk reports whether the setDefaults walk can have any effect // on the struct tree rooted at t: it declares a default tag option, or has an // (exported) anonymous pointer field the walk allocates, anywhere in the @@ -390,12 +616,23 @@ func (c *cache) createField(field reflect.StructField, parentAlias, tag string) elemU = isTextUnmarshaler(reflect.Zero(ft)) } - return &fieldInfo{ + // Non-pointer builtin scalars without unmarshalers or custom converters + // can skip decode's dispatch entirely; converter registration resets the + // cache, so this build-time decision stays valid. + fastKind := reflect.Invalid + if k := field.Type.Kind(); k != reflect.Ptr && !m.IsValid && + getBuiltinConverter(k) != nil && c.converter(field.Type) == nil { + fastKind = k + } + + f := &fieldInfo{ typ: field.Type, + fastKind: fastKind, name: field.Name, alias: alias, aliasLower: utilstrings.ToLower(alias), canonicalAlias: canonicalAlias, + canonicalDot: canonicalAlias + ".", unmarshalerInfo: m, derefUnmarshaler: derefU, elemUnmarshaler: elemU, @@ -405,6 +642,8 @@ func (c *cache) createField(field reflect.StructField, parentAlias, tag string) isRequired: options.Contains("required"), defaultValue: options.getDefaultOptionValue(), } + f.resolveDefault() + return f } // converter returns the converter for a type. @@ -422,11 +661,24 @@ type structInfo struct { fields []*fieldInfo fieldsByName map[string]*fieldInfo anonymousPtrFields []int - requiredFields map[string][]fieldWithPrefix - // paths caches parsed paths rooted at this struct type - // (map[string][]pathPart); keys are cloned so they never alias reused - // request buffers. - paths sync.Map + // requiredGroups lists the required keys in a stable order, so each has + // an index the satisfied-group bitset can address; requiredPrefixes maps + // a nested-key prefix to the groups a key under it can satisfy. + requiredGroups []requiredGroup + requiredPrefixes map[string][]requiredPrefix + // direct maps lowercase statically-resolvable keys to their precomputed + // parsed paths; built once and immutable, see buildDirectPaths. + direct map[string][]pathPart + // paths caches parsed paths rooted at this struct type; keys are cloned + // so they never alias reused request buffers. + paths pathCache + // hasIndexedSlice reports whether any field's paths carry a slice element + // index, and so may grow that slice while decoding. + hasIndexedSlice bool + // defaultFields are the fields the setDefaults walk has to visit: those + // with a default, and the structs and pointers to structs it descends + // into. The rest of the fields can never be affected by it. + defaultFields []*fieldInfo // needsDefaultsWalk reports whether the setDefaults walk can have any // effect on this struct tree: it is set when a default tag option or an // anonymous embedded pointer field (which the walk allocates) exists @@ -435,35 +687,85 @@ type structInfo struct { } func (i *structInfo) get(alias string) *fieldInfo { - aliasKey := utilstrings.ToLower(alias) - if field, ok := i.fieldsByName[aliasKey]; ok { + // fieldsByName is keyed by lowercase alias, so the raw probe settles an + // already-lowercase one without folding. A mixed-case alias is folded + // into a stack buffer and probed from there: the compiler elides the + // string conversion in a map index, so that allocates nothing either. + if field, ok := i.fieldsByName[alias]; ok { return field } - return nil + if n := len(alias); n <= maxDirectKeyLen { + var buf [maxDirectKeyLen]byte + if !foldASCIILower(buf[:], alias) { + return nil // already lowercase: the probe above was conclusive + } + return i.fieldsByName[string(buf[:n])] + } + return i.fieldsByName[utilstrings.ToLower(alias)] } -func (c *cache) buildRequiredFields(info *structInfo) map[string][]fieldWithPrefix { - var requiredFields map[string][]fieldWithPrefix +func (c *cache) buildRequiredFields(info *structInfo) []requiredGroup { + var groups []requiredGroup + var byKey map[string]int + add := func(key string, f fieldWithPrefix) { + if i, ok := byKey[key]; ok { + groups[i].fields = append(groups[i].fields, f) + return + } + if byKey == nil { + byKey = make(map[string]int) + } + byKey[key] = len(groups) + groups = append(groups, requiredGroup{key: key, fields: []fieldWithPrefix{f}}) + } for _, field := range info.fields { if field.typ.Kind() == reflect.Struct { nested := c.get(field.typ) for _, prefix := range field.paths("") { nestedPrefix := prefix + "." - for key, fields := range nested.requiredFields { - requiredKey := field.canonicalAlias + "." + key - for _, nestedField := range fields { - requiredFields = appendRequiredField(requiredFields, requiredKey, - newFieldWithPrefix(nestedField.fieldInfo, nestedPrefix+nestedField.prefix)) + for _, group := range nested.requiredGroups { + requiredKey := field.canonicalAlias + "." + group.key + for _, nestedField := range group.fields { + add(requiredKey, newFieldWithPrefix(nestedField.fieldInfo, nestedPrefix+nestedField.prefix)) } } } } if field.isRequired { - requiredFields = appendRequiredField(requiredFields, field.canonicalAlias, - newFieldWithPrefix(field, "")) + add(field.canonicalAlias, newFieldWithPrefix(field, "")) + } + } + return groups +} + +// buildRequiredPrefixes indexes the groups by the nested-key prefix that can +// satisfy them ("d." for required key "d"), so a source key can be resolved +// against all of them at once. +func buildRequiredPrefixes(groups []requiredGroup) map[string][]requiredPrefix { + if len(groups) == 0 { + return nil + } + prefixes := make(map[string][]requiredPrefix) + for gi := range groups { + for _, f := range groups[gi].fields { + for _, dot := range f.searchPathDots { + owners := prefixes[dot] + // One entry per (group, type): several fields of a group + // can reach the same prefix. + dup := false + for _, o := range owners { + if o.group == gi && o.typ == f.typ { + dup = true + break + } + } + if !dup { + prefixes[dot] = append(owners, requiredPrefix{group: gi, typ: f.typ}) + } + } } } - return requiredFields + return prefixes } func containsAlias(infos []*structInfo, alias string) bool { @@ -478,6 +780,9 @@ func containsAlias(infos []*structInfo, alias string) bool { type fieldInfo struct { typ reflect.Type + // fastKind is the field's builtin scalar kind when decode can set it + // directly (no pointer, unmarshaler, or custom converter); else Invalid. + fastKind reflect.Kind // index is the field index chain relative to the struct type whose // structInfo holds this fieldInfo; promoted fields carry the full chain // through the embedded structs (a copy is made per promotion level). @@ -516,6 +821,24 @@ type fieldInfo struct { isAnonymous bool isRequired bool defaultValue string + // canonicalDot is canonicalAlias with the trailing separator, the prefix + // the fields of a nested struct are looked up under. + canonicalDot string + // def is the default option resolved at build time, nil for the fields + // that have none; see resolveDefault. + def *fieldDefault +} + +// fieldDefault is what setDefaults assigns for a field's default option: +// val for a scalar field (converted to the field type) or a pointer field +// (converted to the pointee type), and slice, a template a slice field's +// default is copied from. An element that failed to convert leaves the +// template short and sets err, which is reported each time the default +// applies. A kind that takes no default leaves all three unset. +type fieldDefault struct { + val reflect.Value + slice reflect.Value + err error } func (f *fieldInfo) paths(prefix string) []string { @@ -529,12 +852,25 @@ type pathPart struct { field *fieldInfo hops []pathHop // path to the field: walks structs using field indices. index int // struct index in slices of structs. + // soleIndex is the single struct field index hops walks, or -1; see + // soleHopIndex. + soleIndex int // elem marks a terminal part whose path ended at a slice index ("a.0"): // the decoder's value is then an element of the slice field rather than // the field itself. elem bool } +// soleHopIndex returns the single struct field index hops walks, or -1 when +// the walk needs decode's general loop: several hops, a promoted field's +// index chain, or embedded pointers to allocate on the way. +func soleHopIndex(hops []pathHop) int { + if len(hops) != 1 || len(hops[0].ensure) != 0 || len(hops[0].index) != 1 { + return -1 + } + return hops[0].index[0] +} + // pathHop describes one named-field lookup along a path. index is the field // index chain relative to the struct at this level (more than one element // when the field is promoted from embedded structs), and ensure lists the diff --git a/src/vendor/github.com/gofiber/schema/converter.go b/src/vendor/github.com/gofiber/schema/converter.go index 27aa76bb..7190a33a 100644 --- a/src/vendor/github.com/gofiber/schema/converter.go +++ b/src/vendor/github.com/gofiber/schema/converter.go @@ -169,6 +169,44 @@ func convertUint64(value string) reflect.Value { return invalidValue } +// parseNative* adapt the builtin parsers to the (T, bool) shape used by the +// native slice decode path, mirroring setBuiltinKind's per-kind behavior. + +func parseNativeString(s string) (string, bool) { return s, true } + +func parseNativeInt(s string) (int, bool) { + n, err := utils.ParseInt(s) + return int(n), err == nil && int64(int(n)) == n +} + +func parseNativeInt64(s string) (int64, bool) { + n, err := utils.ParseInt(s) + return n, err == nil +} + +func parseNativeUint(s string) (uint, bool) { + n, err := utils.ParseUint(s) + return uint(n), err == nil && uint64(uint(n)) == n +} + +func parseNativeUint64(s string) (uint64, bool) { + n, err := utils.ParseUint(s) + return n, err == nil +} + +func parseNativeFloat64(s string) (float64, bool) { + f, err := utils.ParseFloat64(s) + return f, err == nil +} + +func parseNativeBool(s string) (bool, bool) { + if s == "on" { + return true, true + } + b, err := strconv.ParseBool(s) + return b, err == nil +} + // setBuiltinKind parses val and assigns it directly into v for builtin // convertible kinds, avoiding the reflect.Value boxing of the Converter API. // handled reports whether the kind is builtin-convertible; ok reports whether diff --git a/src/vendor/github.com/gofiber/schema/decoder.go b/src/vendor/github.com/gofiber/schema/decoder.go index 0b8b6bcf..b8473497 100644 --- a/src/vendor/github.com/gofiber/schema/decoder.go +++ b/src/vendor/github.com/gofiber/schema/decoder.go @@ -11,8 +11,11 @@ import ( "maps" "mime/multipart" "reflect" + "strconv" "strings" "sync" + + utils "github.com/gofiber/utils/v2" ) const ( @@ -23,6 +26,11 @@ const ( // hoisted so the check does not allocate on every call. var errNotPointerToStruct = errors.New("schema: interface must be a pointer to struct") +// fileKeyValues stands in for the value of a multipart file's key in the +// decode view. Nothing writes through a source map's values and the map it +// goes into is this package's own copy, so one slice serves every file key. +var fileKeyValues = []string{""} + var decodeValueBufferPool = sync.Pool{ New: func() any { buf := make([]reflect.Value, 0, 8) @@ -129,7 +137,7 @@ func (d *Decoder) Decode(dst interface{}, src map[string][]string, files ...map[ merged := make(map[string][]string, len(src)+len(multipartFiles)) maps.Copy(merged, src) for path := range multipartFiles { - merged[path] = []string{""} + merged[path] = fileKeyValues } src = merged } @@ -137,28 +145,51 @@ func (d *Decoder) Decode(dst interface{}, src map[string][]string, files ...map[ v = v.Elem() t := v.Type() rootInfo := d.cache.get(t) + // Required-key bookkeeping rides along with the loop below so src is + // walked once: the direct lookups settle almost every group here, and + // the rest are answered by the nested keys the loop visits anyway. + var satisfied []uint64 + pending := 0 + if len(rootInfo.requiredGroups) > 0 { + // Declared here so a struct with no required keys never pays to + // zero it. + var requiredBits [requiredBitWords]uint64 + satisfied, pending = markProvidedDirectly(rootInfo.requiredGroups, src, requiredBits[:]) + } + // Only a struct whose paths carry an index can grow anything. + var grow *growTracker + if rootInfo.hasIndexedSlice { + var tracker growTracker + grow = &tracker + } var multiErrors MultiError for path, values := range src { + if pending > 0 { + if i := strings.IndexByte(path, '.'); i >= 0 && len(values) > 0 { + pending = markProvidedByNestedKey(rootInfo, path, i+1, values, satisfied, pending) + } + } if parts, err := d.cache.parsePathInfo(path, rootInfo); err == nil { var filesSlice []*multipart.FileHeader if multipartFiles != nil { filesSlice = multipartFiles[path] } - if err = d.decode(v, path, parts, values, filesSlice); err != nil { - multiErrors = appendError(multiErrors, path, err) - } - } else { - if errors.Is(err, errIndexTooLarge) { + if err = d.decode(v, path, parts, values, filesSlice, grow); err != nil { multiErrors = appendError(multiErrors, path, err) - } else if !d.ignoreUnknownKeys { - multiErrors = appendError(multiErrors, path, UnknownKeyError{Key: path}) } + // A key that names no field is by far the most common failure, + // and parsePathInfo returns that sentinel unwrapped, so the + // pointer compare keeps errors.Is off the per-key path. + } else if err != errInvalidPath && errors.Is(err, errIndexTooLarge) { //nolint:errorlint // see above + multiErrors = appendError(multiErrors, path, err) + } else if !d.ignoreUnknownKeys { + multiErrors = appendError(multiErrors, path, UnknownKeyError{Key: path}) } } if rootInfo.needsDefaultsWalk { multiErrors = mergeErrors(multiErrors, d.setDefaults(t, v, src, "")) } - multiErrors = mergeErrors(multiErrors, d.checkRequired(rootInfo, src)) + multiErrors = mergeErrors(multiErrors, missingRequired(rootInfo.requiredGroups, satisfied, pending)) if len(multiErrors) > 0 { return multiErrors } @@ -168,6 +199,56 @@ func (d *Decoder) Decode(dst interface{}, src map[string][]string, files ...map[ // setDefaults sets the default values when the `default` tag is specified, // default is supported on basic/primitive types and their pointers, // nested structs can also have default tags +var ( + errUnsupportedDefault = errors.New("default option is supported only on: bool, float variants, string, unit variants types or their corresponding pointers or slices") + errRequiredDefault = errors.New("required fields cannot have a default value") +) + +// resolveDefault converts the field's default option once, when the struct +// metadata is built, so setDefaults assigns a resolved value on every call +// instead of converting the string each time. Slice and pointer defaults are +// still instantiated per call, so no two decoded values share one. +func (f *fieldInfo) resolveDefault() { + if f.defaultValue == "" { + return + } + def := &fieldDefault{} + f.def = def + switch f.typ.Kind() { + case reflect.Slice: + elemT := f.typ.Elem() + conv := getBuiltinConverter(elemT.Kind()) + if conv == nil { + return + } + tmpl := reflect.MakeSlice(f.typ, 0, strings.Count(f.defaultValue, "|")+1) + for val := range strings.SplitSeq(f.defaultValue, "|") { + v := conv(val) + if !v.IsValid() { + def.err = fmt.Errorf("failed setting default: %s is not compatible with field %s type", val, f.name) + break + } + // Builtin converters return the underlying kind; convert to the + // (possibly named) element type, else Append panics for []MyInt. + tmpl = reflect.Append(tmpl, v.Convert(elemT)) + } + def.slice = tmpl + case reflect.Ptr: + t1 := f.typ.Elem() + if conv := getBuiltinConverter(t1.Kind()); conv != nil { + if v := conv(f.defaultValue); v.IsValid() { + def.val = v.Convert(t1) + } + } + default: + if conv := getBuiltinConverter(f.typ.Kind()); conv != nil { + if v := conv(f.defaultValue); v.IsValid() { + def.val = v.Convert(f.typ) + } + } + } +} + func (d *Decoder) setDefaults(t reflect.Type, v reflect.Value, src map[string][]string, prefix string) MultiError { struc := d.cache.get(t) // Skip the walk entirely when it can have no effect (no default tags and @@ -187,79 +268,69 @@ func (d *Decoder) setDefaults(t reflect.Type, v reflect.Value, src map[string][] } } - for _, f := range struc.fields { + for _, f := range struc.defaultFields { vCurrent := walkIndexChain(v, f.index) if !vCurrent.IsValid() { // Unreachable behind an unsettable nil embedded pointer. continue } - if vCurrent.Type().Kind() == reflect.Struct && f.defaultValue == "" { - errs = mergeErrors(errs, d.setDefaults(vCurrent.Type(), vCurrent, src, prefix+f.canonicalAlias+".")) - } else if isPointerToStruct(vCurrent) && f.defaultValue == "" { - errs = mergeErrors(errs, d.setDefaults(vCurrent.Elem().Type(), vCurrent.Elem(), src, prefix+f.canonicalAlias+".")) + // vCurrent's type is f.typ; a nested struct is walked under its own + // prefix (an empty prefix concatenates without allocating). + kind := f.typ.Kind() + if kind == reflect.Struct && f.defaultValue == "" { + errs = mergeErrors(errs, d.setDefaults(f.typ, vCurrent, src, prefix+f.canonicalDot)) + } else if kind == reflect.Ptr && f.defaultValue == "" && isPointerToStruct(vCurrent) { + errs = mergeErrors(errs, d.setDefaults(f.typ.Elem(), vCurrent.Elem(), src, prefix+f.canonicalDot)) } - if f.defaultValue != "" && f.isRequired { - errs = appendError(errs, "default-"+f.name, errors.New("required fields cannot have a default value")) - } else if f.defaultValue != "" && vCurrent.IsZero() && !f.isRequired && !fieldProvided(src, prefix, f) { - if f.typ.Kind() == reflect.Struct { - errs = appendError(errs, "default-"+f.name, errors.New("default option is supported only on: bool, float variants, string, unit variants types or their corresponding pointers or slices")) - } else if f.typ.Kind() == reflect.Slice { - // check if slice has one of the supported types for defaults - conv := getBuiltinConverter(f.typ.Elem().Kind()) - if conv == nil { - errs = appendError(errs, "default-"+f.name, errors.New("default option is supported only on: bool, float variants, string, unit variants types or their corresponding pointers or slices")) - continue - } - - elemT := f.typ.Elem() - defaultSlice := reflect.MakeSlice(f.typ, 0, strings.Count(f.defaultValue, "|")+1) - for val := range strings.SplitSeq(f.defaultValue, "|") { - // this check is to handle if the wrong value is provided - convertedVal := conv(val) - if !convertedVal.IsValid() { - errs = appendError(errs, "default-"+f.name, fmt.Errorf("failed setting default: %s is not compatible with field %s type", val, f.name)) - break - } - // Builtin converters return the underlying kind; convert to - // the (possibly named) element type before appending, else - // reflect.Append panics for e.g. []MyInt. - defaultSlice = reflect.Append(defaultSlice, convertedVal.Convert(elemT)) - } - vCurrent.Set(defaultSlice) - } else if f.typ.Kind() == reflect.Ptr { - t1 := f.typ.Elem() - - if t1.Kind() == reflect.Struct || t1.Kind() == reflect.Slice { - errs = appendError(errs, "default-"+f.name, errors.New("default option is supported only on: bool, float variants, string, unit variants types or their corresponding pointers or slices")) - } - - // this check is to handle if the wrong value is provided - if conv := getBuiltinConverter(t1.Kind()); conv != nil { - if convertedVal := conv(f.defaultValue); convertedVal.IsValid() { - // Build a pointer of the field's actual element type: - // the converter yields the underlying kind, which is - // convertible to the (possibly named) element type, - // and *elem is assignable to the field even when the - // field's type is itself a named pointer type (e.g. - // type MyIntPtr *MyInt), where converting a *int - // directly would panic. - p := reflect.New(t1) - p.Elem().Set(convertedVal.Convert(t1)) - vCurrent.Set(p) - } - } - } else { - // this check is to handle if the wrong value is provided - conv := getBuiltinConverter(f.typ.Kind()) - if conv == nil { - errs = appendError(errs, "default-"+f.name, errors.New("default option is supported only on: bool, float variants, string, unit variants types or their corresponding pointers or slices")) - } else if convertedVal := conv(f.defaultValue); convertedVal.IsValid() { - // Builtin converters return the underlying kind; convert to - // the field's (possibly named) type before assigning. - vCurrent.Set(convertedVal.Convert(f.typ)) - } + def := f.def + if def == nil { + continue + } + if f.isRequired { + errs = appendError(errs, "default-"+f.name, errRequiredDefault) + continue + } + if !vCurrent.IsZero() || fieldProvided(src, prefix, f) { + continue + } + // The default itself was resolved when the metadata was built; see + // resolveDefault. Only the per-call parts remain: the errors a kind + // that takes no default reports, and a fresh pointer or slice so no + // two decoded values share one. + switch kind { + case reflect.Struct: + errs = appendError(errs, "default-"+f.name, errUnsupportedDefault) + case reflect.Slice: + if !def.slice.IsValid() { + errs = appendError(errs, "default-"+f.name, errUnsupportedDefault) + continue + } + if def.err != nil { + errs = appendError(errs, "default-"+f.name, def.err) + } + fresh := reflect.MakeSlice(f.typ, def.slice.Len(), def.slice.Cap()) + reflect.Copy(fresh, def.slice) + vCurrent.Set(fresh) + case reflect.Ptr: + t1 := f.typ.Elem() + if t1.Kind() == reflect.Struct || t1.Kind() == reflect.Slice { + errs = appendError(errs, "default-"+f.name, errUnsupportedDefault) + } + if def.val.IsValid() { + // *elem is assignable to the field even when the field's + // type is itself a named pointer type (type MyIntPtr *MyInt), + // where converting a *int directly would panic. + p := reflect.New(t1) + p.Elem().Set(def.val) + vCurrent.Set(p) + } + default: + if getBuiltinConverter(kind) == nil { + errs = appendError(errs, "default-"+f.name, errUnsupportedDefault) + } else if def.val.IsValid() { + vCurrent.Set(def.val) } } } @@ -267,36 +338,159 @@ func (d *Decoder) setDefaults(t reflect.Type, v reflect.Value, src map[string][] return errs } +// growCap is the capacity to give a slice being grown to n elements: room for +// another doubling when the slice is tracked, so later indices mostly land +// inside it, and exactly n when it is not, since the extra would go unused. +func (d *Decoder) growCap(n int, tracked bool) int { + if !tracked { + return n + } + c := 2 * n + if c < n || c > d.maxSize+1 { // overflow, or past what maxSize admits + c = d.maxSize + 1 + } + if c < n { + c = n + } + return c +} + func isPointerToStruct(v reflect.Value) bool { return !v.IsZero() && v.Type().Kind() == reflect.Ptr && v.Elem().Type().Kind() == reflect.Struct } func fieldProvided(src map[string][]string, prefix string, f *fieldInfo) bool { - for _, p := range f.paths(prefix) { - if _, ok := src[p]; ok { - return true - } + if keyProvided(src, prefix, f.alias) { + return true } - return false + return f.alias != f.canonicalAlias && keyProvided(src, prefix, f.canonicalAlias) +} + +// keyProvided reports whether prefix+name is a key of src, assembling the key +// in a stack buffer when it fits so the probe allocates nothing. +func keyProvided(src map[string][]string, prefix, name string) bool { + if prefix == "" { + _, ok := src[name] + return ok + } + if n := len(prefix) + len(name); n <= maxDirectKeyLen { + var buf [maxDirectKeyLen]byte + copy(buf[copy(buf[:], prefix):], name) + _, ok := src[string(buf[:n])] + return ok + } + _, ok := src[prefix+name] + return ok } -// checkRequired checks whether required fields are empty -// // The set of required fields (including those of nested structs) is -// precomputed once per struct type in structInfo.requiredFields, so this -// only performs the per-request emptiness checks against src. +// precomputed once per struct type in structInfo.requiredGroups, so what +// follows only performs the per-request emptiness checks against src. // -// src is the source map for decoding, we use it here to see if those required fields are included in src -func (d *Decoder) checkRequired(info *structInfo, src map[string][]string) MultiError { +// A group is satisfied by a value under one of its own paths, or by any +// nested key below one of them ("d.e" satisfies required "d"). Direct paths +// are looked up first, since they settle almost every group; what is left is +// answered by walking the dotted prefixes of each source key. Decode runs +// those three steps around its own loop over src; checkRequired composes them +// for a standalone check. + +// requiredBitWords sizes the inline satisfied-group bitset: 256 required +// keys, past which it is allocated. +const requiredBitWords = 4 + +// markProvidedDirectly marks every required group src answers through one of +// its own paths, returning the bitset — backed by inline when the groups fit +// — and how many are still pending. +func markProvidedDirectly(groups []requiredGroup, src map[string][]string, inline []uint64) ([]uint64, int) { + if len(groups) == 0 { + return nil, 0 + } + var satisfied []uint64 + if w := (len(groups) + 63) >> 6; w <= len(inline) { + satisfied = inline[:w] + } else { + satisfied = make([]uint64, w) + } + pending := len(groups) + for gi := range groups { + if directlyProvided(groups[gi].fields, src) { + satisfied[gi>>6] |= 1 << uint(gi&63) + pending-- + } + } + return satisfied, pending +} + +// markProvidedByNestedKey walks the dotted prefixes of key from off, marking +// every required group they name that val is non-empty for, and returns the +// new pending count. Callers test for a dotted, non-empty key themselves, so +// the keys that can answer nothing do not pay for a call. +func markProvidedByNestedKey(info *structInfo, key string, off int, val []string, satisfied []uint64, pending int) int { + for { + for _, p := range info.requiredPrefixes[key[:off]] { + if satisfied[p.group>>6]&(1<>6] |= 1 << uint(p.group&63) + pending-- + } + } + i := strings.IndexByte(key[off:], '.') + if i < 0 { + return pending + } + off += i + 1 + } +} + +// missingRequired reports the required keys nothing in src answered. +func missingRequired(groups []requiredGroup, satisfied []uint64, pending int) MultiError { + if pending == 0 { + return nil + } var errs MultiError - for key, fields := range info.requiredFields { - if isEmptyFields(fields, src) { - errs = appendError(errs, key, EmptyFieldError{Key: key}) + for gi := range groups { + if satisfied[gi>>6]&(1< 0 { + for key, val := range src { + i := strings.IndexByte(key, '.') + if i < 0 || len(val) == 0 { + continue + } + if pending = markProvidedByNestedKey(info, key, i+1, val, satisfied, pending); pending == 0 { + break + } + } + } + return missingRequired(info.requiredGroups, satisfied, pending) +} + +// requiredGroup is one required key together with the fields that can +// satisfy it; its position in structInfo.requiredGroups is its bitset index. +type requiredGroup struct { + key string + fields []fieldWithPrefix +} + +// requiredPrefix names a group a nested source key can satisfy, with the +// field type that judges whether the key's value counts as non-empty. +type requiredPrefix struct { + typ reflect.Type + group int +} + type fieldWithPrefix struct { *fieldInfo prefix string @@ -322,30 +516,17 @@ func newFieldWithPrefix(f *fieldInfo, prefix string) fieldWithPrefix { } } -// isEmptyFields returns true if all of specified fields are empty. -func isEmptyFields(fields []fieldWithPrefix, src map[string][]string) bool { +// directlyProvided reports whether any of the group's own paths carries a +// non-empty value in src. +func directlyProvided(fields []fieldWithPrefix, src map[string][]string) bool { for _, f := range fields { - for i, path := range f.searchPaths { - v, ok := src[path] - if ok && !isEmpty(f.typ, v) { - return false - } - // Check for nested keys that match this field. - pathDot := f.searchPathDots[i] - for key, val := range src { - if len(val) == 0 { - continue - } - // for nested structs - if strings.HasPrefix(key, pathDot) { - if !isEmpty(f.typ, val) { - return false - } - } + for _, path := range f.searchPaths { + if v, ok := src[path]; ok && !isEmpty(f.typ, v) { + return true } } } - return true + return false } // isEmpty returns true if value is empty for specific type @@ -435,6 +616,36 @@ func isMultipartField(typ reflect.Type) bool { return false } +// walkHops follows a path to the target field, dereferencing pointers and +// allocating the embedded pointers promoted fields need on the way. It +// returns the zero Value when an unsettable nil embedded pointer blocks the +// walk. +func walkHops(v reflect.Value, hops []pathHop) reflect.Value { + for _, hop := range hops { + // A previous hop may have been blocked by an unsettable nil + // embedded pointer; the field is unreachable then. + if !v.IsValid() { + return v + } + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + + // Allocate embedded anonymous pointers required for promoted fields. + for _, idx := range hop.ensure { + if f := v.Field(idx); f.IsNil() { + f.Set(reflect.New(f.Type().Elem())) + } + } + + v = walkIndexChain(v, hop.index) + } + return v +} + // walkIndexChain walks v along a struct field index chain. Chains longer // than one element traverse embedded structs; intermediate nil pointers are // allocated so promoted fields stay reachable. It returns the zero Value @@ -457,30 +668,54 @@ func walkIndexChain(v reflect.Value, chain []int) reflect.Value { return v } -// decode fills a struct field using a parsed path. -func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values []string, files []*multipart.FileHeader) error { - // Get the field walking the struct fields by index. - for _, hop := range parts[0].hops { - // A previous hop may have been blocked by an unsettable nil - // embedded pointer; the field is unreachable then. - if !v.IsValid() { - return nil - } - if v.Kind() == reflect.Ptr { - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - v = v.Elem() +// growTracker remembers which of the destination struct's slice fields a +// Decode call has already reallocated, and how much room it reserved in each. +// Fields are keyed by their index in that struct, which is what pathPart's +// soleIndex carries: only a slice reached by one hop can be tracked, since a +// deeper path reaches a slice inside some element, which the field alone +// cannot tell apart from the same field in another. Fields past the four +// entries keep growing exactly. +type growTracker struct { + fields [4]int + caps [4]int + n int +} + +// reserved returns the capacity this call gave the slice at struct field +// index i, or 0 if it has not reallocated it. +func (g *growTracker) reserved(i int) int { + for j := 0; j < g.n; j++ { + if g.fields[j] == i { + return g.caps[j] } + } + return 0 +} - // Allocate embedded anonymous pointers required for promoted fields. - for _, idx := range hop.ensure { - if f := v.Field(idx); f.IsNil() { - f.Set(reflect.New(f.Type().Elem())) - } +func (g *growTracker) record(i, c int) { + for j := 0; j < g.n; j++ { + if g.fields[j] == i { + g.caps[j] = c + return } + } + if g.n < len(g.fields) { + g.fields[g.n] = i + g.caps[g.n] = c + g.n++ + } +} - v = walkIndexChain(v, hop.index) +// decode fills a struct field using a parsed path. grow is non-nil only for +// the outermost call, the one place slice growth can be tracked. +func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values []string, files []*multipart.FileHeader, grow *growTracker) error { + // Get the field walking the struct fields by index. Almost every path is + // one hop into a field of v, which needs none of the loop's bookkeeping. + if idx := parts[0].soleIndex; idx >= 0 && v.Kind() == reflect.Struct { + v = v.Field(idx) + } else if v = walkHops(v, parts[0].hops); !v.IsValid() { + // Unreachable behind an unsettable nil embedded pointer. + return nil } // Don't even bother for unexported fields. @@ -488,6 +723,29 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values return nil } + // Fast path: plain builtin scalar fields skip the converter/unmarshaler + // dispatch below; fastKind was validated at cache-build time. + if k := parts[0].field.fastKind; k != reflect.Invalid && len(parts) == 1 && !parts[0].elem { + val := "" + if len(values) > 0 { + val = values[len(values)-1] + } + if val == "" { + if d.zeroEmpty { + v.SetZero() + } + return nil + } + if _, ok := setBuiltinKind(v, k, val); !ok { + return ConversionError{ + Key: path, + Type: parts[0].field.typ, + Index: -1, + } + } + return nil + } + // Check multipart files if parts[0].field.isMultipart && handleMultipartField(v, files) { return nil @@ -510,18 +768,32 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values if idx > d.maxSize { return fmt.Errorf("%v index %d is larger than the configured maxSize %d", v.Kind(), idx, d.maxSize) } - if v.IsNil() || v.Len() < idx+1 { - // Grow into a fresh backing array: extending within existing - // capacity would write into memory the caller may still share - // through other slices aliasing the original array. - value := reflect.MakeSlice(t, idx+1, idx+1) - if v.Len() > 0 { - // Resize it. - reflect.Copy(value, v) + if n := idx + 1; v.IsNil() || v.Len() < n { + // Indices arrive in map order, so a slice is typically grown + // several times per call. Extending one this call allocated is + // free: the room past its length is ours and freshly zeroed. + owner := -1 + if grow != nil { + owner = parts[0].soleIndex + } + if owner >= 0 && n <= v.Cap() && grow.reserved(owner) >= n { + v.SetLen(n) + } else { + // Otherwise grow into a fresh backing array: extending within + // the existing capacity would write into memory the caller + // may still share through another slice aliasing it. + value := reflect.MakeSlice(t, n, d.growCap(n, owner >= 0)) + if v.Len() > 0 { + // Resize it. + reflect.Copy(value, v) + } + v.Set(value) + if owner >= 0 { + grow.record(owner, value.Cap()) + } } - v.Set(value) } - return d.decode(v.Index(idx), path, parts[1:], values, files) + return d.decode(v.Index(idx), path, parts[1:], values, files, nil) } // Get the converter early in case there is one for a slice type. @@ -560,73 +832,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values return d.decodeBuiltinSlice(v, t, path, values) } - itemsBuf := decodeValueBufferPool.Get().(*[]reflect.Value) - items := (*itemsBuf)[:0] - defer func() { - clear(items) - *itemsBuf = items[:0] - decodeValueBufferPool.Put(itemsBuf) - }() - - for key, value := range values { - if value == "" { - if d.zeroEmpty { - items = append(items, reflect.Zero(t.Elem())) - } - } else if m.IsValid { - u := reflect.New(elemT) - if m.IsSliceElementPtr { - u = reflect.New(reflect.PointerTo(elemT).Elem()) - } - um, _ := reflect.TypeAssert[encoding.TextUnmarshaler](u) - if err := um.UnmarshalText([]byte(value)); err != nil { - return ConversionError{ - Key: path, - Type: t, - Index: key, - Err: err, - } - } - if m.IsSliceElementPtr { - items = append(items, u.Elem().Addr()) - } else { - // u is always a pointer from reflect.New; store the - // pointed-to value. - items = append(items, u.Elem()) - } - } else if item := conv(value); item.IsValid() { - items = appendConvertedItem(items, item, elemT, isPtrElem) - } else { - if strings.IndexByte(value, ',') != -1 { - for value := range strings.SplitSeq(value, ",") { - if value == "" { - if d.zeroEmpty { - items = append(items, reflect.Zero(t.Elem())) - } - } else if item := conv(value); item.IsValid() { - items = appendConvertedItem(items, item, elemT, isPtrElem) - } else { - return ConversionError{ - Key: path, - Type: elemT, - Index: key, - } - } - } - } else { - return ConversionError{ - Key: path, - Type: elemT, - Index: key, - } - } - } - } - value := reflect.MakeSlice(t, len(items), len(items)) - for i, item := range items { - value.Index(i).Set(item) - } - v.Set(value) + return d.decodeBoxedSlice(v, t, elemT, path, values, conv, m, isPtrElem) } else { val := "" // Use the last value provided if any values were provided @@ -690,6 +896,81 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values return nil } +// decodeBoxedSlice decodes values into the slice field v whose elements have +// to round-trip through a reflect.Value: a custom converter, a +// TextUnmarshaler, or pointer elements. It is split out so that decode, which +// runs once per source key, carries no defer of its own. +func (d *Decoder) decodeBoxedSlice(v reflect.Value, t, elemT reflect.Type, path string, values []string, conv Converter, m unmarshaler, isPtrElem bool) error { + itemsBuf := decodeValueBufferPool.Get().(*[]reflect.Value) + items := (*itemsBuf)[:0] + defer func() { + clear(items) + *itemsBuf = items[:0] + decodeValueBufferPool.Put(itemsBuf) + }() + + for key, value := range values { + if value == "" { + if d.zeroEmpty { + items = append(items, reflect.Zero(t.Elem())) + } + } else if m.IsValid { + u := reflect.New(elemT) + if m.IsSliceElementPtr { + u = reflect.New(reflect.PointerTo(elemT).Elem()) + } + um, _ := reflect.TypeAssert[encoding.TextUnmarshaler](u) + if err := um.UnmarshalText([]byte(value)); err != nil { + return ConversionError{ + Key: path, + Type: t, + Index: key, + Err: err, + } + } + if m.IsSliceElementPtr { + items = append(items, u.Elem().Addr()) + } else { + // u is always a pointer from reflect.New; store the + // pointed-to value. + items = append(items, u.Elem()) + } + } else if item := conv(value); item.IsValid() { + items = appendConvertedItem(items, item, elemT, isPtrElem) + } else { + if strings.IndexByte(value, ',') != -1 { + for value := range strings.SplitSeq(value, ",") { + if value == "" { + if d.zeroEmpty { + items = append(items, reflect.Zero(t.Elem())) + } + } else if item := conv(value); item.IsValid() { + items = appendConvertedItem(items, item, elemT, isPtrElem) + } else { + return ConversionError{ + Key: path, + Type: elemT, + Index: key, + } + } + } + } else { + return ConversionError{ + Key: path, + Type: elemT, + Index: key, + } + } + } + } + value := reflect.MakeSlice(t, len(items), len(items)) + for i, item := range items { + value.Index(i).Set(item) + } + v.Set(value) + return nil +} + // appendConvertedItem converts a builtin/custom converter result to the slice // element type and appends it, wrapping it in a freshly allocated pointer for // pointer-element slices. The conversion must happen before the pointer wrap: @@ -725,12 +1006,33 @@ func (d *Decoder) decodeBuiltinSlice(v reflect.Value, t reflect.Type, path strin k := elemT.Kind() split := k != reflect.String - n := 0 - for _, value := range values { - if split { + n := len(values) + if split { + for _, value := range values { n += strings.Count(value, ",") } - n++ + // The counts already say whether any value holds a separator, so + // when none does the per-value scans below have nothing to find. + split = n > len(values) + } + + // Exact builtin slice types decode without per-element reflect calls; + // named slice or element types fall through to the generic path. + switch t { + case typSliceString: + return decodeNativeSlice(d.zeroEmpty, v, path, values, elemT, n, split, parseNativeString) + case typSliceInt: + return decodeNativeSlice(d.zeroEmpty, v, path, values, elemT, n, split, parseNativeInt) + case typSliceInt64: + return decodeNativeSlice(d.zeroEmpty, v, path, values, elemT, n, split, parseNativeInt64) + case typSliceUint: + return decodeNativeSlice(d.zeroEmpty, v, path, values, elemT, n, split, parseNativeUint) + case typSliceUint64: + return decodeNativeSlice(d.zeroEmpty, v, path, values, elemT, n, split, parseNativeUint64) + case typSliceFloat64: + return decodeNativeSlice(d.zeroEmpty, v, path, values, elemT, n, split, parseNativeFloat64) + case typSliceBool: + return decodeNativeSlice(d.zeroEmpty, v, path, values, elemT, n, split, parseNativeBool) } sl := reflect.MakeSlice(t, n, n) @@ -776,6 +1078,66 @@ func (d *Decoder) decodeBuiltinSlice(v reflect.Value, t reflect.Type, path strin return nil } +// Exact (unnamed) builtin slice types eligible for the native decode path. +var ( + typSliceString = reflect.TypeOf([]string(nil)) + typSliceInt = reflect.TypeOf([]int(nil)) + typSliceInt64 = reflect.TypeOf([]int64(nil)) + typSliceUint = reflect.TypeOf([]uint(nil)) + typSliceUint64 = reflect.TypeOf([]uint64(nil)) + typSliceFloat64 = reflect.TypeOf([]float64(nil)) + typSliceBool = reflect.TypeOf([]bool(nil)) +) + +// decodeNativeSlice mirrors the generic decodeBuiltinSlice loop for a field +// typed exactly []T, parsing into a native slice assigned only if every value +// parsed (all-or-nothing). n is the precomputed element upper bound. +func decodeNativeSlice[T any](zeroEmpty bool, v reflect.Value, path string, values []string, elemT reflect.Type, n int, split bool, parse func(string) (T, bool)) error { + out := make([]T, 0, n) + var zero T + for key, value := range values { + switch { + case value == "": + if zeroEmpty { + out = append(out, zero) + } + case split && strings.IndexByte(value, ',') != -1: + for item := range strings.SplitSeq(value, ",") { + if item == "" { + if zeroEmpty { + out = append(out, zero) + } + continue + } + ev, ok := parse(item) + if !ok { + return ConversionError{ + Key: path, + Type: elemT, + Index: key, + } + } + out = append(out, ev) + } + default: + ev, ok := parse(value) + if !ok { + return ConversionError{ + Key: path, + Type: elemT, + Index: key, + } + } + out = append(out, ev) + } + } + // v's type is exactly []T here (the dispatch switch guarantees it), so + // assign through the typed pointer: no reflect.ValueOf escape, no Set + // assignability checks, and a loud panic if the invariant is ever broken. + *v.Addr().Interface().(*[]T) = out + return nil +} + func isTextUnmarshaler(v reflect.Value) unmarshaler { // Create a new unmarshaller instance m := unmarshaler{} @@ -841,18 +1203,21 @@ type ConversionError struct { Err error // low-level error (when it exists) } +// The error strings below are assembled by concatenation instead of +// fmt.Sprintf: %q is strconv.Quote and %d is utils.FormatInt, so the messages +// are byte-identical without the reflection-based formatter. func (e ConversionError) Error() string { var output string if e.Index < 0 { - output = fmt.Sprintf("schema: error converting value for %q", e.Key) + output = "schema: error converting value for " + strconv.Quote(e.Key) } else { - output = fmt.Sprintf("schema: error converting value for index %d of %q", - e.Index, e.Key) + output = "schema: error converting value for index " + + utils.FormatInt(int64(e.Index)) + " of " + strconv.Quote(e.Key) } if e.Err != nil { - output = fmt.Sprintf("%s. Details: %s", output, e.Err) + output += ". Details: " + e.Err.Error() } return output @@ -864,7 +1229,7 @@ type UnknownKeyError struct { } func (e UnknownKeyError) Error() string { - return fmt.Sprintf("schema: invalid path %q", e.Key) + return "schema: invalid path " + strconv.Quote(e.Key) } // EmptyFieldError stores information about an empty required field. @@ -873,7 +1238,7 @@ type EmptyFieldError struct { } func (e EmptyFieldError) Error() string { - return fmt.Sprintf("%v is empty", e.Key) + return e.Key + " is empty" } // MultiError stores multiple decoding errors. @@ -895,15 +1260,7 @@ func (e MultiError) Error() string { case 2: return s + " (and 1 other error)" } - return fmt.Sprintf("%s (and %d other errors)", s, len(e)-1) -} - -func appendRequiredField(m map[string][]fieldWithPrefix, key string, field fieldWithPrefix) map[string][]fieldWithPrefix { - if m == nil { - m = make(map[string][]fieldWithPrefix) - } - m[key] = append(m[key], field) - return m + return s + " (and " + utils.FormatInt(int64(len(e)-1)) + " other errors)" } func appendError(m MultiError, key string, err error) MultiError { diff --git a/src/vendor/github.com/gofiber/schema/encoder.go b/src/vendor/github.com/gofiber/schema/encoder.go index b1d53b36..c85c4c9c 100644 --- a/src/vendor/github.com/gofiber/schema/encoder.go +++ b/src/vendor/github.com/gofiber/schema/encoder.go @@ -21,6 +21,13 @@ var errNotStruct = errors.New("schema: interface must be a struct") // would otherwise panic on the first map assignment. var errNilDst = errors.New("schema: dst map must not be nil") +// maxScratchValueLen bounds values stored in encode's shared scratch array, +// capping how much data a surviving dst entry can keep reachable after the +// caller deletes neighboring keys. Only strings allocated by this package's +// own formatters are eligible at all (see encField.scratchSafe), so the cap +// bounds real bytes, not just headers. +const maxScratchValueLen = 64 + // Encoder encodes values from a struct into url.Values. type Encoder struct { cache *cache @@ -43,6 +50,12 @@ type Encoder struct { type encPlan struct { fields []encField gen uint64 + // freshKeys reports that encoding a value of this type into an empty map + // writes every key exactly once: no two fields share a name, and no field + // is recursed into — a nested struct's keys land in the same map, without + // a prefix, so they could collide with these. encode can then assign each + // key outright instead of reading it back to append. + freshKeys bool } // encField is the precomputed encoding plan for one struct field. @@ -55,7 +68,16 @@ type encField struct { // recurseStructPtr marks pointer-to-struct fields without a custom // encoder: non-nil values are encoded by recursing into the element. recurseStructPtr bool - isStruct bool + // scratchSafe marks fields whose encoder output is allocated by this + // package (numeric/bool/float formatters), so it can never alias a large + // caller-owned buffer and may be batched in encode's shared scratch. + scratchSafe bool + // hasIsZero marks a struct-typed field whose type decides omitempty for + // itself through an IsZero method. Settling that here keeps the check off + // reflect.Value.Interface, which copies the struct to the heap every time + // it is asked — whether or not the method is there. + hasIsZero bool + isStruct bool // nilAsNull marks pointer fields whose element has no immediate // encoder (structs recursed via recurseStructPtr, or unsupported // types): nil values encode as "null", matching the closure behavior @@ -120,18 +142,18 @@ func (e *Encoder) SetAliasTag(tag string) { // on first use. The build reads the tag and registered encoders under the // configuration lock; the generation re-checks around the cache store keep a // build racing a reconfiguration from inserting a stale plan. -func (e *Encoder) structInfo(t reflect.Type) []encField { +func (e *Encoder) structInfo(t reflect.Type) (fields []encField, freshKeys bool) { //nolint:nonamedreturns // the bool is only readable named gen := e.encGen.Load() if cached, ok := e.encCache.Load(t); ok { // Ignore plans built under an older configuration; fall through and // rebuild (the fresh plan overwrites the stale entry). if p := cached.(*encPlan); p.gen == gen { - return p.fields + return p.fields, p.freshKeys } } e.cache.l.RLock() tag := e.cache.tag - fields := make([]encField, 0, t.NumField()) + fields = make([]encField, 0, t.NumField()) for i := 0; i < t.NumField(); i++ { sf := t.Field(i) name, opts := fieldAlias(sf, tag) @@ -146,7 +168,9 @@ func (e *Encoder) structInfo(t reflect.Type) []encField { recurseStructPtr: ft.Kind() == reflect.Ptr && ft.Elem().Kind() == reflect.Struct && !e.hasCustomEncoder(ft), - enc: typeEncoder(ft, e.regenc), + enc: typeEncoder(ft, e.regenc), + scratchSafe: scratchSafeEncoder(ft, e.regenc), + hasIsZero: ft.Kind() == reflect.Struct && ft.Implements(zeroerType), } if f.enc == nil { switch ft.Kind() { @@ -164,14 +188,65 @@ func (e *Encoder) structInfo(t reflect.Type) []encField { fields = append(fields, f) } e.cache.l.RUnlock() + freshKeys = writesEachKeyOnce(fields) // Don't cache a plan whose inputs (tag, registered encoders) changed // while it was being built; the next call rebuilds it fresh. Even if a // stale plan slips in after the clear, its generation tag keeps it from // ever being served. if e.encGen.Load() == gen { - e.encCache.Store(t, &encPlan{fields: fields, gen: gen}) + e.encCache.Store(t, &encPlan{fields: fields, gen: gen, freshKeys: freshKeys}) + } + return fields, freshKeys +} + +// writesEachKeyOnce reports whether the plan's fields write distinct keys and +// none recurses into a nested struct, whose keys land in the same map and +// could repeat one of these. +func writesEachKeyOnce(fields []encField) bool { + names := make(map[string]struct{}, len(fields)) + for i := range fields { + f := &fields[i] + if f.isStruct || f.recurseStructPtr { + return false + } + if _, dup := names[f.name]; dup { + return false + } + names[f.name] = struct{}{} + } + return true +} + +// zeroer is the optional method a type can provide to decide, for omitempty, +// whether a value of it counts as empty. +type zeroer interface{ IsZero() bool } + +var zeroerType = reflect.TypeFor[zeroer]() + +// isZeroValue applies omitempty to one of this field's values: isZero with +// the struct case answered from the plan, so neither outcome goes through +// reflect.Value.Interface. An addressable struct becomes an interface through +// its address, without a copy, and a type known to lack IsZero skips the +// conversion altogether. +func (f *encField) isZeroValue(v reflect.Value) bool { + if v.Kind() != reflect.Struct || !v.CanInterface() { + return isZero(v) + } + if f.hasIsZero { + if v.CanAddr() { + // A value receiver's IsZero is in the pointer's method set too. + iz, _ := reflect.TypeAssert[zeroer](v.Addr()) + return iz.IsZero() + } + iz, _ := reflect.TypeAssert[zeroer](v) + return iz.IsZero() + } + for i := 0; i < v.NumField(); i++ { + if !isZero(v.Field(i)) { + return false + } } - return fields + return true } func isZero(v reflect.Value) bool { @@ -213,7 +288,40 @@ func (e *Encoder) encode(v reflect.Value, dst map[string][]string) error { var errs MultiError - fields := e.structInfo(v.Type()) + fields, freshKeys := e.structInfo(v.Type()) + // When dst starts empty (fresh url.Values), single short package-allocated + // values of distinct keys share one backing array instead of allocating a + // 1-element slice each; the three-index slice caps entries so later + // appends cannot overwrite a neighbor. Caller-derived strings (string + // fields, custom encoders) and long values get their own independently + // collectible slice so a surviving entry cannot keep a deleted neighbor's + // allocation alive; a non-empty dst keeps the single-map-op append pattern. + useScratch := len(dst) == 0 + // An empty dst plus a plan that writes every key once means each key is + // new, so the read append needs — a second hash of the key — is skipped. + fresh := useScratch && freshKeys + var scratch []string + appendValue := func(name, s string, scratchSafe bool) { + if !useScratch || !scratchSafe || len(s) > maxScratchValueLen { + if fresh { + dst[name] = []string{s} + return + } + dst[name] = append(dst[name], s) + return + } + if !fresh { + if old := dst[name]; old != nil { + dst[name] = append(old, s) + return + } + } + if scratch == nil { + scratch = make([]string, 0, len(fields)) + } + scratch = append(scratch, s) + dst[name] = scratch[len(scratch)-1 : len(scratch) : len(scratch)] + } for i := range fields { f := &fields[i] fieldValue := v.Field(f.idx) @@ -228,10 +336,10 @@ func (e *Encoder) encode(v reflect.Value, dst map[string][]string) error { // Encode non-slice types and custom implementations immediately. if f.enc != nil { - if f.omitEmpty && isZero(fieldValue) { + if f.omitEmpty && f.isZeroValue(fieldValue) { continue } - dst[f.name] = append(dst[f.name], f.enc(fieldValue)) + appendValue(f.name, f.enc(fieldValue), f.scratchSafe) continue } @@ -239,7 +347,8 @@ func (e *Encoder) encode(v reflect.Value, dst map[string][]string) error { if f.omitEmpty { continue } - dst[f.name] = append(dst[f.name], "null") + // The "null" literal is static data; always scratch-safe. + appendValue(f.name, "null", true) continue } @@ -312,6 +421,27 @@ func (e *Encoder) hasCustomEncoder(t reflect.Type) bool { return exists } +// scratchSafeEncoder reports whether typeEncoder(t, reg)'s output strings are +// always allocated by this package's own formatters: string fields return the +// caller's string and custom encoders may return anything — either could be a +// small substring aliasing a large buffer, so neither may enter the scratch. +func scratchSafeEncoder(t reflect.Type, reg map[reflect.Type]encoderFunc) bool { + if _, ok := reg[t]; ok { + return false + } + switch t.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.Float32, reflect.Float64: + return true + case reflect.Ptr: + return scratchSafeEncoder(t.Elem(), reg) + default: + return false + } +} + func typeEncoder(t reflect.Type, reg map[reflect.Type]encoderFunc) encoderFunc { if f, ok := reg[t]; ok { return f @@ -320,9 +450,21 @@ func typeEncoder(t reflect.Type, reg map[reflect.Type]encoderFunc) encoderFunc { switch t.Kind() { case reflect.Bool: return encodeBool - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + case reflect.Int8: + return encodeInt8 + case reflect.Int16: + return encodeInt16 + case reflect.Int32: + return encodeInt32 + case reflect.Int, reflect.Int64: return encodeInt - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + case reflect.Uint8: + return encodeUint8 + case reflect.Uint16: + return encodeUint16 + case reflect.Uint32: + return encodeUint32 + case reflect.Uint, reflect.Uint64: return encodeUint case reflect.Float32: return encodeFloat32 @@ -353,16 +495,44 @@ func encodeBool(v reflect.Value) string { return strconv.FormatBool(v.Bool()) } +// Integers go through the width-specific utils helpers: the 8-bit ones are +// table lookups, allocating nothing, and the 32-bit ones skip a digit group +// the 64-bit formatter has to consider. + func encodeInt(v reflect.Value) string { return utils.FormatInt(v.Int()) } +func encodeInt8(v reflect.Value) string { + return utils.FormatInt8(int8(v.Int())) +} + +func encodeInt16(v reflect.Value) string { + return utils.FormatInt16(int16(v.Int())) +} + +func encodeInt32(v reflect.Value) string { + return utils.FormatInt32(int32(v.Int())) +} + func encodeUint(v reflect.Value) string { return utils.FormatUint(v.Uint()) } +func encodeUint8(v reflect.Value) string { + return utils.FormatUint8(uint8(v.Uint())) +} + +func encodeUint16(v reflect.Value) string { + return utils.FormatUint16(uint16(v.Uint())) +} + +func encodeUint32(v reflect.Value) string { + return utils.FormatUint32(uint32(v.Uint())) +} + func encodeFloat(v reflect.Value, bits int) string { - return strconv.FormatFloat(v.Float(), 'f', 6, bits) + return formatFloatFixed(v.Float(), bits) } func encodeFloat32(v reflect.Value) string { diff --git a/src/vendor/github.com/gofiber/schema/floatfmt.go b/src/vendor/github.com/gofiber/schema/floatfmt.go new file mode 100644 index 00000000..a68fa461 --- /dev/null +++ b/src/vendor/github.com/gofiber/schema/floatfmt.go @@ -0,0 +1,105 @@ +package schema + +import ( + "math" + "math/bits" + "strconv" + + utils "github.com/gofiber/utils/v2" +) + +// encFloatPrec is the number of fractional digits the encoder emits for +// float fields. +const encFloatPrec = 6 + +// scaleFixed is 10^encFloatPrec, the factor that turns a value into the +// integer the formatter prints. +const scaleFixed = 1_000_000 + +// fastFixedLimit bounds the magnitude the exact-integer path accepts: below +// it |value|*10^6 stays under 10^18, so the scaled result and a round-up's +1 +// both fit a uint64. +const fastFixedLimit = 1e12 + +// formatFloatFixed is strconv.FormatFloat(f, 'f', encFloatPrec, bitSize). +// +// strconv has no Ryū fast path for the 'f' verb with a fixed precision (see +// the `fmt != 'f'` guard in its ftoa), so every such call runs the +// multi-precision decimal path. A float's exact value is mant*2^exp, so for +// exponents in range the printed digits are exactly +// round-half-to-even(mant*10^6 * 2^exp), which a 128-bit multiply and a shift +// compute directly; utils.AppendUint then lays down the digits. Inf, NaN and +// magnitudes outside the fast range fall back to strconv. +func formatFloatFixed(f float64, bitSize int) string { + if bitSize == 32 { + // strconv formats the float32 value, which is what the decomposition + // below must see. + f = float64(float32(f)) + } + + u := math.Float64bits(f) + neg := u>>63 != 0 + biasedExp := int(u>>52) & 0x7FF + mant := u & (1<<52 - 1) + if biasedExp == 0x7FF { + // Inf or NaN. + return strconv.FormatFloat(f, 'f', encFloatPrec, bitSize) + } + if biasedExp == 0 { + biasedExp = 1 // subnormal: no implicit leading bit + } else { + mant |= 1 << 52 + } + // f == mant * 2^exp exactly. + exp := biasedExp - 1023 - 52 + // exp >= 0 means |f| >= 2^52, where f*10^6 overflows a uint64; the + // magnitude check bounds the scaled value for everything else. + if exp >= 0 || f > fastFixedLimit || f < -fastFixedLimit { + return strconv.FormatFloat(f, 'f', encFloatPrec, bitSize) + } + + // n = round-half-to-even(mant*10^6 / 2^k), computed on the exact + // 128-bit product so the tie test sees the value's true remainder. + k := uint(-exp) + hi, lo := bits.Mul64(mant, scaleFixed) + var n uint64 + switch { + case k >= 74: + // mant*10^6 < 2^73 <= 2^(k-1), i.e. below half a unit: rounds to 0. + n = 0 + case k < 64: + n = lo>>k | hi<<(64-k) + half := uint64(1) << (k - 1) + if r := lo & (half<<1 - 1); r > half || (r == half && n&1 != 0) { + n++ + } + case k == 64: + n = hi + if lo > 1<<63 || (lo == 1<<63 && n&1 != 0) { + n++ + } + default: + s := k - 64 + n = hi >> s + half := uint64(1) << (s - 1) + // The discarded bits are hi's low s bits followed by all of lo, so + // a tie needs the half bit set and every lower bit clear. + if r := hi & (half<<1 - 1); r > half || (r == half && (lo != 0 || n&1 != 0)) { + n++ + } + } + + // Sign, integer digits (at most 13), '.', then six fractional digits. + var buf [24]byte + dst := buf[:0] + if neg { + dst = append(dst, '-') + } + dst = utils.AppendUint(dst, n/scaleFixed) + dst = append(dst, '.') + // Formatting 10^6+frac and dropping its leading '1' zero-pads the + // fraction without a per-digit loop. + var frac [8]byte + dst = append(dst, utils.AppendUint(frac[:0], scaleFixed+n%scaleFixed)[1:]...) + return string(dst) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/README.md b/src/vendor/github.com/gofiber/utils/v2/README.md index 3e8afccb..d6d215e6 100644 --- a/src/vendor/github.com/gofiber/utils/v2/README.md +++ b/src/vendor/github.com/gofiber/utils/v2/README.md @@ -24,425 +24,432 @@ cpu: Apple M2 Pro // (swar's Benchmark_Load8_Fusion, an advisory codegen guard, is deliberately omitted) # Case Conversion -Benchmark_ToLowerBytes/empty/fiber-12 599341221 1.970 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/empty/fiber/unsafe-12 613673802 1.951 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/empty/default-12 363300402 3.316 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/http-get/fiber-12 350302147 3.434 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/http-get/fiber/unsafe-12 250488015 4.803 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/http-get/default-12 65883986 18.03 ns/op 8 B/op 1 allocs/op -Benchmark_ToLowerBytes/http-get-upper/fiber-12 95234625 12.53 ns/op 3 B/op 1 allocs/op -Benchmark_ToLowerBytes/http-get-upper/fiber/unsafe-12 242418936 4.802 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/http-get-upper/default-12 86405012 13.85 ns/op 8 B/op 1 allocs/op -Benchmark_ToLowerBytes/header-content-type-mixed/fiber-12 52263289 22.74 ns/op 48 B/op 1 allocs/op -Benchmark_ToLowerBytes/header-content-type-mixed/fiber/unsafe-12 131711175 9.101 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/header-content-type-mixed/default-12 25312339 47.13 ns/op 48 B/op 1 allocs/op -Benchmark_ToLowerBytes/large-lower/fiber-12 120148472 10.02 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/large-lower/fiber/unsafe-12 100000000 10.57 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/large-lower/default-12 16746064 71.43 ns/op 64 B/op 1 allocs/op -Benchmark_ToLowerBytes/large-upper/fiber-12 46270634 26.82 ns/op 64 B/op 1 allocs/op -Benchmark_ToLowerBytes/large-upper/fiber/unsafe-12 100000000 10.71 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/large-upper/default-12 15734505 76.92 ns/op 64 B/op 1 allocs/op -Benchmark_ToLowerBytes/large-mixed/fiber-12 46607823 26.06 ns/op 64 B/op 1 allocs/op -Benchmark_ToLowerBytes/large-mixed/fiber/unsafe-12 100000000 10.86 ns/op 0 B/op 0 allocs/op -Benchmark_ToLowerBytes/large-mixed/default-12 16291084 73.76 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpperBytes/empty/fiber-12 607678140 1.976 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/empty/fiber/unsafe-12 611928006 1.981 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/empty/default-12 362632894 3.309 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/http-get/fiber-12 95358867 12.55 ns/op 3 B/op 1 allocs/op -Benchmark_ToUpperBytes/http-get/fiber/unsafe-12 249490471 4.905 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/http-get/default-12 79248020 14.63 ns/op 8 B/op 1 allocs/op -Benchmark_ToUpperBytes/http-get-upper/fiber-12 365516280 3.330 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/http-get-upper/fiber/unsafe-12 249981619 4.803 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/http-get-upper/default-12 64343162 19.01 ns/op 8 B/op 1 allocs/op -Benchmark_ToUpperBytes/header-content-type-mixed/fiber-12 52506741 22.69 ns/op 48 B/op 1 allocs/op -Benchmark_ToUpperBytes/header-content-type-mixed/fiber/unsafe-12 130478352 9.350 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/header-content-type-mixed/default-12 22415607 54.44 ns/op 48 B/op 1 allocs/op -Benchmark_ToUpperBytes/large-lower/fiber-12 44765679 26.92 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpperBytes/large-lower/fiber/unsafe-12 100000000 13.68 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/large-lower/default-12 14464340 110.7 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpperBytes/large-upper/fiber-12 100000000 11.98 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/large-upper/fiber/unsafe-12 83808488 13.94 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/large-upper/default-12 13142096 87.35 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpperBytes/large-mixed/fiber-12 33038661 32.75 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpperBytes/large-mixed/fiber/unsafe-12 100000000 10.93 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpperBytes/large-mixed/default-12 15034422 98.27 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpper/empty/fiber-12 595298628 2.309 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/empty/fiber/unsafe-12 595273404 2.021 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/empty/default-12 636980288 1.883 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/http-get/fiber-12 97025577 12.40 ns/op 3 B/op 1 allocs/op -Benchmark_ToUpper/http-get/fiber/unsafe-12 244711635 4.857 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/http-get/default-12 59790234 19.54 ns/op 8 B/op 1 allocs/op -Benchmark_ToUpper/http-get-upper/fiber-12 383218539 3.056 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/http-get-upper/fiber/unsafe-12 247851331 4.864 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/http-get-upper/default-12 223044249 5.182 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/header-content-type-mixed/fiber-12 52628502 24.13 ns/op 48 B/op 1 allocs/op -Benchmark_ToUpper/header-content-type-mixed/fiber/unsafe-12 127726341 9.233 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/header-content-type-mixed/default-12 11549816 104.0 ns/op 48 B/op 1 allocs/op -Benchmark_ToUpper/large-lower/fiber-12 42409070 26.04 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpper/large-lower/fiber/unsafe-12 100000000 11.00 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/large-lower/default-12 7051911 169.0 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpper/large-upper/fiber-12 123837582 9.590 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/large-upper/fiber/unsafe-12 100000000 10.83 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/large-upper/default-12 19115356 61.51 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/large-mixed/fiber-12 45872143 27.77 ns/op 64 B/op 1 allocs/op -Benchmark_ToUpper/large-mixed/fiber/unsafe-12 100000000 11.00 ns/op 0 B/op 0 allocs/op -Benchmark_ToUpper/large-mixed/default-12 5927710 203.1 ns/op 64 B/op 1 allocs/op -Benchmark_ToLower/empty/fiber-12 613625554 1.952 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/empty/fiber/unsafe-12 572670608 1.989 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/empty/default-12 644769141 1.863 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/http-get/fiber-12 395302272 3.034 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/http-get/fiber/unsafe-12 252231990 4.813 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/http-get/default-12 284202345 4.219 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/http-get-upper/fiber-12 100000000 12.08 ns/op 3 B/op 1 allocs/op -Benchmark_ToLower/http-get-upper/fiber/unsafe-12 252859507 4.816 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/http-get-upper/default-12 60415860 19.54 ns/op 8 B/op 1 allocs/op -Benchmark_ToLower/header-content-type-mixed/fiber-12 53446660 22.49 ns/op 48 B/op 1 allocs/op -Benchmark_ToLower/header-content-type-mixed/fiber/unsafe-12 131152108 9.153 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/header-content-type-mixed/default-12 18039788 66.79 ns/op 48 B/op 1 allocs/op -Benchmark_ToLower/large-lower/fiber-12 120227584 9.982 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/large-lower/fiber/unsafe-12 100000000 10.68 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/large-lower/default-12 24070928 48.79 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/large-upper/fiber-12 44699118 25.92 ns/op 64 B/op 1 allocs/op -Benchmark_ToLower/large-upper/fiber/unsafe-12 100000000 10.74 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/large-upper/default-12 7075200 170.0 ns/op 64 B/op 1 allocs/op -Benchmark_ToLower/large-mixed/fiber-12 46426453 26.01 ns/op 64 B/op 1 allocs/op -Benchmark_ToLower/large-mixed/fiber/unsafe-12 100000000 10.74 ns/op 0 B/op 0 allocs/op -Benchmark_ToLower/large-mixed/default-12 5682778 204.3 ns/op 64 B/op 1 allocs/op +Benchmark_ToLowerBytes/empty/fiber-12 599341221 1.970 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/empty/fiber/unsafe-12 613673802 1.951 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/empty/default-12 363300402 3.316 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/http-get/fiber-12 350302147 3.434 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/http-get/fiber/unsafe-12 250488015 4.803 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/http-get/default-12 65883986 18.03 ns/op 8 B/op 1 allocs/op +Benchmark_ToLowerBytes/http-get-upper/fiber-12 95234625 12.53 ns/op 3 B/op 1 allocs/op +Benchmark_ToLowerBytes/http-get-upper/fiber/unsafe-12 242418936 4.802 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/http-get-upper/default-12 86405012 13.85 ns/op 8 B/op 1 allocs/op +Benchmark_ToLowerBytes/header-content-type-mixed/fiber-12 52263289 22.74 ns/op 48 B/op 1 allocs/op +Benchmark_ToLowerBytes/header-content-type-mixed/fiber/unsafe-12 131711175 9.101 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/header-content-type-mixed/default-12 25312339 47.13 ns/op 48 B/op 1 allocs/op +Benchmark_ToLowerBytes/large-lower/fiber-12 120148472 10.02 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/large-lower/fiber/unsafe-12 100000000 10.57 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/large-lower/default-12 16746064 71.43 ns/op 64 B/op 1 allocs/op +Benchmark_ToLowerBytes/large-upper/fiber-12 46270634 26.82 ns/op 64 B/op 1 allocs/op +Benchmark_ToLowerBytes/large-upper/fiber/unsafe-12 100000000 10.71 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/large-upper/default-12 15734505 76.92 ns/op 64 B/op 1 allocs/op +Benchmark_ToLowerBytes/large-mixed/fiber-12 46607823 26.06 ns/op 64 B/op 1 allocs/op +Benchmark_ToLowerBytes/large-mixed/fiber/unsafe-12 100000000 10.86 ns/op 0 B/op 0 allocs/op +Benchmark_ToLowerBytes/large-mixed/default-12 16291084 73.76 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpperBytes/empty/fiber-12 607678140 1.976 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/empty/fiber/unsafe-12 611928006 1.981 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/empty/default-12 362632894 3.309 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/http-get/fiber-12 95358867 12.55 ns/op 3 B/op 1 allocs/op +Benchmark_ToUpperBytes/http-get/fiber/unsafe-12 249490471 4.905 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/http-get/default-12 79248020 14.63 ns/op 8 B/op 1 allocs/op +Benchmark_ToUpperBytes/http-get-upper/fiber-12 365516280 3.330 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/http-get-upper/fiber/unsafe-12 249981619 4.803 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/http-get-upper/default-12 64343162 19.01 ns/op 8 B/op 1 allocs/op +Benchmark_ToUpperBytes/header-content-type-mixed/fiber-12 52506741 22.69 ns/op 48 B/op 1 allocs/op +Benchmark_ToUpperBytes/header-content-type-mixed/fiber/unsafe-12 130478352 9.350 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/header-content-type-mixed/default-12 22415607 54.44 ns/op 48 B/op 1 allocs/op +Benchmark_ToUpperBytes/large-lower/fiber-12 44765679 26.92 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpperBytes/large-lower/fiber/unsafe-12 100000000 13.68 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/large-lower/default-12 14464340 110.7 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpperBytes/large-upper/fiber-12 100000000 11.98 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/large-upper/fiber/unsafe-12 83808488 13.94 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/large-upper/default-12 13142096 87.35 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpperBytes/large-mixed/fiber-12 33038661 32.75 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpperBytes/large-mixed/fiber/unsafe-12 100000000 10.93 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpperBytes/large-mixed/default-12 15034422 98.27 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpper/empty/fiber-12 595298628 2.309 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/empty/fiber/unsafe-12 595273404 2.021 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/empty/default-12 636980288 1.883 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/http-get/fiber-12 97025577 12.40 ns/op 3 B/op 1 allocs/op +Benchmark_ToUpper/http-get/fiber/unsafe-12 244711635 4.857 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/http-get/default-12 59790234 19.54 ns/op 8 B/op 1 allocs/op +Benchmark_ToUpper/http-get-upper/fiber-12 383218539 3.056 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/http-get-upper/fiber/unsafe-12 247851331 4.864 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/http-get-upper/default-12 223044249 5.182 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/header-content-type-mixed/fiber-12 52628502 24.13 ns/op 48 B/op 1 allocs/op +Benchmark_ToUpper/header-content-type-mixed/fiber/unsafe-12 127726341 9.233 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/header-content-type-mixed/default-12 11549816 104.0 ns/op 48 B/op 1 allocs/op +Benchmark_ToUpper/large-lower/fiber-12 42409070 26.04 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpper/large-lower/fiber/unsafe-12 100000000 11.00 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/large-lower/default-12 7051911 169.0 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpper/large-upper/fiber-12 123837582 9.590 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/large-upper/fiber/unsafe-12 100000000 10.83 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/large-upper/default-12 19115356 61.51 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/large-mixed/fiber-12 45872143 27.77 ns/op 64 B/op 1 allocs/op +Benchmark_ToUpper/large-mixed/fiber/unsafe-12 100000000 11.00 ns/op 0 B/op 0 allocs/op +Benchmark_ToUpper/large-mixed/default-12 5927710 203.1 ns/op 64 B/op 1 allocs/op +Benchmark_ToLower/empty/fiber-12 613625554 1.952 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/empty/fiber/unsafe-12 572670608 1.989 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/empty/default-12 644769141 1.863 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/http-get/fiber-12 395302272 3.034 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/http-get/fiber/unsafe-12 252231990 4.813 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/http-get/default-12 284202345 4.219 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/http-get-upper/fiber-12 100000000 12.08 ns/op 3 B/op 1 allocs/op +Benchmark_ToLower/http-get-upper/fiber/unsafe-12 252859507 4.816 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/http-get-upper/default-12 60415860 19.54 ns/op 8 B/op 1 allocs/op +Benchmark_ToLower/header-content-type-mixed/fiber-12 53446660 22.49 ns/op 48 B/op 1 allocs/op +Benchmark_ToLower/header-content-type-mixed/fiber/unsafe-12 131152108 9.153 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/header-content-type-mixed/default-12 18039788 66.79 ns/op 48 B/op 1 allocs/op +Benchmark_ToLower/large-lower/fiber-12 120227584 9.982 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/large-lower/fiber/unsafe-12 100000000 10.68 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/large-lower/default-12 24070928 48.79 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/large-upper/fiber-12 44699118 25.92 ns/op 64 B/op 1 allocs/op +Benchmark_ToLower/large-upper/fiber/unsafe-12 100000000 10.74 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/large-upper/default-12 7075200 170.0 ns/op 64 B/op 1 allocs/op +Benchmark_ToLower/large-mixed/fiber-12 46426453 26.01 ns/op 64 B/op 1 allocs/op +Benchmark_ToLower/large-mixed/fiber/unsafe-12 100000000 10.74 ns/op 0 B/op 0 allocs/op +Benchmark_ToLower/large-mixed/default-12 5682778 204.3 ns/op 64 B/op 1 allocs/op # Add Trailing Slash -Benchmark_AddTrailingSlashBytes/empty-12 1000000000 0.5857 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashBytes/slash-only-12 1000000000 0.8694 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashBytes/short-no-slash-12 100000000 11.65 ns/op 4 B/op 1 allocs/op -Benchmark_AddTrailingSlashBytes/short-with-slash-12 1000000000 0.8867 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashBytes/path-no-slash-12 93543546 13.36 ns/op 16 B/op 1 allocs/op -Benchmark_AddTrailingSlashBytes/path-with-slash-12 1000000000 0.9011 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashString/empty-12 1000000000 0.2926 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashString/slash-only-12 1000000000 0.4482 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashString/short-no-slash-12 100000000 11.37 ns/op 4 B/op 1 allocs/op -Benchmark_AddTrailingSlashString/short-with-slash-12 1000000000 0.4502 ns/op 0 B/op 0 allocs/op -Benchmark_AddTrailingSlashString/path-no-slash-12 82427726 14.41 ns/op 16 B/op 1 allocs/op -Benchmark_AddTrailingSlashString/path-with-slash-12 1000000000 0.4529 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashBytes/empty-12 1000000000 0.5857 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashBytes/slash-only-12 1000000000 0.8694 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashBytes/short-no-slash-12 100000000 11.65 ns/op 4 B/op 1 allocs/op +Benchmark_AddTrailingSlashBytes/short-with-slash-12 1000000000 0.8867 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashBytes/path-no-slash-12 93543546 13.36 ns/op 16 B/op 1 allocs/op +Benchmark_AddTrailingSlashBytes/path-with-slash-12 1000000000 0.9011 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashString/empty-12 1000000000 0.2926 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashString/slash-only-12 1000000000 0.4482 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashString/short-no-slash-12 100000000 11.37 ns/op 4 B/op 1 allocs/op +Benchmark_AddTrailingSlashString/short-with-slash-12 1000000000 0.4502 ns/op 0 B/op 0 allocs/op +Benchmark_AddTrailingSlashString/path-no-slash-12 82427726 14.41 ns/op 16 B/op 1 allocs/op +Benchmark_AddTrailingSlashString/path-with-slash-12 1000000000 0.4529 ns/op 0 B/op 0 allocs/op # EqualFold -Benchmark_EqualFoldBytes/fiber-12 67368261 18.48 ns/op 0 B/op 0 allocs/op -Benchmark_EqualFoldBytes/default-12 17774803 65.91 ns/op 0 B/op 0 allocs/op -Benchmark_EqualFold/fiber-12 80501566 14.75 ns/op 0 B/op 0 allocs/op -Benchmark_EqualFold/default-12 18314365 65.96 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFoldBytes/fiber-12 67368261 18.48 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFoldBytes/default-12 17774803 65.91 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold/fiber-12 80501566 14.75 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold/default-12 18314365 65.96 ns/op 0 B/op 0 allocs/op # Search -Benchmark_IndexAny2/7B/swar-12 282163779 4.297 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/7B/scalar-12 314553402 3.826 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/7B/stdlib-indexany-12 50085909 23.97 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/8B/swar-12 522780714 2.289 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/8B/scalar-12 271494799 4.206 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/8B/stdlib-indexany-12 44831599 26.78 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/16B/swar-12 393245086 3.047 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/16B/scalar-12 168476984 7.117 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/16B/stdlib-indexany-12 100000000 10.03 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/32B/swar-12 252199587 4.802 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/32B/scalar-12 84105762 14.27 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/32B/stdlib-indexany-12 70291048 17.37 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/64B/swar-12 144335962 8.290 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/64B/scalar-12 42694686 28.60 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/64B/stdlib-indexany-12 37615540 32.23 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/512B/swar-12 20231538 59.71 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/512B/scalar-12 5071586 233.6 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny2/512B/stdlib-indexany-12 4448119 274.2 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/7B/swar-12 221889592 5.397 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/7B/scalar-12 240859849 4.977 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/8B/swar-12 445742876 2.689 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/8B/scalar-12 211981612 5.620 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/16B/swar-12 326475568 3.739 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/16B/scalar-12 100000000 10.31 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/32B/swar-12 196365920 6.112 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/32B/scalar-12 60021255 19.81 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/64B/swar-12 100000000 10.98 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/64B/scalar-12 31180405 38.97 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/512B/swar-12 15466316 79.22 ns/op 0 B/op 0 allocs/op -Benchmark_IndexAny3/512B/scalar-12 3911382 307.1 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/miss-8B/swar-12 332497509 3.634 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/miss-8B/scalar-12 491493494 2.408 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/miss-32B/swar-12 149769112 7.928 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/miss-32B/scalar-12 44041342 27.13 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/hit-32B/swar-12 138732252 8.758 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/hit-32B/scalar-12 33871633 30.73 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/hit-tail/swar-12 100000000 12.34 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/hit-tail/scalar-12 16138168 75.39 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/miss-64B/swar-12 100000000 11.37 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/miss-64B/scalar-12 17902330 67.78 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/miss-512B/swar-12 17640939 67.65 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/miss-512B/scalar-12 2211582 544.4 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/long-hit-64B/swar-12 100000000 11.58 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/long-hit-64B/scalar-12 23906326 51.33 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/long-miss-64B/swar-12 100000000 11.33 ns/op 0 B/op 0 allocs/op -Benchmark_IndexFold/long-miss-64B/scalar-12 23553600 50.27 ns/op 0 B/op 0 allocs/op +// amd64 note: IndexAny2/IndexAny3 dispatch to package simd for 32+ byte +// inputs; these arm64 rows keep the portable SWAR path. For amd64 numbers +// see the Benchmark_Memchr2/Benchmark_Memchr3 rows in the simd section +// below (the kernels these functions dispatch to). +Benchmark_IndexAny2/7B/swar-12 282163779 4.297 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/7B/scalar-12 314553402 3.826 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/7B/stdlib-indexany-12 50085909 23.97 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/8B/swar-12 522780714 2.289 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/8B/scalar-12 271494799 4.206 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/8B/stdlib-indexany-12 44831599 26.78 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/16B/swar-12 393245086 3.047 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/16B/scalar-12 168476984 7.117 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/16B/stdlib-indexany-12 100000000 10.03 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/32B/swar-12 252199587 4.802 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/32B/scalar-12 84105762 14.27 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/32B/stdlib-indexany-12 70291048 17.37 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/64B/swar-12 144335962 8.290 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/64B/scalar-12 42694686 28.60 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/64B/stdlib-indexany-12 37615540 32.23 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/512B/swar-12 20231538 59.71 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/512B/scalar-12 5071586 233.6 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny2/512B/stdlib-indexany-12 4448119 274.2 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/7B/swar-12 221889592 5.397 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/7B/scalar-12 240859849 4.977 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/8B/swar-12 445742876 2.689 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/8B/scalar-12 211981612 5.620 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/16B/swar-12 326475568 3.739 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/16B/scalar-12 100000000 10.31 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/32B/swar-12 196365920 6.112 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/32B/scalar-12 60021255 19.81 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/64B/swar-12 100000000 10.98 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/64B/scalar-12 31180405 38.97 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/512B/swar-12 15466316 79.22 ns/op 0 B/op 0 allocs/op +Benchmark_IndexAny3/512B/scalar-12 3911382 307.1 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-8B/swar-12 332497509 3.634 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-8B/scalar-12 491493494 2.408 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-32B/swar-12 149769112 7.928 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-32B/scalar-12 44041342 27.13 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/hit-32B/swar-12 138732252 8.758 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/hit-32B/scalar-12 33871633 30.73 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/hit-tail/swar-12 100000000 12.34 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/hit-tail/scalar-12 16138168 75.39 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-64B/swar-12 100000000 11.37 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-64B/scalar-12 17902330 67.78 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-512B/swar-12 17640939 67.65 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/miss-512B/scalar-12 2211582 544.4 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/long-hit-64B/swar-12 100000000 11.58 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/long-hit-64B/scalar-12 23906326 51.33 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/long-miss-64B/swar-12 100000000 11.33 ns/op 0 B/op 0 allocs/op +Benchmark_IndexFold/long-miss-64B/scalar-12 23553600 50.27 ns/op 0 B/op 0 allocs/op # ASCII -Benchmark_IsASCII/7B/swar-12 238699563 5.001 ns/op 0 B/op 0 allocs/op -Benchmark_IsASCII/7B/scalar-12 292669958 4.064 ns/op 0 B/op 0 allocs/op -Benchmark_IsASCII/8B/swar-12 439961722 2.687 ns/op 0 B/op 0 allocs/op -Benchmark_IsASCII/8B/scalar-12 274732192 4.364 ns/op 0 B/op 0 allocs/op -Benchmark_IsASCII/16B/swar-12 367179319 3.255 ns/op 0 B/op 0 allocs/op -Benchmark_IsASCII/16B/scalar-12 179331987 6.706 ns/op 0 B/op 0 allocs/op -Benchmark_IsASCII/32B/swar-12 368345228 3.271 ns/op 0 B/op 0 allocs/op -Benchmark_IsASCII/32B/scalar-12 100000000 11.62 ns/op 0 B/op 0 allocs/op -Benchmark_IsASCII/64B/swar-12 265505815 4.486 ns/op 0 B/op 0 allocs/op -Benchmark_IsASCII/64B/scalar-12 57864440 21.33 ns/op 0 B/op 0 allocs/op -Benchmark_IsASCII/512B/swar-12 47664915 25.14 ns/op 0 B/op 0 allocs/op -Benchmark_IsASCII/512B/scalar-12 7081790 169.5 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/7B/swar-12 142234436 8.424 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/7B/scalar-12 142394628 8.174 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/8B/swar-12 401721262 3.099 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/8B/scalar-12 138047568 8.654 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/16B/swar-12 244592613 5.059 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/16B/scalar-12 75413396 15.94 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/32B/swar-12 138857455 8.875 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/32B/scalar-12 39539425 30.18 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/64B/swar-12 75193269 16.46 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/64B/scalar-12 20898807 57.81 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/512B/swar-12 9634008 124.9 ns/op 0 B/op 0 allocs/op -Benchmark_IndexNonQuotable/512B/scalar-12 2619062 460.6 ns/op 0 B/op 0 allocs/op +// amd64 note: IsASCII dispatches to package simd for 32+ byte inputs; +// these arm64 rows keep the portable SWAR path. See the simd section +// below for amd64 numbers. +Benchmark_IsASCII/7B/swar-12 238699563 5.001 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/7B/scalar-12 292669958 4.064 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/8B/swar-12 439961722 2.687 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/8B/scalar-12 274732192 4.364 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/16B/swar-12 367179319 3.255 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/16B/scalar-12 179331987 6.706 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/32B/swar-12 368345228 3.271 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/32B/scalar-12 100000000 11.62 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/64B/swar-12 265505815 4.486 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/64B/scalar-12 57864440 21.33 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/512B/swar-12 47664915 25.14 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/512B/scalar-12 7081790 169.5 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/7B/swar-12 142234436 8.424 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/7B/scalar-12 142394628 8.174 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/8B/swar-12 401721262 3.099 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/8B/scalar-12 138047568 8.654 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/16B/swar-12 244592613 5.059 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/16B/scalar-12 75413396 15.94 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/32B/swar-12 138857455 8.875 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/32B/scalar-12 39539425 30.18 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/64B/swar-12 75193269 16.46 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/64B/scalar-12 20898807 57.81 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/512B/swar-12 9634008 124.9 ns/op 0 B/op 0 allocs/op +Benchmark_IndexNonQuotable/512B/scalar-12 2619062 460.6 ns/op 0 B/op 0 allocs/op # Trim -Benchmark_TrimRight/fiber-12 587360972 2.043 ns/op 0 B/op 0 allocs/op -Benchmark_TrimRight/default-12 417142952 2.887 ns/op 0 B/op 0 allocs/op -Benchmark_TrimRightBytes/fiber-12 590828253 2.067 ns/op 0 B/op 0 allocs/op -Benchmark_TrimRightBytes/default-12 374548395 3.236 ns/op 0 B/op 0 allocs/op -Benchmark_TrimLeft/fiber-12 590822072 2.030 ns/op 0 B/op 0 allocs/op -Benchmark_TrimLeft/default-12 408184784 2.967 ns/op 0 B/op 0 allocs/op -Benchmark_TrimLeftBytes/fiber-12 592875732 2.033 ns/op 0 B/op 0 allocs/op -Benchmark_TrimLeftBytes/default-12 405921434 2.967 ns/op 0 B/op 0 allocs/op -Benchmark_Trim/fiber-12 317625432 3.758 ns/op 0 B/op 0 allocs/op -Benchmark_Trim/default-12 250173384 4.735 ns/op 0 B/op 0 allocs/op -Benchmark_Trim/default.trimspace-12 241883282 5.022 ns/op 0 B/op 0 allocs/op -Benchmark_TrimBytes/fiber-12 308885211 3.858 ns/op 0 B/op 0 allocs/op -Benchmark_TrimBytes/default-12 254064188 4.802 ns/op 0 B/op 0 allocs/op -Benchmark_TrimBytes/default.trimspace-12 224231778 5.330 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/empty-12 1000000000 0.3017 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/empty-12 583064172 2.074 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/spaces-12 387354229 3.059 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/spaces-12 320059388 3.651 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/ascii-word-12 345078337 3.535 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/ascii-word-12 270603267 4.465 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/auth-header-bearer-12 291494109 4.141 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/auth-header-bearer-12 224087944 5.329 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/auth-header-basic-12 390765345 3.047 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/auth-header-basic-12 258943531 4.718 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/accept-encoding-12 344369745 3.490 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/accept-encoding-12 277203638 4.347 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/content-type-12 344263705 3.506 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/content-type-12 276213367 4.343 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/x-forwarded-for-12 460119685 2.653 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/x-forwarded-for-12 296468840 4.058 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/query-params-12 330053276 3.520 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/query-params-12 275688495 4.352 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/ascii-long-12 275511898 4.342 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/ascii-long-12 206143018 5.807 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/no-trim-12 1000000000 0.5914 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/no-trim-12 451842741 2.634 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/fiber/mixed-whitespace-12 296083767 4.054 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpace/default/mixed-whitespace-12 224007750 5.294 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/empty-12 1000000000 0.2914 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/empty-12 519488766 2.352 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/spaces-12 410959255 2.966 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/spaces-12 315602949 3.827 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/ascii-word-12 341217429 3.519 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/ascii-word-12 247799318 4.667 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/auth-header-bearer-12 295130076 4.182 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/auth-header-bearer-12 209162235 5.685 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/auth-header-basic-12 393366796 3.053 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/auth-header-basic-12 240882009 4.930 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/accept-encoding-12 343673244 3.512 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/accept-encoding-12 250962042 4.642 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/content-type-12 344382758 3.516 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/content-type-12 250622116 4.693 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/x-forwarded-for-12 459435145 2.621 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/x-forwarded-for-12 276595178 4.359 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/query-params-12 341144192 3.526 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/query-params-12 255843174 4.873 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/ascii-long-12 270183530 4.445 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/ascii-long-12 189740618 6.335 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/no-trim-12 1000000000 0.5969 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/no-trim-12 406072189 2.941 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/fiber/mixed-whitespace-12 289382116 4.057 ns/op 0 B/op 0 allocs/op -Benchmark_TrimSpaceBytes/default/mixed-whitespace-12 218559462 5.493 ns/op 0 B/op 0 allocs/op +Benchmark_TrimRight/fiber-12 587360972 2.043 ns/op 0 B/op 0 allocs/op +Benchmark_TrimRight/default-12 417142952 2.887 ns/op 0 B/op 0 allocs/op +Benchmark_TrimRightBytes/fiber-12 590828253 2.067 ns/op 0 B/op 0 allocs/op +Benchmark_TrimRightBytes/default-12 374548395 3.236 ns/op 0 B/op 0 allocs/op +Benchmark_TrimLeft/fiber-12 590822072 2.030 ns/op 0 B/op 0 allocs/op +Benchmark_TrimLeft/default-12 408184784 2.967 ns/op 0 B/op 0 allocs/op +Benchmark_TrimLeftBytes/fiber-12 592875732 2.033 ns/op 0 B/op 0 allocs/op +Benchmark_TrimLeftBytes/default-12 405921434 2.967 ns/op 0 B/op 0 allocs/op +Benchmark_Trim/fiber-12 317625432 3.758 ns/op 0 B/op 0 allocs/op +Benchmark_Trim/default-12 250173384 4.735 ns/op 0 B/op 0 allocs/op +Benchmark_Trim/default.trimspace-12 241883282 5.022 ns/op 0 B/op 0 allocs/op +Benchmark_TrimBytes/fiber-12 308885211 3.858 ns/op 0 B/op 0 allocs/op +Benchmark_TrimBytes/default-12 254064188 4.802 ns/op 0 B/op 0 allocs/op +Benchmark_TrimBytes/default.trimspace-12 224231778 5.330 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/empty-12 1000000000 0.3017 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/empty-12 583064172 2.074 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/spaces-12 387354229 3.059 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/spaces-12 320059388 3.651 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/ascii-word-12 345078337 3.535 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/ascii-word-12 270603267 4.465 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/auth-header-bearer-12 291494109 4.141 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/auth-header-bearer-12 224087944 5.329 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/auth-header-basic-12 390765345 3.047 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/auth-header-basic-12 258943531 4.718 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/accept-encoding-12 344369745 3.490 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/accept-encoding-12 277203638 4.347 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/content-type-12 344263705 3.506 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/content-type-12 276213367 4.343 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/x-forwarded-for-12 460119685 2.653 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/x-forwarded-for-12 296468840 4.058 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/query-params-12 330053276 3.520 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/query-params-12 275688495 4.352 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/ascii-long-12 275511898 4.342 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/ascii-long-12 206143018 5.807 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/no-trim-12 1000000000 0.5914 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/no-trim-12 451842741 2.634 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/fiber/mixed-whitespace-12 296083767 4.054 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpace/default/mixed-whitespace-12 224007750 5.294 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/empty-12 1000000000 0.2914 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/empty-12 519488766 2.352 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/spaces-12 410959255 2.966 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/spaces-12 315602949 3.827 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/ascii-word-12 341217429 3.519 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/ascii-word-12 247799318 4.667 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/auth-header-bearer-12 295130076 4.182 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/auth-header-bearer-12 209162235 5.685 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/auth-header-basic-12 393366796 3.053 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/auth-header-basic-12 240882009 4.930 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/accept-encoding-12 343673244 3.512 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/accept-encoding-12 250962042 4.642 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/content-type-12 344382758 3.516 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/content-type-12 250622116 4.693 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/x-forwarded-for-12 459435145 2.621 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/x-forwarded-for-12 276595178 4.359 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/query-params-12 341144192 3.526 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/query-params-12 255843174 4.873 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/ascii-long-12 270183530 4.445 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/ascii-long-12 189740618 6.335 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/no-trim-12 1000000000 0.5969 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/no-trim-12 406072189 2.941 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/fiber/mixed-whitespace-12 289382116 4.057 ns/op 0 B/op 0 allocs/op +Benchmark_TrimSpaceBytes/default/mixed-whitespace-12 218559462 5.493 ns/op 0 B/op 0 allocs/op # Convert -Benchmark_ConvertToBytes/fiber-12 320332576 3.787 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/int-12 499429904 2.382 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/int8-12 614406423 1.965 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/int16-12 486644316 2.463 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/int32-12 495227163 2.422 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/int64-12 502362236 2.429 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/uint-12 561693333 2.101 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/uint8-12 611239028 1.965 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/uint16-12 573383422 2.127 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/uint32-12 575723191 2.093 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/uint64-12 575901750 2.089 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/string-12 613909396 1.959 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/[]uint8-12 96832432 12.11 ns/op 16 B/op 1 allocs/op -Benchmark_ToString/bool-12 608058547 1.990 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/float32-12 23195016 47.11 ns/op 4 B/op 1 allocs/op -Benchmark_ToString/float64-12 17204126 70.24 ns/op 4 B/op 1 allocs/op -Benchmark_ToString/time.Time-12 13103935 91.85 ns/op 24 B/op 1 allocs/op -Benchmark_ToString/time.Time#01-12 13198113 91.22 ns/op 24 B/op 1 allocs/op -Benchmark_ToString/[]string-12 65187865 18.35 ns/op 16 B/op 1 allocs/op -Benchmark_ToString/[]int-12 54417859 21.53 ns/op 8 B/op 1 allocs/op -Benchmark_ToString/[2]int-12 32691942 36.57 ns/op 16 B/op 1 allocs/op -Benchmark_ToString/[][]int-12 9382754 128.8 ns/op 112 B/op 6 allocs/op -Benchmark_ToString/[]interface_{}-12 10584483 114.5 ns/op 72 B/op 3 allocs/op -Benchmark_ToString/utils.MyStringer-12 365979882 3.277 ns/op 0 B/op 0 allocs/op -Benchmark_ToString/utils.CustomType-12 11649330 102.5 ns/op 16 B/op 1 allocs/op -Benchmark_ToString_concurrency/int-12 1000000000 0.2619 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/int8-12 1000000000 0.2202 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/int16-12 1000000000 0.2708 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/int32-12 1000000000 0.2658 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/int64-12 1000000000 0.2658 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/uint-12 1000000000 0.2281 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/uint8-12 1000000000 0.2223 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/uint16-12 1000000000 0.2396 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/uint32-12 1000000000 0.2273 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/uint64-12 1000000000 0.2271 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/string-12 1000000000 0.2117 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/[]uint8-12 213842515 5.718 ns/op 16 B/op 1 allocs/op -Benchmark_ToString_concurrency/bool-12 1000000000 0.2118 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/float32-12 201081819 6.011 ns/op 4 B/op 1 allocs/op -Benchmark_ToString_concurrency/float64-12 142000966 8.799 ns/op 4 B/op 1 allocs/op -Benchmark_ToString_concurrency/time.Time-12 71451783 18.04 ns/op 24 B/op 1 allocs/op -Benchmark_ToString_concurrency/time.Time#01-12 69313578 17.74 ns/op 24 B/op 1 allocs/op -Benchmark_ToString_concurrency/[]string-12 187564670 6.455 ns/op 16 B/op 1 allocs/op -Benchmark_ToString_concurrency/[]int-12 262707805 4.498 ns/op 8 B/op 1 allocs/op -Benchmark_ToString_concurrency/[2]int-12 129274200 8.777 ns/op 16 B/op 1 allocs/op -Benchmark_ToString_concurrency/[][]int-12 22638411 52.65 ns/op 112 B/op 6 allocs/op -Benchmark_ToString_concurrency/[]interface_{}-12 34120837 35.36 ns/op 72 B/op 3 allocs/op -Benchmark_ToString_concurrency/utils.MyStringer-12 1000000000 0.4259 ns/op 0 B/op 0 allocs/op -Benchmark_ToString_concurrency/utils.CustomType-12 54806094 25.95 ns/op 16 B/op 1 allocs/op -Benchmark_UnsafeBytes/unsafe-12 1000000000 0.5658 ns/op 0 B/op 0 allocs/op -Benchmark_UnsafeBytes/default-12 88407558 13.50 ns/op 16 B/op 1 allocs/op -Benchmark_UnsafeString/unsafe-12 1000000000 0.3545 ns/op 0 B/op 0 allocs/op -Benchmark_UnsafeString/default-12 100000000 12.09 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/0-12 395954607 3.023 ns/op 0 B/op 0 allocs/op -Benchmark_ByteSize/1-12 65295756 18.15 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/500-12 58264801 20.92 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1024-12 60886531 19.80 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1126-12 53409986 22.69 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1048576-12 60969927 19.41 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1153024-12 53647869 22.12 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1073741824-12 63792180 19.05 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1180696576-12 54560540 22.02 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1099511627776-12 64080169 18.85 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1209033293824-12 52957434 22.01 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1125899906842624-12 65629659 18.33 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1238050092875776-12 56535770 21.73 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1152921504606846976-12 64569356 18.56 ns/op 16 B/op 1 allocs/op -Benchmark_ByteSize/1267763295104794624-12 56481996 21.10 ns/op 16 B/op 1 allocs/op +Benchmark_ConvertToBytes/fiber-12 320332576 3.787 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/int-12 499429904 2.382 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/int8-12 614406423 1.965 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/int16-12 486644316 2.463 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/int32-12 495227163 2.422 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/int64-12 502362236 2.429 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/uint-12 561693333 2.101 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/uint8-12 611239028 1.965 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/uint16-12 573383422 2.127 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/uint32-12 575723191 2.093 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/uint64-12 575901750 2.089 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/string-12 613909396 1.959 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/[]uint8-12 96832432 12.11 ns/op 16 B/op 1 allocs/op +Benchmark_ToString/bool-12 608058547 1.990 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/float32-12 23195016 47.11 ns/op 4 B/op 1 allocs/op +Benchmark_ToString/float64-12 17204126 70.24 ns/op 4 B/op 1 allocs/op +Benchmark_ToString/time.Time-12 13103935 91.85 ns/op 24 B/op 1 allocs/op +Benchmark_ToString/time.Time#01-12 13198113 91.22 ns/op 24 B/op 1 allocs/op +Benchmark_ToString/[]string-12 65187865 18.35 ns/op 16 B/op 1 allocs/op +Benchmark_ToString/[]int-12 54417859 21.53 ns/op 8 B/op 1 allocs/op +Benchmark_ToString/[2]int-12 32691942 36.57 ns/op 16 B/op 1 allocs/op +Benchmark_ToString/[][]int-12 9382754 128.8 ns/op 112 B/op 6 allocs/op +Benchmark_ToString/[]interface_{}-12 10584483 114.5 ns/op 72 B/op 3 allocs/op +Benchmark_ToString/utils.MyStringer-12 365979882 3.277 ns/op 0 B/op 0 allocs/op +Benchmark_ToString/utils.CustomType-12 11649330 102.5 ns/op 16 B/op 1 allocs/op +Benchmark_ToString_concurrency/int-12 1000000000 0.2619 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/int8-12 1000000000 0.2202 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/int16-12 1000000000 0.2708 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/int32-12 1000000000 0.2658 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/int64-12 1000000000 0.2658 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/uint-12 1000000000 0.2281 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/uint8-12 1000000000 0.2223 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/uint16-12 1000000000 0.2396 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/uint32-12 1000000000 0.2273 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/uint64-12 1000000000 0.2271 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/string-12 1000000000 0.2117 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/[]uint8-12 213842515 5.718 ns/op 16 B/op 1 allocs/op +Benchmark_ToString_concurrency/bool-12 1000000000 0.2118 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/float32-12 201081819 6.011 ns/op 4 B/op 1 allocs/op +Benchmark_ToString_concurrency/float64-12 142000966 8.799 ns/op 4 B/op 1 allocs/op +Benchmark_ToString_concurrency/time.Time-12 71451783 18.04 ns/op 24 B/op 1 allocs/op +Benchmark_ToString_concurrency/time.Time#01-12 69313578 17.74 ns/op 24 B/op 1 allocs/op +Benchmark_ToString_concurrency/[]string-12 187564670 6.455 ns/op 16 B/op 1 allocs/op +Benchmark_ToString_concurrency/[]int-12 262707805 4.498 ns/op 8 B/op 1 allocs/op +Benchmark_ToString_concurrency/[2]int-12 129274200 8.777 ns/op 16 B/op 1 allocs/op +Benchmark_ToString_concurrency/[][]int-12 22638411 52.65 ns/op 112 B/op 6 allocs/op +Benchmark_ToString_concurrency/[]interface_{}-12 34120837 35.36 ns/op 72 B/op 3 allocs/op +Benchmark_ToString_concurrency/utils.MyStringer-12 1000000000 0.4259 ns/op 0 B/op 0 allocs/op +Benchmark_ToString_concurrency/utils.CustomType-12 54806094 25.95 ns/op 16 B/op 1 allocs/op +Benchmark_UnsafeBytes/unsafe-12 1000000000 0.5658 ns/op 0 B/op 0 allocs/op +Benchmark_UnsafeBytes/default-12 88407558 13.50 ns/op 16 B/op 1 allocs/op +Benchmark_UnsafeString/unsafe-12 1000000000 0.3545 ns/op 0 B/op 0 allocs/op +Benchmark_UnsafeString/default-12 100000000 12.09 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/0-12 395954607 3.023 ns/op 0 B/op 0 allocs/op +Benchmark_ByteSize/1-12 65295756 18.15 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/500-12 58264801 20.92 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1024-12 60886531 19.80 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1126-12 53409986 22.69 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1048576-12 60969927 19.41 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1153024-12 53647869 22.12 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1073741824-12 63792180 19.05 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1180696576-12 54560540 22.02 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1099511627776-12 64080169 18.85 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1209033293824-12 52957434 22.01 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1125899906842624-12 65629659 18.33 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1238050092875776-12 56535770 21.73 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1152921504606846976-12 64569356 18.56 ns/op 16 B/op 1 allocs/op +Benchmark_ByteSize/1267763295104794624-12 56481996 21.10 ns/op 16 B/op 1 allocs/op # Format and Append -Benchmark_FormatUint/small/fiber-12 607527520 1.966 ns/op 0 B/op 0 allocs/op -Benchmark_FormatUint/small/strconv-12 607521366 1.973 ns/op 0 B/op 0 allocs/op -Benchmark_FormatUint/medium/fiber-12 64427509 19.04 ns/op 16 B/op 1 allocs/op -Benchmark_FormatUint/medium/strconv-12 59566404 20.42 ns/op 16 B/op 1 allocs/op -Benchmark_FormatUint/large/fiber-12 45395149 26.16 ns/op 24 B/op 1 allocs/op -Benchmark_FormatUint/large/strconv-12 45620366 26.38 ns/op 24 B/op 1 allocs/op -Benchmark_FormatInt/small_pos/fiber-12 608898928 1.963 ns/op 0 B/op 0 allocs/op -Benchmark_FormatInt/small_pos/strconv-12 598721480 1.976 ns/op 0 B/op 0 allocs/op -Benchmark_FormatInt/small_neg/fiber-12 616958124 1.946 ns/op 0 B/op 0 allocs/op -Benchmark_FormatInt/small_neg/strconv-12 87181050 13.77 ns/op 3 B/op 1 allocs/op -Benchmark_FormatInt/medium_pos/fiber-12 63105722 19.12 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt/medium_pos/strconv-12 57454753 20.70 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt/medium_neg/fiber-12 63631222 19.10 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt/medium_neg/strconv-12 61296942 20.17 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt/large_pos/fiber-12 48604558 25.08 ns/op 24 B/op 1 allocs/op -Benchmark_FormatInt/large_pos/strconv-12 45605844 26.25 ns/op 24 B/op 1 allocs/op -Benchmark_FormatInt/large_neg/fiber-12 47388217 25.09 ns/op 24 B/op 1 allocs/op -Benchmark_FormatInt/large_neg/strconv-12 45871998 26.10 ns/op 24 B/op 1 allocs/op -Benchmark_FormatUint32/fiber-12 63452196 18.63 ns/op 16 B/op 1 allocs/op -Benchmark_FormatUint32/strconv-12 59485942 20.08 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt32/fiber-12 63030724 18.98 ns/op 16 B/op 1 allocs/op -Benchmark_FormatInt32/strconv-12 61887302 19.69 ns/op 16 B/op 1 allocs/op -Benchmark_FormatUint16/fiber-12 80149611 14.48 ns/op 5 B/op 1 allocs/op -Benchmark_FormatUint16/strconv-12 77022440 15.43 ns/op 5 B/op 1 allocs/op -Benchmark_FormatInt16/fiber-12 79013646 15.23 ns/op 8 B/op 1 allocs/op -Benchmark_FormatInt16/strconv-12 79695165 15.24 ns/op 8 B/op 1 allocs/op -Benchmark_FormatUint8/fiber-12 599811685 1.947 ns/op 0 B/op 0 allocs/op -Benchmark_FormatUint8/strconv-12 84144096 14.18 ns/op 3 B/op 1 allocs/op -Benchmark_FormatInt8/fiber-12 630717244 1.985 ns/op 0 B/op 0 allocs/op -Benchmark_FormatInt8/strconv-12 83826201 14.24 ns/op 4 B/op 1 allocs/op -Benchmark_AppendUint/fiber-12 130817422 9.139 ns/op 0 B/op 0 allocs/op -Benchmark_AppendUint/strconv-12 100000000 10.08 ns/op 0 B/op 0 allocs/op -Benchmark_AppendInt/small_neg/fiber-12 369512403 3.266 ns/op 0 B/op 0 allocs/op -Benchmark_AppendInt/small_neg/strconv-12 213341739 5.627 ns/op 0 B/op 0 allocs/op -Benchmark_AppendInt/medium_neg/fiber-12 125937435 9.531 ns/op 0 B/op 0 allocs/op -Benchmark_AppendInt/medium_neg/strconv-12 122490632 9.791 ns/op 0 B/op 0 allocs/op +Benchmark_FormatUint/small/fiber-12 607527520 1.966 ns/op 0 B/op 0 allocs/op +Benchmark_FormatUint/small/strconv-12 607521366 1.973 ns/op 0 B/op 0 allocs/op +Benchmark_FormatUint/medium/fiber-12 64427509 19.04 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint/medium/strconv-12 59566404 20.42 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint/large/fiber-12 45395149 26.16 ns/op 24 B/op 1 allocs/op +Benchmark_FormatUint/large/strconv-12 45620366 26.38 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/small_pos/fiber-12 608898928 1.963 ns/op 0 B/op 0 allocs/op +Benchmark_FormatInt/small_pos/strconv-12 598721480 1.976 ns/op 0 B/op 0 allocs/op +Benchmark_FormatInt/small_neg/fiber-12 616958124 1.946 ns/op 0 B/op 0 allocs/op +Benchmark_FormatInt/small_neg/strconv-12 87181050 13.77 ns/op 3 B/op 1 allocs/op +Benchmark_FormatInt/medium_pos/fiber-12 63105722 19.12 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/medium_pos/strconv-12 57454753 20.70 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/medium_neg/fiber-12 63631222 19.10 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/medium_neg/strconv-12 61296942 20.17 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/large_pos/fiber-12 48604558 25.08 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/large_pos/strconv-12 45605844 26.25 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/large_neg/fiber-12 47388217 25.09 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/large_neg/strconv-12 45871998 26.10 ns/op 24 B/op 1 allocs/op +Benchmark_FormatUint32/fiber-12 63452196 18.63 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint32/strconv-12 59485942 20.08 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt32/fiber-12 63030724 18.98 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt32/strconv-12 61887302 19.69 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint16/fiber-12 80149611 14.48 ns/op 5 B/op 1 allocs/op +Benchmark_FormatUint16/strconv-12 77022440 15.43 ns/op 5 B/op 1 allocs/op +Benchmark_FormatInt16/fiber-12 79013646 15.23 ns/op 8 B/op 1 allocs/op +Benchmark_FormatInt16/strconv-12 79695165 15.24 ns/op 8 B/op 1 allocs/op +Benchmark_FormatUint8/fiber-12 599811685 1.947 ns/op 0 B/op 0 allocs/op +Benchmark_FormatUint8/strconv-12 84144096 14.18 ns/op 3 B/op 1 allocs/op +Benchmark_FormatInt8/fiber-12 630717244 1.985 ns/op 0 B/op 0 allocs/op +Benchmark_FormatInt8/strconv-12 83826201 14.24 ns/op 4 B/op 1 allocs/op +Benchmark_AppendUint/fiber-12 130817422 9.139 ns/op 0 B/op 0 allocs/op +Benchmark_AppendUint/strconv-12 100000000 10.08 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/small_neg/fiber-12 369512403 3.266 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/small_neg/strconv-12 213341739 5.627 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/medium_neg/fiber-12 125937435 9.531 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/medium_neg/strconv-12 122490632 9.791 ns/op 0 B/op 0 allocs/op # Token -Benchmark_GenerateSecureToken/16_bytes-12 4565527 258.6 ns/op 24 B/op 1 allocs/op -Benchmark_GenerateSecureToken/32_bytes-12 4306404 280.8 ns/op 48 B/op 1 allocs/op -Benchmark_TokenGenerators/UUIDv4-12 4019139 288.2 ns/op 64 B/op 2 allocs/op -Benchmark_TokenGenerators/SecureToken-12 4360036 276.9 ns/op 48 B/op 1 allocs/op +Benchmark_GenerateSecureToken/16_bytes-12 4565527 258.6 ns/op 24 B/op 1 allocs/op +Benchmark_GenerateSecureToken/32_bytes-12 4306404 280.8 ns/op 48 B/op 1 allocs/op +Benchmark_TokenGenerators/UUIDv4-12 4019139 288.2 ns/op 64 B/op 2 allocs/op +Benchmark_TokenGenerators/SecureToken-12 4360036 276.9 ns/op 48 B/op 1 allocs/op # HTTP -Benchmark_GetMIME/fiber-12 22321272 53.90 ns/op 0 B/op 0 allocs/op -Benchmark_GetMIME/default-12 17492530 68.46 ns/op 0 B/op 0 allocs/op -Benchmark_ParseVendorSpecificContentType/vendorContentType-12 125467813 9.619 ns/op 0 B/op 0 allocs/op -Benchmark_ParseVendorSpecificContentType/defaultContentType-12 404169172 2.974 ns/op 0 B/op 0 allocs/op -Benchmark_StatusMessage/fiber-12 1000000000 0.3349 ns/op 0 B/op 0 allocs/op -Benchmark_StatusMessage/default-12 460456902 2.610 ns/op 0 B/op 0 allocs/op +Benchmark_GetMIME/fiber-12 22321272 53.90 ns/op 0 B/op 0 allocs/op +Benchmark_GetMIME/default-12 17492530 68.46 ns/op 0 B/op 0 allocs/op +Benchmark_ParseVendorSpecificContentType/vendorContentType-12 125467813 9.619 ns/op 0 B/op 0 allocs/op +Benchmark_ParseVendorSpecificContentType/defaultContentType-12 404169172 2.974 ns/op 0 B/op 0 allocs/op +Benchmark_StatusMessage/fiber-12 1000000000 0.3349 ns/op 0 B/op 0 allocs/op +Benchmark_StatusMessage/default-12 460456902 2.610 ns/op 0 B/op 0 allocs/op # IP -Benchmark_IsIPv4/fiber-12 80408070 14.58 ns/op 0 B/op 0 allocs/op -Benchmark_IsIPv4/default-12 54025154 21.99 ns/op 0 B/op 0 allocs/op -Benchmark_IsIPv6/fiber-12 28283431 42.67 ns/op 0 B/op 0 allocs/op -Benchmark_IsIPv6/default-12 20747964 58.18 ns/op 0 B/op 0 allocs/op +Benchmark_IsIPv4/fiber-12 80408070 14.58 ns/op 0 B/op 0 allocs/op +Benchmark_IsIPv4/default-12 54025154 21.99 ns/op 0 B/op 0 allocs/op +Benchmark_IsIPv6/fiber-12 28283431 42.67 ns/op 0 B/op 0 allocs/op +Benchmark_IsIPv6/default-12 20747964 58.18 ns/op 0 B/op 0 allocs/op # Parse -Benchmark_ParseUint/fiber-12 236748204 5.049 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint/fiber_bytes-12 224650773 5.348 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint/default-12 88588122 13.75 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint_DigitRuns/6digit-12 207540178 5.769 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint_DigitRuns/8digit-12 222360716 5.403 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint_DigitRuns/12digit-12 156132950 7.699 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint_DigitRuns/19digit-12 135049720 8.880 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint_DigitRuns/1digit-12 338642533 3.553 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint_DigitRuns/4digit-12 212370570 5.672 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt/fiber-12 299791800 3.981 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt/fiber_bytes-12 288714712 4.165 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt/default-12 76370292 15.48 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt32/fiber-12 200451391 5.988 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt32/fiber_bytes-12 201629558 5.956 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt32/default-12 78384832 15.71 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt16/fiber-12 220670613 5.462 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt16/fiber_bytes-12 220175068 5.430 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt16/default-12 100000000 10.71 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt8/fiber-12 277948545 4.279 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt8/fiber_bytes-12 264784368 4.566 ns/op 0 B/op 0 allocs/op -Benchmark_ParseInt8/default-12 142184748 8.373 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint32/fiber-12 238916116 5.025 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint32/fiber_bytes-12 222286592 5.409 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint32/default-12 90395479 13.33 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint16/fiber-12 251398184 4.828 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint16/fiber_bytes-12 248772012 4.838 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint16/default-12 137015901 8.788 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint8/fiber-12 360430984 3.427 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint8/fiber_bytes-12 327526336 3.659 ns/op 0 B/op 0 allocs/op -Benchmark_ParseUint8/default-12 181904056 6.438 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat64/fiber-12 82912768 14.76 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat64/fiber_bytes-12 95692504 12.68 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat64/default-12 50109265 25.05 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat32/fiber-12 76648135 15.76 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat32/fiber_bytes-12 86422119 13.63 ns/op 0 B/op 0 allocs/op -Benchmark_ParseFloat32/default-12 47198646 25.41 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint/fiber-12 236748204 5.049 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint/fiber_bytes-12 224650773 5.348 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint/default-12 88588122 13.75 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/6digit-12 207540178 5.769 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/8digit-12 222360716 5.403 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/12digit-12 156132950 7.699 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/19digit-12 135049720 8.880 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/1digit-12 338642533 3.553 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint_DigitRuns/4digit-12 212370570 5.672 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt/fiber-12 299791800 3.981 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt/fiber_bytes-12 288714712 4.165 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt/default-12 76370292 15.48 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt32/fiber-12 200451391 5.988 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt32/fiber_bytes-12 201629558 5.956 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt32/default-12 78384832 15.71 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt16/fiber-12 220670613 5.462 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt16/fiber_bytes-12 220175068 5.430 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt16/default-12 100000000 10.71 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt8/fiber-12 277948545 4.279 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt8/fiber_bytes-12 264784368 4.566 ns/op 0 B/op 0 allocs/op +Benchmark_ParseInt8/default-12 142184748 8.373 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint32/fiber-12 238916116 5.025 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint32/fiber_bytes-12 222286592 5.409 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint32/default-12 90395479 13.33 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint16/fiber-12 251398184 4.828 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint16/fiber_bytes-12 248772012 4.838 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint16/default-12 137015901 8.788 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint8/fiber-12 360430984 3.427 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint8/fiber_bytes-12 327526336 3.659 ns/op 0 B/op 0 allocs/op +Benchmark_ParseUint8/default-12 181904056 6.438 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat64/fiber-12 82912768 14.76 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat64/fiber_bytes-12 95692504 12.68 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat64/default-12 50109265 25.05 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat32/fiber-12 76648135 15.76 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat32/fiber_bytes-12 86422119 13.63 ns/op 0 B/op 0 allocs/op +Benchmark_ParseFloat32/default-12 47198646 25.41 ns/op 0 B/op 0 allocs/op # Time -Benchmark_CalculateTimestamp/fiber-12 1000000000 0.3366 ns/op 0 B/op 0 allocs/op -Benchmark_CalculateTimestamp/default-12 36163686 32.69 ns/op 0 B/op 0 allocs/op -Benchmark_CalculateTimestamp/fiber_asserted-12 4471299 267.8 ns/op 12 B/op 2 allocs/op -Benchmark_CalculateTimestamp/default_asserted-12 3991147 298.7 ns/op 8 B/op 2 allocs/op +Benchmark_CalculateTimestamp/fiber-12 1000000000 0.3366 ns/op 0 B/op 0 allocs/op +Benchmark_CalculateTimestamp/default-12 36163686 32.69 ns/op 0 B/op 0 allocs/op +Benchmark_CalculateTimestamp/fiber_asserted-12 4471299 267.8 ns/op 12 B/op 2 allocs/op +Benchmark_CalculateTimestamp/default_asserted-12 3991147 298.7 ns/op 8 B/op 2 allocs/op # XML -Benchmark_GolangXMLEncoder-12 574852 2040 ns/op 4864 B/op 12 allocs/op -Benchmark_DefaultXMLEncoder-12 593738 2012 ns/op 4864 B/op 12 allocs/op -Benchmark_DefaultXMLDecoder-12 309031 3876 ns/op 2892 B/op 57 allocs/op +Benchmark_GolangXMLEncoder-12 574852 2040 ns/op 4864 B/op 12 allocs/op +Benchmark_DefaultXMLEncoder-12 593738 2012 ns/op 4864 B/op 12 allocs/op +Benchmark_DefaultXMLDecoder-12 309031 3876 ns/op 2892 B/op 57 allocs/op ``` See all the benchmarks under @@ -462,6 +469,290 @@ as a plain string because call sites pass constant tokens. Their on the [benchmark charts](https://gofiber.github.io/utils/benchmarks/) and join the catalog above on its next regeneration. +## HTTP dates + +`AppendHTTPDate` and `FormatHTTPDate` write a time in the RFC 9110 +preferred HTTP date format (`Mon, 02 Jan 2006 15:04:05 GMT`, +`net/http.TimeFormat`), byte-identical to `time.Format` with that layout +but without walking a layout string: the calendar fields come from one +civil-date conversion of `t.Unix()` (Hinnant's era arithmetic, instead of +the three `abs()` walks behind `Date`, `Clock`, and `Weekday`), and are +written into the fixed-width template with two-digit table lookups. +`ParseHTTPDate` is the reverse: canonical preferred-format input takes a +strict scalar fast path whose validated fields feed `time.Unix` directly +— the same `Time` value `time.Date` builds, minus its normalization pass — +and everything else — the obsolete RFC 850 and asctime forms, unusual +casing, non-GMT zone names, padding — falls back to `time.Parse` with +`net/http.ParseTime` semantics, including its errors. Both directions are +pinned to the `time` package by a day-by-day sweep over the years +0..9999. `Date`, `Last-Modified`, and `If-Modified-Since` handling sit on +every request/response, which makes these the highest-leverage helpers in +this group for Fiber. + +## URL escaping + +`AppendQueryEscape`/`AppendPathEscape` and +`AppendQueryUnescape`/`AppendPathUnescape` produce byte-identical results +(and, for the unescape pair, identical `url.EscapeError` values) to their +`net/url` counterparts, as append-style, allocation-free single passes. +The escape tables are pinned to `net/url.shouldEscape` by exhaustive +per-byte tests. Unescaping jumps between escape sites with the vectorized +scans (`IndexAny2` when `+` needs rewriting, `bytes.IndexByte` otherwise) +and copies clean spans wholesale, so route parameters and query values +without escapes — the common case — cost one scan and one copy. Decoding +never grows the input, so `dst` may be `s[:0]` on a common backing array +to unescape in place; escaping can grow the input, so there `dst` must +not alias `s`. + +## JSON string escaping + +`AppendJSONString` appends a value as a double-quoted JSON string, +byte-identical to `encoding/json.Marshal` of the same string — including +its default HTML escaping (`<`, `>`, `&`), the `\ufffd` replacement of +invalid UTF-8 bytes, and the U+2028/U+2029 escapes — without any of +`Marshal`'s reflection or allocation. Clean spans are located with a SWAR +scan (the same first-match-mask technique as `IndexNonQuotable`) and +copied wholesale. This is the building block for hand-rolled JSON hot +paths such as access-log lines and error bodies. + +## IP address parsing + +`ParseIPv4` and `ParseIPv6` parse addresses into `netip.Addr`, accepting +exactly the strings `netip.ParseAddr` accepts for the respective family +(pinned by fuzzing) while reporting failure with a `bool` instead of a +constructed error. Both take strings or byte slices, so fasthttp-style +callers skip the `string` conversion entirely; remote-address and +trusted-proxy checks parse an IP on every request in Fiber. + +## Header key canonicalization + +`CanonicalHeaderKey` Title-Cases an HTTP header key exactly like +`net/http.CanonicalHeaderKey`, including its return-unchanged guard for +keys containing non-token bytes. Already-canonical keys — the common case +on receive paths — are validated in a single table pass and returned +as-is with zero allocations for strings and byte slices alike. Keys that +do need rewriting cost one allocation; note that for the ~40 header names +in the stdlib's interning table the stdlib returns a cached string +without allocating, so this helper's edge there is time, not allocations. + +## Control-byte scanning + +`IndexControl` returns the index of the first ASCII control byte — a byte +below 0x20 or DEL (0x7F), the RFC 5234 CTL set — and `IndexControlExceptTab` +is the same scan with HTAB permitted, which is the byte set an RFC 9110 +field value may not contain. Both are SWAR first-match scans +(two words per branch, one overlapping word for the tail) over strings or +byte slices; the HTAB exemption is tested only in words that hold a +control byte, so clean input costs the same either way. They never match +bytes >= 0x80, so unlike +`strings.IndexFunc(s, unicode.IsControl)` they neither decode UTF-8 nor +flag the C1 range hidden inside it. Fiber spells this check by hand in +half a dozen places — header values before they are echoed, request IDs, +`Location` values, log fields, Basic auth credentials — and each copy is +one of these two calls. + +## Byte-separator cuts + +`CutByte` and `LastCutByte` are `strings.Cut`/`bytes.Cut` for a single +byte separator, around its first or last occurrence, generic over strings +and byte slices. They return the two parts and a found flag exactly like +the stdlib pair (including the `""`/`nil` after-part of a miss), cost one +`IndexByte`/`LastIndexByte`, and spare `[]byte` callers the `[]byte{sep}` +needle and the length dispatch inside `bytes.Index`. `CutByte` beats +`strings.Cut`; `LastCutByte` has no stdlib counterpart, so its row is +measured against a hand-written `LastIndexByte` split, which it trails by +the cost of the call — its value is the generic `[]byte` support and the +readable spelling. Header parameter splits (`;`), `key=value` pairs, and +host/port and name/extension splits are the intended call sites. + +## Host and port splitting + +`SplitHostPort` splits `host:port`, `host%zone:port`, `[host]:port`, and +`[host%zone]:port` with exactly `net.SplitHostPort`'s acceptance rules +(pinned by fuzzing against it), but reports failure with a `bool` instead +of constructing a `*net.AddrError`, and accepts byte slices. Valid input +costs the same as the stdlib — the scan is the same three `IndexByte` +calls — so the win is on the rejection path, where a malformed `Host` or +`Forwarded` value no longer costs an allocation, and on `[]byte` input, +which no longer needs a string conversion first. + +## List field iteration + +`SplitTrimSeq` returns an iterator over the elements of a list separated +by one byte, with ASCII whitespace trimmed from each element and empty +elements skipped — how HTTP list fields such as `Accept-Encoding`, +`Connection`, `Vary`, and `Cache-Control` are read (RFC 9110 Section +5.6.1: optional whitespace around the commas, empty elements ignored). +It replaces the `strings.SplitSeq` + `TrimSpace` + emptiness-check +triplet, locates each separator with a single `IndexByte`, works on +strings and byte slices alike, and yields subslices without copying. In +an ordinary caller the iterator inlines and allocates nothing, like +`strings.SplitSeq`; the benchmark ranges inside a helper function for +that reason, because calls made directly inside a `b.Loop` body are +never inlined and would show the closure allocations instead. + +## Duration formatting + +`AppendDuration` renders a `time.Duration` exactly as `d.String()` does — +"72h3m0.5s", "1.5ms", "0s" — into the caller's buffer, with the two-digit +table for the field digits; a value with no fraction, the common case, +never touches the fraction digits. `d.String()` allocates its result and +`fmt.Fprintf("%v", d)`, which Fiber's logger uses for the latency column, +costs several times more on top; an append-style form makes per-request +duration rendering (access logs, `Server-Timing`) allocation-free. + +## Decimal formatting + +`FormatUint`/`FormatInt` (and their 32- and 16-bit variants) and +`AppendUint`/`AppendInt` render integers eight digits at a time: a value +below 1e8 becomes eight zero-padded digit lanes through a fixed sequence +of multiplies, shifts, and masks (the SWAR inverse of the 8-digit parse +step in `ParseInt`), so a 64-bit value costs at most three such +conversions and two divisions, all independent of each other, instead of +one dependent divide-and-store per digit; the first significant digit is +found with a trailing-zero count. Values below 100 come from a +precomputed table, and the output is pinned to `strconv` by a dense sweep +plus every decimal and lane-group boundary. `GetMIME` in the same spirit +looks up extensions through a hash table keyed by the extension packed +into one lower-cased word with its length in the top lane, so a hit is a +multiply, a shift, and one slot comparison, with no allocation even for +upper-case input. + +These helpers were added on an amd64 machine, so like the `simd` numbers +their benchmarks are recorded separately from the arm64 catalog above and +join it on its next regeneration. The block also carries the current +numbers for the paths reworked on the same machine (integer formatting, +`GetMIME`, token-sized `EqualFold`), whose arm64 rows above predate that +work: + +Environment: +goos: linux +goarch: amd64 +pkg: github.com/gofiber/utils/v2 +cpu: Intel(R) Xeon(R) Processor @ 2.80GHz + +```text +// go test -benchmem -run=^$ -count=1 . -bench='^Benchmark_(FormatUint|FormatInt|FormatUint32|FormatInt32|FormatUint16|FormatInt16|AppendUint|AppendInt|EqualFold_Short|GetMIME|AppendHTTPDate|ParseHTTPDate|AppendDuration|AppendQueryEscape|AppendQueryUnescape|AppendPathUnescape|AppendJSONString|ParseIPv4|ParseIPv6|CanonicalHeaderKey|IndexControl|CutByte|LastCutByte|SplitHostPort|SplitTrimSeq)$' +Benchmark_EqualFold_Short/3B/fiber-4 229602248 5.312 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/3B/default-4 204528979 5.852 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/4B/fiber-4 229813917 5.255 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/4B/default-4 156456847 7.464 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/5B/fiber-4 229097964 5.234 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/5B/default-4 197214793 6.189 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/7B/fiber-4 232463892 5.179 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/7B/default-4 160397131 7.450 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/8B/fiber-4 216077086 5.531 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/8B/default-4 159104245 7.543 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/10B/fiber-4 144306822 8.317 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/10B/default-4 120878482 9.925 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/16B/fiber-4 143038372 8.357 ns/op 0 B/op 0 allocs/op +Benchmark_EqualFold_Short/16B/default-4 85405070 14.49 ns/op 0 B/op 0 allocs/op +Benchmark_IndexControl/clean-16B/fiber-4 169144147 7.146 ns/op 0 B/op 0 allocs/op +Benchmark_IndexControl/clean-16B/fiber-except-tab-4 167529128 7.135 ns/op 0 B/op 0 allocs/op +Benchmark_IndexControl/clean-16B/default-4 32870788 36.35 ns/op 0 B/op 0 allocs/op +Benchmark_IndexControl/clean-64B/fiber-4 75379568 16.27 ns/op 0 B/op 0 allocs/op +Benchmark_IndexControl/clean-64B/fiber-except-tab-4 73955293 16.14 ns/op 0 B/op 0 allocs/op +Benchmark_IndexControl/clean-64B/default-4 8875356 135.6 ns/op 0 B/op 0 allocs/op +Benchmark_IndexControl/ctl-at-end-64B/fiber-4 72450939 16.83 ns/op 0 B/op 0 allocs/op +Benchmark_IndexControl/ctl-at-end-64B/fiber-except-tab-4 71671362 16.68 ns/op 0 B/op 0 allocs/op +Benchmark_IndexControl/ctl-at-end-64B/default-4 8478050 141.1 ns/op 0 B/op 0 allocs/op +Benchmark_CutByte/fiber-4 180741241 6.688 ns/op 0 B/op 0 allocs/op +Benchmark_CutByte/default-4 100000000 10.28 ns/op 0 B/op 0 allocs/op +Benchmark_CutByte/fiber-bytes-4 168499478 7.147 ns/op 0 B/op 0 allocs/op +Benchmark_CutByte/default-bytes-4 141645026 8.407 ns/op 0 B/op 0 allocs/op +Benchmark_LastCutByte/fiber-4 190695121 6.336 ns/op 0 B/op 0 allocs/op +Benchmark_LastCutByte/default-4 201893814 5.937 ns/op 0 B/op 0 allocs/op +Benchmark_AppendDuration/micros/fiber-4 94853876 12.96 ns/op 0 B/op 0 allocs/op +Benchmark_AppendDuration/micros/default-4 37404410 30.76 ns/op 8 B/op 1 allocs/op +Benchmark_AppendDuration/micros/fmt-4 9448436 127.8 ns/op 16 B/op 2 allocs/op +Benchmark_AppendDuration/millis-frac/fiber-4 57206034 20.25 ns/op 0 B/op 0 allocs/op +Benchmark_AppendDuration/millis-frac/default-4 28241080 39.08 ns/op 16 B/op 1 allocs/op +Benchmark_AppendDuration/millis-frac/fmt-4 8029897 144.3 ns/op 24 B/op 2 allocs/op +Benchmark_AppendDuration/hours/fiber-4 77311298 15.06 ns/op 0 B/op 0 allocs/op +Benchmark_AppendDuration/hours/default-4 26855806 42.60 ns/op 8 B/op 1 allocs/op +Benchmark_AppendDuration/hours/fmt-4 8546384 146.6 ns/op 16 B/op 2 allocs/op +Benchmark_FormatUint/small/fiber-4 629069014 1.888 ns/op 0 B/op 0 allocs/op +Benchmark_FormatUint/small/strconv-4 505295925 2.371 ns/op 0 B/op 0 allocs/op +Benchmark_FormatUint/medium/fiber-4 40310542 28.33 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint/medium/strconv-4 36065356 33.07 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint/large/fiber-4 36428881 33.66 ns/op 24 B/op 1 allocs/op +Benchmark_FormatUint/large/strconv-4 24582408 49.04 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/small_pos/fiber-4 568438807 2.074 ns/op 0 B/op 0 allocs/op +Benchmark_FormatInt/small_pos/strconv-4 509641584 2.378 ns/op 0 B/op 0 allocs/op +Benchmark_FormatInt/small_neg/fiber-4 552536096 2.169 ns/op 0 B/op 0 allocs/op +Benchmark_FormatInt/small_neg/strconv-4 67741922 18.14 ns/op 3 B/op 1 allocs/op +Benchmark_FormatInt/medium_pos/fiber-4 36409581 28.36 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/medium_pos/strconv-4 34719836 34.57 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/medium_neg/fiber-4 43244299 27.74 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/medium_neg/strconv-4 36308307 33.28 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt/large_pos/fiber-4 34108224 34.78 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/large_pos/strconv-4 23271465 49.00 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/large_neg/fiber-4 35237299 34.85 ns/op 24 B/op 1 allocs/op +Benchmark_FormatInt/large_neg/strconv-4 24433351 47.63 ns/op 24 B/op 1 allocs/op +Benchmark_FormatUint32/fiber-4 46063810 26.37 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint32/strconv-4 34846262 33.88 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt32/fiber-4 42975921 27.59 ns/op 16 B/op 1 allocs/op +Benchmark_FormatInt32/strconv-4 36954268 33.17 ns/op 16 B/op 1 allocs/op +Benchmark_FormatUint16/fiber-4 60632233 19.36 ns/op 5 B/op 1 allocs/op +Benchmark_FormatUint16/strconv-4 51189382 22.75 ns/op 5 B/op 1 allocs/op +Benchmark_FormatInt16/fiber-4 55760065 20.90 ns/op 8 B/op 1 allocs/op +Benchmark_FormatInt16/strconv-4 48868172 24.20 ns/op 8 B/op 1 allocs/op +Benchmark_AppendUint/fiber-4 91578640 12.35 ns/op 0 B/op 0 allocs/op +Benchmark_AppendUint/strconv-4 72172658 17.55 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/small_neg/fiber-4 314797556 3.782 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/small_neg/strconv-4 100000000 10.91 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/medium_neg/fiber-4 91859277 13.20 ns/op 0 B/op 0 allocs/op +Benchmark_AppendInt/medium_neg/strconv-4 70492820 17.12 ns/op 0 B/op 0 allocs/op +Benchmark_CanonicalHeaderKey/canonical/fiber-4 66962880 17.98 ns/op 0 B/op 0 allocs/op +Benchmark_CanonicalHeaderKey/canonical/default-4 46076755 26.65 ns/op 0 B/op 0 allocs/op +Benchmark_CanonicalHeaderKey/common-lower/fiber-4 28066642 44.43 ns/op 16 B/op 1 allocs/op +Benchmark_CanonicalHeaderKey/common-lower/default-4 23367423 50.83 ns/op 0 B/op 0 allocs/op +Benchmark_CanonicalHeaderKey/custom-lower/fiber-4 20437851 58.07 ns/op 24 B/op 1 allocs/op +Benchmark_CanonicalHeaderKey/custom-lower/default-4 13395525 87.34 ns/op 24 B/op 1 allocs/op +Benchmark_SplitHostPort/host-port/fiber-4 66885448 17.17 ns/op 0 B/op 0 allocs/op +Benchmark_SplitHostPort/host-port/default-4 73398602 16.60 ns/op 0 B/op 0 allocs/op +Benchmark_SplitHostPort/ipv6-port/fiber-4 69142788 17.70 ns/op 0 B/op 0 allocs/op +Benchmark_SplitHostPort/ipv6-port/default-4 68252304 17.28 ns/op 0 B/op 0 allocs/op +Benchmark_SplitHostPort/missing-port/fiber-4 167778152 7.224 ns/op 0 B/op 0 allocs/op +Benchmark_SplitHostPort/missing-port/default-4 30424182 38.16 ns/op 32 B/op 1 allocs/op +Benchmark_GetMIME/fiber-4 39471765 29.38 ns/op 0 B/op 0 allocs/op +Benchmark_GetMIME/default-4 10284040 112.3 ns/op 0 B/op 0 allocs/op +Benchmark_AppendHTTPDate/fiber-4 47681026 25.21 ns/op 0 B/op 0 allocs/op +Benchmark_AppendHTTPDate/default-4 8757169 134.9 ns/op 0 B/op 0 allocs/op +Benchmark_ParseHTTPDate/fiber-4 58871844 18.57 ns/op 0 B/op 0 allocs/op +Benchmark_ParseHTTPDate/default-4 6421057 187.1 ns/op 0 B/op 0 allocs/op +Benchmark_ParseIPv4/fiber-4 66056898 18.34 ns/op 0 B/op 0 allocs/op +Benchmark_ParseIPv4/default-4 44932904 26.84 ns/op 0 B/op 0 allocs/op +Benchmark_ParseIPv6/compressed/fiber-4 25820896 46.48 ns/op 0 B/op 0 allocs/op +Benchmark_ParseIPv6/compressed/default-4 17371059 65.48 ns/op 0 B/op 0 allocs/op +Benchmark_ParseIPv6/full/fiber-4 20636487 60.00 ns/op 0 B/op 0 allocs/op +Benchmark_ParseIPv6/full/default-4 12097987 84.13 ns/op 0 B/op 0 allocs/op +Benchmark_AppendJSONString/clean-16B/fiber-4 57606924 21.13 ns/op 0 B/op 0 allocs/op +Benchmark_AppendJSONString/clean-16B/default-4 8575510 143.9 ns/op 40 B/op 2 allocs/op +Benchmark_AppendJSONString/clean-64B/fiber-4 20014062 60.74 ns/op 0 B/op 0 allocs/op +Benchmark_AppendJSONString/clean-64B/default-4 5525064 222.1 ns/op 96 B/op 2 allocs/op +Benchmark_AppendJSONString/escaped-64B/fiber-4 7843610 149.5 ns/op 0 B/op 0 allocs/op +Benchmark_AppendJSONString/escaped-64B/default-4 4009515 291.9 ns/op 96 B/op 2 allocs/op +Benchmark_AppendJSONString/unicode-64B/fiber-4 4916204 239.6 ns/op 0 B/op 0 allocs/op +Benchmark_AppendJSONString/unicode-64B/default-4 3485493 347.0 ns/op 112 B/op 2 allocs/op +Benchmark_SplitTrimSeq/accept-encoding/fiber-4 54431074 21.50 ns/op 0 B/op 0 allocs/op +Benchmark_SplitTrimSeq/accept-encoding/default-4 50593407 24.16 ns/op 0 B/op 0 allocs/op +Benchmark_SplitTrimSeq/accept/fiber-4 19936736 59.24 ns/op 0 B/op 0 allocs/op +Benchmark_SplitTrimSeq/accept/default-4 18168722 65.87 ns/op 0 B/op 0 allocs/op +Benchmark_AppendQueryEscape/clean-64B/fiber-4 25016198 49.70 ns/op 0 B/op 0 allocs/op +Benchmark_AppendQueryEscape/clean-64B/default-4 6857455 176.6 ns/op 0 B/op 0 allocs/op +Benchmark_AppendQueryEscape/mixed-64B/fiber-4 5858684 213.5 ns/op 0 B/op 0 allocs/op +Benchmark_AppendQueryEscape/mixed-64B/default-4 1989934 600.0 ns/op 192 B/op 2 allocs/op +Benchmark_AppendQueryUnescape/plain-64B/fiber-4 76538192 15.30 ns/op 0 B/op 0 allocs/op +Benchmark_AppendQueryUnescape/plain-64B/default-4 10383134 116.5 ns/op 0 B/op 0 allocs/op +Benchmark_AppendQueryUnescape/escaped-64B/fiber-4 4906606 218.5 ns/op 0 B/op 0 allocs/op +Benchmark_AppendQueryUnescape/escaped-64B/default-4 4306238 274.6 ns/op 48 B/op 1 allocs/op +Benchmark_AppendPathUnescape/plain-25B/fiber-4 100000000 12.00 ns/op 0 B/op 0 allocs/op +Benchmark_AppendPathUnescape/plain-25B/default-4 24661267 45.81 ns/op 0 B/op 0 allocs/op +Benchmark_AppendPathUnescape/escaped-31B/fiber-4 20543667 58.60 ns/op 0 B/op 0 allocs/op +Benchmark_AppendPathUnescape/escaped-31B/default-4 8119328 147.5 ns/op 24 B/op 1 allocs/op +``` + ## SWAR primitives The [`swar`](swar/) package exports the SWAR (SIMD within a register) @@ -492,17 +783,375 @@ function for. The package's remaining benchmark, `Benchmark_Load8_Fusion`, is an advisory codegen guard rather than an API performance promise, so it is deliberately not part of the catalog above. +## SIMD-accelerated search (package simd) + +The [`simd`](simd/) package is the vector-width counterpart to `swar`: byte +searching and validation whose scan kernels dispatch to AVX2 assembly (four +32-byte vectors per iteration) on amd64 CPUs for inputs of `simd.MinLen` +(32) bytes or more, and fall back to portable loops built on the `swar` +primitives everywhere else, so it builds and behaves identically on every +platform. +`simd.Accelerated()` reports which mode is active. CPU capability detection +uses [`golang.org/x/sys/cpu`](https://pkg.go.dev/golang.org/x/sys/cpu), +which also verifies OS support for saving the vector register state. + +The AVX2-backed kernels are the multi-needle scans (`Memchr2`, `Memchr3`), +the paired-byte scan (`MemchrPair`), the class scans +(`MemchrDigit`/`MemchrDigitAt`, `MemchrWord`/`MemchrNotWord`), the ASCII +scans (`IsASCII`, `FirstNonASCII`, `CountNonASCII`), and the substring +search (`Memmem`), which +prefilters on the needle's rarest bytes (`SelectRareBytes`, `ByteRank`) +before verifying candidates — 2-6 byte needles containing two distinct +values are scanned for their two rarest bytes at the exact relative +distance, longer or single-valued needles for the single rarest byte. +Each kernel classifies four 32-byte vectors per iteration. Where the +result is a position or a yes/no, the four masks are combined, so a +128-byte block costs a single `VPMOVMSKB` and a single branch, and the +scans that report a position re-extract the four masks in address order on +the (rare) hit path. `CountNonASCII` is the exception — a count cannot be +recovered from a combined mask, so its block loop accumulates per-lane +counts in vector byte lanes (a signed compare against zero and a byte +subtract per vector) and reduces them once at the end, while the +remaining whole vectors are extracted and population-counted; it is the +one kernel gated on `POPCNT` in addition to AVX2. +One tier is documented explicitly as unaccelerated: +`MemchrInTable`/`MemchrNotInTable` are plain +scalar loops, since an arbitrary 256-entry membership test has no cheap +vector form. There is deliberately no single-needle `Memchr`: +`bytes.IndexByte` is already vector-accelerated by the Go runtime. `Memmem` +delegates to `bytes.Index` for haystacks of up to 64 bytes, where the +stdlib's brute-force vector kernel is level with the paired prefilter +(`Benchmark_Memmem_Prefilter` forces the prefilter helpers at every size +to keep that measurable); from 65 bytes `bytes.Index` switches to a loop +anchored on the needle's first byte, and the paired scan takes over. +Needles that take the single rare-byte scan keep a 128-byte routing point, +since that scan is less selective. Both prefilters bail to `bytes.Index` +after a bounded number of failed candidate verifications, so even +adversarial inputs — a rare byte everywhere plus a long almost-matching +needle — stay within a constant of the stdlib's O(n+m) (see +`Benchmark_Memmem_Adversarial`). The +package operates on `[]byte` only; the generic top-level helpers `IsASCII`, +`IndexAny2`, and `IndexAny3` dispatch into it automatically for inputs of +`simd.MinLen`+ bytes on amd64, which is where the AVX2 kernels overtake the +SWAR word loops (-35% to -88% ns/op at 32-512B in `benchstat -count=10` +runs; shorter inputs keep the existing SWAR paths). + +The kernels are adapted from the [coregex](https://github.com/coregx/coregex) +project's `simd` package (MIT License, Copyright (c) 2025 Andrey Kolkov and +contributors; see [`simd/LICENSE`](simd/LICENSE)), with the legacy-SSE +register moves in the kernels replaced by VEX-encoded ones to avoid AVX-SSE +transition stalls, the scalar tail loops replaced by overlapping vector +rescans at the buffer end (a 63-byte scan previously cost ~3.7x a 64-byte +one), the 32-byte main loops replaced by 4x unrolled 128-byte blocks whose +bound is tested once at the bottom against a precomputed limit pointer, the +`\w` classifier rewritten from three `VPMINUB`/`VPMAXUB` clamp-and-compare +range tests into two `VPSHUFB` nibble-table lookups (with the block test +reduced to one compare over the four raw class values), the digit range +test reduced from two signed compares and a `VPANDN` to one biased +`VPADDB` and one compare, `FirstNonASCII` and `CountNonASCII` given +kernels of their own (they were SWAR-only, and the count kernel's block +loop accumulates in vector byte lanes rather than extracting and +population-counting every vector's mask), the 128-byte block loops +placed at fixed offsets inside a 32-byte code window so their throughput +no longer depends on where the linker places each kernel, and the +fallbacks reworked around the stdlib and the `swar` package as described +above. + +Against the pre-unrolling kernels, `benchstat -count=10` on the machine +below reports -26.6%/-49.7% ns/op for `Memchr2` at 512B/4096B, +-17.6%/-34.3% for `Memchr3`, -13.4%/-24.6% for `MemchrPair`, +-39.2%/-50.5% for `MemchrDigit`, -53.5%/-63.7% for `MemchrNotWord`, +-42.2%/-65.7% for `IsASCII`, and -13.7%/-27.1% for `Memmem`, which rides +the paired scan. Those percentages come from `benchstat` over ten runs of +each side; the single-run table below is a catalog, not a base-vs-head +comparison, so subtracting its rows from an older copy of it will not +reproduce them. + +Two bands see no benefit and are worth stating plainly. Inputs below +`simd.MinLen` never reach the kernels at all. Inputs of 32-127 bytes do +reach them but skip the 128-byte block loop, so they pay its setup with +nothing to amortize it against: across that band `benchstat` reports the +class scans clearly ahead (`MemchrNotWord` -8.6% at 32B, -18.4% at 64B; +`IsASCII` -5.0%/-4.3%), most rows statistically unchanged, and two small +regressions — `MemchrDigit` +5.6% at 32B and `Memchr3` +3.8% at 64B. Read +those small-input figures against the run's own noise floor: the `default` +legs call unchanged stdlib code, so their movement bounds what a delta of +that size means. They held within 1% in the run quoted here, but a later +run on the same machine drifted up to 17% on those same rows, so anything +under ~10% at 32-64B should be taken as "no measured change" unless its +control legs are quiet. + +On the portable side, pinning each unrolled group of words with a reslice +before loading at constant offsets inside it removes the per-load bounds +check that `swar.Load8`'s own reslice otherwise repeats. Measured with +`benchstat -count=10` against the same fallbacks, at 32B/512B/4KiB: +`IsASCII` -28%/-60%/-63%, `CountNonASCII` -24%/-44%/-44%, +`FirstNonASCII` -23%/-37%/-43%, `Memchr2` -19%/-23%/-25%, +`MemchrDigit` -7%/-12%/-17%, `Memchr3` -8%/-13%/-18%, +`MemchrWord` -11%/-8%/-11%, `MemchrNotWord` -5%/-7%/-6%. The tier a group +adds costs one compare on inputs too short to use it, which shows up as ++3% to +10% on some of the 8B fallback rows — a few tenths of a +nanosecond, and only below the length where the group pays for itself. +`utils.IsASCII` carries the same rework, so the two copies of that scan +stay in step. + +Making the counting kernel finish its own sub-vector remainder (rather +than splitting the input in Go and calling the SWAR loop for the tail) +also removed a second non-inlinable call from every whole-vector input: +`CountNonASCII` at 32B went from 11.3ns — behind its own fallback — to +6.8ns, level with it, and it leads from 64B up. + +A later audit pass reworked the kernels and fallbacks once more; +`benchstat -count=10` on the machine below, base vs. head, reports: + +- `MemchrDigit` -20% at 512B and -27% at 4KiB from the one-add, + one-compare range test. +- `MemchrWord` -13%/-11% and `MemchrNotWord` -4%/-10% at 512B/4KiB from + comparing the reduced block once instead of every vector, and their + SWAR fallbacks -36%/-41% at 32B, -40%/-43% at 64B and -43%/-45% at + 512B: 15 ALU operations per word instead of 26, from case-folding the + two letter ranges into one test, a one-add underscore test, and a + single shared ASCII gate. +- `CountNonASCII` -15% at 512B and -41% at 4KiB, with 32B and 64B + unchanged: the block loop counts in vector byte lanes (a signed compare + against zero and a byte subtract per vector, flushed through `VPSADBW` + every 127 blocks) instead of four port-0 `VPMOVMSKB` extractions per + block. The remaining whole vectors are still extracted and + population-counted, because the vector reduction is a fixed ten-cycle + chain that one to three vectors cannot amortize — a first version that + used the accumulators for those too was 20% slower at 32-64B. +- `MemchrPair`'s SWAR fallback -33% at 32B, -41% at 64B, -51% at 512B and + -52% at 4KiB, and `MemchrPair` itself -30% at 32B, where the dispatch + routes to that fallback: it now scans two words per branch through + pinned three-index windows (no per-load capacity check or pointer + clamp) and finishes with one overlapping word instead of a scalar + tail. Before, at 32B, it ran no faster than a plain scalar loop. +- `Memmem` -62% at 96B: needles that take the paired prefilter are routed + through it from 65-byte haystacks, where `bytes.Index` leaves its + brute-force vector kernel for a first-byte-anchored loop; 64B and + 128B+ are unchanged. + +The same pinned-window rework applied to the case-conversion loops in +`internal/caseconv`, which the `strings` and `bytes` packages' `ToLower` +and `ToUpper` build on, gives on the same machine -27% to -37% ns/op for +the in-place `UnsafeToLower`/`UnsafeToUpper` at 39-64B, -14% to -19% for +the scan-only path that finds nothing to convert, and -5% to -17% for the +allocating conversions, where the allocation dominates. The arm64 catalog +rows above were not regenerated for that change. + +Comparing the base and head test binaries also showed the untouched +`MemchrPair` kernel ~10% slower at 4KiB, purely because the linker had +moved its entry by 32 bytes: on Skylake-derived cores the JCC erratum +mitigation keeps a macro-fused compare-and-branch that crosses or ends on +a 32-byte boundary out of the decoded-uop cache, so the block loop ran +from the legacy decoder. Every block loop is now placed by a `BLOCKALIGN` +macro at a window offset where all of its fused pairs fit (a few +once-per-call NOPs, visible as +5% on `Memchr2` at 512B and nothing at +4KiB), and an amd64 test reads each kernel's code and fails if a later +edit lets a pair straddle a boundary again. + +Because the AVX2 kernels only engage on amd64, their benchmark numbers are +recorded separately from the arm64 catalog above: + +Environment: +goos: linux +goarch: amd64 +pkg: github.com/gofiber/utils/v2/simd +cpu: Intel(R) Xeon(R) Processor @ 2.80GHz (AVX2) + +```text +// go test ./simd/ -benchmem -run=^$ -bench=Benchmark_ -count=1 +Benchmark_Memchr2/8B/simd-4 190047766 6.344 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/8B/scalar-4 216903783 5.516 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/8B/default-4 37047232 34.54 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/32B/simd-4 230568829 5.549 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/32B/scalar-4 137118788 9.346 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/32B/default-4 37159426 34.23 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/64B/simd-4 202942682 5.969 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/64B/scalar-4 87153786 13.77 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/64B/default-4 23353054 54.76 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/512B/simd-4 85724174 13.67 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/512B/scalar-4 13201143 89.39 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/512B/default-4 3530156 348.3 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/4096B/simd-4 18950438 63.19 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/4096B/scalar-4 1703708 698.6 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr2/4096B/default-4 451885 2773 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/8B/simd-4 161230975 7.399 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/8B/scalar-4 195079063 6.568 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/8B/default-4 39049345 31.96 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/32B/simd-4 209563508 5.767 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/32B/scalar-4 100000000 11.80 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/32B/default-4 36763602 33.60 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/64B/simd-4 186953884 6.553 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/64B/scalar-4 59549791 20.13 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/64B/default-4 22672693 54.92 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/512B/simd-4 75757986 16.84 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/512B/scalar-4 9159388 128.2 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/512B/default-4 3351171 348.3 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/4096B/simd-4 12609099 93.35 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/4096B/scalar-4 1000000 1064 ns/op 0 B/op 0 allocs/op +Benchmark_Memchr3/4096B/default-4 470744 2615 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/8B/simd-4 100000000 10.56 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/8B/swar-4 152141828 7.801 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/8B/scalar-4 201085015 6.059 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/32B/simd-4 88059698 13.00 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/32B/swar-4 100000000 10.63 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/32B/scalar-4 68842016 16.81 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/64B/simd-4 156794418 7.975 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/64B/swar-4 75119947 16.98 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/64B/scalar-4 33130292 32.27 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/512B/simd-4 63940441 18.19 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/512B/swar-4 11641740 103.3 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/512B/scalar-4 4559438 269.0 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/4096B/simd-4 17142175 70.75 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/4096B/swar-4 1548690 776.4 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrPair/4096B/scalar-4 563876 2072 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrDigit/8B/simd-4 195955126 5.458 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrDigit/8B/scalar-4 267192732 4.378 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrDigit/32B/simd-4 248331692 4.985 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrDigit/32B/scalar-4 134102625 8.622 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrDigit/64B/simd-4 212405679 5.785 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrDigit/64B/scalar-4 72030652 15.22 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrDigit/512B/simd-4 124923620 9.429 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrDigit/512B/scalar-4 11478067 103.1 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrDigit/4096B/simd-4 24760083 47.52 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrDigit/4096B/scalar-4 1490264 800.2 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrWord/8B/simd-4 153120554 8.104 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrWord/8B/scalar-4 186279788 6.460 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrWord/32B/simd-4 205711502 5.958 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrWord/32B/scalar-4 86716185 14.24 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrWord/64B/simd-4 185673494 6.833 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrWord/64B/scalar-4 48932490 25.11 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrWord/512B/simd-4 61637564 16.98 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrWord/512B/scalar-4 6845524 174.5 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrWord/4096B/simd-4 12697916 92.19 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrWord/4096B/scalar-4 881439 1442 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrNotWord/8B/simd-4 167067980 7.307 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrNotWord/8B/scalar-4 189991910 6.302 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrNotWord/32B/simd-4 205724659 5.578 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrNotWord/32B/scalar-4 79661326 13.15 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrNotWord/64B/simd-4 185518209 6.497 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrNotWord/64B/scalar-4 47755200 24.15 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrNotWord/512B/simd-4 70365358 16.62 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrNotWord/512B/scalar-4 6722820 172.3 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrNotWord/4096B/simd-4 13096357 93.62 ns/op 0 B/op 0 allocs/op +Benchmark_MemchrNotWord/4096B/scalar-4 892350 1366 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/8B/simd-4 100000000 10.19 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/8B/default-4 148054586 7.966 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/32B/simd-4 98693811 12.81 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/32B/default-4 100000000 10.89 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/64B/simd-4 75442142 15.92 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/64B/default-4 81081360 13.98 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/96B/simd-4 56509897 19.39 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/96B/default-4 25670028 47.21 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/128B/simd-4 62137202 20.18 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/128B/default-4 21325711 57.92 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/192B/simd-4 57145284 21.37 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/192B/default-4 12855652 92.65 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/512B/simd-4 45782227 26.28 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/512B/default-4 4696874 258.5 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/4096B/simd-4 15384080 80.64 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem/4096B/default-4 566840 2110 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/8B/paired-4 100722044 12.11 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/8B/paired-stdlib-4 156602451 7.970 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/32B/paired-4 63617959 16.69 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/32B/paired-stdlib-4 100000000 11.05 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/32B/single-4 83176831 14.12 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/32B/single-stdlib-4 80788734 15.91 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/64B/paired-4 91946842 12.97 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/64B/paired-stdlib-4 86483179 13.90 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/64B/single-4 35353610 32.88 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/64B/single-stdlib-4 33454047 35.61 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/96B/paired-4 90596826 13.71 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/96B/paired-stdlib-4 26030700 45.55 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/96B/single-4 26503994 44.73 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/96B/single-stdlib-4 36078775 33.98 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/128B/paired-4 81232996 14.57 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/128B/paired-stdlib-4 21295238 56.58 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/128B/single-4 19797116 61.11 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/128B/single-stdlib-4 25664023 46.42 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/192B/paired-4 78041734 15.73 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/192B/paired-stdlib-4 13159070 91.53 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/192B/single-4 12339504 99.01 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/192B/single-stdlib-4 14733991 81.86 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/512B/paired-4 55724107 21.69 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/512B/paired-stdlib-4 4627340 261.9 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/512B/single-4 4143304 285.8 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/512B/single-stdlib-4 4889746 246.2 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/4096B/paired-4 15190396 76.16 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/4096B/paired-stdlib-4 571941 2135 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/4096B/single-4 558564 2160 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Prefilter/4096B/single-stdlib-4 539943 2120 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Adversarial/simd-4 721 1676433 ns/op 0 B/op 0 allocs/op +Benchmark_Memmem_Adversarial/default-4 729 1660342 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/8B/simd-4 287283123 4.187 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/8B/swar-4 469731259 2.536 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/32B/simd-4 295464411 4.118 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/32B/swar-4 292665852 4.148 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/64B/simd-4 240708138 4.706 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/64B/swar-4 220235487 5.569 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/512B/simd-4 192368624 6.454 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/512B/swar-4 54892551 21.45 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/4096B/simd-4 43729008 27.50 ns/op 0 B/op 0 allocs/op +Benchmark_IsASCII/4096B/swar-4 7511167 157.0 ns/op 0 B/op 0 allocs/op +Benchmark_FirstNonASCII/8B/simd-4 260435899 4.724 ns/op 0 B/op 0 allocs/op +Benchmark_FirstNonASCII/8B/swar-4 341475208 3.574 ns/op 0 B/op 0 allocs/op +Benchmark_FirstNonASCII/32B/simd-4 297709566 4.219 ns/op 0 B/op 0 allocs/op +Benchmark_FirstNonASCII/32B/swar-4 227647696 5.171 ns/op 0 B/op 0 allocs/op +Benchmark_FirstNonASCII/64B/simd-4 267531430 4.636 ns/op 0 B/op 0 allocs/op +Benchmark_FirstNonASCII/64B/swar-4 160438296 7.334 ns/op 0 B/op 0 allocs/op +Benchmark_FirstNonASCII/512B/simd-4 170822334 7.301 ns/op 0 B/op 0 allocs/op +Benchmark_FirstNonASCII/512B/swar-4 34065859 34.89 ns/op 0 B/op 0 allocs/op +Benchmark_FirstNonASCII/4096B/simd-4 43481222 27.70 ns/op 0 B/op 0 allocs/op +Benchmark_FirstNonASCII/4096B/swar-4 4615596 254.2 ns/op 0 B/op 0 allocs/op +Benchmark_CountNonASCII/8B/simd-4 205752014 5.746 ns/op 0 B/op 0 allocs/op +Benchmark_CountNonASCII/8B/swar-4 281060181 4.143 ns/op 0 B/op 0 allocs/op +Benchmark_CountNonASCII/32B/simd-4 274114710 4.472 ns/op 0 B/op 0 allocs/op +Benchmark_CountNonASCII/32B/swar-4 206395050 5.781 ns/op 0 B/op 0 allocs/op +Benchmark_CountNonASCII/64B/simd-4 242445574 4.774 ns/op 0 B/op 0 allocs/op +Benchmark_CountNonASCII/64B/swar-4 139845796 8.224 ns/op 0 B/op 0 allocs/op +Benchmark_CountNonASCII/512B/simd-4 143031885 8.239 ns/op 0 B/op 0 allocs/op +Benchmark_CountNonASCII/512B/swar-4 27194380 43.84 ns/op 0 B/op 0 allocs/op +Benchmark_CountNonASCII/4096B/simd-4 33436537 35.32 ns/op 0 B/op 0 allocs/op +Benchmark_CountNonASCII/4096B/swar-4 3573552 334.1 ns/op 0 B/op 0 allocs/op +``` + + ## ☕ Supporters Fiber is an open-source project that runs on donations to pay the bills, e.g., our domain name, hosting, and serverless infrastructure. If you want to support Fiber, please become a [GitHub Sponsor](https://github.com/sponsors/gofiber). +

+ + + + CodeRabbit + + +

+

+ + Blacksmith + +

+

+ Tool Sponsors - supporting Fiber with free IDE licenses and AI credits +

+

+ JetBrains +   + OpenAI +   + Anthropic +

+ ### 📅 Monthly Sponsors - +
🔥 Fiber Guardian@coderabbitai
☕ Fiber Supporter@NdoleStudio @petercool
☕ Fiber Supporter@NdoleStudio
🪴 Fiber Friend@simonheisstpeter
@@ -510,5 +1159,7 @@ Fiber is an open-source project that runs on donations to pay the bills, e.g., o +
🚀 Fiber Hero@thnxdev
🪴 Fiber Friend@Gl1tchedPixzl
+ diff --git a/src/vendor/github.com/gofiber/utils/v2/ascii.go b/src/vendor/github.com/gofiber/utils/v2/ascii.go index a16018c7..44ba7e19 100644 --- a/src/vendor/github.com/gofiber/utils/v2/ascii.go +++ b/src/vendor/github.com/gofiber/utils/v2/ascii.go @@ -1,29 +1,61 @@ package utils import ( + "github.com/gofiber/utils/v2/internal/unsafeconv" + "github.com/gofiber/utils/v2/simd" "github.com/gofiber/utils/v2/swar" ) -// quoteLanes and backslashLanes broadcast '"' and '\\' to every lane. +// quoteLanes, backslashLanes, and tabLanes broadcast '"', '\\', and HTAB to every lane. const ( quoteLanes = uint64('"') * swar.Ones backslashLanes = uint64('\\') * swar.Ones + tabLanes = uint64('\t') * swar.Ones ) +// The dispatch prologues below gate on simd.MinLen — the measured length +// from which the AVX2 kernels beat these SWAR word loops — so the crossover +// has a single source of truth in the simd package. The simd.Accelerated() +// gate is a constant false off amd64, so the accelerated branches compile +// away entirely there. + // IsASCII reports whether s contains only ASCII bytes (no byte >= 0x80). // It ORs four words per iteration where possible (no index is needed, so -// detection can be deferred to one test per 32 bytes), then tests word-wise; -// inputs of 8+ bytes finish with one overlapping word at n-8, shorter ones -// byte-wise. +// detection can be deferred to one test per 32 bytes), then two, then +// word-wise; inputs of 8+ bytes finish with one overlapping word at n-8, +// shorter ones byte-wise. +// On amd64 CPUs with AVX2, inputs of 32+ bytes dispatch to package simd +// instead. +// +// The unrolled loops pin their group of words with a reslice and load at +// constant offsets inside it. swar.Load8's own reslice is bounds-checked +// against the backing array, which the length-based loop condition does +// not imply, so a variable index costs a compare and a branch per load; +// pinning the window pays that once per group instead. This mirrors +// simd.isASCIIGeneric — the same scan, kept in step so a retune of either +// is a retune of both. func IsASCII[S byteSeq](s S) bool { n := len(s) + if n >= simd.MinLen && simd.Accelerated() { + return simd.IsASCII(unsafeconv.Bytes(s)) + } + if n >= 8 && n < 16 { + return (swar.Load8(s, 0)|swar.Load8(s, n-8))&swar.HighBits == 0 + } i := 0 for ; i+32 <= n; i += 32 { - acc := swar.Load8(s, i) | swar.Load8(s, i+8) | swar.Load8(s, i+16) | swar.Load8(s, i+24) + w := s[i : i+32] + acc := swar.Load8(w, 0) | swar.Load8(w, 8) | swar.Load8(w, 16) | swar.Load8(w, 24) if acc&swar.HighBits != 0 { return false } } + for ; i+16 <= n; i += 16 { + w := s[i : i+16] + if (swar.Load8(w, 0)|swar.Load8(w, 8))&swar.HighBits != 0 { + return false + } + } for ; i+8 <= n; i += 8 { if swar.Load8(s, i)&swar.HighBits != 0 { return false @@ -57,8 +89,11 @@ func IndexNonQuotable[S byteSeq](s S) int { // Two words per branch: the masks compute independently, and if only the // second word matched, its first set lane is still exact. for ; i+16 <= n; i += 16 { - m0 := nonQuotableMask(swar.Load8(s, i)) - m1 := nonQuotableMask(swar.Load8(s, i+8)) + // Pinned window, as in IsASCII above: the two loads land at + // constant offsets and skip their bounds checks. + w := s[i : i+16] + m0 := nonQuotableMask(swar.Load8(w, 0)) + m1 := nonQuotableMask(swar.Load8(w, 8)) if m0|m1 != 0 { if m0 != 0 { return i + swar.FirstLane(m0) @@ -89,16 +124,9 @@ func IndexNonQuotable[S byteSeq](s S) int { } // nonQuotableMask marks the lanes of w holding bytes that need RFC 9110 -// quoted-string escaping. Like swar.ZeroLanes, the result is exact in and below -// the first marked lane, which is all the first-match scan above consumes. +// quoted-string escaping: controls other than HTAB (quotable qdtext), DEL, +// '"', and '\\'. Like swar.ZeroLanes, the result is exact in and below the +// first marked lane, which is all the first-match scan above consumes. func nonQuotableMask(w uint64) uint64 { - // Controls (< 0x20) and DEL (0x7F) share one biased range test: - // t := ((c & 0x7F) + 1) & 0x7F maps DEL to 0 and controls to 0x01..0x20, - // so t <= 0x20 captures exactly both; lanes with the high bit set - // (obs-text, always quotable) are excluded by the &^ w term. HTAB is - // quotable qdtext, so its lanes are cleared with an exact match mask — - // an approximate one could wrongly clear a control lane above a tab. - t := ((w & swar.LowSeven) + swar.Ones) & swar.LowSeven - ctl := ^(t + (0x80-0x21)*swar.Ones) &^ w & swar.HighBits &^ swar.MatchByteMask(w, '\t') - return ctl | swar.ZeroLanes(w^quoteLanes) | swar.ZeroLanes(w^backslashLanes) + return controlLanes(w)&otherLanes(w, tabLanes) | swar.ZeroLanes(w^quoteLanes) | swar.ZeroLanes(w^backslashLanes) } diff --git a/src/vendor/github.com/gofiber/utils/v2/byteseq.go b/src/vendor/github.com/gofiber/utils/v2/byteseq.go index 707df64a..033d2837 100644 --- a/src/vendor/github.com/gofiber/utils/v2/byteseq.go +++ b/src/vendor/github.com/gofiber/utils/v2/byteseq.go @@ -9,6 +9,12 @@ type byteSeq interface { ~string | ~[]byte } +// load4 assembles s[i:i+4] into a little-endian uint32; the caller guarantees i+4 <= len(s). +func load4[S byteSeq](s S, i int) uint32 { + w := s[i : i+4] + return uint32(w[0]) | uint32(w[1])<<8 | uint32(w[2])<<16 | uint32(w[3])<<24 +} + // EqualFold tests ascii strings or bytes for equality case-insensitively func EqualFold[S byteSeq](b, s S) bool { n := len(b) @@ -36,6 +42,14 @@ func EqualFold[S byteSeq](b, s S) bool { y := swar.Load8(s, n-8) return x == y || swar.ToUpperWord(x) == swar.ToUpperWord(y) } + if n >= 4 { + // 4..7 bytes: two overlapping 4-byte windows packed into one word + // fold with a single ToUpperWord; checked after the word paths so + // longer inputs pay nothing for it. + x := uint64(load4(b, 0)) | uint64(load4(b, n-4))<<32 + y := uint64(load4(s, 0)) | uint64(load4(s, n-4))<<32 + return x == y || swar.ToUpperWord(x) == swar.ToUpperWord(y) + } table := caseconv.ToUpperTable for ; i < n; i++ { diff --git a/src/vendor/github.com/gofiber/utils/v2/control.go b/src/vendor/github.com/gofiber/utils/v2/control.go new file mode 100644 index 00000000..ca72bb13 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/control.go @@ -0,0 +1,83 @@ +package utils + +import ( + "github.com/gofiber/utils/v2/swar" +) + +// noControlExemption is never a control lane, so exempting it is a no-op. +const noControlExemption = 0x80 + +// IndexControl returns the index of the first ASCII control byte in s (below +// 0x20 or DEL, the RFC 5234 CTL set), or -1. HTAB counts as a control byte; +// bytes >= 0x80 never match, unlike unicode.IsControl's C1 range. +func IndexControl[S byteSeq](s S) int { + return scanControl(s, noControlExemption) +} + +// IndexControlExceptTab is IndexControl with HTAB permitted: the bytes an +// RFC 9110 field value may not contain. +func IndexControlExceptTab[S byteSeq](s S) int { + return scanControl(s, '\t') +} + +// scanControl is the word scan behind both. Words holding no control byte, +// the common case, skip the exemption test entirely. +func scanControl[S byteSeq](s S, exempt byte) int { + n := len(s) + exemptLanes := swar.Broadcast(exempt) + i := 0 + for ; i+16 <= n; i += 16 { + w := s[i : i+16] + w0, w1 := swar.Load8(w, 0), swar.Load8(w, 8) + m0, m1 := controlLanes(w0), controlLanes(w1) + if m0|m1 != 0 { + if m0 &= otherLanes(w0, exemptLanes); m0 != 0 { + return i + swar.FirstLane(m0) + } + if m1 &= otherLanes(w1, exemptLanes); m1 != 0 { + return i + 8 + swar.FirstLane(m1) + } + } + } + for ; i+8 <= n; i += 8 { + w := swar.Load8(s, i) + if m := controlLanes(w); m != 0 { + if m &= otherLanes(w, exemptLanes); m != 0 { + return i + swar.FirstLane(m) + } + } + } + if i == n { + return -1 + } + if n >= 8 { + w := swar.Load8(s, n-8) + if m := controlLanes(w); m != 0 { + if m &= otherLanes(w, exemptLanes); m != 0 { + return n - 8 + swar.FirstLane(m) + } + } + return -1 + } + for ; i < n; i++ { + if c := s[i]; (c < 0x20 || c == 0x7f) && c != exempt { + return i + } + } + return -1 +} + +// controlLanes flags the lanes of w below 0x20 or equal to DEL, exactly per +// lane; the biased lanes stay below 0xE0, so no carries. +func controlLanes(w uint64) uint64 { + b := w & swar.LowSeven + return (^(b + (0x80-0x20)*swar.Ones) | (b + swar.Ones)) &^ w & swar.HighBits +} + +// otherLanes flags the lanes of w that differ from the byte broadcast in +// lanes, exactly per lane: x is zero only in the equal lanes, and only there +// is the high bit of ((x | HighBits) - Ones) | x clear (swar.MatchByteMask's test). +func otherLanes(w, lanes uint64) uint64 { + x := w ^ lanes + return ((x | swar.HighBits) - swar.Ones) | x +} diff --git a/src/vendor/github.com/gofiber/utils/v2/cut.go b/src/vendor/github.com/gofiber/utils/v2/cut.go new file mode 100644 index 00000000..fa1eab2f --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/cut.go @@ -0,0 +1,25 @@ +package utils + +import ( + "bytes" + + "github.com/gofiber/utils/v2/internal/unsafeconv" +) + +// CutByte is strings.Cut/bytes.Cut for a single-byte separator, generic over +// strings and byte slices; a miss returns s, the zero S ("" or nil), and +// false. The parts alias s. +func CutByte[S byteSeq](s S, sep byte) (before, after S, found bool) { //nolint:nonamedreturns // the two same-typed parts are only readable named + if i := bytes.IndexByte(unsafeconv.Bytes(s), sep); i >= 0 { + return s[:i], s[i+1:], true + } + return s, after, false +} + +// LastCutByte is CutByte around the last occurrence of sep. +func LastCutByte[S byteSeq](s S, sep byte) (before, after S, found bool) { //nolint:nonamedreturns // the two same-typed parts are only readable named + if i := bytes.LastIndexByte(unsafeconv.Bytes(s), sep); i >= 0 { + return s[:i], s[i+1:], true + } + return s, after, false +} diff --git a/src/vendor/github.com/gofiber/utils/v2/duration.go b/src/vendor/github.com/gofiber/utils/v2/duration.go new file mode 100644 index 00000000..434cd97d --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/duration.go @@ -0,0 +1,121 @@ +package utils + +import ( + "time" +) + +const durationBufLen = 32 // the longest rendering is "-2562047h47m16.854775808s" + +// AppendDuration appends d formatted exactly like time.Duration.String to dst +// and returns the extended slice, without the string allocation. +func AppendDuration(dst []byte, d time.Duration) []byte { + var buf [durationBufLen]byte + w := durationToBuf(&buf, d) + return append(dst, buf[w:]...) +} + +// durationToBuf renders d right-aligned into buf and returns the first offset. +func durationToBuf(buf *[durationBufLen]byte, d time.Duration) int { + w := len(buf) + u := uint64(d) + neg := d < 0 + if neg { + u = -u + } + + w-- + buf[w] = 's' + if u < uint64(time.Second) { + // Sub-second: ns, µs (two UTF-8 bytes), or ms. The unit splits are + // constant divisions, which compile to multiplies. + w-- + switch { + case u == 0: + buf[w] = '0' + return w + case u < uint64(time.Microsecond): + buf[w] = 'n' + case u < uint64(time.Millisecond): + w-- + buf[w] = 0xC2 // "µ" is 0xC2 0xB5 + buf[w+1] = 0xB5 + w = durationFrac(buf, w, u%uint64(time.Microsecond), 3) + u /= uint64(time.Microsecond) + default: + buf[w] = 'm' + w = durationFrac(buf, w, u%uint64(time.Millisecond), 6) + u /= uint64(time.Millisecond) + } + w = durationInt(buf, w, u) + } else { + w = durationFrac(buf, w, u%uint64(time.Second), 9) + u /= uint64(time.Second) + w = durationInt(buf, w, u%60) + u /= 60 + if u > 0 { + w-- + buf[w] = 'm' + w = durationInt(buf, w, u%60) + u /= 60 + if u > 0 { + w-- + buf[w] = 'h' + w = durationInt(buf, w, u) + } + } + } + + if neg { + w-- + buf[w] = '-' + } + return w +} + +// durationFrac writes the prec-digit fraction frac ending at buf[w] without +// its trailing zeros (nothing at all when it is zero, the common case) and +// returns the new offset. +func durationFrac(buf *[durationBufLen]byte, w int, frac uint64, prec int) int { + if frac == 0 { + return w + } + for frac%1000 == 0 { + frac /= 1000 + prec -= 3 + } + for frac%10 == 0 { + frac /= 10 + prec-- + } + for ; prec >= 2; prec -= 2 { + q := frac / 100 + w -= 2 + putPair(buf[:], w, frac-q*100) + frac = q + } + if prec == 1 { + w-- + buf[w] = byte(frac) + '0' + } + w-- + buf[w] = '.' + return w +} + +// durationInt writes the digits of v ending at buf[w] and returns the new offset. +func durationInt(buf *[durationBufLen]byte, w int, v uint64) int { + for v >= 100 { + q := v / 100 + w -= 2 + putPair(buf[:], w, v-q*100) + v = q + } + if v >= 10 { + w -= 2 + putPair(buf[:], w, v) + return w + } + w-- + buf[w] = byte(v) + '0' + return w +} diff --git a/src/vendor/github.com/gofiber/utils/v2/format.go b/src/vendor/github.com/gofiber/utils/v2/format.go index 6c81d14a..fa671283 100644 --- a/src/vendor/github.com/gofiber/utils/v2/format.go +++ b/src/vendor/github.com/gofiber/utils/v2/format.go @@ -1,6 +1,7 @@ package utils import ( + "encoding/binary" "math/bits" ) @@ -51,18 +52,63 @@ func formatUint8Slow(n uint8) string { return string([]byte{n/100 + '0', (n/10)%10 + '0', n%10 + '0'}) } -// formatUintBuf writes the digits of n into buf from the end and returns the start index. -// buf must be at least 20 bytes. -func formatUintBuf(buf *[20]byte, n uint64) int { - i := 20 - for n >= 10 { - i-- - buf[i] = byte(n%10) + '0' - n /= 10 - } - i-- - buf[i] = byte(n) + '0' - return i +// decimalPairs holds "00".."99" back to back: decimalPairs[2*n:2*n+2] is n zero-padded. +const decimalPairs = "00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899" + +// Formatting works on 8-digit groups: digits8 turns a value below 1e8 into +// eight zero-padded digit lanes (most significant first) with lane-parallel +// divisions, and leading zeros are zero lanes found by a trailing-zero count. +const ( + digitZeros = 0x3030303030303030 // '0' in every lane; digit lanes are below 16, so OR equals add + digitsBufLen = 24 // three lane groups; 20 digits plus a sign fit + digitsGroup = 100000000 // value of one lane group +) + +// digits8 returns the eight zero-padded digits of n < 1e8 as 0..9 byte lanes. +// Each multiply is a per-lane division by 100 or 10; no step carries across lanes. +func digits8(n uint32) uint64 { + hi := n / 10000 // two 4-digit halves in 32-bit lanes, high half in the low lane + x := uint64(hi) | uint64(n-hi*10000)<<32 + q := (x * 5243 >> 19) & 0x0000007F0000007F // lane/100, exact below 43699 + y := q | (x-q*100)<<16 // lane%100 into the upper 16 bits + q = (y * 103 >> 10) & 0x000F000F000F000F // lane/10, exact below 100 + return q | (y-q*10)<<8 // lane%10 into the upper byte +} + +// uintToBuf writes the digits of n >= 100 right-aligned into buf and returns +// the index of the first digit. +func uintToBuf(buf *[digitsBufLen]byte, n uint64) int { + if n < digitsGroup { + z := digits8(uint32(n)) + binary.LittleEndian.PutUint64(buf[16:24], z|digitZeros) + return 16 + bits.TrailingZeros64(z)>>3 + } + hi := n / digitsGroup + binary.LittleEndian.PutUint64(buf[16:24], digits8(uint32(n-hi*digitsGroup))|digitZeros) + if hi < digitsGroup { + z := digits8(uint32(hi)) + binary.LittleEndian.PutUint64(buf[8:16], z|digitZeros) + return 8 + bits.TrailingZeros64(z)>>3 + } + top := uint32(hi / digitsGroup) // at most 1844 + binary.LittleEndian.PutUint64(buf[8:16], digits8(uint32(hi-uint64(top)*digitsGroup))|digitZeros) + z := digits8(top) + binary.LittleEndian.PutUint64(buf[0:8], z|digitZeros) + return bits.TrailingZeros64(z) >> 3 +} + +// uint32ToBuf is uintToBuf for 32-bit values, which need at most two groups. +func uint32ToBuf(buf *[16]byte, n uint32) int { + if n < digitsGroup { + z := digits8(n) + binary.LittleEndian.PutUint64(buf[8:16], z|digitZeros) + return 8 + bits.TrailingZeros64(z)>>3 + } + hi := n / digitsGroup // at most 42 + binary.LittleEndian.PutUint64(buf[8:16], digits8(n-hi*digitsGroup)|digitZeros) + z := digits8(hi) + binary.LittleEndian.PutUint64(buf[0:8], z|digitZeros) + return bits.TrailingZeros64(z) >> 3 } // FormatUint formats a uint64 as a decimal string. @@ -71,28 +117,25 @@ func FormatUint(n uint64) string { if n < 100 { return smallInts[n] } - var buf [20]byte - i := formatUintBuf(&buf, n) + var buf [digitsBufLen]byte + i := uintToBuf(&buf, n) return string(buf[i:]) } // FormatInt formats an int64 as a decimal string. // It is faster than strconv.FormatInt for most inputs. func FormatInt(n int64) string { - if n >= 0 && n < 100 { - return smallInts[n] + if n >= 0 { + if n < 100 { + return smallInts[n] // inline: a FormatUint call would double the cost + } + return FormatUint(uint64(n)) } - if n < 0 && n > -100 { + if n > -100 { return smallNegInts[-n] } - if n >= 0 { - var buf [20]byte - i := formatUintBuf(&buf, uint64(n)) - return string(buf[i:]) - } - var buf [20]byte - i := formatUintBuf(&buf, uint64(-n)) - i-- + var buf [digitsBufLen]byte + i := uintToBuf(&buf, uint64(-n)) - 1 // uint64(-n) is the magnitude, math.MinInt64 included buf[i] = '-' return string(buf[i:]) } @@ -102,85 +145,36 @@ func FormatUint32(n uint32) string { if n < 100 { return smallInts[n] } - var buf [10]byte // max 4294967295 - i := 10 - for n >= 10 { - i-- - buf[i] = byte(n%10) + '0' - n /= 10 - } - i-- - buf[i] = byte(n) + '0' + var buf [16]byte + i := uint32ToBuf(&buf, n) return string(buf[i:]) } // FormatInt32 formats an int32 as a decimal string. func FormatInt32(n int32) string { - if n >= 0 && n < 100 { - return smallInts[n] - } - if n < 0 && n > -100 { - return smallNegInts[-n] - } if n >= 0 { + if n < 100 { + return smallInts[n] + } return FormatUint32(uint32(n)) } - var buf [11]byte // max -2147483648 - un := uint32(-n) - i := 11 - for un >= 10 { - i-- - buf[i] = byte(un%10) + '0' - un /= 10 - } - i-- - buf[i] = byte(un) + '0' - i-- + if n > -100 { + return smallNegInts[-n] + } + var buf [16]byte + i := uint32ToBuf(&buf, uint32(-n)) - 1 buf[i] = '-' return string(buf[i:]) } // FormatUint16 formats a uint16 as a decimal string. func FormatUint16(n uint16) string { - if n < 100 { - return smallInts[n] - } - var buf [5]byte // max 65535 - i := 5 - for n >= 10 { - i-- - buf[i] = byte(n%10) + '0' - n /= 10 - } - i-- - buf[i] = byte(n) + '0' - return string(buf[i:]) + return FormatUint32(uint32(n)) } // FormatInt16 formats an int16 as a decimal string. func FormatInt16(n int16) string { - if n >= 0 && n < 100 { - return smallInts[n] - } - if n < 0 && n > -100 { - return smallNegInts[-n] - } - if n >= 0 { - return FormatUint16(uint16(n)) - } - var buf [6]byte // max -32768 - un := uint16(-n) - i := 6 - for un >= 10 { - i-- - buf[i] = byte(un%10) + '0' - un /= 10 - } - i-- - buf[i] = byte(un) + '0' - i-- - buf[i] = '-' - return string(buf[i:]) + return FormatInt32(int32(n)) } // FormatUint8 formats a uint8 as a decimal string. @@ -229,22 +223,24 @@ func AppendUint(dst []byte, n uint64) []byte { if n < 100 { return append(dst, smallInts[n]...) } - var buf [20]byte - i := formatUintBuf(&buf, n) + var buf [digitsBufLen]byte + i := uintToBuf(&buf, n) return append(dst, buf[i:]...) } // AppendInt appends the decimal string representation of n to dst. func AppendInt(dst []byte, n int64) []byte { if n >= 0 { + if n < 100 { + return append(dst, smallInts[n]...) + } return AppendUint(dst, uint64(n)) } if n > -100 { return append(dst, smallNegInts[-n]...) } - var buf [20]byte - i := formatUintBuf(&buf, uint64(-n)) - i-- + var buf [digitsBufLen]byte + i := uintToBuf(&buf, uint64(-n)) - 1 buf[i] = '-' return append(dst, buf[i:]...) } diff --git a/src/vendor/github.com/gofiber/utils/v2/headerkey.go b/src/vendor/github.com/gofiber/utils/v2/headerkey.go new file mode 100644 index 00000000..971e0d9f --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/headerkey.go @@ -0,0 +1,71 @@ +package utils + +import ( + "github.com/gofiber/utils/v2/internal/caseconv" + "github.com/gofiber/utils/v2/internal/unsafeconv" +) + +// headerTokenTable flags the bytes valid in an HTTP header field name — the +// RFC 9110 token alphabet, matching net/http's validHeaderFieldByte. +var headerTokenTable = buildHeaderTokenTable() + +func buildHeaderTokenTable() [256]bool { + var t [256]bool + for c := byte('0'); c <= '9'; c++ { + t[c] = true + } + for c := byte('a'); c <= 'z'; c++ { + t[c] = true + } + for c := byte('A'); c <= 'Z'; c++ { + t[c] = true + } + for _, c := range []byte("!#$%&'*+-.^_`|~") { + t[c] = true + } + return t +} + +// CanonicalHeaderKey returns the canonical form of the HTTP header key: +// the first letter and any letter following a hyphen upper-cased, the rest +// lower-cased. The output matches net/http.CanonicalHeaderKey byte for +// byte, including its guard: a key containing any byte outside the header +// token alphabet is returned unchanged. Unlike the stdlib it accepts byte +// slices as well as strings and allocates only when the key actually needs +// rewriting — already-canonical keys, the overwhelmingly common case on +// receive paths, are validated in one table pass and returned as-is +// without the stdlib's canonical-key cache lookup. +func CanonicalHeaderKey[S byteSeq](key S) S { + upper := true + fix := -1 + for i := 0; i < len(key); i++ { + c := key[i] + if !headerTokenTable[c] { + return key + } + if fix < 0 && (upper && 'a' <= c && c <= 'z' || !upper && 'A' <= c && c <= 'Z') { + fix = i + } + upper = c == '-' + } + if fix < 0 { + return key + } + + buf := make([]byte, len(key)) + copy(buf, unsafeconv.Bytes(key)) + upper = fix == 0 || buf[fix-1] == '-' + for i := fix; i < len(buf); i++ { + c := buf[i] + if upper { + c = caseconv.ToUpperTable[c] + } else { + c = caseconv.ToLowerTable[c] + } + buf[i] = c + upper = c == '-' + } + // The zero-copy view is sound: buf is uniquely owned here and is never + // written again, which is what the string instantiation requires. + return unsafeconv.Seq[S](buf) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/hostport.go b/src/vendor/github.com/gofiber/utils/v2/hostport.go new file mode 100644 index 00000000..964191b7 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/hostport.go @@ -0,0 +1,35 @@ +package utils + +import ( + "bytes" + + "github.com/gofiber/utils/v2/internal/unsafeconv" +) + +// SplitHostPort splits "host:port", "[host]:port", and their %zone forms +// with net.SplitHostPort's exact rules, reporting failure as ok == false +// instead of a *net.AddrError; it accepts byte slices as well as strings, +// and the parts alias hostport. +func SplitHostPort[S byteSeq](hostport S) (host, port S, ok bool) { //nolint:nonamedreturns // the two same-typed parts are only readable named + b := unsafeconv.Bytes(hostport) + // The port starts after the last colon. + i := bytes.LastIndexByte(b, ':') + if i < 0 { + return host, port, false + } + j, k, hostEnd := 0, 0, i + if hostport[0] == '[' { + // Expect the first ']' just before the last ':'. + end := bytes.IndexByte(b, ']') + if end < 0 || end+1 != i { + return host, port, false + } + j, k, hostEnd = 1, end+1, end // there can't be a '[' resp. ']' before these positions + } else if bytes.IndexByte(b[:i], ':') >= 0 { + return host, port, false + } + if bytes.IndexByte(b[j:], '[') >= 0 || bytes.IndexByte(b[k:], ']') >= 0 { + return host, port, false + } + return hostport[j:hostEnd], hostport[i+1:], true +} diff --git a/src/vendor/github.com/gofiber/utils/v2/http.go b/src/vendor/github.com/gofiber/utils/v2/http.go index 99e762bd..08f96ece 100644 --- a/src/vendor/github.com/gofiber/utils/v2/http.go +++ b/src/vendor/github.com/gofiber/utils/v2/http.go @@ -9,6 +9,7 @@ import ( "strings" casestrings "github.com/gofiber/utils/v2/strings" + "github.com/gofiber/utils/v2/swar" ) const MIMEOctetStream = "application/octet-stream" @@ -19,31 +20,79 @@ const ( contentTypePrefixApplicationWithSlash = "application/" ) -// GetMIME returns the content-type of a file extension +// Extensions are looked up in an open-addressed table keyed by the extension +// packed into one lower-cased word and built from mimeExtensions at init: a +// hit is a multiply, a shift, and usually one comparison, with no allocation. +const ( + mimeTableBits = 9 // 512 slots for ~130 entries + mimeTableMask = 1< mimeTableMaxEntries { + panic("utils: the MIME extension table holds at most " + FormatInt(mimeTableMaxEntries) + " entries; raise mimeTableBits") + } + var t [1 << mimeTableBits]mimeEntry + for ext, mimeType := range exts { + if ext == "" || len(ext) > mimeKeyMaxLen { + panic("utils: MIME extension \"" + ext + "\" must be 1.." + FormatInt(mimeKeyMaxLen) + " bytes to fit a packed key") + } + key := packExtension(ext) + h := mimeHash(key) + for t[h].mimeType != "" { + h = (h + 1) & mimeTableMask + } + t[h] = mimeEntry{key: key, mimeType: mimeType} + } + return t +} + +// packExtension packs 1..mimeKeyMaxLen bytes lower-cased into a little-endian +// word with the length in the top lane, so "html\x00" and "html" differ. +func packExtension(ext string) uint64 { + return foldNeedle(ext) | uint64(len(ext))<<(8*mimeKeyMaxLen) +} + +func mimeHash(key uint64) int { + return int(key * mimeHashMul >> (64 - mimeTableBits)) +} + +// GetMIME returns the content-type of a file extension, matched +// case-insensitively with or without the leading dot. Unknown extensions map +// to MIMEOctetStream; an empty extension yields an empty string. func GetMIME(extension string) string { if len(extension) == 0 { return "" } - // Normalize extension once at the start to avoid repeated checks - var extWithoutDot string - var extWithDot string - if extension[0] == '.' { - extWithoutDot = extension[1:] - extWithDot = extension - } else { - extWithoutDot = extension - extWithDot = "." + extension + ext := extension + if ext[0] == '.' { + ext = ext[1:] } - - // Single map lookup with normalized key. Extensions are matched - // case-insensitively; ToLower only allocates for upper-case input. - if foundMime := mimeExtensions[casestrings.ToLower(extWithoutDot)]; len(foundMime) > 0 { - return foundMime + if len(ext) > 0 && len(ext) <= mimeKeyMaxLen { + key := packExtension(ext) + for h := mimeHash(key); mimeTable[h].mimeType != ""; h = (h + 1) & mimeTableMask { + if mimeTable[h].key == key { + return mimeTable[h].mimeType + } + } } - // Fallback to mime package with pre-computed extension - if foundMime := mime.TypeByExtension(extWithDot); foundMime != "" { + // Fallback to the mime package, which wants the dotted form. + if extension[0] != '.' { + extension = "." + extension + } + if foundMime := mime.TypeByExtension(extension); foundMime != "" { return foundMime } diff --git a/src/vendor/github.com/gofiber/utils/v2/httpdate.go b/src/vendor/github.com/gofiber/utils/v2/httpdate.go new file mode 100644 index 00000000..50b08390 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/httpdate.go @@ -0,0 +1,283 @@ +package utils + +import ( + "time" +) + +// httpDateLayout is the RFC 9110 preferred date format (net/http.TimeFormat), +// a fixed-width 29-byte layout that doubles as the formatting template: every +// separator byte is already in place, so AppendHTTPDate only overwrites the +// fields. +const ( + httpDateLayout = "Mon, 02 Jan 2006 15:04:05 GMT" + httpDateLen = len(httpDateLayout) +) + +var ( + httpWeekdays = [7]string{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"} + httpMonths = [12]string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"} + + // httpDaysInMonth is indexed by time.Month; February is adjusted for + // leap years in daysInHTTPMonth. + httpDaysInMonth = [13]int{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} +) + +// Calendar fields are converted with Hinnant's civil_from_days and +// days_from_civil (400-year eras of 146097 days, origin -0400-03-01 so every +// intermediate is non-negative); the tests sweep every day of 0..9999. +const ( + httpDateMinUnix = -62167219200 // 0000-01-01T00:00:00Z + httpDateMaxUnix = 253402300799 // 9999-12-31T23:59:59Z + secondsPerDay = 86400 + daysPerEra = 146097 + eraDaysToMarch = daysPerEra - 60 // 0000-01-01 to -0400-03-01 + daysFromMarchEraToUnix = 719468 + daysPerEra // -0400-03-01 to 1970-01-01 + weekdayOfYearZero = 6 // 0000-01-01 was a Saturday +) + +// civilFromDays converts days since 0000-01-01 (at most 3652424) into a +// proleptic Gregorian year, month (1..12), and day (1..31). +func civilFromDays(days uint64) (year, month, day uint64) { //nolint:nonamedreturns // the three calendar fields are only readable named + z := days + eraDaysToMarch + era := z / daysPerEra + doe := z - era*daysPerEra // day of era, [0, 146096] + yoe := (doe - doe/1460 + doe/36524 - doe/146096) / 365 // year of era, [0, 399] + doy := doe - (365*yoe + yoe/4 - yoe/100) // day of March-based year, [0, 365] + mp := (5*doy + 2) / 153 // March-based month, [0, 11] + day = doy - (153*mp+2)/5 + 1 + month = mp + 3 + if mp >= 10 { + month = mp - 9 + } + year = yoe + era*400 - 400 + if month <= 2 { + year++ + } + return year, month, day +} + +// unixFromCivil returns the Unix time of valid UTC calendar fields with the +// year in 0..9999, as parseRFC1123 guarantees. +func unixFromCivil(year, month, day, hour, minute, sec int) int64 { + y := year + 400 // one era back keeps January/February of year 0 non-negative + mp := month + 9 + if month > 2 { + mp = month - 3 + } else { + y-- + } + era := y / 400 + yoe := y - era*400 + doy := (153*mp+2)/5 + day - 1 + doe := yoe*365 + yoe/4 - yoe/100 + doy + days := era*daysPerEra + doe - daysFromMarchEraToUnix + return int64(days)*secondsPerDay + int64(hour*3600+minute*60+sec) +} + +// putPair writes n < 100 as two zero-padded digits at b[i] and b[i+1]. +func putPair(b []byte, i int, n uint64) { + _ = b[i+1] + b[i] = decimalPairs[2*n] + b[i+1] = decimalPairs[2*n+1] +} + +// AppendHTTPDate appends t in the RFC 9110 preferred HTTP date format +// ("Mon, 02 Jan 2006 15:04:05 GMT", net/http.TimeFormat) to dst and returns +// the extended slice. The output is byte-identical to +// t.UTC().AppendFormat(dst, http.TimeFormat) and always 29 bytes for the +// years 0..9999 that HTTP dates can represent; times outside that range +// delegate to time.AppendFormat. +func AppendHTTPDate(dst []byte, t time.Time) []byte { + sec := t.Unix() + if sec < httpDateMinUnix || sec > httpDateMaxUnix { + // RFC 1123 assumes a four-digit year; keep stdlib behavior for the + // unrepresentable rest instead of mis-padding it. + return t.UTC().AppendFormat(dst, httpDateLayout) + } + u := uint64(sec - httpDateMinUnix) // seconds since 0000-01-01, so every split is unsigned + days := u / secondsPerDay + sod := u - days*secondsPerDay + hour := sod / 3600 + sod -= hour * 3600 + minute := sod / 60 + second := sod - minute*60 + year, month, day := civilFromDays(days) + + var b [httpDateLen]byte + copy(b[:], httpDateLayout) + weekday := httpWeekdays[(days+weekdayOfYearZero)%7] // byte stores: copy would be a memmove call + b[0], b[1], b[2] = weekday[0], weekday[1], weekday[2] + putPair(b[:], 5, day) + monthName := httpMonths[month-1] + b[8], b[9], b[10] = monthName[0], monthName[1], monthName[2] + century := year / 100 + putPair(b[:], 12, century) + putPair(b[:], 14, year-century*100) + putPair(b[:], 17, hour) + putPair(b[:], 20, minute) + putPair(b[:], 23, second) + return append(dst, b[:]...) +} + +// FormatHTTPDate returns t in the RFC 9110 preferred HTTP date format, equal +// to t.UTC().Format(http.TimeFormat) with a single allocation for the result. +func FormatHTTPDate(t time.Time) string { + var buf [httpDateLen]byte + return string(AppendHTTPDate(buf[:0], t)) +} + +// ParseHTTPDate parses an HTTP date the way net/http.ParseTime does: +// the RFC 9110 preferred format ("Mon, 02 Jan 2006 15:04:05 GMT") plus the +// obsolete RFC 850 and ANSI C asctime forms, with surrounding ASCII +// whitespace tolerated. Canonical preferred-format input takes a fast scalar +// path that never calls time.Parse; every other input — legacy formats, +// unusual casing, non-GMT zone names, padding — falls back to time.Parse +// with byte-for-byte stdlib semantics, including its errors. The returned +// time is in time.UTC on the fast path and whatever time.Parse yields on the +// fallback; the instants agree in both cases. +func ParseHTTPDate[S byteSeq](s S) (time.Time, error) { + if t, ok := parseRFC1123(s); ok { + return t, nil + } + return parseHTTPDateSlow(string(s)) +} + +// parseRFC1123 is the strict fast path for canonical +// "Mon, 02 Jan 2006 15:04:05 GMT" input: exact length, exact separators, +// exact-case names. It reports ok=false for anything else — including +// out-of-range fields — so the slow path can produce stdlib-identical +// results and errors for the long tail. +func parseRFC1123[S byteSeq](s S) (time.Time, bool) { + if len(s) != httpDateLen { + return time.Time{}, false + } + if s[3] != ',' || s[4] != ' ' || s[7] != ' ' || s[11] != ' ' || s[16] != ' ' || + s[19] != ':' || s[22] != ':' || s[25] != ' ' || + s[26] != 'G' || s[27] != 'M' || s[28] != 'T' { + return time.Time{}, false + } + if !isHTTPWeekday(pack3(s[0], s[1], s[2])) { + return time.Time{}, false + } + month := httpMonthNum(pack3(s[8], s[9], s[10])) + if month == 0 { + return time.Time{}, false + } + day, okDay := twoDigits(s[5], s[6]) + yh, okYh := twoDigits(s[12], s[13]) + yl, okYl := twoDigits(s[14], s[15]) + hour, okHour := twoDigits(s[17], s[18]) + minute, okMin := twoDigits(s[20], s[21]) + sec, okSec := twoDigits(s[23], s[24]) + if !okDay || !okYh || !okYl || !okHour || !okMin || !okSec { + return time.Time{}, false + } + year := yh*100 + yl + if hour > 23 || minute > 59 || sec > 59 || + day < 1 || day > daysInHTTPMonth(month, year) { + // time.Parse rejects these; let it produce the exact error. + return time.Time{}, false + } + return time.Unix(unixFromCivil(year, month, day, hour, minute, sec), 0).UTC(), true +} + +// parseHTTPDateSlow mirrors net/http.ParseTime: trim the whitespace +// textproto would, then try the three allowed layouts in order, returning +// the last error when none matches. +func parseHTTPDateSlow(s string) (time.Time, error) { + start, end := 0, len(s) + for start < end && isHTTPDateSpace(s[start]) { + start++ + } + for start < end && isHTTPDateSpace(s[end-1]) { + end-- + } + s = s[start:end] + t, err := time.Parse(httpDateLayout, s) + if err == nil { + return t, nil + } + if t, err850 := time.Parse(time.RFC850, s); err850 == nil { + return t, nil + } + t, errANSIC := time.Parse(time.ANSIC, s) + if errANSIC == nil { + return t, nil + } + return time.Time{}, errANSIC +} + +// isHTTPDateSpace matches textproto.TrimString's notion of whitespace. +func isHTTPDateSpace(c byte) bool { + return c == ' ' || c == '\t' || c == '\r' || c == '\n' +} + +// pack3 packs three bytes for the name switches below. +func pack3(a, b, c byte) uint32 { + return uint32(a)<<16 | uint32(b)<<8 | uint32(c) +} + +// isHTTPWeekday reports whether w is one of the seven exact-case short +// weekday names. Like time.Parse, callers do not check the name against the +// date; any valid name is accepted. +func isHTTPWeekday(w uint32) bool { + switch w { + case 'S'<<16 | 'u'<<8 | 'n', 'M'<<16 | 'o'<<8 | 'n', 'T'<<16 | 'u'<<8 | 'e', + 'W'<<16 | 'e'<<8 | 'd', 'T'<<16 | 'h'<<8 | 'u', 'F'<<16 | 'r'<<8 | 'i', + 'S'<<16 | 'a'<<8 | 't': + return true + } + return false +} + +// httpMonthNum maps an exact-case short month name to 1..12, or 0 if w is +// not one. +func httpMonthNum(w uint32) int { + switch w { + case 'J'<<16 | 'a'<<8 | 'n': + return 1 + case 'F'<<16 | 'e'<<8 | 'b': + return 2 + case 'M'<<16 | 'a'<<8 | 'r': + return 3 + case 'A'<<16 | 'p'<<8 | 'r': + return 4 + case 'M'<<16 | 'a'<<8 | 'y': + return 5 + case 'J'<<16 | 'u'<<8 | 'n': + return 6 + case 'J'<<16 | 'u'<<8 | 'l': + return 7 + case 'A'<<16 | 'u'<<8 | 'g': + return 8 + case 'S'<<16 | 'e'<<8 | 'p': + return 9 + case 'O'<<16 | 'c'<<8 | 't': + return 10 + case 'N'<<16 | 'o'<<8 | 'v': + return 11 + case 'D'<<16 | 'e'<<8 | 'c': + return 12 + } + return 0 +} + +// twoDigits parses two ASCII digits into an int, reporting whether both +// bytes were digits. +func twoDigits(a, b byte) (int, bool) { + a -= '0' + b -= '0' + if a > 9 || b > 9 { + return 0, false + } + return int(a)*10 + int(b), true +} + +// daysInHTTPMonth returns the number of days in month for year, using the +// same leap-year rule as the time package. +func daysInHTTPMonth(month, year int) int { + if month == 2 && year%4 == 0 && (year%100 != 0 || year%400 == 0) { + return 29 + } + return httpDaysInMonth[month] +} diff --git a/src/vendor/github.com/gofiber/utils/v2/internal/caseconv/swar.go b/src/vendor/github.com/gofiber/utils/v2/internal/caseconv/swar.go index 5bbf3a84..7846848e 100644 --- a/src/vendor/github.com/gofiber/utils/v2/internal/caseconv/swar.go +++ b/src/vendor/github.com/gofiber/utils/v2/internal/caseconv/swar.go @@ -16,6 +16,14 @@ import ( // word loops here (benchstat -count=10, Go 1.25, Apple M2 Pro). The lane // order is identical, so swar words and binary.LittleEndian loads/stores // can be mixed freely. +// +// The word loops pin each group of four words with a three-index reslice +// and address the words at constant offsets inside it. A two-index +// reslice at a variable offset costs a capacity check plus the +// four-instruction pointer clamp the compiler emits when the new +// capacity is not a known nonzero constant; the pinned form pays one +// check per group and no clamp, and the constant-offset accesses inside +// it are check-free. See swar.Load8 for the same note. // WordLen is the SWAR word width in bytes, re-exported for the case // conversion callers in the strings and bytes packages: they route inputs @@ -42,10 +50,11 @@ func FirstUpperIndex(b []byte) int { // fold; only the cold hit-resolution ladder is shared, and it // inlines (the no-match loop never reaches it). for i = 8; i+32 <= n; i += 32 { - m0 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i:i+8]), 'A', 'Z') - m1 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+8:i+16]), 'A', 'Z') - m2 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+16:i+24]), 'A', 'Z') - m3 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+24:i+32]), 'A', 'Z') + w := b[i : i+32 : i+32] + m0 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[0:8]), 'A', 'Z') + m1 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[8:16]), 'A', 'Z') + m2 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[16:24]), 'A', 'Z') + m3 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[24:32]), 'A', 'Z') if m0|m1|m2|m3 != 0 { return firstSetLane32(i, m0, m1, m2, m3) } @@ -57,10 +66,11 @@ func FirstUpperIndex(b []byte) int { // per-lane exact, so re-scanned lanes are known non-matching and the // first set lane always falls in the new bytes. i = n - 32 - m0 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i:i+8]), 'A', 'Z') - m1 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+8:i+16]), 'A', 'Z') - m2 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+16:i+24]), 'A', 'Z') - m3 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+24:i+32]), 'A', 'Z') + w := b[i : i+32 : i+32] + m0 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[0:8]), 'A', 'Z') + m1 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[8:16]), 'A', 'Z') + m2 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[16:24]), 'A', 'Z') + m3 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[24:32]), 'A', 'Z') if m0|m1|m2|m3 != 0 { return firstSetLane32(i, m0, m1, m2, m3) } @@ -120,10 +130,11 @@ func FirstLowerIndex(b []byte) int { return swar.FirstLane(m) } for i = 8; i+32 <= n; i += 32 { - m0 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i:i+8]), 'a', 'z') - m1 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+8:i+16]), 'a', 'z') - m2 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+16:i+24]), 'a', 'z') - m3 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+24:i+32]), 'a', 'z') + w := b[i : i+32 : i+32] + m0 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[0:8]), 'a', 'z') + m1 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[8:16]), 'a', 'z') + m2 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[16:24]), 'a', 'z') + m3 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[24:32]), 'a', 'z') if m0|m1|m2|m3 != 0 { return firstSetLane32(i, m0, m1, m2, m3) } @@ -132,10 +143,11 @@ func FirstLowerIndex(b []byte) int { return -1 } i = n - 32 - m0 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i:i+8]), 'a', 'z') - m1 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+8:i+16]), 'a', 'z') - m2 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+16:i+24]), 'a', 'z') - m3 := swar.MatchRangeMask(binary.LittleEndian.Uint64(b[i+24:i+32]), 'a', 'z') + w := b[i : i+32 : i+32] + m0 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[0:8]), 'a', 'z') + m1 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[8:16]), 'a', 'z') + m2 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[16:24]), 'a', 'z') + m3 := swar.MatchRangeMask(binary.LittleEndian.Uint64(w[24:32]), 'a', 'z') if m0|m1|m2|m3 != 0 { return firstSetLane32(i, m0, m1, m2, m3) } @@ -163,12 +175,21 @@ func FirstLowerIndex(b []byte) int { return -1 } -// ToLowerInPlace lower-cases every ASCII uppercase byte of b in place. +// ToLowerInPlace lower-cases every ASCII uppercase byte of b in place: +// four words per pinned group, then single words, then bytes. func ToLowerInPlace(b []byte) { n := len(b) i := 0 + for ; i+32 <= n; i += 32 { + w := b[i : i+32 : i+32] + binary.LittleEndian.PutUint64(w[0:8], swar.ToLowerWord(binary.LittleEndian.Uint64(w[0:8]))) + binary.LittleEndian.PutUint64(w[8:16], swar.ToLowerWord(binary.LittleEndian.Uint64(w[8:16]))) + binary.LittleEndian.PutUint64(w[16:24], swar.ToLowerWord(binary.LittleEndian.Uint64(w[16:24]))) + binary.LittleEndian.PutUint64(w[24:32], swar.ToLowerWord(binary.LittleEndian.Uint64(w[24:32]))) + } for ; i+8 <= n; i += 8 { - binary.LittleEndian.PutUint64(b[i:i+8], swar.ToLowerWord(binary.LittleEndian.Uint64(b[i:i+8]))) + w := b[i : i+8 : i+8] + binary.LittleEndian.PutUint64(w, swar.ToLowerWord(binary.LittleEndian.Uint64(w))) } // Finish byte-wise: an overlapping word here would partially overlap the // previous 8-byte store and stall on store-to-load forwarding. @@ -177,12 +198,21 @@ func ToLowerInPlace(b []byte) { } } -// ToUpperInPlace upper-cases every ASCII lowercase byte of b in place. +// ToUpperInPlace upper-cases every ASCII lowercase byte of b in place; the +// loop shape mirrors ToLowerInPlace. func ToUpperInPlace(b []byte) { n := len(b) i := 0 + for ; i+32 <= n; i += 32 { + w := b[i : i+32 : i+32] + binary.LittleEndian.PutUint64(w[0:8], swar.ToUpperWord(binary.LittleEndian.Uint64(w[0:8]))) + binary.LittleEndian.PutUint64(w[8:16], swar.ToUpperWord(binary.LittleEndian.Uint64(w[8:16]))) + binary.LittleEndian.PutUint64(w[16:24], swar.ToUpperWord(binary.LittleEndian.Uint64(w[16:24]))) + binary.LittleEndian.PutUint64(w[24:32], swar.ToUpperWord(binary.LittleEndian.Uint64(w[24:32]))) + } for ; i+8 <= n; i += 8 { - binary.LittleEndian.PutUint64(b[i:i+8], swar.ToUpperWord(binary.LittleEndian.Uint64(b[i:i+8]))) + w := b[i : i+8 : i+8] + binary.LittleEndian.PutUint64(w, swar.ToUpperWord(binary.LittleEndian.Uint64(w))) } for ; i < n; i++ { b[i] = ToUpperTable[b[i]] @@ -205,14 +235,22 @@ func ToUpperInPlace(b []byte) { func ToLowerCopy(dst, src []byte, from int) { n := len(src) i := from + for ; i+32 <= n; i += 32 { + s := src[i : i+32 : i+32] + d := dst[i : i+32 : i+32] + binary.LittleEndian.PutUint64(d[0:8], swar.ToLowerWord(binary.LittleEndian.Uint64(s[0:8]))) + binary.LittleEndian.PutUint64(d[8:16], swar.ToLowerWord(binary.LittleEndian.Uint64(s[8:16]))) + binary.LittleEndian.PutUint64(d[16:24], swar.ToLowerWord(binary.LittleEndian.Uint64(s[16:24]))) + binary.LittleEndian.PutUint64(d[24:32], swar.ToLowerWord(binary.LittleEndian.Uint64(s[24:32]))) + } for ; i+8 <= n; i += 8 { - binary.LittleEndian.PutUint64(dst[i:i+8], swar.ToLowerWord(binary.LittleEndian.Uint64(src[i:i+8]))) + binary.LittleEndian.PutUint64(dst[i:i+8:i+8], swar.ToLowerWord(binary.LittleEndian.Uint64(src[i:i+8:i+8]))) } if i == n { return } if n >= 8 { - binary.LittleEndian.PutUint64(dst[n-8:n], swar.ToLowerWord(binary.LittleEndian.Uint64(src[n-8:n]))) + binary.LittleEndian.PutUint64(dst[n-8:n:n], swar.ToLowerWord(binary.LittleEndian.Uint64(src[n-8:n:n]))) return } for ; i < n; i++ { @@ -230,14 +268,22 @@ func ToLowerCopy(dst, src []byte, from int) { func ToUpperCopy(dst, src []byte, from int) { n := len(src) i := from + for ; i+32 <= n; i += 32 { + s := src[i : i+32 : i+32] + d := dst[i : i+32 : i+32] + binary.LittleEndian.PutUint64(d[0:8], swar.ToUpperWord(binary.LittleEndian.Uint64(s[0:8]))) + binary.LittleEndian.PutUint64(d[8:16], swar.ToUpperWord(binary.LittleEndian.Uint64(s[8:16]))) + binary.LittleEndian.PutUint64(d[16:24], swar.ToUpperWord(binary.LittleEndian.Uint64(s[16:24]))) + binary.LittleEndian.PutUint64(d[24:32], swar.ToUpperWord(binary.LittleEndian.Uint64(s[24:32]))) + } for ; i+8 <= n; i += 8 { - binary.LittleEndian.PutUint64(dst[i:i+8], swar.ToUpperWord(binary.LittleEndian.Uint64(src[i:i+8]))) + binary.LittleEndian.PutUint64(dst[i:i+8:i+8], swar.ToUpperWord(binary.LittleEndian.Uint64(src[i:i+8:i+8]))) } if i == n { return } if n >= 8 { - binary.LittleEndian.PutUint64(dst[n-8:n], swar.ToUpperWord(binary.LittleEndian.Uint64(src[n-8:n]))) + binary.LittleEndian.PutUint64(dst[n-8:n:n], swar.ToUpperWord(binary.LittleEndian.Uint64(src[n-8:n:n]))) return } for ; i < n; i++ { diff --git a/src/vendor/github.com/gofiber/utils/v2/internal/unsafeconv/unsafeconv.go b/src/vendor/github.com/gofiber/utils/v2/internal/unsafeconv/unsafeconv.go index a7510df5..0927938b 100644 --- a/src/vendor/github.com/gofiber/utils/v2/internal/unsafeconv/unsafeconv.go +++ b/src/vendor/github.com/gofiber/utils/v2/internal/unsafeconv/unsafeconv.go @@ -13,3 +13,25 @@ func UnsafeBytes(s string) []byte { // #nosec G103 return unsafe.Slice(unsafe.StringData(s), len(s)) } + +// Bytes returns a []byte view of s without allocation for any string- or +// byte-slice-backed type. It relies on string and slice headers both +// starting with the data pointer (guaranteed by the gc runtime layout, and +// the same assumption UnsafeString makes). When S's underlying type is +// string, the result aliases immutable memory and must only be read. +func Bytes[S ~string | ~[]byte](s S) []byte { + // #nosec G103 + return unsafe.Slice(*(**byte)(unsafe.Pointer(&s)), len(s)) +} + +// Seq is Bytes' inverse: it returns b viewed as S without allocation, for +// either instantiation. It relies on the string header being a prefix of +// the slice header (data pointer, then length), so reinterpreting a slice +// header yields a valid string view; the []byte instantiation reads the +// full header back unchanged. The caller must guarantee b is never written +// again when S's underlying type is string, since the result would alias +// memory the runtime assumes immutable. +func Seq[S ~string | ~[]byte](b []byte) S { + // #nosec G103 + return *(*S)(unsafe.Pointer(&b)) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/ipparse.go b/src/vendor/github.com/gofiber/utils/v2/ipparse.go new file mode 100644 index 00000000..2469b496 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/ipparse.go @@ -0,0 +1,171 @@ +package utils + +import ( + "bytes" + "encoding/binary" + "net/netip" + + "github.com/gofiber/utils/v2/internal/unsafeconv" +) + +// ParseIPv4 parses a dotted-decimal IPv4 address into a netip.Addr. It +// accepts exactly the IPv4 strings netip.ParseAddr does — four octets 0-255, +// no leading zeros, nothing before or after — and reports ok=false for +// everything else, including IPv6 forms. It never allocates, so []byte +// callers skip both the string conversion and netip's error construction. +func ParseIPv4[S byteSeq](s S) (netip.Addr, bool) { + var b [4]byte + n := len(s) + i := 0 + for oct := range 4 { + if oct > 0 { + if i >= n || s[i] != '.' { + return netip.Addr{}, false + } + i++ + } + if i >= n { + return netip.Addr{}, false + } + c := s[i] - '0' + if c > 9 { + return netip.Addr{}, false + } + v := uint32(c) + i++ + digits := 1 + for i < n && digits < 3 { + c = s[i] - '0' + if c > 9 { + break + } + v = v*10 + uint32(c) + i++ + digits++ + } + // Reject values above 255 and, like netip, leading zeros. + if v > 255 || (digits > 1 && s[i-digits] == '0') { + return netip.Addr{}, false + } + b[oct] = byte(v) + } + if i != n { + return netip.Addr{}, false + } + return netip.AddrFrom4(b), true +} + +// ParseIPv6 parses an IPv6 address into a netip.Addr. It accepts exactly +// the IPv6 strings netip.ParseAddr does — 16-bit hex fields, one optional +// "::", an optional embedded dotted-decimal IPv4 tail, and an optional +// non-empty "%zone" suffix — and reports ok=false for everything else, +// including plain IPv4 forms (use ParseIPv4 for those). The parse itself +// never allocates; only a present zone is materialized as a string because +// netip.Addr stores zones as strings. +func ParseIPv6[S byteSeq](s S) (netip.Addr, bool) { + n := len(s) + zone := bytes.IndexByte(unsafeconv.Bytes(s), '%') + end := n + if zone >= 0 { + if zone == n-1 { + // Empty zone. + return netip.Addr{}, false + } + end = zone + } + + var ip [16]byte + off := 0 + ellipsis := -1 + i := 0 + if end >= 2 && s[0] == ':' && s[1] == ':' { + ellipsis = 0 + i = 2 + } else if end > 0 && s[0] == ':' { + // A single leading colon starts no field. + return netip.Addr{}, false + } + + for off < 16 && i < end { + // Parse up to four hex digits; a fifth is an error. + fieldStart := i + val := uint32(0) + lim := min(i+4, end) + for i < lim { + d := unhexTable[s[i]] + if d == 0xFF { + break + } + val = val<<4 | uint32(d) + i++ + } + if i == lim && i < end && unhexTable[s[i]] != 0xFF { + return netip.Addr{}, false + } + if i < end && s[i] == '.' { + // Embedded IPv4 tail filling the final four bytes. + if off > 12 { + return netip.Addr{}, false + } + v4, ok := ParseIPv4(s[fieldStart:end]) + if !ok { + return netip.Addr{}, false + } + b4 := v4.As4() + copy(ip[off:], b4[:]) + off += 4 + i = end + break + } + if i == fieldStart { + // Every colon-separated field needs at least one digit. + return netip.Addr{}, false + } + // off is always even and < 16 here, so the two-byte store fits. + binary.BigEndian.PutUint16(ip[off:], uint16(val)) + off += 2 + if i == end { + break + } + if s[i] != ':' { + return netip.Addr{}, false + } + i++ + if i < end && s[i] == ':' { + if ellipsis >= 0 { + // At most one "::". + return netip.Addr{}, false + } + ellipsis = off + i++ + continue + } + if i == end { + // A trailing single colon is invalid. + return netip.Addr{}, false + } + } + if i != end { + return netip.Addr{}, false + } + if off < 16 { + if ellipsis < 0 { + return netip.Addr{}, false + } + // Expand "::": shift the fields after it to the end, zero the gap. + gap := 16 - off + for j := off - 1; j >= ellipsis; j-- { + ip[j+gap] = ip[j] + ip[j] = 0 + } + } else if ellipsis >= 0 { + // "::" must stand for at least one field of zeros. + return netip.Addr{}, false + } + + addr := netip.AddrFrom16(ip) + if zone >= 0 { + addr = addr.WithZone(string(s[zone+1:])) + } + return addr, true +} diff --git a/src/vendor/github.com/gofiber/utils/v2/jsonstring.go b/src/vendor/github.com/gofiber/utils/v2/jsonstring.go new file mode 100644 index 00000000..d8b52970 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/jsonstring.go @@ -0,0 +1,124 @@ +package utils + +import ( + "unicode/utf8" + + "github.com/gofiber/utils/v2/internal/unsafeconv" + "github.com/gofiber/utils/v2/swar" +) + +// ltLanes, gtLanes, and ampLanes broadcast the HTML-escaped characters to +// every lane; quoteLanes and backslashLanes live in ascii.go. +const ( + ltLanes = uint64('<') * swar.Ones + gtLanes = uint64('>') * swar.Ones + ampLanes = uint64('&') * swar.Ones +) + +// jsonHexDigits is the escape alphabet for \u00XX sequences, matching +// encoding/json. +const jsonHexDigits = "0123456789abcdef" + +// jsonSafeTable flags the ASCII bytes that pass through a JSON string +// encoder verbatim: 0x20..0x7E minus '"', '\\', and the HTML-escaped +// '<', '>', '&'. Bytes >= 0x80 are false so the scalar loop routes them +// to the UTF-8 path. +var jsonSafeTable = buildJSONSafeTable() + +func buildJSONSafeTable() [256]bool { + var t [256]bool + for c := byte(0x20); c < utf8.RuneSelf; c++ { + t[c] = c != '"' && c != '\\' && c != '<' && c != '>' && c != '&' + } + return t +} + +// AppendJSONString appends s to dst as a double-quoted JSON string and +// returns the extended slice. The output is byte-identical to +// encoding/json.Marshal of the same string value, including its default +// HTML escaping: '"' and '\\' get backslash escapes; control bytes below +// 0x20 become \b, \f, \n, \r, \t, or \u00XX; '<', '>', '&' become \u00XX; each +// invalid UTF-8 byte becomes the six literal characters \ufffd; and the +// line separators U+2028/U+2029 become the \u2028 and \u2029 escapes. +// All other bytes, including multi-byte UTF-8 sequences, are copied +// verbatim. dst must not alias s: the output is longer than the input (at +// minimum by the surrounding quotes), so in-place encoding is impossible +// and an aliased dst would overwrite bytes before they are read. Clean +// spans are located with a SWAR scan and copied wholesale, so typical log +// or header values cost one scan and one copy — with none of +// encoding/json.Marshal's reflection or allocation. +func AppendJSONString[S byteSeq](dst []byte, s S) []byte { + bs := unsafeconv.Bytes(s) + n := len(bs) + dst = append(dst, '"') + start, i := 0, 0 + for i < n { + // Skip to the next byte needing attention. Like nonQuotableMask, + // the combined mask is exact in and below its first set lane, which + // is all this first-match scan consumes. + if i+8 <= n { + m := jsonUnsafeMask(swar.Load8(bs, i)) + if m == 0 { + i += 8 + continue + } + i += swar.FirstLane(m) + } else if c := bs[i]; jsonSafeTable[c] { + i++ + continue + } + c := bs[i] + if c < utf8.RuneSelf { + dst = append(dst, bs[start:i]...) + dst = append(dst, '\\') + switch c { + case '"', '\\': + dst = append(dst, c) + case '\b': + dst = append(dst, 'b') + case '\f': + dst = append(dst, 'f') + case '\n': + dst = append(dst, 'n') + case '\r': + dst = append(dst, 'r') + case '\t': + dst = append(dst, 't') + default: + // Other control bytes and the HTML characters '<', '>', '&'. + dst = append(dst, 'u', '0', '0', jsonHexDigits[c>>4], jsonHexDigits[c&0x0F]) + } + i++ + start = i + continue + } + r, size := utf8.DecodeRune(bs[i:]) + switch { + case r == utf8.RuneError && size == 1: + dst = append(dst, bs[start:i]...) + dst = append(dst, '\\', 'u', 'f', 'f', 'f', 'd') + i++ + start = i + case r == '\u2028' || r == '\u2029': + dst = append(dst, bs[start:i]...) + dst = append(dst, '\\', 'u', '2', '0', '2', byte('8'+r-'\u2028')) + i += size + start = i + default: + i += size + } + } + dst = append(dst, bs[start:]...) + return append(dst, '"') +} + +// jsonUnsafeMask flags the lanes of w holding bytes a JSON string encoder +// cannot copy verbatim: controls below 0x20 (exact range mask), the five +// escaped ASCII characters (ZeroLanes needle matches, exact in and below +// their first hit), and all bytes >= 0x80, which the caller inspects as +// UTF-8. +func jsonUnsafeMask(w uint64) uint64 { + return swar.MatchRangeMask(w, 0x00, 0x1F) | w&swar.HighBits | + swar.ZeroLanes(w^quoteLanes) | swar.ZeroLanes(w^backslashLanes) | + swar.ZeroLanes(w^ltLanes) | swar.ZeroLanes(w^gtLanes) | swar.ZeroLanes(w^ampLanes) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/parse.go b/src/vendor/github.com/gofiber/utils/v2/parse.go index 2df8ae7c..46b52342 100644 --- a/src/vendor/github.com/gofiber/utils/v2/parse.go +++ b/src/vendor/github.com/gofiber/utils/v2/parse.go @@ -181,10 +181,9 @@ func isEightDigits(w uint64) bool { // steps. The caller must have validated that every lane is '0'..'9'. func parse8Digits(w uint64) uint64 { const ( - digitZeros = 0x3030303030303030 // '0' in every lane - pairMask = 0x000000FF000000FF - mul1 = 100 + (1000000 << 32) - mul2 = 1 + (10000 << 32) + pairMask = 0x000000FF000000FF + mul1 = 100 + (1000000 << 32) + mul2 = 1 + (10000 << 32) ) w -= digitZeros w = w*10 + w>>8 // adjacent digit pairs -> 2-digit values in even lanes diff --git a/src/vendor/github.com/gofiber/utils/v2/search.go b/src/vendor/github.com/gofiber/utils/v2/search.go index 58df1e45..6466e443 100644 --- a/src/vendor/github.com/gofiber/utils/v2/search.go +++ b/src/vendor/github.com/gofiber/utils/v2/search.go @@ -2,6 +2,8 @@ package utils import ( "github.com/gofiber/utils/v2/internal/caseconv" + "github.com/gofiber/utils/v2/internal/unsafeconv" + "github.com/gofiber/utils/v2/simd" "github.com/gofiber/utils/v2/swar" ) @@ -16,9 +18,13 @@ import ( // Inputs shorter than a word use scalar loops throughout. // IndexAny2 returns the index of the first occurrence in s of either a or b, -// or -1 if neither is present. +// or -1 if neither is present. On amd64 CPUs with AVX2, inputs of 32+ bytes +// dispatch to package simd instead. func IndexAny2[S byteSeq](s S, a, b byte) int { n := len(s) + if n >= simd.MinLen && simd.Accelerated() { + return simd.Memchr2(unsafeconv.Bytes(s), a, b) + } if n >= 8 { // The needle broadcasts are hoisted here so sub-word inputs never // pay for the multiplies. @@ -63,9 +69,13 @@ func IndexAny2[S byteSeq](s S, a, b byte) int { } // IndexAny3 returns the index of the first occurrence in s of a, b, or c, -// or -1 if none is present. +// or -1 if none is present. On amd64 CPUs with AVX2, inputs of 32+ bytes +// dispatch to package simd instead. func IndexAny3[S byteSeq](s S, a, b, c byte) int { n := len(s) + if n >= simd.MinLen && simd.Accelerated() { + return simd.Memchr3(unsafeconv.Bytes(s), a, b, c) + } if n >= 8 { bcA := swar.Broadcast(a) bcB := swar.Broadcast(b) diff --git a/src/vendor/github.com/gofiber/utils/v2/seq.go b/src/vendor/github.com/gofiber/utils/v2/seq.go new file mode 100644 index 00000000..562ded05 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/seq.go @@ -0,0 +1,32 @@ +package utils + +import ( + "bytes" + "iter" + + "github.com/gofiber/utils/v2/internal/unsafeconv" +) + +// SplitTrimSeq iterates over the sep-separated elements of s with ASCII +// whitespace trimmed and empty elements skipped, as HTTP list fields are read +// (RFC 9110 Section 5.6.1); the elements alias s. +func SplitTrimSeq[S byteSeq](s S, sep byte) iter.Seq[S] { + return func(yield func(S) bool) { + rest := s // traversal state stays local, so the sequence can be ranged over again + for { + // CutByte's body, inline: it is too large to inline into the iterator. + i := bytes.IndexByte(unsafeconv.Bytes(rest), sep) + elem := rest + if i >= 0 { + elem = rest[:i] + } + if elem = TrimSpace(elem); len(elem) > 0 && !yield(elem) { + return + } + if i < 0 { + return + } + rest = rest[i+1:] + } + } +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/LICENSE b/src/vendor/github.com/gofiber/utils/v2/simd/LICENSE new file mode 100644 index 00000000..6fc282c7 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Andrey Kolkov 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/src/vendor/github.com/gofiber/utils/v2/simd/ascii.go b/src/vendor/github.com/gofiber/utils/v2/simd/ascii.go new file mode 100644 index 00000000..0c49f7c4 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/ascii.go @@ -0,0 +1,177 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +package simd + +import ( + "math/bits" + + "github.com/gofiber/utils/v2/swar" +) + +// IsASCII reports whether every byte in data is ASCII (< 0x80). An empty +// slice is trivially ASCII. +// +// On amd64 with AVX2 and inputs of MinLen+ bytes it ORs four 32-byte +// vectors and tests all 128 bytes with a single VPMOVMSKB; elsewhere it +// uses a SWAR loop over 8-byte words. +func IsASCII(data []byte) bool { + if len(data) == 0 { + return true + } + return isASCIIImpl(data) +} + +// FirstNonASCII returns the index of the first byte >= 0x80 in data, or -1 +// if data is all ASCII. Use it to find where UTF-8 sequences begin. +// +// It reads the same signal as IsASCII — a non-ASCII byte is exactly a byte +// with its high bit set — so on amd64 with AVX2 and inputs of MinLen+ +// bytes it also tests 128 bytes per VPMOVMSKB, keeping the four vectors +// live so the hit path can pinpoint the byte; elsewhere it falls back to +// SWAR words. +func FirstNonASCII(data []byte) int { + if len(data) == 0 { + return -1 + } + return firstNonASCIIImpl(data) +} + +// CountNonASCII returns the number of bytes >= 0x80 in data. +// +// On amd64 with AVX2 and inputs of MinLen+ bytes it accumulates a per-lane +// count of high-bit bytes in vector byte lanes, four 32-byte vectors per +// iteration, sums the lanes once at the end, and population-counts the +// high-bit masks of the remaining whole vectors; elsewhere it counts +// SWAR-word-wise with a popcount per word. +func CountNonASCII(data []byte) int { + return countNonASCIIImpl(data) +} + +// The unrolled loops below all pin their group of words with a +// three-index reslice before loading from it. swar.Load8's own reslice is +// bounds-checked against the backing array's capacity, which the loop +// condition (stated in terms of length) does not imply, so a variable +// index costs a compare, a branch and a four-instruction empty-slice +// pointer clamp per load. Pinning the window once pays that at group +// granularity and leaves the loads inside it at constant offsets, where +// the checks fold away entirely: measured -20% at 32B rising to -62% at +// 4KiB for the ASCII scan, and the same shape for the first-match scans. + +// isASCIIGeneric is the portable SWAR implementation behind IsASCII. No +// index is needed, so detection can be deferred: whole groups of words are +// OR-ed into one accumulator and tested once, four words per branch and +// then two, which is what turns the per-word test into a per-32-byte one. +// Inputs of 8..15 bytes skip the loops entirely — two overlapping words +// already cover them — and every 8+ byte input finishes with one +// overlapping word at n-8. +func isASCIIGeneric(data []byte) bool { + n := len(data) + if n < swar.WordLen { + for i := range n { + if data[i] >= 0x80 { + return false + } + } + return true + } + if n < 2*swar.WordLen { + return (swar.Load8(data, 0)|swar.Load8(data, n-swar.WordLen))&swar.HighBits == 0 + } + i := 0 + for ; i+4*swar.WordLen <= n; i += 4 * swar.WordLen { + w := data[i : i+4*swar.WordLen : i+4*swar.WordLen] + acc := swar.Load8(w, 0) | + swar.Load8(w, swar.WordLen) | + swar.Load8(w, 2*swar.WordLen) | + swar.Load8(w, 3*swar.WordLen) + if acc&swar.HighBits != 0 { + return false + } + } + for ; i+2*swar.WordLen <= n; i += 2 * swar.WordLen { + w := data[i : i+2*swar.WordLen : i+2*swar.WordLen] + if (swar.Load8(w, 0)|swar.Load8(w, swar.WordLen))&swar.HighBits != 0 { + return false + } + } + for ; i+swar.WordLen <= n; i += swar.WordLen { + if swar.Load8(data, i)&swar.HighBits != 0 { + return false + } + } + if i == n { + return true + } + return swar.Load8(data, n-swar.WordLen)&swar.HighBits == 0 +} + +// firstNonASCIIGeneric is the portable SWAR implementation behind +// FirstNonASCII: two words per branch, then one overlapping word at n-8. +func firstNonASCIIGeneric(data []byte) int { + n := len(data) + if n < swar.WordLen { + for i := range n { + if data[i] >= 0x80 { + return i + } + } + return -1 + } + i := 0 + for ; i+2*swar.WordLen <= n; i += 2 * swar.WordLen { + w := data[i : i+2*swar.WordLen : i+2*swar.WordLen] + m0 := swar.Load8(w, 0) & swar.HighBits + m1 := swar.Load8(w, swar.WordLen) & swar.HighBits + if m0|m1 != 0 { + if m0 != 0 { + return i + swar.FirstLane(m0) + } + return i + swar.WordLen + swar.FirstLane(m1) + } + } + for ; i+swar.WordLen <= n; i += swar.WordLen { + if m := swar.Load8(data, i) & swar.HighBits; m != 0 { + return i + swar.FirstLane(m) + } + } + if i == n { + return -1 + } + // Overlapping final word: lanes before i are known ASCII, so any set + // lane falls in the new bytes. + if m := swar.Load8(data, n-swar.WordLen) & swar.HighBits; m != 0 { + return n - swar.WordLen + swar.FirstLane(m) + } + return -1 +} + +// countNonASCIIGeneric is the portable SWAR implementation behind +// CountNonASCII: a popcount of the 0x80 lane bits per word, four words per +// pinned window. Every word has to be visited whatever happens, so unlike +// the first-match scans there is no branch to amortize — the win here is +// purely the bounds checks the window removes. +func countNonASCIIGeneric(data []byte) int { + count := 0 + i := 0 + n := len(data) + for ; i+4*swar.WordLen <= n; i += 4 * swar.WordLen { + w := data[i : i+4*swar.WordLen : i+4*swar.WordLen] + count += bits.OnesCount64(swar.Load8(w, 0)&swar.HighBits) + + bits.OnesCount64(swar.Load8(w, swar.WordLen)&swar.HighBits) + + bits.OnesCount64(swar.Load8(w, 2*swar.WordLen)&swar.HighBits) + + bits.OnesCount64(swar.Load8(w, 3*swar.WordLen)&swar.HighBits) + } + for ; i+swar.WordLen <= n; i += swar.WordLen { + count += bits.OnesCount64(swar.Load8(data, i) & swar.HighBits) + } + // No overlapping word here: it would double-count. The tail is at most + // seven bytes. + for ; i < n; i++ { + if data[i] >= 0x80 { + count++ + } + } + return count +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/ascii_amd64.go b/src/vendor/github.com/gofiber/utils/v2/simd/ascii_amd64.go new file mode 100644 index 00000000..04ec50e5 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/ascii_amd64.go @@ -0,0 +1,55 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +//go:build amd64 + +package simd + +// The ASCII kernels are implemented in ascii_amd64.s. All three read the +// same signal (a byte is non-ASCII exactly when its high bit is set, which +// VPMOVMSKB gathers 32 at a time) and process four vectors per iteration. +// Like the rest of the package's kernels they are self-bounding: each one +// clamps its own vector loops and finishes short remainders itself, so +// none of them carries a length precondition for the caller to uphold. +// +//go:noescape +func isASCIIAVX2(data []byte) bool + +//go:noescape +func firstNonASCIIAVX2(data []byte) int + +//go:noescape +func countNonASCIIAVX2(data []byte) int + +// isASCIIImpl dispatches to the AVX2 kernel for inputs large enough to amortize +// the vector setup; smaller inputs and pre-AVX2 CPUs take the SWAR path. +func isASCIIImpl(data []byte) bool { + if hasAVX2 && len(data) >= MinLen { + return isASCIIAVX2(data) + } + return isASCIIGeneric(data) +} + +// firstNonASCIIImpl dispatches like isASCIIImpl. +func firstNonASCIIImpl(data []byte) int { + if hasAVX2 && len(data) >= MinLen { + return firstNonASCIIAVX2(data) + } + return firstNonASCIIGeneric(data) +} + +// countNonASCIIImpl dispatches like isASCIIImpl, with the extra POPCNT +// check its kernel needs. The kernel counts its own sub-vector remainder, +// so there is no prefix/suffix split here. An earlier version did split, +// handing the remainder to countNonASCIIGeneric, and paid a second +// non-inlinable call even when the remainder was empty — enough to put +// this scan behind its own SWAR fallback at MinLen (11.3ns vs 8.8ns at +// 32B). With the split gone the two are level at 32B and the kernel pulls +// ahead from 64B up, so MinLen stays the shared threshold. +func countNonASCIIImpl(data []byte) int { + if hasAVX2 && hasPOPCNT && len(data) >= MinLen { + return countNonASCIIAVX2(data) + } + return countNonASCIIGeneric(data) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/ascii_amd64.s b/src/vendor/github.com/gofiber/utils/v2/simd/ascii_amd64.s new file mode 100644 index 00000000..b815c546 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/ascii_amd64.s @@ -0,0 +1,399 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. +// Modified: legacy-SSE MOVD/MOVQ register moves replaced with VEX-encoded +// VMOVD/VMOVQ to avoid AVX-SSE transition penalties on Intel CPUs, the +// scalar tail loop replaced with one overlapping vector at the buffer end +// for the MinLen+ inputs the Go dispatch guarantees, the 32-byte main loop +// replaced with a 4x unrolled 128-byte block, and firstNonASCIIAVX2 / +// countNonASCIIAVX2 added so the locating and counting scans no longer +// have to fall back to SWAR words on amd64 (the counting kernel's block +// loop accumulating in vector byte lanes rather than extracting and +// population-counting every vector's mask). + +//go:build amd64 + +#include "textflag.h" +#include "block_align_amd64.h" + +// All three kernels share one observation: a byte is non-ASCII exactly when +// its high bit is set, and VPMOVMSKB gathers those 32 high bits into a +// scalar register in one instruction. OR-ing four vectors before the +// extraction therefore preserves "some byte in these 128 was non-ASCII" +// exactly, which is what lets the block loop test 128 bytes with a single +// port-0 VPMOVMSKB. Both loops test their bound at the bottom against a +// precomputed limit pointer. + +// func isASCIIAVX2(data []byte) bool +// +// AVX2 implementation of ASCII detection that checks if all bytes are < 0x80. +// +// Algorithm: +// 1. Block loop: OR four 32-byte vectors, extract the high bits with +// VPMOVMSKB, and return false if any is set. The loads fold into the +// VPOR operands, so a block costs four memory ops and one extraction. +// 2. 32-byte loop for the remainder, then one overlapping 32-byte window +// ending at the buffer end (rescanning bytes already proven ASCII +// cannot change the outcome). A scalar loop serves only sub-32 direct +// calls, unreachable through the Go dispatch. +// 3. Always call VZEROUPPER before returning (critical for performance) +// +// Parameters (FP offsets): +// data_base+0(FP) - pointer to data (8 bytes) +// data_len+8(FP) - data length (8 bytes) +// data_cap+16(FP) - data capacity (8 bytes, unused but part of slice) +// ret+24(FP) - return value: bool (1 byte) +// +// Total argument frame size: 25 bytes (8+8+8+1) +TEXT ·isASCIIAVX2(SB), NOSPLIT, $0-25 + // Load parameters + MOVQ data_base+0(FP), SI // SI = data pointer + MOVQ data_len+8(FP), DX // DX = data length + + // Empty data check + TESTQ DX, DX + JZ all_ascii + + // Calculate end pointer + LEAQ (SI)(DX*1), R8 // R8 = SI + length (end pointer) + + CMPQ DX, $32 + JB tail_loop // sub-32 direct call: scalar + + LEAQ -32(R8), R12 // last valid 32-byte window base + LEAQ -128(R8), R11 // last valid 128-byte block base + CMPQ SI, R11 + JA loop32_entry + + BLOCKALIGN +loop128: + VMOVDQU (SI), Y0 + VPOR 32(SI), Y0, Y0 + VPOR 64(SI), Y0, Y0 + VPOR 96(SI), Y0, Y0 + VPMOVMSKB Y0, AX + TESTL AX, AX + JNZ found_non_ascii + + ADDQ $128, SI + CMPQ SI, R11 + JBE loop128 + +loop32_entry: + CMPQ SI, R12 + JA last32 + +loop32: + // Load 32 bytes (unaligned load is safe and fast with AVX2) and + // extract the high bit of each byte into a 32-bit mask. + VMOVDQU (SI), Y0 + VPMOVMSKB Y0, AX + TESTL AX, AX + JNZ found_non_ascii + + ADDQ $32, SI + CMPQ SI, R12 + JBE loop32 + +last32: + // Fewer than 32 bytes remain past SI; retest the final window. + CMPQ SI, R8 + JAE all_ascii + VMOVDQU (R12), Y0 + VPMOVMSKB Y0, AX + TESTL AX, AX + JNZ found_non_ascii + JMP all_ascii + +tail_loop: + // Load one byte and check high bit + MOVBLZX (SI), AX // AX = data[SI] (zero-extended) + TESTB $0x80, AL // Check if high bit is set + JNZ found_non_ascii // If set, non-ASCII found + + // Advance to next byte + INCQ SI + CMPQ SI, R8 // Check if reached end + JB tail_loop // Continue if SI < end + +all_ascii: + // All bytes are ASCII + MOVB $1, ret+24(FP) // Return true + VZEROUPPER // Clear upper YMM bits (CRITICAL!) + RET + +found_non_ascii: + MOVB $0, ret+24(FP) // Return false + VZEROUPPER // Clear upper YMM bits + RET + +// func firstNonASCIIAVX2(data []byte) int +// +// AVX2 kernel behind FirstNonASCII: the same scan as isASCIIAVX2, but the +// block loop keeps the four source vectors live so the hit path can +// re-extract them in address order and BSF the first non-ASCII byte. +// +// Parameters (FP offsets): +// data_base+0(FP) - pointer to data (8 bytes) +// data_len+8(FP) - data length (8 bytes) +// data_cap+16(FP) - data capacity (8 bytes, unused) +// ret+24(FP) - return value: index or -1 (8 bytes) +TEXT ·firstNonASCIIAVX2(SB), NOSPLIT, $0-32 + MOVQ data_base+0(FP), SI + MOVQ data_len+8(FP), DX + + TESTQ DX, DX + JZ fna_not_found + + MOVQ SI, DI // DI = data start (preserved) + LEAQ (SI)(DX*1), R8 + + CMPQ DX, $32 + JB fna_tail_loop // sub-32 direct call: scalar + + LEAQ -32(R8), R12 + LEAQ -128(R8), R11 + CMPQ SI, R11 + JA fna_loop32_entry + + BLOCKALIGN +fna_loop128: + VMOVDQU (SI), Y0 + VMOVDQU 32(SI), Y1 + VMOVDQU 64(SI), Y2 + VMOVDQU 96(SI), Y3 + VPOR Y0, Y1, Y4 + VPOR Y2, Y3, Y5 + VPOR Y4, Y5, Y4 + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ fna_found_in_block + + ADDQ $128, SI + CMPQ SI, R11 + JBE fna_loop128 + +fna_loop32_entry: + CMPQ SI, R12 + JA fna_last32 + +fna_loop32: + VMOVDQU (SI), Y0 + VPMOVMSKB Y0, CX + TESTL CX, CX + JNZ fna_found_in_vector + + ADDQ $32, SI + CMPQ SI, R12 + JBE fna_loop32 + +fna_last32: + // Fewer than 32 bytes remain past SI; rescan the final window. Lanes + // before SI are known ASCII, so the first set lane falls in the new + // bytes. + CMPQ SI, R8 + JAE fna_not_found + MOVQ R12, SI + VMOVDQU (SI), Y0 + VPMOVMSKB Y0, CX + TESTL CX, CX + JNZ fna_found_in_vector + JMP fna_not_found + +fna_tail_loop: + MOVBLZX (SI), AX + TESTB $0x80, AL + JNZ fna_found_scalar + INCQ SI + CMPQ SI, R8 + JB fna_tail_loop + +fna_not_found: + MOVQ $-1, AX + MOVQ AX, ret+24(FP) + VZEROUPPER + RET + +fna_found_in_block: + VPMOVMSKB Y0, CX + TESTL CX, CX + JNZ fna_found_in_vector + ADDQ $32, SI + VPMOVMSKB Y1, CX + TESTL CX, CX + JNZ fna_found_in_vector + ADDQ $32, SI + VPMOVMSKB Y2, CX + TESTL CX, CX + JNZ fna_found_in_vector + ADDQ $32, SI + VPMOVMSKB Y3, CX + +fna_found_in_vector: + BSFL CX, CX + SUBQ DI, SI + ADDQ SI, CX + MOVQ CX, ret+24(FP) + VZEROUPPER + RET + +fna_found_scalar: + SUBQ DI, SI + MOVQ SI, ret+24(FP) + VZEROUPPER + RET + +// func countNonASCIIAVX2(data []byte) int +// +// AVX2 kernel behind CountNonASCII. Counting is the one scan here that +// cannot finish with the overlapping final window the first-match kernels +// use — rescanning bytes would count them twice — so instead the vector +// loops stop at the last whole vector and a branch-free byte loop takes +// the remaining 0-31 bytes. That keeps the kernel self-bounding for any +// length, like every other kernel in this package: it never reads past +// data[len(data)-1], so no caller-side length preconditioning stands +// between it and an out-of-bounds read. +// +// The block loop accumulates in vector byte lanes rather than extracting +// a mask per vector. A signed compare against zero turns each non-ASCII +// byte (the only bytes that read as negative) into 0xFF, and subtracting +// that lane from a byte accumulator adds one to it; the compare takes its +// input straight from memory, so a vector costs two vector ops and no +// scalar work. An earlier version extracted every vector's high bits +// with VPMOVMSKB and population-counted them, four extractions per block +// on the one port that executes them, which held the block loop to about +// half the throughput of the ASCII scans. Two accumulators alternate so +// each carries a two-op dependency chain per block. +// +// A byte lane can hold 255 and gains at most two per block, so the block +// loop flushes both accumulators every 127 blocks: VPSADBW against zero +// sums each accumulator's bytes into four 64-bit lanes, which are added +// to a running vector total. After the last block the totals are reduced +// to one scalar. That reduction is a fixed ten-cycle latency chain, which +// the 1-3 vectors left after the block loop (or the 1-3 vectors of a +// sub-block input) could not amortize, so those are still extracted with +// VPMOVMSKB and population-counted, exactly as before; each POPCNT writes +// the register its own VPMOVMSKB just produced, so the destination false +// dependency Intel CPUs carry on POPCNT is already satisfied. Inputs +// below one block therefore never touch the vector accumulators. +// +// POPCNT is a separate CPUID feature from AVX2, so countNonASCIIImpl gates +// on both; see cpu_amd64.go. +// +// Parameters (FP offsets): +// data_base+0(FP) - pointer to data (8 bytes) +// data_len+8(FP) - data length (8 bytes) +// data_cap+16(FP) - data capacity (8 bytes, unused) +// ret+24(FP) - number of bytes >= 0x80 (8 bytes) + +// FLUSH folds the two byte accumulators Y4 and Y5 into the 64-bit lane +// totals in Y8 and clears them. Y7 is the zero vector; Y0 and Y1 are +// scratch. +#define FLUSH \ + VPSADBW Y7, Y4, Y0; \ + VPSADBW Y7, Y5, Y1; \ + VPADDQ Y0, Y8, Y8; \ + VPADDQ Y1, Y8, Y8; \ + VPXOR Y4, Y4, Y4; \ + VPXOR Y5, Y5, Y5 + +TEXT ·countNonASCIIAVX2(SB), NOSPLIT, $0-32 + MOVQ data_base+0(FP), SI + MOVQ data_len+8(FP), DX + + XORQ R9, R9 // R9 = block loop total + XORQ R10, R10 // R10 = remainder total (kept apart so + // the remainder need not wait for the + // vector reduction) + + TESTQ DX, DX + JZ cna_done + + LEAQ (SI)(DX*1), R8 // R8 = end pointer + CMPQ DX, $32 + JB cna_tail // no whole vector: byte loop only + + LEAQ -32(R8), R12 // last valid 32-byte window base + LEAQ -128(R8), R11 // last valid 128-byte block base + CMPQ SI, R11 + JA cna_loop32_entry // no whole block: extract and count + + VPXOR Y7, Y7, Y7 // Y7 = zero (compare and SAD operand) + VPXOR Y4, Y4, Y4 // Y4 = byte accumulator A + VPXOR Y5, Y5, Y5 // Y5 = byte accumulator B + VPXOR Y8, Y8, Y8 // Y8 = 64-bit lane totals + MOVQ $127, R13 // blocks until a byte lane could overflow + + // This loop carries a third fused pair, the DECQ/JZ flush countdown, + // which at BLOCKALIGN's offset would straddle a window boundary; see + // block_align_amd64.h. + BLOCKALIGN_LONG +cna_loop128: + // 0 > byte is exactly "high bit set"; the compares read their data + // operand from memory. + VPCMPGTB (SI), Y7, Y0 + VPCMPGTB 32(SI), Y7, Y1 + VPCMPGTB 64(SI), Y7, Y2 + VPCMPGTB 96(SI), Y7, Y3 + VPSUBB Y0, Y4, Y4 // lane -= 0xFF, i.e. += 1 where non-ASCII + VPSUBB Y1, Y5, Y5 + VPSUBB Y2, Y4, Y4 + VPSUBB Y3, Y5, Y5 + + ADDQ $128, SI + DECQ R13 + JZ cna_flush + +cna_loop128_next: + CMPQ SI, R11 + JBE cna_loop128 + JMP cna_block_done + +cna_flush: + FLUSH + MOVQ $127, R13 + JMP cna_loop128_next + +cna_block_done: + // Fold the accumulators into the lane totals and the four totals into + // one scalar: high half onto low, then the high 64-bit lane onto the + // low one. + VPSADBW Y7, Y4, Y0 + VPSADBW Y7, Y5, Y1 + VPADDQ Y0, Y8, Y8 + VPADDQ Y1, Y8, Y8 + VEXTRACTI128 $1, Y8, X0 + VPADDQ X0, X8, X8 + VPSRLDQ $8, X8, X0 + VPADDQ X0, X8, X8 + VMOVQ X8, R9 + +cna_loop32_entry: + CMPQ SI, R12 + JA cna_tail + +cna_loop32: + VMOVDQU (SI), Y0 + VPMOVMSKB Y0, AX + POPCNTL AX, AX + ADDQ AX, R10 + ADDQ $32, SI + CMPQ SI, R12 + JBE cna_loop32 + +cna_tail: + // 0-31 bytes left. Shifting the byte down to its high bit turns the + // test into an add, so the loop carries no data-dependent branch. + CMPQ SI, R8 + JAE cna_done + MOVBLZX (SI), AX + SHRL $7, AX + ADDQ AX, R10 + INCQ SI + JMP cna_tail + +cna_done: + ADDQ R10, R9 + MOVQ R9, ret+24(FP) + VZEROUPPER + RET diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/ascii_other.go b/src/vendor/github.com/gofiber/utils/v2/simd/ascii_other.go new file mode 100644 index 00000000..19c55813 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/ascii_other.go @@ -0,0 +1,21 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +//go:build !amd64 + +package simd + +// The portable SWAR implementations are the only ones off amd64. + +func isASCIIImpl(data []byte) bool { + return isASCIIGeneric(data) +} + +func firstNonASCIIImpl(data []byte) int { + return firstNonASCIIGeneric(data) +} + +func countNonASCIIImpl(data []byte) int { + return countNonASCIIGeneric(data) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/block_align_amd64.h b/src/vendor/github.com/gofiber/utils/v2/simd/block_align_amd64.h new file mode 100644 index 00000000..f928e805 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/block_align_amd64.h @@ -0,0 +1,31 @@ +// BLOCKALIGN and BLOCKALIGN_LONG place the 128-byte block loop that +// follows them at byte 18, respectively 27, of a 32-byte code window: +// PCALIGN pads to the window, then two (or three) nine-byte NOPs — the +// canonical 66 0F 1F 84 00 00 00 00 00 form — shift the loop head. The +// NOPs sit before the label, so they run once per call that enters the +// block loop, never per iteration. +// +// The offset matters because of the Intel JCC erratum: on Skylake-derived +// cores (Skylake, Cascade Lake, Coffee Lake and their siblings) the +// microcode mitigation refuses to keep a jump — or a macro-fused +// compare-and-jump pair — in the decoded-uop cache when it crosses a +// 32-byte boundary or ends exactly on one. A block loop whose TEST/JNZ, +// DEC/JZ or CMP/JBE lands on such a boundary then runs from the legacy +// decoder every iteration, which measured ~10% slower on the pair kernel +// at 4KiB, and whether that happened used to depend on where the linker +// placed each kernel. Which offsets keep every pair of a loop inside one +// window depends on the loop's exact byte layout: 18 does for the six +// loops that use BLOCKALIGN, 27 for the three that use BLOCKALIGN_LONG. +// block_align_amd64_test.go checks the property against the linked test +// binary and logs each pair's position relative to its loop head, so a +// kernel edit that moves a branch onto a boundary fails the test (and +// the log shows which offset to pick) instead of silently costing +// throughput. +#define BLOCKALIGN \ + PCALIGN $32; \ + BYTE $0x66; BYTE $0x0F; BYTE $0x1F; BYTE $0x84; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00; \ + BYTE $0x66; BYTE $0x0F; BYTE $0x1F; BYTE $0x84; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00 + +#define BLOCKALIGN_LONG \ + BLOCKALIGN; \ + BYTE $0x66; BYTE $0x0F; BYTE $0x1F; BYTE $0x84; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00 diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/byte_frequencies.go b/src/vendor/github.com/gofiber/utils/v2/simd/byte_frequencies.go new file mode 100644 index 00000000..04160d6f --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/byte_frequencies.go @@ -0,0 +1,102 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +package simd + +// byteFrequencies holds empirical byte frequency ranks derived from English +// text, source code, and binary data samples. Lower rank means rarer byte, +// which makes it a better anchor for a search prefilter. The approach +// mirrors Rust's memchr crate (https://github.com/BurntSushi/memchr). +// The table is unexported (read it through ByteRank) so callers cannot +// mutate the ranking Memmem's prefilter selection depends on. +var byteFrequencies = [256]byte{ + // 0x00-0x0F: control characters (generally rare) + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + // 0x10-0x1F: more control characters + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // 0x20-0x2F: space and punctuation + 255, 60, 140, 50, 40, 35, 30, 160, 130, 130, 80, 55, 200, 140, 210, 100, + // 0x30-0x3F: digits and more punctuation + 180, 190, 170, 150, 140, 140, 130, 120, 120, 120, 150, 100, 70, 160, 70, 50, + // 0x40-0x4F: '@' and uppercase A-O + 25, 120, 80, 90, 85, 130, 75, 70, 80, 115, 30, 35, 90, 85, 100, 105, + // 0x50-0x5F: uppercase P-Z and brackets + 80, 15, 100, 110, 115, 70, 45, 55, 20, 50, 10, 90, 60, 90, 20, 110, + // 0x60-0x6F: backtick and lowercase a-o + 30, 225, 140, 170, 165, 245, 135, 130, 150, 200, 25, 65, 175, 155, 195, 205, + // 0x70-0x7F: lowercase p-z and braces + 145, 15, 195, 200, 215, 150, 75, 95, 45, 120, 20, 85, 40, 85, 15, 0, + // 0x80-0xFF: UTF-8 continuation/lead bytes (rare in typical text) + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +} + +// ByteRank returns the empirical frequency rank of b. Lower values indicate +// rarer bytes, which are better anchors for search prefilters; SelectRareBytes +// and Memmem rank needle bytes with it. +func ByteRank(b byte) byte { + return byteFrequencies[b] +} + +// RareByteInfo describes the two rarest bytes of a needle, as selected by +// SelectRareBytes. When the needle contains at least two distinct byte +// values, Byte2 always differs from Byte1; only for empty, single-byte, or +// all-identical needles do Byte2/Index2 equal Byte1/Index1. +type RareByteInfo struct { + // Byte1 is the rarest byte found in the needle. + Byte1 byte + // Byte2 is the rarest byte with a value different from Byte1, when the + // needle has one; otherwise it equals Byte1. + Byte2 byte + // Index1 is the position of Byte1's first occurrence in the needle. + Index1 int + // Index2 is the position of Byte2's first occurrence in the needle. + Index2 int +} + +// SelectRareBytes returns the two rarest bytes of needle according to +// ByteRank, preferring distinct byte values: whenever the needle contains +// two distinct values, Byte2 is the rarest byte different from Byte1, so +// duplicated occurrences of the rarest byte never crowd out a usable +// second anchor. Memmem feeds the result to MemchrPair to build a highly +// selective substring prefilter; it is exported so downstream code can +// build its own prefilters the same way. +func SelectRareBytes(needle []byte) RareByteInfo { + n := len(needle) + if n == 0 { + return RareByteInfo{} + } + + byte1, idx1 := needle[0], 0 + byte2, idx2 := needle[0], 0 + have2 := false + + for i := 1; i < n; i++ { + b := needle[i] + switch { + case byteFrequencies[b] < byteFrequencies[byte1]: + // b is strictly rarer than byte1, so it also has a different + // value; the demoted byte1 is at least as rare as any previous + // byte2 and becomes the second anchor. + byte2, idx2 = byte1, idx1 + byte1, idx1 = b, i + have2 = true + case b != byte1 && (!have2 || byteFrequencies[b] < byteFrequencies[byte2]): + byte2, idx2 = b, i + have2 = true + } + } + if !have2 { + // All bytes identical: no distinct second anchor exists. + byte2, idx2 = byte1, idx1 + } + + return RareByteInfo{Byte1: byte1, Byte2: byte2, Index1: idx1, Index2: idx2} +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/cpu_amd64.go b/src/vendor/github.com/gofiber/utils/v2/simd/cpu_amd64.go new file mode 100644 index 00000000..3ee4864f --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/cpu_amd64.go @@ -0,0 +1,22 @@ +//go:build amd64 + +package simd + +import ( + "golang.org/x/sys/cpu" +) + +// hasAVX2 gates every AVX2 kernel in this package. golang.org/x/sys/cpu +// verifies both the CPU capability and OS support for saving the YMM +// register state, and the value is read once at init so the per-call +// dispatch is a single predictable branch. +var hasAVX2 = cpu.X86.HasAVX2 + +// hasPOPCNT gates countNonASCIIAVX2, the one kernel that reaches outside +// the AVX/AVX2 instruction set: its remainder loop turns a vector's +// high-bit mask into a lane count with POPCNT, whose CPUID bit +// (01H:ECX[23]) is independent of AVX2's. Every shipping AVX2 part has +// POPCNT, but a hypervisor can mask the two separately, and an ungated +// POPCNT would be SIGILL rather than a fallback — so the count dispatch +// checks both and drops to the SWAR path if either is missing. +var hasPOPCNT = cpu.X86.HasPOPCNT diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/cpu_other.go b/src/vendor/github.com/gofiber/utils/v2/simd/cpu_other.go new file mode 100644 index 00000000..f9de7075 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/cpu_other.go @@ -0,0 +1,7 @@ +//go:build !amd64 + +package simd + +// hasAVX2 is constant false off amd64, letting the compiler prune the +// accelerated branches entirely. +const hasAVX2 = false diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr.go b/src/vendor/github.com/gofiber/utils/v2/simd/memchr.go new file mode 100644 index 00000000..8a536b71 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr.go @@ -0,0 +1,242 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +package simd + +import ( + "bytes" + + "github.com/gofiber/utils/v2/swar" +) + +// The portable fallbacks below are composed from the swar package's +// primitives rather than re-deriving the bit tricks; see swar's package +// documentation for the ZeroLanes contract the first-match scans rely on +// (false positives only above the first true match, so the first set lane +// is always exact). + +// Memchr2 returns the index of the first occurrence in haystack of either +// needle1 or needle2, or -1 if neither is present. Both needles are checked +// in the same pass, so it costs the same as a single-byte scan. +// +// There is deliberately no single-needle Memchr: use bytes.IndexByte, which +// the Go runtime already accelerates on all major architectures. +func Memchr2(haystack []byte, needle1, needle2 byte) int { + if len(haystack) == 0 { + return -1 + } + return memchr2Impl(haystack, needle1, needle2) +} + +// Memchr3 returns the index of the first occurrence in haystack of needle1, +// needle2, or needle3, or -1 if none is present. All three needles are +// checked in the same pass. +func Memchr3(haystack []byte, needle1, needle2, needle3 byte) int { + if len(haystack) == 0 { + return -1 + } + return memchr3Impl(haystack, needle1, needle2, needle3) +} + +// MemchrPair returns the first index i such that haystack[i] == byte1 and +// haystack[i+offset] == byte2, or -1 if no such position exists. offset must +// be >= 0; a negative offset returns -1. +// +// Requiring two bytes at a fixed distance makes the scan far more selective +// than a single-byte search, which is what makes it a good substring +// prefilter: false candidates need both bytes at exactly the right distance. +// Memmem uses it for short needles. +func MemchrPair(haystack []byte, byte1, byte2 byte, offset int) int { + if offset < 0 || len(haystack) <= offset { + return -1 + } + if offset == 0 { + // Both bytes would occupy the same position, so they must be equal. + if byte1 != byte2 { + return -1 + } + return bytes.IndexByte(haystack, byte1) + } + return memchrPairImpl(haystack, byte1, byte2, offset) +} + +// memchr2Generic is the portable SWAR fallback for Memchr2: a ZeroLanes +// first-match scan over both needle broadcasts, finishing 8+ byte inputs +// with one overlapping word at n-8 (already-scanned lanes are known +// non-matching, so the first set lane falls in the new bytes). +func memchr2Generic(haystack []byte, needle1, needle2 byte) int { + n := len(haystack) + if n < swar.WordLen { + for i := range n { + if haystack[i] == needle1 || haystack[i] == needle2 { + return i + } + } + return -1 + } + + bc1 := swar.Broadcast(needle1) + bc2 := swar.Broadcast(needle2) + i := 0 + for ; i+2*swar.WordLen <= n; i += 2 * swar.WordLen { + // Pinned window: see the note above isASCIIGeneric in ascii.go for + // why the loads use constant offsets into it. + win := haystack[i : i+2*swar.WordLen : i+2*swar.WordLen] + w0, w1 := swar.Load8(win, 0), swar.Load8(win, swar.WordLen) + m0 := swar.ZeroLanes(w0^bc1) | swar.ZeroLanes(w0^bc2) + m1 := swar.ZeroLanes(w1^bc1) | swar.ZeroLanes(w1^bc2) + if m0|m1 != 0 { + if m0 != 0 { + return i + swar.FirstLane(m0) + } + return i + swar.WordLen + swar.FirstLane(m1) + } + } + for ; i+swar.WordLen <= n; i += swar.WordLen { + w := swar.Load8(haystack, i) + if m := swar.ZeroLanes(w^bc1) | swar.ZeroLanes(w^bc2); m != 0 { + return i + swar.FirstLane(m) + } + } + if i == n { + return -1 + } + w := swar.Load8(haystack, n-swar.WordLen) + if m := swar.ZeroLanes(w^bc1) | swar.ZeroLanes(w^bc2); m != 0 { + return n - swar.WordLen + swar.FirstLane(m) + } + return -1 +} + +// memchr3Generic is the portable SWAR fallback for Memchr3; see +// memchr2Generic for the scan shape. +func memchr3Generic(haystack []byte, needle1, needle2, needle3 byte) int { + n := len(haystack) + if n < swar.WordLen { + for i := range n { + if haystack[i] == needle1 || haystack[i] == needle2 || haystack[i] == needle3 { + return i + } + } + return -1 + } + + bc1 := swar.Broadcast(needle1) + bc2 := swar.Broadcast(needle2) + bc3 := swar.Broadcast(needle3) + i := 0 + for ; i+2*swar.WordLen <= n; i += 2 * swar.WordLen { + win := haystack[i : i+2*swar.WordLen : i+2*swar.WordLen] + w0, w1 := swar.Load8(win, 0), swar.Load8(win, swar.WordLen) + m0 := swar.ZeroLanes(w0^bc1) | swar.ZeroLanes(w0^bc2) | swar.ZeroLanes(w0^bc3) + m1 := swar.ZeroLanes(w1^bc1) | swar.ZeroLanes(w1^bc2) | swar.ZeroLanes(w1^bc3) + if m0|m1 != 0 { + if m0 != 0 { + return i + swar.FirstLane(m0) + } + return i + swar.WordLen + swar.FirstLane(m1) + } + } + for ; i+swar.WordLen <= n; i += swar.WordLen { + w := swar.Load8(haystack, i) + if m := swar.ZeroLanes(w^bc1) | swar.ZeroLanes(w^bc2) | swar.ZeroLanes(w^bc3); m != 0 { + return i + swar.FirstLane(m) + } + } + if i == n { + return -1 + } + w := swar.Load8(haystack, n-swar.WordLen) + if m := swar.ZeroLanes(w^bc1) | swar.ZeroLanes(w^bc2) | swar.ZeroLanes(w^bc3); m != 0 { + return n - swar.WordLen + swar.FirstLane(m) + } + return -1 +} + +// memchrPairGeneric is the portable SWAR fallback for MemchrPair. It leans +// on ZeroLanes flagging every true zero lane (part of its contract), so +// ANDing the two per-position masks can never drop a real pair; what the +// AND does lose is lane exactness — a flagged lane may be a false +// candidate sitting strictly below the first true pair — so every +// candidate is re-verified scalar and refuted ones are stepped past. +// ZeroLanes plus this rare verify step beats a pair of exact +// swar.MatchByteMask masks on the no-candidate fast path, which is the +// common case. The caller guarantees offset >= 1 and +// len(haystack) > offset. +// +// The scan runs over the candidate positions 0..len-offset-1: two words +// per branch through pinned windows (see ascii.go), then one word, then +// one overlapping word ending at the last candidate. Positions below the +// overlap were either never flagged or refuted by the verify step, so +// both are known non-pairs and any candidate the overlap flags there +// fails verification harmlessly; the first candidate to verify is the +// first pair. An earlier version loaded both words of every step through +// swar.Load8 at variable offsets and finished the last 1-7 positions +// scalar, which at 32 bytes ran no faster than a plain scalar loop. +func memchrPairGeneric(haystack []byte, byte1, byte2 byte, offset int) int { + n := len(haystack) + if n < swar.WordLen+offset { + for i := 0; i+offset < n; i++ { + if haystack[i] == byte1 && haystack[i+offset] == byte2 { + return i + } + } + return -1 + } + + bc1 := swar.Broadcast(byte1) + bc2 := swar.Broadcast(byte2) + last := n - offset // candidate positions are 0..last-1 + i := 0 + for ; i+2*swar.WordLen <= last; i += 2 * swar.WordLen { + a := haystack[i : i+2*swar.WordLen : i+2*swar.WordLen] + b := haystack[i+offset : i+offset+2*swar.WordLen : i+offset+2*swar.WordLen] + c0 := swar.ZeroLanes(swar.Load8(a, 0)^bc1) & swar.ZeroLanes(swar.Load8(b, 0)^bc2) + c1 := swar.ZeroLanes(swar.Load8(a, swar.WordLen)^bc1) & swar.ZeroLanes(swar.Load8(b, swar.WordLen)^bc2) + if c0|c1 != 0 { + if pos := verifyPairCandidates(haystack, byte1, byte2, offset, i, c0); pos >= 0 { + return pos + } + if pos := verifyPairCandidates(haystack, byte1, byte2, offset, i+swar.WordLen, c1); pos >= 0 { + return pos + } + } + } + for ; i+swar.WordLen <= last; i += swar.WordLen { + a := haystack[i : i+swar.WordLen : i+swar.WordLen] + b := haystack[i+offset : i+offset+swar.WordLen : i+offset+swar.WordLen] + c := swar.ZeroLanes(swar.Load8(a, 0)^bc1) & swar.ZeroLanes(swar.Load8(b, 0)^bc2) + if c != 0 { + if pos := verifyPairCandidates(haystack, byte1, byte2, offset, i, c); pos >= 0 { + return pos + } + } + } + if i == last { + return -1 + } + i = last - swar.WordLen + a := haystack[i : i+swar.WordLen : i+swar.WordLen] + b := haystack[i+offset : i+offset+swar.WordLen : i+offset+swar.WordLen] + c := swar.ZeroLanes(swar.Load8(a, 0)^bc1) & swar.ZeroLanes(swar.Load8(b, 0)^bc2) + if c != 0 { + return verifyPairCandidates(haystack, byte1, byte2, offset, i, c) + } + return -1 +} + +// verifyPairCandidates checks the candidate lanes of cand, a ZeroLanes AND +// mask for the word at base, in address order and returns the first +// position that really holds byte1 and byte2 at distance offset, or -1. +// It runs only on the rare candidate path, so the scalar re-reads are +// never on the no-match loop. +func verifyPairCandidates(haystack []byte, byte1, byte2 byte, offset, base int, cand uint64) int { + for ; cand != 0; cand &= cand - 1 { + pos := base + swar.FirstLane(cand) + if haystack[pos] == byte1 && haystack[pos+offset] == byte2 { + return pos + } + } + return -1 +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr_amd64.go b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_amd64.go new file mode 100644 index 00000000..bc282eac --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_amd64.go @@ -0,0 +1,52 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +//go:build amd64 + +package simd + +// Assembly kernels implemented in memchr_amd64.s. Each consumes four +// 32-byte AVX2 vectors per iteration (OR-ing the per-vector match masks so +// a 128-byte block needs one extraction and one branch), drops to a +// 32-byte loop for the remainder, and finishes the last 1-31 positions +// with an overlapping rescan: memchr2 and memchr3 reload one 32-byte +// vector ending at the buffer end, while memchrPair reloads both of its +// windows — the byte1 side ending at len-offset, the byte2 side at the +// buffer end. +// +//go:noescape +func memchr2AVX2(haystack []byte, needle1, needle2 byte) int + +//go:noescape +func memchr3AVX2(haystack []byte, needle1, needle2, needle3 byte) int + +//go:noescape +func memchrPairAVX2(haystack []byte, byte1, byte2 byte, offset int) int + +// memchr2Impl dispatches to the AVX2 kernel for inputs large enough to amortize +// the vector setup. The caller guarantees a non-empty haystack. +func memchr2Impl(haystack []byte, needle1, needle2 byte) int { + if hasAVX2 && len(haystack) >= MinLen { + return memchr2AVX2(haystack, needle1, needle2) + } + return memchr2Generic(haystack, needle1, needle2) +} + +// memchr3Impl dispatches like memchr2Impl. +func memchr3Impl(haystack []byte, needle1, needle2, needle3 byte) int { + if hasAVX2 && len(haystack) >= MinLen { + return memchr3AVX2(haystack, needle1, needle2, needle3) + } + return memchr3Generic(haystack, needle1, needle2, needle3) +} + +// memchrPairImpl dispatches to the AVX2 kernel when there is room for at least +// one 32-byte vector of pair positions. The caller guarantees offset >= 1 +// and len(haystack) > offset. +func memchrPairImpl(haystack []byte, byte1, byte2 byte, offset int) int { + if hasAVX2 && len(haystack) >= MinLen+offset { + return memchrPairAVX2(haystack, byte1, byte2, offset) + } + return memchrPairGeneric(haystack, byte1, byte2, offset) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr_amd64.s b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_amd64.s new file mode 100644 index 00000000..de56502c --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_amd64.s @@ -0,0 +1,570 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. +// Modified: legacy-SSE MOVD/MOVQ register moves replaced with VEX-encoded +// VMOVD/VMOVQ to avoid AVX-SSE transition penalties on Intel CPUs, the +// scalar tail loops replaced with overlapping vector rescans of the final +// window (a vector pair in memchrPairAVX2) for the MinLen+ inputs the Go +// dispatch guarantees, and the 32-byte main loops replaced with 4x +// unrolled 128-byte blocks that OR the per-vector masks together and +// extract a single VPMOVMSKB per block. + +//go:build amd64 + +#include "textflag.h" +#include "block_align_amd64.h" + +// The kernels below share one loop skeleton: +// +// 1. A 128-byte block loop, entered only while base <= end-128. Four +// vectors are compared in parallel, their match masks OR-ed together, +// and a single VPMOVMSKB tests all 128 bytes at once. The per-vector +// masks stay live, so the (rare) hit path re-extracts them in address +// order to locate the first match. This keeps the port-0-only +// VPMOVMSKB and the loop bookkeeping off the critical path: the block +// loop retires four 32-byte compares for the branch overhead of one. +// 2. A 32-byte loop for the remainder, entered while base <= end-32. +// 3. One overlapping 32-byte window ending at the buffer end for the +// last 1-31 bytes. Lanes before the current base were already +// resolved as non-matching, so the first set lane of the overlap +// always falls in the new bytes and BSF stays exact. +// +// Both loops test their bound at the bottom against a precomputed limit +// pointer, so the steady state costs one ADDQ/CMPQ/JBE instead of the +// LEAQ/CMPQ/JA/ADDQ/JMP the original 32-byte loops carried. Inputs shorter +// than one vector — unreachable through the Go dispatch, which routes them +// to the SWAR fallbacks — take the scalar tail loops. + +// func memchr2AVX2(haystack []byte, needle1, needle2 byte) int +// +// AVX2 kernel behind Memchr2 that searches for either of two bytes. +// Uses parallel comparison with two broadcast vectors and combines results +// with VPOR. +// +// Parameters (FP offsets, ABI0; the byte arguments are packed into +// adjacent 1-byte slots after the 24-byte slice header, then padded to +// align the return value): +// haystack_base+0(FP) - pointer (8 bytes) +// haystack_len+8(FP) - length (8 bytes) +// haystack_cap+16(FP) - capacity (8 bytes, unused) +// needle1+24(FP) - first needle (1 byte) +// needle2+25(FP) - second needle (1 byte, then 6 bytes padding) +// ret+32(FP) - return value (8 bytes) +// +// Total argument frame: 40 bytes (24 slice + 1 + 1 + 6 padding + 8 ret) +TEXT ·memchr2AVX2(SB), NOSPLIT, $0-40 + // Load parameters + MOVQ haystack_base+0(FP), SI + MOVQ haystack_len+8(FP), DX + MOVBQZX needle1+24(FP), AX + MOVBQZX needle2+25(FP), BX + + // Empty check + TESTQ DX, DX + JZ not_found2 + + // Broadcast both needles + VMOVD AX, X0 + VPBROADCASTB X0, Y0 // Y0 = [needle1 × 32] + VMOVD BX, X1 + VPBROADCASTB X1, Y1 // Y1 = [needle2 × 32] + + // Save start pointer and compute the end + MOVQ SI, DI + LEAQ (SI)(DX*1), R8 + + CMPQ DX, $32 + JB tail_loop2 // sub-32 direct call: scalar + + LEAQ -32(R8), R12 // last valid 32-byte window base + LEAQ -128(R8), R11 // last valid 128-byte block base + CMPQ SI, R11 + JA loop32_2_entry + + BLOCKALIGN +loop128_2: + VMOVDQU (SI), Y2 + VMOVDQU 32(SI), Y3 + VMOVDQU 64(SI), Y4 + VMOVDQU 96(SI), Y5 + + VPCMPEQB Y0, Y2, Y6 + VPCMPEQB Y1, Y2, Y7 + VPOR Y6, Y7, Y2 // Y2 = matches in bytes 0-31 + VPCMPEQB Y0, Y3, Y6 + VPCMPEQB Y1, Y3, Y7 + VPOR Y6, Y7, Y3 // Y3 = matches in bytes 32-63 + VPCMPEQB Y0, Y4, Y6 + VPCMPEQB Y1, Y4, Y7 + VPOR Y6, Y7, Y4 // Y4 = matches in bytes 64-95 + VPCMPEQB Y0, Y5, Y6 + VPCMPEQB Y1, Y5, Y7 + VPOR Y6, Y7, Y5 // Y5 = matches in bytes 96-127 + + VPOR Y2, Y3, Y6 + VPOR Y4, Y5, Y7 + VPOR Y6, Y7, Y6 // Y6 = matches anywhere in the block + VPMOVMSKB Y6, CX + TESTL CX, CX + JNZ found_in_block2 + + ADDQ $128, SI + CMPQ SI, R11 + JBE loop128_2 + +loop32_2_entry: + CMPQ SI, R12 + JA last32_2 + +loop32_2: + VMOVDQU (SI), Y2 + VPCMPEQB Y0, Y2, Y3 + VPCMPEQB Y1, Y2, Y4 + VPOR Y3, Y4, Y3 + VPMOVMSKB Y3, CX + TESTL CX, CX + JNZ found_in_vector2 + + ADDQ $32, SI + CMPQ SI, R12 + JBE loop32_2 + +last32_2: + // Fewer than 32 bytes remain past SI; rescan the final window. + CMPQ SI, R8 + JAE not_found2 + MOVQ R12, SI + VMOVDQU (SI), Y2 + VPCMPEQB Y0, Y2, Y3 + VPCMPEQB Y1, Y2, Y4 + VPOR Y3, Y4, Y3 + VPMOVMSKB Y3, CX + TESTL CX, CX + JNZ found_in_vector2 + JMP not_found2 + +tail_loop2: + MOVBLZX (SI), CX + CMPB CL, AL // Compare with needle1 + JE found_scalar2 + CMPB CL, BL // Compare with needle2 + JE found_scalar2 + + INCQ SI + CMPQ SI, R8 + JB tail_loop2 + +not_found2: + MOVQ $-1, AX + MOVQ AX, ret+32(FP) + VZEROUPPER + RET + +found_in_block2: + // Locate the first hit by re-extracting the per-vector masks in + // address order; only one of the four can hold the lowest match. + VPMOVMSKB Y2, CX + TESTL CX, CX + JNZ found_in_vector2 + ADDQ $32, SI + VPMOVMSKB Y3, CX + TESTL CX, CX + JNZ found_in_vector2 + ADDQ $32, SI + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ found_in_vector2 + ADDQ $32, SI + VPMOVMSKB Y5, CX + +found_in_vector2: + BSFL CX, CX + SUBQ DI, SI + ADDQ SI, CX + MOVQ CX, ret+32(FP) + VZEROUPPER + RET + +found_scalar2: + SUBQ DI, SI + MOVQ SI, ret+32(FP) + VZEROUPPER + RET + +// func memchr3AVX2(haystack []byte, needle1, needle2, needle3 byte) int +// +// AVX2 kernel behind Memchr3 that searches for any of three bytes. Same +// skeleton as memchr2AVX2 with a third broadcast/compare. +// +// Parameters (FP offsets, ABI0; byte arguments packed into adjacent 1-byte +// slots after the slice header, then padded): +// haystack_base+0(FP) - pointer (8 bytes) +// haystack_len+8(FP) - length (8 bytes) +// haystack_cap+16(FP) - capacity (8 bytes, unused) +// needle1+24(FP) - first needle (1 byte) +// needle2+25(FP) - second needle (1 byte) +// needle3+26(FP) - third needle (1 byte, then 5 bytes padding) +// ret+32(FP) - return value (8 bytes) +// +// Total argument frame: 40 bytes (24 slice + 3 + 5 padding + 8 ret) +TEXT ·memchr3AVX2(SB), NOSPLIT, $0-40 + // Load parameters + MOVQ haystack_base+0(FP), SI + MOVQ haystack_len+8(FP), DX + MOVBQZX needle1+24(FP), AX + MOVBQZX needle2+25(FP), BX + MOVBQZX needle3+26(FP), R10 + + // Empty check + TESTQ DX, DX + JZ not_found3 + + // Broadcast all three needles + VMOVD AX, X0 + VPBROADCASTB X0, Y0 // Y0 = [needle1 × 32] + VMOVD BX, X1 + VPBROADCASTB X1, Y1 // Y1 = [needle2 × 32] + VMOVD R10, X2 + VPBROADCASTB X2, Y2 // Y2 = [needle3 × 32] + + // Save start pointer and compute the end + MOVQ SI, DI + LEAQ (SI)(DX*1), R8 + + CMPQ DX, $32 + JB tail_loop3 // sub-32 direct call: scalar + + LEAQ -32(R8), R12 // last valid 32-byte window base + LEAQ -128(R8), R11 // last valid 128-byte block base + CMPQ SI, R11 + JA loop32_3_entry + + BLOCKALIGN +loop128_3: + VMOVDQU (SI), Y3 + VMOVDQU 32(SI), Y4 + VMOVDQU 64(SI), Y5 + VMOVDQU 96(SI), Y6 + + VPCMPEQB Y0, Y3, Y7 + VPCMPEQB Y1, Y3, Y8 + VPCMPEQB Y2, Y3, Y9 + VPOR Y7, Y8, Y7 + VPOR Y7, Y9, Y3 // Y3 = matches in bytes 0-31 + VPCMPEQB Y0, Y4, Y7 + VPCMPEQB Y1, Y4, Y8 + VPCMPEQB Y2, Y4, Y9 + VPOR Y7, Y8, Y7 + VPOR Y7, Y9, Y4 // Y4 = matches in bytes 32-63 + VPCMPEQB Y0, Y5, Y7 + VPCMPEQB Y1, Y5, Y8 + VPCMPEQB Y2, Y5, Y9 + VPOR Y7, Y8, Y7 + VPOR Y7, Y9, Y5 // Y5 = matches in bytes 64-95 + VPCMPEQB Y0, Y6, Y7 + VPCMPEQB Y1, Y6, Y8 + VPCMPEQB Y2, Y6, Y9 + VPOR Y7, Y8, Y7 + VPOR Y7, Y9, Y6 // Y6 = matches in bytes 96-127 + + VPOR Y3, Y4, Y7 + VPOR Y5, Y6, Y8 + VPOR Y7, Y8, Y7 // Y7 = matches anywhere in the block + VPMOVMSKB Y7, CX + TESTL CX, CX + JNZ found_in_block3 + + ADDQ $128, SI + CMPQ SI, R11 + JBE loop128_3 + +loop32_3_entry: + CMPQ SI, R12 + JA last32_3 + +loop32_3: + VMOVDQU (SI), Y3 + VPCMPEQB Y0, Y3, Y4 + VPCMPEQB Y1, Y3, Y5 + VPCMPEQB Y2, Y3, Y6 + VPOR Y4, Y5, Y4 + VPOR Y4, Y6, Y4 + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ found_in_vector3 + + ADDQ $32, SI + CMPQ SI, R12 + JBE loop32_3 + +last32_3: + CMPQ SI, R8 + JAE not_found3 + MOVQ R12, SI + VMOVDQU (SI), Y3 + VPCMPEQB Y0, Y3, Y4 + VPCMPEQB Y1, Y3, Y5 + VPCMPEQB Y2, Y3, Y6 + VPOR Y4, Y5, Y4 + VPOR Y4, Y6, Y4 + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ found_in_vector3 + JMP not_found3 + +tail_loop3: + MOVBLZX (SI), CX + CMPB CL, AL // Compare with needle1 + JE found_scalar3 + CMPB CL, BL // Compare with needle2 + JE found_scalar3 + CMPB CL, R10B // Compare with needle3 + JE found_scalar3 + + INCQ SI + CMPQ SI, R8 + JB tail_loop3 + +not_found3: + MOVQ $-1, AX + MOVQ AX, ret+32(FP) + VZEROUPPER + RET + +found_in_block3: + VPMOVMSKB Y3, CX + TESTL CX, CX + JNZ found_in_vector3 + ADDQ $32, SI + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ found_in_vector3 + ADDQ $32, SI + VPMOVMSKB Y5, CX + TESTL CX, CX + JNZ found_in_vector3 + ADDQ $32, SI + VPMOVMSKB Y6, CX + +found_in_vector3: + BSFL CX, CX + SUBQ DI, SI + ADDQ SI, CX + MOVQ CX, ret+32(FP) + VZEROUPPER + RET + +found_scalar3: + SUBQ DI, SI + MOVQ SI, ret+32(FP) + VZEROUPPER + RET + +// func memchrPairAVX2(haystack []byte, byte1, byte2 byte, offset int) int +// +// AVX2 implementation of paired-byte search. Finds positions where byte1 +// appears at position i and byte2 appears at position i+offset. +// +// Algorithm: +// 1. Broadcast byte1 to YMM0, byte2 to YMM1 +// 2. For each 32-byte chunk at position p: +// - Load haystack[p:p+32], compare with byte1 → mask1 +// - Load haystack[p+offset:p+offset+32], compare with byte2 → mask2 +// - AND mask1, mask2 → combined mask (both bytes at correct distance) +// 3. First set bit in combined mask is the answer +// 4. The block loop runs the same AND over four chunk pairs at a time. +// 5. The final 1-31 pair positions are rescanned with one overlapping +// vector pair whose second load ends exactly at the buffer end; pair +// positions before it are known non-matching, so BSF stays exact. +// Inputs with fewer than offset+32 bytes — unreachable through the Go +// dispatch — take a scalar loop instead. +// +// Parameters (FP offsets, ABI0; the byte arguments are packed into +// adjacent 1-byte slots, then padded to align the int argument): +// haystack_base+0(FP) - pointer (8 bytes) +// haystack_len+8(FP) - length (8 bytes) +// haystack_cap+16(FP) - capacity (8 bytes, unused) +// byte1+24(FP) - first byte to find (1 byte) +// byte2+25(FP) - second byte to find (1 byte, then 6 bytes padding) +// offset+32(FP) - distance between byte1 and byte2 (8 bytes) +// ret+40(FP) - return value (8 bytes) +// +// Total argument frame: 48 bytes (24 slice + 1 + 1 + 6 padding + 8 + 8 ret) +TEXT ·memchrPairAVX2(SB), NOSPLIT, $0-48 + // Load parameters + MOVQ haystack_base+0(FP), SI // SI = haystack pointer + MOVQ haystack_len+8(FP), DX // DX = haystack length + MOVBQZX byte1+24(FP), AX // AX = byte1 + MOVBQZX byte2+25(FP), BX // BX = byte2 + MOVQ offset+32(FP), R10 // R10 = offset + + // Empty check and bounds check + TESTQ DX, DX + JZ not_found_pair + CMPQ R10, DX // offset >= length? + JAE not_found_pair + + // Broadcast both bytes + VMOVD AX, X0 + VPBROADCASTB X0, Y0 // Y0 = [byte1 × 32] + VMOVD BX, X1 + VPBROADCASTB X1, Y1 // Y1 = [byte2 × 32] + + // Save start pointer + MOVQ SI, DI // DI = haystack start + + // Calculate limits: + // - We need 32 bytes at position p (for byte1 check) + // - We need 32 bytes at position p+offset (for byte2 check) + // - So we need p + offset + 32 <= length + // - Which means p <= length - offset - 32 + MOVQ DX, R12 // R12 = length + SUBQ R10, R12 // R12 = length - offset + SUBQ $32, R12 // R12 = length - offset - 32 (last valid p) + JL scalar_entry_pair // sub-(offset+32) direct call: scalar + ADDQ SI, R12 // R12 = absolute last valid base + + LEAQ -96(R12), R11 // last valid 128-position block base + CMPQ SI, R11 + JA loop32_pair_entry + + BLOCKALIGN +loop128_pair: + // byte1 side: four consecutive 32-byte chunks + VMOVDQU (SI), Y2 + VMOVDQU 32(SI), Y3 + VMOVDQU 64(SI), Y4 + VMOVDQU 96(SI), Y5 + VPCMPEQB Y0, Y2, Y2 + VPCMPEQB Y0, Y3, Y3 + VPCMPEQB Y0, Y4, Y4 + VPCMPEQB Y0, Y5, Y5 + + // byte2 side: the same chunks shifted by offset + VMOVDQU (SI)(R10*1), Y6 + VMOVDQU 32(SI)(R10*1), Y7 + VMOVDQU 64(SI)(R10*1), Y8 + VMOVDQU 96(SI)(R10*1), Y9 + VPCMPEQB Y1, Y6, Y6 + VPCMPEQB Y1, Y7, Y7 + VPCMPEQB Y1, Y8, Y8 + VPCMPEQB Y1, Y9, Y9 + + VPAND Y2, Y6, Y2 // Y2 = pairs in positions 0-31 + VPAND Y3, Y7, Y3 // Y3 = pairs in positions 32-63 + VPAND Y4, Y8, Y4 // Y4 = pairs in positions 64-95 + VPAND Y5, Y9, Y5 // Y5 = pairs in positions 96-127 + + VPOR Y2, Y3, Y6 + VPOR Y4, Y5, Y7 + VPOR Y6, Y7, Y6 + VPMOVMSKB Y6, CX + TESTL CX, CX + JNZ found_in_block_pair + + ADDQ $128, SI + CMPQ SI, R11 + JBE loop128_pair + +loop32_pair_entry: + CMPQ SI, R12 + JA vector_tail_pair + +loop32_pair: + // Load 32 bytes at position p (for byte1) and at p+offset (for byte2) + VMOVDQU (SI), Y2 // Y2 = haystack[p:p+32] + VMOVDQU (SI)(R10*1), Y3 // Y3 = haystack[p+offset:p+offset+32] + VPCMPEQB Y0, Y2, Y4 // Y4 = positions where haystack[p+k] == byte1 + VPCMPEQB Y1, Y3, Y5 // Y5 = positions where haystack[p+offset+k] == byte2 + + // AND the results: bit k is set only if: + // - haystack[p+k] == byte1 + // - haystack[p+offset+k] == byte2 + VPAND Y4, Y5, Y4 // Y4 = combined mask + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ found_in_vector_pair + + ADDQ $32, SI + CMPQ SI, R12 + JBE loop32_pair + +vector_tail_pair: + // Fewer than 32 pair positions remain past SI. If any do, rescan the + // final 32-position window based at R12 = base+len-offset-32: its second + // load ends exactly at the buffer end, and pair positions before SI are + // known non-matching. + LEAQ (DI)(DX*1), R9 // R9 = buffer end + SUBQ R10, R9 // R9 = end of valid pair positions + CMPQ SI, R9 + JAE not_found_pair + MOVQ R12, SI // SI = base of the final window + VMOVDQU (SI), Y2 + VMOVDQU (SI)(R10*1), Y3 + VPCMPEQB Y0, Y2, Y4 + VPCMPEQB Y1, Y3, Y5 + VPAND Y4, Y5, Y4 + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ found_in_vector_pair + JMP not_found_pair + +scalar_entry_pair: + // Scalar path for direct calls with fewer than offset+32 bytes. + LEAQ (DI)(DX*1), R8 // R8 = end pointer + +tail_loop_pair: + // Check if SI + offset < end + LEAQ (SI)(R10*1), R9 // R9 = SI + offset + CMPQ R9, R8 + JAE not_found_pair // If SI + offset >= end, we're done + + // Load and compare both bytes + MOVBLZX (SI), CX // CX = haystack[SI] + CMPB CL, AL // Compare with byte1 + JNE tail_next_pair // Not byte1, skip + + // byte1 matches, check byte2 + MOVBLZX (SI)(R10*1), CX // CX = haystack[SI + offset] + CMPB CL, BL // Compare with byte2 + JE found_scalar_pair // Both match! + +tail_next_pair: + INCQ SI + JMP tail_loop_pair + +not_found_pair: + MOVQ $-1, AX + MOVQ AX, ret+40(FP) + VZEROUPPER + RET + +found_in_block_pair: + VPMOVMSKB Y2, CX + TESTL CX, CX + JNZ found_in_vector_pair + ADDQ $32, SI + VPMOVMSKB Y3, CX + TESTL CX, CX + JNZ found_in_vector_pair + ADDQ $32, SI + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ found_in_vector_pair + ADDQ $32, SI + VPMOVMSKB Y5, CX + +found_in_vector_pair: + // Match found in vector! CX contains mask + BSFL CX, CX // CX = index of first set bit (0-31) + SUBQ DI, SI // SI = offset from start to current chunk + ADDQ SI, CX // CX = absolute index + MOVQ CX, ret+40(FP) + VZEROUPPER + RET + +found_scalar_pair: + SUBQ DI, SI + MOVQ SI, ret+40(FP) + VZEROUPPER + RET diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class.go b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class.go new file mode 100644 index 00000000..95889a61 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class.go @@ -0,0 +1,177 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +package simd + +import ( + "github.com/gofiber/utils/v2/swar" +) + +// MemchrWord returns the index of the first word character — 'A'..'Z', +// 'a'..'z', '0'..'9', or '_' (the regex \w class) — in haystack, or -1 if +// none is present. +func MemchrWord(haystack []byte) int { + if len(haystack) == 0 { + return -1 + } + return memchrWordImpl(haystack) +} + +// MemchrNotWord is the complement of MemchrWord: it returns the index of the +// first byte that is NOT a word character, or -1 if every byte is one. +func MemchrNotWord(haystack []byte) int { + if len(haystack) == 0 { + return -1 + } + return memchrNotWordImpl(haystack) +} + +// MemchrInTable returns the index of the first byte b of haystack with +// table[b] true, or -1 if none matches or table is nil. +// +// This is a plain scalar table scan on every architecture — an arbitrary +// 256-entry membership test has no cheap SIMD or SWAR form — so unlike the +// rest of this package it carries no acceleration. For the \w class +// specifically, MemchrWord is much faster. +func MemchrInTable(haystack []byte, table *[256]bool) int { + if table == nil { + return -1 + } + for i, b := range haystack { + if table[b] { + return i + } + } + return -1 +} + +// MemchrNotInTable is the complement of MemchrInTable: it returns the index +// of the first byte b with table[b] false, or -1 if every byte is in the +// table or table is nil. Like MemchrInTable it is a plain scalar loop on +// every architecture. +func MemchrNotInTable(haystack []byte, table *[256]bool) int { + if table == nil { + return -1 + } + for i, b := range haystack { + if !table[b] { + return i + } + } + return -1 +} + +// isWordChar reports whether b is in [A-Za-z0-9_]. +func isWordChar(b byte) bool { + return (b >= 'A' && b <= 'Z') || + (b >= 'a' && b <= 'z') || + (b >= '0' && b <= '9') || + b == '_' +} + +// wordMask flags the lanes of w holding word characters, exactly per lane; +// bytes >= 0x80 never match. It is the swar.MatchRangeMask construction +// with the three range tests fused into one expression: +// +// - the ASCII gate (&^ w & HighBits) is applied once to the OR of the +// tests instead of once per test; +// - 'A'..'Z' and 'a'..'z' collapse into a single 'a'..'z' test on a +// case-folded copy (bit 5 set in every lane), which maps exactly the +// two letter ranges onto 0x61..0x7A; +// - '_' (0x5F) is the only byte besides DEL (0x7F) that folds to 0x7F, +// so "folded lane == 0x7F" is one biased add, and the DEL lanes are +// removed by w<<2, which moves each lane's bit 5 — clear for '_', set +// for DEL — into the bit-7 marker position. +// +// Every addition below adds a per-lane bias of at most 0x50 to lanes that +// are at most 0x7F, so no lane can carry into its neighbor and the bit-7 +// markers stay exact. That is 15 ALU operations per word instead of 26 +// for the four separate masks. +func wordMask(w uint64) uint64 { + b := w & swar.LowSeven + bf := b | 0x20*swar.Ones + letters := (bf + (0x80-'a')*swar.Ones) &^ (bf + (0x80-'z'-1)*swar.Ones) + digits := (b + (0x80-'0')*swar.Ones) &^ (b + (0x80-'9'-1)*swar.Ones) + underscore := (bf + swar.Ones) &^ (w << 2) + return (letters | digits | underscore) &^ w & swar.HighBits +} + +// memchrWordGeneric is the portable SWAR fallback for MemchrWord, finishing +// 8+ byte inputs with one overlapping word at n-8. +func memchrWordGeneric(haystack []byte) int { + n := len(haystack) + if n < swar.WordLen { + for i := range n { + if isWordChar(haystack[i]) { + return i + } + } + return -1 + } + i := 0 + for ; i+2*swar.WordLen <= n; i += 2 * swar.WordLen { + // Pinned window: see the note above isASCIIGeneric in ascii.go for + // why the loads use constant offsets into it. + w := haystack[i : i+2*swar.WordLen : i+2*swar.WordLen] + m0 := wordMask(swar.Load8(w, 0)) + m1 := wordMask(swar.Load8(w, swar.WordLen)) + if m0|m1 != 0 { + if m0 != 0 { + return i + swar.FirstLane(m0) + } + return i + swar.WordLen + swar.FirstLane(m1) + } + } + for ; i+swar.WordLen <= n; i += swar.WordLen { + if m := wordMask(swar.Load8(haystack, i)); m != 0 { + return i + swar.FirstLane(m) + } + } + if i == n { + return -1 + } + if m := wordMask(swar.Load8(haystack, n-swar.WordLen)); m != 0 { + return n - swar.WordLen + swar.FirstLane(m) + } + return -1 +} + +// memchrNotWordGeneric is the portable SWAR fallback for MemchrNotWord. +// wordMask is exact per lane, so its complement within the 0x80 lane +// markers is exact as well. +func memchrNotWordGeneric(haystack []byte) int { + n := len(haystack) + if n < swar.WordLen { + for i := range n { + if !isWordChar(haystack[i]) { + return i + } + } + return -1 + } + i := 0 + for ; i+2*swar.WordLen <= n; i += 2 * swar.WordLen { + w := haystack[i : i+2*swar.WordLen : i+2*swar.WordLen] + m0 := swar.HighBits &^ wordMask(swar.Load8(w, 0)) + m1 := swar.HighBits &^ wordMask(swar.Load8(w, swar.WordLen)) + if m0|m1 != 0 { + if m0 != 0 { + return i + swar.FirstLane(m0) + } + return i + swar.WordLen + swar.FirstLane(m1) + } + } + for ; i+swar.WordLen <= n; i += swar.WordLen { + if m := swar.HighBits &^ wordMask(swar.Load8(haystack, i)); m != 0 { + return i + swar.FirstLane(m) + } + } + if i == n { + return -1 + } + if m := swar.HighBits &^ wordMask(swar.Load8(haystack, n-swar.WordLen)); m != 0 { + return n - swar.WordLen + swar.FirstLane(m) + } + return -1 +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class_amd64.go b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class_amd64.go new file mode 100644 index 00000000..1a331a4d --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class_amd64.go @@ -0,0 +1,35 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +//go:build amd64 + +package simd + +// Assembly kernels implemented in memchr_class_amd64.s. Class membership +// is computed with a pair of VPSHUFB nibble lookups instead of one +// clamp-and-compare per range, and four 32-byte vectors are classified per +// iteration. +// +//go:noescape +func memchrWordAVX2(haystack []byte) int + +//go:noescape +func memchrNotWordAVX2(haystack []byte) int + +// memchrWordImpl dispatches to the AVX2 kernel for inputs large enough to +// amortize the vector setup. The caller guarantees a non-empty haystack. +func memchrWordImpl(haystack []byte) int { + if hasAVX2 && len(haystack) >= MinLen { + return memchrWordAVX2(haystack) + } + return memchrWordGeneric(haystack) +} + +// memchrNotWordImpl dispatches like memchrWordImpl. +func memchrNotWordImpl(haystack []byte) int { + if hasAVX2 && len(haystack) >= MinLen { + return memchrNotWordAVX2(haystack) + } + return memchrNotWordGeneric(haystack) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class_amd64.s b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class_amd64.s new file mode 100644 index 00000000..5faee304 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class_amd64.s @@ -0,0 +1,417 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. +// Modified: legacy-SSE MOVD/MOVQ register moves replaced with VEX-encoded +// VMOVD/VMOVQ to avoid AVX-SSE transition penalties on Intel CPUs, the +// scalar tail loops replaced with one overlapping vector at the buffer end +// for the MinLen+ inputs the Go dispatch guarantees, the per-range +// clamp-and-compare classifier replaced with a nibble table lookup, the +// 32-byte main loops replaced with 4x unrolled 128-byte blocks, and the +// block test reduced to one compare over the four raw class values. + +//go:build amd64 + +#include "textflag.h" +#include "block_align_amd64.h" + +// Classifying \w = [A-Za-z0-9_] with unsigned clamp-and-compare costs three +// VPMINUB/VPMAXUB/VPCMPEQB triples plus a VPCMPEQB for '_' and three VPORs: +// thirteen vector ops per 32 bytes, ten of them on the two general vector +// ALU ports. A nibble table does the same job in six (five in the block +// loops, which defer the compare to the reduced block value), and the two +// VPSHUFBs it adds run on the otherwise idle shuffle port. +// +// The table splits each byte into its high and low nibble. Every high +// nibble that contains word characters gets one bit: +// +// 0x3_ -> 0x01 0x4_ -> 0x02 0x5_ -> 0x04 0x6_ -> 0x08 0x7_ -> 0x10 +// +// and each low-nibble entry carries the set of high-nibble rows in which +// that low nibble is a word character, so a byte is a word character +// exactly when lowTable[lo] & highTable[hi] != 0: +// +// lo 0x0 -> 0x15 ('0', 'P', 'p') +// lo 0x1..0x9 -> 0x1F (digits and letters in every row) +// lo 0xA -> 0x1E ('J', 'Z', 'j', 'z' but not ':') +// lo 0xB..0xE -> 0x0A ('K'..'N', 'k'..'n' only) +// lo 0xF -> 0x0E ('O', '_', 'o') +// +// Bytes >= 0x80 need no separate guard: VPSHUFB zeroes any lane whose +// index byte has bit 7 set, so the low-nibble lookup already returns 0 for +// them and they classify as non-word, matching the SWAR fallback. +// +// Both kernels compute the same per-lane class value: the AND of the two +// lookups, which is nonzero exactly in the word-character lanes. The +// 32-byte paths compare it against zero at once, giving the "not a word +// character" mask (0xFF per non-word lane) that VPMOVMSKB can extract; +// memchrNotWord scans those bits directly and memchrWord inverts them +// with a single NOTL. The block loops instead reduce the four raw class +// values first and compare only the reduction: memchrNotWord takes the +// per-lane minimum (zero exactly where some vector has a non-word lane), +// memchrWord the per-lane OR (nonzero exactly where some vector has a +// word lane). That is three reductions and one compare per block instead +// of four compares and three reductions, and the four raw values stay +// live so the (rare) hit path can still compare them one at a time. + +// WORDBITS leaves in dst the class value of every lane of src: nonzero +// for a word character, zero otherwise. t0 is scratch; dst may alias src. +#define WORDBITS(src, dst, t0) \ + VPSRLW $4, src, t0; \ + VPAND Y2, t0, t0; \ + VPSHUFB t0, Y1, t0; \ + VPSHUFB src, Y0, dst; \ + VPAND t0, dst, dst + +// NOTWORD leaves in dst a mask with 0xFF in every lane of src that is NOT +// a word character. t0 is scratch; dst may alias src. +#define NOTWORD(src, dst, t0) \ + WORDBITS(src, dst, t0); \ + VPCMPEQB Y3, dst, dst + +// SETUPTABLES loads the nibble tables, the low-nibble mask and a zero +// vector into Y0-Y3. The tables are built from immediates rather than a +// RODATA section so the kernels stay position-independent and free of +// relocations. +#define SETUPTABLES \ + MOVQ $0x1F1F1F1F1F1F1F15, AX; \ + VMOVQ AX, X0; \ + MOVQ $0x0E0A0A0A0A1E1F1F, AX; \ + VPINSRQ $1, AX, X0, X0; \ + VINSERTI128 $1, X0, Y0, Y0; \ + MOVQ $0x1008040201000000, AX; \ + VMOVQ AX, X1; \ + VINSERTI128 $1, X1, Y1, Y1; \ + MOVQ $0x0F0F0F0F0F0F0F0F, AX; \ + VMOVQ AX, X2; \ + VPBROADCASTQ X2, Y2; \ + VPXOR Y3, Y3, Y3 + +// func memchrWordAVX2(haystack []byte) int +// +// AVX2 implementation to find the first word character [A-Za-z0-9_]. +// +// Parameters: +// haystack_base+0(FP) - pointer to haystack (8 bytes) +// haystack_len+8(FP) - length (8 bytes) +// haystack_cap+16(FP) - capacity (8 bytes, unused) +// ret+24(FP) - return value (8 bytes) +// +TEXT ·memchrWordAVX2(SB), NOSPLIT, $0-32 + // Load parameters + MOVQ haystack_base+0(FP), SI // SI = haystack pointer + MOVQ haystack_len+8(FP), DX // DX = length + + // Empty check + TESTQ DX, DX + JZ word_not_found + + // Save start for offset calculation and compute the end pointer + MOVQ SI, DI // DI = start pointer + LEAQ (SI)(DX*1), R8 // R8 = end pointer + + CMPQ DX, $32 + JB word_tail_loop // sub-32 direct call: scalar + + SETUPTABLES + + LEAQ -32(R8), R12 // last valid 32-byte window base + LEAQ -128(R8), R11 // last valid 128-byte block base + CMPQ SI, R11 + JA word_loop32_entry + + BLOCKALIGN_LONG +word_loop128: + VMOVDQU (SI), Y4 + VMOVDQU 32(SI), Y5 + VMOVDQU 64(SI), Y6 + VMOVDQU 96(SI), Y7 + WORDBITS(Y4, Y4, Y8) + WORDBITS(Y5, Y5, Y8) + WORDBITS(Y6, Y6, Y8) + WORDBITS(Y7, Y7, Y8) + + // A word character exists in the block iff some lane's class value is + // nonzero in some vector, so OR the four values and look for a lane + // that is not zero. + VPOR Y4, Y5, Y8 + VPOR Y6, Y7, Y9 + VPOR Y8, Y9, Y8 + VPCMPEQB Y3, Y8, Y8 + VPMOVMSKB Y8, CX + NOTL CX + TESTL CX, CX + JNZ word_found_in_block + + ADDQ $128, SI + CMPQ SI, R11 + JBE word_loop128 + +word_loop32_entry: + CMPQ SI, R12 + JA word_last32 + +word_loop32: + VMOVDQU (SI), Y4 + NOTWORD(Y4, Y4, Y8) + VPMOVMSKB Y4, CX + NOTL CX + TESTL CX, CX + JNZ word_found_in_vector + + ADDQ $32, SI + CMPQ SI, R12 + JBE word_loop32 + +word_last32: + // Fewer than 32 bytes remain past SI; rescan the final window. Lanes + // before SI were already resolved as non-matching, so BSF stays exact. + CMPQ SI, R8 + JAE word_not_found + MOVQ R12, SI + VMOVDQU (SI), Y4 + NOTWORD(Y4, Y4, Y8) + VPMOVMSKB Y4, CX + NOTL CX + TESTL CX, CX + JNZ word_found_in_vector + JMP word_not_found + +word_tail_loop: + MOVBLZX (SI), AX // AX = byte + + // Check [A-Z]: 65 <= b <= 90 + CMPB AL, $65 + JB word_check_lower + CMPB AL, $90 + JBE word_found_scalar + +word_check_lower: + // Check [a-z]: 97 <= b <= 122 + CMPB AL, $97 + JB word_check_digit + CMPB AL, $122 + JBE word_found_scalar + +word_check_digit: + // Check [0-9]: 48 <= b <= 57 + CMPB AL, $48 + JB word_check_underscore + CMPB AL, $57 + JBE word_found_scalar + +word_check_underscore: + // Check '_': 95 + CMPB AL, $95 + JE word_found_scalar + + // Not a word char, continue + INCQ SI + CMPQ SI, R8 + JB word_tail_loop + +word_not_found: + MOVQ $-1, AX + MOVQ AX, ret+24(FP) + VZEROUPPER + RET + +word_found_in_block: + // Locate the first hit by comparing and extracting the per-vector + // class values in address order; only one of the four can hold the + // lowest match. + VPCMPEQB Y3, Y4, Y4 + VPMOVMSKB Y4, CX + NOTL CX + TESTL CX, CX + JNZ word_found_in_vector + ADDQ $32, SI + VPCMPEQB Y3, Y5, Y5 + VPMOVMSKB Y5, CX + NOTL CX + TESTL CX, CX + JNZ word_found_in_vector + ADDQ $32, SI + VPCMPEQB Y3, Y6, Y6 + VPMOVMSKB Y6, CX + NOTL CX + TESTL CX, CX + JNZ word_found_in_vector + ADDQ $32, SI + VPCMPEQB Y3, Y7, Y7 + VPMOVMSKB Y7, CX + NOTL CX + +word_found_in_vector: + BSFL CX, BX + SUBQ DI, SI // SI = offset to chunk start + ADDQ SI, BX // BX = absolute position + MOVQ BX, ret+24(FP) + VZEROUPPER + RET + +word_found_scalar: + SUBQ DI, SI + MOVQ SI, ret+24(FP) + VZEROUPPER + RET + +// func memchrNotWordAVX2(haystack []byte) int +// +// AVX2 implementation to find the first non-word character, the complement +// of memchrWordAVX2. The nibble classifier already produces the non-word +// mask directly, so this kernel skips the NOTL memchrWordAVX2 needs. +// +TEXT ·memchrNotWordAVX2(SB), NOSPLIT, $0-32 + // Load parameters + MOVQ haystack_base+0(FP), SI + MOVQ haystack_len+8(FP), DX + + // Empty check + TESTQ DX, DX + JZ notword_not_found + + // Save start for offset calculation and compute the end pointer + MOVQ SI, DI + LEAQ (SI)(DX*1), R8 + + CMPQ DX, $32 + JB notword_tail_loop // sub-32 direct call: scalar + + SETUPTABLES + + LEAQ -32(R8), R12 + LEAQ -128(R8), R11 + CMPQ SI, R11 + JA notword_loop32_entry + + BLOCKALIGN_LONG +notword_loop128: + VMOVDQU (SI), Y4 + VMOVDQU 32(SI), Y5 + VMOVDQU 64(SI), Y6 + VMOVDQU 96(SI), Y7 + WORDBITS(Y4, Y4, Y8) + WORDBITS(Y5, Y5, Y8) + WORDBITS(Y6, Y6, Y8) + WORDBITS(Y7, Y7, Y8) + + // A non-word character exists in the block iff some lane's class + // value is zero in some vector, so take the per-lane minimum of the + // four values and look for a zero lane. + VPMINUB Y4, Y5, Y8 + VPMINUB Y6, Y7, Y9 + VPMINUB Y8, Y9, Y8 + VPCMPEQB Y3, Y8, Y8 + VPMOVMSKB Y8, CX + TESTL CX, CX + JNZ notword_found_in_block + + ADDQ $128, SI + CMPQ SI, R11 + JBE notword_loop128 + +notword_loop32_entry: + CMPQ SI, R12 + JA notword_last32 + +notword_loop32: + VMOVDQU (SI), Y4 + NOTWORD(Y4, Y4, Y8) + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ notword_found_in_vector + + ADDQ $32, SI + CMPQ SI, R12 + JBE notword_loop32 + +notword_last32: + CMPQ SI, R8 + JAE notword_not_found + MOVQ R12, SI + VMOVDQU (SI), Y4 + NOTWORD(Y4, Y4, Y8) + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ notword_found_in_vector + JMP notword_not_found + +notword_tail_loop: + MOVBLZX (SI), AX + + // Check if NOT a word char (inverse of word_tail_loop logic) + // Word chars: [A-Z], [a-z], [0-9], '_' + // If it's a word char, skip; if not, found + + // Check [A-Z]: 65 <= b <= 90 + CMPB AL, $65 + JB notword_check_lower_gap + CMPB AL, $90 + JBE notword_is_word // It's [A-Z], skip + +notword_check_lower_gap: + // Check [a-z]: 97 <= b <= 122 + CMPB AL, $97 + JB notword_check_digit_gap + CMPB AL, $122 + JBE notword_is_word // It's [a-z], skip + +notword_check_digit_gap: + // Check [0-9]: 48 <= b <= 57 + CMPB AL, $48 + JB notword_check_underscore_gap + CMPB AL, $57 + JBE notword_is_word // It's [0-9], skip + +notword_check_underscore_gap: + // Check '_': 95 + CMPB AL, $95 + JE notword_is_word // It's '_', skip + + // Not a word char - found! + JMP notword_found_scalar + +notword_is_word: + // It's a word char, continue searching + INCQ SI + CMPQ SI, R8 + JB notword_tail_loop + +notword_not_found: + MOVQ $-1, AX + MOVQ AX, ret+24(FP) + VZEROUPPER + RET + +notword_found_in_block: + VPCMPEQB Y3, Y4, Y4 + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ notword_found_in_vector + ADDQ $32, SI + VPCMPEQB Y3, Y5, Y5 + VPMOVMSKB Y5, CX + TESTL CX, CX + JNZ notword_found_in_vector + ADDQ $32, SI + VPCMPEQB Y3, Y6, Y6 + VPMOVMSKB Y6, CX + TESTL CX, CX + JNZ notword_found_in_vector + ADDQ $32, SI + VPCMPEQB Y3, Y7, Y7 + VPMOVMSKB Y7, CX + +notword_found_in_vector: + BSFL CX, BX + SUBQ DI, SI + ADDQ SI, BX + MOVQ BX, ret+24(FP) + VZEROUPPER + RET + +notword_found_scalar: + SUBQ DI, SI + MOVQ SI, ret+24(FP) + VZEROUPPER + RET diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class_other.go b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class_other.go new file mode 100644 index 00000000..2cd88cf7 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_class_other.go @@ -0,0 +1,17 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +//go:build !amd64 + +package simd + +// The portable implementations are the only ones off amd64. + +func memchrWordImpl(haystack []byte) int { + return memchrWordGeneric(haystack) +} + +func memchrNotWordImpl(haystack []byte) int { + return memchrNotWordGeneric(haystack) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit.go b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit.go new file mode 100644 index 00000000..02947406 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit.go @@ -0,0 +1,79 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +package simd + +import ( + "github.com/gofiber/utils/v2/swar" +) + +// MemchrDigit returns the index of the first ASCII digit '0'..'9' in +// haystack, or -1 if no digit is present. Only ASCII digits match; Unicode +// digit characters do not. +// +// On amd64 with AVX2 the range check runs on 32 bytes per vector, four +// vectors per iteration, which is useful for locating numeric fields +// (ports, lengths, IP octets) in request data. +func MemchrDigit(haystack []byte) int { + if len(haystack) == 0 { + return -1 + } + return memchrDigitImpl(haystack) +} + +// MemchrDigitAt is MemchrDigit(haystack[at:]) with the result translated +// back to an absolute index in haystack. It returns -1 when no digit is +// found or when at is out of bounds. +func MemchrDigitAt(haystack []byte, at int) int { + if at < 0 || at >= len(haystack) { + return -1 + } + pos := MemchrDigit(haystack[at:]) + if pos < 0 { + return -1 + } + return pos + at +} + +// memchrDigitGeneric is the portable SWAR fallback for MemchrDigit: a +// MatchRangeMask first-match scan (exact per lane; bytes >= 0x80 never +// match), two words per branch, finishing 8+ byte inputs with one +// overlapping word at n-8. +func memchrDigitGeneric(haystack []byte) int { + n := len(haystack) + if n < swar.WordLen { + for i, b := range haystack { + if b >= '0' && b <= '9' { + return i + } + } + return -1 + } + i := 0 + for ; i+2*swar.WordLen <= n; i += 2 * swar.WordLen { + // Pinned window: see the note above isASCIIGeneric in ascii.go for + // why the loads use constant offsets into it. + w := haystack[i : i+2*swar.WordLen : i+2*swar.WordLen] + m0 := swar.MatchRangeMask(swar.Load8(w, 0), '0', '9') + m1 := swar.MatchRangeMask(swar.Load8(w, swar.WordLen), '0', '9') + if m0|m1 != 0 { + if m0 != 0 { + return i + swar.FirstLane(m0) + } + return i + swar.WordLen + swar.FirstLane(m1) + } + } + for ; i+swar.WordLen <= n; i += swar.WordLen { + if m := swar.MatchRangeMask(swar.Load8(haystack, i), '0', '9'); m != 0 { + return i + swar.FirstLane(m) + } + } + if i == n { + return -1 + } + if m := swar.MatchRangeMask(swar.Load8(haystack, n-swar.WordLen), '0', '9'); m != 0 { + return n - swar.WordLen + swar.FirstLane(m) + } + return -1 +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit_amd64.go b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit_amd64.go new file mode 100644 index 00000000..13de5cc1 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit_amd64.go @@ -0,0 +1,23 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +//go:build amd64 + +package simd + +// memchrDigitAVX2 is implemented in memchr_digit_amd64.s. It finds bytes in +// ['0','9'] with one biased VPADDB and one signed VPCMPGTB per vector, four +// 32-byte vectors per iteration. +// +//go:noescape +func memchrDigitAVX2(haystack []byte) int + +// memchrDigitImpl dispatches to the AVX2 kernel for inputs large enough to +// amortize the vector setup. The caller guarantees a non-empty haystack. +func memchrDigitImpl(haystack []byte) int { + if hasAVX2 && len(haystack) >= MinLen { + return memchrDigitAVX2(haystack) + } + return memchrDigitGeneric(haystack) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit_amd64.s b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit_amd64.s new file mode 100644 index 00000000..69fe0eb7 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit_amd64.s @@ -0,0 +1,192 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. +// Modified: legacy-SSE MOVD/MOVQ register moves replaced with VEX-encoded +// VMOVD/VMOVQ to avoid AVX-SSE transition penalties on Intel CPUs, the +// scalar tail loop replaced with one overlapping vector at the buffer end +// for the MinLen+ inputs the Go dispatch guarantees, and the 32-byte main +// loop replaced with a 4x unrolled 128-byte block. + +//go:build amd64 + +#include "textflag.h" +#include "block_align_amd64.h" + +// DIGITS leaves in dst a mask with 0xFF in every lane of src holding an +// ASCII digit. t0 is scratch; dst may alias src. +// +// Y0 = [0x46 x 32] (0x7F - '9') Y1 = [0x75 x 32] ('0' + 0x46 - 1) +// +// A range test needs only one compare when the range is first slid up +// against the signed maximum: adding 0x46 maps '0'..'9' onto 0x76..0x7F, +// the ten largest positive int8 values, so a signed "> 0x75" is exact for +// every byte value. Everything above '9' lands in 0x80..0xFF and reads as +// negative, everything below '0' stays at or under 0x75, and the byte +// values from 0xBA up wrap around to 0x00..0x45, still under the +// threshold. The earlier two-compare form (> 0x2F, then not > 0x39, AND-ed +// with VPANDN) cost three vector ops and two scratch registers per vector; +// this is two ops and one. +#define DIGITS(src, dst, t0) \ + VPADDB Y0, src, t0; \ + VPCMPGTB Y1, t0, dst + +// func memchrDigitAVX2(haystack []byte) int +// +// AVX2 implementation of digit search that finds the first ASCII digit [0-9]. +// +// Algorithm for range check [0-9] (bytes 0x30-0x39): +// 1. Broadcast the 0x46 bias and the 0x75 threshold to YMM registers +// 2. Load 32 bytes from haystack +// 3. VPADDB: slide the digit range up to 0x76..0x7F +// 4. VPCMPGTB: signed compare against 0x75 (see DIGITS above) +// 5. VPMOVMSKB: extract 32-bit mask +// 6. BSFL: find first set bit +// +// The block loop runs steps 2-4 over four vectors, ORs the four masks and +// extracts once; the (rare) hit path re-extracts the per-vector masks in +// address order to locate the first digit. +// +// Parameters (FP offsets): +// haystack_base+0(FP) - pointer to haystack data (8 bytes) +// haystack_len+8(FP) - haystack length (8 bytes) +// haystack_cap+16(FP) - haystack capacity (8 bytes, unused but part of slice) +// ret+24(FP) - return value: index or -1 (8 bytes) +// +// Total argument frame size: 32 bytes (8+8+8+8) +TEXT ·memchrDigitAVX2(SB), NOSPLIT, $0-32 + // Load parameters + MOVQ haystack_base+0(FP), SI // SI = haystack pointer + MOVQ haystack_len+8(FP), DX // DX = haystack length + + // Empty haystack check + TESTQ DX, DX + JZ not_found + + // Prepare constants for range check ['0'-'9'] = [0x30-0x39]: + // the bias that slides the range up to 0x76..0x7F and the signed + // threshold just below it. + MOVQ $0x4646464646464646, AX + VMOVQ AX, X0 + VPBROADCASTQ X0, Y0 // Y0 = [0x46 x 32] + + MOVQ $0x7575757575757575, AX + VMOVQ AX, X1 + VPBROADCASTQ X1, Y1 // Y1 = [0x75 x 32] + + // Save start pointer for offset calculation, compute the end pointer + MOVQ SI, DI // DI = haystack start (preserved) + LEAQ (SI)(DX*1), R8 // R8 = SI + length (end pointer) + + CMPQ DX, $32 + JB tail_loop // sub-32 direct call: scalar + + LEAQ -32(R8), R12 // last valid 32-byte window base + LEAQ -128(R8), R11 // last valid 128-byte block base + CMPQ SI, R11 + JA loop32_entry + + BLOCKALIGN +loop128: + VMOVDQU (SI), Y2 + VMOVDQU 32(SI), Y3 + VMOVDQU 64(SI), Y4 + VMOVDQU 96(SI), Y5 + DIGITS(Y2, Y2, Y6) + DIGITS(Y3, Y3, Y6) + DIGITS(Y4, Y4, Y6) + DIGITS(Y5, Y5, Y6) + + VPOR Y2, Y3, Y6 + VPOR Y4, Y5, Y7 + VPOR Y6, Y7, Y6 + VPMOVMSKB Y6, CX + TESTL CX, CX + JNZ found_in_block + + ADDQ $128, SI + CMPQ SI, R11 + JBE loop128 + +loop32_entry: + CMPQ SI, R12 + JA last32 + +loop32: + VMOVDQU (SI), Y2 + DIGITS(Y2, Y2, Y6) + VPMOVMSKB Y2, CX + TESTL CX, CX + JNZ found_in_vector + + ADDQ $32, SI + CMPQ SI, R12 + JBE loop32 + +last32: + // Fewer than 32 bytes remain past SI; rescan the final window. Lanes + // before SI were already resolved as non-digits, so BSF stays exact. + CMPQ SI, R8 + JAE not_found + MOVQ R12, SI + VMOVDQU (SI), Y2 + DIGITS(Y2, Y2, Y6) + VPMOVMSKB Y2, CX + TESTL CX, CX + JNZ found_in_vector + JMP not_found + +tail_loop: + // Load one byte + MOVBLZX (SI), BX // BX = haystack[SI] (zero-extended) + + // Check if byte is in range ['0'-'9'] (0x30-0x39) + CMPB BL, $0x30 // Compare with '0' + JB tail_next // If < '0', not a digit + CMPB BL, $0x39 // Compare with '9' + JA tail_next // If > '9', not a digit + + // Found digit! + SUBQ DI, SI // SI = offset from start + MOVQ SI, ret+24(FP) // Return index + VZEROUPPER // Clear upper YMM bits (CRITICAL!) + RET + +tail_next: + // Advance to next byte + INCQ SI + CMPQ SI, R8 // Check if reached end + JB tail_loop // Continue if SI < end + +not_found: + // No digit found in entire haystack + MOVQ $-1, AX // Return -1 + MOVQ AX, ret+24(FP) + VZEROUPPER // Clear upper YMM bits (CRITICAL!) + RET + +found_in_block: + // Locate the first digit by re-extracting the per-vector masks in + // address order; only one of the four can hold the lowest match. + VPMOVMSKB Y2, CX + TESTL CX, CX + JNZ found_in_vector + ADDQ $32, SI + VPMOVMSKB Y3, CX + TESTL CX, CX + JNZ found_in_vector + ADDQ $32, SI + VPMOVMSKB Y4, CX + TESTL CX, CX + JNZ found_in_vector + ADDQ $32, SI + VPMOVMSKB Y5, CX + +found_in_vector: + // Digit found in vector! CX contains a 32-bit mask with set bits at + // digit positions; BSFL finds the index of the first one. + BSFL CX, BX // BX = index of first set bit (0-31) + SUBQ DI, SI // SI = offset from start to current chunk + ADDQ SI, BX // BX = absolute index + MOVQ BX, ret+24(FP) // Return index + VZEROUPPER // Clear upper YMM bits + RET diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit_other.go b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit_other.go new file mode 100644 index 00000000..9799c5f0 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_digit_other.go @@ -0,0 +1,12 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +//go:build !amd64 + +package simd + +// memchrDigitImpl uses the portable implementation off amd64. +func memchrDigitImpl(haystack []byte) int { + return memchrDigitGeneric(haystack) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memchr_other.go b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_other.go new file mode 100644 index 00000000..891be6f5 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memchr_other.go @@ -0,0 +1,21 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +//go:build !amd64 + +package simd + +// The portable SWAR implementations are the only ones off amd64. + +func memchr2Impl(haystack []byte, needle1, needle2 byte) int { + return memchr2Generic(haystack, needle1, needle2) +} + +func memchr3Impl(haystack []byte, needle1, needle2, needle3 byte) int { + return memchr3Generic(haystack, needle1, needle2, needle3) +} + +func memchrPairImpl(haystack []byte, byte1, byte2 byte, offset int) int { + return memchrPairGeneric(haystack, byte1, byte2, offset) +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/memmem.go b/src/vendor/github.com/gofiber/utils/v2/simd/memmem.go new file mode 100644 index 00000000..8059f005 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/memmem.go @@ -0,0 +1,162 @@ +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. + +package simd + +import ( + "bytes" +) + +// memmemMinPairedHaystack is the haystack size from which Memmem routes +// needles eligible for the paired prefilter through it instead of +// bytes.Index. bytes.Index brute-forces haystacks of up to 64 bytes with +// a vector kernel the prefilter cannot beat — Benchmark_Memmem_Prefilter +// shows the two level at 64B before SelectRareBytes is even paid — and +// from 65 bytes switches to a loop anchored on the needle's first byte, +// which is where a scan anchored on the needle's two rarest bytes at +// their exact distance pulls ahead. Benchmark_Memmem shows the resulting +// end-to-end routing; its 96B row is the band this constant opens up. +const memmemMinPairedHaystack = 65 + +// memmemMinSingleHaystack is the same routing point for needles that take +// the single rare-byte scan. That scan is far less selective (its false +// candidates need only one byte to match) and its verification is +// longer, so it needs more haystack to amortize the rare-byte selection +// and the candidate loop; 128 keeps a conservative margin over the band +// where Benchmark_Memmem_Prefilter's single rows trail bytes.Index. +const memmemMinSingleHaystack = 128 + +// memmemMaxPairNeedle is the needle length up to which the paired-byte +// prefilter beats a single rare-byte scan: short needles produce frequent +// single-byte false positives, and verifying them costs more than the second +// byte check saves. +const memmemMaxPairNeedle = 6 + +// memmemMaxMisses caps how many failed candidate verifications the +// prefilter loops tolerate before handing the search to bytes.Index. A +// pathological input (rare byte everywhere, long almost-matching needle) +// would otherwise cost O(len(haystack) * len(needle)); the cap bounds the +// wasted work at memmemMaxMisses needle comparisons, keeping the worst case +// at bytes.Index's O(n+m) plus a constant. +const memmemMaxMisses = 16 + +// Memmem returns the index of the first occurrence of needle in haystack, +// or -1 if needle is not present. An empty needle matches at index 0, +// mirroring bytes.Index. +// +// On amd64 with AVX2 it prefilters with the needle's rarest bytes (per +// ByteRank) and verifies only the candidate positions, which typically +// beats bytes.Index by a wide margin on large inputs: needles of 2-6 +// bytes containing two distinct byte values are scanned, on haystacks of +// 65+ bytes, for their two rarest values at the exact relative distance, +// while longer or single-valued needles are scanned, on haystacks of +// 128+ bytes, for the single rarest byte. In all other cases it delegates +// to bytes.Index directly, and the prefilter itself falls back to +// bytes.Index after a bounded number of failed candidate verifications, +// so the worst case stays within a constant of the stdlib's O(n+m). +func Memmem(haystack, needle []byte) int { + needleLen := len(needle) + if needleLen == 0 { + return 0 + } + if len(haystack) < needleLen { + return -1 + } + if needleLen == 1 { + return bytes.IndexByte(haystack, needle[0]) + } + if !hasAVX2 || len(haystack) < memmemMinPairedHaystack { + return bytes.Index(haystack, needle) + } + + var info RareByteInfo + pairable := needleLen <= memmemMaxPairNeedle + if pairable { + info = SelectRareBytes(needle) + // Distinct byte values imply distinct indices, so Byte1 != Byte2 + // alone guarantees the offset MemchrPair needs is >= 1. + if info.Byte1 != info.Byte2 { + return memmemPaired(haystack, needle, info) + } + } + if len(haystack) < memmemMinSingleHaystack { + return bytes.Index(haystack, needle) + } + if !pairable { + info = SelectRareBytes(needle) + } + return memmemSingle(haystack, needle, info.Byte1, info.Index1) +} + +// memmemPaired scans for the needle's two rarest bytes at their exact +// relative distance with MemchrPair and verifies each candidate. False +// candidates need both bytes at the right distance, so verification is +// rare; if it still misses too often, memmemFallback finishes the search. +func memmemPaired(haystack, needle []byte, info RareByteInfo) int { + byte1, idx1 := info.Byte1, info.Index1 + byte2, idx2 := info.Byte2, info.Index2 + if idx1 > idx2 { + byte1, byte2 = byte2, byte1 + idx1, idx2 = idx2, idx1 + } + offset := idx2 - idx1 + + misses := 0 + for start := 0; ; { + cand := MemchrPair(haystack[start:], byte1, byte2, offset) + if cand == -1 { + return -1 + } + // cand is the position of byte1; the needle would start idx1 earlier. + pos := start + cand - idx1 + if pos >= 0 && pos+len(needle) <= len(haystack) && + bytes.Equal(haystack[pos:pos+len(needle)], needle) { + return pos + } + start += cand + 1 + if misses++; misses >= memmemMaxMisses { + return memmemFallback(haystack, needle, start, idx1) + } + } +} + +// memmemSingle scans for the needle's rarest byte and verifies each +// candidate; for longer needles the rare byte alone is selective enough +// that the paired scan's second comparison stops paying for itself. Like +// memmemPaired it hands persistent misses to memmemFallback. +func memmemSingle(haystack, needle []byte, rareByte byte, rareIdx int) int { + misses := 0 + for start := 0; ; { + cand := bytes.IndexByte(haystack[start:], rareByte) + if cand == -1 { + return -1 + } + pos := start + cand - rareIdx + if pos >= 0 && pos+len(needle) <= len(haystack) && + bytes.Equal(haystack[pos:pos+len(needle)], needle) { + return pos + } + start += cand + 1 + if misses++; misses >= memmemMaxMisses { + return memmemFallback(haystack, needle, start, rareIdx) + } + } +} + +// memmemFallback finishes a prefiltered search with bytes.Index once the +// candidate loops exhaust their miss budget. Every anchor before start has +// been checked, and any remaining occurrence carries its anchor byte at +// anchorIdx, so it starts at or after start-anchorIdx; searching from there +// cannot skip a match or return one out of order. The subtraction is in +// fact defensive: start-1 is always an anchor at handover and anchorIdx is +// the anchor byte's first occurrence in the needle, so no remaining +// occurrence can start below start itself — resuming at start-anchorIdx +// keeps correctness independent of that selection detail. +func memmemFallback(haystack, needle []byte, start, anchorIdx int) int { + from := max(start-anchorIdx, 0) + if pos := bytes.Index(haystack[from:], needle); pos >= 0 { + return from + pos + } + return -1 +} diff --git a/src/vendor/github.com/gofiber/utils/v2/simd/simd.go b/src/vendor/github.com/gofiber/utils/v2/simd/simd.go new file mode 100644 index 00000000..a769f402 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/simd/simd.go @@ -0,0 +1,51 @@ +// Package simd provides SIMD-accelerated byte searching and validation +// primitives for the Fiber ecosystem: multi-needle scans, character-class +// scans, paired-byte scans, substring search, and ASCII validation. +// +// Acceleration comes in two tiers. The scan kernels — Memchr2, Memchr3, +// MemchrPair, MemchrDigit, MemchrWord, MemchrNotWord, IsASCII, +// FirstNonASCII, and CountNonASCII — dispatch to AVX2 assembly on amd64 +// CPUs (for inputs of MinLen+ bytes) and fall back to portable SWAR loops +// built on the swar package everywhere else. The kernels consume four +// 32-byte vectors per iteration. The first-match scans and IsASCII combine +// the per-vector masks, so a 128-byte block costs one mask extraction and +// one branch, and the scans that report a position then re-extract the +// four masks in address order to locate the hit. CountNonASCII is the +// exception: a count cannot be recovered from a combined mask, so its +// block loop accumulates per-lane counts in vector byte lanes and reduces +// them once at the end, and the remaining whole vectors are extracted and +// population-counted (which is why it, unlike the others, gates on POPCNT +// as well as AVX2). +// Memmem prefilters on amd64 — needles of 2-6 bytes containing two +// distinct values through the MemchrPair kernel from 65-byte haystacks, +// longer or single-valued needles through a single rare-byte +// bytes.IndexByte scan from 128 bytes — and delegates to bytes.Index for +// shorter haystacks or without AVX2. +// MemchrInTable/MemchrNotInTable are plain scalar loops on every +// architecture, since an arbitrary 256-entry membership test has no cheap +// vector form. Accelerated reports whether the AVX2 tier is active. +// Single-byte search is deliberately absent: bytes.IndexByte is already +// vector-accelerated by the Go runtime on all major architectures. +// +// Unlike the top-level utils helpers, this package operates on []byte only — +// it is the raw engine underneath the generic helpers. Callers holding a +// string can use the top-level generic functions instead of converting. +// +// Adapted from the coregex project, https://github.com/coregx/coregex +// (package simd), Copyright (c) 2025 Andrey Kolkov and contributors, +// MIT License. See the LICENSE file in this directory for the full text. +package simd + +// MinLen is the input length from which the AVX2 kernels engage on amd64: +// they consume whole 32-byte vectors, and below one vector their setup cost +// outweighs the win, so shorter inputs take the SWAR fallbacks. Callers +// that route between their own word loops and this package (as the +// top-level utils helpers do) should gate on this constant rather than +// hard-coding 32, so a retune here propagates everywhere. +const MinLen = 32 + +// Accelerated reports whether the AVX2 assembly kernels are in use on this +// CPU. When false, all functions use portable fallback implementations. +func Accelerated() bool { + return hasAVX2 +} diff --git a/src/vendor/github.com/gofiber/utils/v2/swar/swar.go b/src/vendor/github.com/gofiber/utils/v2/swar/swar.go index 6290a000..dcf7fa61 100644 --- a/src/vendor/github.com/gofiber/utils/v2/swar/swar.go +++ b/src/vendor/github.com/gofiber/utils/v2/swar/swar.go @@ -44,6 +44,22 @@ const ( // reslice pins the length so the constant-index reads are bounds-check free, // and the compiler fuses them into a single 8-byte load on little-endian // targets (verified for both the string and []byte instantiations). +// +// The reslice itself is still checked, against the backing array's +// capacity, which a loop condition written in terms of len does not imply. +// A loop that loads several words per iteration should therefore pin the +// whole group once and index into it with constants rather than call Load8 +// at a variable offset each time: +// +// for ; i+4*WordLen <= n; i += 4 * WordLen { +// w := b[i : i+4*WordLen : i+4*WordLen] +// acc := Load8(w, 0) | Load8(w, WordLen) | Load8(w, 2*WordLen) | Load8(w, 3*WordLen) +// // ... +// } +// +// That moves four checks and their empty-slice pointer clamps down to one +// per group; on []byte the three-index form pins the capacity too and +// removes the rest. It is worth 20-60% on the word loops in package simd. func Load8[S ~string | ~[]byte](s S, i int) uint64 { w := s[i : i+8] return uint64(w[0]) | @@ -94,11 +110,17 @@ func ToUpperWord(w uint64) uint64 { return w &^ (MatchRangeMask(w, 'a', 'z') >> 2) // clear bit 5 on matched lanes } -// ZeroLanes returns a mask whose lowest set lane is the lowest zero-byte -// lane of x; higher lanes may carry false positives (borrows propagate -// strictly upward from true zero lanes), and the mask is zero iff x has no -// zero byte. It is two ops cheaper than MatchByteMask, which makes it the -// right primitive for first-match scans, typically as +// ZeroLanes returns a mask flagging the zero-byte lanes of x. Three +// properties are part of the contract: the mask is zero iff x has no zero +// byte; the lowest set lane is always the lowest true zero lane; and every +// true zero lane has its high bit set — a 0x00 lane leaves the subtraction +// as 0xFF or 0xFE regardless of borrow-in, and &^ x keeps its high bit — +// so combining masks (OR for multi-needle scans, AND for pair scans, as +// simd.Memchr2 and simd.MemchrPair's fallbacks do) never loses a true +// match. Lanes above the first true zero may carry false positives +// (borrows propagate strictly upward), so anything beyond the lowest set +// lane must be re-verified. It is two ops cheaper than MatchByteMask, +// which makes it the right primitive for first-match scans, typically as // ZeroLanes(w ^ Broadcast(c)) with the broadcast hoisted out of the word // loop. Use MatchByteMask when every lane must be exact. func ZeroLanes(x uint64) uint64 { diff --git a/src/vendor/github.com/gofiber/utils/v2/url.go b/src/vendor/github.com/gofiber/utils/v2/url.go new file mode 100644 index 00000000..fd2bbcf5 --- /dev/null +++ b/src/vendor/github.com/gofiber/utils/v2/url.go @@ -0,0 +1,167 @@ +package utils + +import ( + "bytes" + "net/url" + "strings" + + "github.com/gofiber/utils/v2/internal/unsafeconv" +) + +// escapeMode selects between net/url's query-component and path-segment +// escaping dialects: only the query dialect maps '+' to space. +type escapeMode uint8 + +const ( + escapeQuery escapeMode = iota + escapePath +) + +// upperHexDigits is the escape alphabet used by the Append*Escape helpers, +// matching net/url. +const upperHexDigits = "0123456789ABCDEF" + +// unhexTable maps an ASCII byte to its hexadecimal digit value, or 0xFF for +// bytes that are not hex digits. +var unhexTable = buildUnhexTable() + +func buildUnhexTable() [256]byte { + var t [256]byte + for i := range t { + t[i] = 0xFF + } + for c := byte('0'); c <= '9'; c++ { + t[c] = c - '0' + } + for c := byte('a'); c <= 'f'; c++ { + t[c] = c - 'a' + 10 + } + for c := byte('A'); c <= 'F'; c++ { + t[c] = c - 'A' + 10 + } + return t +} + +// queryNoEscapeTable and pathNoEscapeTable flag the bytes net/url leaves +// verbatim in query components and path segments respectively. They are +// derived from net/url's shouldEscape rules and pinned to them by +// exhaustive per-byte tests. Path segments additionally keep the sub-delims +// net/url's encodePathSegment mode does not escape. +var ( + queryNoEscapeTable = buildNoEscapeTable("") + pathNoEscapeTable = buildNoEscapeTable("$&+:=@") +) + +// buildNoEscapeTable flags the RFC 3986 unreserved bytes plus alsoSafe as +// not needing escape. +func buildNoEscapeTable(alsoSafe string) [256]bool { + var t [256]bool + for i := range 256 { + c := byte(i) + t[i] = c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || + c == '-' || c == '_' || c == '.' || c == '~' || + strings.IndexByte(alsoSafe, c) >= 0 + } + return t +} + +// AppendQueryEscape appends the percent-encoded form of s to dst and returns +// the extended slice. The output is byte-identical to net/url.QueryEscape: +// unreserved bytes pass through, space becomes '+', everything else becomes +// %XX with uppercase hex. dst must not alias s: escaping can grow the input, +// so in-place operation is impossible. +func AppendQueryEscape[S byteSeq](dst []byte, s S) []byte { + return appendEscape(dst, unsafeconv.Bytes(s), &queryNoEscapeTable, escapeQuery) +} + +// AppendPathEscape appends the percent-encoded path-segment form of s to dst +// and returns the extended slice. The output is byte-identical to +// net/url.PathEscape; the aliasing rule matches AppendQueryEscape. +func AppendPathEscape[S byteSeq](dst []byte, s S) []byte { + return appendEscape(dst, unsafeconv.Bytes(s), &pathNoEscapeTable, escapePath) +} + +// appendEscape copies runs of unescaped bytes wholesale and expands the rest, +// in one pass with no intermediate allocation — unlike net/url, which counts +// in a first pass and then rebuilds the string byte by byte. +func appendEscape(dst, s []byte, noEscape *[256]bool, mode escapeMode) []byte { + i, n := 0, len(s) + for i < n { + j := i + for j < n && noEscape[s[j]] { + j++ + } + dst = append(dst, s[i:j]...) + if j == n { + break + } + if c := s[j]; mode == escapeQuery && c == ' ' { + dst = append(dst, '+') + } else { + dst = append(dst, '%', upperHexDigits[c>>4], upperHexDigits[c&0x0F]) + } + i = j + 1 + } + return dst +} + +// AppendQueryUnescape appends the decoded form of the query component s to +// dst and returns the extended slice, converting '+' to space and %XX to the +// byte it encodes, exactly like net/url.QueryUnescape including its +// url.EscapeError values for malformed escapes. On error the returned slice +// is dst with its original length (its backing array may still have been +// reallocated by growth). Decoding never grows the input, so dst may be +// s[:0] on a common backing array to decode in place; any other overlap is +// invalid. Note that an in-place decode that fails has already overwritten +// the prefix of s before the malformed escape with decoded bytes — treat s +// as consumed once an in-place decode starts, error or not. +func AppendQueryUnescape[S byteSeq](dst []byte, s S) ([]byte, error) { + return appendUnescape(dst, unsafeconv.Bytes(s), escapeQuery) +} + +// AppendPathUnescape appends the decoded form of the path component s to dst +// and returns the extended slice, decoding %XX and leaving '+' verbatim, +// exactly like net/url.PathUnescape. Error and aliasing behavior match +// AppendQueryUnescape. +func AppendPathUnescape[S byteSeq](dst []byte, s S) ([]byte, error) { + return appendUnescape(dst, unsafeconv.Bytes(s), escapePath) +} + +// appendUnescape jumps between escape sites with vectorized scans — +// IndexAny2 (SWAR/AVX2) when '+' also needs rewriting, bytes.IndexByte +// otherwise — and copies the clean spans between them wholesale, so input +// without escapes costs one scan and one copy. +func appendUnescape(dst, s []byte, mode escapeMode) ([]byte, error) { + off := len(dst) + i, n := 0, len(s) + for i < n { + var j int + if mode == escapeQuery { + j = IndexAny2(s[i:], '%', '+') + } else { + j = bytes.IndexByte(s[i:], '%') + } + if j < 0 { + return append(dst, s[i:]...), nil + } + j += i + dst = append(dst, s[i:j]...) + if s[j] == '+' { + dst = append(dst, ' ') + i = j + 1 + continue + } + // s[j] == '%': the error substrings below match net/url's unescape. + if j+2 >= n { + return dst[:off], url.EscapeError(s[j:]) + } + hi := unhexTable[s[j+1]] + lo := unhexTable[s[j+2]] + if hi > 0x0F || lo > 0x0F { + return dst[:off], url.EscapeError(s[j : j+3]) + } + dst = append(dst, hi<<4|lo) + i = j + 3 + } + return dst, nil +} diff --git a/src/vendor/github.com/klauspost/compress/README.md b/src/vendor/github.com/klauspost/compress/README.md index 0e9f170d..bf31b905 100644 --- a/src/vendor/github.com/klauspost/compress/README.md +++ b/src/vendor/github.com/klauspost/compress/README.md @@ -6,7 +6,9 @@ This package provides various compression algorithms. * [S2](https://github.com/klauspost/compress/tree/master/s2#s2-compression) is a high performance replacement for Snappy. * Optimized [deflate](https://godoc.org/github.com/klauspost/compress/flate) packages which can be used as a dropin replacement for [gzip](https://godoc.org/github.com/klauspost/compress/gzip), [zip](https://godoc.org/github.com/klauspost/compress/zip) and [zlib](https://godoc.org/github.com/klauspost/compress/zlib). * [snappy](https://github.com/klauspost/compress/tree/master/snappy) is a drop-in replacement for `github.com/golang/snappy` offering better compression and concurrent streams. +* [lzw](https://github.com/klauspost/compress/tree/master/lzw) is a drop-in replacement for `compress/lzw` with 1.4-4x faster decompression and 1.1-2.7x faster compression, depending on the data. * [huff0](https://github.com/klauspost/compress/tree/master/huff0) and [FSE](https://github.com/klauspost/compress/tree/master/fse) implementations for raw entropy encoding. +* [Xpress](https://github.com/klauspost/compress/tree/master/xpress) decompression of the Microsoft XPRESS (MS-XCA) plain LZ77 and LZ77+Huffman formats (the LZ77+Huffman variant is the one used in WIM images and Windows Compact OS / WOF data). * [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp) Provides client and server wrappers for handling gzipped/zstd HTTP requests efficiently. * [pgzip](https://github.com/klauspost/pgzip) is a separate package that provides a very fast parallel gzip implementation. diff --git a/src/vendor/github.com/klauspost/compress/flate/deflate.go b/src/vendor/github.com/klauspost/compress/flate/deflate.go index 57d17eea..73d81088 100644 --- a/src/vendor/github.com/klauspost/compress/flate/deflate.go +++ b/src/vendor/github.com/klauspost/compress/flate/deflate.go @@ -260,6 +260,7 @@ func (d *compressor) fillWindow(b []byte) { } // Update window information. d.windowEnd += n + d.blockStart = d.windowEnd s.index = n } diff --git a/src/vendor/github.com/klauspost/compress/flate/fast_encoder.go b/src/vendor/github.com/klauspost/compress/flate/fast_encoder.go index 791c9dcb..a8cdc5c9 100644 --- a/src/vendor/github.com/klauspost/compress/flate/fast_encoder.go +++ b/src/vendor/github.com/klauspost/compress/flate/fast_encoder.go @@ -9,6 +9,7 @@ import ( "fmt" "github.com/klauspost/compress/internal/le" + "github.com/klauspost/compress/internal/regmask" ) type fastEnc interface { @@ -108,7 +109,7 @@ type tableEntryPrev struct { // hash7 returns the hash of the lowest 7 bytes of u to fit in a hash table with h bits. // Preferably h should be a constant and should always be <64. func hash7(u uint64, h uint8) uint32 { - return uint32(((u << (64 - 56)) * prime7bytes) >> ((64 - h) & reg8SizeMask64)) + return uint32(((u << (64 - 56)) * prime7bytes) >> ((64 - h) & regmask.Shift64ByUint8)) } // hashLen returns a hash of the lowest mls bytes of with length output bits. diff --git a/src/vendor/github.com/klauspost/compress/flate/inflate.go b/src/vendor/github.com/klauspost/compress/flate/inflate.go index 39dd683b..ad0ad3e2 100644 --- a/src/vendor/github.com/klauspost/compress/flate/inflate.go +++ b/src/vendor/github.com/klauspost/compress/flate/inflate.go @@ -14,6 +14,8 @@ import ( "io" "math/bits" "sync" + + "github.com/klauspost/compress/internal/regmask" ) const ( @@ -557,8 +559,8 @@ func (f *decompressor) readHuffman() error { return err } } - rep += int(f.b & uint32(1<<(nb®SizeMaskUint32)-1)) - f.b >>= nb & regSizeMaskUint32 + rep += int(f.b & uint32(1<<(nb®mask.Shift32ByUint)-1)) + f.b >>= nb & regmask.Shift32ByUint f.nb -= nb if i+rep > n { if debugDecode { @@ -731,7 +733,7 @@ func (f *decompressor) moreBits() error { return noEOF(err) } f.roffset++ - f.b |= uint32(c) << (f.nb & regSizeMaskUint32) + f.b |= uint32(c) << (f.nb & regmask.Shift32ByUint) f.nb += 8 return nil } @@ -756,7 +758,7 @@ func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) { return 0, noEOF(err) } f.roffset++ - b |= uint32(c) << (nb & regSizeMaskUint32) + b |= uint32(c) << (nb & regmask.Shift32ByUint) nb += 8 } chunk := h.chunks[b&(huffmanNumChunks-1)] @@ -775,7 +777,7 @@ func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) { f.err = CorruptInputError(f.roffset) return 0, f.err } - f.b = b >> (n & regSizeMaskUint32) + f.b = b >> (n & regmask.Shift32ByUint) f.nb = nb - n return int(chunk >> huffmanValueShift), nil } diff --git a/src/vendor/github.com/klauspost/compress/flate/inflate_gen.go b/src/vendor/github.com/klauspost/compress/flate/inflate_gen.go index e80f1965..3bc1cf1c 100644 --- a/src/vendor/github.com/klauspost/compress/flate/inflate_gen.go +++ b/src/vendor/github.com/klauspost/compress/flate/inflate_gen.go @@ -8,6 +8,8 @@ import ( "fmt" "math/bits" "strings" + + "github.com/klauspost/compress/internal/regmask" ) func peekBufio(fr *bufio.Reader) ([]byte, error) { @@ -62,7 +64,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } chunk := f.hl.chunks[fb&(huffmanNumChunks-1)] @@ -80,7 +82,7 @@ readLiteral: f.err = CorruptInputError(f.roffset) return } - fb = fb >> (n & regSizeMaskUint32) + fb = fb >> (n & regmask.Shift32ByUint) fnb = fnb - n v = int(chunk >> huffmanValueShift) break @@ -122,11 +124,11 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } length += int(fb & bitMask32[n]) - fb >>= n & regSizeMaskUint32 + fb >>= n & regmask.Shift32ByUint fnb -= n default: if debugDecode { @@ -150,7 +152,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } dist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3))) @@ -174,7 +176,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } chunk := f.hd.chunks[fb&(huffmanNumChunks-1)] @@ -192,7 +194,7 @@ readLiteral: f.err = CorruptInputError(f.roffset) return } - fb = fb >> (n & regSizeMaskUint32) + fb = fb >> (n & regmask.Shift32ByUint) fnb = fnb - n dist = uint32(chunk >> huffmanValueShift) break @@ -206,7 +208,7 @@ readLiteral: case dist < maxNumDist: nb := uint(dist-2) >> 1 // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << (nb & regSizeMaskUint32) + extra := (dist & 1) << (nb & regmask.Shift32ByUint) for fnb < nb { c, err := fr.ReadByte() if err != nil { @@ -218,13 +220,13 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } extra |= fb & bitMask32[nb] - fb >>= nb & regSizeMaskUint32 + fb >>= nb & regmask.Shift32ByUint fnb -= nb - dist = 1<<((nb+1)®SizeMaskUint32) + 1 + extra + dist = 1<<((nb+1)®mask.Shift32ByUint) + 1 + extra // slower: dist = bitMask32[nb+1] + 2 + extra default: f.b, f.nb = fb, fnb @@ -313,7 +315,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } chunk := f.hl.chunks[fb&(huffmanNumChunks-1)] @@ -331,7 +333,7 @@ readLiteral: f.err = CorruptInputError(f.roffset) return } - fb = fb >> (n & regSizeMaskUint32) + fb = fb >> (n & regmask.Shift32ByUint) fnb = fnb - n v = int(chunk >> huffmanValueShift) break @@ -373,11 +375,11 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } length += int(fb & bitMask32[n]) - fb >>= n & regSizeMaskUint32 + fb >>= n & regmask.Shift32ByUint fnb -= n default: if debugDecode { @@ -401,7 +403,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } dist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3))) @@ -425,7 +427,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } chunk := f.hd.chunks[fb&(huffmanNumChunks-1)] @@ -443,7 +445,7 @@ readLiteral: f.err = CorruptInputError(f.roffset) return } - fb = fb >> (n & regSizeMaskUint32) + fb = fb >> (n & regmask.Shift32ByUint) fnb = fnb - n dist = uint32(chunk >> huffmanValueShift) break @@ -457,7 +459,7 @@ readLiteral: case dist < maxNumDist: nb := uint(dist-2) >> 1 // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << (nb & regSizeMaskUint32) + extra := (dist & 1) << (nb & regmask.Shift32ByUint) for fnb < nb { c, err := fr.ReadByte() if err != nil { @@ -469,13 +471,13 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } extra |= fb & bitMask32[nb] - fb >>= nb & regSizeMaskUint32 + fb >>= nb & regmask.Shift32ByUint fnb -= nb - dist = 1<<((nb+1)®SizeMaskUint32) + 1 + extra + dist = 1<<((nb+1)®mask.Shift32ByUint) + 1 + extra // slower: dist = bitMask32[nb+1] + 2 + extra default: f.b, f.nb = fb, fnb @@ -573,7 +575,7 @@ readLiteral: c := pbuf[pos] pos++ f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } chunk := f.hl.chunks[fb&(huffmanNumChunks-1)] @@ -592,7 +594,7 @@ readLiteral: f.err = CorruptInputError(f.roffset) return } - fb = fb >> (n & regSizeMaskUint32) + fb = fb >> (n & regmask.Shift32ByUint) fnb = fnb - n v = int(chunk >> huffmanValueShift) break @@ -643,11 +645,11 @@ readLiteral: c := pbuf[pos] pos++ f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } length += int(fb & bitMask32[n]) - fb >>= n & regSizeMaskUint32 + fb >>= n & regmask.Shift32ByUint fnb -= n default: fr.Discard(pos) @@ -679,7 +681,7 @@ readLiteral: c := pbuf[pos] pos++ f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } dist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3))) @@ -710,7 +712,7 @@ readLiteral: c := pbuf[pos] pos++ f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } chunk := f.hd.chunks[fb&(huffmanNumChunks-1)] @@ -729,7 +731,7 @@ readLiteral: f.err = CorruptInputError(f.roffset) return } - fb = fb >> (n & regSizeMaskUint32) + fb = fb >> (n & regmask.Shift32ByUint) fnb = fnb - n dist = uint32(chunk >> huffmanValueShift) break @@ -743,7 +745,7 @@ readLiteral: case dist < maxNumDist: nb := uint(dist-2) >> 1 // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << (nb & regSizeMaskUint32) + extra := (dist & 1) << (nb & regmask.Shift32ByUint) for fnb < nb { if pos >= len(pbuf) { fr.Discard(pos) @@ -762,13 +764,13 @@ readLiteral: c := pbuf[pos] pos++ f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } extra |= fb & bitMask32[nb] - fb >>= nb & regSizeMaskUint32 + fb >>= nb & regmask.Shift32ByUint fnb -= nb - dist = 1<<((nb+1)®SizeMaskUint32) + 1 + extra + dist = 1<<((nb+1)®mask.Shift32ByUint) + 1 + extra // slower: dist = bitMask32[nb+1] + 2 + extra default: fr.Discard(pos) @@ -860,7 +862,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } chunk := f.hl.chunks[fb&(huffmanNumChunks-1)] @@ -878,7 +880,7 @@ readLiteral: f.err = CorruptInputError(f.roffset) return } - fb = fb >> (n & regSizeMaskUint32) + fb = fb >> (n & regmask.Shift32ByUint) fnb = fnb - n v = int(chunk >> huffmanValueShift) break @@ -920,11 +922,11 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } length += int(fb & bitMask32[n]) - fb >>= n & regSizeMaskUint32 + fb >>= n & regmask.Shift32ByUint fnb -= n default: if debugDecode { @@ -948,7 +950,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } dist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3))) @@ -972,7 +974,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } chunk := f.hd.chunks[fb&(huffmanNumChunks-1)] @@ -990,7 +992,7 @@ readLiteral: f.err = CorruptInputError(f.roffset) return } - fb = fb >> (n & regSizeMaskUint32) + fb = fb >> (n & regmask.Shift32ByUint) fnb = fnb - n dist = uint32(chunk >> huffmanValueShift) break @@ -1004,7 +1006,7 @@ readLiteral: case dist < maxNumDist: nb := uint(dist-2) >> 1 // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << (nb & regSizeMaskUint32) + extra := (dist & 1) << (nb & regmask.Shift32ByUint) for fnb < nb { c, err := fr.ReadByte() if err != nil { @@ -1016,13 +1018,13 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } extra |= fb & bitMask32[nb] - fb >>= nb & regSizeMaskUint32 + fb >>= nb & regmask.Shift32ByUint fnb -= nb - dist = 1<<((nb+1)®SizeMaskUint32) + 1 + extra + dist = 1<<((nb+1)®mask.Shift32ByUint) + 1 + extra // slower: dist = bitMask32[nb+1] + 2 + extra default: f.b, f.nb = fb, fnb @@ -1111,7 +1113,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } chunk := f.hl.chunks[fb&(huffmanNumChunks-1)] @@ -1129,7 +1131,7 @@ readLiteral: f.err = CorruptInputError(f.roffset) return } - fb = fb >> (n & regSizeMaskUint32) + fb = fb >> (n & regmask.Shift32ByUint) fnb = fnb - n v = int(chunk >> huffmanValueShift) break @@ -1171,11 +1173,11 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } length += int(fb & bitMask32[n]) - fb >>= n & regSizeMaskUint32 + fb >>= n & regmask.Shift32ByUint fnb -= n default: if debugDecode { @@ -1199,7 +1201,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } dist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3))) @@ -1223,7 +1225,7 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } chunk := f.hd.chunks[fb&(huffmanNumChunks-1)] @@ -1241,7 +1243,7 @@ readLiteral: f.err = CorruptInputError(f.roffset) return } - fb = fb >> (n & regSizeMaskUint32) + fb = fb >> (n & regmask.Shift32ByUint) fnb = fnb - n dist = uint32(chunk >> huffmanValueShift) break @@ -1255,7 +1257,7 @@ readLiteral: case dist < maxNumDist: nb := uint(dist-2) >> 1 // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << (nb & regSizeMaskUint32) + extra := (dist & 1) << (nb & regmask.Shift32ByUint) for fnb < nb { c, err := fr.ReadByte() if err != nil { @@ -1267,13 +1269,13 @@ readLiteral: return } f.roffset++ - fb |= uint32(c) << (fnb & regSizeMaskUint32) + fb |= uint32(c) << (fnb & regmask.Shift32ByUint) fnb += 8 } extra |= fb & bitMask32[nb] - fb >>= nb & regSizeMaskUint32 + fb >>= nb & regmask.Shift32ByUint fnb -= nb - dist = 1<<((nb+1)®SizeMaskUint32) + 1 + extra + dist = 1<<((nb+1)®mask.Shift32ByUint) + 1 + extra // slower: dist = bitMask32[nb+1] + 2 + extra default: f.b, f.nb = fb, fnb diff --git a/src/vendor/github.com/klauspost/compress/flate/regmask_amd64.go b/src/vendor/github.com/klauspost/compress/flate/regmask_amd64.go deleted file mode 100644 index 6ed28061..00000000 --- a/src/vendor/github.com/klauspost/compress/flate/regmask_amd64.go +++ /dev/null @@ -1,37 +0,0 @@ -package flate - -const ( - // Masks for shifts with register sizes of the shift value. - // This can be used to work around the x86 design of shifting by mod register size. - // It can be used when a variable shift is always smaller than the register size. - - // reg8SizeMaskX - shift value is 8 bits, shifted is X - reg8SizeMask8 = 7 - reg8SizeMask16 = 15 - reg8SizeMask32 = 31 - reg8SizeMask64 = 63 - - // reg16SizeMaskX - shift value is 16 bits, shifted is X - reg16SizeMask8 = reg8SizeMask8 - reg16SizeMask16 = reg8SizeMask16 - reg16SizeMask32 = reg8SizeMask32 - reg16SizeMask64 = reg8SizeMask64 - - // reg32SizeMaskX - shift value is 32 bits, shifted is X - reg32SizeMask8 = reg8SizeMask8 - reg32SizeMask16 = reg8SizeMask16 - reg32SizeMask32 = reg8SizeMask32 - reg32SizeMask64 = reg8SizeMask64 - - // reg64SizeMaskX - shift value is 64 bits, shifted is X - reg64SizeMask8 = reg8SizeMask8 - reg64SizeMask16 = reg8SizeMask16 - reg64SizeMask32 = reg8SizeMask32 - reg64SizeMask64 = reg8SizeMask64 - - // regSizeMaskUintX - shift value is uint, shifted is X - regSizeMaskUint8 = reg8SizeMask8 - regSizeMaskUint16 = reg8SizeMask16 - regSizeMaskUint32 = reg8SizeMask32 - regSizeMaskUint64 = reg8SizeMask64 -) diff --git a/src/vendor/github.com/klauspost/compress/flate/regmask_other.go b/src/vendor/github.com/klauspost/compress/flate/regmask_other.go deleted file mode 100644 index e62caf71..00000000 --- a/src/vendor/github.com/klauspost/compress/flate/regmask_other.go +++ /dev/null @@ -1,39 +0,0 @@ -//go:build !amd64 - -package flate - -const ( - // Masks for shifts with register sizes of the shift value. - // This can be used to work around the x86 design of shifting by mod register size. - // It can be used when a variable shift is always smaller than the register size. - - // reg8SizeMaskX - shift value is 8 bits, shifted is X - reg8SizeMask8 = 0xff - reg8SizeMask16 = 0xff - reg8SizeMask32 = 0xff - reg8SizeMask64 = 0xff - - // reg16SizeMaskX - shift value is 16 bits, shifted is X - reg16SizeMask8 = 0xffff - reg16SizeMask16 = 0xffff - reg16SizeMask32 = 0xffff - reg16SizeMask64 = 0xffff - - // reg32SizeMaskX - shift value is 32 bits, shifted is X - reg32SizeMask8 = 0xffffffff - reg32SizeMask16 = 0xffffffff - reg32SizeMask32 = 0xffffffff - reg32SizeMask64 = 0xffffffff - - // reg64SizeMaskX - shift value is 64 bits, shifted is X - reg64SizeMask8 = 0xffffffffffffffff - reg64SizeMask16 = 0xffffffffffffffff - reg64SizeMask32 = 0xffffffffffffffff - reg64SizeMask64 = 0xffffffffffffffff - - // regSizeMaskUintX - shift value is uint, shifted is X - regSizeMaskUint8 = ^uint(0) - regSizeMaskUint16 = ^uint(0) - regSizeMaskUint32 = ^uint(0) - regSizeMaskUint64 = ^uint(0) -) diff --git a/src/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go b/src/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go index 2d6ef64b..7035d656 100644 --- a/src/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go +++ b/src/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go @@ -1,222 +1,49 @@ //go:build amd64 && !appengine && !noasm && gc -// This file contains the specialisation of Decoder.Decompress4X -// and Decoder.Decompress1X that use an asm implementation of thir main loops. +// amd64 stubs and dispatch for the asm loops used by decompress_asm.go. package huff0 import ( - "errors" - "fmt" - "github.com/klauspost/compress/internal/cpuinfo" ) -// decompress4x_main_loop_x86 is an x86 assembler implementation +// decompress4x_main_loop_amd64 is an x86 assembler implementation // of Decompress4X when tablelog > 8. // //go:noescape func decompress4x_main_loop_amd64(ctx *decompress4xContext) -// decompress4x_8b_loop_x86 is an x86 assembler implementation +// decompress4x_8b_main_loop_amd64 is an x86 assembler implementation // of Decompress4X when tablelog <= 8 which decodes 4 entries // per loop. // //go:noescape func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) -// fallback8BitSize is the size where using Go version is faster. -const fallback8BitSize = 800 - -type decompress4xContext struct { - pbr *[4]bitReaderShifted - peekBits uint8 - out *byte - dstEvery int - tbl *dEntrySingle - decoded int - limit *byte -} - -// Decompress4X will decompress a 4X encoded stream. -// The length of the supplied input must match the end of a block exactly. -// The *capacity* of the dst slice must match the destination size of -// the uncompressed data exactly. -func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { - if len(d.dt.single) == 0 { - return nil, errors.New("no table loaded") - } - if len(src) < 6+(4*1) { - return nil, errors.New("input too small") - } - - use8BitTables := d.actualTableLog <= 8 - if cap(dst) < fallback8BitSize && use8BitTables { - return d.decompress4X8bit(dst, src) - } - - var br [4]bitReaderShifted - // Decode "jump table" - start := 6 - for i := range 3 { - length := int(src[i*2]) | (int(src[i*2+1]) << 8) - if start+length >= len(src) { - return nil, errors.New("truncated input (or invalid offset)") - } - err := br[i].init(src[start : start+length]) - if err != nil { - return nil, err - } - start += length - } - err := br[3].init(src[start:]) - if err != nil { - return nil, err - } - - // destination, offset to match first output - dstSize := cap(dst) - dst = dst[:dstSize] - out := dst - dstEvery := (dstSize + 3) / 4 - - const tlSize = 1 << tableLogMax - const tlMask = tlSize - 1 - single := d.dt.single[:tlSize] - - var decoded int - - if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) { - ctx := decompress4xContext{ - pbr: &br, - peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() - out: &out[0], - dstEvery: dstEvery, - tbl: &single[0], - limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last. - } - if use8BitTables { - decompress4x_8b_main_loop_amd64(&ctx) - } else { - decompress4x_main_loop_amd64(&ctx) - } - - decoded = ctx.decoded - out = out[decoded/4:] - } - - // Decode remaining. - remainBytes := dstEvery - (decoded / 4) - for i := range br { - offset := dstEvery * i - endsAt := min(offset+remainBytes, len(out)) - br := &br[i] - bitsLeft := br.remaining() - for bitsLeft > 0 { - br.fill() - if offset >= endsAt { - return nil, errors.New("corruption detected: stream overrun 4") - } - - // Read value and increment offset. - val := br.peekBitsFast(d.actualTableLog) - v := single[val&tlMask].entry - nBits := uint8(v) - br.advance(nBits) - bitsLeft -= uint(nBits) - out[offset] = uint8(v >> 8) - offset++ - } - if offset != endsAt { - return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt) - } - decoded += offset - dstEvery*i - err = br.close() - if err != nil { - return nil, err - } - } - if dstSize != decoded { - return nil, errors.New("corruption detected: short output block") - } - return dst, nil -} - -// decompress4x_main_loop_x86 is an x86 assembler implementation +// decompress1x_main_loop_amd64 is an x86 assembler implementation // of Decompress1X when tablelog > 8. // //go:noescape func decompress1x_main_loop_amd64(ctx *decompress1xContext) -// decompress4x_main_loop_x86 is an x86 with BMI2 assembler implementation +// decompress1x_main_loop_bmi2 is an x86 with BMI2 assembler implementation // of Decompress1X when tablelog > 8. // //go:noescape func decompress1x_main_loop_bmi2(ctx *decompress1xContext) -type decompress1xContext struct { - pbr *bitReaderShifted - peekBits uint8 - out *byte - outCap int - tbl *dEntrySingle - decoded int +func decompress4x_main_loop_asm(ctx *decompress4xContext) { + decompress4x_main_loop_amd64(ctx) } -// Error reported by asm implementations -const error_max_decoded_size_exeeded = -1 - -// Decompress1X will decompress a 1X encoded stream. -// The cap of the output buffer will be the maximum decompressed size. -// The length of the supplied input must match the end of a block exactly. -func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { - if len(d.dt.single) == 0 { - return nil, errors.New("no table loaded") - } - var br bitReaderShifted - err := br.init(src) - if err != nil { - return dst, err - } - maxDecodedSize := cap(dst) - dst = dst[:maxDecodedSize] - - const tlSize = 1 << tableLogMax - const tlMask = tlSize - 1 - - if maxDecodedSize >= 4 { - ctx := decompress1xContext{ - pbr: &br, - out: &dst[0], - outCap: maxDecodedSize, - peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() - tbl: &d.dt.single[0], - } - - if cpuinfo.HasBMI2() { - decompress1x_main_loop_bmi2(&ctx) - } else { - decompress1x_main_loop_amd64(&ctx) - } - if ctx.decoded == error_max_decoded_size_exeeded { - return nil, ErrMaxDecodedSizeExceeded - } - - dst = dst[:ctx.decoded] - } +func decompress4x_8b_main_loop_asm(ctx *decompress4xContext) { + decompress4x_8b_main_loop_amd64(ctx) +} - // br < 8, so uint8 is fine - bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead - for bitsLeft > 0 { - br.fill() - if len(dst) >= maxDecodedSize { - br.close() - return nil, ErrMaxDecodedSizeExceeded - } - v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] - nBits := uint8(v.entry) - br.advance(nBits) - bitsLeft -= nBits - dst = append(dst, uint8(v.entry>>8)) +func decompress1x_main_loop_asm(ctx *decompress1xContext) { + if cpuinfo.HasBMI2() { + decompress1x_main_loop_bmi2(ctx) + } else { + decompress1x_main_loop_amd64(ctx) } - return dst, br.close() } diff --git a/src/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s b/src/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s index c4c7ab2d..920628c5 100644 --- a/src/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s +++ b/src/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s @@ -1,6 +1,6 @@ -// Code generated by command: go run gen.go -out ../decompress_amd64.s -pkg=huff0. DO NOT EDIT. +// Code generated by command: go run gen.go -out ../decompress.s -arch amd64,arm64 -pkg=huff0. DO NOT EDIT. -//go:build amd64 && !appengine && !noasm && gc +//go:build !appengine && !noasm && gc // func decompress4x_main_loop_amd64(ctx *decompress4xContext) TEXT ·decompress4x_main_loop_amd64(SB), $0-8 @@ -47,12 +47,12 @@ skip_fill0: SHRQ CL, R13 // v0 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br0.advance(uint8(v0.entry) - MOVB CH, AL - SHLQ CL, R11 - ADDB CL, R12 + MOVBLZX CH, AX + SHLQ CL, R11 + ADDB CL, R12 // val1 := br0.peekTopBits(peekBits) MOVQ DI, CX @@ -60,7 +60,7 @@ skip_fill0: SHRQ CL, R13 // v1 := table[val1&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br0.advance(uint8(v1.entry)) MOVB CH, AH @@ -104,12 +104,12 @@ skip_fill1: SHRQ CL, R13 // v0 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br1.advance(uint8(v0.entry) - MOVB CH, AL - SHLQ CL, R11 - ADDB CL, R12 + MOVBLZX CH, AX + SHLQ CL, R11 + ADDB CL, R12 // val1 := br1.peekTopBits(peekBits) MOVQ DI, CX @@ -117,7 +117,7 @@ skip_fill1: SHRQ CL, R13 // v1 := table[val1&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br1.advance(uint8(v1.entry)) MOVB CH, AH @@ -161,12 +161,12 @@ skip_fill2: SHRQ CL, R13 // v0 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br2.advance(uint8(v0.entry) - MOVB CH, AL - SHLQ CL, R11 - ADDB CL, R12 + MOVBLZX CH, AX + SHLQ CL, R11 + ADDB CL, R12 // val1 := br2.peekTopBits(peekBits) MOVQ DI, CX @@ -174,7 +174,7 @@ skip_fill2: SHRQ CL, R13 // v1 := table[val1&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br2.advance(uint8(v1.entry)) MOVB CH, AH @@ -218,12 +218,12 @@ skip_fill3: SHRQ CL, R13 // v0 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br3.advance(uint8(v0.entry) - MOVB CH, AL - SHLQ CL, R11 - ADDB CL, R12 + MOVBLZX CH, AX + SHLQ CL, R11 + ADDB CL, R12 // val1 := br3.peekTopBits(peekBits) MOVQ DI, CX @@ -231,7 +231,7 @@ skip_fill3: SHRQ CL, R13 // v1 := table[val1&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br3.advance(uint8(v1.entry)) MOVB CH, AH @@ -259,13 +259,13 @@ skip_fill3: // func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) TEXT ·decompress4x_8b_main_loop_amd64(SB), $0-8 // Preload values - MOVQ ctx+0(FP), CX - MOVBQZX 8(CX), DI - MOVQ 16(CX), BX - MOVQ 48(CX), SI - MOVQ 24(CX), R8 - MOVQ 32(CX), R9 - MOVQ (CX), R10 + MOVQ ctx+0(FP), AX + MOVBQZX 8(AX), DI + MOVQ 16(AX), BX + MOVQ 48(AX), SI + MOVQ 24(AX), R8 + MOVQ 32(AX), R9 + MOVQ (AX), R10 // Main loop main_loop: @@ -278,35 +278,35 @@ main_loop: MOVBQZX 40(R10), R12 CMPQ R12, $0x20 JBE skip_fill0 - MOVQ 24(R10), R13 + MOVQ 24(R10), AX SUBQ $0x20, R12 - SUBQ $0x04, R13 - MOVQ (R10), R14 + SUBQ $0x04, AX + MOVQ (R10), R13 // b.value |= uint64(low) << (b.bitsRead & 63) - MOVL (R13)(R14*1), R14 + MOVL (AX)(R13*1), R13 MOVQ R12, CX - SHLQ CL, R14 - MOVQ R13, 24(R10) - ORQ R14, R11 + SHLQ CL, R13 + MOVQ AX, 24(R10) + ORQ R13, R11 // exhausted += (br0.off < 4) - CMPQ R13, $0x04 + CMPQ AX, $0x04 ADCB $+0, DL skip_fill0: // val0 := br0.peekTopBits(peekBits) - MOVQ R11, R13 + MOVQ R11, AX MOVQ DI, CX - SHRQ CL, R13 + SHRQ CL, AX // v0 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(AX*2), CX // br0.advance(uint8(v0.entry) - MOVB CH, AL - SHLQ CL, R11 - ADDB CL, R12 + MOVBLZX CH, AX + SHLQ CL, R11 + ADDB CL, R12 // val1 := br0.peekTopBits(peekBits) MOVQ R11, R13 @@ -314,7 +314,7 @@ skip_fill0: SHRQ CL, R13 // v1 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br0.advance(uint8(v1.entry) MOVB CH, AH @@ -328,7 +328,7 @@ skip_fill0: SHRQ CL, R13 // v2 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br0.advance(uint8(v2.entry) MOVB CH, AH @@ -341,7 +341,7 @@ skip_fill0: SHRQ CL, R13 // v3 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br0.advance(uint8(v3.entry) MOVB CH, AL @@ -365,35 +365,35 @@ skip_fill0: MOVBQZX 88(R10), R12 CMPQ R12, $0x20 JBE skip_fill1 - MOVQ 72(R10), R13 + MOVQ 72(R10), AX SUBQ $0x20, R12 - SUBQ $0x04, R13 - MOVQ 48(R10), R14 + SUBQ $0x04, AX + MOVQ 48(R10), R13 // b.value |= uint64(low) << (b.bitsRead & 63) - MOVL (R13)(R14*1), R14 + MOVL (AX)(R13*1), R13 MOVQ R12, CX - SHLQ CL, R14 - MOVQ R13, 72(R10) - ORQ R14, R11 + SHLQ CL, R13 + MOVQ AX, 72(R10) + ORQ R13, R11 // exhausted += (br1.off < 4) - CMPQ R13, $0x04 + CMPQ AX, $0x04 ADCB $+0, DL skip_fill1: // val0 := br1.peekTopBits(peekBits) - MOVQ R11, R13 + MOVQ R11, AX MOVQ DI, CX - SHRQ CL, R13 + SHRQ CL, AX // v0 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(AX*2), CX // br1.advance(uint8(v0.entry) - MOVB CH, AL - SHLQ CL, R11 - ADDB CL, R12 + MOVBLZX CH, AX + SHLQ CL, R11 + ADDB CL, R12 // val1 := br1.peekTopBits(peekBits) MOVQ R11, R13 @@ -401,7 +401,7 @@ skip_fill1: SHRQ CL, R13 // v1 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br1.advance(uint8(v1.entry) MOVB CH, AH @@ -415,7 +415,7 @@ skip_fill1: SHRQ CL, R13 // v2 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br1.advance(uint8(v2.entry) MOVB CH, AH @@ -428,7 +428,7 @@ skip_fill1: SHRQ CL, R13 // v3 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br1.advance(uint8(v3.entry) MOVB CH, AL @@ -452,35 +452,35 @@ skip_fill1: MOVBQZX 136(R10), R12 CMPQ R12, $0x20 JBE skip_fill2 - MOVQ 120(R10), R13 + MOVQ 120(R10), AX SUBQ $0x20, R12 - SUBQ $0x04, R13 - MOVQ 96(R10), R14 + SUBQ $0x04, AX + MOVQ 96(R10), R13 // b.value |= uint64(low) << (b.bitsRead & 63) - MOVL (R13)(R14*1), R14 + MOVL (AX)(R13*1), R13 MOVQ R12, CX - SHLQ CL, R14 - MOVQ R13, 120(R10) - ORQ R14, R11 + SHLQ CL, R13 + MOVQ AX, 120(R10) + ORQ R13, R11 // exhausted += (br2.off < 4) - CMPQ R13, $0x04 + CMPQ AX, $0x04 ADCB $+0, DL skip_fill2: // val0 := br2.peekTopBits(peekBits) - MOVQ R11, R13 + MOVQ R11, AX MOVQ DI, CX - SHRQ CL, R13 + SHRQ CL, AX // v0 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(AX*2), CX // br2.advance(uint8(v0.entry) - MOVB CH, AL - SHLQ CL, R11 - ADDB CL, R12 + MOVBLZX CH, AX + SHLQ CL, R11 + ADDB CL, R12 // val1 := br2.peekTopBits(peekBits) MOVQ R11, R13 @@ -488,7 +488,7 @@ skip_fill2: SHRQ CL, R13 // v1 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br2.advance(uint8(v1.entry) MOVB CH, AH @@ -502,7 +502,7 @@ skip_fill2: SHRQ CL, R13 // v2 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br2.advance(uint8(v2.entry) MOVB CH, AH @@ -515,7 +515,7 @@ skip_fill2: SHRQ CL, R13 // v3 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br2.advance(uint8(v3.entry) MOVB CH, AL @@ -539,35 +539,35 @@ skip_fill2: MOVBQZX 184(R10), R12 CMPQ R12, $0x20 JBE skip_fill3 - MOVQ 168(R10), R13 + MOVQ 168(R10), AX SUBQ $0x20, R12 - SUBQ $0x04, R13 - MOVQ 144(R10), R14 + SUBQ $0x04, AX + MOVQ 144(R10), R13 // b.value |= uint64(low) << (b.bitsRead & 63) - MOVL (R13)(R14*1), R14 + MOVL (AX)(R13*1), R13 MOVQ R12, CX - SHLQ CL, R14 - MOVQ R13, 168(R10) - ORQ R14, R11 + SHLQ CL, R13 + MOVQ AX, 168(R10) + ORQ R13, R11 // exhausted += (br3.off < 4) - CMPQ R13, $0x04 + CMPQ AX, $0x04 ADCB $+0, DL skip_fill3: // val0 := br3.peekTopBits(peekBits) - MOVQ R11, R13 + MOVQ R11, AX MOVQ DI, CX - SHRQ CL, R13 + SHRQ CL, AX // v0 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(AX*2), CX // br3.advance(uint8(v0.entry) - MOVB CH, AL - SHLQ CL, R11 - ADDB CL, R12 + MOVBLZX CH, AX + SHLQ CL, R11 + ADDB CL, R12 // val1 := br3.peekTopBits(peekBits) MOVQ R11, R13 @@ -575,7 +575,7 @@ skip_fill3: SHRQ CL, R13 // v1 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br3.advance(uint8(v1.entry) MOVB CH, AH @@ -589,7 +589,7 @@ skip_fill3: SHRQ CL, R13 // v2 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br3.advance(uint8(v2.entry) MOVB CH, AH @@ -602,7 +602,7 @@ skip_fill3: SHRQ CL, R13 // v3 := table[val0&mask] - MOVW (R9)(R13*2), CX + MOVWQZX (R9)(R13*2), CX // br3.advance(uint8(v3.entry) MOVB CH, AL @@ -667,7 +667,7 @@ bitReader_fillFast_1_end: MOVQ DI, CX MOVQ R10, R12 SHRQ CL, R12 - MOVW (SI)(R12*2), CX + MOVWQZX (SI)(R12*2), CX MOVB CH, AL MOVBQZX CL, CX ADDQ CX, R11 @@ -675,7 +675,7 @@ bitReader_fillFast_1_end: MOVQ DI, CX MOVQ R10, R12 SHRQ CL, R12 - MOVW (SI)(R12*2), CX + MOVWQZX (SI)(R12*2), CX MOVB CH, AH MOVBQZX CL, CX ADDQ CX, R11 @@ -694,7 +694,7 @@ bitReader_fillFast_2_end: MOVQ DI, CX MOVQ R10, R12 SHRQ CL, R12 - MOVW (SI)(R12*2), CX + MOVWQZX (SI)(R12*2), CX MOVB CH, AH MOVBQZX CL, CX ADDQ CX, R11 @@ -702,7 +702,7 @@ bitReader_fillFast_2_end: MOVQ DI, CX MOVQ R10, R12 SHRQ CL, R12 - MOVW (SI)(R12*2), CX + MOVWQZX (SI)(R12*2), CX MOVB CH, AL MOVBQZX CL, CX ADDQ CX, R11 @@ -769,13 +769,13 @@ main_loop: bitReader_fillFast_1_end: SHRXQ DI, R10, CX - MOVW (SI)(CX*2), CX + MOVWQZX (SI)(CX*2), CX MOVB CH, AL MOVBQZX CL, CX ADDQ CX, R11 SHLXQ CX, R10, R10 SHRXQ DI, R10, CX - MOVW (SI)(CX*2), CX + MOVWQZX (SI)(CX*2), CX MOVB CH, AH MOVBQZX CL, CX ADDQ CX, R11 @@ -791,13 +791,13 @@ bitReader_fillFast_1_end: bitReader_fillFast_2_end: SHRXQ DI, R10, CX - MOVW (SI)(CX*2), CX + MOVWQZX (SI)(CX*2), CX MOVB CH, AH MOVBQZX CL, CX ADDQ CX, R11 SHLXQ CX, R10, R10 SHRXQ DI, R10, CX - MOVW (SI)(CX*2), CX + MOVWQZX (SI)(CX*2), CX MOVB CH, AL MOVBQZX CL, CX ADDQ CX, R11 diff --git a/src/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go b/src/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go new file mode 100644 index 00000000..8ba3c810 --- /dev/null +++ b/src/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go @@ -0,0 +1,37 @@ +//go:build arm64 && !appengine && !noasm && gc + +// arm64 stubs and dispatch for the asm loops used by decompress_asm.go. +// The asm (decompress_arm64.s) is generated by the avo arm64 lowering +// printer from the same source as the amd64 asm; see _generate/gen.go. +package huff0 + +// decompress4x_main_loop_arm64 is an arm64 assembler implementation +// of Decompress4X when tablelog > 8. +// +//go:noescape +func decompress4x_main_loop_arm64(ctx *decompress4xContext) + +// decompress4x_8b_main_loop_arm64 is an arm64 assembler implementation +// of Decompress4X when tablelog <= 8 which decodes 4 entries +// per loop. +// +//go:noescape +func decompress4x_8b_main_loop_arm64(ctx *decompress4xContext) + +// decompress1x_main_loop_arm64 is an arm64 assembler implementation +// of Decompress1X when tablelog > 8. +// +//go:noescape +func decompress1x_main_loop_arm64(ctx *decompress1xContext) + +func decompress4x_main_loop_asm(ctx *decompress4xContext) { + decompress4x_main_loop_arm64(ctx) +} + +func decompress4x_8b_main_loop_asm(ctx *decompress4xContext) { + decompress4x_8b_main_loop_arm64(ctx) +} + +func decompress1x_main_loop_asm(ctx *decompress1xContext) { + decompress1x_main_loop_arm64(ctx) +} diff --git a/src/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s b/src/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s new file mode 100644 index 00000000..357df28e --- /dev/null +++ b/src/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s @@ -0,0 +1,796 @@ +// Code generated by command: go run gen.go -out ../decompress.s -arch amd64,arm64 -pkg=huff0. DO NOT EDIT. +// EXPERIMENTAL arm64 output lowered from an amd64 avo program. + +//go:build arm64 && (!appengine && !noasm && gc) + +// func decompress4x_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_main_loop_arm64(SB), $0-8 + // Preload values + MOVD ctx+0(FP), R0 + MOVBU 8(R0), R6 + MOVD 16(R0), R3 + MOVD 48(R0), R5 + MOVD 24(R0), R7 + MOVD 32(R0), R8 + MOVD (R0), R9 + + // Main loop +main_loop: + MOVD $0, R2 + CMP R5, R3 + CSET GE, R16 + BFI $0, R16, $8, R2 + + // br0.fillFast32() + MOVD 32(R9), R10 + MOVBU 40(R9), R11 + CMP $0x20, R11 + BLS skip_fill0 + MOVD 24(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD (R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVWU (R0)(R12), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 24(R9) + ORR R12, R10, R10 + + // exhausted += (br0.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill0: + // val0 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br0.advance(uint8(v0.entry) + UBFX $8, R1, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br0.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + MOVHU (R8)(R12<<1), R1 + + // br0.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVH R0, (R3) + + // update the bitreader structure + MOVD R10, 32(R9) + MOVB R11, 40(R9) + + // br1.fillFast32() + MOVD 80(R9), R10 + MOVBU 88(R9), R11 + CMP $0x20, R11 + BLS skip_fill1 + MOVD 72(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 48(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVWU (R0)(R12), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 72(R9) + ORR R12, R10, R10 + + // exhausted += (br1.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill1: + // val0 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br1.advance(uint8(v0.entry) + UBFX $8, R1, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br1.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + MOVHU (R8)(R12<<1), R1 + + // br1.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVH R0, (R3)(R7) + + // update the bitreader structure + MOVD R10, 80(R9) + MOVB R11, 88(R9) + + // br2.fillFast32() + MOVD 128(R9), R10 + MOVBU 136(R9), R11 + CMP $0x20, R11 + BLS skip_fill2 + MOVD 120(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 96(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVWU (R0)(R12), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 120(R9) + ORR R12, R10, R10 + + // exhausted += (br2.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill2: + // val0 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br2.advance(uint8(v0.entry) + UBFX $8, R1, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br2.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + MOVHU (R8)(R12<<1), R1 + + // br2.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVH R0, (R3)(R7<<1) + + // update the bitreader structure + MOVD R10, 128(R9) + MOVB R11, 136(R9) + + // br3.fillFast32() + MOVD 176(R9), R10 + MOVBU 184(R9), R11 + CMP $0x20, R11 + BLS skip_fill3 + MOVD 168(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 144(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVWU (R0)(R12), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 168(R9) + ORR R12, R10, R10 + + // exhausted += (br3.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill3: + // val0 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br3.advance(uint8(v0.entry) + UBFX $8, R1, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br3.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + MOVHU (R8)(R12<<1), R1 + + // br3.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + ADD R7<<1, R7, R1 + MOVH R0, (R3)(R1) + + // update the bitreader structure + MOVD R10, 176(R9) + MOVB R11, 184(R9) + ADD $0x02, R3, R3 + TST $0xff, R2 + BEQ main_loop + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R3, R3 + LSL $0x02, R3, R3 + MOVD R3, 40(R0) + RET + +// func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_8b_main_loop_arm64(SB), $0-8 + // Preload values + MOVD ctx+0(FP), R0 + MOVBU 8(R0), R6 + MOVD 16(R0), R3 + MOVD 48(R0), R5 + MOVD 24(R0), R7 + MOVD 32(R0), R8 + MOVD (R0), R9 + + // Main loop +main_loop: + MOVD $0, R2 + CMP R5, R3 + CSET GE, R16 + BFI $0, R16, $8, R2 + + // br0.fillFast32() + MOVD 32(R9), R10 + MOVBU 40(R9), R11 + CMP $0x20, R11 + BLS skip_fill0 + MOVD 24(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD (R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVWU (R0)(R12), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 24(R9) + ORR R12, R10, R10 + + // exhausted += (br0.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill0: + // val0 := br0.peekTopBits(peekBits) + MOVD R10, R0 + MOVD R6, R1 + LSR R1, R0, R0 + + // v0 := table[val0&mask] + MOVHU (R8)(R0<<1), R1 + + // br0.advance(uint8(v0.entry) + UBFX $8, R1, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br0.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br0.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br0.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVW R0, (R3) + + // update the bitreader structure + MOVD R10, 32(R9) + MOVB R11, 40(R9) + + // br1.fillFast32() + MOVD 80(R9), R10 + MOVBU 88(R9), R11 + CMP $0x20, R11 + BLS skip_fill1 + MOVD 72(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 48(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVWU (R0)(R12), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 72(R9) + ORR R12, R10, R10 + + // exhausted += (br1.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill1: + // val0 := br1.peekTopBits(peekBits) + MOVD R10, R0 + MOVD R6, R1 + LSR R1, R0, R0 + + // v0 := table[val0&mask] + MOVHU (R8)(R0<<1), R1 + + // br1.advance(uint8(v0.entry) + UBFX $8, R1, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br1.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br1.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br1.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVW R0, (R3)(R7) + + // update the bitreader structure + MOVD R10, 80(R9) + MOVB R11, 88(R9) + + // br2.fillFast32() + MOVD 128(R9), R10 + MOVBU 136(R9), R11 + CMP $0x20, R11 + BLS skip_fill2 + MOVD 120(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 96(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVWU (R0)(R12), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 120(R9) + ORR R12, R10, R10 + + // exhausted += (br2.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill2: + // val0 := br2.peekTopBits(peekBits) + MOVD R10, R0 + MOVD R6, R1 + LSR R1, R0, R0 + + // v0 := table[val0&mask] + MOVHU (R8)(R0<<1), R1 + + // br2.advance(uint8(v0.entry) + UBFX $8, R1, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br2.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br2.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br2.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + ADD R7<<1, R3, R15 + MOVW R0, (R15) + + // update the bitreader structure + MOVD R10, 128(R9) + MOVB R11, 136(R9) + + // br3.fillFast32() + MOVD 176(R9), R10 + MOVBU 184(R9), R11 + CMP $0x20, R11 + BLS skip_fill3 + MOVD 168(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 144(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVWU (R0)(R12), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 168(R9) + ORR R12, R10, R10 + + // exhausted += (br3.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill3: + // val0 := br3.peekTopBits(peekBits) + MOVD R10, R0 + MOVD R6, R1 + LSR R1, R0, R0 + + // v0 := table[val0&mask] + MOVHU (R8)(R0<<1), R1 + + // br3.advance(uint8(v0.entry) + UBFX $8, R1, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br3.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br3.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + MOVHU (R8)(R12<<1), R1 + + // br3.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + ADD R7<<1, R7, R1 + MOVW R0, (R3)(R1) + + // update the bitreader structure + MOVD R10, 176(R9) + MOVB R11, 184(R9) + ADD $0x04, R3, R3 + TST $0xff, R2 + BEQ main_loop + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R3, R3 + LSL $0x02, R3, R3 + MOVD R3, 40(R0) + RET + +// func decompress1x_main_loop_amd64(ctx *decompress1xContext) +TEXT ·decompress1x_main_loop_arm64(SB), $0-8 + MOVD ctx+0(FP), R1 + MOVD 16(R1), R2 + MOVD 24(R1), R3 + CMP $0x04, R3 + BLO error_max_decoded_size_exceeded + ADD R3, R2, R3 + MOVD (R1), R5 + MOVD (R5), R7 + MOVD 24(R5), R8 + MOVD 32(R5), R9 + MOVBU 40(R5), R10 + MOVD 32(R1), R5 + MOVBU 8(R1), R6 + JMP loop_condition + +main_loop: + // Check if we have room for 4 bytes in the output buffer + ADD $4, R2, R1 + CMP R3, R1 + BGE error_max_decoded_size_exceeded + + // Decode 4 values + CMP $0x20, R10 + BLT bitReader_fillFast_1_end + SUB $0x20, R10, R10 + SUB $0x04, R8, R8 + MOVWU (R7)(R8), R11 + MOVD R10, R1 + LSL R1, R11, R11 + ORR R11, R9, R9 + +bitReader_fillFast_1_end: + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + MOVHU (R5)(R11<<1), R1 + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + MOVHU (R5)(R11<<1), R1 + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + REVW R0, R0 + CMP $0x20, R10 + BLT bitReader_fillFast_2_end + SUB $0x20, R10, R10 + SUB $0x04, R8, R8 + MOVWU (R7)(R8), R11 + MOVD R10, R1 + LSL R1, R11, R11 + ORR R11, R9, R9 + +bitReader_fillFast_2_end: + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + MOVHU (R5)(R11<<1), R1 + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + MOVHU (R5)(R11<<1), R1 + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + REVW R0, R0 + + // Store the decoded values + MOVW R0, (R2) + ADD $0x04, R2, R2 + +loop_condition: + CMP $0x08, R8 + BGE main_loop + + // Update ctx structure + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R2, R2 + MOVD R2, 40(R0) + MOVD (R0), R0 + MOVD R8, 24(R0) + MOVD R9, 32(R0) + MOVB R10, 40(R0) + RET + + // Report error +error_max_decoded_size_exceeded: + MOVD ctx+0(FP), R0 + MOVD $-1, R1 + MOVD R1, 40(R0) + RET + +// skipped decompress1x_main_loop_bmi2 (generic twin preferred on arm64) diff --git a/src/vendor/github.com/klauspost/compress/huff0/decompress_asm.go b/src/vendor/github.com/klauspost/compress/huff0/decompress_asm.go new file mode 100644 index 00000000..4854dd43 --- /dev/null +++ b/src/vendor/github.com/klauspost/compress/huff0/decompress_asm.go @@ -0,0 +1,193 @@ +//go:build (amd64 || arm64) && !appengine && !noasm && gc + +// This file contains the specialisation of Decoder.Decompress4X +// and Decoder.Decompress1X that use an asm implementation of their main loops. +// The asm function stubs and any per-arch dispatch live in decompress_amd64.go +// and decompress_arm64.go. +package huff0 + +import ( + "errors" + "fmt" +) + +// fallback8BitSize is the size where using Go version is faster. +const fallback8BitSize = 800 + +type decompress4xContext struct { + pbr *[4]bitReaderShifted + peekBits uint8 + out *byte + dstEvery int + tbl *dEntrySingle + decoded int + limit *byte +} + +// Decompress4X will decompress a 4X encoded stream. +// The length of the supplied input must match the end of a block exactly. +// The *capacity* of the dst slice must match the destination size of +// the uncompressed data exactly. +func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + if len(src) < 6+(4*1) { + return nil, errors.New("input too small") + } + + use8BitTables := d.actualTableLog <= 8 + if cap(dst) < fallback8BitSize && use8BitTables { + return d.decompress4X8bit(dst, src) + } + + var br [4]bitReaderShifted + // Decode "jump table" + start := 6 + for i := range 3 { + length := int(src[i*2]) | (int(src[i*2+1]) << 8) + if start+length >= len(src) { + return nil, errors.New("truncated input (or invalid offset)") + } + err := br[i].init(src[start : start+length]) + if err != nil { + return nil, err + } + start += length + } + err := br[3].init(src[start:]) + if err != nil { + return nil, err + } + + // destination, offset to match first output + dstSize := cap(dst) + dst = dst[:dstSize] + out := dst + dstEvery := (dstSize + 3) / 4 + + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + single := d.dt.single[:tlSize] + + var decoded int + + if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) { + ctx := decompress4xContext{ + pbr: &br, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + out: &out[0], + dstEvery: dstEvery, + tbl: &single[0], + limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last. + } + if use8BitTables { + decompress4x_8b_main_loop_asm(&ctx) + } else { + decompress4x_main_loop_asm(&ctx) + } + + decoded = ctx.decoded + out = out[decoded/4:] + } + + // Decode remaining. + remainBytes := dstEvery - (decoded / 4) + for i := range br { + offset := dstEvery * i + endsAt := min(offset+remainBytes, len(out)) + br := &br[i] + bitsLeft := br.remaining() + for bitsLeft > 0 { + br.fill() + if offset >= endsAt { + return nil, errors.New("corruption detected: stream overrun 4") + } + + // Read value and increment offset. + val := br.peekBitsFast(d.actualTableLog) + v := single[val&tlMask].entry + nBits := uint8(v) + br.advance(nBits) + bitsLeft -= uint(nBits) + out[offset] = uint8(v >> 8) + offset++ + } + if offset != endsAt { + return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt) + } + decoded += offset - dstEvery*i + err = br.close() + if err != nil { + return nil, err + } + } + if dstSize != decoded { + return nil, errors.New("corruption detected: short output block") + } + return dst, nil +} + +type decompress1xContext struct { + pbr *bitReaderShifted + peekBits uint8 + out *byte + outCap int + tbl *dEntrySingle + decoded int +} + +// Error reported by asm implementations +const error_max_decoded_size_exeeded = -1 + +// Decompress1X will decompress a 1X encoded stream. +// The cap of the output buffer will be the maximum decompressed size. +// The length of the supplied input must match the end of a block exactly. +func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + var br bitReaderShifted + err := br.init(src) + if err != nil { + return dst, err + } + maxDecodedSize := cap(dst) + dst = dst[:maxDecodedSize] + + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + + if maxDecodedSize >= 4 { + ctx := decompress1xContext{ + pbr: &br, + out: &dst[0], + outCap: maxDecodedSize, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + tbl: &d.dt.single[0], + } + + decompress1x_main_loop_asm(&ctx) + if ctx.decoded == error_max_decoded_size_exeeded { + return nil, ErrMaxDecodedSizeExceeded + } + + dst = dst[:ctx.decoded] + } + + // br < 8, so uint8 is fine + bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead + for bitsLeft > 0 { + br.fill() + if len(dst) >= maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] + nBits := uint8(v.entry) + br.advance(nBits) + bitsLeft -= nBits + dst = append(dst, uint8(v.entry>>8)) + } + return dst, br.close() +} diff --git a/src/vendor/github.com/klauspost/compress/huff0/decompress_generic.go b/src/vendor/github.com/klauspost/compress/huff0/decompress_generic.go index 61039232..e1bca5c6 100644 --- a/src/vendor/github.com/klauspost/compress/huff0/decompress_generic.go +++ b/src/vendor/github.com/klauspost/compress/huff0/decompress_generic.go @@ -1,4 +1,4 @@ -//go:build !amd64 || appengine || !gc || noasm +//go:build (!amd64 && !arm64) || appengine || !gc || noasm // This file contains a generic implementation of Decoder.Decompress4X. package huff0 diff --git a/src/vendor/github.com/klauspost/compress/internal/regmask/regmask.go b/src/vendor/github.com/klauspost/compress/internal/regmask/regmask.go new file mode 100644 index 00000000..3da49d15 --- /dev/null +++ b/src/vendor/github.com/klauspost/compress/internal/regmask/regmask.go @@ -0,0 +1,50 @@ +//go:build !386 + +// Package regmask provides masks for variable shift counts. +// +// Go defines a shift by more than the width of the shifted value as producing +// zero, so the compiler has to guard every variable shift against that: on +// amd64 with a CMP and an SBB, on arm64 with a CMP and a CSEL, and so on. When +// the count is known to be smaller than the width anyway, masking it with the +// width minus one lets the compiler drop the guard. The mask itself costs +// nothing on the architectures whose shift instructions already use only the +// low bits of the count, which the compiler knows about. +// +// Each constant is named for the width of the value being shifted and the type +// of the shift count, and may only be used where the count is always smaller +// than that width: +// +// x := y >> (n & regmask.Shift64ByUint) // y is 64 bits, n is a uint below 64 +package regmask + +const ( + // ShiftNByUint8 - shifting an N bit value by a uint8 + Shift8ByUint8 = 7 + Shift16ByUint8 = 15 + Shift32ByUint8 = 31 + Shift64ByUint8 = 63 + + // ShiftNByUint16 - shifting an N bit value by a uint16 + Shift8ByUint16 = Shift8ByUint8 + Shift16ByUint16 = Shift16ByUint8 + Shift32ByUint16 = Shift32ByUint8 + Shift64ByUint16 = Shift64ByUint8 + + // ShiftNByUint32 - shifting an N bit value by a uint32 + Shift8ByUint32 = Shift8ByUint8 + Shift16ByUint32 = Shift16ByUint8 + Shift32ByUint32 = Shift32ByUint8 + Shift64ByUint32 = Shift64ByUint8 + + // ShiftNByUint64 - shifting an N bit value by a uint64 + Shift8ByUint64 = Shift8ByUint8 + Shift16ByUint64 = Shift16ByUint8 + Shift32ByUint64 = Shift32ByUint8 + Shift64ByUint64 = Shift64ByUint8 + + // ShiftNByUint - shifting an N bit value by a uint + Shift8ByUint = Shift8ByUint8 + Shift16ByUint = Shift16ByUint8 + Shift32ByUint = Shift32ByUint8 + Shift64ByUint = Shift64ByUint8 +) diff --git a/src/vendor/github.com/klauspost/compress/internal/regmask/regmask_386.go b/src/vendor/github.com/klauspost/compress/internal/regmask/regmask_386.go new file mode 100644 index 00000000..ff15f7c1 --- /dev/null +++ b/src/vendor/github.com/klauspost/compress/internal/regmask/regmask_386.go @@ -0,0 +1,39 @@ +//go:build 386 + +package regmask + +// A 64 bit shift on 386 is synthesized from 32 bit instructions, and masking its +// count makes the compiler emit more code rather than less, so those masks are +// no-ops here: each is the largest value its count type can hold, which the +// compiler folds away. Shifts of narrower values behave as elsewhere. +const ( + // ShiftNByUint8 - shifting an N bit value by a uint8 + Shift8ByUint8 = 7 + Shift16ByUint8 = 15 + Shift32ByUint8 = 31 + Shift64ByUint8 = 0xff + + // ShiftNByUint16 - shifting an N bit value by a uint16 + Shift8ByUint16 = Shift8ByUint8 + Shift16ByUint16 = Shift16ByUint8 + Shift32ByUint16 = Shift32ByUint8 + Shift64ByUint16 = 0xffff + + // ShiftNByUint32 - shifting an N bit value by a uint32 + Shift8ByUint32 = Shift8ByUint8 + Shift16ByUint32 = Shift16ByUint8 + Shift32ByUint32 = Shift32ByUint8 + Shift64ByUint32 = 0xffffffff + + // ShiftNByUint64 - shifting an N bit value by a uint64 + Shift8ByUint64 = Shift8ByUint8 + Shift16ByUint64 = Shift16ByUint8 + Shift32ByUint64 = Shift32ByUint8 + Shift64ByUint64 = 0xffffffffffffffff + + // ShiftNByUint - shifting an N bit value by a uint + Shift8ByUint = Shift8ByUint8 + Shift16ByUint = Shift16ByUint8 + Shift32ByUint = Shift32ByUint8 + Shift64ByUint = ^uint(0) +) diff --git a/src/vendor/github.com/klauspost/compress/s2/encode_amd64.go b/src/vendor/github.com/klauspost/compress/s2/encode_asm.go similarity index 98% rename from src/vendor/github.com/klauspost/compress/s2/encode_amd64.go rename to src/vendor/github.com/klauspost/compress/s2/encode_asm.go index 68d72a41..eee24e72 100644 --- a/src/vendor/github.com/klauspost/compress/s2/encode_amd64.go +++ b/src/vendor/github.com/klauspost/compress/s2/encode_asm.go @@ -1,4 +1,4 @@ -//go:build !appengine && !noasm && gc +//go:build (amd64 || arm64) && !appengine && !noasm && gc package s2 @@ -8,7 +8,7 @@ import ( "github.com/klauspost/compress/internal/race" ) -const hasAmd64Asm = true +const hasAsm = true var encPools [4]sync.Pool diff --git a/src/vendor/github.com/klauspost/compress/s2/encode_better.go b/src/vendor/github.com/klauspost/compress/s2/encode_better.go index adbc57c4..2509d1c9 100644 --- a/src/vendor/github.com/klauspost/compress/s2/encode_better.go +++ b/src/vendor/github.com/klauspost/compress/s2/encode_better.go @@ -86,12 +86,18 @@ func encodeBlockBetterGo(dst, src []byte) (d int) { // We initialize repeat to 0, so we never match on first attempt repeat := 0 + // Cap the adaptive skip, as encodeBetterBlockAsm and the snappy Go encoder + // below already do. Without a cap, a long stretch with no matches lets the + // skip grow geometrically until it strides past the start of the next + // compressible region and loses the matches there. + const maxSkip = 100 + for { candidateL := 0 nextS := 0 for { // Next src position to check - nextS = s + (s-nextEmit)>>7 + 1 + nextS = s + min((s-nextEmit)>>7+1, maxSkip) if nextS > sLimit { goto emitRemainder } diff --git a/src/vendor/github.com/klauspost/compress/s2/encode_go.go b/src/vendor/github.com/klauspost/compress/s2/encode_go.go index 5597f3ef..0270d33b 100644 --- a/src/vendor/github.com/klauspost/compress/s2/encode_go.go +++ b/src/vendor/github.com/klauspost/compress/s2/encode_go.go @@ -1,4 +1,4 @@ -//go:build !amd64 || appengine || !gc || noasm +//go:build (!amd64 && !arm64) || appengine || !gc || noasm package s2 @@ -7,7 +7,7 @@ import ( "math/bits" ) -const hasAmd64Asm = false +const hasAsm = false // encodeBlock encodes a non-empty src to a guaranteed-large-enough dst. It // assumes that the varint-encoded length of the decompressed bytes has already diff --git a/src/vendor/github.com/klauspost/compress/s2/encodeblock_amd64.s b/src/vendor/github.com/klauspost/compress/s2/encodeblock_amd64.s index df9be687..92a17756 100644 --- a/src/vendor/github.com/klauspost/compress/s2/encodeblock_amd64.s +++ b/src/vendor/github.com/klauspost/compress/s2/encodeblock_amd64.s @@ -1,6 +1,6 @@ -// Code generated by command: go run gen.go -out ../encodeblock_amd64.s -stubs ../encodeblock_amd64.go -pkg=s2. DO NOT EDIT. +// Code generated by command: go run gen.go -out ../encodeblock_amd64.s -stubs ../encodeblock_asm.go -pkg=s2. DO NOT EDIT. -//go:build !appengine && !noasm && gc && !noasm +//go:build (amd64 || arm64) && !appengine && !noasm && gc && !noasm #include "textflag.h" @@ -274,16 +274,10 @@ matchlen_loopback_16_repeat_extend_encodeBlockAsm: JMP matchlen_loopback_16_repeat_extend_encodeBlockAsm matchlen_bsf_16repeat_extend_encodeBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP repeat_extend_forward_end_encodeBlockAsm + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP repeat_extend_forward_end_encodeBlockAsm matchlen_match8_repeat_extend_encodeBlockAsm: CMPL R9, $0x08 @@ -296,16 +290,10 @@ matchlen_match8_repeat_extend_encodeBlockAsm: JMP matchlen_match4_repeat_extend_encodeBlockAsm matchlen_bsf_8_repeat_extend_encodeBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP repeat_extend_forward_end_encodeBlockAsm + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP repeat_extend_forward_end_encodeBlockAsm matchlen_match4_repeat_extend_encodeBlockAsm: CMPL R9, $0x04 @@ -898,16 +886,10 @@ matchlen_loopback_16_match_nolit_encodeBlockAsm: JMP matchlen_loopback_16_match_nolit_encodeBlockAsm matchlen_bsf_16match_nolit_encodeBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_encodeBlockAsm + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_encodeBlockAsm matchlen_match8_match_nolit_encodeBlockAsm: CMPL DI, $0x08 @@ -920,16 +902,10 @@ matchlen_match8_match_nolit_encodeBlockAsm: JMP matchlen_match4_match_nolit_encodeBlockAsm matchlen_bsf_8_match_nolit_encodeBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_encodeBlockAsm + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_encodeBlockAsm matchlen_match4_match_nolit_encodeBlockAsm: CMPL DI, $0x04 @@ -1689,16 +1665,10 @@ matchlen_loopback_16_repeat_extend_encodeBlockAsm4MB: JMP matchlen_loopback_16_repeat_extend_encodeBlockAsm4MB matchlen_bsf_16repeat_extend_encodeBlockAsm4MB: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP repeat_extend_forward_end_encodeBlockAsm4MB + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP repeat_extend_forward_end_encodeBlockAsm4MB matchlen_match8_repeat_extend_encodeBlockAsm4MB: CMPL R9, $0x08 @@ -1711,16 +1681,10 @@ matchlen_match8_repeat_extend_encodeBlockAsm4MB: JMP matchlen_match4_repeat_extend_encodeBlockAsm4MB matchlen_bsf_8_repeat_extend_encodeBlockAsm4MB: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP repeat_extend_forward_end_encodeBlockAsm4MB + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP repeat_extend_forward_end_encodeBlockAsm4MB matchlen_match4_repeat_extend_encodeBlockAsm4MB: CMPL R9, $0x04 @@ -2263,16 +2227,10 @@ matchlen_loopback_16_match_nolit_encodeBlockAsm4MB: JMP matchlen_loopback_16_match_nolit_encodeBlockAsm4MB matchlen_bsf_16match_nolit_encodeBlockAsm4MB: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_encodeBlockAsm4MB + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_encodeBlockAsm4MB matchlen_match8_match_nolit_encodeBlockAsm4MB: CMPL DI, $0x08 @@ -2285,16 +2243,10 @@ matchlen_match8_match_nolit_encodeBlockAsm4MB: JMP matchlen_match4_match_nolit_encodeBlockAsm4MB matchlen_bsf_8_match_nolit_encodeBlockAsm4MB: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_encodeBlockAsm4MB + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_encodeBlockAsm4MB matchlen_match4_match_nolit_encodeBlockAsm4MB: CMPL DI, $0x04 @@ -3006,16 +2958,10 @@ matchlen_loopback_16_repeat_extend_encodeBlockAsm12B: JMP matchlen_loopback_16_repeat_extend_encodeBlockAsm12B matchlen_bsf_16repeat_extend_encodeBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP repeat_extend_forward_end_encodeBlockAsm12B + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP repeat_extend_forward_end_encodeBlockAsm12B matchlen_match8_repeat_extend_encodeBlockAsm12B: CMPL R9, $0x08 @@ -3028,16 +2974,10 @@ matchlen_match8_repeat_extend_encodeBlockAsm12B: JMP matchlen_match4_repeat_extend_encodeBlockAsm12B matchlen_bsf_8_repeat_extend_encodeBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP repeat_extend_forward_end_encodeBlockAsm12B + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP repeat_extend_forward_end_encodeBlockAsm12B matchlen_match4_repeat_extend_encodeBlockAsm12B: CMPL R9, $0x04 @@ -3458,16 +3398,10 @@ matchlen_loopback_16_match_nolit_encodeBlockAsm12B: JMP matchlen_loopback_16_match_nolit_encodeBlockAsm12B matchlen_bsf_16match_nolit_encodeBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_encodeBlockAsm12B + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_encodeBlockAsm12B matchlen_match8_match_nolit_encodeBlockAsm12B: CMPL DI, $0x08 @@ -3480,16 +3414,10 @@ matchlen_match8_match_nolit_encodeBlockAsm12B: JMP matchlen_match4_match_nolit_encodeBlockAsm12B matchlen_bsf_8_match_nolit_encodeBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_encodeBlockAsm12B + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_encodeBlockAsm12B matchlen_match4_match_nolit_encodeBlockAsm12B: CMPL DI, $0x04 @@ -4091,16 +4019,10 @@ matchlen_loopback_16_repeat_extend_encodeBlockAsm10B: JMP matchlen_loopback_16_repeat_extend_encodeBlockAsm10B matchlen_bsf_16repeat_extend_encodeBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP repeat_extend_forward_end_encodeBlockAsm10B + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP repeat_extend_forward_end_encodeBlockAsm10B matchlen_match8_repeat_extend_encodeBlockAsm10B: CMPL R9, $0x08 @@ -4113,16 +4035,10 @@ matchlen_match8_repeat_extend_encodeBlockAsm10B: JMP matchlen_match4_repeat_extend_encodeBlockAsm10B matchlen_bsf_8_repeat_extend_encodeBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP repeat_extend_forward_end_encodeBlockAsm10B + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP repeat_extend_forward_end_encodeBlockAsm10B matchlen_match4_repeat_extend_encodeBlockAsm10B: CMPL R9, $0x04 @@ -4543,16 +4459,10 @@ matchlen_loopback_16_match_nolit_encodeBlockAsm10B: JMP matchlen_loopback_16_match_nolit_encodeBlockAsm10B matchlen_bsf_16match_nolit_encodeBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_encodeBlockAsm10B + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_encodeBlockAsm10B matchlen_match8_match_nolit_encodeBlockAsm10B: CMPL DI, $0x08 @@ -4565,16 +4475,10 @@ matchlen_match8_match_nolit_encodeBlockAsm10B: JMP matchlen_match4_match_nolit_encodeBlockAsm10B matchlen_bsf_8_match_nolit_encodeBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_encodeBlockAsm10B + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_encodeBlockAsm10B matchlen_match4_match_nolit_encodeBlockAsm10B: CMPL DI, $0x04 @@ -5176,16 +5080,10 @@ matchlen_loopback_16_repeat_extend_encodeBlockAsm8B: JMP matchlen_loopback_16_repeat_extend_encodeBlockAsm8B matchlen_bsf_16repeat_extend_encodeBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP repeat_extend_forward_end_encodeBlockAsm8B + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP repeat_extend_forward_end_encodeBlockAsm8B matchlen_match8_repeat_extend_encodeBlockAsm8B: CMPL R9, $0x08 @@ -5198,16 +5096,10 @@ matchlen_match8_repeat_extend_encodeBlockAsm8B: JMP matchlen_match4_repeat_extend_encodeBlockAsm8B matchlen_bsf_8_repeat_extend_encodeBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP repeat_extend_forward_end_encodeBlockAsm8B + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP repeat_extend_forward_end_encodeBlockAsm8B matchlen_match4_repeat_extend_encodeBlockAsm8B: CMPL R9, $0x04 @@ -5614,16 +5506,10 @@ matchlen_loopback_16_match_nolit_encodeBlockAsm8B: JMP matchlen_loopback_16_match_nolit_encodeBlockAsm8B matchlen_bsf_16match_nolit_encodeBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_encodeBlockAsm8B + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_encodeBlockAsm8B matchlen_match8_match_nolit_encodeBlockAsm8B: CMPL DI, $0x08 @@ -5636,16 +5522,10 @@ matchlen_match8_match_nolit_encodeBlockAsm8B: JMP matchlen_match4_match_nolit_encodeBlockAsm8B matchlen_bsf_8_match_nolit_encodeBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_encodeBlockAsm8B + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_encodeBlockAsm8B matchlen_match4_match_nolit_encodeBlockAsm8B: CMPL DI, $0x04 @@ -6140,16 +6020,10 @@ matchlen_loopback_16_match_nolit_encodeBetterBlockAsm: JMP matchlen_loopback_16_match_nolit_encodeBetterBlockAsm matchlen_bsf_16match_nolit_encodeBetterBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP match_nolit_end_encodeBetterBlockAsm + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP match_nolit_end_encodeBetterBlockAsm matchlen_match8_match_nolit_encodeBetterBlockAsm: CMPL R8, $0x08 @@ -6162,16 +6036,10 @@ matchlen_match8_match_nolit_encodeBetterBlockAsm: JMP matchlen_match4_match_nolit_encodeBetterBlockAsm matchlen_bsf_8_match_nolit_encodeBetterBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP match_nolit_end_encodeBetterBlockAsm + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP match_nolit_end_encodeBetterBlockAsm matchlen_match4_match_nolit_encodeBetterBlockAsm: CMPL R8, $0x04 @@ -7235,16 +7103,10 @@ matchlen_loopback_16_match_nolit_encodeBetterBlockAsm4MB: JMP matchlen_loopback_16_match_nolit_encodeBetterBlockAsm4MB matchlen_bsf_16match_nolit_encodeBetterBlockAsm4MB: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP match_nolit_end_encodeBetterBlockAsm4MB + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP match_nolit_end_encodeBetterBlockAsm4MB matchlen_match8_match_nolit_encodeBetterBlockAsm4MB: CMPL R8, $0x08 @@ -7257,16 +7119,10 @@ matchlen_match8_match_nolit_encodeBetterBlockAsm4MB: JMP matchlen_match4_match_nolit_encodeBetterBlockAsm4MB matchlen_bsf_8_match_nolit_encodeBetterBlockAsm4MB: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP match_nolit_end_encodeBetterBlockAsm4MB + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP match_nolit_end_encodeBetterBlockAsm4MB matchlen_match4_match_nolit_encodeBetterBlockAsm4MB: CMPL R8, $0x04 @@ -8256,16 +8112,10 @@ matchlen_loopback_16_match_nolit_encodeBetterBlockAsm12B: JMP matchlen_loopback_16_match_nolit_encodeBetterBlockAsm12B matchlen_bsf_16match_nolit_encodeBetterBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP match_nolit_end_encodeBetterBlockAsm12B + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP match_nolit_end_encodeBetterBlockAsm12B matchlen_match8_match_nolit_encodeBetterBlockAsm12B: CMPL R8, $0x08 @@ -8278,16 +8128,10 @@ matchlen_match8_match_nolit_encodeBetterBlockAsm12B: JMP matchlen_match4_match_nolit_encodeBetterBlockAsm12B matchlen_bsf_8_match_nolit_encodeBetterBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP match_nolit_end_encodeBetterBlockAsm12B + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP match_nolit_end_encodeBetterBlockAsm12B matchlen_match4_match_nolit_encodeBetterBlockAsm12B: CMPL R8, $0x04 @@ -9130,16 +8974,10 @@ matchlen_loopback_16_match_nolit_encodeBetterBlockAsm10B: JMP matchlen_loopback_16_match_nolit_encodeBetterBlockAsm10B matchlen_bsf_16match_nolit_encodeBetterBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP match_nolit_end_encodeBetterBlockAsm10B + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP match_nolit_end_encodeBetterBlockAsm10B matchlen_match8_match_nolit_encodeBetterBlockAsm10B: CMPL R8, $0x08 @@ -9152,16 +8990,10 @@ matchlen_match8_match_nolit_encodeBetterBlockAsm10B: JMP matchlen_match4_match_nolit_encodeBetterBlockAsm10B matchlen_bsf_8_match_nolit_encodeBetterBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP match_nolit_end_encodeBetterBlockAsm10B + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP match_nolit_end_encodeBetterBlockAsm10B matchlen_match4_match_nolit_encodeBetterBlockAsm10B: CMPL R8, $0x04 @@ -10004,16 +9836,10 @@ matchlen_loopback_16_match_nolit_encodeBetterBlockAsm8B: JMP matchlen_loopback_16_match_nolit_encodeBetterBlockAsm8B matchlen_bsf_16match_nolit_encodeBetterBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP match_nolit_end_encodeBetterBlockAsm8B + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP match_nolit_end_encodeBetterBlockAsm8B matchlen_match8_match_nolit_encodeBetterBlockAsm8B: CMPL R8, $0x08 @@ -10026,16 +9852,10 @@ matchlen_match8_match_nolit_encodeBetterBlockAsm8B: JMP matchlen_match4_match_nolit_encodeBetterBlockAsm8B matchlen_bsf_8_match_nolit_encodeBetterBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP match_nolit_end_encodeBetterBlockAsm8B + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP match_nolit_end_encodeBetterBlockAsm8B matchlen_match4_match_nolit_encodeBetterBlockAsm8B: CMPL R8, $0x04 @@ -10985,16 +10805,10 @@ matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm: JMP matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R12, R12 - -#else - BSFQ R12, R12 - -#endif - SARQ $0x03, R12 - LEAL 8(R11)(R12*1), R11 - JMP repeat_extend_forward_end_encodeSnappyBlockAsm + SARQ $0x03, R12 + LEAL 8(R11)(R12*1), R11 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm matchlen_match8_repeat_extend_encodeSnappyBlockAsm: CMPL R8, $0x08 @@ -11007,16 +10821,10 @@ matchlen_match8_repeat_extend_encodeSnappyBlockAsm: JMP matchlen_match4_repeat_extend_encodeSnappyBlockAsm matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R10, R10 - -#else - BSFQ R10, R10 - -#endif - SARQ $0x03, R10 - LEAL (R11)(R10*1), R11 - JMP repeat_extend_forward_end_encodeSnappyBlockAsm + SARQ $0x03, R10 + LEAL (R11)(R10*1), R11 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm matchlen_match4_repeat_extend_encodeSnappyBlockAsm: CMPL R8, $0x04 @@ -11329,16 +11137,10 @@ matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm: JMP matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm matchlen_bsf_16match_nolit_encodeSnappyBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_encodeSnappyBlockAsm + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_encodeSnappyBlockAsm matchlen_match8_match_nolit_encodeSnappyBlockAsm: CMPL DI, $0x08 @@ -11351,16 +11153,10 @@ matchlen_match8_match_nolit_encodeSnappyBlockAsm: JMP matchlen_match4_match_nolit_encodeSnappyBlockAsm matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_encodeSnappyBlockAsm + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_encodeSnappyBlockAsm matchlen_match4_match_nolit_encodeSnappyBlockAsm: CMPL DI, $0x04 @@ -11901,16 +11697,10 @@ matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm64K: JMP matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm64K matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm64K: -#ifdef GOAMD64_v3 TZCNTQ R12, R12 - -#else - BSFQ R12, R12 - -#endif - SARQ $0x03, R12 - LEAL 8(R11)(R12*1), R11 - JMP repeat_extend_forward_end_encodeSnappyBlockAsm64K + SARQ $0x03, R12 + LEAL 8(R11)(R12*1), R11 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm64K matchlen_match8_repeat_extend_encodeSnappyBlockAsm64K: CMPL R8, $0x08 @@ -11923,16 +11713,10 @@ matchlen_match8_repeat_extend_encodeSnappyBlockAsm64K: JMP matchlen_match4_repeat_extend_encodeSnappyBlockAsm64K matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm64K: -#ifdef GOAMD64_v3 TZCNTQ R10, R10 - -#else - BSFQ R10, R10 - -#endif - SARQ $0x03, R10 - LEAL (R11)(R10*1), R11 - JMP repeat_extend_forward_end_encodeSnappyBlockAsm64K + SARQ $0x03, R10 + LEAL (R11)(R10*1), R11 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm64K matchlen_match4_repeat_extend_encodeSnappyBlockAsm64K: CMPL R8, $0x04 @@ -12205,16 +11989,10 @@ matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm64K: JMP matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm64K matchlen_bsf_16match_nolit_encodeSnappyBlockAsm64K: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_encodeSnappyBlockAsm64K + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_encodeSnappyBlockAsm64K matchlen_match8_match_nolit_encodeSnappyBlockAsm64K: CMPL DI, $0x08 @@ -12227,16 +12005,10 @@ matchlen_match8_match_nolit_encodeSnappyBlockAsm64K: JMP matchlen_match4_match_nolit_encodeSnappyBlockAsm64K matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm64K: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_encodeSnappyBlockAsm64K + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_encodeSnappyBlockAsm64K matchlen_match4_match_nolit_encodeSnappyBlockAsm64K: CMPL DI, $0x04 @@ -12737,16 +12509,10 @@ matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm12B: JMP matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm12B matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R12, R12 - -#else - BSFQ R12, R12 - -#endif - SARQ $0x03, R12 - LEAL 8(R11)(R12*1), R11 - JMP repeat_extend_forward_end_encodeSnappyBlockAsm12B + SARQ $0x03, R12 + LEAL 8(R11)(R12*1), R11 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm12B matchlen_match8_repeat_extend_encodeSnappyBlockAsm12B: CMPL R8, $0x08 @@ -12759,16 +12525,10 @@ matchlen_match8_repeat_extend_encodeSnappyBlockAsm12B: JMP matchlen_match4_repeat_extend_encodeSnappyBlockAsm12B matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R10, R10 - -#else - BSFQ R10, R10 - -#endif - SARQ $0x03, R10 - LEAL (R11)(R10*1), R11 - JMP repeat_extend_forward_end_encodeSnappyBlockAsm12B + SARQ $0x03, R10 + LEAL (R11)(R10*1), R11 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm12B matchlen_match4_repeat_extend_encodeSnappyBlockAsm12B: CMPL R8, $0x04 @@ -13041,16 +12801,10 @@ matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm12B: JMP matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm12B matchlen_bsf_16match_nolit_encodeSnappyBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_encodeSnappyBlockAsm12B + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_encodeSnappyBlockAsm12B matchlen_match8_match_nolit_encodeSnappyBlockAsm12B: CMPL DI, $0x08 @@ -13063,16 +12817,10 @@ matchlen_match8_match_nolit_encodeSnappyBlockAsm12B: JMP matchlen_match4_match_nolit_encodeSnappyBlockAsm12B matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_encodeSnappyBlockAsm12B + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_encodeSnappyBlockAsm12B matchlen_match4_match_nolit_encodeSnappyBlockAsm12B: CMPL DI, $0x04 @@ -13573,16 +13321,10 @@ matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm10B: JMP matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm10B matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R12, R12 - -#else - BSFQ R12, R12 - -#endif - SARQ $0x03, R12 - LEAL 8(R11)(R12*1), R11 - JMP repeat_extend_forward_end_encodeSnappyBlockAsm10B + SARQ $0x03, R12 + LEAL 8(R11)(R12*1), R11 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm10B matchlen_match8_repeat_extend_encodeSnappyBlockAsm10B: CMPL R8, $0x08 @@ -13595,16 +13337,10 @@ matchlen_match8_repeat_extend_encodeSnappyBlockAsm10B: JMP matchlen_match4_repeat_extend_encodeSnappyBlockAsm10B matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R10, R10 - -#else - BSFQ R10, R10 - -#endif - SARQ $0x03, R10 - LEAL (R11)(R10*1), R11 - JMP repeat_extend_forward_end_encodeSnappyBlockAsm10B + SARQ $0x03, R10 + LEAL (R11)(R10*1), R11 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm10B matchlen_match4_repeat_extend_encodeSnappyBlockAsm10B: CMPL R8, $0x04 @@ -13877,16 +13613,10 @@ matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm10B: JMP matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm10B matchlen_bsf_16match_nolit_encodeSnappyBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_encodeSnappyBlockAsm10B + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_encodeSnappyBlockAsm10B matchlen_match8_match_nolit_encodeSnappyBlockAsm10B: CMPL DI, $0x08 @@ -13899,16 +13629,10 @@ matchlen_match8_match_nolit_encodeSnappyBlockAsm10B: JMP matchlen_match4_match_nolit_encodeSnappyBlockAsm10B matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_encodeSnappyBlockAsm10B + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_encodeSnappyBlockAsm10B matchlen_match4_match_nolit_encodeSnappyBlockAsm10B: CMPL DI, $0x04 @@ -14409,16 +14133,10 @@ matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm8B: JMP matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm8B matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R12, R12 - -#else - BSFQ R12, R12 - -#endif - SARQ $0x03, R12 - LEAL 8(R11)(R12*1), R11 - JMP repeat_extend_forward_end_encodeSnappyBlockAsm8B + SARQ $0x03, R12 + LEAL 8(R11)(R12*1), R11 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm8B matchlen_match8_repeat_extend_encodeSnappyBlockAsm8B: CMPL R8, $0x08 @@ -14431,16 +14149,10 @@ matchlen_match8_repeat_extend_encodeSnappyBlockAsm8B: JMP matchlen_match4_repeat_extend_encodeSnappyBlockAsm8B matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R10, R10 - -#else - BSFQ R10, R10 - -#endif - SARQ $0x03, R10 - LEAL (R11)(R10*1), R11 - JMP repeat_extend_forward_end_encodeSnappyBlockAsm8B + SARQ $0x03, R10 + LEAL (R11)(R10*1), R11 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm8B matchlen_match4_repeat_extend_encodeSnappyBlockAsm8B: CMPL R8, $0x04 @@ -14711,16 +14423,10 @@ matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm8B: JMP matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm8B matchlen_bsf_16match_nolit_encodeSnappyBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_encodeSnappyBlockAsm8B + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_encodeSnappyBlockAsm8B matchlen_match8_match_nolit_encodeSnappyBlockAsm8B: CMPL DI, $0x08 @@ -14733,16 +14439,10 @@ matchlen_match8_match_nolit_encodeSnappyBlockAsm8B: JMP matchlen_match4_match_nolit_encodeSnappyBlockAsm8B matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_encodeSnappyBlockAsm8B + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_encodeSnappyBlockAsm8B matchlen_match4_match_nolit_encodeSnappyBlockAsm8B: CMPL DI, $0x04 @@ -15144,16 +14844,10 @@ matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm: JMP matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP match_nolit_end_encodeSnappyBetterBlockAsm + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP match_nolit_end_encodeSnappyBetterBlockAsm matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm: CMPL R8, $0x08 @@ -15166,16 +14860,10 @@ matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm: JMP matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP match_nolit_end_encodeSnappyBetterBlockAsm + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP match_nolit_end_encodeSnappyBetterBlockAsm matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm: CMPL R8, $0x04 @@ -15790,16 +15478,10 @@ matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm64K: JMP matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm64K matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm64K: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP match_nolit_end_encodeSnappyBetterBlockAsm64K + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP match_nolit_end_encodeSnappyBetterBlockAsm64K matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm64K: CMPL R8, $0x08 @@ -15812,16 +15494,10 @@ matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm64K: JMP matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm64K matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm64K: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP match_nolit_end_encodeSnappyBetterBlockAsm64K + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP match_nolit_end_encodeSnappyBetterBlockAsm64K matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm64K: CMPL R8, $0x04 @@ -16371,16 +16047,10 @@ matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm12B: JMP matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm12B matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP match_nolit_end_encodeSnappyBetterBlockAsm12B + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP match_nolit_end_encodeSnappyBetterBlockAsm12B matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm12B: CMPL R8, $0x08 @@ -16393,16 +16063,10 @@ matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm12B: JMP matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm12B matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm12B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP match_nolit_end_encodeSnappyBetterBlockAsm12B + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP match_nolit_end_encodeSnappyBetterBlockAsm12B matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm12B: CMPL R8, $0x04 @@ -16952,16 +16616,10 @@ matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm10B: JMP matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm10B matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP match_nolit_end_encodeSnappyBetterBlockAsm10B + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP match_nolit_end_encodeSnappyBetterBlockAsm10B matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm10B: CMPL R8, $0x08 @@ -16974,16 +16632,10 @@ matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm10B: JMP matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm10B matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm10B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP match_nolit_end_encodeSnappyBetterBlockAsm10B + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP match_nolit_end_encodeSnappyBetterBlockAsm10B matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm10B: CMPL R8, $0x04 @@ -17533,16 +17185,10 @@ matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm8B: JMP matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm8B matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R13, R13 - -#else - BSFQ R13, R13 - -#endif - SARQ $0x03, R13 - LEAL 8(R12)(R13*1), R12 - JMP match_nolit_end_encodeSnappyBetterBlockAsm8B + SARQ $0x03, R13 + LEAL 8(R12)(R13*1), R12 + JMP match_nolit_end_encodeSnappyBetterBlockAsm8B matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm8B: CMPL R8, $0x08 @@ -17555,16 +17201,10 @@ matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm8B: JMP matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm8B matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm8B: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL (R12)(R11*1), R12 - JMP match_nolit_end_encodeSnappyBetterBlockAsm8B + SARQ $0x03, R11 + LEAL (R12)(R11*1), R12 + JMP match_nolit_end_encodeSnappyBetterBlockAsm8B matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm8B: CMPL R8, $0x04 @@ -18138,16 +17778,10 @@ matchlen_loopback_16_repeat_extend_calcBlockSize: JMP matchlen_loopback_16_repeat_extend_calcBlockSize matchlen_bsf_16repeat_extend_calcBlockSize: -#ifdef GOAMD64_v3 TZCNTQ R12, R12 - -#else - BSFQ R12, R12 - -#endif - SARQ $0x03, R12 - LEAL 8(R11)(R12*1), R11 - JMP repeat_extend_forward_end_calcBlockSize + SARQ $0x03, R12 + LEAL 8(R11)(R12*1), R11 + JMP repeat_extend_forward_end_calcBlockSize matchlen_match8_repeat_extend_calcBlockSize: CMPL R8, $0x08 @@ -18160,16 +17794,10 @@ matchlen_match8_repeat_extend_calcBlockSize: JMP matchlen_match4_repeat_extend_calcBlockSize matchlen_bsf_8_repeat_extend_calcBlockSize: -#ifdef GOAMD64_v3 TZCNTQ R10, R10 - -#else - BSFQ R10, R10 - -#endif - SARQ $0x03, R10 - LEAL (R11)(R10*1), R11 - JMP repeat_extend_forward_end_calcBlockSize + SARQ $0x03, R10 + LEAL (R11)(R10*1), R11 + JMP repeat_extend_forward_end_calcBlockSize matchlen_match4_repeat_extend_calcBlockSize: CMPL R8, $0x04 @@ -18371,16 +17999,10 @@ matchlen_loopback_16_match_nolit_calcBlockSize: JMP matchlen_loopback_16_match_nolit_calcBlockSize matchlen_bsf_16match_nolit_calcBlockSize: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_calcBlockSize + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_calcBlockSize matchlen_match8_match_nolit_calcBlockSize: CMPL DI, $0x08 @@ -18393,16 +18015,10 @@ matchlen_match8_match_nolit_calcBlockSize: JMP matchlen_match4_match_nolit_calcBlockSize matchlen_bsf_8_match_nolit_calcBlockSize: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_calcBlockSize + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_calcBlockSize matchlen_match4_match_nolit_calcBlockSize: CMPL DI, $0x04 @@ -18723,16 +18339,10 @@ matchlen_loopback_16_repeat_extend_calcBlockSizeSmall: JMP matchlen_loopback_16_repeat_extend_calcBlockSizeSmall matchlen_bsf_16repeat_extend_calcBlockSizeSmall: -#ifdef GOAMD64_v3 TZCNTQ R12, R12 - -#else - BSFQ R12, R12 - -#endif - SARQ $0x03, R12 - LEAL 8(R11)(R12*1), R11 - JMP repeat_extend_forward_end_calcBlockSizeSmall + SARQ $0x03, R12 + LEAL 8(R11)(R12*1), R11 + JMP repeat_extend_forward_end_calcBlockSizeSmall matchlen_match8_repeat_extend_calcBlockSizeSmall: CMPL R8, $0x08 @@ -18745,16 +18355,10 @@ matchlen_match8_repeat_extend_calcBlockSizeSmall: JMP matchlen_match4_repeat_extend_calcBlockSizeSmall matchlen_bsf_8_repeat_extend_calcBlockSizeSmall: -#ifdef GOAMD64_v3 TZCNTQ R10, R10 - -#else - BSFQ R10, R10 - -#endif - SARQ $0x03, R10 - LEAL (R11)(R10*1), R11 - JMP repeat_extend_forward_end_calcBlockSizeSmall + SARQ $0x03, R10 + LEAL (R11)(R10*1), R11 + JMP repeat_extend_forward_end_calcBlockSizeSmall matchlen_match4_repeat_extend_calcBlockSizeSmall: CMPL R8, $0x04 @@ -18926,16 +18530,10 @@ matchlen_loopback_16_match_nolit_calcBlockSizeSmall: JMP matchlen_loopback_16_match_nolit_calcBlockSizeSmall matchlen_bsf_16match_nolit_calcBlockSizeSmall: -#ifdef GOAMD64_v3 TZCNTQ R11, R11 - -#else - BSFQ R11, R11 - -#endif - SARQ $0x03, R11 - LEAL 8(R10)(R11*1), R10 - JMP match_nolit_end_calcBlockSizeSmall + SARQ $0x03, R11 + LEAL 8(R10)(R11*1), R10 + JMP match_nolit_end_calcBlockSizeSmall matchlen_match8_match_nolit_calcBlockSizeSmall: CMPL DI, $0x08 @@ -18948,16 +18546,10 @@ matchlen_match8_match_nolit_calcBlockSizeSmall: JMP matchlen_match4_match_nolit_calcBlockSizeSmall matchlen_bsf_8_match_nolit_calcBlockSizeSmall: -#ifdef GOAMD64_v3 TZCNTQ R9, R9 - -#else - BSFQ R9, R9 - -#endif - SARQ $0x03, R9 - LEAL (R10)(R9*1), R10 - JMP match_nolit_end_calcBlockSizeSmall + SARQ $0x03, R9 + LEAL (R10)(R9*1), R10 + JMP match_nolit_end_calcBlockSizeSmall matchlen_match4_match_nolit_calcBlockSizeSmall: CMPL DI, $0x04 @@ -19737,16 +19329,10 @@ matchlen_loopback_16_standalone: JMP matchlen_loopback_16_standalone matchlen_bsf_16standalone: -#ifdef GOAMD64_v3 TZCNTQ DI, DI - -#else - BSFQ DI, DI - -#endif - SARQ $0x03, DI - LEAL 8(SI)(DI*1), SI - JMP gen_match_len_end + SARQ $0x03, DI + LEAL 8(SI)(DI*1), SI + JMP gen_match_len_end matchlen_match8_standalone: CMPL DX, $0x08 @@ -19759,16 +19345,10 @@ matchlen_match8_standalone: JMP matchlen_match4_standalone matchlen_bsf_8_standalone: -#ifdef GOAMD64_v3 TZCNTQ BX, BX - -#else - BSFQ BX, BX - -#endif - SARQ $0x03, BX - LEAL (SI)(BX*1), SI - JMP gen_match_len_end + SARQ $0x03, BX + LEAL (SI)(BX*1), SI + JMP gen_match_len_end matchlen_match4_standalone: CMPL DX, $0x04 diff --git a/src/vendor/github.com/klauspost/compress/s2/encodeblock_arm64.s b/src/vendor/github.com/klauspost/compress/s2/encodeblock_arm64.s new file mode 100644 index 00000000..cfcb9e40 --- /dev/null +++ b/src/vendor/github.com/klauspost/compress/s2/encodeblock_arm64.s @@ -0,0 +1,23562 @@ +// Code generated by command: go run gen.go -out ../encodeblock.s -arch arm64 -arm64gen -pkg=s2. DO NOT EDIT. +// EXPERIMENTAL arm64 output lowered from an amd64 avo program. + +//go:build arm64 && ((amd64 || arm64) && !appengine && !noasm && gc && !noasm) + +#include "textflag.h" + +// func encodeBlockAsm(dst []byte, src []byte, tmp *[65536]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeBlockAsm(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000200, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeBlockAsm: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeBlockAsm + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeBlockAsm: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x06, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeBlockAsm + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + LSL $0x10, R10, R10 + MUL R8, R10, R10 + LSR $0x32, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_encodeBlockAsm + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R7 + MOVWU R6, R5 + MOVWU 24(RSP), R16 + SUBSW R16, R5, R5 + BEQ repeat_extend_back_end_encodeBlockAsm + +repeat_extend_back_loop_encodeBlockAsm: + CMPW R7, R6 + BLS repeat_extend_back_end_encodeBlockAsm + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_encodeBlockAsm + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R5, R5 + BNE repeat_extend_back_loop_encodeBlockAsm + +repeat_extend_back_end_encodeBlockAsm: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $5, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_encodeBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +repeat_dst_size_check_encodeBlockAsm: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_encodeBlockAsm + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_encodeBlockAsm + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_encodeBlockAsm + CMPW $0x00010000, R5 + BLO three_bytes_repeat_emit_encodeBlockAsm + CMPW $0x01000000, R5 + BLO four_bytes_repeat_emit_encodeBlockAsm + MOVD $0xfc, R16 + MOVB R16, (R1) + MOVW R5, 1(R1) + ADD $0x05, R1, R1 + JMP memmove_long_repeat_emit_encodeBlockAsm + +four_bytes_repeat_emit_encodeBlockAsm: + MOVWU R5, R10 + LSRW $0x10, R10, R10 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + MOVB R10, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_repeat_emit_encodeBlockAsm + +three_bytes_repeat_emit_encodeBlockAsm: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_encodeBlockAsm + +two_bytes_repeat_emit_encodeBlockAsm: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_encodeBlockAsm + JMP memmove_long_repeat_emit_encodeBlockAsm + +one_byte_repeat_emit_encodeBlockAsm: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_repeat_emit_encodeBlockAsm: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm_memmove_move_17through32 + JMP emit_lit_memmove_repeat_emit_encodeBlockAsm_memmove_move_33through64 + +emit_lit_memmove_repeat_emit_encodeBlockAsm_memmove_move_8: + MOVD (R9), R10 + MOVD R10, (R1) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm + +emit_lit_memmove_repeat_emit_encodeBlockAsm_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm + +emit_lit_memmove_repeat_emit_encodeBlockAsm_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm + +emit_lit_memmove_repeat_emit_encodeBlockAsm_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_repeat_emit_encodeBlockAsm: + MOVD R5, R1 + JMP emit_literal_done_repeat_emit_encodeBlockAsm + +memmove_long_repeat_emit_encodeBlockAsm: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R11 + MOVD R8, R12 + +emit_lit_memmove_long_repeat_emit_encodeBlockAsmlarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R11) + FMOVQ F1, 16(R11) + ADD $0x20, R10, R10 + ADD $0x20, R11, R11 + SUB $0x20, R12, R12 + CMP $0x20, R12 + BHS emit_lit_memmove_long_repeat_emit_encodeBlockAsmlarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_repeat_emit_encodeBlockAsm: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+32(FP), R8 + SUBW R2, R8, R8 + ADD R2, R3, R9 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_repeat_extend_encodeBlockAsm: + CMPW $0x10, R8 + BLO matchlen_match8_repeat_extend_encodeBlockAsm + MOVD (R9)(R11), R10 + ADD R11, R9, R15 + MOVD 8(R15), R12 + MOVD (R5)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_repeat_extend_encodeBlockAsm + ADD R11, R5, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16repeat_extend_encodeBlockAsm + SUB $16, R8, R8 + MOVWU R8, R8 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_repeat_extend_encodeBlockAsm + +matchlen_bsf_16repeat_extend_encodeBlockAsm: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP repeat_extend_forward_end_encodeBlockAsm + +matchlen_match8_repeat_extend_encodeBlockAsm: + CMPW $0x08, R8 + BLO matchlen_match4_repeat_extend_encodeBlockAsm + MOVD (R9)(R11), R10 + MOVD (R5)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_repeat_extend_encodeBlockAsm + SUB $8, R8, R8 + MOVWU R8, R8 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_repeat_extend_encodeBlockAsm + +matchlen_bsf_8_repeat_extend_encodeBlockAsm: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP repeat_extend_forward_end_encodeBlockAsm + +matchlen_match4_repeat_extend_encodeBlockAsm: + CMPW $0x04, R8 + BLO matchlen_match2_repeat_extend_encodeBlockAsm + MOVWU (R9)(R11), R10 + MOVWU (R5)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_repeat_extend_encodeBlockAsm + SUB $4, R8, R8 + MOVWU R8, R8 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_repeat_extend_encodeBlockAsm: + CMPW $0x01, R8 + BEQ matchlen_match1_repeat_extend_encodeBlockAsm + BLO repeat_extend_forward_end_encodeBlockAsm + MOVHU (R9)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_encodeBlockAsm + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R8, R8 + BEQ repeat_extend_forward_end_encodeBlockAsm + +matchlen_match1_repeat_extend_encodeBlockAsm: + MOVBU (R9)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R5, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_encodeBlockAsm + ADD $1, R11, R11 + MOVWU R11, R11 + +repeat_extend_forward_end_encodeBlockAsm: + ADDW R11, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + TSTW R7, R7 + BEQ repeat_as_copy_encodeBlockAsm + + // emitRepeat +emit_repeat_again_match_repeat_encodeBlockAsm: + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_match_repeat_encodeBlockAsm + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_match_repeat_encodeBlockAsm + CMPW $0x00000800, R6 + BLO repeat_two_offset_match_repeat_encodeBlockAsm + +cant_repeat_two_offset_match_repeat_encodeBlockAsm: + CMPW $0x00000104, R5 + BLO repeat_three_match_repeat_encodeBlockAsm + CMPW $0x00010100, R5 + BLO repeat_four_match_repeat_encodeBlockAsm + CMPW $0x0100ffff, R5 + BLO repeat_five_match_repeat_encodeBlockAsm + SUB $16842747, R5, R5 + MOVWU R5, R5 + MOVD $0xfffb001d, R16 + MOVW R16, (R1) + MOVD $0xff, R16 + MOVB R16, 4(R1) + ADD $0x05, R1, R1 + JMP emit_repeat_again_match_repeat_encodeBlockAsm + +repeat_five_match_repeat_encodeBlockAsm: + SUB $65536, R5, R5 + MOVWU R5, R5 + MOVWU R5, R6 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ASRW $0x10, R6, R6 + MOVB R6, 4(R1) + ADD $0x05, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_four_match_repeat_encodeBlockAsm: + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_three_match_repeat_encodeBlockAsm: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_two_match_repeat_encodeBlockAsm: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_two_offset_match_repeat_encodeBlockAsm: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_as_copy_encodeBlockAsm: + // emitCopy + CMPW $0x00010000, R6 + BLO two_byte_offset_repeat_as_copy_encodeBlockAsm + CMPW $0x40, R5 + BLS four_bytes_remain_repeat_as_copy_encodeBlockAsm + MOVD $0xff, R16 + MOVB R16, (R1) + MOVW R6, 1(R1) + SUB $64, R5, R5 + MOVWU R5, R5 + ADD $0x05, R1, R1 + CMPW $0x04, R5 + BLO four_bytes_remain_repeat_as_copy_encodeBlockAsm + + // emitRepeat +emit_repeat_again_repeat_as_copy_encodeBlockAsm_emit_copy: + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_repeat_as_copy_encodeBlockAsm_emit_copy + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy + CMPW $0x00000800, R6 + BLO repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm_emit_copy + CMPW $0x00010100, R5 + BLO repeat_four_repeat_as_copy_encodeBlockAsm_emit_copy + CMPW $0x0100ffff, R5 + BLO repeat_five_repeat_as_copy_encodeBlockAsm_emit_copy + SUB $16842747, R5, R5 + MOVWU R5, R5 + MOVD $0xfffb001d, R16 + MOVW R16, (R1) + MOVD $0xff, R16 + MOVB R16, 4(R1) + ADD $0x05, R1, R1 + JMP emit_repeat_again_repeat_as_copy_encodeBlockAsm_emit_copy + +repeat_five_repeat_as_copy_encodeBlockAsm_emit_copy: + SUB $65536, R5, R5 + MOVWU R5, R5 + MOVWU R5, R6 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ASRW $0x10, R6, R6 + MOVB R6, 4(R1) + ADD $0x05, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_four_repeat_as_copy_encodeBlockAsm_emit_copy: + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_three_repeat_as_copy_encodeBlockAsm_emit_copy: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_two_repeat_as_copy_encodeBlockAsm_emit_copy: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +four_bytes_remain_repeat_as_copy_encodeBlockAsm: + TSTW R5, R5 + BEQ repeat_end_emit_encodeBlockAsm + MOVD $0, R7 + ADD R5<<2, R7, R5 + SUB $1, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVW R6, 1(R1) + ADD $0x05, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +two_byte_offset_repeat_as_copy_encodeBlockAsm: + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_encodeBlockAsm + CMPW $0x00000800, R6 + BHS long_offset_short_repeat_as_copy_encodeBlockAsm + MOVD $0x00000001, R7 + ADD $16, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + MOVWU R6, R8 + LSRW $0x08, R8, R8 + LSLW $0x05, R8, R8 + ORRW R8, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R5, R5 + + // emitRepeat + SUB $4, R5, R5 + MOVWU R5, R5 + JMP cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b + +emit_repeat_again_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b: + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b + CMPW $0x00000800, R6 + BLO repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b + CMPW $0x00010100, R5 + BLO repeat_four_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b + CMPW $0x0100ffff, R5 + BLO repeat_five_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b + SUB $16842747, R5, R5 + MOVWU R5, R5 + MOVD $0xfffb001d, R16 + MOVW R16, (R1) + MOVD $0xff, R16 + MOVB R16, 4(R1) + ADD $0x05, R1, R1 + JMP emit_repeat_again_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b + +repeat_five_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b: + SUB $65536, R5, R5 + MOVWU R5, R5 + MOVWU R5, R6 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ASRW $0x10, R6, R6 + MOVB R6, 4(R1) + ADD $0x05, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_four_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b: + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_three_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_two_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy_short_2b: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +long_offset_short_repeat_as_copy_encodeBlockAsm: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R6, 1(R1) + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + + // emitRepeat +emit_repeat_again_repeat_as_copy_encodeBlockAsm_emit_copy_short: + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_repeat_as_copy_encodeBlockAsm_emit_copy_short + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy_short + CMPW $0x00000800, R6 + BLO repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy_short + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy_short: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm_emit_copy_short + CMPW $0x00010100, R5 + BLO repeat_four_repeat_as_copy_encodeBlockAsm_emit_copy_short + CMPW $0x0100ffff, R5 + BLO repeat_five_repeat_as_copy_encodeBlockAsm_emit_copy_short + SUB $16842747, R5, R5 + MOVWU R5, R5 + MOVD $0xfffb001d, R16 + MOVW R16, (R1) + MOVD $0xff, R16 + MOVB R16, 4(R1) + ADD $0x05, R1, R1 + JMP emit_repeat_again_repeat_as_copy_encodeBlockAsm_emit_copy_short + +repeat_five_repeat_as_copy_encodeBlockAsm_emit_copy_short: + SUB $65536, R5, R5 + MOVWU R5, R5 + MOVWU R5, R6 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ASRW $0x10, R6, R6 + MOVB R6, 4(R1) + ADD $0x05, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_four_repeat_as_copy_encodeBlockAsm_emit_copy_short: + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_three_repeat_as_copy_encodeBlockAsm_emit_copy_short: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_two_repeat_as_copy_encodeBlockAsm_emit_copy_short: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +repeat_two_offset_repeat_as_copy_encodeBlockAsm_emit_copy_short: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +two_byte_offset_short_repeat_as_copy_encodeBlockAsm: + MOVWU R5, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_encodeBlockAsm + CMPW $0x00000800, R6 + BHS emit_copy_three_repeat_as_copy_encodeBlockAsm + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm + +emit_copy_three_repeat_as_copy_encodeBlockAsm: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R1) + MOVH R6, 1(R1) + ADD $0x03, R1, R1 + +repeat_end_emit_encodeBlockAsm: + MOVW R2, 20(RSP) + JMP search_loop_encodeBlockAsm + +no_repeat_found_encodeBlockAsm: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeBlockAsm + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_encodeBlockAsm + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_encodeBlockAsm + MOVWU 28(RSP), R2 + JMP search_loop_encodeBlockAsm + +candidate3_match_encodeBlockAsm: + ADDW $0x02, R2, R2 + JMP candidate_match_encodeBlockAsm + +candidate2_match_encodeBlockAsm: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeBlockAsm: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeBlockAsm + +match_extend_back_loop_encodeBlockAsm: + CMPW R6, R2 + BLS match_extend_back_end_encodeBlockAsm + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeBlockAsm + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeBlockAsm + JMP match_extend_back_loop_encodeBlockAsm + +match_extend_back_end_encodeBlockAsm: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $5, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeBlockAsm: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_encodeBlockAsm + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R7 + MOVWU R7, R7 + CMPW $0x3c, R7 + BLO one_byte_match_emit_encodeBlockAsm + CMPW $0x00000100, R7 + BLO two_bytes_match_emit_encodeBlockAsm + CMPW $0x00010000, R7 + BLO three_bytes_match_emit_encodeBlockAsm + CMPW $0x01000000, R7 + BLO four_bytes_match_emit_encodeBlockAsm + MOVD $0xfc, R16 + MOVB R16, (R1) + MOVW R7, 1(R1) + ADD $0x05, R1, R1 + JMP memmove_long_match_emit_encodeBlockAsm + +four_bytes_match_emit_encodeBlockAsm: + MOVWU R7, R9 + LSRW $0x10, R9, R9 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + MOVB R9, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_match_emit_encodeBlockAsm + +three_bytes_match_emit_encodeBlockAsm: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeBlockAsm + +two_bytes_match_emit_encodeBlockAsm: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R7, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R7 + BLO memmove_match_emit_encodeBlockAsm + JMP memmove_long_match_emit_encodeBlockAsm + +one_byte_match_emit_encodeBlockAsm: + LSLW $0x02, R7, R16 + BFI $0, R16, $8, R7 + MOVB R7, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeBlockAsm: + ADD R8, R1, R7 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeBlockAsm_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeBlockAsm_memmove_move_8: + MOVD (R6), R9 + MOVD R9, (R1) + JMP memmove_end_copy_match_emit_encodeBlockAsm + +emit_lit_memmove_match_emit_encodeBlockAsm_memmove_move_8through16: + MOVD (R6), R9 + ADD R8, R6, R15 + MOVD -8(R15), R6 + MOVD R9, (R1) + ADD R8, R1, R15 + MOVD R6, -8(R15) + JMP memmove_end_copy_match_emit_encodeBlockAsm + +emit_lit_memmove_match_emit_encodeBlockAsm_memmove_move_17through32: + FMOVQ (R6), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeBlockAsm + +emit_lit_memmove_match_emit_encodeBlockAsm_memmove_move_33through64: + FMOVQ (R6), F0 + FMOVQ 16(R6), F1 + ADD R8, R6, R15 + FMOVQ -32(R15), F2 + ADD R8, R6, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeBlockAsm: + MOVD R7, R1 + JMP emit_literal_done_match_emit_encodeBlockAsm + +memmove_long_match_emit_encodeBlockAsm: + ADD R8, R1, R7 + + // genMemMoveLong + MOVD R6, R9 + MOVD R1, R10 + MOVD R8, R11 + +emit_lit_memmove_long_match_emit_encodeBlockAsmlarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_match_emit_encodeBlockAsmlarge_big_loop_back + ADD R8, R6, R15 + FMOVQ -32(R15), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R7, R1 + +emit_literal_done_match_emit_encodeBlockAsm: +match_nolit_loop_encodeBlockAsm: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_encodeBlockAsm: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_encodeBlockAsm + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeBlockAsm + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_encodeBlockAsm + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_encodeBlockAsm + +matchlen_bsf_16match_nolit_encodeBlockAsm: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeBlockAsm + +matchlen_match8_match_nolit_encodeBlockAsm: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_encodeBlockAsm + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeBlockAsm + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_encodeBlockAsm + +matchlen_bsf_8_match_nolit_encodeBlockAsm: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeBlockAsm + +matchlen_match4_match_nolit_encodeBlockAsm: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_encodeBlockAsm + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_encodeBlockAsm + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_encodeBlockAsm: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_encodeBlockAsm + BLO match_nolit_end_encodeBlockAsm + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeBlockAsm + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_encodeBlockAsm + +matchlen_match1_match_nolit_encodeBlockAsm: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_encodeBlockAsm + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_encodeBlockAsm: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x00010000, R5 + BLO two_byte_offset_match_nolit_encodeBlockAsm + CMPW $0x40, R9 + BLS four_bytes_remain_match_nolit_encodeBlockAsm + MOVD $0xff, R16 + MOVB R16, (R1) + MOVW R5, 1(R1) + SUB $64, R9, R9 + MOVWU R9, R9 + ADD $0x05, R1, R1 + CMPW $0x04, R9 + BLO four_bytes_remain_match_nolit_encodeBlockAsm + + // emitRepeat +emit_repeat_again_match_nolit_encodeBlockAsm_emit_copy: + MOVWU R9, R6 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R6 + BLS repeat_two_match_nolit_encodeBlockAsm_emit_copy + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy + CMPW $0x00000800, R5 + BLO repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy + +cant_repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm_emit_copy + CMPW $0x00010100, R9 + BLO repeat_four_match_nolit_encodeBlockAsm_emit_copy + CMPW $0x0100ffff, R9 + BLO repeat_five_match_nolit_encodeBlockAsm_emit_copy + SUB $16842747, R9, R9 + MOVWU R9, R9 + MOVD $0xfffb001d, R16 + MOVW R16, (R1) + MOVD $0xff, R16 + MOVB R16, 4(R1) + ADD $0x05, R1, R1 + JMP emit_repeat_again_match_nolit_encodeBlockAsm_emit_copy + +repeat_five_match_nolit_encodeBlockAsm_emit_copy: + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R5 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ASRW $0x10, R5, R5 + MOVB R5, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_four_match_nolit_encodeBlockAsm_emit_copy: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_three_match_nolit_encodeBlockAsm_emit_copy: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_two_match_nolit_encodeBlockAsm_emit_copy: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy: + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +four_bytes_remain_match_nolit_encodeBlockAsm: + TSTW R9, R9 + BEQ match_nolit_emitcopy_end_encodeBlockAsm + MOVD $0, R6 + ADD R9<<2, R6, R9 + SUB $1, R9, R9 + MOVWU R9, R9 + MOVB R9, (R1) + MOVW R5, 1(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +two_byte_offset_match_nolit_encodeBlockAsm: + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_encodeBlockAsm + CMPW $0x00000800, R5 + BHS long_offset_short_match_nolit_encodeBlockAsm + MOVD $0x00000001, R6 + ADD $16, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + MOVWU R5, R7 + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R9, R9 + + // emitRepeat + SUB $4, R9, R9 + MOVWU R9, R9 + JMP cant_repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy_short_2b + +emit_repeat_again_match_nolit_encodeBlockAsm_emit_copy_short_2b: + MOVWU R9, R6 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R6 + BLS repeat_two_match_nolit_encodeBlockAsm_emit_copy_short_2b + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy_short_2b + CMPW $0x00000800, R5 + BLO repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy_short_2b + +cant_repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy_short_2b: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm_emit_copy_short_2b + CMPW $0x00010100, R9 + BLO repeat_four_match_nolit_encodeBlockAsm_emit_copy_short_2b + CMPW $0x0100ffff, R9 + BLO repeat_five_match_nolit_encodeBlockAsm_emit_copy_short_2b + SUB $16842747, R9, R9 + MOVWU R9, R9 + MOVD $0xfffb001d, R16 + MOVW R16, (R1) + MOVD $0xff, R16 + MOVB R16, 4(R1) + ADD $0x05, R1, R1 + JMP emit_repeat_again_match_nolit_encodeBlockAsm_emit_copy_short_2b + +repeat_five_match_nolit_encodeBlockAsm_emit_copy_short_2b: + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R5 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ASRW $0x10, R5, R5 + MOVB R5, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_four_match_nolit_encodeBlockAsm_emit_copy_short_2b: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_three_match_nolit_encodeBlockAsm_emit_copy_short_2b: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_two_match_nolit_encodeBlockAsm_emit_copy_short_2b: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy_short_2b: + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +long_offset_short_match_nolit_encodeBlockAsm: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + + // emitRepeat +emit_repeat_again_match_nolit_encodeBlockAsm_emit_copy_short: + MOVWU R9, R6 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R6 + BLS repeat_two_match_nolit_encodeBlockAsm_emit_copy_short + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy_short + CMPW $0x00000800, R5 + BLO repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy_short + +cant_repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy_short: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm_emit_copy_short + CMPW $0x00010100, R9 + BLO repeat_four_match_nolit_encodeBlockAsm_emit_copy_short + CMPW $0x0100ffff, R9 + BLO repeat_five_match_nolit_encodeBlockAsm_emit_copy_short + SUB $16842747, R9, R9 + MOVWU R9, R9 + MOVD $0xfffb001d, R16 + MOVW R16, (R1) + MOVD $0xff, R16 + MOVB R16, 4(R1) + ADD $0x05, R1, R1 + JMP emit_repeat_again_match_nolit_encodeBlockAsm_emit_copy_short + +repeat_five_match_nolit_encodeBlockAsm_emit_copy_short: + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R5 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ASRW $0x10, R5, R5 + MOVB R5, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_four_match_nolit_encodeBlockAsm_emit_copy_short: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_three_match_nolit_encodeBlockAsm_emit_copy_short: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_two_match_nolit_encodeBlockAsm_emit_copy_short: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +repeat_two_offset_match_nolit_encodeBlockAsm_emit_copy_short: + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +two_byte_offset_short_match_nolit_encodeBlockAsm: + MOVWU R9, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_encodeBlockAsm + CMPW $0x00000800, R5 + BHS emit_copy_three_match_nolit_encodeBlockAsm + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm + +emit_copy_three_match_nolit_encodeBlockAsm: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeBlockAsm: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeBlockAsm + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeBlockAsm: + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x10, R7, R7 + MUL R8, R7, R7 + LSR $0x32, R7, R7 + LSL $0x10, R5, R5 + MUL R8, R5, R5 + LSR $0x32, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_encodeBlockAsm + ADDW $1, R2, R2 + JMP search_loop_encodeBlockAsm + +emit_remainder_encodeBlockAsm: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $5, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeBlockAsm: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeBlockAsm + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeBlockAsm + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeBlockAsm + CMPW $0x00010000, R2 + BLO three_bytes_emit_remainder_encodeBlockAsm + CMPW $0x01000000, R2 + BLO four_bytes_emit_remainder_encodeBlockAsm + MOVD $0xfc, R16 + MOVB R16, (R1) + MOVW R2, 1(R1) + ADD $0x05, R1, R1 + JMP memmove_long_emit_remainder_encodeBlockAsm + +four_bytes_emit_remainder_encodeBlockAsm: + MOVWU R2, R3 + LSRW $0x10, R3, R3 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + MOVB R3, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_emit_remainder_encodeBlockAsm + +three_bytes_emit_remainder_encodeBlockAsm: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeBlockAsm + +two_bytes_emit_remainder_encodeBlockAsm: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeBlockAsm + JMP memmove_long_emit_remainder_encodeBlockAsm + +one_byte_emit_remainder_encodeBlockAsm: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeBlockAsm: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm + +emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm + +emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm + +emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm + +emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm + +emit_lit_memmove_emit_remainder_encodeBlockAsm_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeBlockAsm: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeBlockAsm + +memmove_long_emit_remainder_encodeBlockAsm: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeBlockAsmlarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeBlockAsmlarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeBlockAsm: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeBlockAsm4MB(dst []byte, src []byte, tmp *[65536]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeBlockAsm4MB(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000200, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeBlockAsm4MB: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeBlockAsm4MB + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeBlockAsm4MB: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x06, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeBlockAsm4MB + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + LSL $0x10, R10, R10 + MUL R8, R10, R10 + LSR $0x32, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_encodeBlockAsm4MB + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R7 + MOVWU R6, R5 + MOVWU 24(RSP), R16 + SUBSW R16, R5, R5 + BEQ repeat_extend_back_end_encodeBlockAsm4MB + +repeat_extend_back_loop_encodeBlockAsm4MB: + CMPW R7, R6 + BLS repeat_extend_back_end_encodeBlockAsm4MB + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_encodeBlockAsm4MB + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R5, R5 + BNE repeat_extend_back_loop_encodeBlockAsm4MB + +repeat_extend_back_end_encodeBlockAsm4MB: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $4, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_encodeBlockAsm4MB + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +repeat_dst_size_check_encodeBlockAsm4MB: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_encodeBlockAsm4MB + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_encodeBlockAsm4MB + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_encodeBlockAsm4MB + CMPW $0x00010000, R5 + BLO three_bytes_repeat_emit_encodeBlockAsm4MB + MOVWU R5, R10 + LSRW $0x10, R10, R10 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + MOVB R10, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_repeat_emit_encodeBlockAsm4MB + +three_bytes_repeat_emit_encodeBlockAsm4MB: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_encodeBlockAsm4MB + +two_bytes_repeat_emit_encodeBlockAsm4MB: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_encodeBlockAsm4MB + JMP memmove_long_repeat_emit_encodeBlockAsm4MB + +one_byte_repeat_emit_encodeBlockAsm4MB: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_repeat_emit_encodeBlockAsm4MB: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm4MB_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm4MB_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm4MB_memmove_move_17through32 + JMP emit_lit_memmove_repeat_emit_encodeBlockAsm4MB_memmove_move_33through64 + +emit_lit_memmove_repeat_emit_encodeBlockAsm4MB_memmove_move_8: + MOVD (R9), R10 + MOVD R10, (R1) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm4MB + +emit_lit_memmove_repeat_emit_encodeBlockAsm4MB_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm4MB + +emit_lit_memmove_repeat_emit_encodeBlockAsm4MB_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm4MB + +emit_lit_memmove_repeat_emit_encodeBlockAsm4MB_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_repeat_emit_encodeBlockAsm4MB: + MOVD R5, R1 + JMP emit_literal_done_repeat_emit_encodeBlockAsm4MB + +memmove_long_repeat_emit_encodeBlockAsm4MB: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R11 + MOVD R8, R12 + +emit_lit_memmove_long_repeat_emit_encodeBlockAsm4MBlarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R11) + FMOVQ F1, 16(R11) + ADD $0x20, R10, R10 + ADD $0x20, R11, R11 + SUB $0x20, R12, R12 + CMP $0x20, R12 + BHS emit_lit_memmove_long_repeat_emit_encodeBlockAsm4MBlarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_repeat_emit_encodeBlockAsm4MB: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+32(FP), R8 + SUBW R2, R8, R8 + ADD R2, R3, R9 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_repeat_extend_encodeBlockAsm4MB: + CMPW $0x10, R8 + BLO matchlen_match8_repeat_extend_encodeBlockAsm4MB + MOVD (R9)(R11), R10 + ADD R11, R9, R15 + MOVD 8(R15), R12 + MOVD (R5)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_repeat_extend_encodeBlockAsm4MB + ADD R11, R5, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16repeat_extend_encodeBlockAsm4MB + SUB $16, R8, R8 + MOVWU R8, R8 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_repeat_extend_encodeBlockAsm4MB + +matchlen_bsf_16repeat_extend_encodeBlockAsm4MB: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP repeat_extend_forward_end_encodeBlockAsm4MB + +matchlen_match8_repeat_extend_encodeBlockAsm4MB: + CMPW $0x08, R8 + BLO matchlen_match4_repeat_extend_encodeBlockAsm4MB + MOVD (R9)(R11), R10 + MOVD (R5)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_repeat_extend_encodeBlockAsm4MB + SUB $8, R8, R8 + MOVWU R8, R8 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_repeat_extend_encodeBlockAsm4MB + +matchlen_bsf_8_repeat_extend_encodeBlockAsm4MB: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP repeat_extend_forward_end_encodeBlockAsm4MB + +matchlen_match4_repeat_extend_encodeBlockAsm4MB: + CMPW $0x04, R8 + BLO matchlen_match2_repeat_extend_encodeBlockAsm4MB + MOVWU (R9)(R11), R10 + MOVWU (R5)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_repeat_extend_encodeBlockAsm4MB + SUB $4, R8, R8 + MOVWU R8, R8 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_repeat_extend_encodeBlockAsm4MB: + CMPW $0x01, R8 + BEQ matchlen_match1_repeat_extend_encodeBlockAsm4MB + BLO repeat_extend_forward_end_encodeBlockAsm4MB + MOVHU (R9)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_encodeBlockAsm4MB + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R8, R8 + BEQ repeat_extend_forward_end_encodeBlockAsm4MB + +matchlen_match1_repeat_extend_encodeBlockAsm4MB: + MOVBU (R9)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R5, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_encodeBlockAsm4MB + ADD $1, R11, R11 + MOVWU R11, R11 + +repeat_extend_forward_end_encodeBlockAsm4MB: + ADDW R11, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + TSTW R7, R7 + BEQ repeat_as_copy_encodeBlockAsm4MB + + // emitRepeat + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_match_repeat_encodeBlockAsm4MB + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_match_repeat_encodeBlockAsm4MB + CMPW $0x00000800, R6 + BLO repeat_two_offset_match_repeat_encodeBlockAsm4MB + +cant_repeat_two_offset_match_repeat_encodeBlockAsm4MB: + CMPW $0x00000104, R5 + BLO repeat_three_match_repeat_encodeBlockAsm4MB + CMPW $0x00010100, R5 + BLO repeat_four_match_repeat_encodeBlockAsm4MB + SUB $65536, R5, R5 + MOVWU R5, R5 + MOVWU R5, R6 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ASRW $0x10, R6, R6 + MOVB R6, 4(R1) + ADD $0x05, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_four_match_repeat_encodeBlockAsm4MB: + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_three_match_repeat_encodeBlockAsm4MB: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_two_match_repeat_encodeBlockAsm4MB: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_two_offset_match_repeat_encodeBlockAsm4MB: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_as_copy_encodeBlockAsm4MB: + // emitCopy + CMPW $0x00010000, R6 + BLO two_byte_offset_repeat_as_copy_encodeBlockAsm4MB + CMPW $0x40, R5 + BLS four_bytes_remain_repeat_as_copy_encodeBlockAsm4MB + MOVD $0xff, R16 + MOVB R16, (R1) + MOVW R6, 1(R1) + SUB $64, R5, R5 + MOVWU R5, R5 + ADD $0x05, R1, R1 + CMPW $0x04, R5 + BLO four_bytes_remain_repeat_as_copy_encodeBlockAsm4MB + + // emitRepeat + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_repeat_as_copy_encodeBlockAsm4MB_emit_copy + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy + CMPW $0x00000800, R6 + BLO repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm4MB_emit_copy + CMPW $0x00010100, R5 + BLO repeat_four_repeat_as_copy_encodeBlockAsm4MB_emit_copy + SUB $65536, R5, R5 + MOVWU R5, R5 + MOVWU R5, R6 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ASRW $0x10, R6, R6 + MOVB R6, 4(R1) + ADD $0x05, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_four_repeat_as_copy_encodeBlockAsm4MB_emit_copy: + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_three_repeat_as_copy_encodeBlockAsm4MB_emit_copy: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_two_repeat_as_copy_encodeBlockAsm4MB_emit_copy: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +four_bytes_remain_repeat_as_copy_encodeBlockAsm4MB: + TSTW R5, R5 + BEQ repeat_end_emit_encodeBlockAsm4MB + MOVD $0, R7 + ADD R5<<2, R7, R5 + SUB $1, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVW R6, 1(R1) + ADD $0x05, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +two_byte_offset_repeat_as_copy_encodeBlockAsm4MB: + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_encodeBlockAsm4MB + CMPW $0x00000800, R6 + BHS long_offset_short_repeat_as_copy_encodeBlockAsm4MB + MOVD $0x00000001, R7 + ADD $16, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R5, R5 + + // emitRepeat + SUB $4, R5, R5 + MOVWU R5, R5 + JMP cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short_2b + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short_2b + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short_2b + CMPW $0x00000800, R6 + BLO repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short_2b + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short_2b: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short_2b + CMPW $0x00010100, R5 + BLO repeat_four_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short_2b + SUB $65536, R5, R5 + MOVWU R5, R5 + MOVWU R5, R6 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ASRW $0x10, R6, R6 + MOVB R6, 4(R1) + ADD $0x05, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_four_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short_2b: + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_three_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short_2b: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_two_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short_2b: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short_2b: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +long_offset_short_repeat_as_copy_encodeBlockAsm4MB: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R6, 1(R1) + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short + CMPW $0x00000800, R6 + BLO repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short + CMPW $0x00010100, R5 + BLO repeat_four_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short + SUB $65536, R5, R5 + MOVWU R5, R5 + MOVWU R5, R6 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ASRW $0x10, R6, R6 + MOVB R6, 4(R1) + ADD $0x05, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_four_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short: + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_three_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_two_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +repeat_two_offset_repeat_as_copy_encodeBlockAsm4MB_emit_copy_short: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +two_byte_offset_short_repeat_as_copy_encodeBlockAsm4MB: + MOVWU R5, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_encodeBlockAsm4MB + CMPW $0x00000800, R6 + BHS emit_copy_three_repeat_as_copy_encodeBlockAsm4MB + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm4MB + +emit_copy_three_repeat_as_copy_encodeBlockAsm4MB: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R1) + MOVH R6, 1(R1) + ADD $0x03, R1, R1 + +repeat_end_emit_encodeBlockAsm4MB: + MOVW R2, 20(RSP) + JMP search_loop_encodeBlockAsm4MB + +no_repeat_found_encodeBlockAsm4MB: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeBlockAsm4MB + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_encodeBlockAsm4MB + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_encodeBlockAsm4MB + MOVWU 28(RSP), R2 + JMP search_loop_encodeBlockAsm4MB + +candidate3_match_encodeBlockAsm4MB: + ADDW $0x02, R2, R2 + JMP candidate_match_encodeBlockAsm4MB + +candidate2_match_encodeBlockAsm4MB: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeBlockAsm4MB: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeBlockAsm4MB + +match_extend_back_loop_encodeBlockAsm4MB: + CMPW R6, R2 + BLS match_extend_back_end_encodeBlockAsm4MB + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeBlockAsm4MB + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeBlockAsm4MB + JMP match_extend_back_loop_encodeBlockAsm4MB + +match_extend_back_end_encodeBlockAsm4MB: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $4, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeBlockAsm4MB + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeBlockAsm4MB: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_encodeBlockAsm4MB + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R7 + MOVWU R7, R7 + CMPW $0x3c, R7 + BLO one_byte_match_emit_encodeBlockAsm4MB + CMPW $0x00000100, R7 + BLO two_bytes_match_emit_encodeBlockAsm4MB + CMPW $0x00010000, R7 + BLO three_bytes_match_emit_encodeBlockAsm4MB + MOVWU R7, R9 + LSRW $0x10, R9, R9 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + MOVB R9, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_match_emit_encodeBlockAsm4MB + +three_bytes_match_emit_encodeBlockAsm4MB: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeBlockAsm4MB + +two_bytes_match_emit_encodeBlockAsm4MB: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R7, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R7 + BLO memmove_match_emit_encodeBlockAsm4MB + JMP memmove_long_match_emit_encodeBlockAsm4MB + +one_byte_match_emit_encodeBlockAsm4MB: + LSLW $0x02, R7, R16 + BFI $0, R16, $8, R7 + MOVB R7, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeBlockAsm4MB: + ADD R8, R1, R7 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm4MB_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm4MB_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm4MB_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeBlockAsm4MB_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeBlockAsm4MB_memmove_move_8: + MOVD (R6), R9 + MOVD R9, (R1) + JMP memmove_end_copy_match_emit_encodeBlockAsm4MB + +emit_lit_memmove_match_emit_encodeBlockAsm4MB_memmove_move_8through16: + MOVD (R6), R9 + ADD R8, R6, R15 + MOVD -8(R15), R6 + MOVD R9, (R1) + ADD R8, R1, R15 + MOVD R6, -8(R15) + JMP memmove_end_copy_match_emit_encodeBlockAsm4MB + +emit_lit_memmove_match_emit_encodeBlockAsm4MB_memmove_move_17through32: + FMOVQ (R6), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeBlockAsm4MB + +emit_lit_memmove_match_emit_encodeBlockAsm4MB_memmove_move_33through64: + FMOVQ (R6), F0 + FMOVQ 16(R6), F1 + ADD R8, R6, R15 + FMOVQ -32(R15), F2 + ADD R8, R6, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeBlockAsm4MB: + MOVD R7, R1 + JMP emit_literal_done_match_emit_encodeBlockAsm4MB + +memmove_long_match_emit_encodeBlockAsm4MB: + ADD R8, R1, R7 + + // genMemMoveLong + MOVD R6, R9 + MOVD R1, R10 + MOVD R8, R11 + +emit_lit_memmove_long_match_emit_encodeBlockAsm4MBlarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_match_emit_encodeBlockAsm4MBlarge_big_loop_back + ADD R8, R6, R15 + FMOVQ -32(R15), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R7, R1 + +emit_literal_done_match_emit_encodeBlockAsm4MB: +match_nolit_loop_encodeBlockAsm4MB: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_encodeBlockAsm4MB: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_encodeBlockAsm4MB + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeBlockAsm4MB + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_encodeBlockAsm4MB + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_encodeBlockAsm4MB + +matchlen_bsf_16match_nolit_encodeBlockAsm4MB: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeBlockAsm4MB + +matchlen_match8_match_nolit_encodeBlockAsm4MB: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_encodeBlockAsm4MB + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeBlockAsm4MB + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_encodeBlockAsm4MB + +matchlen_bsf_8_match_nolit_encodeBlockAsm4MB: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeBlockAsm4MB + +matchlen_match4_match_nolit_encodeBlockAsm4MB: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_encodeBlockAsm4MB + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_encodeBlockAsm4MB + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_encodeBlockAsm4MB: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_encodeBlockAsm4MB + BLO match_nolit_end_encodeBlockAsm4MB + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeBlockAsm4MB + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_encodeBlockAsm4MB + +matchlen_match1_match_nolit_encodeBlockAsm4MB: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_encodeBlockAsm4MB + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_encodeBlockAsm4MB: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x00010000, R5 + BLO two_byte_offset_match_nolit_encodeBlockAsm4MB + CMPW $0x40, R9 + BLS four_bytes_remain_match_nolit_encodeBlockAsm4MB + MOVD $0xff, R16 + MOVB R16, (R1) + MOVW R5, 1(R1) + SUB $64, R9, R9 + MOVWU R9, R9 + ADD $0x05, R1, R1 + CMPW $0x04, R9 + BLO four_bytes_remain_match_nolit_encodeBlockAsm4MB + + // emitRepeat + MOVWU R9, R6 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R6 + BLS repeat_two_match_nolit_encodeBlockAsm4MB_emit_copy + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy + CMPW $0x00000800, R5 + BLO repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy + +cant_repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm4MB_emit_copy + CMPW $0x00010100, R9 + BLO repeat_four_match_nolit_encodeBlockAsm4MB_emit_copy + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R5 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ASRW $0x10, R5, R5 + MOVB R5, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_four_match_nolit_encodeBlockAsm4MB_emit_copy: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_three_match_nolit_encodeBlockAsm4MB_emit_copy: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_two_match_nolit_encodeBlockAsm4MB_emit_copy: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy: + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +four_bytes_remain_match_nolit_encodeBlockAsm4MB: + TSTW R9, R9 + BEQ match_nolit_emitcopy_end_encodeBlockAsm4MB + MOVD $0, R6 + ADD R9<<2, R6, R9 + SUB $1, R9, R9 + MOVWU R9, R9 + MOVB R9, (R1) + MOVW R5, 1(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +two_byte_offset_match_nolit_encodeBlockAsm4MB: + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_encodeBlockAsm4MB + CMPW $0x00000800, R5 + BHS long_offset_short_match_nolit_encodeBlockAsm4MB + MOVD $0x00000001, R6 + ADD $16, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R9, R9 + + // emitRepeat + SUB $4, R9, R9 + MOVWU R9, R9 + JMP cant_repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy_short_2b + MOVWU R9, R6 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R6 + BLS repeat_two_match_nolit_encodeBlockAsm4MB_emit_copy_short_2b + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy_short_2b + CMPW $0x00000800, R5 + BLO repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy_short_2b + +cant_repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy_short_2b: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm4MB_emit_copy_short_2b + CMPW $0x00010100, R9 + BLO repeat_four_match_nolit_encodeBlockAsm4MB_emit_copy_short_2b + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R5 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ASRW $0x10, R5, R5 + MOVB R5, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_four_match_nolit_encodeBlockAsm4MB_emit_copy_short_2b: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_three_match_nolit_encodeBlockAsm4MB_emit_copy_short_2b: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_two_match_nolit_encodeBlockAsm4MB_emit_copy_short_2b: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy_short_2b: + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +long_offset_short_match_nolit_encodeBlockAsm4MB: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R9, R6 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R6 + BLS repeat_two_match_nolit_encodeBlockAsm4MB_emit_copy_short + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy_short + CMPW $0x00000800, R5 + BLO repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy_short + +cant_repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy_short: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm4MB_emit_copy_short + CMPW $0x00010100, R9 + BLO repeat_four_match_nolit_encodeBlockAsm4MB_emit_copy_short + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R5 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ASRW $0x10, R5, R5 + MOVB R5, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_four_match_nolit_encodeBlockAsm4MB_emit_copy_short: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_three_match_nolit_encodeBlockAsm4MB_emit_copy_short: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_two_match_nolit_encodeBlockAsm4MB_emit_copy_short: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +repeat_two_offset_match_nolit_encodeBlockAsm4MB_emit_copy_short: + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +two_byte_offset_short_match_nolit_encodeBlockAsm4MB: + MOVWU R9, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_encodeBlockAsm4MB + CMPW $0x00000800, R5 + BHS emit_copy_three_match_nolit_encodeBlockAsm4MB + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm4MB + +emit_copy_three_match_nolit_encodeBlockAsm4MB: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeBlockAsm4MB: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeBlockAsm4MB + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeBlockAsm4MB + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeBlockAsm4MB: + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x10, R7, R7 + MUL R8, R7, R7 + LSR $0x32, R7, R7 + LSL $0x10, R5, R5 + MUL R8, R5, R5 + LSR $0x32, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_encodeBlockAsm4MB + ADDW $1, R2, R2 + JMP search_loop_encodeBlockAsm4MB + +emit_remainder_encodeBlockAsm4MB: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $4, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeBlockAsm4MB + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeBlockAsm4MB: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeBlockAsm4MB + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeBlockAsm4MB + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeBlockAsm4MB + CMPW $0x00010000, R2 + BLO three_bytes_emit_remainder_encodeBlockAsm4MB + MOVWU R2, R3 + LSRW $0x10, R3, R3 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + MOVB R3, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_emit_remainder_encodeBlockAsm4MB + +three_bytes_emit_remainder_encodeBlockAsm4MB: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeBlockAsm4MB + +two_bytes_emit_remainder_encodeBlockAsm4MB: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeBlockAsm4MB + JMP memmove_long_emit_remainder_encodeBlockAsm4MB + +one_byte_emit_remainder_encodeBlockAsm4MB: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeBlockAsm4MB: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm4MB + +emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm4MB + +emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm4MB + +emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm4MB + +emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm4MB + +emit_lit_memmove_emit_remainder_encodeBlockAsm4MB_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeBlockAsm4MB: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeBlockAsm4MB + +memmove_long_emit_remainder_encodeBlockAsm4MB: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeBlockAsm4MBlarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeBlockAsm4MBlarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeBlockAsm4MB: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeBlockAsm12B(dst []byte, src []byte, tmp *[16384]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeBlockAsm12B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000080, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeBlockAsm12B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeBlockAsm12B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeBlockAsm12B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x05, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeBlockAsm12B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x000000cf1bbcdcbb, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x18, R9, R9 + MUL R8, R9, R9 + LSR $0x34, R9, R9 + LSL $0x18, R10, R10 + MUL R8, R10, R10 + LSR $0x34, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x18, R9, R9 + MUL R8, R9, R9 + LSR $0x34, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_encodeBlockAsm12B + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R7 + MOVWU R6, R5 + MOVWU 24(RSP), R16 + SUBSW R16, R5, R5 + BEQ repeat_extend_back_end_encodeBlockAsm12B + +repeat_extend_back_loop_encodeBlockAsm12B: + CMPW R7, R6 + BLS repeat_extend_back_end_encodeBlockAsm12B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_encodeBlockAsm12B + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R5, R5 + BNE repeat_extend_back_loop_encodeBlockAsm12B + +repeat_extend_back_end_encodeBlockAsm12B: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $3, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_encodeBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +repeat_dst_size_check_encodeBlockAsm12B: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_encodeBlockAsm12B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_encodeBlockAsm12B + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_encodeBlockAsm12B + BLO three_bytes_repeat_emit_encodeBlockAsm12B + +three_bytes_repeat_emit_encodeBlockAsm12B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_encodeBlockAsm12B + +two_bytes_repeat_emit_encodeBlockAsm12B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_encodeBlockAsm12B + JMP memmove_long_repeat_emit_encodeBlockAsm12B + +one_byte_repeat_emit_encodeBlockAsm12B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_repeat_emit_encodeBlockAsm12B: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm12B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm12B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm12B_memmove_move_17through32 + JMP emit_lit_memmove_repeat_emit_encodeBlockAsm12B_memmove_move_33through64 + +emit_lit_memmove_repeat_emit_encodeBlockAsm12B_memmove_move_8: + MOVD (R9), R10 + MOVD R10, (R1) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm12B + +emit_lit_memmove_repeat_emit_encodeBlockAsm12B_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm12B + +emit_lit_memmove_repeat_emit_encodeBlockAsm12B_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm12B + +emit_lit_memmove_repeat_emit_encodeBlockAsm12B_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_repeat_emit_encodeBlockAsm12B: + MOVD R5, R1 + JMP emit_literal_done_repeat_emit_encodeBlockAsm12B + +memmove_long_repeat_emit_encodeBlockAsm12B: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R11 + MOVD R8, R12 + +emit_lit_memmove_long_repeat_emit_encodeBlockAsm12Blarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R11) + FMOVQ F1, 16(R11) + ADD $0x20, R10, R10 + ADD $0x20, R11, R11 + SUB $0x20, R12, R12 + CMP $0x20, R12 + BHS emit_lit_memmove_long_repeat_emit_encodeBlockAsm12Blarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_repeat_emit_encodeBlockAsm12B: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+32(FP), R8 + SUBW R2, R8, R8 + ADD R2, R3, R9 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_repeat_extend_encodeBlockAsm12B: + CMPW $0x10, R8 + BLO matchlen_match8_repeat_extend_encodeBlockAsm12B + MOVD (R9)(R11), R10 + ADD R11, R9, R15 + MOVD 8(R15), R12 + MOVD (R5)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_repeat_extend_encodeBlockAsm12B + ADD R11, R5, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16repeat_extend_encodeBlockAsm12B + SUB $16, R8, R8 + MOVWU R8, R8 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_repeat_extend_encodeBlockAsm12B + +matchlen_bsf_16repeat_extend_encodeBlockAsm12B: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP repeat_extend_forward_end_encodeBlockAsm12B + +matchlen_match8_repeat_extend_encodeBlockAsm12B: + CMPW $0x08, R8 + BLO matchlen_match4_repeat_extend_encodeBlockAsm12B + MOVD (R9)(R11), R10 + MOVD (R5)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_repeat_extend_encodeBlockAsm12B + SUB $8, R8, R8 + MOVWU R8, R8 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_repeat_extend_encodeBlockAsm12B + +matchlen_bsf_8_repeat_extend_encodeBlockAsm12B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP repeat_extend_forward_end_encodeBlockAsm12B + +matchlen_match4_repeat_extend_encodeBlockAsm12B: + CMPW $0x04, R8 + BLO matchlen_match2_repeat_extend_encodeBlockAsm12B + MOVWU (R9)(R11), R10 + MOVWU (R5)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_repeat_extend_encodeBlockAsm12B + SUB $4, R8, R8 + MOVWU R8, R8 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_repeat_extend_encodeBlockAsm12B: + CMPW $0x01, R8 + BEQ matchlen_match1_repeat_extend_encodeBlockAsm12B + BLO repeat_extend_forward_end_encodeBlockAsm12B + MOVHU (R9)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_encodeBlockAsm12B + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R8, R8 + BEQ repeat_extend_forward_end_encodeBlockAsm12B + +matchlen_match1_repeat_extend_encodeBlockAsm12B: + MOVBU (R9)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R5, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_encodeBlockAsm12B + ADD $1, R11, R11 + MOVWU R11, R11 + +repeat_extend_forward_end_encodeBlockAsm12B: + ADDW R11, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + TSTW R7, R7 + BEQ repeat_as_copy_encodeBlockAsm12B + + // emitRepeat + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_match_repeat_encodeBlockAsm12B + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_match_repeat_encodeBlockAsm12B + CMPW $0x00000800, R6 + BLO repeat_two_offset_match_repeat_encodeBlockAsm12B + +cant_repeat_two_offset_match_repeat_encodeBlockAsm12B: + CMPW $0x00000104, R5 + BLO repeat_three_match_repeat_encodeBlockAsm12B + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +repeat_three_match_repeat_encodeBlockAsm12B: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +repeat_two_match_repeat_encodeBlockAsm12B: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +repeat_two_offset_match_repeat_encodeBlockAsm12B: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +repeat_as_copy_encodeBlockAsm12B: + // emitCopy + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_encodeBlockAsm12B + CMPW $0x00000800, R6 + BHS long_offset_short_repeat_as_copy_encodeBlockAsm12B + MOVD $0x00000001, R7 + ADD $16, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R5, R5 + + // emitRepeat + SUB $4, R5, R5 + MOVWU R5, R5 + JMP cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm12B_emit_copy_short_2b + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_repeat_as_copy_encodeBlockAsm12B_emit_copy_short_2b + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm12B_emit_copy_short_2b + CMPW $0x00000800, R6 + BLO repeat_two_offset_repeat_as_copy_encodeBlockAsm12B_emit_copy_short_2b + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm12B_emit_copy_short_2b: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm12B_emit_copy_short_2b + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +repeat_three_repeat_as_copy_encodeBlockAsm12B_emit_copy_short_2b: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +repeat_two_repeat_as_copy_encodeBlockAsm12B_emit_copy_short_2b: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +repeat_two_offset_repeat_as_copy_encodeBlockAsm12B_emit_copy_short_2b: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +long_offset_short_repeat_as_copy_encodeBlockAsm12B: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R6, 1(R1) + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_repeat_as_copy_encodeBlockAsm12B_emit_copy_short + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm12B_emit_copy_short + CMPW $0x00000800, R6 + BLO repeat_two_offset_repeat_as_copy_encodeBlockAsm12B_emit_copy_short + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm12B_emit_copy_short: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm12B_emit_copy_short + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +repeat_three_repeat_as_copy_encodeBlockAsm12B_emit_copy_short: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +repeat_two_repeat_as_copy_encodeBlockAsm12B_emit_copy_short: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +repeat_two_offset_repeat_as_copy_encodeBlockAsm12B_emit_copy_short: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +two_byte_offset_short_repeat_as_copy_encodeBlockAsm12B: + MOVWU R5, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_encodeBlockAsm12B + CMPW $0x00000800, R6 + BHS emit_copy_three_repeat_as_copy_encodeBlockAsm12B + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm12B + +emit_copy_three_repeat_as_copy_encodeBlockAsm12B: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R1) + MOVH R6, 1(R1) + ADD $0x03, R1, R1 + +repeat_end_emit_encodeBlockAsm12B: + MOVW R2, 20(RSP) + JMP search_loop_encodeBlockAsm12B + +no_repeat_found_encodeBlockAsm12B: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeBlockAsm12B + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_encodeBlockAsm12B + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_encodeBlockAsm12B + MOVWU 28(RSP), R2 + JMP search_loop_encodeBlockAsm12B + +candidate3_match_encodeBlockAsm12B: + ADDW $0x02, R2, R2 + JMP candidate_match_encodeBlockAsm12B + +candidate2_match_encodeBlockAsm12B: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeBlockAsm12B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeBlockAsm12B + +match_extend_back_loop_encodeBlockAsm12B: + CMPW R6, R2 + BLS match_extend_back_end_encodeBlockAsm12B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeBlockAsm12B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeBlockAsm12B + JMP match_extend_back_loop_encodeBlockAsm12B + +match_extend_back_end_encodeBlockAsm12B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeBlockAsm12B: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_encodeBlockAsm12B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R7 + MOVWU R7, R7 + CMPW $0x3c, R7 + BLO one_byte_match_emit_encodeBlockAsm12B + CMPW $0x00000100, R7 + BLO two_bytes_match_emit_encodeBlockAsm12B + BLO three_bytes_match_emit_encodeBlockAsm12B + +three_bytes_match_emit_encodeBlockAsm12B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeBlockAsm12B + +two_bytes_match_emit_encodeBlockAsm12B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R7, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R7 + BLO memmove_match_emit_encodeBlockAsm12B + JMP memmove_long_match_emit_encodeBlockAsm12B + +one_byte_match_emit_encodeBlockAsm12B: + LSLW $0x02, R7, R16 + BFI $0, R16, $8, R7 + MOVB R7, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeBlockAsm12B: + ADD R8, R1, R7 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm12B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm12B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm12B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeBlockAsm12B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeBlockAsm12B_memmove_move_8: + MOVD (R6), R9 + MOVD R9, (R1) + JMP memmove_end_copy_match_emit_encodeBlockAsm12B + +emit_lit_memmove_match_emit_encodeBlockAsm12B_memmove_move_8through16: + MOVD (R6), R9 + ADD R8, R6, R15 + MOVD -8(R15), R6 + MOVD R9, (R1) + ADD R8, R1, R15 + MOVD R6, -8(R15) + JMP memmove_end_copy_match_emit_encodeBlockAsm12B + +emit_lit_memmove_match_emit_encodeBlockAsm12B_memmove_move_17through32: + FMOVQ (R6), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeBlockAsm12B + +emit_lit_memmove_match_emit_encodeBlockAsm12B_memmove_move_33through64: + FMOVQ (R6), F0 + FMOVQ 16(R6), F1 + ADD R8, R6, R15 + FMOVQ -32(R15), F2 + ADD R8, R6, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeBlockAsm12B: + MOVD R7, R1 + JMP emit_literal_done_match_emit_encodeBlockAsm12B + +memmove_long_match_emit_encodeBlockAsm12B: + ADD R8, R1, R7 + + // genMemMoveLong + MOVD R6, R9 + MOVD R1, R10 + MOVD R8, R11 + +emit_lit_memmove_long_match_emit_encodeBlockAsm12Blarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_match_emit_encodeBlockAsm12Blarge_big_loop_back + ADD R8, R6, R15 + FMOVQ -32(R15), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R7, R1 + +emit_literal_done_match_emit_encodeBlockAsm12B: +match_nolit_loop_encodeBlockAsm12B: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_encodeBlockAsm12B: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_encodeBlockAsm12B + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeBlockAsm12B + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_encodeBlockAsm12B + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_encodeBlockAsm12B + +matchlen_bsf_16match_nolit_encodeBlockAsm12B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeBlockAsm12B + +matchlen_match8_match_nolit_encodeBlockAsm12B: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_encodeBlockAsm12B + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeBlockAsm12B + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_encodeBlockAsm12B + +matchlen_bsf_8_match_nolit_encodeBlockAsm12B: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeBlockAsm12B + +matchlen_match4_match_nolit_encodeBlockAsm12B: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_encodeBlockAsm12B + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_encodeBlockAsm12B + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_encodeBlockAsm12B: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_encodeBlockAsm12B + BLO match_nolit_end_encodeBlockAsm12B + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeBlockAsm12B + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_encodeBlockAsm12B + +matchlen_match1_match_nolit_encodeBlockAsm12B: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_encodeBlockAsm12B + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_encodeBlockAsm12B: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_encodeBlockAsm12B + CMPW $0x00000800, R5 + BHS long_offset_short_match_nolit_encodeBlockAsm12B + MOVD $0x00000001, R6 + ADD $16, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R9, R9 + + // emitRepeat + SUB $4, R9, R9 + MOVWU R9, R9 + JMP cant_repeat_two_offset_match_nolit_encodeBlockAsm12B_emit_copy_short_2b + MOVWU R9, R6 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R6 + BLS repeat_two_match_nolit_encodeBlockAsm12B_emit_copy_short_2b + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm12B_emit_copy_short_2b + CMPW $0x00000800, R5 + BLO repeat_two_offset_match_nolit_encodeBlockAsm12B_emit_copy_short_2b + +cant_repeat_two_offset_match_nolit_encodeBlockAsm12B_emit_copy_short_2b: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm12B_emit_copy_short_2b + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm12B + +repeat_three_match_nolit_encodeBlockAsm12B_emit_copy_short_2b: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm12B + +repeat_two_match_nolit_encodeBlockAsm12B_emit_copy_short_2b: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm12B + +repeat_two_offset_match_nolit_encodeBlockAsm12B_emit_copy_short_2b: + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm12B + +long_offset_short_match_nolit_encodeBlockAsm12B: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R9, R6 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R6 + BLS repeat_two_match_nolit_encodeBlockAsm12B_emit_copy_short + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm12B_emit_copy_short + CMPW $0x00000800, R5 + BLO repeat_two_offset_match_nolit_encodeBlockAsm12B_emit_copy_short + +cant_repeat_two_offset_match_nolit_encodeBlockAsm12B_emit_copy_short: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm12B_emit_copy_short + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm12B + +repeat_three_match_nolit_encodeBlockAsm12B_emit_copy_short: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm12B + +repeat_two_match_nolit_encodeBlockAsm12B_emit_copy_short: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm12B + +repeat_two_offset_match_nolit_encodeBlockAsm12B_emit_copy_short: + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm12B + +two_byte_offset_short_match_nolit_encodeBlockAsm12B: + MOVWU R9, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_encodeBlockAsm12B + CMPW $0x00000800, R5 + BHS emit_copy_three_match_nolit_encodeBlockAsm12B + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm12B + +emit_copy_three_match_nolit_encodeBlockAsm12B: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeBlockAsm12B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeBlockAsm12B + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeBlockAsm12B: + MOVD $0x000000cf1bbcdcbb, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x18, R7, R7 + MUL R8, R7, R7 + LSR $0x34, R7, R7 + LSL $0x18, R5, R5 + MUL R8, R5, R5 + LSR $0x34, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_encodeBlockAsm12B + ADDW $1, R2, R2 + JMP search_loop_encodeBlockAsm12B + +emit_remainder_encodeBlockAsm12B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeBlockAsm12B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeBlockAsm12B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeBlockAsm12B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeBlockAsm12B + BLO three_bytes_emit_remainder_encodeBlockAsm12B + +three_bytes_emit_remainder_encodeBlockAsm12B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeBlockAsm12B + +two_bytes_emit_remainder_encodeBlockAsm12B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeBlockAsm12B + JMP memmove_long_emit_remainder_encodeBlockAsm12B + +one_byte_emit_remainder_encodeBlockAsm12B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeBlockAsm12B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeBlockAsm12B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeBlockAsm12B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeBlockAsm12B + +memmove_long_emit_remainder_encodeBlockAsm12B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeBlockAsm12Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeBlockAsm12Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeBlockAsm12B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeBlockAsm10B(dst []byte, src []byte, tmp *[4096]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeBlockAsm10B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000020, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeBlockAsm10B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeBlockAsm10B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeBlockAsm10B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x05, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeBlockAsm10B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x9e3779b1, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x20, R9, R9 + MUL R8, R9, R9 + LSR $0x36, R9, R9 + LSL $0x20, R10, R10 + MUL R8, R10, R10 + LSR $0x36, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x20, R9, R9 + MUL R8, R9, R9 + LSR $0x36, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_encodeBlockAsm10B + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R7 + MOVWU R6, R5 + MOVWU 24(RSP), R16 + SUBSW R16, R5, R5 + BEQ repeat_extend_back_end_encodeBlockAsm10B + +repeat_extend_back_loop_encodeBlockAsm10B: + CMPW R7, R6 + BLS repeat_extend_back_end_encodeBlockAsm10B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_encodeBlockAsm10B + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R5, R5 + BNE repeat_extend_back_loop_encodeBlockAsm10B + +repeat_extend_back_end_encodeBlockAsm10B: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $3, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_encodeBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +repeat_dst_size_check_encodeBlockAsm10B: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_encodeBlockAsm10B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_encodeBlockAsm10B + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_encodeBlockAsm10B + BLO three_bytes_repeat_emit_encodeBlockAsm10B + +three_bytes_repeat_emit_encodeBlockAsm10B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_encodeBlockAsm10B + +two_bytes_repeat_emit_encodeBlockAsm10B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_encodeBlockAsm10B + JMP memmove_long_repeat_emit_encodeBlockAsm10B + +one_byte_repeat_emit_encodeBlockAsm10B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_repeat_emit_encodeBlockAsm10B: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm10B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm10B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm10B_memmove_move_17through32 + JMP emit_lit_memmove_repeat_emit_encodeBlockAsm10B_memmove_move_33through64 + +emit_lit_memmove_repeat_emit_encodeBlockAsm10B_memmove_move_8: + MOVD (R9), R10 + MOVD R10, (R1) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm10B + +emit_lit_memmove_repeat_emit_encodeBlockAsm10B_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm10B + +emit_lit_memmove_repeat_emit_encodeBlockAsm10B_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm10B + +emit_lit_memmove_repeat_emit_encodeBlockAsm10B_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_repeat_emit_encodeBlockAsm10B: + MOVD R5, R1 + JMP emit_literal_done_repeat_emit_encodeBlockAsm10B + +memmove_long_repeat_emit_encodeBlockAsm10B: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R11 + MOVD R8, R12 + +emit_lit_memmove_long_repeat_emit_encodeBlockAsm10Blarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R11) + FMOVQ F1, 16(R11) + ADD $0x20, R10, R10 + ADD $0x20, R11, R11 + SUB $0x20, R12, R12 + CMP $0x20, R12 + BHS emit_lit_memmove_long_repeat_emit_encodeBlockAsm10Blarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_repeat_emit_encodeBlockAsm10B: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+32(FP), R8 + SUBW R2, R8, R8 + ADD R2, R3, R9 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_repeat_extend_encodeBlockAsm10B: + CMPW $0x10, R8 + BLO matchlen_match8_repeat_extend_encodeBlockAsm10B + MOVD (R9)(R11), R10 + ADD R11, R9, R15 + MOVD 8(R15), R12 + MOVD (R5)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_repeat_extend_encodeBlockAsm10B + ADD R11, R5, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16repeat_extend_encodeBlockAsm10B + SUB $16, R8, R8 + MOVWU R8, R8 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_repeat_extend_encodeBlockAsm10B + +matchlen_bsf_16repeat_extend_encodeBlockAsm10B: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP repeat_extend_forward_end_encodeBlockAsm10B + +matchlen_match8_repeat_extend_encodeBlockAsm10B: + CMPW $0x08, R8 + BLO matchlen_match4_repeat_extend_encodeBlockAsm10B + MOVD (R9)(R11), R10 + MOVD (R5)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_repeat_extend_encodeBlockAsm10B + SUB $8, R8, R8 + MOVWU R8, R8 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_repeat_extend_encodeBlockAsm10B + +matchlen_bsf_8_repeat_extend_encodeBlockAsm10B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP repeat_extend_forward_end_encodeBlockAsm10B + +matchlen_match4_repeat_extend_encodeBlockAsm10B: + CMPW $0x04, R8 + BLO matchlen_match2_repeat_extend_encodeBlockAsm10B + MOVWU (R9)(R11), R10 + MOVWU (R5)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_repeat_extend_encodeBlockAsm10B + SUB $4, R8, R8 + MOVWU R8, R8 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_repeat_extend_encodeBlockAsm10B: + CMPW $0x01, R8 + BEQ matchlen_match1_repeat_extend_encodeBlockAsm10B + BLO repeat_extend_forward_end_encodeBlockAsm10B + MOVHU (R9)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_encodeBlockAsm10B + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R8, R8 + BEQ repeat_extend_forward_end_encodeBlockAsm10B + +matchlen_match1_repeat_extend_encodeBlockAsm10B: + MOVBU (R9)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R5, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_encodeBlockAsm10B + ADD $1, R11, R11 + MOVWU R11, R11 + +repeat_extend_forward_end_encodeBlockAsm10B: + ADDW R11, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + TSTW R7, R7 + BEQ repeat_as_copy_encodeBlockAsm10B + + // emitRepeat + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_match_repeat_encodeBlockAsm10B + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_match_repeat_encodeBlockAsm10B + CMPW $0x00000800, R6 + BLO repeat_two_offset_match_repeat_encodeBlockAsm10B + +cant_repeat_two_offset_match_repeat_encodeBlockAsm10B: + CMPW $0x00000104, R5 + BLO repeat_three_match_repeat_encodeBlockAsm10B + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +repeat_three_match_repeat_encodeBlockAsm10B: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +repeat_two_match_repeat_encodeBlockAsm10B: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +repeat_two_offset_match_repeat_encodeBlockAsm10B: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +repeat_as_copy_encodeBlockAsm10B: + // emitCopy + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_encodeBlockAsm10B + CMPW $0x00000800, R6 + BHS long_offset_short_repeat_as_copy_encodeBlockAsm10B + MOVD $0x00000001, R7 + ADD $16, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R5, R5 + + // emitRepeat + SUB $4, R5, R5 + MOVWU R5, R5 + JMP cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm10B_emit_copy_short_2b + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_repeat_as_copy_encodeBlockAsm10B_emit_copy_short_2b + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm10B_emit_copy_short_2b + CMPW $0x00000800, R6 + BLO repeat_two_offset_repeat_as_copy_encodeBlockAsm10B_emit_copy_short_2b + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm10B_emit_copy_short_2b: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm10B_emit_copy_short_2b + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +repeat_three_repeat_as_copy_encodeBlockAsm10B_emit_copy_short_2b: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +repeat_two_repeat_as_copy_encodeBlockAsm10B_emit_copy_short_2b: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +repeat_two_offset_repeat_as_copy_encodeBlockAsm10B_emit_copy_short_2b: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +long_offset_short_repeat_as_copy_encodeBlockAsm10B: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R6, 1(R1) + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R5, R7 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R7 + BLS repeat_two_repeat_as_copy_encodeBlockAsm10B_emit_copy_short + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm10B_emit_copy_short + CMPW $0x00000800, R6 + BLO repeat_two_offset_repeat_as_copy_encodeBlockAsm10B_emit_copy_short + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm10B_emit_copy_short: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm10B_emit_copy_short + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +repeat_three_repeat_as_copy_encodeBlockAsm10B_emit_copy_short: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +repeat_two_repeat_as_copy_encodeBlockAsm10B_emit_copy_short: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +repeat_two_offset_repeat_as_copy_encodeBlockAsm10B_emit_copy_short: + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +two_byte_offset_short_repeat_as_copy_encodeBlockAsm10B: + MOVWU R5, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_encodeBlockAsm10B + CMPW $0x00000800, R6 + BHS emit_copy_three_repeat_as_copy_encodeBlockAsm10B + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm10B + +emit_copy_three_repeat_as_copy_encodeBlockAsm10B: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R1) + MOVH R6, 1(R1) + ADD $0x03, R1, R1 + +repeat_end_emit_encodeBlockAsm10B: + MOVW R2, 20(RSP) + JMP search_loop_encodeBlockAsm10B + +no_repeat_found_encodeBlockAsm10B: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeBlockAsm10B + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_encodeBlockAsm10B + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_encodeBlockAsm10B + MOVWU 28(RSP), R2 + JMP search_loop_encodeBlockAsm10B + +candidate3_match_encodeBlockAsm10B: + ADDW $0x02, R2, R2 + JMP candidate_match_encodeBlockAsm10B + +candidate2_match_encodeBlockAsm10B: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeBlockAsm10B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeBlockAsm10B + +match_extend_back_loop_encodeBlockAsm10B: + CMPW R6, R2 + BLS match_extend_back_end_encodeBlockAsm10B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeBlockAsm10B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeBlockAsm10B + JMP match_extend_back_loop_encodeBlockAsm10B + +match_extend_back_end_encodeBlockAsm10B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeBlockAsm10B: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_encodeBlockAsm10B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R7 + MOVWU R7, R7 + CMPW $0x3c, R7 + BLO one_byte_match_emit_encodeBlockAsm10B + CMPW $0x00000100, R7 + BLO two_bytes_match_emit_encodeBlockAsm10B + BLO three_bytes_match_emit_encodeBlockAsm10B + +three_bytes_match_emit_encodeBlockAsm10B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeBlockAsm10B + +two_bytes_match_emit_encodeBlockAsm10B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R7, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R7 + BLO memmove_match_emit_encodeBlockAsm10B + JMP memmove_long_match_emit_encodeBlockAsm10B + +one_byte_match_emit_encodeBlockAsm10B: + LSLW $0x02, R7, R16 + BFI $0, R16, $8, R7 + MOVB R7, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeBlockAsm10B: + ADD R8, R1, R7 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm10B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm10B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm10B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeBlockAsm10B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeBlockAsm10B_memmove_move_8: + MOVD (R6), R9 + MOVD R9, (R1) + JMP memmove_end_copy_match_emit_encodeBlockAsm10B + +emit_lit_memmove_match_emit_encodeBlockAsm10B_memmove_move_8through16: + MOVD (R6), R9 + ADD R8, R6, R15 + MOVD -8(R15), R6 + MOVD R9, (R1) + ADD R8, R1, R15 + MOVD R6, -8(R15) + JMP memmove_end_copy_match_emit_encodeBlockAsm10B + +emit_lit_memmove_match_emit_encodeBlockAsm10B_memmove_move_17through32: + FMOVQ (R6), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeBlockAsm10B + +emit_lit_memmove_match_emit_encodeBlockAsm10B_memmove_move_33through64: + FMOVQ (R6), F0 + FMOVQ 16(R6), F1 + ADD R8, R6, R15 + FMOVQ -32(R15), F2 + ADD R8, R6, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeBlockAsm10B: + MOVD R7, R1 + JMP emit_literal_done_match_emit_encodeBlockAsm10B + +memmove_long_match_emit_encodeBlockAsm10B: + ADD R8, R1, R7 + + // genMemMoveLong + MOVD R6, R9 + MOVD R1, R10 + MOVD R8, R11 + +emit_lit_memmove_long_match_emit_encodeBlockAsm10Blarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_match_emit_encodeBlockAsm10Blarge_big_loop_back + ADD R8, R6, R15 + FMOVQ -32(R15), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R7, R1 + +emit_literal_done_match_emit_encodeBlockAsm10B: +match_nolit_loop_encodeBlockAsm10B: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_encodeBlockAsm10B: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_encodeBlockAsm10B + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeBlockAsm10B + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_encodeBlockAsm10B + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_encodeBlockAsm10B + +matchlen_bsf_16match_nolit_encodeBlockAsm10B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeBlockAsm10B + +matchlen_match8_match_nolit_encodeBlockAsm10B: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_encodeBlockAsm10B + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeBlockAsm10B + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_encodeBlockAsm10B + +matchlen_bsf_8_match_nolit_encodeBlockAsm10B: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeBlockAsm10B + +matchlen_match4_match_nolit_encodeBlockAsm10B: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_encodeBlockAsm10B + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_encodeBlockAsm10B + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_encodeBlockAsm10B: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_encodeBlockAsm10B + BLO match_nolit_end_encodeBlockAsm10B + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeBlockAsm10B + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_encodeBlockAsm10B + +matchlen_match1_match_nolit_encodeBlockAsm10B: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_encodeBlockAsm10B + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_encodeBlockAsm10B: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_encodeBlockAsm10B + CMPW $0x00000800, R5 + BHS long_offset_short_match_nolit_encodeBlockAsm10B + MOVD $0x00000001, R6 + ADD $16, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R9, R9 + + // emitRepeat + SUB $4, R9, R9 + MOVWU R9, R9 + JMP cant_repeat_two_offset_match_nolit_encodeBlockAsm10B_emit_copy_short_2b + MOVWU R9, R6 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R6 + BLS repeat_two_match_nolit_encodeBlockAsm10B_emit_copy_short_2b + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm10B_emit_copy_short_2b + CMPW $0x00000800, R5 + BLO repeat_two_offset_match_nolit_encodeBlockAsm10B_emit_copy_short_2b + +cant_repeat_two_offset_match_nolit_encodeBlockAsm10B_emit_copy_short_2b: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm10B_emit_copy_short_2b + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm10B + +repeat_three_match_nolit_encodeBlockAsm10B_emit_copy_short_2b: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm10B + +repeat_two_match_nolit_encodeBlockAsm10B_emit_copy_short_2b: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm10B + +repeat_two_offset_match_nolit_encodeBlockAsm10B_emit_copy_short_2b: + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm10B + +long_offset_short_match_nolit_encodeBlockAsm10B: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R9, R6 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R6 + BLS repeat_two_match_nolit_encodeBlockAsm10B_emit_copy_short + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm10B_emit_copy_short + CMPW $0x00000800, R5 + BLO repeat_two_offset_match_nolit_encodeBlockAsm10B_emit_copy_short + +cant_repeat_two_offset_match_nolit_encodeBlockAsm10B_emit_copy_short: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm10B_emit_copy_short + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm10B + +repeat_three_match_nolit_encodeBlockAsm10B_emit_copy_short: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm10B + +repeat_two_match_nolit_encodeBlockAsm10B_emit_copy_short: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm10B + +repeat_two_offset_match_nolit_encodeBlockAsm10B_emit_copy_short: + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm10B + +two_byte_offset_short_match_nolit_encodeBlockAsm10B: + MOVWU R9, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_encodeBlockAsm10B + CMPW $0x00000800, R5 + BHS emit_copy_three_match_nolit_encodeBlockAsm10B + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm10B + +emit_copy_three_match_nolit_encodeBlockAsm10B: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeBlockAsm10B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeBlockAsm10B + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeBlockAsm10B: + MOVD $0x9e3779b1, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x20, R7, R7 + MUL R8, R7, R7 + LSR $0x36, R7, R7 + LSL $0x20, R5, R5 + MUL R8, R5, R5 + LSR $0x36, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_encodeBlockAsm10B + ADDW $1, R2, R2 + JMP search_loop_encodeBlockAsm10B + +emit_remainder_encodeBlockAsm10B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeBlockAsm10B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeBlockAsm10B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeBlockAsm10B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeBlockAsm10B + BLO three_bytes_emit_remainder_encodeBlockAsm10B + +three_bytes_emit_remainder_encodeBlockAsm10B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeBlockAsm10B + +two_bytes_emit_remainder_encodeBlockAsm10B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeBlockAsm10B + JMP memmove_long_emit_remainder_encodeBlockAsm10B + +one_byte_emit_remainder_encodeBlockAsm10B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeBlockAsm10B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeBlockAsm10B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeBlockAsm10B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeBlockAsm10B + +memmove_long_emit_remainder_encodeBlockAsm10B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeBlockAsm10Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeBlockAsm10Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeBlockAsm10B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeBlockAsm8B(dst []byte, src []byte, tmp *[1024]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeBlockAsm8B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000008, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeBlockAsm8B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeBlockAsm8B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeBlockAsm8B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x04, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeBlockAsm8B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x9e3779b1, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x20, R9, R9 + MUL R8, R9, R9 + LSR $0x38, R9, R9 + LSL $0x20, R10, R10 + MUL R8, R10, R10 + LSR $0x38, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x20, R9, R9 + MUL R8, R9, R9 + LSR $0x38, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_encodeBlockAsm8B + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R7 + MOVWU R6, R5 + MOVWU 24(RSP), R16 + SUBSW R16, R5, R5 + BEQ repeat_extend_back_end_encodeBlockAsm8B + +repeat_extend_back_loop_encodeBlockAsm8B: + CMPW R7, R6 + BLS repeat_extend_back_end_encodeBlockAsm8B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_encodeBlockAsm8B + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R5, R5 + BNE repeat_extend_back_loop_encodeBlockAsm8B + +repeat_extend_back_end_encodeBlockAsm8B: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $3, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_encodeBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +repeat_dst_size_check_encodeBlockAsm8B: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_encodeBlockAsm8B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_encodeBlockAsm8B + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_encodeBlockAsm8B + BLO three_bytes_repeat_emit_encodeBlockAsm8B + +three_bytes_repeat_emit_encodeBlockAsm8B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_encodeBlockAsm8B + +two_bytes_repeat_emit_encodeBlockAsm8B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_encodeBlockAsm8B + JMP memmove_long_repeat_emit_encodeBlockAsm8B + +one_byte_repeat_emit_encodeBlockAsm8B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_repeat_emit_encodeBlockAsm8B: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm8B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm8B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_repeat_emit_encodeBlockAsm8B_memmove_move_17through32 + JMP emit_lit_memmove_repeat_emit_encodeBlockAsm8B_memmove_move_33through64 + +emit_lit_memmove_repeat_emit_encodeBlockAsm8B_memmove_move_8: + MOVD (R9), R10 + MOVD R10, (R1) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm8B + +emit_lit_memmove_repeat_emit_encodeBlockAsm8B_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm8B + +emit_lit_memmove_repeat_emit_encodeBlockAsm8B_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_repeat_emit_encodeBlockAsm8B + +emit_lit_memmove_repeat_emit_encodeBlockAsm8B_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_repeat_emit_encodeBlockAsm8B: + MOVD R5, R1 + JMP emit_literal_done_repeat_emit_encodeBlockAsm8B + +memmove_long_repeat_emit_encodeBlockAsm8B: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R11 + MOVD R8, R12 + +emit_lit_memmove_long_repeat_emit_encodeBlockAsm8Blarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R11) + FMOVQ F1, 16(R11) + ADD $0x20, R10, R10 + ADD $0x20, R11, R11 + SUB $0x20, R12, R12 + CMP $0x20, R12 + BHS emit_lit_memmove_long_repeat_emit_encodeBlockAsm8Blarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_repeat_emit_encodeBlockAsm8B: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+32(FP), R8 + SUBW R2, R8, R8 + ADD R2, R3, R9 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_repeat_extend_encodeBlockAsm8B: + CMPW $0x10, R8 + BLO matchlen_match8_repeat_extend_encodeBlockAsm8B + MOVD (R9)(R11), R10 + ADD R11, R9, R15 + MOVD 8(R15), R12 + MOVD (R5)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_repeat_extend_encodeBlockAsm8B + ADD R11, R5, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16repeat_extend_encodeBlockAsm8B + SUB $16, R8, R8 + MOVWU R8, R8 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_repeat_extend_encodeBlockAsm8B + +matchlen_bsf_16repeat_extend_encodeBlockAsm8B: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP repeat_extend_forward_end_encodeBlockAsm8B + +matchlen_match8_repeat_extend_encodeBlockAsm8B: + CMPW $0x08, R8 + BLO matchlen_match4_repeat_extend_encodeBlockAsm8B + MOVD (R9)(R11), R10 + MOVD (R5)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_repeat_extend_encodeBlockAsm8B + SUB $8, R8, R8 + MOVWU R8, R8 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_repeat_extend_encodeBlockAsm8B + +matchlen_bsf_8_repeat_extend_encodeBlockAsm8B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP repeat_extend_forward_end_encodeBlockAsm8B + +matchlen_match4_repeat_extend_encodeBlockAsm8B: + CMPW $0x04, R8 + BLO matchlen_match2_repeat_extend_encodeBlockAsm8B + MOVWU (R9)(R11), R10 + MOVWU (R5)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_repeat_extend_encodeBlockAsm8B + SUB $4, R8, R8 + MOVWU R8, R8 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_repeat_extend_encodeBlockAsm8B: + CMPW $0x01, R8 + BEQ matchlen_match1_repeat_extend_encodeBlockAsm8B + BLO repeat_extend_forward_end_encodeBlockAsm8B + MOVHU (R9)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_encodeBlockAsm8B + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R8, R8 + BEQ repeat_extend_forward_end_encodeBlockAsm8B + +matchlen_match1_repeat_extend_encodeBlockAsm8B: + MOVBU (R9)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R5, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_encodeBlockAsm8B + ADD $1, R11, R11 + MOVWU R11, R11 + +repeat_extend_forward_end_encodeBlockAsm8B: + ADDW R11, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + TSTW R7, R7 + BEQ repeat_as_copy_encodeBlockAsm8B + + // emitRepeat + MOVWU R5, R6 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R6 + BLS repeat_two_match_repeat_encodeBlockAsm8B + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_match_repeat_encodeBlockAsm8B + +cant_repeat_two_offset_match_repeat_encodeBlockAsm8B: + CMPW $0x00000104, R5 + BLO repeat_three_match_repeat_encodeBlockAsm8B + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + +repeat_three_match_repeat_encodeBlockAsm8B: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + +repeat_two_match_repeat_encodeBlockAsm8B: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + +repeat_as_copy_encodeBlockAsm8B: + // emitCopy + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_encodeBlockAsm8B + CMPW $0x00000800, R6 + BHS long_offset_short_repeat_as_copy_encodeBlockAsm8B + MOVD $0x00000001, R7 + ADD $16, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R5, R5 + + // emitRepeat + SUB $4, R5, R5 + MOVWU R5, R5 + JMP cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm8B_emit_copy_short_2b + MOVWU R5, R6 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R6 + BLS repeat_two_repeat_as_copy_encodeBlockAsm8B_emit_copy_short_2b + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm8B_emit_copy_short_2b + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm8B_emit_copy_short_2b: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm8B_emit_copy_short_2b + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + +repeat_three_repeat_as_copy_encodeBlockAsm8B_emit_copy_short_2b: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + +repeat_two_repeat_as_copy_encodeBlockAsm8B_emit_copy_short_2b: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + +long_offset_short_repeat_as_copy_encodeBlockAsm8B: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R6, 1(R1) + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R5, R6 + SUB $4, R5, R5 + MOVWU R5, R5 + CMPW $0x08, R6 + BLS repeat_two_repeat_as_copy_encodeBlockAsm8B_emit_copy_short + CMPW $0x0c, R6 + BHS cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm8B_emit_copy_short + +cant_repeat_two_offset_repeat_as_copy_encodeBlockAsm8B_emit_copy_short: + CMPW $0x00000104, R5 + BLO repeat_three_repeat_as_copy_encodeBlockAsm8B_emit_copy_short + SUB $256, R5, R5 + MOVWU R5, R5 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R5, 2(R1) + ADD $0x04, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + +repeat_three_repeat_as_copy_encodeBlockAsm8B_emit_copy_short: + SUB $4, R5, R5 + MOVWU R5, R5 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R5, 2(R1) + ADD $0x03, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + +repeat_two_repeat_as_copy_encodeBlockAsm8B_emit_copy_short: + LSLW $0x02, R5, R5 + ORRW $0x01, R5, R5 + MOVH R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + MOVD $0, R7 + ADD R5<<2, R7, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVB R6, 1(R1) + ASRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + +two_byte_offset_short_repeat_as_copy_encodeBlockAsm8B: + MOVWU R5, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_encodeBlockAsm8B + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeBlockAsm8B + +emit_copy_three_repeat_as_copy_encodeBlockAsm8B: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R1) + MOVH R6, 1(R1) + ADD $0x03, R1, R1 + +repeat_end_emit_encodeBlockAsm8B: + MOVW R2, 20(RSP) + JMP search_loop_encodeBlockAsm8B + +no_repeat_found_encodeBlockAsm8B: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeBlockAsm8B + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_encodeBlockAsm8B + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_encodeBlockAsm8B + MOVWU 28(RSP), R2 + JMP search_loop_encodeBlockAsm8B + +candidate3_match_encodeBlockAsm8B: + ADDW $0x02, R2, R2 + JMP candidate_match_encodeBlockAsm8B + +candidate2_match_encodeBlockAsm8B: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeBlockAsm8B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeBlockAsm8B + +match_extend_back_loop_encodeBlockAsm8B: + CMPW R6, R2 + BLS match_extend_back_end_encodeBlockAsm8B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeBlockAsm8B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeBlockAsm8B + JMP match_extend_back_loop_encodeBlockAsm8B + +match_extend_back_end_encodeBlockAsm8B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeBlockAsm8B: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_encodeBlockAsm8B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R7 + MOVWU R7, R7 + CMPW $0x3c, R7 + BLO one_byte_match_emit_encodeBlockAsm8B + CMPW $0x00000100, R7 + BLO two_bytes_match_emit_encodeBlockAsm8B + BLO three_bytes_match_emit_encodeBlockAsm8B + +three_bytes_match_emit_encodeBlockAsm8B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeBlockAsm8B + +two_bytes_match_emit_encodeBlockAsm8B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R7, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R7 + BLO memmove_match_emit_encodeBlockAsm8B + JMP memmove_long_match_emit_encodeBlockAsm8B + +one_byte_match_emit_encodeBlockAsm8B: + LSLW $0x02, R7, R16 + BFI $0, R16, $8, R7 + MOVB R7, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeBlockAsm8B: + ADD R8, R1, R7 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm8B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm8B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeBlockAsm8B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeBlockAsm8B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeBlockAsm8B_memmove_move_8: + MOVD (R6), R9 + MOVD R9, (R1) + JMP memmove_end_copy_match_emit_encodeBlockAsm8B + +emit_lit_memmove_match_emit_encodeBlockAsm8B_memmove_move_8through16: + MOVD (R6), R9 + ADD R8, R6, R15 + MOVD -8(R15), R6 + MOVD R9, (R1) + ADD R8, R1, R15 + MOVD R6, -8(R15) + JMP memmove_end_copy_match_emit_encodeBlockAsm8B + +emit_lit_memmove_match_emit_encodeBlockAsm8B_memmove_move_17through32: + FMOVQ (R6), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeBlockAsm8B + +emit_lit_memmove_match_emit_encodeBlockAsm8B_memmove_move_33through64: + FMOVQ (R6), F0 + FMOVQ 16(R6), F1 + ADD R8, R6, R15 + FMOVQ -32(R15), F2 + ADD R8, R6, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeBlockAsm8B: + MOVD R7, R1 + JMP emit_literal_done_match_emit_encodeBlockAsm8B + +memmove_long_match_emit_encodeBlockAsm8B: + ADD R8, R1, R7 + + // genMemMoveLong + MOVD R6, R9 + MOVD R1, R10 + MOVD R8, R11 + +emit_lit_memmove_long_match_emit_encodeBlockAsm8Blarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_match_emit_encodeBlockAsm8Blarge_big_loop_back + ADD R8, R6, R15 + FMOVQ -32(R15), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R7, R1 + +emit_literal_done_match_emit_encodeBlockAsm8B: +match_nolit_loop_encodeBlockAsm8B: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_encodeBlockAsm8B: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_encodeBlockAsm8B + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeBlockAsm8B + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_encodeBlockAsm8B + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_encodeBlockAsm8B + +matchlen_bsf_16match_nolit_encodeBlockAsm8B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeBlockAsm8B + +matchlen_match8_match_nolit_encodeBlockAsm8B: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_encodeBlockAsm8B + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeBlockAsm8B + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_encodeBlockAsm8B + +matchlen_bsf_8_match_nolit_encodeBlockAsm8B: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeBlockAsm8B + +matchlen_match4_match_nolit_encodeBlockAsm8B: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_encodeBlockAsm8B + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_encodeBlockAsm8B + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_encodeBlockAsm8B: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_encodeBlockAsm8B + BLO match_nolit_end_encodeBlockAsm8B + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeBlockAsm8B + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_encodeBlockAsm8B + +matchlen_match1_match_nolit_encodeBlockAsm8B: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_encodeBlockAsm8B + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_encodeBlockAsm8B: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_encodeBlockAsm8B + CMPW $0x00000800, R5 + BHS long_offset_short_match_nolit_encodeBlockAsm8B + MOVD $0x00000001, R6 + ADD $16, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R9, R9 + + // emitRepeat + SUB $4, R9, R9 + MOVWU R9, R9 + JMP cant_repeat_two_offset_match_nolit_encodeBlockAsm8B_emit_copy_short_2b + MOVWU R9, R5 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBlockAsm8B_emit_copy_short_2b + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm8B_emit_copy_short_2b + +cant_repeat_two_offset_match_nolit_encodeBlockAsm8B_emit_copy_short_2b: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm8B_emit_copy_short_2b + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm8B + +repeat_three_match_nolit_encodeBlockAsm8B_emit_copy_short_2b: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm8B + +repeat_two_match_nolit_encodeBlockAsm8B_emit_copy_short_2b: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm8B + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm8B + +long_offset_short_match_nolit_encodeBlockAsm8B: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R9, R5 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBlockAsm8B_emit_copy_short + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBlockAsm8B_emit_copy_short + +cant_repeat_two_offset_match_nolit_encodeBlockAsm8B_emit_copy_short: + CMPW $0x00000104, R9 + BLO repeat_three_match_nolit_encodeBlockAsm8B_emit_copy_short + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R9, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm8B + +repeat_three_match_nolit_encodeBlockAsm8B_emit_copy_short: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R9, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm8B + +repeat_two_match_nolit_encodeBlockAsm8B_emit_copy_short: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm8B + MOVD $0, R6 + ADD R9<<2, R6, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R5, 1(R1) + ASRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R9, R9 + MOVB R9, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm8B + +two_byte_offset_short_match_nolit_encodeBlockAsm8B: + MOVWU R9, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_encodeBlockAsm8B + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBlockAsm8B + +emit_copy_three_match_nolit_encodeBlockAsm8B: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeBlockAsm8B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeBlockAsm8B + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeBlockAsm8B: + MOVD $0x9e3779b1, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x20, R7, R7 + MUL R8, R7, R7 + LSR $0x38, R7, R7 + LSL $0x20, R5, R5 + MUL R8, R5, R5 + LSR $0x38, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_encodeBlockAsm8B + ADDW $1, R2, R2 + JMP search_loop_encodeBlockAsm8B + +emit_remainder_encodeBlockAsm8B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeBlockAsm8B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeBlockAsm8B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeBlockAsm8B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeBlockAsm8B + BLO three_bytes_emit_remainder_encodeBlockAsm8B + +three_bytes_emit_remainder_encodeBlockAsm8B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeBlockAsm8B + +two_bytes_emit_remainder_encodeBlockAsm8B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeBlockAsm8B + JMP memmove_long_emit_remainder_encodeBlockAsm8B + +one_byte_emit_remainder_encodeBlockAsm8B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeBlockAsm8B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeBlockAsm8B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeBlockAsm8B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeBlockAsm8B + +memmove_long_emit_remainder_encodeBlockAsm8B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeBlockAsm8Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeBlockAsm8Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeBlockAsm8B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeBetterBlockAsm(dst []byte, src []byte, tmp *[589824]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeBetterBlockAsm(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00001200, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeBetterBlockAsm: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeBetterBlockAsm + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $6, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVD $0x00000000, R16 + MOVW R16, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeBetterBlockAsm: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x07, R5, R5 + CMPW $0x63, R5 + BLS check_maxskip_ok_encodeBetterBlockAsm + ADD $100, R2, R5 + MOVWU R5, R5 + JMP check_maxskip_cont_encodeBetterBlockAsm + +check_maxskip_ok_encodeBetterBlockAsm: + ADD R5, R2, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + +check_maxskip_cont_encodeBetterBlockAsm: + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeBetterBlockAsm + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x00cf1bbcdcbfa563, R8 + MOVD $0x9e3779b1, R5 + MOVD R6, R9 + MOVD R6, R10 + LSL $0x08, R9, R9 + MUL R8, R9, R9 + LSR $0x2f, R9, R9 + LSL $0x20, R10, R10 + MUL R5, R10, R10 + LSR $0x32, R10, R10 + MOVWU (R0)(R9<<2), R5 + ADD R10<<2, R0, R15 + MOVWU 524288(R15), R7 + MOVW R2, (R0)(R9<<2) + ADD R10<<2, R0, R15 + MOVW R2, 524288(R15) + MOVD (R3)(R5), R9 + MOVD (R3)(R7), R10 + CMP R6, R9 + BEQ candidate_match_encodeBetterBlockAsm + CMP R6, R10 + BNE no_short_found_encodeBetterBlockAsm + MOVWU R7, R5 + JMP candidate_match_encodeBetterBlockAsm + +no_short_found_encodeBetterBlockAsm: + CMPW R6, R9 + BEQ candidate_match_encodeBetterBlockAsm + CMPW R6, R10 + BEQ candidateS_match_encodeBetterBlockAsm + MOVWU 28(RSP), R2 + JMP search_loop_encodeBetterBlockAsm + +candidateS_match_encodeBetterBlockAsm: + LSR $0x08, R6, R6 + MOVD R6, R9 + LSL $0x08, R9, R9 + MUL R8, R9, R9 + LSR $0x2f, R9, R9 + MOVWU (R0)(R9<<2), R5 + ADDW $1, R2, R2 + MOVW R2, (R0)(R9<<2) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeBetterBlockAsm + SUBW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeBetterBlockAsm: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeBetterBlockAsm + +match_extend_back_loop_encodeBetterBlockAsm: + CMPW R6, R2 + BLS match_extend_back_end_encodeBetterBlockAsm + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeBetterBlockAsm + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeBetterBlockAsm + JMP match_extend_back_loop_encodeBetterBlockAsm + +match_extend_back_end_encodeBetterBlockAsm: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $5, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeBetterBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeBetterBlockAsm: + MOVWU R2, R6 + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R9 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_match_nolit_encodeBetterBlockAsm: + CMPW $0x10, R7 + BLO matchlen_match8_match_nolit_encodeBetterBlockAsm + MOVD (R8)(R11), R10 + ADD R11, R8, R15 + MOVD 8(R15), R12 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeBetterBlockAsm + ADD R11, R9, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16match_nolit_encodeBetterBlockAsm + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_match_nolit_encodeBetterBlockAsm + +matchlen_bsf_16match_nolit_encodeBetterBlockAsm: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeBetterBlockAsm + +matchlen_match8_match_nolit_encodeBetterBlockAsm: + CMPW $0x08, R7 + BLO matchlen_match4_match_nolit_encodeBetterBlockAsm + MOVD (R8)(R11), R10 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeBetterBlockAsm + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_match_nolit_encodeBetterBlockAsm + +matchlen_bsf_8_match_nolit_encodeBetterBlockAsm: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeBetterBlockAsm + +matchlen_match4_match_nolit_encodeBetterBlockAsm: + CMPW $0x04, R7 + BLO matchlen_match2_match_nolit_encodeBetterBlockAsm + MOVWU (R8)(R11), R10 + MOVWU (R9)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_match_nolit_encodeBetterBlockAsm + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_match_nolit_encodeBetterBlockAsm: + CMPW $0x01, R7 + BEQ matchlen_match1_match_nolit_encodeBetterBlockAsm + BLO match_nolit_end_encodeBetterBlockAsm + MOVHU (R8)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R9, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeBetterBlockAsm + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R7, R7 + BEQ match_nolit_end_encodeBetterBlockAsm + +matchlen_match1_match_nolit_encodeBetterBlockAsm: + MOVBU (R8)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R9, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE match_nolit_end_encodeBetterBlockAsm + ADD $1, R11, R11 + MOVWU R11, R11 + +match_nolit_end_encodeBetterBlockAsm: + MOVWU R2, R7 + SUBW R5, R7, R7 + + // Check if repeat + MOVWU 24(RSP), R16 + CMPW R7, R16 + BEQ match_is_repeat_encodeBetterBlockAsm + CMPW $0x01, R11 + BHI match_length_ok_encodeBetterBlockAsm + CMPW $0x0000ffff, R7 + BLS match_length_ok_encodeBetterBlockAsm + MOVWU 28(RSP), R2 + ADDW $1, R2, R2 + JMP search_loop_encodeBetterBlockAsm + +match_length_ok_encodeBetterBlockAsm: + MOVW R7, 24(RSP) + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_encodeBetterBlockAsm + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_encodeBetterBlockAsm + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_encodeBetterBlockAsm + CMPW $0x00010000, R5 + BLO three_bytes_match_emit_encodeBetterBlockAsm + CMPW $0x01000000, R5 + BLO four_bytes_match_emit_encodeBetterBlockAsm + MOVD $0xfc, R16 + MOVB R16, (R1) + MOVW R5, 1(R1) + ADD $0x05, R1, R1 + JMP memmove_long_match_emit_encodeBetterBlockAsm + +four_bytes_match_emit_encodeBetterBlockAsm: + MOVWU R5, R10 + LSRW $0x10, R10, R10 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + MOVB R10, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_match_emit_encodeBetterBlockAsm + +three_bytes_match_emit_encodeBetterBlockAsm: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeBetterBlockAsm + +two_bytes_match_emit_encodeBetterBlockAsm: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_encodeBetterBlockAsm + JMP memmove_long_match_emit_encodeBetterBlockAsm + +one_byte_match_emit_encodeBetterBlockAsm: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeBetterBlockAsm: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x04, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm_memmove_move_4 + CMP $0x08, R8 + BLO emit_lit_memmove_match_emit_encodeBetterBlockAsm_memmove_move_4through7 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeBetterBlockAsm_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeBetterBlockAsm_memmove_move_4: + MOVWU (R9), R10 + MOVW R10, (R1) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm + +emit_lit_memmove_match_emit_encodeBetterBlockAsm_memmove_move_4through7: + MOVWU (R9), R10 + ADD R8, R9, R15 + MOVWU -4(R15), R9 + MOVW R10, (R1) + ADD R8, R1, R15 + MOVW R9, -4(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm + +emit_lit_memmove_match_emit_encodeBetterBlockAsm_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm + +emit_lit_memmove_match_emit_encodeBetterBlockAsm_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm + +emit_lit_memmove_match_emit_encodeBetterBlockAsm_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeBetterBlockAsm: + MOVD R5, R1 + JMP emit_literal_done_match_emit_encodeBetterBlockAsm + +memmove_long_match_emit_encodeBetterBlockAsm: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_encodeBetterBlockAsmlarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_encodeBetterBlockAsmlarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_encodeBetterBlockAsm: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x00010000, R7 + BLO two_byte_offset_match_nolit_encodeBetterBlockAsm + CMPW $0x40, R11 + BLS four_bytes_remain_match_nolit_encodeBetterBlockAsm + MOVD $0xff, R16 + MOVB R16, (R1) + MOVW R7, 1(R1) + SUB $64, R11, R11 + MOVWU R11, R11 + ADD $0x05, R1, R1 + CMPW $0x04, R11 + BLO four_bytes_remain_match_nolit_encodeBetterBlockAsm + + // emitRepeat +emit_repeat_again_match_nolit_encodeBetterBlockAsm_emit_copy: + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm_emit_copy + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm_emit_copy + CMPW $0x00010100, R11 + BLO repeat_four_match_nolit_encodeBetterBlockAsm_emit_copy + CMPW $0x0100ffff, R11 + BLO repeat_five_match_nolit_encodeBetterBlockAsm_emit_copy + SUB $16842747, R11, R11 + MOVWU R11, R11 + MOVD $0xfffb001d, R16 + MOVW R16, (R1) + MOVD $0xff, R16 + MOVB R16, 4(R1) + ADD $0x05, R1, R1 + JMP emit_repeat_again_match_nolit_encodeBetterBlockAsm_emit_copy + +repeat_five_match_nolit_encodeBetterBlockAsm_emit_copy: + SUB $65536, R11, R11 + MOVWU R11, R11 + MOVWU R11, R7 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ASRW $0x10, R7, R7 + MOVB R7, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_four_match_nolit_encodeBetterBlockAsm_emit_copy: + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_three_match_nolit_encodeBetterBlockAsm_emit_copy: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_two_match_nolit_encodeBetterBlockAsm_emit_copy: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +four_bytes_remain_match_nolit_encodeBetterBlockAsm: + TSTW R11, R11 + BEQ match_nolit_emitcopy_end_encodeBetterBlockAsm + MOVD $0, R5 + ADD R11<<2, R5, R11 + SUB $1, R11, R11 + MOVWU R11, R11 + MOVB R11, (R1) + MOVW R7, 1(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +two_byte_offset_match_nolit_encodeBetterBlockAsm: + CMPW $0x40, R11 + BLS two_byte_offset_short_match_nolit_encodeBetterBlockAsm + CMPW $0x00000800, R7 + BHS long_offset_short_match_nolit_encodeBetterBlockAsm + MOVD $0x00000001, R5 + ADD $16, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + MOVWU R7, R8 + LSRW $0x08, R8, R8 + LSLW $0x05, R8, R8 + ORRW R8, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R11, R11 + + // emitRepeat + SUB $4, R11, R11 + MOVWU R11, R11 + JMP cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b + +emit_repeat_again_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b: + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b + CMPW $0x00010100, R11 + BLO repeat_four_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b + CMPW $0x0100ffff, R11 + BLO repeat_five_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b + SUB $16842747, R11, R11 + MOVWU R11, R11 + MOVD $0xfffb001d, R16 + MOVW R16, (R1) + MOVD $0xff, R16 + MOVB R16, 4(R1) + ADD $0x05, R1, R1 + JMP emit_repeat_again_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b + +repeat_five_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b: + SUB $65536, R11, R11 + MOVWU R11, R11 + MOVWU R11, R7 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ASRW $0x10, R7, R7 + MOVB R7, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_four_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b: + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_three_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_two_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy_short_2b: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +long_offset_short_match_nolit_encodeBetterBlockAsm: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + SUB $60, R11, R11 + MOVWU R11, R11 + ADD $0x03, R1, R1 + + // emitRepeat +emit_repeat_again_match_nolit_encodeBetterBlockAsm_emit_copy_short: + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm_emit_copy_short + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy_short + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy_short + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy_short: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm_emit_copy_short + CMPW $0x00010100, R11 + BLO repeat_four_match_nolit_encodeBetterBlockAsm_emit_copy_short + CMPW $0x0100ffff, R11 + BLO repeat_five_match_nolit_encodeBetterBlockAsm_emit_copy_short + SUB $16842747, R11, R11 + MOVWU R11, R11 + MOVD $0xfffb001d, R16 + MOVW R16, (R1) + MOVD $0xff, R16 + MOVB R16, 4(R1) + ADD $0x05, R1, R1 + JMP emit_repeat_again_match_nolit_encodeBetterBlockAsm_emit_copy_short + +repeat_five_match_nolit_encodeBetterBlockAsm_emit_copy_short: + SUB $65536, R11, R11 + MOVWU R11, R11 + MOVWU R11, R7 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ASRW $0x10, R7, R7 + MOVB R7, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_four_match_nolit_encodeBetterBlockAsm_emit_copy_short: + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_three_match_nolit_encodeBetterBlockAsm_emit_copy_short: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_two_match_nolit_encodeBetterBlockAsm_emit_copy_short: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_two_offset_match_nolit_encodeBetterBlockAsm_emit_copy_short: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +two_byte_offset_short_match_nolit_encodeBetterBlockAsm: + MOVWU R11, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R11 + BHS emit_copy_three_match_nolit_encodeBetterBlockAsm + CMPW $0x00000800, R7 + BHS emit_copy_three_match_nolit_encodeBetterBlockAsm + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +emit_copy_three_match_nolit_encodeBetterBlockAsm: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +match_is_repeat_encodeBetterBlockAsm: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_repeat_encodeBetterBlockAsm + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_repeat_encodeBetterBlockAsm + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_repeat_encodeBetterBlockAsm + CMPW $0x00010000, R5 + BLO three_bytes_match_emit_repeat_encodeBetterBlockAsm + CMPW $0x01000000, R5 + BLO four_bytes_match_emit_repeat_encodeBetterBlockAsm + MOVD $0xfc, R16 + MOVB R16, (R1) + MOVW R5, 1(R1) + ADD $0x05, R1, R1 + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm + +four_bytes_match_emit_repeat_encodeBetterBlockAsm: + MOVWU R5, R10 + LSRW $0x10, R10, R10 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + MOVB R10, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm + +three_bytes_match_emit_repeat_encodeBetterBlockAsm: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm + +two_bytes_match_emit_repeat_encodeBetterBlockAsm: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_repeat_encodeBetterBlockAsm + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm + +one_byte_match_emit_repeat_encodeBetterBlockAsm: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_repeat_encodeBetterBlockAsm: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x04, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm_memmove_move_4 + CMP $0x08, R8 + BLO emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm_memmove_move_4through7 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm_memmove_move_33through64 + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm_memmove_move_4: + MOVWU (R9), R10 + MOVW R10, (R1) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm_memmove_move_4through7: + MOVWU (R9), R10 + ADD R8, R9, R15 + MOVWU -4(R15), R9 + MOVW R10, (R1) + ADD R8, R1, R15 + MOVW R9, -4(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm: + MOVD R5, R1 + JMP emit_literal_done_match_emit_repeat_encodeBetterBlockAsm + +memmove_long_match_emit_repeat_encodeBetterBlockAsm: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_repeat_encodeBetterBlockAsmlarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_repeat_encodeBetterBlockAsmlarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_repeat_encodeBetterBlockAsm: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitRepeat +emit_repeat_again_match_nolit_repeat_encodeBetterBlockAsm: + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_repeat_encodeBetterBlockAsm + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm + +cant_repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_repeat_encodeBetterBlockAsm + CMPW $0x00010100, R11 + BLO repeat_four_match_nolit_repeat_encodeBetterBlockAsm + CMPW $0x0100ffff, R11 + BLO repeat_five_match_nolit_repeat_encodeBetterBlockAsm + SUB $16842747, R11, R11 + MOVWU R11, R11 + MOVD $0xfffb001d, R16 + MOVW R16, (R1) + MOVD $0xff, R16 + MOVB R16, 4(R1) + ADD $0x05, R1, R1 + JMP emit_repeat_again_match_nolit_repeat_encodeBetterBlockAsm + +repeat_five_match_nolit_repeat_encodeBetterBlockAsm: + SUB $65536, R11, R11 + MOVWU R11, R11 + MOVWU R11, R7 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ASRW $0x10, R7, R7 + MOVB R7, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_four_match_nolit_repeat_encodeBetterBlockAsm: + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_three_match_nolit_repeat_encodeBetterBlockAsm: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_two_match_nolit_repeat_encodeBetterBlockAsm: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm + +repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + +match_nolit_emitcopy_end_encodeBetterBlockAsm: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeBetterBlockAsm + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeBetterBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeBetterBlockAsm: + MOVD $0x00cf1bbcdcbfa563, R5 + MOVD $0x9e3779b1, R7 + ADD $1, R6, R6 + SUB $2, R2, R8 + MOVD (R3)(R6), R9 + ADD R6, R3, R15 + MOVD 1(R15), R10 + MOVD (R3)(R8), R11 + ADD R8, R3, R15 + MOVD 1(R15), R12 + LSL $0x08, R9, R9 + MUL R5, R9, R9 + LSR $0x2f, R9, R9 + LSL $0x20, R10, R10 + MUL R7, R10, R10 + LSR $0x32, R10, R10 + LSL $0x08, R11, R11 + MUL R5, R11, R11 + LSR $0x2f, R11, R11 + LSL $0x20, R12, R12 + MUL R7, R12, R12 + LSR $0x32, R12, R12 + ADD $1, R6, R7 + ADD $1, R8, R13 + MOVW R6, (R0)(R9<<2) + MOVW R8, (R0)(R11<<2) + ADD R10<<2, R0, R15 + MOVW R7, 524288(R15) + ADD R12<<2, R0, R15 + MOVW R13, 524288(R15) + ADD R6, R8, R7 + ADD $1, R7, R7 + LSR $0x01, R7, R7 + ADD $0x01, R6, R6 + SUB $0x01, R8, R8 + +index_loop_encodeBetterBlockAsm: + CMP R8, R7 + BHS search_loop_encodeBetterBlockAsm + MOVD (R3)(R6), R9 + MOVD (R3)(R7), R10 + LSL $0x08, R9, R9 + MUL R5, R9, R9 + LSR $0x2f, R9, R9 + LSL $0x08, R10, R10 + MUL R5, R10, R10 + LSR $0x2f, R10, R10 + MOVW R6, (R0)(R9<<2) + MOVW R7, (R0)(R10<<2) + ADD $0x02, R6, R6 + ADD $0x02, R7, R7 + JMP index_loop_encodeBetterBlockAsm + +emit_remainder_encodeBetterBlockAsm: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $5, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeBetterBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeBetterBlockAsm: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeBetterBlockAsm + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeBetterBlockAsm + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeBetterBlockAsm + CMPW $0x00010000, R2 + BLO three_bytes_emit_remainder_encodeBetterBlockAsm + CMPW $0x01000000, R2 + BLO four_bytes_emit_remainder_encodeBetterBlockAsm + MOVD $0xfc, R16 + MOVB R16, (R1) + MOVW R2, 1(R1) + ADD $0x05, R1, R1 + JMP memmove_long_emit_remainder_encodeBetterBlockAsm + +four_bytes_emit_remainder_encodeBetterBlockAsm: + MOVWU R2, R3 + LSRW $0x10, R3, R3 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + MOVB R3, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_emit_remainder_encodeBetterBlockAsm + +three_bytes_emit_remainder_encodeBetterBlockAsm: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeBetterBlockAsm + +two_bytes_emit_remainder_encodeBetterBlockAsm: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeBetterBlockAsm + JMP memmove_long_emit_remainder_encodeBetterBlockAsm + +one_byte_emit_remainder_encodeBetterBlockAsm: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeBetterBlockAsm: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeBetterBlockAsm: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeBetterBlockAsm + +memmove_long_emit_remainder_encodeBetterBlockAsm: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeBetterBlockAsmlarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeBetterBlockAsmlarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeBetterBlockAsm: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeBetterBlockAsm4MB(dst []byte, src []byte, tmp *[589824]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeBetterBlockAsm4MB(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00001200, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeBetterBlockAsm4MB: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeBetterBlockAsm4MB + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $6, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVD $0x00000000, R16 + MOVW R16, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeBetterBlockAsm4MB: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x07, R5, R5 + CMPW $0x63, R5 + BLS check_maxskip_ok_encodeBetterBlockAsm4MB + ADD $100, R2, R5 + MOVWU R5, R5 + JMP check_maxskip_cont_encodeBetterBlockAsm4MB + +check_maxskip_ok_encodeBetterBlockAsm4MB: + ADD R5, R2, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + +check_maxskip_cont_encodeBetterBlockAsm4MB: + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeBetterBlockAsm4MB + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x00cf1bbcdcbfa563, R8 + MOVD $0x9e3779b1, R5 + MOVD R6, R9 + MOVD R6, R10 + LSL $0x08, R9, R9 + MUL R8, R9, R9 + LSR $0x2f, R9, R9 + LSL $0x20, R10, R10 + MUL R5, R10, R10 + LSR $0x32, R10, R10 + MOVWU (R0)(R9<<2), R5 + ADD R10<<2, R0, R15 + MOVWU 524288(R15), R7 + MOVW R2, (R0)(R9<<2) + ADD R10<<2, R0, R15 + MOVW R2, 524288(R15) + MOVD (R3)(R5), R9 + MOVD (R3)(R7), R10 + CMP R6, R9 + BEQ candidate_match_encodeBetterBlockAsm4MB + CMP R6, R10 + BNE no_short_found_encodeBetterBlockAsm4MB + MOVWU R7, R5 + JMP candidate_match_encodeBetterBlockAsm4MB + +no_short_found_encodeBetterBlockAsm4MB: + CMPW R6, R9 + BEQ candidate_match_encodeBetterBlockAsm4MB + CMPW R6, R10 + BEQ candidateS_match_encodeBetterBlockAsm4MB + MOVWU 28(RSP), R2 + JMP search_loop_encodeBetterBlockAsm4MB + +candidateS_match_encodeBetterBlockAsm4MB: + LSR $0x08, R6, R6 + MOVD R6, R9 + LSL $0x08, R9, R9 + MUL R8, R9, R9 + LSR $0x2f, R9, R9 + MOVWU (R0)(R9<<2), R5 + ADDW $1, R2, R2 + MOVW R2, (R0)(R9<<2) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeBetterBlockAsm4MB + SUBW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeBetterBlockAsm4MB: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeBetterBlockAsm4MB + +match_extend_back_loop_encodeBetterBlockAsm4MB: + CMPW R6, R2 + BLS match_extend_back_end_encodeBetterBlockAsm4MB + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeBetterBlockAsm4MB + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeBetterBlockAsm4MB + JMP match_extend_back_loop_encodeBetterBlockAsm4MB + +match_extend_back_end_encodeBetterBlockAsm4MB: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $4, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeBetterBlockAsm4MB + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeBetterBlockAsm4MB: + MOVWU R2, R6 + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R9 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_match_nolit_encodeBetterBlockAsm4MB: + CMPW $0x10, R7 + BLO matchlen_match8_match_nolit_encodeBetterBlockAsm4MB + MOVD (R8)(R11), R10 + ADD R11, R8, R15 + MOVD 8(R15), R12 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeBetterBlockAsm4MB + ADD R11, R9, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16match_nolit_encodeBetterBlockAsm4MB + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_match_nolit_encodeBetterBlockAsm4MB + +matchlen_bsf_16match_nolit_encodeBetterBlockAsm4MB: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeBetterBlockAsm4MB + +matchlen_match8_match_nolit_encodeBetterBlockAsm4MB: + CMPW $0x08, R7 + BLO matchlen_match4_match_nolit_encodeBetterBlockAsm4MB + MOVD (R8)(R11), R10 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeBetterBlockAsm4MB + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_match_nolit_encodeBetterBlockAsm4MB + +matchlen_bsf_8_match_nolit_encodeBetterBlockAsm4MB: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeBetterBlockAsm4MB + +matchlen_match4_match_nolit_encodeBetterBlockAsm4MB: + CMPW $0x04, R7 + BLO matchlen_match2_match_nolit_encodeBetterBlockAsm4MB + MOVWU (R8)(R11), R10 + MOVWU (R9)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_match_nolit_encodeBetterBlockAsm4MB + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_match_nolit_encodeBetterBlockAsm4MB: + CMPW $0x01, R7 + BEQ matchlen_match1_match_nolit_encodeBetterBlockAsm4MB + BLO match_nolit_end_encodeBetterBlockAsm4MB + MOVHU (R8)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R9, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeBetterBlockAsm4MB + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R7, R7 + BEQ match_nolit_end_encodeBetterBlockAsm4MB + +matchlen_match1_match_nolit_encodeBetterBlockAsm4MB: + MOVBU (R8)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R9, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE match_nolit_end_encodeBetterBlockAsm4MB + ADD $1, R11, R11 + MOVWU R11, R11 + +match_nolit_end_encodeBetterBlockAsm4MB: + MOVWU R2, R7 + SUBW R5, R7, R7 + + // Check if repeat + MOVWU 24(RSP), R16 + CMPW R7, R16 + BEQ match_is_repeat_encodeBetterBlockAsm4MB + CMPW $0x01, R11 + BHI match_length_ok_encodeBetterBlockAsm4MB + CMPW $0x0000ffff, R7 + BLS match_length_ok_encodeBetterBlockAsm4MB + MOVWU 28(RSP), R2 + ADDW $1, R2, R2 + JMP search_loop_encodeBetterBlockAsm4MB + +match_length_ok_encodeBetterBlockAsm4MB: + MOVW R7, 24(RSP) + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_encodeBetterBlockAsm4MB + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_encodeBetterBlockAsm4MB + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_encodeBetterBlockAsm4MB + CMPW $0x00010000, R5 + BLO three_bytes_match_emit_encodeBetterBlockAsm4MB + MOVWU R5, R10 + LSRW $0x10, R10, R10 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + MOVB R10, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_match_emit_encodeBetterBlockAsm4MB + +three_bytes_match_emit_encodeBetterBlockAsm4MB: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeBetterBlockAsm4MB + +two_bytes_match_emit_encodeBetterBlockAsm4MB: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_encodeBetterBlockAsm4MB + JMP memmove_long_match_emit_encodeBetterBlockAsm4MB + +one_byte_match_emit_encodeBetterBlockAsm4MB: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeBetterBlockAsm4MB: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x04, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm4MB_memmove_move_4 + CMP $0x08, R8 + BLO emit_lit_memmove_match_emit_encodeBetterBlockAsm4MB_memmove_move_4through7 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm4MB_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm4MB_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeBetterBlockAsm4MB_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeBetterBlockAsm4MB_memmove_move_4: + MOVWU (R9), R10 + MOVW R10, (R1) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm4MB + +emit_lit_memmove_match_emit_encodeBetterBlockAsm4MB_memmove_move_4through7: + MOVWU (R9), R10 + ADD R8, R9, R15 + MOVWU -4(R15), R9 + MOVW R10, (R1) + ADD R8, R1, R15 + MOVW R9, -4(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm4MB + +emit_lit_memmove_match_emit_encodeBetterBlockAsm4MB_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm4MB + +emit_lit_memmove_match_emit_encodeBetterBlockAsm4MB_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm4MB + +emit_lit_memmove_match_emit_encodeBetterBlockAsm4MB_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeBetterBlockAsm4MB: + MOVD R5, R1 + JMP emit_literal_done_match_emit_encodeBetterBlockAsm4MB + +memmove_long_match_emit_encodeBetterBlockAsm4MB: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_encodeBetterBlockAsm4MBlarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_encodeBetterBlockAsm4MBlarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_encodeBetterBlockAsm4MB: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x00010000, R7 + BLO two_byte_offset_match_nolit_encodeBetterBlockAsm4MB + CMPW $0x40, R11 + BLS four_bytes_remain_match_nolit_encodeBetterBlockAsm4MB + MOVD $0xff, R16 + MOVB R16, (R1) + MOVW R7, 1(R1) + SUB $64, R11, R11 + MOVWU R11, R11 + ADD $0x05, R1, R1 + CMPW $0x04, R11 + BLO four_bytes_remain_match_nolit_encodeBetterBlockAsm4MB + + // emitRepeat + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm4MB_emit_copy + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm4MB_emit_copy + CMPW $0x00010100, R11 + BLO repeat_four_match_nolit_encodeBetterBlockAsm4MB_emit_copy + SUB $65536, R11, R11 + MOVWU R11, R11 + MOVWU R11, R7 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ASRW $0x10, R7, R7 + MOVB R7, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_four_match_nolit_encodeBetterBlockAsm4MB_emit_copy: + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_three_match_nolit_encodeBetterBlockAsm4MB_emit_copy: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_two_match_nolit_encodeBetterBlockAsm4MB_emit_copy: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +four_bytes_remain_match_nolit_encodeBetterBlockAsm4MB: + TSTW R11, R11 + BEQ match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + MOVD $0, R5 + ADD R11<<2, R5, R11 + SUB $1, R11, R11 + MOVWU R11, R11 + MOVB R11, (R1) + MOVW R7, 1(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +two_byte_offset_match_nolit_encodeBetterBlockAsm4MB: + CMPW $0x40, R11 + BLS two_byte_offset_short_match_nolit_encodeBetterBlockAsm4MB + CMPW $0x00000800, R7 + BHS long_offset_short_match_nolit_encodeBetterBlockAsm4MB + MOVD $0x00000001, R5 + ADD $16, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R11, R11 + + // emitRepeat + SUB $4, R11, R11 + MOVWU R11, R11 + JMP cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short_2b + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short_2b + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short_2b + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short_2b + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short_2b: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short_2b + CMPW $0x00010100, R11 + BLO repeat_four_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short_2b + SUB $65536, R11, R11 + MOVWU R11, R11 + MOVWU R11, R7 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ASRW $0x10, R7, R7 + MOVB R7, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_four_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short_2b: + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_three_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short_2b: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_two_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short_2b: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short_2b: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +long_offset_short_match_nolit_encodeBetterBlockAsm4MB: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + SUB $60, R11, R11 + MOVWU R11, R11 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short + CMPW $0x00010100, R11 + BLO repeat_four_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short + SUB $65536, R11, R11 + MOVWU R11, R11 + MOVWU R11, R7 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ASRW $0x10, R7, R7 + MOVB R7, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_four_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short: + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_three_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_two_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_two_offset_match_nolit_encodeBetterBlockAsm4MB_emit_copy_short: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +two_byte_offset_short_match_nolit_encodeBetterBlockAsm4MB: + MOVWU R11, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R11 + BHS emit_copy_three_match_nolit_encodeBetterBlockAsm4MB + CMPW $0x00000800, R7 + BHS emit_copy_three_match_nolit_encodeBetterBlockAsm4MB + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +emit_copy_three_match_nolit_encodeBetterBlockAsm4MB: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +match_is_repeat_encodeBetterBlockAsm4MB: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_repeat_encodeBetterBlockAsm4MB + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_repeat_encodeBetterBlockAsm4MB + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_repeat_encodeBetterBlockAsm4MB + CMPW $0x00010000, R5 + BLO three_bytes_match_emit_repeat_encodeBetterBlockAsm4MB + MOVWU R5, R10 + LSRW $0x10, R10, R10 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + MOVB R10, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm4MB + +three_bytes_match_emit_repeat_encodeBetterBlockAsm4MB: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm4MB + +two_bytes_match_emit_repeat_encodeBetterBlockAsm4MB: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_repeat_encodeBetterBlockAsm4MB + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm4MB + +one_byte_match_emit_repeat_encodeBetterBlockAsm4MB: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_repeat_encodeBetterBlockAsm4MB: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x04, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm4MB_memmove_move_4 + CMP $0x08, R8 + BLO emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm4MB_memmove_move_4through7 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm4MB_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm4MB_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm4MB_memmove_move_33through64 + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm4MB_memmove_move_4: + MOVWU (R9), R10 + MOVW R10, (R1) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm4MB + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm4MB_memmove_move_4through7: + MOVWU (R9), R10 + ADD R8, R9, R15 + MOVWU -4(R15), R9 + MOVW R10, (R1) + ADD R8, R1, R15 + MOVW R9, -4(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm4MB + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm4MB_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm4MB + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm4MB_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm4MB + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm4MB_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm4MB: + MOVD R5, R1 + JMP emit_literal_done_match_emit_repeat_encodeBetterBlockAsm4MB + +memmove_long_match_emit_repeat_encodeBetterBlockAsm4MB: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_repeat_encodeBetterBlockAsm4MBlarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_repeat_encodeBetterBlockAsm4MBlarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_repeat_encodeBetterBlockAsm4MB: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitRepeat + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_repeat_encodeBetterBlockAsm4MB + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm4MB + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm4MB + +cant_repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm4MB: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_repeat_encodeBetterBlockAsm4MB + CMPW $0x00010100, R11 + BLO repeat_four_match_nolit_repeat_encodeBetterBlockAsm4MB + SUB $65536, R11, R11 + MOVWU R11, R11 + MOVWU R11, R7 + MOVD $0x001d, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ASRW $0x10, R7, R7 + MOVB R7, 4(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_four_match_nolit_repeat_encodeBetterBlockAsm4MB: + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_three_match_nolit_repeat_encodeBetterBlockAsm4MB: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_two_match_nolit_repeat_encodeBetterBlockAsm4MB: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm4MB + +repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm4MB: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + +match_nolit_emitcopy_end_encodeBetterBlockAsm4MB: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeBetterBlockAsm4MB + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeBetterBlockAsm4MB + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeBetterBlockAsm4MB: + MOVD $0x00cf1bbcdcbfa563, R5 + MOVD $0x9e3779b1, R7 + ADD $1, R6, R6 + SUB $2, R2, R8 + MOVD (R3)(R6), R9 + ADD R6, R3, R15 + MOVD 1(R15), R10 + MOVD (R3)(R8), R11 + ADD R8, R3, R15 + MOVD 1(R15), R12 + LSL $0x08, R9, R9 + MUL R5, R9, R9 + LSR $0x2f, R9, R9 + LSL $0x20, R10, R10 + MUL R7, R10, R10 + LSR $0x32, R10, R10 + LSL $0x08, R11, R11 + MUL R5, R11, R11 + LSR $0x2f, R11, R11 + LSL $0x20, R12, R12 + MUL R7, R12, R12 + LSR $0x32, R12, R12 + ADD $1, R6, R7 + ADD $1, R8, R13 + MOVW R6, (R0)(R9<<2) + MOVW R8, (R0)(R11<<2) + ADD R10<<2, R0, R15 + MOVW R7, 524288(R15) + ADD R12<<2, R0, R15 + MOVW R13, 524288(R15) + ADD R6, R8, R7 + ADD $1, R7, R7 + LSR $0x01, R7, R7 + ADD $0x01, R6, R6 + SUB $0x01, R8, R8 + +index_loop_encodeBetterBlockAsm4MB: + CMP R8, R7 + BHS search_loop_encodeBetterBlockAsm4MB + MOVD (R3)(R6), R9 + MOVD (R3)(R7), R10 + LSL $0x08, R9, R9 + MUL R5, R9, R9 + LSR $0x2f, R9, R9 + LSL $0x08, R10, R10 + MUL R5, R10, R10 + LSR $0x2f, R10, R10 + MOVW R6, (R0)(R9<<2) + MOVW R7, (R0)(R10<<2) + ADD $0x02, R6, R6 + ADD $0x02, R7, R7 + JMP index_loop_encodeBetterBlockAsm4MB + +emit_remainder_encodeBetterBlockAsm4MB: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $4, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeBetterBlockAsm4MB + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeBetterBlockAsm4MB: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeBetterBlockAsm4MB + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeBetterBlockAsm4MB + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeBetterBlockAsm4MB + CMPW $0x00010000, R2 + BLO three_bytes_emit_remainder_encodeBetterBlockAsm4MB + MOVWU R2, R3 + LSRW $0x10, R3, R3 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + MOVB R3, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_emit_remainder_encodeBetterBlockAsm4MB + +three_bytes_emit_remainder_encodeBetterBlockAsm4MB: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeBetterBlockAsm4MB + +two_bytes_emit_remainder_encodeBetterBlockAsm4MB: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeBetterBlockAsm4MB + JMP memmove_long_emit_remainder_encodeBetterBlockAsm4MB + +one_byte_emit_remainder_encodeBetterBlockAsm4MB: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeBetterBlockAsm4MB: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm4MB + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm4MB + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm4MB + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm4MB + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm4MB + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm4MB_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeBetterBlockAsm4MB: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeBetterBlockAsm4MB + +memmove_long_emit_remainder_encodeBetterBlockAsm4MB: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeBetterBlockAsm4MBlarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeBetterBlockAsm4MBlarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeBetterBlockAsm4MB: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeBetterBlockAsm12B(dst []byte, src []byte, tmp *[81920]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeBetterBlockAsm12B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000280, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeBetterBlockAsm12B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeBetterBlockAsm12B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $6, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVD $0x00000000, R16 + MOVW R16, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeBetterBlockAsm12B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x06, R5, R5 + ADD R5, R2, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeBetterBlockAsm12B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD $0x9e3779b1, R5 + MOVD R6, R9 + MOVD R6, R10 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + LSL $0x20, R10, R10 + MUL R5, R10, R10 + LSR $0x34, R10, R10 + MOVWU (R0)(R9<<2), R5 + ADD R10<<2, R0, R15 + MOVWU 65536(R15), R7 + MOVW R2, (R0)(R9<<2) + ADD R10<<2, R0, R15 + MOVW R2, 65536(R15) + MOVD (R3)(R5), R9 + MOVD (R3)(R7), R10 + CMP R6, R9 + BEQ candidate_match_encodeBetterBlockAsm12B + CMP R6, R10 + BNE no_short_found_encodeBetterBlockAsm12B + MOVWU R7, R5 + JMP candidate_match_encodeBetterBlockAsm12B + +no_short_found_encodeBetterBlockAsm12B: + CMPW R6, R9 + BEQ candidate_match_encodeBetterBlockAsm12B + CMPW R6, R10 + BEQ candidateS_match_encodeBetterBlockAsm12B + MOVWU 28(RSP), R2 + JMP search_loop_encodeBetterBlockAsm12B + +candidateS_match_encodeBetterBlockAsm12B: + LSR $0x08, R6, R6 + MOVD R6, R9 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + MOVWU (R0)(R9<<2), R5 + ADDW $1, R2, R2 + MOVW R2, (R0)(R9<<2) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeBetterBlockAsm12B + SUBW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeBetterBlockAsm12B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeBetterBlockAsm12B + +match_extend_back_loop_encodeBetterBlockAsm12B: + CMPW R6, R2 + BLS match_extend_back_end_encodeBetterBlockAsm12B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeBetterBlockAsm12B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeBetterBlockAsm12B + JMP match_extend_back_loop_encodeBetterBlockAsm12B + +match_extend_back_end_encodeBetterBlockAsm12B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeBetterBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeBetterBlockAsm12B: + MOVWU R2, R6 + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R9 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_match_nolit_encodeBetterBlockAsm12B: + CMPW $0x10, R7 + BLO matchlen_match8_match_nolit_encodeBetterBlockAsm12B + MOVD (R8)(R11), R10 + ADD R11, R8, R15 + MOVD 8(R15), R12 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeBetterBlockAsm12B + ADD R11, R9, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16match_nolit_encodeBetterBlockAsm12B + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_match_nolit_encodeBetterBlockAsm12B + +matchlen_bsf_16match_nolit_encodeBetterBlockAsm12B: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeBetterBlockAsm12B + +matchlen_match8_match_nolit_encodeBetterBlockAsm12B: + CMPW $0x08, R7 + BLO matchlen_match4_match_nolit_encodeBetterBlockAsm12B + MOVD (R8)(R11), R10 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeBetterBlockAsm12B + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_match_nolit_encodeBetterBlockAsm12B + +matchlen_bsf_8_match_nolit_encodeBetterBlockAsm12B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeBetterBlockAsm12B + +matchlen_match4_match_nolit_encodeBetterBlockAsm12B: + CMPW $0x04, R7 + BLO matchlen_match2_match_nolit_encodeBetterBlockAsm12B + MOVWU (R8)(R11), R10 + MOVWU (R9)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_match_nolit_encodeBetterBlockAsm12B + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_match_nolit_encodeBetterBlockAsm12B: + CMPW $0x01, R7 + BEQ matchlen_match1_match_nolit_encodeBetterBlockAsm12B + BLO match_nolit_end_encodeBetterBlockAsm12B + MOVHU (R8)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R9, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeBetterBlockAsm12B + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R7, R7 + BEQ match_nolit_end_encodeBetterBlockAsm12B + +matchlen_match1_match_nolit_encodeBetterBlockAsm12B: + MOVBU (R8)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R9, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE match_nolit_end_encodeBetterBlockAsm12B + ADD $1, R11, R11 + MOVWU R11, R11 + +match_nolit_end_encodeBetterBlockAsm12B: + MOVWU R2, R7 + SUBW R5, R7, R7 + + // Check if repeat + MOVWU 24(RSP), R16 + CMPW R7, R16 + BEQ match_is_repeat_encodeBetterBlockAsm12B + MOVW R7, 24(RSP) + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_encodeBetterBlockAsm12B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_encodeBetterBlockAsm12B + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_encodeBetterBlockAsm12B + BLO three_bytes_match_emit_encodeBetterBlockAsm12B + +three_bytes_match_emit_encodeBetterBlockAsm12B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeBetterBlockAsm12B + +two_bytes_match_emit_encodeBetterBlockAsm12B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_encodeBetterBlockAsm12B + JMP memmove_long_match_emit_encodeBetterBlockAsm12B + +one_byte_match_emit_encodeBetterBlockAsm12B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeBetterBlockAsm12B: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x04, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm12B_memmove_move_4 + CMP $0x08, R8 + BLO emit_lit_memmove_match_emit_encodeBetterBlockAsm12B_memmove_move_4through7 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm12B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm12B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeBetterBlockAsm12B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeBetterBlockAsm12B_memmove_move_4: + MOVWU (R9), R10 + MOVW R10, (R1) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm12B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm12B_memmove_move_4through7: + MOVWU (R9), R10 + ADD R8, R9, R15 + MOVWU -4(R15), R9 + MOVW R10, (R1) + ADD R8, R1, R15 + MOVW R9, -4(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm12B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm12B_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm12B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm12B_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm12B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm12B_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeBetterBlockAsm12B: + MOVD R5, R1 + JMP emit_literal_done_match_emit_encodeBetterBlockAsm12B + +memmove_long_match_emit_encodeBetterBlockAsm12B: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_encodeBetterBlockAsm12Blarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_encodeBetterBlockAsm12Blarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_encodeBetterBlockAsm12B: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x40, R11 + BLS two_byte_offset_short_match_nolit_encodeBetterBlockAsm12B + CMPW $0x00000800, R7 + BHS long_offset_short_match_nolit_encodeBetterBlockAsm12B + MOVD $0x00000001, R5 + ADD $16, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R11, R11 + + // emitRepeat + SUB $4, R11, R11 + MOVWU R11, R11 + JMP cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm12B_emit_copy_short_2b + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm12B_emit_copy_short_2b + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm12B_emit_copy_short_2b + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_encodeBetterBlockAsm12B_emit_copy_short_2b + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm12B_emit_copy_short_2b: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm12B_emit_copy_short_2b + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +repeat_three_match_nolit_encodeBetterBlockAsm12B_emit_copy_short_2b: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +repeat_two_match_nolit_encodeBetterBlockAsm12B_emit_copy_short_2b: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +repeat_two_offset_match_nolit_encodeBetterBlockAsm12B_emit_copy_short_2b: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +long_offset_short_match_nolit_encodeBetterBlockAsm12B: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + SUB $60, R11, R11 + MOVWU R11, R11 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm12B_emit_copy_short + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm12B_emit_copy_short + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_encodeBetterBlockAsm12B_emit_copy_short + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm12B_emit_copy_short: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm12B_emit_copy_short + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +repeat_three_match_nolit_encodeBetterBlockAsm12B_emit_copy_short: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +repeat_two_match_nolit_encodeBetterBlockAsm12B_emit_copy_short: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +repeat_two_offset_match_nolit_encodeBetterBlockAsm12B_emit_copy_short: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +two_byte_offset_short_match_nolit_encodeBetterBlockAsm12B: + MOVWU R11, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R11 + BHS emit_copy_three_match_nolit_encodeBetterBlockAsm12B + CMPW $0x00000800, R7 + BHS emit_copy_three_match_nolit_encodeBetterBlockAsm12B + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +emit_copy_three_match_nolit_encodeBetterBlockAsm12B: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +match_is_repeat_encodeBetterBlockAsm12B: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_repeat_encodeBetterBlockAsm12B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_repeat_encodeBetterBlockAsm12B + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_repeat_encodeBetterBlockAsm12B + BLO three_bytes_match_emit_repeat_encodeBetterBlockAsm12B + +three_bytes_match_emit_repeat_encodeBetterBlockAsm12B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm12B + +two_bytes_match_emit_repeat_encodeBetterBlockAsm12B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_repeat_encodeBetterBlockAsm12B + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm12B + +one_byte_match_emit_repeat_encodeBetterBlockAsm12B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_repeat_encodeBetterBlockAsm12B: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x04, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm12B_memmove_move_4 + CMP $0x08, R8 + BLO emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm12B_memmove_move_4through7 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm12B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm12B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm12B_memmove_move_33through64 + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm12B_memmove_move_4: + MOVWU (R9), R10 + MOVW R10, (R1) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm12B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm12B_memmove_move_4through7: + MOVWU (R9), R10 + ADD R8, R9, R15 + MOVWU -4(R15), R9 + MOVW R10, (R1) + ADD R8, R1, R15 + MOVW R9, -4(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm12B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm12B_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm12B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm12B_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm12B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm12B_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm12B: + MOVD R5, R1 + JMP emit_literal_done_match_emit_repeat_encodeBetterBlockAsm12B + +memmove_long_match_emit_repeat_encodeBetterBlockAsm12B: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_repeat_encodeBetterBlockAsm12Blarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_repeat_encodeBetterBlockAsm12Blarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_repeat_encodeBetterBlockAsm12B: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitRepeat + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_repeat_encodeBetterBlockAsm12B + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm12B + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm12B + +cant_repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm12B: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_repeat_encodeBetterBlockAsm12B + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +repeat_three_match_nolit_repeat_encodeBetterBlockAsm12B: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +repeat_two_match_nolit_repeat_encodeBetterBlockAsm12B: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm12B + +repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm12B: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + +match_nolit_emitcopy_end_encodeBetterBlockAsm12B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeBetterBlockAsm12B + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeBetterBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeBetterBlockAsm12B: + MOVD $0x0000cf1bbcdcbf9b, R5 + MOVD $0x9e3779b1, R7 + ADD $1, R6, R6 + SUB $2, R2, R8 + MOVD (R3)(R6), R9 + ADD R6, R3, R15 + MOVD 1(R15), R10 + MOVD (R3)(R8), R11 + ADD R8, R3, R15 + MOVD 1(R15), R12 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x32, R9, R9 + LSL $0x20, R10, R10 + MUL R7, R10, R10 + LSR $0x34, R10, R10 + LSL $0x10, R11, R11 + MUL R5, R11, R11 + LSR $0x32, R11, R11 + LSL $0x20, R12, R12 + MUL R7, R12, R12 + LSR $0x34, R12, R12 + ADD $1, R6, R7 + ADD $1, R8, R13 + MOVW R6, (R0)(R9<<2) + MOVW R8, (R0)(R11<<2) + ADD R10<<2, R0, R15 + MOVW R7, 65536(R15) + ADD R12<<2, R0, R15 + MOVW R13, 65536(R15) + ADD R6, R8, R7 + ADD $1, R7, R7 + LSR $0x01, R7, R7 + ADD $0x01, R6, R6 + SUB $0x01, R8, R8 + +index_loop_encodeBetterBlockAsm12B: + CMP R8, R7 + BHS search_loop_encodeBetterBlockAsm12B + MOVD (R3)(R6), R9 + MOVD (R3)(R7), R10 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x32, R9, R9 + LSL $0x10, R10, R10 + MUL R5, R10, R10 + LSR $0x32, R10, R10 + MOVW R6, (R0)(R9<<2) + MOVW R7, (R0)(R10<<2) + ADD $0x02, R6, R6 + ADD $0x02, R7, R7 + JMP index_loop_encodeBetterBlockAsm12B + +emit_remainder_encodeBetterBlockAsm12B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeBetterBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeBetterBlockAsm12B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeBetterBlockAsm12B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeBetterBlockAsm12B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeBetterBlockAsm12B + BLO three_bytes_emit_remainder_encodeBetterBlockAsm12B + +three_bytes_emit_remainder_encodeBetterBlockAsm12B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeBetterBlockAsm12B + +two_bytes_emit_remainder_encodeBetterBlockAsm12B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeBetterBlockAsm12B + JMP memmove_long_emit_remainder_encodeBetterBlockAsm12B + +one_byte_emit_remainder_encodeBetterBlockAsm12B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeBetterBlockAsm12B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm12B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeBetterBlockAsm12B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeBetterBlockAsm12B + +memmove_long_emit_remainder_encodeBetterBlockAsm12B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeBetterBlockAsm12Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeBetterBlockAsm12Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeBetterBlockAsm12B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeBetterBlockAsm10B(dst []byte, src []byte, tmp *[20480]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeBetterBlockAsm10B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x000000a0, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeBetterBlockAsm10B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeBetterBlockAsm10B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $6, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVD $0x00000000, R16 + MOVW R16, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeBetterBlockAsm10B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x05, R5, R5 + ADD R5, R2, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeBetterBlockAsm10B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD $0x9e3779b1, R5 + MOVD R6, R9 + MOVD R6, R10 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x34, R9, R9 + LSL $0x20, R10, R10 + MUL R5, R10, R10 + LSR $0x36, R10, R10 + MOVWU (R0)(R9<<2), R5 + ADD R10<<2, R0, R15 + MOVWU 16384(R15), R7 + MOVW R2, (R0)(R9<<2) + ADD R10<<2, R0, R15 + MOVW R2, 16384(R15) + MOVD (R3)(R5), R9 + MOVD (R3)(R7), R10 + CMP R6, R9 + BEQ candidate_match_encodeBetterBlockAsm10B + CMP R6, R10 + BNE no_short_found_encodeBetterBlockAsm10B + MOVWU R7, R5 + JMP candidate_match_encodeBetterBlockAsm10B + +no_short_found_encodeBetterBlockAsm10B: + CMPW R6, R9 + BEQ candidate_match_encodeBetterBlockAsm10B + CMPW R6, R10 + BEQ candidateS_match_encodeBetterBlockAsm10B + MOVWU 28(RSP), R2 + JMP search_loop_encodeBetterBlockAsm10B + +candidateS_match_encodeBetterBlockAsm10B: + LSR $0x08, R6, R6 + MOVD R6, R9 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x34, R9, R9 + MOVWU (R0)(R9<<2), R5 + ADDW $1, R2, R2 + MOVW R2, (R0)(R9<<2) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeBetterBlockAsm10B + SUBW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeBetterBlockAsm10B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeBetterBlockAsm10B + +match_extend_back_loop_encodeBetterBlockAsm10B: + CMPW R6, R2 + BLS match_extend_back_end_encodeBetterBlockAsm10B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeBetterBlockAsm10B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeBetterBlockAsm10B + JMP match_extend_back_loop_encodeBetterBlockAsm10B + +match_extend_back_end_encodeBetterBlockAsm10B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeBetterBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeBetterBlockAsm10B: + MOVWU R2, R6 + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R9 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_match_nolit_encodeBetterBlockAsm10B: + CMPW $0x10, R7 + BLO matchlen_match8_match_nolit_encodeBetterBlockAsm10B + MOVD (R8)(R11), R10 + ADD R11, R8, R15 + MOVD 8(R15), R12 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeBetterBlockAsm10B + ADD R11, R9, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16match_nolit_encodeBetterBlockAsm10B + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_match_nolit_encodeBetterBlockAsm10B + +matchlen_bsf_16match_nolit_encodeBetterBlockAsm10B: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeBetterBlockAsm10B + +matchlen_match8_match_nolit_encodeBetterBlockAsm10B: + CMPW $0x08, R7 + BLO matchlen_match4_match_nolit_encodeBetterBlockAsm10B + MOVD (R8)(R11), R10 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeBetterBlockAsm10B + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_match_nolit_encodeBetterBlockAsm10B + +matchlen_bsf_8_match_nolit_encodeBetterBlockAsm10B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeBetterBlockAsm10B + +matchlen_match4_match_nolit_encodeBetterBlockAsm10B: + CMPW $0x04, R7 + BLO matchlen_match2_match_nolit_encodeBetterBlockAsm10B + MOVWU (R8)(R11), R10 + MOVWU (R9)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_match_nolit_encodeBetterBlockAsm10B + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_match_nolit_encodeBetterBlockAsm10B: + CMPW $0x01, R7 + BEQ matchlen_match1_match_nolit_encodeBetterBlockAsm10B + BLO match_nolit_end_encodeBetterBlockAsm10B + MOVHU (R8)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R9, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeBetterBlockAsm10B + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R7, R7 + BEQ match_nolit_end_encodeBetterBlockAsm10B + +matchlen_match1_match_nolit_encodeBetterBlockAsm10B: + MOVBU (R8)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R9, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE match_nolit_end_encodeBetterBlockAsm10B + ADD $1, R11, R11 + MOVWU R11, R11 + +match_nolit_end_encodeBetterBlockAsm10B: + MOVWU R2, R7 + SUBW R5, R7, R7 + + // Check if repeat + MOVWU 24(RSP), R16 + CMPW R7, R16 + BEQ match_is_repeat_encodeBetterBlockAsm10B + MOVW R7, 24(RSP) + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_encodeBetterBlockAsm10B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_encodeBetterBlockAsm10B + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_encodeBetterBlockAsm10B + BLO three_bytes_match_emit_encodeBetterBlockAsm10B + +three_bytes_match_emit_encodeBetterBlockAsm10B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeBetterBlockAsm10B + +two_bytes_match_emit_encodeBetterBlockAsm10B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_encodeBetterBlockAsm10B + JMP memmove_long_match_emit_encodeBetterBlockAsm10B + +one_byte_match_emit_encodeBetterBlockAsm10B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeBetterBlockAsm10B: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x04, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm10B_memmove_move_4 + CMP $0x08, R8 + BLO emit_lit_memmove_match_emit_encodeBetterBlockAsm10B_memmove_move_4through7 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm10B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm10B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeBetterBlockAsm10B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeBetterBlockAsm10B_memmove_move_4: + MOVWU (R9), R10 + MOVW R10, (R1) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm10B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm10B_memmove_move_4through7: + MOVWU (R9), R10 + ADD R8, R9, R15 + MOVWU -4(R15), R9 + MOVW R10, (R1) + ADD R8, R1, R15 + MOVW R9, -4(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm10B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm10B_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm10B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm10B_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm10B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm10B_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeBetterBlockAsm10B: + MOVD R5, R1 + JMP emit_literal_done_match_emit_encodeBetterBlockAsm10B + +memmove_long_match_emit_encodeBetterBlockAsm10B: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_encodeBetterBlockAsm10Blarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_encodeBetterBlockAsm10Blarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_encodeBetterBlockAsm10B: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x40, R11 + BLS two_byte_offset_short_match_nolit_encodeBetterBlockAsm10B + CMPW $0x00000800, R7 + BHS long_offset_short_match_nolit_encodeBetterBlockAsm10B + MOVD $0x00000001, R5 + ADD $16, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R11, R11 + + // emitRepeat + SUB $4, R11, R11 + MOVWU R11, R11 + JMP cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm10B_emit_copy_short_2b + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm10B_emit_copy_short_2b + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm10B_emit_copy_short_2b + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_encodeBetterBlockAsm10B_emit_copy_short_2b + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm10B_emit_copy_short_2b: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm10B_emit_copy_short_2b + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +repeat_three_match_nolit_encodeBetterBlockAsm10B_emit_copy_short_2b: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +repeat_two_match_nolit_encodeBetterBlockAsm10B_emit_copy_short_2b: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +repeat_two_offset_match_nolit_encodeBetterBlockAsm10B_emit_copy_short_2b: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +long_offset_short_match_nolit_encodeBetterBlockAsm10B: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + SUB $60, R11, R11 + MOVWU R11, R11 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm10B_emit_copy_short + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm10B_emit_copy_short + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_encodeBetterBlockAsm10B_emit_copy_short + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm10B_emit_copy_short: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm10B_emit_copy_short + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +repeat_three_match_nolit_encodeBetterBlockAsm10B_emit_copy_short: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +repeat_two_match_nolit_encodeBetterBlockAsm10B_emit_copy_short: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +repeat_two_offset_match_nolit_encodeBetterBlockAsm10B_emit_copy_short: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +two_byte_offset_short_match_nolit_encodeBetterBlockAsm10B: + MOVWU R11, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R11 + BHS emit_copy_three_match_nolit_encodeBetterBlockAsm10B + CMPW $0x00000800, R7 + BHS emit_copy_three_match_nolit_encodeBetterBlockAsm10B + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +emit_copy_three_match_nolit_encodeBetterBlockAsm10B: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +match_is_repeat_encodeBetterBlockAsm10B: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_repeat_encodeBetterBlockAsm10B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_repeat_encodeBetterBlockAsm10B + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_repeat_encodeBetterBlockAsm10B + BLO three_bytes_match_emit_repeat_encodeBetterBlockAsm10B + +three_bytes_match_emit_repeat_encodeBetterBlockAsm10B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm10B + +two_bytes_match_emit_repeat_encodeBetterBlockAsm10B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_repeat_encodeBetterBlockAsm10B + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm10B + +one_byte_match_emit_repeat_encodeBetterBlockAsm10B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_repeat_encodeBetterBlockAsm10B: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x04, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm10B_memmove_move_4 + CMP $0x08, R8 + BLO emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm10B_memmove_move_4through7 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm10B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm10B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm10B_memmove_move_33through64 + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm10B_memmove_move_4: + MOVWU (R9), R10 + MOVW R10, (R1) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm10B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm10B_memmove_move_4through7: + MOVWU (R9), R10 + ADD R8, R9, R15 + MOVWU -4(R15), R9 + MOVW R10, (R1) + ADD R8, R1, R15 + MOVW R9, -4(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm10B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm10B_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm10B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm10B_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm10B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm10B_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm10B: + MOVD R5, R1 + JMP emit_literal_done_match_emit_repeat_encodeBetterBlockAsm10B + +memmove_long_match_emit_repeat_encodeBetterBlockAsm10B: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_repeat_encodeBetterBlockAsm10Blarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_repeat_encodeBetterBlockAsm10Blarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_repeat_encodeBetterBlockAsm10B: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitRepeat + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_repeat_encodeBetterBlockAsm10B + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm10B + CMPW $0x00000800, R7 + BLO repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm10B + +cant_repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm10B: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_repeat_encodeBetterBlockAsm10B + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +repeat_three_match_nolit_repeat_encodeBetterBlockAsm10B: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +repeat_two_match_nolit_repeat_encodeBetterBlockAsm10B: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm10B + +repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm10B: + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + +match_nolit_emitcopy_end_encodeBetterBlockAsm10B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeBetterBlockAsm10B + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeBetterBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeBetterBlockAsm10B: + MOVD $0x0000cf1bbcdcbf9b, R5 + MOVD $0x9e3779b1, R7 + ADD $1, R6, R6 + SUB $2, R2, R8 + MOVD (R3)(R6), R9 + ADD R6, R3, R15 + MOVD 1(R15), R10 + MOVD (R3)(R8), R11 + ADD R8, R3, R15 + MOVD 1(R15), R12 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x34, R9, R9 + LSL $0x20, R10, R10 + MUL R7, R10, R10 + LSR $0x36, R10, R10 + LSL $0x10, R11, R11 + MUL R5, R11, R11 + LSR $0x34, R11, R11 + LSL $0x20, R12, R12 + MUL R7, R12, R12 + LSR $0x36, R12, R12 + ADD $1, R6, R7 + ADD $1, R8, R13 + MOVW R6, (R0)(R9<<2) + MOVW R8, (R0)(R11<<2) + ADD R10<<2, R0, R15 + MOVW R7, 16384(R15) + ADD R12<<2, R0, R15 + MOVW R13, 16384(R15) + ADD R6, R8, R7 + ADD $1, R7, R7 + LSR $0x01, R7, R7 + ADD $0x01, R6, R6 + SUB $0x01, R8, R8 + +index_loop_encodeBetterBlockAsm10B: + CMP R8, R7 + BHS search_loop_encodeBetterBlockAsm10B + MOVD (R3)(R6), R9 + MOVD (R3)(R7), R10 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x34, R9, R9 + LSL $0x10, R10, R10 + MUL R5, R10, R10 + LSR $0x34, R10, R10 + MOVW R6, (R0)(R9<<2) + MOVW R7, (R0)(R10<<2) + ADD $0x02, R6, R6 + ADD $0x02, R7, R7 + JMP index_loop_encodeBetterBlockAsm10B + +emit_remainder_encodeBetterBlockAsm10B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeBetterBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeBetterBlockAsm10B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeBetterBlockAsm10B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeBetterBlockAsm10B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeBetterBlockAsm10B + BLO three_bytes_emit_remainder_encodeBetterBlockAsm10B + +three_bytes_emit_remainder_encodeBetterBlockAsm10B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeBetterBlockAsm10B + +two_bytes_emit_remainder_encodeBetterBlockAsm10B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeBetterBlockAsm10B + JMP memmove_long_emit_remainder_encodeBetterBlockAsm10B + +one_byte_emit_remainder_encodeBetterBlockAsm10B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeBetterBlockAsm10B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm10B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeBetterBlockAsm10B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeBetterBlockAsm10B + +memmove_long_emit_remainder_encodeBetterBlockAsm10B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeBetterBlockAsm10Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeBetterBlockAsm10Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeBetterBlockAsm10B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeBetterBlockAsm8B(dst []byte, src []byte, tmp *[5120]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeBetterBlockAsm8B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000028, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeBetterBlockAsm8B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeBetterBlockAsm8B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $6, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVD $0x00000000, R16 + MOVW R16, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeBetterBlockAsm8B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x04, R5, R5 + ADD R5, R2, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeBetterBlockAsm8B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD $0x9e3779b1, R5 + MOVD R6, R9 + MOVD R6, R10 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x36, R9, R9 + LSL $0x20, R10, R10 + MUL R5, R10, R10 + LSR $0x38, R10, R10 + MOVWU (R0)(R9<<2), R5 + ADD R10<<2, R0, R15 + MOVWU 4096(R15), R7 + MOVW R2, (R0)(R9<<2) + ADD R10<<2, R0, R15 + MOVW R2, 4096(R15) + MOVD (R3)(R5), R9 + MOVD (R3)(R7), R10 + CMP R6, R9 + BEQ candidate_match_encodeBetterBlockAsm8B + CMP R6, R10 + BNE no_short_found_encodeBetterBlockAsm8B + MOVWU R7, R5 + JMP candidate_match_encodeBetterBlockAsm8B + +no_short_found_encodeBetterBlockAsm8B: + CMPW R6, R9 + BEQ candidate_match_encodeBetterBlockAsm8B + CMPW R6, R10 + BEQ candidateS_match_encodeBetterBlockAsm8B + MOVWU 28(RSP), R2 + JMP search_loop_encodeBetterBlockAsm8B + +candidateS_match_encodeBetterBlockAsm8B: + LSR $0x08, R6, R6 + MOVD R6, R9 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x36, R9, R9 + MOVWU (R0)(R9<<2), R5 + ADDW $1, R2, R2 + MOVW R2, (R0)(R9<<2) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeBetterBlockAsm8B + SUBW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeBetterBlockAsm8B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeBetterBlockAsm8B + +match_extend_back_loop_encodeBetterBlockAsm8B: + CMPW R6, R2 + BLS match_extend_back_end_encodeBetterBlockAsm8B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeBetterBlockAsm8B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeBetterBlockAsm8B + JMP match_extend_back_loop_encodeBetterBlockAsm8B + +match_extend_back_end_encodeBetterBlockAsm8B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeBetterBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeBetterBlockAsm8B: + MOVWU R2, R6 + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R9 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_match_nolit_encodeBetterBlockAsm8B: + CMPW $0x10, R7 + BLO matchlen_match8_match_nolit_encodeBetterBlockAsm8B + MOVD (R8)(R11), R10 + ADD R11, R8, R15 + MOVD 8(R15), R12 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeBetterBlockAsm8B + ADD R11, R9, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16match_nolit_encodeBetterBlockAsm8B + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_match_nolit_encodeBetterBlockAsm8B + +matchlen_bsf_16match_nolit_encodeBetterBlockAsm8B: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeBetterBlockAsm8B + +matchlen_match8_match_nolit_encodeBetterBlockAsm8B: + CMPW $0x08, R7 + BLO matchlen_match4_match_nolit_encodeBetterBlockAsm8B + MOVD (R8)(R11), R10 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeBetterBlockAsm8B + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_match_nolit_encodeBetterBlockAsm8B + +matchlen_bsf_8_match_nolit_encodeBetterBlockAsm8B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeBetterBlockAsm8B + +matchlen_match4_match_nolit_encodeBetterBlockAsm8B: + CMPW $0x04, R7 + BLO matchlen_match2_match_nolit_encodeBetterBlockAsm8B + MOVWU (R8)(R11), R10 + MOVWU (R9)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_match_nolit_encodeBetterBlockAsm8B + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_match_nolit_encodeBetterBlockAsm8B: + CMPW $0x01, R7 + BEQ matchlen_match1_match_nolit_encodeBetterBlockAsm8B + BLO match_nolit_end_encodeBetterBlockAsm8B + MOVHU (R8)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R9, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeBetterBlockAsm8B + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R7, R7 + BEQ match_nolit_end_encodeBetterBlockAsm8B + +matchlen_match1_match_nolit_encodeBetterBlockAsm8B: + MOVBU (R8)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R9, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE match_nolit_end_encodeBetterBlockAsm8B + ADD $1, R11, R11 + MOVWU R11, R11 + +match_nolit_end_encodeBetterBlockAsm8B: + MOVWU R2, R7 + SUBW R5, R7, R7 + + // Check if repeat + MOVWU 24(RSP), R16 + CMPW R7, R16 + BEQ match_is_repeat_encodeBetterBlockAsm8B + MOVW R7, 24(RSP) + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_encodeBetterBlockAsm8B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_encodeBetterBlockAsm8B + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_encodeBetterBlockAsm8B + BLO three_bytes_match_emit_encodeBetterBlockAsm8B + +three_bytes_match_emit_encodeBetterBlockAsm8B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeBetterBlockAsm8B + +two_bytes_match_emit_encodeBetterBlockAsm8B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_encodeBetterBlockAsm8B + JMP memmove_long_match_emit_encodeBetterBlockAsm8B + +one_byte_match_emit_encodeBetterBlockAsm8B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeBetterBlockAsm8B: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x04, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm8B_memmove_move_4 + CMP $0x08, R8 + BLO emit_lit_memmove_match_emit_encodeBetterBlockAsm8B_memmove_move_4through7 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm8B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeBetterBlockAsm8B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeBetterBlockAsm8B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeBetterBlockAsm8B_memmove_move_4: + MOVWU (R9), R10 + MOVW R10, (R1) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm8B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm8B_memmove_move_4through7: + MOVWU (R9), R10 + ADD R8, R9, R15 + MOVWU -4(R15), R9 + MOVW R10, (R1) + ADD R8, R1, R15 + MOVW R9, -4(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm8B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm8B_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm8B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm8B_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeBetterBlockAsm8B + +emit_lit_memmove_match_emit_encodeBetterBlockAsm8B_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeBetterBlockAsm8B: + MOVD R5, R1 + JMP emit_literal_done_match_emit_encodeBetterBlockAsm8B + +memmove_long_match_emit_encodeBetterBlockAsm8B: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_encodeBetterBlockAsm8Blarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_encodeBetterBlockAsm8Blarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_encodeBetterBlockAsm8B: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x40, R11 + BLS two_byte_offset_short_match_nolit_encodeBetterBlockAsm8B + CMPW $0x00000800, R7 + BHS long_offset_short_match_nolit_encodeBetterBlockAsm8B + MOVD $0x00000001, R5 + ADD $16, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + SUBW $0x08, R11, R11 + + // emitRepeat + SUB $4, R11, R11 + MOVWU R11, R11 + JMP cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm8B_emit_copy_short_2b + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm8B_emit_copy_short_2b + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm8B_emit_copy_short_2b + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm8B_emit_copy_short_2b: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm8B_emit_copy_short_2b + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + +repeat_three_match_nolit_encodeBetterBlockAsm8B_emit_copy_short_2b: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + +repeat_two_match_nolit_encodeBetterBlockAsm8B_emit_copy_short_2b: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + +long_offset_short_match_nolit_encodeBetterBlockAsm8B: + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + SUB $60, R11, R11 + MOVWU R11, R11 + ADD $0x03, R1, R1 + + // emitRepeat + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_encodeBetterBlockAsm8B_emit_copy_short + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm8B_emit_copy_short + +cant_repeat_two_offset_match_nolit_encodeBetterBlockAsm8B_emit_copy_short: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_encodeBetterBlockAsm8B_emit_copy_short + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + +repeat_three_match_nolit_encodeBetterBlockAsm8B_emit_copy_short: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + +repeat_two_match_nolit_encodeBetterBlockAsm8B_emit_copy_short: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + +two_byte_offset_short_match_nolit_encodeBetterBlockAsm8B: + MOVWU R11, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R11 + BHS emit_copy_three_match_nolit_encodeBetterBlockAsm8B + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + +emit_copy_three_match_nolit_encodeBetterBlockAsm8B: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + +match_is_repeat_encodeBetterBlockAsm8B: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_repeat_encodeBetterBlockAsm8B + MOVWU R6, R7 + MOVW R6, 20(RSP) + ADD R5, R3, R8 + SUBW R5, R7, R7 + SUB $1, R7, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_repeat_encodeBetterBlockAsm8B + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_repeat_encodeBetterBlockAsm8B + BLO three_bytes_match_emit_repeat_encodeBetterBlockAsm8B + +three_bytes_match_emit_repeat_encodeBetterBlockAsm8B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm8B + +two_bytes_match_emit_repeat_encodeBetterBlockAsm8B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_repeat_encodeBetterBlockAsm8B + JMP memmove_long_match_emit_repeat_encodeBetterBlockAsm8B + +one_byte_match_emit_repeat_encodeBetterBlockAsm8B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_repeat_encodeBetterBlockAsm8B: + ADD R7, R1, R5 + + // genMemMoveShort + CMP $0x04, R7 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm8B_memmove_move_4 + CMP $0x08, R7 + BLO emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm8B_memmove_move_4through7 + CMP $0x10, R7 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm8B_memmove_move_8through16 + CMP $0x20, R7 + BLS emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm8B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm8B_memmove_move_33through64 + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm8B_memmove_move_4: + MOVWU (R8), R9 + MOVW R9, (R1) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm8B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm8B_memmove_move_4through7: + MOVWU (R8), R9 + ADD R7, R8, R15 + MOVWU -4(R15), R8 + MOVW R9, (R1) + ADD R7, R1, R15 + MOVW R8, -4(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm8B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm8B_memmove_move_8through16: + MOVD (R8), R9 + ADD R7, R8, R15 + MOVD -8(R15), R8 + MOVD R9, (R1) + ADD R7, R1, R15 + MOVD R8, -8(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm8B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm8B_memmove_move_17through32: + FMOVQ (R8), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm8B + +emit_lit_memmove_match_emit_repeat_encodeBetterBlockAsm8B_memmove_move_33through64: + FMOVQ (R8), F0 + FMOVQ 16(R8), F1 + ADD R7, R8, R15 + FMOVQ -32(R15), F2 + ADD R7, R8, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R7, R1, R15 + FMOVQ F2, -32(R15) + ADD R7, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_repeat_encodeBetterBlockAsm8B: + MOVD R5, R1 + JMP emit_literal_done_match_emit_repeat_encodeBetterBlockAsm8B + +memmove_long_match_emit_repeat_encodeBetterBlockAsm8B: + ADD R7, R1, R5 + + // genMemMoveLong + MOVD R8, R9 + MOVD R1, R10 + MOVD R7, R12 + +emit_lit_memmove_long_match_emit_repeat_encodeBetterBlockAsm8Blarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R12, R12 + CMP $0x20, R12 + BHS emit_lit_memmove_long_match_emit_repeat_encodeBetterBlockAsm8Blarge_big_loop_back + ADD R7, R8, R15 + FMOVQ -32(R15), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + ADD R7, R1, R15 + FMOVQ F0, -32(R15) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_repeat_encodeBetterBlockAsm8B: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitRepeat + MOVWU R11, R5 + SUB $4, R11, R11 + MOVWU R11, R11 + CMPW $0x08, R5 + BLS repeat_two_match_nolit_repeat_encodeBetterBlockAsm8B + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm8B + +cant_repeat_two_offset_match_nolit_repeat_encodeBetterBlockAsm8B: + CMPW $0x00000104, R11 + BLO repeat_three_match_nolit_repeat_encodeBetterBlockAsm8B + SUB $256, R11, R11 + MOVWU R11, R11 + MOVD $0x0019, R16 + MOVH R16, (R1) + MOVH R11, 2(R1) + ADD $0x04, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + +repeat_three_match_nolit_repeat_encodeBetterBlockAsm8B: + SUB $4, R11, R11 + MOVWU R11, R11 + MOVD $0x0015, R16 + MOVH R16, (R1) + MOVB R11, 2(R1) + ADD $0x03, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + +repeat_two_match_nolit_repeat_encodeBetterBlockAsm8B: + LSLW $0x02, R11, R11 + ORRW $0x01, R11, R11 + MOVH R11, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeBetterBlockAsm8B + MOVD $0, R5 + ADD R11<<2, R5, R11 + ADD $1, R11, R11 + MOVWU R11, R11 + MOVB R7, 1(R1) + ASRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R11, R11 + MOVB R11, (R1) + ADD $0x02, R1, R1 + +match_nolit_emitcopy_end_encodeBetterBlockAsm8B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeBetterBlockAsm8B + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeBetterBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeBetterBlockAsm8B: + MOVD $0x0000cf1bbcdcbf9b, R5 + MOVD $0x9e3779b1, R7 + ADD $1, R6, R6 + SUB $2, R2, R8 + MOVD (R3)(R6), R9 + ADD R6, R3, R15 + MOVD 1(R15), R10 + MOVD (R3)(R8), R11 + ADD R8, R3, R15 + MOVD 1(R15), R12 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x36, R9, R9 + LSL $0x20, R10, R10 + MUL R7, R10, R10 + LSR $0x38, R10, R10 + LSL $0x10, R11, R11 + MUL R5, R11, R11 + LSR $0x36, R11, R11 + LSL $0x20, R12, R12 + MUL R7, R12, R12 + LSR $0x38, R12, R12 + ADD $1, R6, R7 + ADD $1, R8, R13 + MOVW R6, (R0)(R9<<2) + MOVW R8, (R0)(R11<<2) + ADD R10<<2, R0, R15 + MOVW R7, 4096(R15) + ADD R12<<2, R0, R15 + MOVW R13, 4096(R15) + ADD R6, R8, R7 + ADD $1, R7, R7 + LSR $0x01, R7, R7 + ADD $0x01, R6, R6 + SUB $0x01, R8, R8 + +index_loop_encodeBetterBlockAsm8B: + CMP R8, R7 + BHS search_loop_encodeBetterBlockAsm8B + MOVD (R3)(R6), R9 + MOVD (R3)(R7), R10 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x36, R9, R9 + LSL $0x10, R10, R10 + MUL R5, R10, R10 + LSR $0x36, R10, R10 + MOVW R6, (R0)(R9<<2) + MOVW R7, (R0)(R10<<2) + ADD $0x02, R6, R6 + ADD $0x02, R7, R7 + JMP index_loop_encodeBetterBlockAsm8B + +emit_remainder_encodeBetterBlockAsm8B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeBetterBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeBetterBlockAsm8B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeBetterBlockAsm8B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeBetterBlockAsm8B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeBetterBlockAsm8B + BLO three_bytes_emit_remainder_encodeBetterBlockAsm8B + +three_bytes_emit_remainder_encodeBetterBlockAsm8B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeBetterBlockAsm8B + +two_bytes_emit_remainder_encodeBetterBlockAsm8B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeBetterBlockAsm8B + JMP memmove_long_emit_remainder_encodeBetterBlockAsm8B + +one_byte_emit_remainder_encodeBetterBlockAsm8B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeBetterBlockAsm8B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeBetterBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeBetterBlockAsm8B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeBetterBlockAsm8B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeBetterBlockAsm8B + +memmove_long_emit_remainder_encodeBetterBlockAsm8B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeBetterBlockAsm8Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeBetterBlockAsm8Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeBetterBlockAsm8B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeSnappyBlockAsm(dst []byte, src []byte, tmp *[65536]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeSnappyBlockAsm(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000200, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeSnappyBlockAsm: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeSnappyBlockAsm + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeSnappyBlockAsm: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x06, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeSnappyBlockAsm + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + LSL $0x10, R10, R10 + MUL R8, R10, R10 + LSR $0x32, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_encodeSnappyBlockAsm + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R5 + MOVWU R6, R7 + MOVWU 24(RSP), R16 + SUBSW R16, R7, R7 + BEQ repeat_extend_back_end_encodeSnappyBlockAsm + +repeat_extend_back_loop_encodeSnappyBlockAsm: + CMPW R5, R6 + BLS repeat_extend_back_end_encodeSnappyBlockAsm + ADD R7, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_encodeSnappyBlockAsm + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R7, R7 + BNE repeat_extend_back_loop_encodeSnappyBlockAsm + +repeat_extend_back_end_encodeSnappyBlockAsm: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $5, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_encodeSnappyBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +repeat_dst_size_check_encodeSnappyBlockAsm: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_encodeSnappyBlockAsm + MOVWU R6, R7 + MOVW R6, 20(RSP) + ADD R5, R3, R8 + SUBW R5, R7, R7 + SUB $1, R7, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_encodeSnappyBlockAsm + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_encodeSnappyBlockAsm + CMPW $0x00010000, R5 + BLO three_bytes_repeat_emit_encodeSnappyBlockAsm + CMPW $0x01000000, R5 + BLO four_bytes_repeat_emit_encodeSnappyBlockAsm + MOVD $0xfc, R16 + MOVB R16, (R1) + MOVW R5, 1(R1) + ADD $0x05, R1, R1 + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm + +four_bytes_repeat_emit_encodeSnappyBlockAsm: + MOVWU R5, R9 + LSRW $0x10, R9, R9 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + MOVB R9, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm + +three_bytes_repeat_emit_encodeSnappyBlockAsm: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm + +two_bytes_repeat_emit_encodeSnappyBlockAsm: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_encodeSnappyBlockAsm + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm + +one_byte_repeat_emit_encodeSnappyBlockAsm: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_repeat_emit_encodeSnappyBlockAsm: + ADD R7, R1, R5 + + // genMemMoveShort + CMP $0x08, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm_memmove_move_8 + CMP $0x10, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm_memmove_move_8through16 + CMP $0x20, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm_memmove_move_17through32 + JMP emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm_memmove_move_33through64 + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm_memmove_move_8: + MOVD (R8), R9 + MOVD R9, (R1) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm_memmove_move_8through16: + MOVD (R8), R9 + ADD R7, R8, R15 + MOVD -8(R15), R8 + MOVD R9, (R1) + ADD R7, R1, R15 + MOVD R8, -8(R15) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm_memmove_move_17through32: + FMOVQ (R8), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm_memmove_move_33through64: + FMOVQ (R8), F0 + FMOVQ 16(R8), F1 + ADD R7, R8, R15 + FMOVQ -32(R15), F2 + ADD R7, R8, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R7, R1, R15 + FMOVQ F2, -32(R15) + ADD R7, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_repeat_emit_encodeSnappyBlockAsm: + MOVD R5, R1 + JMP emit_literal_done_repeat_emit_encodeSnappyBlockAsm + +memmove_long_repeat_emit_encodeSnappyBlockAsm: + ADD R7, R1, R5 + + // genMemMoveLong + MOVD R8, R9 + MOVD R1, R10 + MOVD R7, R11 + +emit_lit_memmove_long_repeat_emit_encodeSnappyBlockAsmlarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_repeat_emit_encodeSnappyBlockAsmlarge_big_loop_back + ADD R7, R8, R15 + FMOVQ -32(R15), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + ADD R7, R1, R15 + FMOVQ F0, -32(R15) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_repeat_emit_encodeSnappyBlockAsm: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R10 + +matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm: + CMPW $0x10, R7 + BLO matchlen_match8_repeat_extend_encodeSnappyBlockAsm + MOVD (R8)(R10), R9 + ADD R10, R8, R15 + MOVD 8(R15), R11 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm + ADD R10, R5, R15 + MOVD 8(R15), R16 + EOR R16, R11, R11 + TST R11, R11 + BNE matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R10, R10 + MOVWU R10, R10 + JMP matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm + +matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm: + RBIT R11, R11 + CLZ R11, R11 + ASR $0x03, R11, R11 + ADD R11, R10, R10 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm + +matchlen_match8_repeat_extend_encodeSnappyBlockAsm: + CMPW $0x08, R7 + BLO matchlen_match4_repeat_extend_encodeSnappyBlockAsm + MOVD (R8)(R10), R9 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP matchlen_match4_repeat_extend_encodeSnappyBlockAsm + +matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm: + RBIT R9, R9 + CLZ R9, R9 + ASR $0x03, R9, R9 + ADD R9, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm + +matchlen_match4_repeat_extend_encodeSnappyBlockAsm: + CMPW $0x04, R7 + BLO matchlen_match2_repeat_extend_encodeSnappyBlockAsm + MOVWU (R8)(R10), R9 + MOVWU (R5)(R10), R16 + CMPW R9, R16 + BNE matchlen_match2_repeat_extend_encodeSnappyBlockAsm + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R10, R10 + MOVWU R10, R10 + +matchlen_match2_repeat_extend_encodeSnappyBlockAsm: + CMPW $0x01, R7 + BEQ matchlen_match1_repeat_extend_encodeSnappyBlockAsm + BLO repeat_extend_forward_end_encodeSnappyBlockAsm + MOVHU (R8)(R10), R16 + BFI $0, R16, $16, R9 + ADD R10, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R9, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_encodeSnappyBlockAsm + ADD $2, R10, R10 + MOVWU R10, R10 + SUBSW $0x02, R7, R7 + BEQ repeat_extend_forward_end_encodeSnappyBlockAsm + +matchlen_match1_repeat_extend_encodeSnappyBlockAsm: + MOVBU (R8)(R10), R16 + BFI $0, R16, $8, R9 + ADD R10, R5, R15 + MOVBU (R15), R15 + AND $0xff, R9, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_encodeSnappyBlockAsm + ADD $1, R10, R10 + MOVWU R10, R10 + +repeat_extend_forward_end_encodeSnappyBlockAsm: + ADDW R10, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + + // emitCopy + CMPW $0x00010000, R6 + BLO two_byte_offset_repeat_as_copy_encodeSnappyBlockAsm + +four_bytes_loop_back_repeat_as_copy_encodeSnappyBlockAsm: + CMPW $0x40, R5 + BLS four_bytes_remain_repeat_as_copy_encodeSnappyBlockAsm + MOVD $0xff, R16 + MOVB R16, (R1) + MOVW R6, 1(R1) + SUB $64, R5, R5 + MOVWU R5, R5 + ADD $0x05, R1, R1 + CMPW $0x04, R5 + BLO four_bytes_remain_repeat_as_copy_encodeSnappyBlockAsm + JMP four_bytes_loop_back_repeat_as_copy_encodeSnappyBlockAsm + +four_bytes_remain_repeat_as_copy_encodeSnappyBlockAsm: + TSTW R5, R5 + BEQ repeat_end_emit_encodeSnappyBlockAsm + MOVD $0, R7 + ADD R5<<2, R7, R5 + SUB $1, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVW R6, 1(R1) + ADD $0x05, R1, R1 + JMP repeat_end_emit_encodeSnappyBlockAsm + +two_byte_offset_repeat_as_copy_encodeSnappyBlockAsm: + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_encodeSnappyBlockAsm + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R6, 1(R1) + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + JMP two_byte_offset_repeat_as_copy_encodeSnappyBlockAsm + +two_byte_offset_short_repeat_as_copy_encodeSnappyBlockAsm: + MOVWU R5, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm + CMPW $0x00000800, R6 + BHS emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeSnappyBlockAsm + +emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R1) + MOVH R6, 1(R1) + ADD $0x03, R1, R1 + +repeat_end_emit_encodeSnappyBlockAsm: + MOVW R2, 20(RSP) + JMP search_loop_encodeSnappyBlockAsm + +no_repeat_found_encodeSnappyBlockAsm: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeSnappyBlockAsm + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_encodeSnappyBlockAsm + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_encodeSnappyBlockAsm + MOVWU 28(RSP), R2 + JMP search_loop_encodeSnappyBlockAsm + +candidate3_match_encodeSnappyBlockAsm: + ADDW $0x02, R2, R2 + JMP candidate_match_encodeSnappyBlockAsm + +candidate2_match_encodeSnappyBlockAsm: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeSnappyBlockAsm: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeSnappyBlockAsm + +match_extend_back_loop_encodeSnappyBlockAsm: + CMPW R6, R2 + BLS match_extend_back_end_encodeSnappyBlockAsm + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeSnappyBlockAsm + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeSnappyBlockAsm + JMP match_extend_back_loop_encodeSnappyBlockAsm + +match_extend_back_end_encodeSnappyBlockAsm: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $5, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeSnappyBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeSnappyBlockAsm: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_encodeSnappyBlockAsm + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R7 + MOVWU R7, R7 + CMPW $0x3c, R7 + BLO one_byte_match_emit_encodeSnappyBlockAsm + CMPW $0x00000100, R7 + BLO two_bytes_match_emit_encodeSnappyBlockAsm + CMPW $0x00010000, R7 + BLO three_bytes_match_emit_encodeSnappyBlockAsm + CMPW $0x01000000, R7 + BLO four_bytes_match_emit_encodeSnappyBlockAsm + MOVD $0xfc, R16 + MOVB R16, (R1) + MOVW R7, 1(R1) + ADD $0x05, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBlockAsm + +four_bytes_match_emit_encodeSnappyBlockAsm: + MOVWU R7, R9 + LSRW $0x10, R9, R9 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + MOVB R9, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBlockAsm + +three_bytes_match_emit_encodeSnappyBlockAsm: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBlockAsm + +two_bytes_match_emit_encodeSnappyBlockAsm: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R7, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R7 + BLO memmove_match_emit_encodeSnappyBlockAsm + JMP memmove_long_match_emit_encodeSnappyBlockAsm + +one_byte_match_emit_encodeSnappyBlockAsm: + LSLW $0x02, R7, R16 + BFI $0, R16, $8, R7 + MOVB R7, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeSnappyBlockAsm: + ADD R8, R1, R7 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeSnappyBlockAsm_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm_memmove_move_8: + MOVD (R6), R9 + MOVD R9, (R1) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm_memmove_move_8through16: + MOVD (R6), R9 + ADD R8, R6, R15 + MOVD -8(R15), R6 + MOVD R9, (R1) + ADD R8, R1, R15 + MOVD R6, -8(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm_memmove_move_17through32: + FMOVQ (R6), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm_memmove_move_33through64: + FMOVQ (R6), F0 + FMOVQ 16(R6), F1 + ADD R8, R6, R15 + FMOVQ -32(R15), F2 + ADD R8, R6, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeSnappyBlockAsm: + MOVD R7, R1 + JMP emit_literal_done_match_emit_encodeSnappyBlockAsm + +memmove_long_match_emit_encodeSnappyBlockAsm: + ADD R8, R1, R7 + + // genMemMoveLong + MOVD R6, R9 + MOVD R1, R10 + MOVD R8, R11 + +emit_lit_memmove_long_match_emit_encodeSnappyBlockAsmlarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_match_emit_encodeSnappyBlockAsmlarge_big_loop_back + ADD R8, R6, R15 + FMOVQ -32(R15), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R7, R1 + +emit_literal_done_match_emit_encodeSnappyBlockAsm: +match_nolit_loop_encodeSnappyBlockAsm: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_encodeSnappyBlockAsm + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_encodeSnappyBlockAsm + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm + +matchlen_bsf_16match_nolit_encodeSnappyBlockAsm: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeSnappyBlockAsm + +matchlen_match8_match_nolit_encodeSnappyBlockAsm: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_encodeSnappyBlockAsm + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_encodeSnappyBlockAsm + +matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeSnappyBlockAsm + +matchlen_match4_match_nolit_encodeSnappyBlockAsm: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_encodeSnappyBlockAsm + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_encodeSnappyBlockAsm + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_encodeSnappyBlockAsm: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_encodeSnappyBlockAsm + BLO match_nolit_end_encodeSnappyBlockAsm + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeSnappyBlockAsm + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_encodeSnappyBlockAsm + +matchlen_match1_match_nolit_encodeSnappyBlockAsm: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_encodeSnappyBlockAsm + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_encodeSnappyBlockAsm: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x00010000, R5 + BLO two_byte_offset_match_nolit_encodeSnappyBlockAsm + +four_bytes_loop_back_match_nolit_encodeSnappyBlockAsm: + CMPW $0x40, R9 + BLS four_bytes_remain_match_nolit_encodeSnappyBlockAsm + MOVD $0xff, R16 + MOVB R16, (R1) + MOVW R5, 1(R1) + SUB $64, R9, R9 + MOVWU R9, R9 + ADD $0x05, R1, R1 + CMPW $0x04, R9 + BLO four_bytes_remain_match_nolit_encodeSnappyBlockAsm + JMP four_bytes_loop_back_match_nolit_encodeSnappyBlockAsm + +four_bytes_remain_match_nolit_encodeSnappyBlockAsm: + TSTW R9, R9 + BEQ match_nolit_emitcopy_end_encodeSnappyBlockAsm + MOVD $0, R6 + ADD R9<<2, R6, R9 + SUB $1, R9, R9 + MOVWU R9, R9 + MOVB R9, (R1) + MOVW R5, 1(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBlockAsm + +two_byte_offset_match_nolit_encodeSnappyBlockAsm: + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_encodeSnappyBlockAsm + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_encodeSnappyBlockAsm + +two_byte_offset_short_match_nolit_encodeSnappyBlockAsm: + MOVWU R9, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_encodeSnappyBlockAsm + CMPW $0x00000800, R5 + BHS emit_copy_three_match_nolit_encodeSnappyBlockAsm + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBlockAsm + +emit_copy_three_match_nolit_encodeSnappyBlockAsm: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeSnappyBlockAsm: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeSnappyBlockAsm + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeSnappyBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeSnappyBlockAsm: + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x10, R7, R7 + MUL R8, R7, R7 + LSR $0x32, R7, R7 + LSL $0x10, R5, R5 + MUL R8, R5, R5 + LSR $0x32, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_encodeSnappyBlockAsm + ADDW $1, R2, R2 + JMP search_loop_encodeSnappyBlockAsm + +emit_remainder_encodeSnappyBlockAsm: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $5, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeSnappyBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeSnappyBlockAsm: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeSnappyBlockAsm + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeSnappyBlockAsm + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeSnappyBlockAsm + CMPW $0x00010000, R2 + BLO three_bytes_emit_remainder_encodeSnappyBlockAsm + CMPW $0x01000000, R2 + BLO four_bytes_emit_remainder_encodeSnappyBlockAsm + MOVD $0xfc, R16 + MOVB R16, (R1) + MOVW R2, 1(R1) + ADD $0x05, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm + +four_bytes_emit_remainder_encodeSnappyBlockAsm: + MOVWU R2, R3 + LSRW $0x10, R3, R3 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + MOVB R3, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm + +three_bytes_emit_remainder_encodeSnappyBlockAsm: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm + +two_bytes_emit_remainder_encodeSnappyBlockAsm: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeSnappyBlockAsm + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm + +one_byte_emit_remainder_encodeSnappyBlockAsm: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeSnappyBlockAsm: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeSnappyBlockAsm: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeSnappyBlockAsm + +memmove_long_emit_remainder_encodeSnappyBlockAsm: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeSnappyBlockAsmlarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeSnappyBlockAsmlarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeSnappyBlockAsm: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeSnappyBlockAsm64K(dst []byte, src []byte, tmp *[65536]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeSnappyBlockAsm64K(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000200, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeSnappyBlockAsm64K: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeSnappyBlockAsm64K + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeSnappyBlockAsm64K: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x06, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeSnappyBlockAsm64K + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + LSL $0x10, R10, R10 + MUL R8, R10, R10 + LSR $0x32, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_encodeSnappyBlockAsm64K + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R5 + MOVWU R6, R7 + MOVWU 24(RSP), R16 + SUBSW R16, R7, R7 + BEQ repeat_extend_back_end_encodeSnappyBlockAsm64K + +repeat_extend_back_loop_encodeSnappyBlockAsm64K: + CMPW R5, R6 + BLS repeat_extend_back_end_encodeSnappyBlockAsm64K + ADD R7, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_encodeSnappyBlockAsm64K + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R7, R7 + BNE repeat_extend_back_loop_encodeSnappyBlockAsm64K + +repeat_extend_back_end_encodeSnappyBlockAsm64K: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $3, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_encodeSnappyBlockAsm64K + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +repeat_dst_size_check_encodeSnappyBlockAsm64K: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_encodeSnappyBlockAsm64K + MOVWU R6, R7 + MOVW R6, 20(RSP) + ADD R5, R3, R8 + SUBW R5, R7, R7 + SUB $1, R7, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_encodeSnappyBlockAsm64K + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_encodeSnappyBlockAsm64K + BLO three_bytes_repeat_emit_encodeSnappyBlockAsm64K + +three_bytes_repeat_emit_encodeSnappyBlockAsm64K: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm64K + +two_bytes_repeat_emit_encodeSnappyBlockAsm64K: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_encodeSnappyBlockAsm64K + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm64K + +one_byte_repeat_emit_encodeSnappyBlockAsm64K: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_repeat_emit_encodeSnappyBlockAsm64K: + ADD R7, R1, R5 + + // genMemMoveShort + CMP $0x08, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm64K_memmove_move_8 + CMP $0x10, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm64K_memmove_move_8through16 + CMP $0x20, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm64K_memmove_move_17through32 + JMP emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm64K_memmove_move_33through64 + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm64K_memmove_move_8: + MOVD (R8), R9 + MOVD R9, (R1) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm64K + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm64K_memmove_move_8through16: + MOVD (R8), R9 + ADD R7, R8, R15 + MOVD -8(R15), R8 + MOVD R9, (R1) + ADD R7, R1, R15 + MOVD R8, -8(R15) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm64K + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm64K_memmove_move_17through32: + FMOVQ (R8), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm64K + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm64K_memmove_move_33through64: + FMOVQ (R8), F0 + FMOVQ 16(R8), F1 + ADD R7, R8, R15 + FMOVQ -32(R15), F2 + ADD R7, R8, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R7, R1, R15 + FMOVQ F2, -32(R15) + ADD R7, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_repeat_emit_encodeSnappyBlockAsm64K: + MOVD R5, R1 + JMP emit_literal_done_repeat_emit_encodeSnappyBlockAsm64K + +memmove_long_repeat_emit_encodeSnappyBlockAsm64K: + ADD R7, R1, R5 + + // genMemMoveLong + MOVD R8, R9 + MOVD R1, R10 + MOVD R7, R11 + +emit_lit_memmove_long_repeat_emit_encodeSnappyBlockAsm64Klarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_repeat_emit_encodeSnappyBlockAsm64Klarge_big_loop_back + ADD R7, R8, R15 + FMOVQ -32(R15), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + ADD R7, R1, R15 + FMOVQ F0, -32(R15) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_repeat_emit_encodeSnappyBlockAsm64K: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R10 + +matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm64K: + CMPW $0x10, R7 + BLO matchlen_match8_repeat_extend_encodeSnappyBlockAsm64K + MOVD (R8)(R10), R9 + ADD R10, R8, R15 + MOVD 8(R15), R11 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm64K + ADD R10, R5, R15 + MOVD 8(R15), R16 + EOR R16, R11, R11 + TST R11, R11 + BNE matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm64K + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R10, R10 + MOVWU R10, R10 + JMP matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm64K + +matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm64K: + RBIT R11, R11 + CLZ R11, R11 + ASR $0x03, R11, R11 + ADD R11, R10, R10 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm64K + +matchlen_match8_repeat_extend_encodeSnappyBlockAsm64K: + CMPW $0x08, R7 + BLO matchlen_match4_repeat_extend_encodeSnappyBlockAsm64K + MOVD (R8)(R10), R9 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm64K + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP matchlen_match4_repeat_extend_encodeSnappyBlockAsm64K + +matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm64K: + RBIT R9, R9 + CLZ R9, R9 + ASR $0x03, R9, R9 + ADD R9, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm64K + +matchlen_match4_repeat_extend_encodeSnappyBlockAsm64K: + CMPW $0x04, R7 + BLO matchlen_match2_repeat_extend_encodeSnappyBlockAsm64K + MOVWU (R8)(R10), R9 + MOVWU (R5)(R10), R16 + CMPW R9, R16 + BNE matchlen_match2_repeat_extend_encodeSnappyBlockAsm64K + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R10, R10 + MOVWU R10, R10 + +matchlen_match2_repeat_extend_encodeSnappyBlockAsm64K: + CMPW $0x01, R7 + BEQ matchlen_match1_repeat_extend_encodeSnappyBlockAsm64K + BLO repeat_extend_forward_end_encodeSnappyBlockAsm64K + MOVHU (R8)(R10), R16 + BFI $0, R16, $16, R9 + ADD R10, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R9, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_encodeSnappyBlockAsm64K + ADD $2, R10, R10 + MOVWU R10, R10 + SUBSW $0x02, R7, R7 + BEQ repeat_extend_forward_end_encodeSnappyBlockAsm64K + +matchlen_match1_repeat_extend_encodeSnappyBlockAsm64K: + MOVBU (R8)(R10), R16 + BFI $0, R16, $8, R9 + ADD R10, R5, R15 + MOVBU (R15), R15 + AND $0xff, R9, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_encodeSnappyBlockAsm64K + ADD $1, R10, R10 + MOVWU R10, R10 + +repeat_extend_forward_end_encodeSnappyBlockAsm64K: + ADDW R10, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + + // emitCopy +two_byte_offset_repeat_as_copy_encodeSnappyBlockAsm64K: + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_encodeSnappyBlockAsm64K + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R6, 1(R1) + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + JMP two_byte_offset_repeat_as_copy_encodeSnappyBlockAsm64K + +two_byte_offset_short_repeat_as_copy_encodeSnappyBlockAsm64K: + MOVWU R5, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm64K + CMPW $0x00000800, R6 + BHS emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm64K + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeSnappyBlockAsm64K + +emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm64K: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R1) + MOVH R6, 1(R1) + ADD $0x03, R1, R1 + +repeat_end_emit_encodeSnappyBlockAsm64K: + MOVW R2, 20(RSP) + JMP search_loop_encodeSnappyBlockAsm64K + +no_repeat_found_encodeSnappyBlockAsm64K: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeSnappyBlockAsm64K + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_encodeSnappyBlockAsm64K + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_encodeSnappyBlockAsm64K + MOVWU 28(RSP), R2 + JMP search_loop_encodeSnappyBlockAsm64K + +candidate3_match_encodeSnappyBlockAsm64K: + ADDW $0x02, R2, R2 + JMP candidate_match_encodeSnappyBlockAsm64K + +candidate2_match_encodeSnappyBlockAsm64K: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeSnappyBlockAsm64K: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeSnappyBlockAsm64K + +match_extend_back_loop_encodeSnappyBlockAsm64K: + CMPW R6, R2 + BLS match_extend_back_end_encodeSnappyBlockAsm64K + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeSnappyBlockAsm64K + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeSnappyBlockAsm64K + JMP match_extend_back_loop_encodeSnappyBlockAsm64K + +match_extend_back_end_encodeSnappyBlockAsm64K: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeSnappyBlockAsm64K + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeSnappyBlockAsm64K: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_encodeSnappyBlockAsm64K + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R7 + MOVWU R7, R7 + CMPW $0x3c, R7 + BLO one_byte_match_emit_encodeSnappyBlockAsm64K + CMPW $0x00000100, R7 + BLO two_bytes_match_emit_encodeSnappyBlockAsm64K + BLO three_bytes_match_emit_encodeSnappyBlockAsm64K + +three_bytes_match_emit_encodeSnappyBlockAsm64K: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBlockAsm64K + +two_bytes_match_emit_encodeSnappyBlockAsm64K: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R7, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R7 + BLO memmove_match_emit_encodeSnappyBlockAsm64K + JMP memmove_long_match_emit_encodeSnappyBlockAsm64K + +one_byte_match_emit_encodeSnappyBlockAsm64K: + LSLW $0x02, R7, R16 + BFI $0, R16, $8, R7 + MOVB R7, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeSnappyBlockAsm64K: + ADD R8, R1, R7 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm64K_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm64K_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm64K_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeSnappyBlockAsm64K_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm64K_memmove_move_8: + MOVD (R6), R9 + MOVD R9, (R1) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm64K + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm64K_memmove_move_8through16: + MOVD (R6), R9 + ADD R8, R6, R15 + MOVD -8(R15), R6 + MOVD R9, (R1) + ADD R8, R1, R15 + MOVD R6, -8(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm64K + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm64K_memmove_move_17through32: + FMOVQ (R6), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm64K + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm64K_memmove_move_33through64: + FMOVQ (R6), F0 + FMOVQ 16(R6), F1 + ADD R8, R6, R15 + FMOVQ -32(R15), F2 + ADD R8, R6, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeSnappyBlockAsm64K: + MOVD R7, R1 + JMP emit_literal_done_match_emit_encodeSnappyBlockAsm64K + +memmove_long_match_emit_encodeSnappyBlockAsm64K: + ADD R8, R1, R7 + + // genMemMoveLong + MOVD R6, R9 + MOVD R1, R10 + MOVD R8, R11 + +emit_lit_memmove_long_match_emit_encodeSnappyBlockAsm64Klarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_match_emit_encodeSnappyBlockAsm64Klarge_big_loop_back + ADD R8, R6, R15 + FMOVQ -32(R15), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R7, R1 + +emit_literal_done_match_emit_encodeSnappyBlockAsm64K: +match_nolit_loop_encodeSnappyBlockAsm64K: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm64K: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_encodeSnappyBlockAsm64K + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm64K + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_encodeSnappyBlockAsm64K + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm64K + +matchlen_bsf_16match_nolit_encodeSnappyBlockAsm64K: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeSnappyBlockAsm64K + +matchlen_match8_match_nolit_encodeSnappyBlockAsm64K: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_encodeSnappyBlockAsm64K + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm64K + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_encodeSnappyBlockAsm64K + +matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm64K: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeSnappyBlockAsm64K + +matchlen_match4_match_nolit_encodeSnappyBlockAsm64K: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_encodeSnappyBlockAsm64K + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_encodeSnappyBlockAsm64K + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_encodeSnappyBlockAsm64K: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_encodeSnappyBlockAsm64K + BLO match_nolit_end_encodeSnappyBlockAsm64K + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeSnappyBlockAsm64K + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_encodeSnappyBlockAsm64K + +matchlen_match1_match_nolit_encodeSnappyBlockAsm64K: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_encodeSnappyBlockAsm64K + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_encodeSnappyBlockAsm64K: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy +two_byte_offset_match_nolit_encodeSnappyBlockAsm64K: + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_encodeSnappyBlockAsm64K + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_encodeSnappyBlockAsm64K + +two_byte_offset_short_match_nolit_encodeSnappyBlockAsm64K: + MOVWU R9, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_encodeSnappyBlockAsm64K + CMPW $0x00000800, R5 + BHS emit_copy_three_match_nolit_encodeSnappyBlockAsm64K + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBlockAsm64K + +emit_copy_three_match_nolit_encodeSnappyBlockAsm64K: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeSnappyBlockAsm64K: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeSnappyBlockAsm64K + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeSnappyBlockAsm64K + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeSnappyBlockAsm64K: + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x10, R7, R7 + MUL R8, R7, R7 + LSR $0x32, R7, R7 + LSL $0x10, R5, R5 + MUL R8, R5, R5 + LSR $0x32, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_encodeSnappyBlockAsm64K + ADDW $1, R2, R2 + JMP search_loop_encodeSnappyBlockAsm64K + +emit_remainder_encodeSnappyBlockAsm64K: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeSnappyBlockAsm64K + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeSnappyBlockAsm64K: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeSnappyBlockAsm64K + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeSnappyBlockAsm64K + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeSnappyBlockAsm64K + BLO three_bytes_emit_remainder_encodeSnappyBlockAsm64K + +three_bytes_emit_remainder_encodeSnappyBlockAsm64K: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm64K + +two_bytes_emit_remainder_encodeSnappyBlockAsm64K: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeSnappyBlockAsm64K + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm64K + +one_byte_emit_remainder_encodeSnappyBlockAsm64K: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeSnappyBlockAsm64K: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm64K + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm64K + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm64K + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm64K + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm64K + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm64K_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeSnappyBlockAsm64K: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeSnappyBlockAsm64K + +memmove_long_emit_remainder_encodeSnappyBlockAsm64K: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeSnappyBlockAsm64Klarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeSnappyBlockAsm64Klarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeSnappyBlockAsm64K: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeSnappyBlockAsm12B(dst []byte, src []byte, tmp *[16384]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeSnappyBlockAsm12B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000080, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeSnappyBlockAsm12B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeSnappyBlockAsm12B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeSnappyBlockAsm12B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x05, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeSnappyBlockAsm12B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x000000cf1bbcdcbb, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x18, R9, R9 + MUL R8, R9, R9 + LSR $0x34, R9, R9 + LSL $0x18, R10, R10 + MUL R8, R10, R10 + LSR $0x34, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x18, R9, R9 + MUL R8, R9, R9 + LSR $0x34, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_encodeSnappyBlockAsm12B + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R5 + MOVWU R6, R7 + MOVWU 24(RSP), R16 + SUBSW R16, R7, R7 + BEQ repeat_extend_back_end_encodeSnappyBlockAsm12B + +repeat_extend_back_loop_encodeSnappyBlockAsm12B: + CMPW R5, R6 + BLS repeat_extend_back_end_encodeSnappyBlockAsm12B + ADD R7, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_encodeSnappyBlockAsm12B + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R7, R7 + BNE repeat_extend_back_loop_encodeSnappyBlockAsm12B + +repeat_extend_back_end_encodeSnappyBlockAsm12B: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $3, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_encodeSnappyBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +repeat_dst_size_check_encodeSnappyBlockAsm12B: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_encodeSnappyBlockAsm12B + MOVWU R6, R7 + MOVW R6, 20(RSP) + ADD R5, R3, R8 + SUBW R5, R7, R7 + SUB $1, R7, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_encodeSnappyBlockAsm12B + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_encodeSnappyBlockAsm12B + BLO three_bytes_repeat_emit_encodeSnappyBlockAsm12B + +three_bytes_repeat_emit_encodeSnappyBlockAsm12B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm12B + +two_bytes_repeat_emit_encodeSnappyBlockAsm12B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_encodeSnappyBlockAsm12B + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm12B + +one_byte_repeat_emit_encodeSnappyBlockAsm12B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_repeat_emit_encodeSnappyBlockAsm12B: + ADD R7, R1, R5 + + // genMemMoveShort + CMP $0x08, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm12B_memmove_move_8 + CMP $0x10, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm12B_memmove_move_8through16 + CMP $0x20, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm12B_memmove_move_17through32 + JMP emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm12B_memmove_move_33through64 + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm12B_memmove_move_8: + MOVD (R8), R9 + MOVD R9, (R1) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm12B + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm12B_memmove_move_8through16: + MOVD (R8), R9 + ADD R7, R8, R15 + MOVD -8(R15), R8 + MOVD R9, (R1) + ADD R7, R1, R15 + MOVD R8, -8(R15) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm12B + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm12B_memmove_move_17through32: + FMOVQ (R8), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm12B + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm12B_memmove_move_33through64: + FMOVQ (R8), F0 + FMOVQ 16(R8), F1 + ADD R7, R8, R15 + FMOVQ -32(R15), F2 + ADD R7, R8, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R7, R1, R15 + FMOVQ F2, -32(R15) + ADD R7, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_repeat_emit_encodeSnappyBlockAsm12B: + MOVD R5, R1 + JMP emit_literal_done_repeat_emit_encodeSnappyBlockAsm12B + +memmove_long_repeat_emit_encodeSnappyBlockAsm12B: + ADD R7, R1, R5 + + // genMemMoveLong + MOVD R8, R9 + MOVD R1, R10 + MOVD R7, R11 + +emit_lit_memmove_long_repeat_emit_encodeSnappyBlockAsm12Blarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_repeat_emit_encodeSnappyBlockAsm12Blarge_big_loop_back + ADD R7, R8, R15 + FMOVQ -32(R15), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + ADD R7, R1, R15 + FMOVQ F0, -32(R15) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_repeat_emit_encodeSnappyBlockAsm12B: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R10 + +matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm12B: + CMPW $0x10, R7 + BLO matchlen_match8_repeat_extend_encodeSnappyBlockAsm12B + MOVD (R8)(R10), R9 + ADD R10, R8, R15 + MOVD 8(R15), R11 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm12B + ADD R10, R5, R15 + MOVD 8(R15), R16 + EOR R16, R11, R11 + TST R11, R11 + BNE matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm12B + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R10, R10 + MOVWU R10, R10 + JMP matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm12B + +matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm12B: + RBIT R11, R11 + CLZ R11, R11 + ASR $0x03, R11, R11 + ADD R11, R10, R10 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm12B + +matchlen_match8_repeat_extend_encodeSnappyBlockAsm12B: + CMPW $0x08, R7 + BLO matchlen_match4_repeat_extend_encodeSnappyBlockAsm12B + MOVD (R8)(R10), R9 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm12B + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP matchlen_match4_repeat_extend_encodeSnappyBlockAsm12B + +matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm12B: + RBIT R9, R9 + CLZ R9, R9 + ASR $0x03, R9, R9 + ADD R9, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm12B + +matchlen_match4_repeat_extend_encodeSnappyBlockAsm12B: + CMPW $0x04, R7 + BLO matchlen_match2_repeat_extend_encodeSnappyBlockAsm12B + MOVWU (R8)(R10), R9 + MOVWU (R5)(R10), R16 + CMPW R9, R16 + BNE matchlen_match2_repeat_extend_encodeSnappyBlockAsm12B + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R10, R10 + MOVWU R10, R10 + +matchlen_match2_repeat_extend_encodeSnappyBlockAsm12B: + CMPW $0x01, R7 + BEQ matchlen_match1_repeat_extend_encodeSnappyBlockAsm12B + BLO repeat_extend_forward_end_encodeSnappyBlockAsm12B + MOVHU (R8)(R10), R16 + BFI $0, R16, $16, R9 + ADD R10, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R9, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_encodeSnappyBlockAsm12B + ADD $2, R10, R10 + MOVWU R10, R10 + SUBSW $0x02, R7, R7 + BEQ repeat_extend_forward_end_encodeSnappyBlockAsm12B + +matchlen_match1_repeat_extend_encodeSnappyBlockAsm12B: + MOVBU (R8)(R10), R16 + BFI $0, R16, $8, R9 + ADD R10, R5, R15 + MOVBU (R15), R15 + AND $0xff, R9, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_encodeSnappyBlockAsm12B + ADD $1, R10, R10 + MOVWU R10, R10 + +repeat_extend_forward_end_encodeSnappyBlockAsm12B: + ADDW R10, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + + // emitCopy +two_byte_offset_repeat_as_copy_encodeSnappyBlockAsm12B: + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_encodeSnappyBlockAsm12B + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R6, 1(R1) + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + JMP two_byte_offset_repeat_as_copy_encodeSnappyBlockAsm12B + +two_byte_offset_short_repeat_as_copy_encodeSnappyBlockAsm12B: + MOVWU R5, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm12B + CMPW $0x00000800, R6 + BHS emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm12B + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeSnappyBlockAsm12B + +emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm12B: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R1) + MOVH R6, 1(R1) + ADD $0x03, R1, R1 + +repeat_end_emit_encodeSnappyBlockAsm12B: + MOVW R2, 20(RSP) + JMP search_loop_encodeSnappyBlockAsm12B + +no_repeat_found_encodeSnappyBlockAsm12B: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeSnappyBlockAsm12B + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_encodeSnappyBlockAsm12B + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_encodeSnappyBlockAsm12B + MOVWU 28(RSP), R2 + JMP search_loop_encodeSnappyBlockAsm12B + +candidate3_match_encodeSnappyBlockAsm12B: + ADDW $0x02, R2, R2 + JMP candidate_match_encodeSnappyBlockAsm12B + +candidate2_match_encodeSnappyBlockAsm12B: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeSnappyBlockAsm12B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeSnappyBlockAsm12B + +match_extend_back_loop_encodeSnappyBlockAsm12B: + CMPW R6, R2 + BLS match_extend_back_end_encodeSnappyBlockAsm12B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeSnappyBlockAsm12B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeSnappyBlockAsm12B + JMP match_extend_back_loop_encodeSnappyBlockAsm12B + +match_extend_back_end_encodeSnappyBlockAsm12B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeSnappyBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeSnappyBlockAsm12B: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_encodeSnappyBlockAsm12B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R7 + MOVWU R7, R7 + CMPW $0x3c, R7 + BLO one_byte_match_emit_encodeSnappyBlockAsm12B + CMPW $0x00000100, R7 + BLO two_bytes_match_emit_encodeSnappyBlockAsm12B + BLO three_bytes_match_emit_encodeSnappyBlockAsm12B + +three_bytes_match_emit_encodeSnappyBlockAsm12B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBlockAsm12B + +two_bytes_match_emit_encodeSnappyBlockAsm12B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R7, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R7 + BLO memmove_match_emit_encodeSnappyBlockAsm12B + JMP memmove_long_match_emit_encodeSnappyBlockAsm12B + +one_byte_match_emit_encodeSnappyBlockAsm12B: + LSLW $0x02, R7, R16 + BFI $0, R16, $8, R7 + MOVB R7, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeSnappyBlockAsm12B: + ADD R8, R1, R7 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm12B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm12B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm12B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeSnappyBlockAsm12B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm12B_memmove_move_8: + MOVD (R6), R9 + MOVD R9, (R1) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm12B + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm12B_memmove_move_8through16: + MOVD (R6), R9 + ADD R8, R6, R15 + MOVD -8(R15), R6 + MOVD R9, (R1) + ADD R8, R1, R15 + MOVD R6, -8(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm12B + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm12B_memmove_move_17through32: + FMOVQ (R6), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm12B + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm12B_memmove_move_33through64: + FMOVQ (R6), F0 + FMOVQ 16(R6), F1 + ADD R8, R6, R15 + FMOVQ -32(R15), F2 + ADD R8, R6, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeSnappyBlockAsm12B: + MOVD R7, R1 + JMP emit_literal_done_match_emit_encodeSnappyBlockAsm12B + +memmove_long_match_emit_encodeSnappyBlockAsm12B: + ADD R8, R1, R7 + + // genMemMoveLong + MOVD R6, R9 + MOVD R1, R10 + MOVD R8, R11 + +emit_lit_memmove_long_match_emit_encodeSnappyBlockAsm12Blarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_match_emit_encodeSnappyBlockAsm12Blarge_big_loop_back + ADD R8, R6, R15 + FMOVQ -32(R15), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R7, R1 + +emit_literal_done_match_emit_encodeSnappyBlockAsm12B: +match_nolit_loop_encodeSnappyBlockAsm12B: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm12B: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_encodeSnappyBlockAsm12B + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm12B + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_encodeSnappyBlockAsm12B + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm12B + +matchlen_bsf_16match_nolit_encodeSnappyBlockAsm12B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeSnappyBlockAsm12B + +matchlen_match8_match_nolit_encodeSnappyBlockAsm12B: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_encodeSnappyBlockAsm12B + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm12B + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_encodeSnappyBlockAsm12B + +matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm12B: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeSnappyBlockAsm12B + +matchlen_match4_match_nolit_encodeSnappyBlockAsm12B: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_encodeSnappyBlockAsm12B + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_encodeSnappyBlockAsm12B + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_encodeSnappyBlockAsm12B: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_encodeSnappyBlockAsm12B + BLO match_nolit_end_encodeSnappyBlockAsm12B + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeSnappyBlockAsm12B + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_encodeSnappyBlockAsm12B + +matchlen_match1_match_nolit_encodeSnappyBlockAsm12B: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_encodeSnappyBlockAsm12B + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_encodeSnappyBlockAsm12B: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy +two_byte_offset_match_nolit_encodeSnappyBlockAsm12B: + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_encodeSnappyBlockAsm12B + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_encodeSnappyBlockAsm12B + +two_byte_offset_short_match_nolit_encodeSnappyBlockAsm12B: + MOVWU R9, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_encodeSnappyBlockAsm12B + CMPW $0x00000800, R5 + BHS emit_copy_three_match_nolit_encodeSnappyBlockAsm12B + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBlockAsm12B + +emit_copy_three_match_nolit_encodeSnappyBlockAsm12B: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeSnappyBlockAsm12B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeSnappyBlockAsm12B + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeSnappyBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeSnappyBlockAsm12B: + MOVD $0x000000cf1bbcdcbb, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x18, R7, R7 + MUL R8, R7, R7 + LSR $0x34, R7, R7 + LSL $0x18, R5, R5 + MUL R8, R5, R5 + LSR $0x34, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_encodeSnappyBlockAsm12B + ADDW $1, R2, R2 + JMP search_loop_encodeSnappyBlockAsm12B + +emit_remainder_encodeSnappyBlockAsm12B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeSnappyBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeSnappyBlockAsm12B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeSnappyBlockAsm12B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeSnappyBlockAsm12B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeSnappyBlockAsm12B + BLO three_bytes_emit_remainder_encodeSnappyBlockAsm12B + +three_bytes_emit_remainder_encodeSnappyBlockAsm12B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm12B + +two_bytes_emit_remainder_encodeSnappyBlockAsm12B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeSnappyBlockAsm12B + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm12B + +one_byte_emit_remainder_encodeSnappyBlockAsm12B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeSnappyBlockAsm12B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm12B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeSnappyBlockAsm12B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeSnappyBlockAsm12B + +memmove_long_emit_remainder_encodeSnappyBlockAsm12B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeSnappyBlockAsm12Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeSnappyBlockAsm12Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeSnappyBlockAsm12B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeSnappyBlockAsm10B(dst []byte, src []byte, tmp *[4096]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeSnappyBlockAsm10B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000020, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeSnappyBlockAsm10B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeSnappyBlockAsm10B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeSnappyBlockAsm10B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x05, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeSnappyBlockAsm10B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x9e3779b1, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x20, R9, R9 + MUL R8, R9, R9 + LSR $0x36, R9, R9 + LSL $0x20, R10, R10 + MUL R8, R10, R10 + LSR $0x36, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x20, R9, R9 + MUL R8, R9, R9 + LSR $0x36, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_encodeSnappyBlockAsm10B + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R5 + MOVWU R6, R7 + MOVWU 24(RSP), R16 + SUBSW R16, R7, R7 + BEQ repeat_extend_back_end_encodeSnappyBlockAsm10B + +repeat_extend_back_loop_encodeSnappyBlockAsm10B: + CMPW R5, R6 + BLS repeat_extend_back_end_encodeSnappyBlockAsm10B + ADD R7, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_encodeSnappyBlockAsm10B + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R7, R7 + BNE repeat_extend_back_loop_encodeSnappyBlockAsm10B + +repeat_extend_back_end_encodeSnappyBlockAsm10B: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $3, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_encodeSnappyBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +repeat_dst_size_check_encodeSnappyBlockAsm10B: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_encodeSnappyBlockAsm10B + MOVWU R6, R7 + MOVW R6, 20(RSP) + ADD R5, R3, R8 + SUBW R5, R7, R7 + SUB $1, R7, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_encodeSnappyBlockAsm10B + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_encodeSnappyBlockAsm10B + BLO three_bytes_repeat_emit_encodeSnappyBlockAsm10B + +three_bytes_repeat_emit_encodeSnappyBlockAsm10B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm10B + +two_bytes_repeat_emit_encodeSnappyBlockAsm10B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_encodeSnappyBlockAsm10B + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm10B + +one_byte_repeat_emit_encodeSnappyBlockAsm10B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_repeat_emit_encodeSnappyBlockAsm10B: + ADD R7, R1, R5 + + // genMemMoveShort + CMP $0x08, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm10B_memmove_move_8 + CMP $0x10, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm10B_memmove_move_8through16 + CMP $0x20, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm10B_memmove_move_17through32 + JMP emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm10B_memmove_move_33through64 + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm10B_memmove_move_8: + MOVD (R8), R9 + MOVD R9, (R1) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm10B + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm10B_memmove_move_8through16: + MOVD (R8), R9 + ADD R7, R8, R15 + MOVD -8(R15), R8 + MOVD R9, (R1) + ADD R7, R1, R15 + MOVD R8, -8(R15) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm10B + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm10B_memmove_move_17through32: + FMOVQ (R8), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm10B + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm10B_memmove_move_33through64: + FMOVQ (R8), F0 + FMOVQ 16(R8), F1 + ADD R7, R8, R15 + FMOVQ -32(R15), F2 + ADD R7, R8, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R7, R1, R15 + FMOVQ F2, -32(R15) + ADD R7, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_repeat_emit_encodeSnappyBlockAsm10B: + MOVD R5, R1 + JMP emit_literal_done_repeat_emit_encodeSnappyBlockAsm10B + +memmove_long_repeat_emit_encodeSnappyBlockAsm10B: + ADD R7, R1, R5 + + // genMemMoveLong + MOVD R8, R9 + MOVD R1, R10 + MOVD R7, R11 + +emit_lit_memmove_long_repeat_emit_encodeSnappyBlockAsm10Blarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_repeat_emit_encodeSnappyBlockAsm10Blarge_big_loop_back + ADD R7, R8, R15 + FMOVQ -32(R15), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + ADD R7, R1, R15 + FMOVQ F0, -32(R15) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_repeat_emit_encodeSnappyBlockAsm10B: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R10 + +matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm10B: + CMPW $0x10, R7 + BLO matchlen_match8_repeat_extend_encodeSnappyBlockAsm10B + MOVD (R8)(R10), R9 + ADD R10, R8, R15 + MOVD 8(R15), R11 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm10B + ADD R10, R5, R15 + MOVD 8(R15), R16 + EOR R16, R11, R11 + TST R11, R11 + BNE matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm10B + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R10, R10 + MOVWU R10, R10 + JMP matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm10B + +matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm10B: + RBIT R11, R11 + CLZ R11, R11 + ASR $0x03, R11, R11 + ADD R11, R10, R10 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm10B + +matchlen_match8_repeat_extend_encodeSnappyBlockAsm10B: + CMPW $0x08, R7 + BLO matchlen_match4_repeat_extend_encodeSnappyBlockAsm10B + MOVD (R8)(R10), R9 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm10B + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP matchlen_match4_repeat_extend_encodeSnappyBlockAsm10B + +matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm10B: + RBIT R9, R9 + CLZ R9, R9 + ASR $0x03, R9, R9 + ADD R9, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm10B + +matchlen_match4_repeat_extend_encodeSnappyBlockAsm10B: + CMPW $0x04, R7 + BLO matchlen_match2_repeat_extend_encodeSnappyBlockAsm10B + MOVWU (R8)(R10), R9 + MOVWU (R5)(R10), R16 + CMPW R9, R16 + BNE matchlen_match2_repeat_extend_encodeSnappyBlockAsm10B + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R10, R10 + MOVWU R10, R10 + +matchlen_match2_repeat_extend_encodeSnappyBlockAsm10B: + CMPW $0x01, R7 + BEQ matchlen_match1_repeat_extend_encodeSnappyBlockAsm10B + BLO repeat_extend_forward_end_encodeSnappyBlockAsm10B + MOVHU (R8)(R10), R16 + BFI $0, R16, $16, R9 + ADD R10, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R9, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_encodeSnappyBlockAsm10B + ADD $2, R10, R10 + MOVWU R10, R10 + SUBSW $0x02, R7, R7 + BEQ repeat_extend_forward_end_encodeSnappyBlockAsm10B + +matchlen_match1_repeat_extend_encodeSnappyBlockAsm10B: + MOVBU (R8)(R10), R16 + BFI $0, R16, $8, R9 + ADD R10, R5, R15 + MOVBU (R15), R15 + AND $0xff, R9, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_encodeSnappyBlockAsm10B + ADD $1, R10, R10 + MOVWU R10, R10 + +repeat_extend_forward_end_encodeSnappyBlockAsm10B: + ADDW R10, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + + // emitCopy +two_byte_offset_repeat_as_copy_encodeSnappyBlockAsm10B: + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_encodeSnappyBlockAsm10B + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R6, 1(R1) + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + JMP two_byte_offset_repeat_as_copy_encodeSnappyBlockAsm10B + +two_byte_offset_short_repeat_as_copy_encodeSnappyBlockAsm10B: + MOVWU R5, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm10B + CMPW $0x00000800, R6 + BHS emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm10B + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeSnappyBlockAsm10B + +emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm10B: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R1) + MOVH R6, 1(R1) + ADD $0x03, R1, R1 + +repeat_end_emit_encodeSnappyBlockAsm10B: + MOVW R2, 20(RSP) + JMP search_loop_encodeSnappyBlockAsm10B + +no_repeat_found_encodeSnappyBlockAsm10B: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeSnappyBlockAsm10B + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_encodeSnappyBlockAsm10B + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_encodeSnappyBlockAsm10B + MOVWU 28(RSP), R2 + JMP search_loop_encodeSnappyBlockAsm10B + +candidate3_match_encodeSnappyBlockAsm10B: + ADDW $0x02, R2, R2 + JMP candidate_match_encodeSnappyBlockAsm10B + +candidate2_match_encodeSnappyBlockAsm10B: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeSnappyBlockAsm10B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeSnappyBlockAsm10B + +match_extend_back_loop_encodeSnappyBlockAsm10B: + CMPW R6, R2 + BLS match_extend_back_end_encodeSnappyBlockAsm10B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeSnappyBlockAsm10B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeSnappyBlockAsm10B + JMP match_extend_back_loop_encodeSnappyBlockAsm10B + +match_extend_back_end_encodeSnappyBlockAsm10B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeSnappyBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeSnappyBlockAsm10B: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_encodeSnappyBlockAsm10B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R7 + MOVWU R7, R7 + CMPW $0x3c, R7 + BLO one_byte_match_emit_encodeSnappyBlockAsm10B + CMPW $0x00000100, R7 + BLO two_bytes_match_emit_encodeSnappyBlockAsm10B + BLO three_bytes_match_emit_encodeSnappyBlockAsm10B + +three_bytes_match_emit_encodeSnappyBlockAsm10B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBlockAsm10B + +two_bytes_match_emit_encodeSnappyBlockAsm10B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R7, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R7 + BLO memmove_match_emit_encodeSnappyBlockAsm10B + JMP memmove_long_match_emit_encodeSnappyBlockAsm10B + +one_byte_match_emit_encodeSnappyBlockAsm10B: + LSLW $0x02, R7, R16 + BFI $0, R16, $8, R7 + MOVB R7, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeSnappyBlockAsm10B: + ADD R8, R1, R7 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm10B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm10B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm10B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeSnappyBlockAsm10B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm10B_memmove_move_8: + MOVD (R6), R9 + MOVD R9, (R1) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm10B + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm10B_memmove_move_8through16: + MOVD (R6), R9 + ADD R8, R6, R15 + MOVD -8(R15), R6 + MOVD R9, (R1) + ADD R8, R1, R15 + MOVD R6, -8(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm10B + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm10B_memmove_move_17through32: + FMOVQ (R6), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm10B + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm10B_memmove_move_33through64: + FMOVQ (R6), F0 + FMOVQ 16(R6), F1 + ADD R8, R6, R15 + FMOVQ -32(R15), F2 + ADD R8, R6, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeSnappyBlockAsm10B: + MOVD R7, R1 + JMP emit_literal_done_match_emit_encodeSnappyBlockAsm10B + +memmove_long_match_emit_encodeSnappyBlockAsm10B: + ADD R8, R1, R7 + + // genMemMoveLong + MOVD R6, R9 + MOVD R1, R10 + MOVD R8, R11 + +emit_lit_memmove_long_match_emit_encodeSnappyBlockAsm10Blarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_match_emit_encodeSnappyBlockAsm10Blarge_big_loop_back + ADD R8, R6, R15 + FMOVQ -32(R15), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R7, R1 + +emit_literal_done_match_emit_encodeSnappyBlockAsm10B: +match_nolit_loop_encodeSnappyBlockAsm10B: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm10B: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_encodeSnappyBlockAsm10B + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm10B + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_encodeSnappyBlockAsm10B + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm10B + +matchlen_bsf_16match_nolit_encodeSnappyBlockAsm10B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeSnappyBlockAsm10B + +matchlen_match8_match_nolit_encodeSnappyBlockAsm10B: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_encodeSnappyBlockAsm10B + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm10B + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_encodeSnappyBlockAsm10B + +matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm10B: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeSnappyBlockAsm10B + +matchlen_match4_match_nolit_encodeSnappyBlockAsm10B: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_encodeSnappyBlockAsm10B + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_encodeSnappyBlockAsm10B + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_encodeSnappyBlockAsm10B: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_encodeSnappyBlockAsm10B + BLO match_nolit_end_encodeSnappyBlockAsm10B + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeSnappyBlockAsm10B + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_encodeSnappyBlockAsm10B + +matchlen_match1_match_nolit_encodeSnappyBlockAsm10B: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_encodeSnappyBlockAsm10B + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_encodeSnappyBlockAsm10B: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy +two_byte_offset_match_nolit_encodeSnappyBlockAsm10B: + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_encodeSnappyBlockAsm10B + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_encodeSnappyBlockAsm10B + +two_byte_offset_short_match_nolit_encodeSnappyBlockAsm10B: + MOVWU R9, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_encodeSnappyBlockAsm10B + CMPW $0x00000800, R5 + BHS emit_copy_three_match_nolit_encodeSnappyBlockAsm10B + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBlockAsm10B + +emit_copy_three_match_nolit_encodeSnappyBlockAsm10B: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeSnappyBlockAsm10B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeSnappyBlockAsm10B + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeSnappyBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeSnappyBlockAsm10B: + MOVD $0x9e3779b1, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x20, R7, R7 + MUL R8, R7, R7 + LSR $0x36, R7, R7 + LSL $0x20, R5, R5 + MUL R8, R5, R5 + LSR $0x36, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_encodeSnappyBlockAsm10B + ADDW $1, R2, R2 + JMP search_loop_encodeSnappyBlockAsm10B + +emit_remainder_encodeSnappyBlockAsm10B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeSnappyBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeSnappyBlockAsm10B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeSnappyBlockAsm10B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeSnappyBlockAsm10B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeSnappyBlockAsm10B + BLO three_bytes_emit_remainder_encodeSnappyBlockAsm10B + +three_bytes_emit_remainder_encodeSnappyBlockAsm10B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm10B + +two_bytes_emit_remainder_encodeSnappyBlockAsm10B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeSnappyBlockAsm10B + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm10B + +one_byte_emit_remainder_encodeSnappyBlockAsm10B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeSnappyBlockAsm10B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm10B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeSnappyBlockAsm10B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeSnappyBlockAsm10B + +memmove_long_emit_remainder_encodeSnappyBlockAsm10B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeSnappyBlockAsm10Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeSnappyBlockAsm10Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeSnappyBlockAsm10B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeSnappyBlockAsm8B(dst []byte, src []byte, tmp *[1024]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeSnappyBlockAsm8B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000008, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeSnappyBlockAsm8B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeSnappyBlockAsm8B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeSnappyBlockAsm8B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x04, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeSnappyBlockAsm8B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x9e3779b1, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x20, R9, R9 + MUL R8, R9, R9 + LSR $0x38, R9, R9 + LSL $0x20, R10, R10 + MUL R8, R10, R10 + LSR $0x38, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x20, R9, R9 + MUL R8, R9, R9 + LSR $0x38, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_encodeSnappyBlockAsm8B + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R5 + MOVWU R6, R7 + MOVWU 24(RSP), R16 + SUBSW R16, R7, R7 + BEQ repeat_extend_back_end_encodeSnappyBlockAsm8B + +repeat_extend_back_loop_encodeSnappyBlockAsm8B: + CMPW R5, R6 + BLS repeat_extend_back_end_encodeSnappyBlockAsm8B + ADD R7, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_encodeSnappyBlockAsm8B + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R7, R7 + BNE repeat_extend_back_loop_encodeSnappyBlockAsm8B + +repeat_extend_back_end_encodeSnappyBlockAsm8B: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $3, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_encodeSnappyBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +repeat_dst_size_check_encodeSnappyBlockAsm8B: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_encodeSnappyBlockAsm8B + MOVWU R6, R7 + MOVW R6, 20(RSP) + ADD R5, R3, R8 + SUBW R5, R7, R7 + SUB $1, R7, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_encodeSnappyBlockAsm8B + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_encodeSnappyBlockAsm8B + BLO three_bytes_repeat_emit_encodeSnappyBlockAsm8B + +three_bytes_repeat_emit_encodeSnappyBlockAsm8B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm8B + +two_bytes_repeat_emit_encodeSnappyBlockAsm8B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_encodeSnappyBlockAsm8B + JMP memmove_long_repeat_emit_encodeSnappyBlockAsm8B + +one_byte_repeat_emit_encodeSnappyBlockAsm8B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_repeat_emit_encodeSnappyBlockAsm8B: + ADD R7, R1, R5 + + // genMemMoveShort + CMP $0x08, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm8B_memmove_move_8 + CMP $0x10, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm8B_memmove_move_8through16 + CMP $0x20, R7 + BLS emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm8B_memmove_move_17through32 + JMP emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm8B_memmove_move_33through64 + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm8B_memmove_move_8: + MOVD (R8), R9 + MOVD R9, (R1) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm8B + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm8B_memmove_move_8through16: + MOVD (R8), R9 + ADD R7, R8, R15 + MOVD -8(R15), R8 + MOVD R9, (R1) + ADD R7, R1, R15 + MOVD R8, -8(R15) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm8B + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm8B_memmove_move_17through32: + FMOVQ (R8), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_repeat_emit_encodeSnappyBlockAsm8B + +emit_lit_memmove_repeat_emit_encodeSnappyBlockAsm8B_memmove_move_33through64: + FMOVQ (R8), F0 + FMOVQ 16(R8), F1 + ADD R7, R8, R15 + FMOVQ -32(R15), F2 + ADD R7, R8, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R7, R1, R15 + FMOVQ F2, -32(R15) + ADD R7, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_repeat_emit_encodeSnappyBlockAsm8B: + MOVD R5, R1 + JMP emit_literal_done_repeat_emit_encodeSnappyBlockAsm8B + +memmove_long_repeat_emit_encodeSnappyBlockAsm8B: + ADD R7, R1, R5 + + // genMemMoveLong + MOVD R8, R9 + MOVD R1, R10 + MOVD R7, R11 + +emit_lit_memmove_long_repeat_emit_encodeSnappyBlockAsm8Blarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_repeat_emit_encodeSnappyBlockAsm8Blarge_big_loop_back + ADD R7, R8, R15 + FMOVQ -32(R15), F0 + ADD R7, R8, R15 + FMOVQ -16(R15), F1 + ADD R7, R1, R15 + FMOVQ F0, -32(R15) + ADD R7, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_repeat_emit_encodeSnappyBlockAsm8B: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R10 + +matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm8B: + CMPW $0x10, R7 + BLO matchlen_match8_repeat_extend_encodeSnappyBlockAsm8B + MOVD (R8)(R10), R9 + ADD R10, R8, R15 + MOVD 8(R15), R11 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm8B + ADD R10, R5, R15 + MOVD 8(R15), R16 + EOR R16, R11, R11 + TST R11, R11 + BNE matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm8B + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R10, R10 + MOVWU R10, R10 + JMP matchlen_loopback_16_repeat_extend_encodeSnappyBlockAsm8B + +matchlen_bsf_16repeat_extend_encodeSnappyBlockAsm8B: + RBIT R11, R11 + CLZ R11, R11 + ASR $0x03, R11, R11 + ADD R11, R10, R10 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm8B + +matchlen_match8_repeat_extend_encodeSnappyBlockAsm8B: + CMPW $0x08, R7 + BLO matchlen_match4_repeat_extend_encodeSnappyBlockAsm8B + MOVD (R8)(R10), R9 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm8B + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP matchlen_match4_repeat_extend_encodeSnappyBlockAsm8B + +matchlen_bsf_8_repeat_extend_encodeSnappyBlockAsm8B: + RBIT R9, R9 + CLZ R9, R9 + ASR $0x03, R9, R9 + ADD R9, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_encodeSnappyBlockAsm8B + +matchlen_match4_repeat_extend_encodeSnappyBlockAsm8B: + CMPW $0x04, R7 + BLO matchlen_match2_repeat_extend_encodeSnappyBlockAsm8B + MOVWU (R8)(R10), R9 + MOVWU (R5)(R10), R16 + CMPW R9, R16 + BNE matchlen_match2_repeat_extend_encodeSnappyBlockAsm8B + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R10, R10 + MOVWU R10, R10 + +matchlen_match2_repeat_extend_encodeSnappyBlockAsm8B: + CMPW $0x01, R7 + BEQ matchlen_match1_repeat_extend_encodeSnappyBlockAsm8B + BLO repeat_extend_forward_end_encodeSnappyBlockAsm8B + MOVHU (R8)(R10), R16 + BFI $0, R16, $16, R9 + ADD R10, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R9, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_encodeSnappyBlockAsm8B + ADD $2, R10, R10 + MOVWU R10, R10 + SUBSW $0x02, R7, R7 + BEQ repeat_extend_forward_end_encodeSnappyBlockAsm8B + +matchlen_match1_repeat_extend_encodeSnappyBlockAsm8B: + MOVBU (R8)(R10), R16 + BFI $0, R16, $8, R9 + ADD R10, R5, R15 + MOVBU (R15), R15 + AND $0xff, R9, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_encodeSnappyBlockAsm8B + ADD $1, R10, R10 + MOVWU R10, R10 + +repeat_extend_forward_end_encodeSnappyBlockAsm8B: + ADDW R10, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + + // emitCopy +two_byte_offset_repeat_as_copy_encodeSnappyBlockAsm8B: + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_encodeSnappyBlockAsm8B + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R6, 1(R1) + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + JMP two_byte_offset_repeat_as_copy_encodeSnappyBlockAsm8B + +two_byte_offset_short_repeat_as_copy_encodeSnappyBlockAsm8B: + MOVWU R5, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm8B + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R6, 1(R1) + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R7, R7 + MOVB R7, (R1) + ADD $0x02, R1, R1 + JMP repeat_end_emit_encodeSnappyBlockAsm8B + +emit_copy_three_repeat_as_copy_encodeSnappyBlockAsm8B: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R1) + MOVH R6, 1(R1) + ADD $0x03, R1, R1 + +repeat_end_emit_encodeSnappyBlockAsm8B: + MOVW R2, 20(RSP) + JMP search_loop_encodeSnappyBlockAsm8B + +no_repeat_found_encodeSnappyBlockAsm8B: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeSnappyBlockAsm8B + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_encodeSnappyBlockAsm8B + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_encodeSnappyBlockAsm8B + MOVWU 28(RSP), R2 + JMP search_loop_encodeSnappyBlockAsm8B + +candidate3_match_encodeSnappyBlockAsm8B: + ADDW $0x02, R2, R2 + JMP candidate_match_encodeSnappyBlockAsm8B + +candidate2_match_encodeSnappyBlockAsm8B: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeSnappyBlockAsm8B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeSnappyBlockAsm8B + +match_extend_back_loop_encodeSnappyBlockAsm8B: + CMPW R6, R2 + BLS match_extend_back_end_encodeSnappyBlockAsm8B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeSnappyBlockAsm8B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeSnappyBlockAsm8B + JMP match_extend_back_loop_encodeSnappyBlockAsm8B + +match_extend_back_end_encodeSnappyBlockAsm8B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeSnappyBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeSnappyBlockAsm8B: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_encodeSnappyBlockAsm8B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R7 + MOVWU R7, R7 + CMPW $0x3c, R7 + BLO one_byte_match_emit_encodeSnappyBlockAsm8B + CMPW $0x00000100, R7 + BLO two_bytes_match_emit_encodeSnappyBlockAsm8B + BLO three_bytes_match_emit_encodeSnappyBlockAsm8B + +three_bytes_match_emit_encodeSnappyBlockAsm8B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBlockAsm8B + +two_bytes_match_emit_encodeSnappyBlockAsm8B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R7, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R7 + BLO memmove_match_emit_encodeSnappyBlockAsm8B + JMP memmove_long_match_emit_encodeSnappyBlockAsm8B + +one_byte_match_emit_encodeSnappyBlockAsm8B: + LSLW $0x02, R7, R16 + BFI $0, R16, $8, R7 + MOVB R7, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeSnappyBlockAsm8B: + ADD R8, R1, R7 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm8B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm8B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBlockAsm8B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeSnappyBlockAsm8B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm8B_memmove_move_8: + MOVD (R6), R9 + MOVD R9, (R1) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm8B + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm8B_memmove_move_8through16: + MOVD (R6), R9 + ADD R8, R6, R15 + MOVD -8(R15), R6 + MOVD R9, (R1) + ADD R8, R1, R15 + MOVD R6, -8(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm8B + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm8B_memmove_move_17through32: + FMOVQ (R6), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBlockAsm8B + +emit_lit_memmove_match_emit_encodeSnappyBlockAsm8B_memmove_move_33through64: + FMOVQ (R6), F0 + FMOVQ 16(R6), F1 + ADD R8, R6, R15 + FMOVQ -32(R15), F2 + ADD R8, R6, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeSnappyBlockAsm8B: + MOVD R7, R1 + JMP emit_literal_done_match_emit_encodeSnappyBlockAsm8B + +memmove_long_match_emit_encodeSnappyBlockAsm8B: + ADD R8, R1, R7 + + // genMemMoveLong + MOVD R6, R9 + MOVD R1, R10 + MOVD R8, R11 + +emit_lit_memmove_long_match_emit_encodeSnappyBlockAsm8Blarge_big_loop_back: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + FMOVQ F0, (R10) + FMOVQ F1, 16(R10) + ADD $0x20, R9, R9 + ADD $0x20, R10, R10 + SUB $0x20, R11, R11 + CMP $0x20, R11 + BHS emit_lit_memmove_long_match_emit_encodeSnappyBlockAsm8Blarge_big_loop_back + ADD R8, R6, R15 + FMOVQ -32(R15), F0 + ADD R8, R6, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R7, R1 + +emit_literal_done_match_emit_encodeSnappyBlockAsm8B: +match_nolit_loop_encodeSnappyBlockAsm8B: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm8B: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_encodeSnappyBlockAsm8B + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm8B + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_encodeSnappyBlockAsm8B + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_encodeSnappyBlockAsm8B + +matchlen_bsf_16match_nolit_encodeSnappyBlockAsm8B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeSnappyBlockAsm8B + +matchlen_match8_match_nolit_encodeSnappyBlockAsm8B: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_encodeSnappyBlockAsm8B + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm8B + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_encodeSnappyBlockAsm8B + +matchlen_bsf_8_match_nolit_encodeSnappyBlockAsm8B: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_encodeSnappyBlockAsm8B + +matchlen_match4_match_nolit_encodeSnappyBlockAsm8B: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_encodeSnappyBlockAsm8B + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_encodeSnappyBlockAsm8B + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_encodeSnappyBlockAsm8B: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_encodeSnappyBlockAsm8B + BLO match_nolit_end_encodeSnappyBlockAsm8B + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeSnappyBlockAsm8B + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_encodeSnappyBlockAsm8B + +matchlen_match1_match_nolit_encodeSnappyBlockAsm8B: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_encodeSnappyBlockAsm8B + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_encodeSnappyBlockAsm8B: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy +two_byte_offset_match_nolit_encodeSnappyBlockAsm8B: + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_encodeSnappyBlockAsm8B + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_encodeSnappyBlockAsm8B + +two_byte_offset_short_match_nolit_encodeSnappyBlockAsm8B: + MOVWU R9, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_encodeSnappyBlockAsm8B + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R5, 1(R1) + LSRW $0x08, R5, R5 + LSLW $0x05, R5, R5 + ORRW R5, R6, R6 + MOVB R6, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBlockAsm8B + +emit_copy_three_match_nolit_encodeSnappyBlockAsm8B: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeSnappyBlockAsm8B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeSnappyBlockAsm8B + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeSnappyBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeSnappyBlockAsm8B: + MOVD $0x9e3779b1, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x20, R7, R7 + MUL R8, R7, R7 + LSR $0x38, R7, R7 + LSL $0x20, R5, R5 + MUL R8, R5, R5 + LSR $0x38, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_encodeSnappyBlockAsm8B + ADDW $1, R2, R2 + JMP search_loop_encodeSnappyBlockAsm8B + +emit_remainder_encodeSnappyBlockAsm8B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeSnappyBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeSnappyBlockAsm8B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeSnappyBlockAsm8B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeSnappyBlockAsm8B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeSnappyBlockAsm8B + BLO three_bytes_emit_remainder_encodeSnappyBlockAsm8B + +three_bytes_emit_remainder_encodeSnappyBlockAsm8B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm8B + +two_bytes_emit_remainder_encodeSnappyBlockAsm8B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeSnappyBlockAsm8B + JMP memmove_long_emit_remainder_encodeSnappyBlockAsm8B + +one_byte_emit_remainder_encodeSnappyBlockAsm8B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeSnappyBlockAsm8B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeSnappyBlockAsm8B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeSnappyBlockAsm8B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeSnappyBlockAsm8B + +memmove_long_emit_remainder_encodeSnappyBlockAsm8B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeSnappyBlockAsm8Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeSnappyBlockAsm8Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeSnappyBlockAsm8B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeSnappyBetterBlockAsm(dst []byte, src []byte, tmp *[589824]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeSnappyBetterBlockAsm(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00001200, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeSnappyBetterBlockAsm: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeSnappyBetterBlockAsm + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVD $0x00000000, R16 + MOVW R16, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeSnappyBetterBlockAsm: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x07, R5, R5 + CMPW $0x63, R5 + BLS check_maxskip_ok_encodeSnappyBetterBlockAsm + ADD $100, R2, R5 + MOVWU R5, R5 + JMP check_maxskip_cont_encodeSnappyBetterBlockAsm + +check_maxskip_ok_encodeSnappyBetterBlockAsm: + ADD R5, R2, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + +check_maxskip_cont_encodeSnappyBetterBlockAsm: + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeSnappyBetterBlockAsm + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x00cf1bbcdcbfa563, R8 + MOVD $0x9e3779b1, R5 + MOVD R6, R9 + MOVD R6, R10 + LSL $0x08, R9, R9 + MUL R8, R9, R9 + LSR $0x2f, R9, R9 + LSL $0x20, R10, R10 + MUL R5, R10, R10 + LSR $0x32, R10, R10 + MOVWU (R0)(R9<<2), R5 + ADD R10<<2, R0, R15 + MOVWU 524288(R15), R7 + MOVW R2, (R0)(R9<<2) + ADD R10<<2, R0, R15 + MOVW R2, 524288(R15) + MOVD (R3)(R5), R9 + MOVD (R3)(R7), R10 + CMP R6, R9 + BEQ candidate_match_encodeSnappyBetterBlockAsm + CMP R6, R10 + BNE no_short_found_encodeSnappyBetterBlockAsm + MOVWU R7, R5 + JMP candidate_match_encodeSnappyBetterBlockAsm + +no_short_found_encodeSnappyBetterBlockAsm: + CMPW R6, R9 + BEQ candidate_match_encodeSnappyBetterBlockAsm + CMPW R6, R10 + BEQ candidateS_match_encodeSnappyBetterBlockAsm + MOVWU 28(RSP), R2 + JMP search_loop_encodeSnappyBetterBlockAsm + +candidateS_match_encodeSnappyBetterBlockAsm: + LSR $0x08, R6, R6 + MOVD R6, R9 + LSL $0x08, R9, R9 + MUL R8, R9, R9 + LSR $0x2f, R9, R9 + MOVWU (R0)(R9<<2), R5 + ADDW $1, R2, R2 + MOVW R2, (R0)(R9<<2) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeSnappyBetterBlockAsm + SUBW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeSnappyBetterBlockAsm: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeSnappyBetterBlockAsm + +match_extend_back_loop_encodeSnappyBetterBlockAsm: + CMPW R6, R2 + BLS match_extend_back_end_encodeSnappyBetterBlockAsm + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeSnappyBetterBlockAsm + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeSnappyBetterBlockAsm + JMP match_extend_back_loop_encodeSnappyBetterBlockAsm + +match_extend_back_end_encodeSnappyBetterBlockAsm: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $5, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeSnappyBetterBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeSnappyBetterBlockAsm: + MOVWU R2, R6 + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R9 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm: + CMPW $0x10, R7 + BLO matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm + MOVD (R8)(R11), R10 + ADD R11, R8, R15 + MOVD 8(R15), R12 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm + ADD R11, R9, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm + +matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeSnappyBetterBlockAsm + +matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm: + CMPW $0x08, R7 + BLO matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm + MOVD (R8)(R11), R10 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm + +matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeSnappyBetterBlockAsm + +matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm: + CMPW $0x04, R7 + BLO matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm + MOVWU (R8)(R11), R10 + MOVWU (R9)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm: + CMPW $0x01, R7 + BEQ matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm + BLO match_nolit_end_encodeSnappyBetterBlockAsm + MOVHU (R8)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R9, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R7, R7 + BEQ match_nolit_end_encodeSnappyBetterBlockAsm + +matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm: + MOVBU (R8)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R9, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE match_nolit_end_encodeSnappyBetterBlockAsm + ADD $1, R11, R11 + MOVWU R11, R11 + +match_nolit_end_encodeSnappyBetterBlockAsm: + MOVWU R2, R7 + SUBW R5, R7, R7 + + // Check if repeat + CMPW $0x01, R11 + BHI match_length_ok_encodeSnappyBetterBlockAsm + CMPW $0x0000ffff, R7 + BLS match_length_ok_encodeSnappyBetterBlockAsm + MOVWU 28(RSP), R2 + ADDW $1, R2, R2 + JMP search_loop_encodeSnappyBetterBlockAsm + +match_length_ok_encodeSnappyBetterBlockAsm: + MOVW R7, 24(RSP) + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_encodeSnappyBetterBlockAsm + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_encodeSnappyBetterBlockAsm + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_encodeSnappyBetterBlockAsm + CMPW $0x00010000, R5 + BLO three_bytes_match_emit_encodeSnappyBetterBlockAsm + CMPW $0x01000000, R5 + BLO four_bytes_match_emit_encodeSnappyBetterBlockAsm + MOVD $0xfc, R16 + MOVB R16, (R1) + MOVW R5, 1(R1) + ADD $0x05, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm + +four_bytes_match_emit_encodeSnappyBetterBlockAsm: + MOVWU R5, R10 + LSRW $0x10, R10, R10 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + MOVB R10, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm + +three_bytes_match_emit_encodeSnappyBetterBlockAsm: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm + +two_bytes_match_emit_encodeSnappyBetterBlockAsm: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_encodeSnappyBetterBlockAsm + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm + +one_byte_match_emit_encodeSnappyBetterBlockAsm: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeSnappyBetterBlockAsm: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm_memmove_move_8: + MOVD (R9), R10 + MOVD R10, (R1) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm: + MOVD R5, R1 + JMP emit_literal_done_match_emit_encodeSnappyBetterBlockAsm + +memmove_long_match_emit_encodeSnappyBetterBlockAsm: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_encodeSnappyBetterBlockAsmlarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_encodeSnappyBetterBlockAsmlarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_encodeSnappyBetterBlockAsm: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x00010000, R7 + BLO two_byte_offset_match_nolit_encodeSnappyBetterBlockAsm + +four_bytes_loop_back_match_nolit_encodeSnappyBetterBlockAsm: + CMPW $0x40, R11 + BLS four_bytes_remain_match_nolit_encodeSnappyBetterBlockAsm + MOVD $0xff, R16 + MOVB R16, (R1) + MOVW R7, 1(R1) + SUB $64, R11, R11 + MOVWU R11, R11 + ADD $0x05, R1, R1 + CMPW $0x04, R11 + BLO four_bytes_remain_match_nolit_encodeSnappyBetterBlockAsm + JMP four_bytes_loop_back_match_nolit_encodeSnappyBetterBlockAsm + +four_bytes_remain_match_nolit_encodeSnappyBetterBlockAsm: + TSTW R11, R11 + BEQ match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm + MOVD $0, R5 + ADD R11<<2, R5, R11 + SUB $1, R11, R11 + MOVWU R11, R11 + MOVB R11, (R1) + MOVW R7, 1(R1) + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm + +two_byte_offset_match_nolit_encodeSnappyBetterBlockAsm: + CMPW $0x40, R11 + BLS two_byte_offset_short_match_nolit_encodeSnappyBetterBlockAsm + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + SUB $60, R11, R11 + MOVWU R11, R11 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_encodeSnappyBetterBlockAsm + +two_byte_offset_short_match_nolit_encodeSnappyBetterBlockAsm: + MOVWU R11, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R11 + BHS emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm + CMPW $0x00000800, R7 + BHS emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm + +emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeSnappyBetterBlockAsm + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeSnappyBetterBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeSnappyBetterBlockAsm: + MOVD $0x00cf1bbcdcbfa563, R5 + MOVD $0x9e3779b1, R7 + ADD $1, R6, R6 + SUB $2, R2, R8 + MOVD (R3)(R6), R9 + ADD R6, R3, R15 + MOVD 1(R15), R10 + MOVD (R3)(R8), R11 + ADD R8, R3, R15 + MOVD 1(R15), R12 + LSL $0x08, R9, R9 + MUL R5, R9, R9 + LSR $0x2f, R9, R9 + LSL $0x20, R10, R10 + MUL R7, R10, R10 + LSR $0x32, R10, R10 + LSL $0x08, R11, R11 + MUL R5, R11, R11 + LSR $0x2f, R11, R11 + LSL $0x20, R12, R12 + MUL R7, R12, R12 + LSR $0x32, R12, R12 + ADD $1, R6, R7 + ADD $1, R8, R13 + MOVW R6, (R0)(R9<<2) + MOVW R8, (R0)(R11<<2) + ADD R10<<2, R0, R15 + MOVW R7, 524288(R15) + ADD R12<<2, R0, R15 + MOVW R13, 524288(R15) + ADD R6, R8, R7 + ADD $1, R7, R7 + LSR $0x01, R7, R7 + ADD $0x01, R6, R6 + SUB $0x01, R8, R8 + +index_loop_encodeSnappyBetterBlockAsm: + CMP R8, R7 + BHS search_loop_encodeSnappyBetterBlockAsm + MOVD (R3)(R6), R9 + MOVD (R3)(R7), R10 + LSL $0x08, R9, R9 + MUL R5, R9, R9 + LSR $0x2f, R9, R9 + LSL $0x08, R10, R10 + MUL R5, R10, R10 + LSR $0x2f, R10, R10 + MOVW R6, (R0)(R9<<2) + MOVW R7, (R0)(R10<<2) + ADD $0x02, R6, R6 + ADD $0x02, R7, R7 + JMP index_loop_encodeSnappyBetterBlockAsm + +emit_remainder_encodeSnappyBetterBlockAsm: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $5, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeSnappyBetterBlockAsm + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeSnappyBetterBlockAsm: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeSnappyBetterBlockAsm + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeSnappyBetterBlockAsm + CMPW $0x00010000, R2 + BLO three_bytes_emit_remainder_encodeSnappyBetterBlockAsm + CMPW $0x01000000, R2 + BLO four_bytes_emit_remainder_encodeSnappyBetterBlockAsm + MOVD $0xfc, R16 + MOVB R16, (R1) + MOVW R2, 1(R1) + ADD $0x05, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm + +four_bytes_emit_remainder_encodeSnappyBetterBlockAsm: + MOVWU R2, R3 + LSRW $0x10, R3, R3 + MOVD $0xf8, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + MOVB R3, 3(R1) + ADD $0x04, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm + +three_bytes_emit_remainder_encodeSnappyBetterBlockAsm: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm + +two_bytes_emit_remainder_encodeSnappyBetterBlockAsm: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeSnappyBetterBlockAsm + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm + +one_byte_emit_remainder_encodeSnappyBetterBlockAsm: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeSnappyBetterBlockAsm: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm + +memmove_long_emit_remainder_encodeSnappyBetterBlockAsm: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeSnappyBetterBlockAsmlarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeSnappyBetterBlockAsmlarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeSnappyBetterBlockAsm64K(dst []byte, src []byte, tmp *[294912]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeSnappyBetterBlockAsm64K(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000900, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeSnappyBetterBlockAsm64K: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeSnappyBetterBlockAsm64K + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVD $0x00000000, R16 + MOVW R16, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeSnappyBetterBlockAsm64K: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x07, R5, R5 + ADD R5, R2, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeSnappyBetterBlockAsm64K + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x00cf1bbcdcbfa563, R8 + MOVD $0x9e3779b1, R5 + MOVD R6, R9 + MOVD R6, R10 + LSL $0x08, R9, R9 + MUL R8, R9, R9 + LSR $0x30, R9, R9 + LSL $0x20, R10, R10 + MUL R5, R10, R10 + LSR $0x33, R10, R10 + MOVWU (R0)(R9<<2), R5 + ADD R10<<2, R0, R15 + MOVWU 262144(R15), R7 + MOVW R2, (R0)(R9<<2) + ADD R10<<2, R0, R15 + MOVW R2, 262144(R15) + MOVD (R3)(R5), R9 + MOVD (R3)(R7), R10 + CMP R6, R9 + BEQ candidate_match_encodeSnappyBetterBlockAsm64K + CMP R6, R10 + BNE no_short_found_encodeSnappyBetterBlockAsm64K + MOVWU R7, R5 + JMP candidate_match_encodeSnappyBetterBlockAsm64K + +no_short_found_encodeSnappyBetterBlockAsm64K: + CMPW R6, R9 + BEQ candidate_match_encodeSnappyBetterBlockAsm64K + CMPW R6, R10 + BEQ candidateS_match_encodeSnappyBetterBlockAsm64K + MOVWU 28(RSP), R2 + JMP search_loop_encodeSnappyBetterBlockAsm64K + +candidateS_match_encodeSnappyBetterBlockAsm64K: + LSR $0x08, R6, R6 + MOVD R6, R9 + LSL $0x08, R9, R9 + MUL R8, R9, R9 + LSR $0x30, R9, R9 + MOVWU (R0)(R9<<2), R5 + ADDW $1, R2, R2 + MOVW R2, (R0)(R9<<2) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeSnappyBetterBlockAsm64K + SUBW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeSnappyBetterBlockAsm64K: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeSnappyBetterBlockAsm64K + +match_extend_back_loop_encodeSnappyBetterBlockAsm64K: + CMPW R6, R2 + BLS match_extend_back_end_encodeSnappyBetterBlockAsm64K + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeSnappyBetterBlockAsm64K + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeSnappyBetterBlockAsm64K + JMP match_extend_back_loop_encodeSnappyBetterBlockAsm64K + +match_extend_back_end_encodeSnappyBetterBlockAsm64K: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeSnappyBetterBlockAsm64K + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeSnappyBetterBlockAsm64K: + MOVWU R2, R6 + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R9 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm64K: + CMPW $0x10, R7 + BLO matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm64K + MOVD (R8)(R11), R10 + ADD R11, R8, R15 + MOVD 8(R15), R12 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm64K + ADD R11, R9, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm64K + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm64K + +matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm64K: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeSnappyBetterBlockAsm64K + +matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm64K: + CMPW $0x08, R7 + BLO matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm64K + MOVD (R8)(R11), R10 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm64K + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm64K + +matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm64K: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeSnappyBetterBlockAsm64K + +matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm64K: + CMPW $0x04, R7 + BLO matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm64K + MOVWU (R8)(R11), R10 + MOVWU (R9)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm64K + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm64K: + CMPW $0x01, R7 + BEQ matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm64K + BLO match_nolit_end_encodeSnappyBetterBlockAsm64K + MOVHU (R8)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R9, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm64K + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R7, R7 + BEQ match_nolit_end_encodeSnappyBetterBlockAsm64K + +matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm64K: + MOVBU (R8)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R9, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE match_nolit_end_encodeSnappyBetterBlockAsm64K + ADD $1, R11, R11 + MOVWU R11, R11 + +match_nolit_end_encodeSnappyBetterBlockAsm64K: + MOVWU R2, R7 + SUBW R5, R7, R7 + + // Check if repeat + MOVW R7, 24(RSP) + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_encodeSnappyBetterBlockAsm64K + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_encodeSnappyBetterBlockAsm64K + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_encodeSnappyBetterBlockAsm64K + BLO three_bytes_match_emit_encodeSnappyBetterBlockAsm64K + +three_bytes_match_emit_encodeSnappyBetterBlockAsm64K: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm64K + +two_bytes_match_emit_encodeSnappyBetterBlockAsm64K: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_encodeSnappyBetterBlockAsm64K + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm64K + +one_byte_match_emit_encodeSnappyBetterBlockAsm64K: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeSnappyBetterBlockAsm64K: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm64K_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm64K_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm64K_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm64K_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm64K_memmove_move_8: + MOVD (R9), R10 + MOVD R10, (R1) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm64K + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm64K_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm64K + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm64K_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm64K + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm64K_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm64K: + MOVD R5, R1 + JMP emit_literal_done_match_emit_encodeSnappyBetterBlockAsm64K + +memmove_long_match_emit_encodeSnappyBetterBlockAsm64K: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_encodeSnappyBetterBlockAsm64Klarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_encodeSnappyBetterBlockAsm64Klarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_encodeSnappyBetterBlockAsm64K: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitCopy +two_byte_offset_match_nolit_encodeSnappyBetterBlockAsm64K: + CMPW $0x40, R11 + BLS two_byte_offset_short_match_nolit_encodeSnappyBetterBlockAsm64K + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + SUB $60, R11, R11 + MOVWU R11, R11 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_encodeSnappyBetterBlockAsm64K + +two_byte_offset_short_match_nolit_encodeSnappyBetterBlockAsm64K: + MOVWU R11, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R11 + BHS emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm64K + CMPW $0x00000800, R7 + BHS emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm64K + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm64K + +emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm64K: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm64K: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeSnappyBetterBlockAsm64K + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeSnappyBetterBlockAsm64K + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeSnappyBetterBlockAsm64K: + MOVD $0x00cf1bbcdcbfa563, R5 + MOVD $0x9e3779b1, R7 + ADD $1, R6, R6 + SUB $2, R2, R8 + MOVD (R3)(R6), R9 + ADD R6, R3, R15 + MOVD 1(R15), R10 + MOVD (R3)(R8), R11 + ADD R8, R3, R15 + MOVD 1(R15), R12 + LSL $0x08, R9, R9 + MUL R5, R9, R9 + LSR $0x30, R9, R9 + LSL $0x20, R10, R10 + MUL R7, R10, R10 + LSR $0x33, R10, R10 + LSL $0x08, R11, R11 + MUL R5, R11, R11 + LSR $0x30, R11, R11 + LSL $0x20, R12, R12 + MUL R7, R12, R12 + LSR $0x33, R12, R12 + ADD $1, R6, R7 + ADD $1, R8, R13 + MOVW R6, (R0)(R9<<2) + MOVW R8, (R0)(R11<<2) + ADD R10<<2, R0, R15 + MOVW R7, 262144(R15) + ADD R12<<2, R0, R15 + MOVW R13, 262144(R15) + ADD R6, R8, R7 + ADD $1, R7, R7 + LSR $0x01, R7, R7 + ADD $0x01, R6, R6 + SUB $0x01, R8, R8 + +index_loop_encodeSnappyBetterBlockAsm64K: + CMP R8, R7 + BHS search_loop_encodeSnappyBetterBlockAsm64K + MOVD (R3)(R6), R9 + MOVD (R3)(R7), R10 + LSL $0x08, R9, R9 + MUL R5, R9, R9 + LSR $0x30, R9, R9 + LSL $0x08, R10, R10 + MUL R5, R10, R10 + LSR $0x30, R10, R10 + MOVW R6, (R0)(R9<<2) + MOVW R7, (R0)(R10<<2) + ADD $0x02, R6, R6 + ADD $0x02, R7, R7 + JMP index_loop_encodeSnappyBetterBlockAsm64K + +emit_remainder_encodeSnappyBetterBlockAsm64K: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeSnappyBetterBlockAsm64K + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeSnappyBetterBlockAsm64K: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm64K + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeSnappyBetterBlockAsm64K + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeSnappyBetterBlockAsm64K + BLO three_bytes_emit_remainder_encodeSnappyBetterBlockAsm64K + +three_bytes_emit_remainder_encodeSnappyBetterBlockAsm64K: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm64K + +two_bytes_emit_remainder_encodeSnappyBetterBlockAsm64K: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeSnappyBetterBlockAsm64K + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm64K + +one_byte_emit_remainder_encodeSnappyBetterBlockAsm64K: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeSnappyBetterBlockAsm64K: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm64K + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm64K + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm64K + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm64K + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm64K + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm64K_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm64K: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm64K + +memmove_long_emit_remainder_encodeSnappyBetterBlockAsm64K: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeSnappyBetterBlockAsm64Klarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeSnappyBetterBlockAsm64Klarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm64K: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeSnappyBetterBlockAsm12B(dst []byte, src []byte, tmp *[81920]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeSnappyBetterBlockAsm12B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000280, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeSnappyBetterBlockAsm12B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeSnappyBetterBlockAsm12B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVD $0x00000000, R16 + MOVW R16, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeSnappyBetterBlockAsm12B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x06, R5, R5 + ADD R5, R2, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeSnappyBetterBlockAsm12B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD $0x9e3779b1, R5 + MOVD R6, R9 + MOVD R6, R10 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + LSL $0x20, R10, R10 + MUL R5, R10, R10 + LSR $0x34, R10, R10 + MOVWU (R0)(R9<<2), R5 + ADD R10<<2, R0, R15 + MOVWU 65536(R15), R7 + MOVW R2, (R0)(R9<<2) + ADD R10<<2, R0, R15 + MOVW R2, 65536(R15) + MOVD (R3)(R5), R9 + MOVD (R3)(R7), R10 + CMP R6, R9 + BEQ candidate_match_encodeSnappyBetterBlockAsm12B + CMP R6, R10 + BNE no_short_found_encodeSnappyBetterBlockAsm12B + MOVWU R7, R5 + JMP candidate_match_encodeSnappyBetterBlockAsm12B + +no_short_found_encodeSnappyBetterBlockAsm12B: + CMPW R6, R9 + BEQ candidate_match_encodeSnappyBetterBlockAsm12B + CMPW R6, R10 + BEQ candidateS_match_encodeSnappyBetterBlockAsm12B + MOVWU 28(RSP), R2 + JMP search_loop_encodeSnappyBetterBlockAsm12B + +candidateS_match_encodeSnappyBetterBlockAsm12B: + LSR $0x08, R6, R6 + MOVD R6, R9 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x32, R9, R9 + MOVWU (R0)(R9<<2), R5 + ADDW $1, R2, R2 + MOVW R2, (R0)(R9<<2) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeSnappyBetterBlockAsm12B + SUBW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeSnappyBetterBlockAsm12B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeSnappyBetterBlockAsm12B + +match_extend_back_loop_encodeSnappyBetterBlockAsm12B: + CMPW R6, R2 + BLS match_extend_back_end_encodeSnappyBetterBlockAsm12B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeSnappyBetterBlockAsm12B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeSnappyBetterBlockAsm12B + JMP match_extend_back_loop_encodeSnappyBetterBlockAsm12B + +match_extend_back_end_encodeSnappyBetterBlockAsm12B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeSnappyBetterBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeSnappyBetterBlockAsm12B: + MOVWU R2, R6 + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R9 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm12B: + CMPW $0x10, R7 + BLO matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm12B + MOVD (R8)(R11), R10 + ADD R11, R8, R15 + MOVD 8(R15), R12 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm12B + ADD R11, R9, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm12B + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm12B + +matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm12B: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeSnappyBetterBlockAsm12B + +matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm12B: + CMPW $0x08, R7 + BLO matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm12B + MOVD (R8)(R11), R10 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm12B + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm12B + +matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm12B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeSnappyBetterBlockAsm12B + +matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm12B: + CMPW $0x04, R7 + BLO matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm12B + MOVWU (R8)(R11), R10 + MOVWU (R9)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm12B + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm12B: + CMPW $0x01, R7 + BEQ matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm12B + BLO match_nolit_end_encodeSnappyBetterBlockAsm12B + MOVHU (R8)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R9, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm12B + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R7, R7 + BEQ match_nolit_end_encodeSnappyBetterBlockAsm12B + +matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm12B: + MOVBU (R8)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R9, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE match_nolit_end_encodeSnappyBetterBlockAsm12B + ADD $1, R11, R11 + MOVWU R11, R11 + +match_nolit_end_encodeSnappyBetterBlockAsm12B: + MOVWU R2, R7 + SUBW R5, R7, R7 + + // Check if repeat + MOVW R7, 24(RSP) + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_encodeSnappyBetterBlockAsm12B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_encodeSnappyBetterBlockAsm12B + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_encodeSnappyBetterBlockAsm12B + BLO three_bytes_match_emit_encodeSnappyBetterBlockAsm12B + +three_bytes_match_emit_encodeSnappyBetterBlockAsm12B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm12B + +two_bytes_match_emit_encodeSnappyBetterBlockAsm12B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_encodeSnappyBetterBlockAsm12B + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm12B + +one_byte_match_emit_encodeSnappyBetterBlockAsm12B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeSnappyBetterBlockAsm12B: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm12B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm12B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm12B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm12B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm12B_memmove_move_8: + MOVD (R9), R10 + MOVD R10, (R1) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm12B + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm12B_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm12B + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm12B_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm12B + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm12B_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm12B: + MOVD R5, R1 + JMP emit_literal_done_match_emit_encodeSnappyBetterBlockAsm12B + +memmove_long_match_emit_encodeSnappyBetterBlockAsm12B: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_encodeSnappyBetterBlockAsm12Blarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_encodeSnappyBetterBlockAsm12Blarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_encodeSnappyBetterBlockAsm12B: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitCopy +two_byte_offset_match_nolit_encodeSnappyBetterBlockAsm12B: + CMPW $0x40, R11 + BLS two_byte_offset_short_match_nolit_encodeSnappyBetterBlockAsm12B + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + SUB $60, R11, R11 + MOVWU R11, R11 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_encodeSnappyBetterBlockAsm12B + +two_byte_offset_short_match_nolit_encodeSnappyBetterBlockAsm12B: + MOVWU R11, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R11 + BHS emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm12B + CMPW $0x00000800, R7 + BHS emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm12B + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm12B + +emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm12B: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm12B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeSnappyBetterBlockAsm12B + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeSnappyBetterBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeSnappyBetterBlockAsm12B: + MOVD $0x0000cf1bbcdcbf9b, R5 + MOVD $0x9e3779b1, R7 + ADD $1, R6, R6 + SUB $2, R2, R8 + MOVD (R3)(R6), R9 + ADD R6, R3, R15 + MOVD 1(R15), R10 + MOVD (R3)(R8), R11 + ADD R8, R3, R15 + MOVD 1(R15), R12 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x32, R9, R9 + LSL $0x20, R10, R10 + MUL R7, R10, R10 + LSR $0x34, R10, R10 + LSL $0x10, R11, R11 + MUL R5, R11, R11 + LSR $0x32, R11, R11 + LSL $0x20, R12, R12 + MUL R7, R12, R12 + LSR $0x34, R12, R12 + ADD $1, R6, R7 + ADD $1, R8, R13 + MOVW R6, (R0)(R9<<2) + MOVW R8, (R0)(R11<<2) + ADD R10<<2, R0, R15 + MOVW R7, 65536(R15) + ADD R12<<2, R0, R15 + MOVW R13, 65536(R15) + ADD R6, R8, R7 + ADD $1, R7, R7 + LSR $0x01, R7, R7 + ADD $0x01, R6, R6 + SUB $0x01, R8, R8 + +index_loop_encodeSnappyBetterBlockAsm12B: + CMP R8, R7 + BHS search_loop_encodeSnappyBetterBlockAsm12B + MOVD (R3)(R6), R9 + MOVD (R3)(R7), R10 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x32, R9, R9 + LSL $0x10, R10, R10 + MUL R5, R10, R10 + LSR $0x32, R10, R10 + MOVW R6, (R0)(R9<<2) + MOVW R7, (R0)(R10<<2) + ADD $0x02, R6, R6 + ADD $0x02, R7, R7 + JMP index_loop_encodeSnappyBetterBlockAsm12B + +emit_remainder_encodeSnappyBetterBlockAsm12B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeSnappyBetterBlockAsm12B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeSnappyBetterBlockAsm12B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm12B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeSnappyBetterBlockAsm12B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeSnappyBetterBlockAsm12B + BLO three_bytes_emit_remainder_encodeSnappyBetterBlockAsm12B + +three_bytes_emit_remainder_encodeSnappyBetterBlockAsm12B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm12B + +two_bytes_emit_remainder_encodeSnappyBetterBlockAsm12B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeSnappyBetterBlockAsm12B + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm12B + +one_byte_emit_remainder_encodeSnappyBetterBlockAsm12B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeSnappyBetterBlockAsm12B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm12B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm12B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm12B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm12B + +memmove_long_emit_remainder_encodeSnappyBetterBlockAsm12B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeSnappyBetterBlockAsm12Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeSnappyBetterBlockAsm12Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm12B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeSnappyBetterBlockAsm10B(dst []byte, src []byte, tmp *[20480]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeSnappyBetterBlockAsm10B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x000000a0, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeSnappyBetterBlockAsm10B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeSnappyBetterBlockAsm10B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVD $0x00000000, R16 + MOVW R16, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeSnappyBetterBlockAsm10B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x05, R5, R5 + ADD R5, R2, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeSnappyBetterBlockAsm10B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD $0x9e3779b1, R5 + MOVD R6, R9 + MOVD R6, R10 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x34, R9, R9 + LSL $0x20, R10, R10 + MUL R5, R10, R10 + LSR $0x36, R10, R10 + MOVWU (R0)(R9<<2), R5 + ADD R10<<2, R0, R15 + MOVWU 16384(R15), R7 + MOVW R2, (R0)(R9<<2) + ADD R10<<2, R0, R15 + MOVW R2, 16384(R15) + MOVD (R3)(R5), R9 + MOVD (R3)(R7), R10 + CMP R6, R9 + BEQ candidate_match_encodeSnappyBetterBlockAsm10B + CMP R6, R10 + BNE no_short_found_encodeSnappyBetterBlockAsm10B + MOVWU R7, R5 + JMP candidate_match_encodeSnappyBetterBlockAsm10B + +no_short_found_encodeSnappyBetterBlockAsm10B: + CMPW R6, R9 + BEQ candidate_match_encodeSnappyBetterBlockAsm10B + CMPW R6, R10 + BEQ candidateS_match_encodeSnappyBetterBlockAsm10B + MOVWU 28(RSP), R2 + JMP search_loop_encodeSnappyBetterBlockAsm10B + +candidateS_match_encodeSnappyBetterBlockAsm10B: + LSR $0x08, R6, R6 + MOVD R6, R9 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x34, R9, R9 + MOVWU (R0)(R9<<2), R5 + ADDW $1, R2, R2 + MOVW R2, (R0)(R9<<2) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeSnappyBetterBlockAsm10B + SUBW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeSnappyBetterBlockAsm10B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeSnappyBetterBlockAsm10B + +match_extend_back_loop_encodeSnappyBetterBlockAsm10B: + CMPW R6, R2 + BLS match_extend_back_end_encodeSnappyBetterBlockAsm10B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeSnappyBetterBlockAsm10B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeSnappyBetterBlockAsm10B + JMP match_extend_back_loop_encodeSnappyBetterBlockAsm10B + +match_extend_back_end_encodeSnappyBetterBlockAsm10B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeSnappyBetterBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeSnappyBetterBlockAsm10B: + MOVWU R2, R6 + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R9 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm10B: + CMPW $0x10, R7 + BLO matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm10B + MOVD (R8)(R11), R10 + ADD R11, R8, R15 + MOVD 8(R15), R12 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm10B + ADD R11, R9, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm10B + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm10B + +matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm10B: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeSnappyBetterBlockAsm10B + +matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm10B: + CMPW $0x08, R7 + BLO matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm10B + MOVD (R8)(R11), R10 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm10B + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm10B + +matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm10B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeSnappyBetterBlockAsm10B + +matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm10B: + CMPW $0x04, R7 + BLO matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm10B + MOVWU (R8)(R11), R10 + MOVWU (R9)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm10B + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm10B: + CMPW $0x01, R7 + BEQ matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm10B + BLO match_nolit_end_encodeSnappyBetterBlockAsm10B + MOVHU (R8)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R9, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm10B + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R7, R7 + BEQ match_nolit_end_encodeSnappyBetterBlockAsm10B + +matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm10B: + MOVBU (R8)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R9, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE match_nolit_end_encodeSnappyBetterBlockAsm10B + ADD $1, R11, R11 + MOVWU R11, R11 + +match_nolit_end_encodeSnappyBetterBlockAsm10B: + MOVWU R2, R7 + SUBW R5, R7, R7 + + // Check if repeat + MOVW R7, 24(RSP) + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_encodeSnappyBetterBlockAsm10B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_encodeSnappyBetterBlockAsm10B + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_encodeSnappyBetterBlockAsm10B + BLO three_bytes_match_emit_encodeSnappyBetterBlockAsm10B + +three_bytes_match_emit_encodeSnappyBetterBlockAsm10B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm10B + +two_bytes_match_emit_encodeSnappyBetterBlockAsm10B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_encodeSnappyBetterBlockAsm10B + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm10B + +one_byte_match_emit_encodeSnappyBetterBlockAsm10B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeSnappyBetterBlockAsm10B: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm10B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm10B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm10B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm10B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm10B_memmove_move_8: + MOVD (R9), R10 + MOVD R10, (R1) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm10B + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm10B_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm10B + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm10B_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm10B + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm10B_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm10B: + MOVD R5, R1 + JMP emit_literal_done_match_emit_encodeSnappyBetterBlockAsm10B + +memmove_long_match_emit_encodeSnappyBetterBlockAsm10B: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_encodeSnappyBetterBlockAsm10Blarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_encodeSnappyBetterBlockAsm10Blarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_encodeSnappyBetterBlockAsm10B: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitCopy +two_byte_offset_match_nolit_encodeSnappyBetterBlockAsm10B: + CMPW $0x40, R11 + BLS two_byte_offset_short_match_nolit_encodeSnappyBetterBlockAsm10B + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + SUB $60, R11, R11 + MOVWU R11, R11 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_encodeSnappyBetterBlockAsm10B + +two_byte_offset_short_match_nolit_encodeSnappyBetterBlockAsm10B: + MOVWU R11, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R11 + BHS emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm10B + CMPW $0x00000800, R7 + BHS emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm10B + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm10B + +emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm10B: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm10B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeSnappyBetterBlockAsm10B + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeSnappyBetterBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeSnappyBetterBlockAsm10B: + MOVD $0x0000cf1bbcdcbf9b, R5 + MOVD $0x9e3779b1, R7 + ADD $1, R6, R6 + SUB $2, R2, R8 + MOVD (R3)(R6), R9 + ADD R6, R3, R15 + MOVD 1(R15), R10 + MOVD (R3)(R8), R11 + ADD R8, R3, R15 + MOVD 1(R15), R12 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x34, R9, R9 + LSL $0x20, R10, R10 + MUL R7, R10, R10 + LSR $0x36, R10, R10 + LSL $0x10, R11, R11 + MUL R5, R11, R11 + LSR $0x34, R11, R11 + LSL $0x20, R12, R12 + MUL R7, R12, R12 + LSR $0x36, R12, R12 + ADD $1, R6, R7 + ADD $1, R8, R13 + MOVW R6, (R0)(R9<<2) + MOVW R8, (R0)(R11<<2) + ADD R10<<2, R0, R15 + MOVW R7, 16384(R15) + ADD R12<<2, R0, R15 + MOVW R13, 16384(R15) + ADD R6, R8, R7 + ADD $1, R7, R7 + LSR $0x01, R7, R7 + ADD $0x01, R6, R6 + SUB $0x01, R8, R8 + +index_loop_encodeSnappyBetterBlockAsm10B: + CMP R8, R7 + BHS search_loop_encodeSnappyBetterBlockAsm10B + MOVD (R3)(R6), R9 + MOVD (R3)(R7), R10 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x34, R9, R9 + LSL $0x10, R10, R10 + MUL R5, R10, R10 + LSR $0x34, R10, R10 + MOVW R6, (R0)(R9<<2) + MOVW R7, (R0)(R10<<2) + ADD $0x02, R6, R6 + ADD $0x02, R7, R7 + JMP index_loop_encodeSnappyBetterBlockAsm10B + +emit_remainder_encodeSnappyBetterBlockAsm10B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeSnappyBetterBlockAsm10B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeSnappyBetterBlockAsm10B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm10B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeSnappyBetterBlockAsm10B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeSnappyBetterBlockAsm10B + BLO three_bytes_emit_remainder_encodeSnappyBetterBlockAsm10B + +three_bytes_emit_remainder_encodeSnappyBetterBlockAsm10B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm10B + +two_bytes_emit_remainder_encodeSnappyBetterBlockAsm10B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeSnappyBetterBlockAsm10B + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm10B + +one_byte_emit_remainder_encodeSnappyBetterBlockAsm10B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeSnappyBetterBlockAsm10B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm10B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm10B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm10B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm10B + +memmove_long_emit_remainder_encodeSnappyBetterBlockAsm10B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeSnappyBetterBlockAsm10Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeSnappyBetterBlockAsm10Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm10B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func encodeSnappyBetterBlockAsm8B(dst []byte, src []byte, tmp *[5120]byte) int +// Requires: BMI, SSE2 +TEXT ·encodeSnappyBetterBlockAsm8B(SB), $24-64 + MOVD tmp+48(FP), R0 + MOVD dst_base+0(FP), R1 + MOVD $0x00000028, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_encodeSnappyBetterBlockAsm8B: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_encodeSnappyBetterBlockAsm8B + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+32(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVD $0x00000000, R16 + MOVW R16, 24(RSP) + MOVD src_base+24(FP), R3 + +search_loop_encodeSnappyBetterBlockAsm8B: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x04, R5, R5 + ADD R5, R2, R5 + ADD $1, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_encodeSnappyBetterBlockAsm8B + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD $0x9e3779b1, R5 + MOVD R6, R9 + MOVD R6, R10 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x36, R9, R9 + LSL $0x20, R10, R10 + MUL R5, R10, R10 + LSR $0x38, R10, R10 + MOVWU (R0)(R9<<2), R5 + ADD R10<<2, R0, R15 + MOVWU 4096(R15), R7 + MOVW R2, (R0)(R9<<2) + ADD R10<<2, R0, R15 + MOVW R2, 4096(R15) + MOVD (R3)(R5), R9 + MOVD (R3)(R7), R10 + CMP R6, R9 + BEQ candidate_match_encodeSnappyBetterBlockAsm8B + CMP R6, R10 + BNE no_short_found_encodeSnappyBetterBlockAsm8B + MOVWU R7, R5 + JMP candidate_match_encodeSnappyBetterBlockAsm8B + +no_short_found_encodeSnappyBetterBlockAsm8B: + CMPW R6, R9 + BEQ candidate_match_encodeSnappyBetterBlockAsm8B + CMPW R6, R10 + BEQ candidateS_match_encodeSnappyBetterBlockAsm8B + MOVWU 28(RSP), R2 + JMP search_loop_encodeSnappyBetterBlockAsm8B + +candidateS_match_encodeSnappyBetterBlockAsm8B: + LSR $0x08, R6, R6 + MOVD R6, R9 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x36, R9, R9 + MOVWU (R0)(R9<<2), R5 + ADDW $1, R2, R2 + MOVW R2, (R0)(R9<<2) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_encodeSnappyBetterBlockAsm8B + SUBW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_encodeSnappyBetterBlockAsm8B: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_encodeSnappyBetterBlockAsm8B + +match_extend_back_loop_encodeSnappyBetterBlockAsm8B: + CMPW R6, R2 + BLS match_extend_back_end_encodeSnappyBetterBlockAsm8B + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_encodeSnappyBetterBlockAsm8B + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_encodeSnappyBetterBlockAsm8B + JMP match_extend_back_loop_encodeSnappyBetterBlockAsm8B + +match_extend_back_end_encodeSnappyBetterBlockAsm8B: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_encodeSnappyBetterBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_dst_size_check_encodeSnappyBetterBlockAsm8B: + MOVWU R2, R6 + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+32(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R9 + + // matchLen + MOVD $0, R11 + +matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm8B: + CMPW $0x10, R7 + BLO matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm8B + MOVD (R8)(R11), R10 + ADD R11, R8, R15 + MOVD 8(R15), R12 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm8B + ADD R11, R9, R15 + MOVD 8(R15), R16 + EOR R16, R12, R12 + TST R12, R12 + BNE matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm8B + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R11, R11 + MOVWU R11, R11 + JMP matchlen_loopback_16_match_nolit_encodeSnappyBetterBlockAsm8B + +matchlen_bsf_16match_nolit_encodeSnappyBetterBlockAsm8B: + RBIT R12, R12 + CLZ R12, R12 + ASR $0x03, R12, R12 + ADD R12, R11, R11 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeSnappyBetterBlockAsm8B + +matchlen_match8_match_nolit_encodeSnappyBetterBlockAsm8B: + CMPW $0x08, R7 + BLO matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm8B + MOVD (R8)(R11), R10 + MOVD (R9)(R11), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm8B + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R11, R11 + MOVWU R11, R11 + JMP matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm8B + +matchlen_bsf_8_match_nolit_encodeSnappyBetterBlockAsm8B: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R11, R11 + MOVWU R11, R11 + JMP match_nolit_end_encodeSnappyBetterBlockAsm8B + +matchlen_match4_match_nolit_encodeSnappyBetterBlockAsm8B: + CMPW $0x04, R7 + BLO matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm8B + MOVWU (R8)(R11), R10 + MOVWU (R9)(R11), R16 + CMPW R10, R16 + BNE matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm8B + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R11, R11 + MOVWU R11, R11 + +matchlen_match2_match_nolit_encodeSnappyBetterBlockAsm8B: + CMPW $0x01, R7 + BEQ matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm8B + BLO match_nolit_end_encodeSnappyBetterBlockAsm8B + MOVHU (R8)(R11), R16 + BFI $0, R16, $16, R10 + ADD R11, R9, R15 + MOVHU (R15), R15 + AND $0xffff, R10, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm8B + ADD $2, R11, R11 + MOVWU R11, R11 + SUBSW $0x02, R7, R7 + BEQ match_nolit_end_encodeSnappyBetterBlockAsm8B + +matchlen_match1_match_nolit_encodeSnappyBetterBlockAsm8B: + MOVBU (R8)(R11), R16 + BFI $0, R16, $8, R10 + ADD R11, R9, R15 + MOVBU (R15), R15 + AND $0xff, R10, R16 + CMP R16, R15 + BNE match_nolit_end_encodeSnappyBetterBlockAsm8B + ADD $1, R11, R11 + MOVWU R11, R11 + +match_nolit_end_encodeSnappyBetterBlockAsm8B: + MOVWU R2, R7 + SUBW R5, R7, R7 + + // Check if repeat + MOVW R7, 24(RSP) + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_match_emit_encodeSnappyBetterBlockAsm8B + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R5, R3, R9 + SUBW R5, R8, R8 + SUB $1, R8, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_match_emit_encodeSnappyBetterBlockAsm8B + CMPW $0x00000100, R5 + BLO two_bytes_match_emit_encodeSnappyBetterBlockAsm8B + BLO three_bytes_match_emit_encodeSnappyBetterBlockAsm8B + +three_bytes_match_emit_encodeSnappyBetterBlockAsm8B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R5, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm8B + +two_bytes_match_emit_encodeSnappyBetterBlockAsm8B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R5, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_match_emit_encodeSnappyBetterBlockAsm8B + JMP memmove_long_match_emit_encodeSnappyBetterBlockAsm8B + +one_byte_match_emit_encodeSnappyBetterBlockAsm8B: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R1) + ADD $0x01, R1, R1 + +memmove_match_emit_encodeSnappyBetterBlockAsm8B: + ADD R8, R1, R5 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm8B_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm8B_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm8B_memmove_move_17through32 + JMP emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm8B_memmove_move_33through64 + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm8B_memmove_move_8: + MOVD (R9), R10 + MOVD R10, (R1) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm8B + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm8B_memmove_move_8through16: + MOVD (R9), R10 + ADD R8, R9, R15 + MOVD -8(R15), R9 + MOVD R10, (R1) + ADD R8, R1, R15 + MOVD R9, -8(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm8B + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm8B_memmove_move_17through32: + FMOVQ (R9), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm8B + +emit_lit_memmove_match_emit_encodeSnappyBetterBlockAsm8B_memmove_move_33through64: + FMOVQ (R9), F0 + FMOVQ 16(R9), F1 + ADD R8, R9, R15 + FMOVQ -32(R15), F2 + ADD R8, R9, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R8, R1, R15 + FMOVQ F2, -32(R15) + ADD R8, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_match_emit_encodeSnappyBetterBlockAsm8B: + MOVD R5, R1 + JMP emit_literal_done_match_emit_encodeSnappyBetterBlockAsm8B + +memmove_long_match_emit_encodeSnappyBetterBlockAsm8B: + ADD R8, R1, R5 + + // genMemMoveLong + MOVD R9, R10 + MOVD R1, R12 + MOVD R8, R13 + +emit_lit_memmove_long_match_emit_encodeSnappyBetterBlockAsm8Blarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R10, R10 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_match_emit_encodeSnappyBetterBlockAsm8Blarge_big_loop_back + ADD R8, R9, R15 + FMOVQ -32(R15), F0 + ADD R8, R9, R15 + FMOVQ -16(R15), F1 + ADD R8, R1, R15 + FMOVQ F0, -32(R15) + ADD R8, R1, R15 + FMOVQ F1, -16(R15) + MOVD R5, R1 + +emit_literal_done_match_emit_encodeSnappyBetterBlockAsm8B: + ADDW R11, R2, R2 + ADDW $0x04, R11, R11 + MOVW R2, 20(RSP) + + // emitCopy +two_byte_offset_match_nolit_encodeSnappyBetterBlockAsm8B: + CMPW $0x40, R11 + BLS two_byte_offset_short_match_nolit_encodeSnappyBetterBlockAsm8B + MOVD $0xee, R16 + MOVB R16, (R1) + MOVH R7, 1(R1) + SUB $60, R11, R11 + MOVWU R11, R11 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_encodeSnappyBetterBlockAsm8B + +two_byte_offset_short_match_nolit_encodeSnappyBetterBlockAsm8B: + MOVWU R11, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R11 + BHS emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm8B + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R7, 1(R1) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R5, R5 + MOVB R5, (R1) + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm8B + +emit_copy_three_match_nolit_encodeSnappyBetterBlockAsm8B: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R1) + MOVH R7, 1(R1) + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_encodeSnappyBetterBlockAsm8B: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_encodeSnappyBetterBlockAsm8B + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_encodeSnappyBetterBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +match_nolit_dst_ok_encodeSnappyBetterBlockAsm8B: + MOVD $0x0000cf1bbcdcbf9b, R5 + MOVD $0x9e3779b1, R7 + ADD $1, R6, R6 + SUB $2, R2, R8 + MOVD (R3)(R6), R9 + ADD R6, R3, R15 + MOVD 1(R15), R10 + MOVD (R3)(R8), R11 + ADD R8, R3, R15 + MOVD 1(R15), R12 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x36, R9, R9 + LSL $0x20, R10, R10 + MUL R7, R10, R10 + LSR $0x38, R10, R10 + LSL $0x10, R11, R11 + MUL R5, R11, R11 + LSR $0x36, R11, R11 + LSL $0x20, R12, R12 + MUL R7, R12, R12 + LSR $0x38, R12, R12 + ADD $1, R6, R7 + ADD $1, R8, R13 + MOVW R6, (R0)(R9<<2) + MOVW R8, (R0)(R11<<2) + ADD R10<<2, R0, R15 + MOVW R7, 4096(R15) + ADD R12<<2, R0, R15 + MOVW R13, 4096(R15) + ADD R6, R8, R7 + ADD $1, R7, R7 + LSR $0x01, R7, R7 + ADD $0x01, R6, R6 + SUB $0x01, R8, R8 + +index_loop_encodeSnappyBetterBlockAsm8B: + CMP R8, R7 + BHS search_loop_encodeSnappyBetterBlockAsm8B + MOVD (R3)(R6), R9 + MOVD (R3)(R7), R10 + LSL $0x10, R9, R9 + MUL R5, R9, R9 + LSR $0x36, R9, R9 + LSL $0x10, R10, R10 + MUL R5, R10, R10 + LSR $0x36, R10, R10 + MOVW R6, (R0)(R9<<2) + MOVW R7, (R0)(R10<<2) + ADD $0x02, R6, R6 + ADD $0x02, R7, R7 + JMP index_loop_encodeSnappyBetterBlockAsm8B + +emit_remainder_encodeSnappyBetterBlockAsm8B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_encodeSnappyBetterBlockAsm8B + MOVD $0x00000000, R16 + MOVD R16, ret+56(FP) + RET + +emit_remainder_ok_encodeSnappyBetterBlockAsm8B: + MOVD src_len+32(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm8B + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R2 + MOVWU R2, R2 + CMPW $0x3c, R2 + BLO one_byte_emit_remainder_encodeSnappyBetterBlockAsm8B + CMPW $0x00000100, R2 + BLO two_bytes_emit_remainder_encodeSnappyBetterBlockAsm8B + BLO three_bytes_emit_remainder_encodeSnappyBetterBlockAsm8B + +three_bytes_emit_remainder_encodeSnappyBetterBlockAsm8B: + MOVD $0xf4, R16 + MOVB R16, (R1) + MOVH R2, 1(R1) + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm8B + +two_bytes_emit_remainder_encodeSnappyBetterBlockAsm8B: + MOVD $0xf0, R16 + MOVB R16, (R1) + MOVB R2, 1(R1) + ADD $0x02, R1, R1 + CMPW $0x40, R2 + BLO memmove_emit_remainder_encodeSnappyBetterBlockAsm8B + JMP memmove_long_emit_remainder_encodeSnappyBetterBlockAsm8B + +one_byte_emit_remainder_encodeSnappyBetterBlockAsm8B: + LSLW $0x02, R2, R16 + BFI $0, R16, $8, R2 + MOVB R2, (R1) + ADD $0x01, R1, R1 + +memmove_emit_remainder_encodeSnappyBetterBlockAsm8B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveShort + CMP $0x03, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_1or2 + BEQ emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_3 + CMP $0x08, R3 + BLO emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_4through7 + CMP $0x10, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_8through16 + CMP $0x20, R3 + BLS emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_17through32 + JMP emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_33through64 + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R5 + ADD R3, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R0 + MOVB R5, (R1) + ADD R3, R1, R15 + MOVB R0, -1(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_3: + MOVHU (R0), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R0 + MOVH R5, (R1) + MOVB R0, 2(R1) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_4through7: + MOVWU (R0), R5 + ADD R3, R0, R15 + MOVWU -4(R15), R0 + MOVW R5, (R1) + ADD R3, R1, R15 + MOVW R0, -4(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_8through16: + MOVD (R0), R5 + ADD R3, R0, R15 + MOVD -8(R15), R0 + MOVD R5, (R1) + ADD R3, R1, R15 + MOVD R0, -8(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_17through32: + FMOVQ (R0), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R1) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm8B + +emit_lit_memmove_emit_remainder_encodeSnappyBetterBlockAsm8B_memmove_move_33through64: + FMOVQ (R0), F0 + FMOVQ 16(R0), F1 + ADD R3, R0, R15 + FMOVQ -32(R15), F2 + ADD R3, R0, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R1) + FMOVQ F1, 16(R1) + ADD R3, R1, R15 + FMOVQ F2, -32(R15) + ADD R3, R1, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_emit_remainder_encodeSnappyBetterBlockAsm8B: + MOVD R2, R1 + JMP emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm8B + +memmove_long_emit_remainder_encodeSnappyBetterBlockAsm8B: + ADD R5, R1, R2 + MOVWU R5, R3 + + // genMemMoveLong + MOVD R0, R5 + MOVD R1, R6 + MOVD R3, R7 + +emit_lit_memmove_long_emit_remainder_encodeSnappyBetterBlockAsm8Blarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_emit_remainder_encodeSnappyBetterBlockAsm8Blarge_big_loop_back + ADD R3, R0, R15 + FMOVQ -32(R15), F0 + ADD R3, R0, R15 + FMOVQ -16(R15), F1 + ADD R3, R1, R15 + FMOVQ F0, -32(R15) + ADD R3, R1, R15 + FMOVQ F1, -16(R15) + MOVD R2, R1 + +emit_literal_done_emit_remainder_encodeSnappyBetterBlockAsm8B: + MOVD dst_base+0(FP), R0 + SUB R0, R1, R1 + MOVD R1, ret+56(FP) + RET + +// func calcBlockSize(src []byte, tmp *[32768]byte) int +// Requires: BMI, SSE2 +TEXT ·calcBlockSize(SB), $24-40 + MOVD tmp+24(FP), R0 + MOVD $0, R1 + MOVD $0x00000100, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_calcBlockSize: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_calcBlockSize + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+8(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+0(FP), R3 + +search_loop_calcBlockSize: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x05, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_calcBlockSize + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x33, R9, R9 + LSL $0x10, R10, R10 + MUL R8, R10, R10 + LSR $0x33, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x10, R9, R9 + MUL R8, R9, R9 + LSR $0x33, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_calcBlockSize + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R5 + MOVWU R6, R7 + MOVWU 24(RSP), R16 + SUBSW R16, R7, R7 + BEQ repeat_extend_back_end_calcBlockSize + +repeat_extend_back_loop_calcBlockSize: + CMPW R5, R6 + BLS repeat_extend_back_end_calcBlockSize + ADD R7, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_calcBlockSize + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R7, R7 + BNE repeat_extend_back_loop_calcBlockSize + +repeat_extend_back_end_calcBlockSize: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $5, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_calcBlockSize + MOVD $0x00000000, R16 + MOVD R16, ret+32(FP) + RET + +repeat_dst_size_check_calcBlockSize: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_calcBlockSize + MOVWU R6, R7 + MOVW R6, 20(RSP) + ADD R5, R3, R8 + SUBW R5, R7, R7 + SUB $1, R7, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_calcBlockSize + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_calcBlockSize + CMPW $0x00010000, R5 + BLO three_bytes_repeat_emit_calcBlockSize + CMPW $0x01000000, R5 + BLO four_bytes_repeat_emit_calcBlockSize + ADD $0x05, R1, R1 + JMP memmove_long_repeat_emit_calcBlockSize + +four_bytes_repeat_emit_calcBlockSize: + ADD $0x04, R1, R1 + JMP memmove_long_repeat_emit_calcBlockSize + +three_bytes_repeat_emit_calcBlockSize: + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_calcBlockSize + +two_bytes_repeat_emit_calcBlockSize: + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_calcBlockSize + JMP memmove_long_repeat_emit_calcBlockSize + +one_byte_repeat_emit_calcBlockSize: + ADD $0x01, R1, R1 + +memmove_repeat_emit_calcBlockSize: + ADD R7, R1, R1 + JMP emit_literal_done_repeat_emit_calcBlockSize + +memmove_long_repeat_emit_calcBlockSize: + ADD R7, R1, R1 + +emit_literal_done_repeat_emit_calcBlockSize: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+8(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R10 + +matchlen_loopback_16_repeat_extend_calcBlockSize: + CMPW $0x10, R7 + BLO matchlen_match8_repeat_extend_calcBlockSize + MOVD (R8)(R10), R9 + ADD R10, R8, R15 + MOVD 8(R15), R11 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_calcBlockSize + ADD R10, R5, R15 + MOVD 8(R15), R16 + EOR R16, R11, R11 + TST R11, R11 + BNE matchlen_bsf_16repeat_extend_calcBlockSize + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R10, R10 + MOVWU R10, R10 + JMP matchlen_loopback_16_repeat_extend_calcBlockSize + +matchlen_bsf_16repeat_extend_calcBlockSize: + RBIT R11, R11 + CLZ R11, R11 + ASR $0x03, R11, R11 + ADD R11, R10, R10 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_calcBlockSize + +matchlen_match8_repeat_extend_calcBlockSize: + CMPW $0x08, R7 + BLO matchlen_match4_repeat_extend_calcBlockSize + MOVD (R8)(R10), R9 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_calcBlockSize + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP matchlen_match4_repeat_extend_calcBlockSize + +matchlen_bsf_8_repeat_extend_calcBlockSize: + RBIT R9, R9 + CLZ R9, R9 + ASR $0x03, R9, R9 + ADD R9, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_calcBlockSize + +matchlen_match4_repeat_extend_calcBlockSize: + CMPW $0x04, R7 + BLO matchlen_match2_repeat_extend_calcBlockSize + MOVWU (R8)(R10), R9 + MOVWU (R5)(R10), R16 + CMPW R9, R16 + BNE matchlen_match2_repeat_extend_calcBlockSize + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R10, R10 + MOVWU R10, R10 + +matchlen_match2_repeat_extend_calcBlockSize: + CMPW $0x01, R7 + BEQ matchlen_match1_repeat_extend_calcBlockSize + BLO repeat_extend_forward_end_calcBlockSize + MOVHU (R8)(R10), R16 + BFI $0, R16, $16, R9 + ADD R10, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R9, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_calcBlockSize + ADD $2, R10, R10 + MOVWU R10, R10 + SUBSW $0x02, R7, R7 + BEQ repeat_extend_forward_end_calcBlockSize + +matchlen_match1_repeat_extend_calcBlockSize: + MOVBU (R8)(R10), R16 + BFI $0, R16, $8, R9 + ADD R10, R5, R15 + MOVBU (R15), R15 + AND $0xff, R9, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_calcBlockSize + ADD $1, R10, R10 + MOVWU R10, R10 + +repeat_extend_forward_end_calcBlockSize: + ADDW R10, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + + // emitCopy + CMPW $0x00010000, R6 + BLO two_byte_offset_repeat_as_copy_calcBlockSize + +four_bytes_loop_back_repeat_as_copy_calcBlockSize: + CMPW $0x40, R5 + BLS four_bytes_remain_repeat_as_copy_calcBlockSize + SUB $64, R5, R5 + MOVWU R5, R5 + ADD $0x05, R1, R1 + CMPW $0x04, R5 + BLO four_bytes_remain_repeat_as_copy_calcBlockSize + JMP four_bytes_loop_back_repeat_as_copy_calcBlockSize + +four_bytes_remain_repeat_as_copy_calcBlockSize: + TSTW R5, R5 + BEQ repeat_end_emit_calcBlockSize + MOVD $0, R5 + ADD $0x05, R1, R1 + JMP repeat_end_emit_calcBlockSize + +two_byte_offset_repeat_as_copy_calcBlockSize: + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_calcBlockSize + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + JMP two_byte_offset_repeat_as_copy_calcBlockSize + +two_byte_offset_short_repeat_as_copy_calcBlockSize: + MOVWU R5, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_calcBlockSize + CMPW $0x00000800, R6 + BHS emit_copy_three_repeat_as_copy_calcBlockSize + ADD $0x02, R1, R1 + JMP repeat_end_emit_calcBlockSize + +emit_copy_three_repeat_as_copy_calcBlockSize: + ADD $0x03, R1, R1 + +repeat_end_emit_calcBlockSize: + MOVW R2, 20(RSP) + JMP search_loop_calcBlockSize + +no_repeat_found_calcBlockSize: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_calcBlockSize + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_calcBlockSize + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_calcBlockSize + MOVWU 28(RSP), R2 + JMP search_loop_calcBlockSize + +candidate3_match_calcBlockSize: + ADDW $0x02, R2, R2 + JMP candidate_match_calcBlockSize + +candidate2_match_calcBlockSize: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_calcBlockSize: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_calcBlockSize + +match_extend_back_loop_calcBlockSize: + CMPW R6, R2 + BLS match_extend_back_end_calcBlockSize + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_calcBlockSize + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_calcBlockSize + JMP match_extend_back_loop_calcBlockSize + +match_extend_back_end_calcBlockSize: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $5, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_calcBlockSize + MOVD $0x00000000, R16 + MOVD R16, ret+32(FP) + RET + +match_dst_size_check_calcBlockSize: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_calcBlockSize + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R6 + MOVWU R6, R6 + CMPW $0x3c, R6 + BLO one_byte_match_emit_calcBlockSize + CMPW $0x00000100, R6 + BLO two_bytes_match_emit_calcBlockSize + CMPW $0x00010000, R6 + BLO three_bytes_match_emit_calcBlockSize + CMPW $0x01000000, R6 + BLO four_bytes_match_emit_calcBlockSize + ADD $0x05, R1, R1 + JMP memmove_long_match_emit_calcBlockSize + +four_bytes_match_emit_calcBlockSize: + ADD $0x04, R1, R1 + JMP memmove_long_match_emit_calcBlockSize + +three_bytes_match_emit_calcBlockSize: + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_calcBlockSize + +two_bytes_match_emit_calcBlockSize: + ADD $0x02, R1, R1 + CMPW $0x40, R6 + BLO memmove_match_emit_calcBlockSize + JMP memmove_long_match_emit_calcBlockSize + +one_byte_match_emit_calcBlockSize: + ADD $0x01, R1, R1 + +memmove_match_emit_calcBlockSize: + ADD R8, R1, R1 + JMP emit_literal_done_match_emit_calcBlockSize + +memmove_long_match_emit_calcBlockSize: + ADD R8, R1, R1 + +emit_literal_done_match_emit_calcBlockSize: +match_nolit_loop_calcBlockSize: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+8(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_calcBlockSize: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_calcBlockSize + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_calcBlockSize + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_calcBlockSize + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_calcBlockSize + +matchlen_bsf_16match_nolit_calcBlockSize: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_calcBlockSize + +matchlen_match8_match_nolit_calcBlockSize: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_calcBlockSize + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_calcBlockSize + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_calcBlockSize + +matchlen_bsf_8_match_nolit_calcBlockSize: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_calcBlockSize + +matchlen_match4_match_nolit_calcBlockSize: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_calcBlockSize + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_calcBlockSize + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_calcBlockSize: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_calcBlockSize + BLO match_nolit_end_calcBlockSize + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_calcBlockSize + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_calcBlockSize + +matchlen_match1_match_nolit_calcBlockSize: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_calcBlockSize + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_calcBlockSize: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy + CMPW $0x00010000, R5 + BLO two_byte_offset_match_nolit_calcBlockSize + +four_bytes_loop_back_match_nolit_calcBlockSize: + CMPW $0x40, R9 + BLS four_bytes_remain_match_nolit_calcBlockSize + SUB $64, R9, R9 + MOVWU R9, R9 + ADD $0x05, R1, R1 + CMPW $0x04, R9 + BLO four_bytes_remain_match_nolit_calcBlockSize + JMP four_bytes_loop_back_match_nolit_calcBlockSize + +four_bytes_remain_match_nolit_calcBlockSize: + TSTW R9, R9 + BEQ match_nolit_emitcopy_end_calcBlockSize + MOVD $0, R5 + ADD $0x05, R1, R1 + JMP match_nolit_emitcopy_end_calcBlockSize + +two_byte_offset_match_nolit_calcBlockSize: + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_calcBlockSize + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_calcBlockSize + +two_byte_offset_short_match_nolit_calcBlockSize: + MOVWU R9, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_calcBlockSize + CMPW $0x00000800, R5 + BHS emit_copy_three_match_nolit_calcBlockSize + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_calcBlockSize + +emit_copy_three_match_nolit_calcBlockSize: + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_calcBlockSize: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_calcBlockSize + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_calcBlockSize + MOVD $0x00000000, R16 + MOVD R16, ret+32(FP) + RET + +match_nolit_dst_ok_calcBlockSize: + MOVD $0x0000cf1bbcdcbf9b, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x10, R7, R7 + MUL R8, R7, R7 + LSR $0x33, R7, R7 + LSL $0x10, R5, R5 + MUL R8, R5, R5 + LSR $0x33, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_calcBlockSize + ADDW $1, R2, R2 + JMP search_loop_calcBlockSize + +emit_remainder_calcBlockSize: + MOVD src_len+8(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $5, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_calcBlockSize + MOVD $0x00000000, R16 + MOVD R16, ret+32(FP) + RET + +emit_remainder_ok_calcBlockSize: + MOVD src_len+8(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_calcBlockSize + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R0 + MOVWU R0, R0 + CMPW $0x3c, R0 + BLO one_byte_emit_remainder_calcBlockSize + CMPW $0x00000100, R0 + BLO two_bytes_emit_remainder_calcBlockSize + CMPW $0x00010000, R0 + BLO three_bytes_emit_remainder_calcBlockSize + CMPW $0x01000000, R0 + BLO four_bytes_emit_remainder_calcBlockSize + ADD $0x05, R1, R1 + JMP memmove_long_emit_remainder_calcBlockSize + +four_bytes_emit_remainder_calcBlockSize: + ADD $0x04, R1, R1 + JMP memmove_long_emit_remainder_calcBlockSize + +three_bytes_emit_remainder_calcBlockSize: + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_calcBlockSize + +two_bytes_emit_remainder_calcBlockSize: + ADD $0x02, R1, R1 + CMPW $0x40, R0 + BLO memmove_emit_remainder_calcBlockSize + JMP memmove_long_emit_remainder_calcBlockSize + +one_byte_emit_remainder_calcBlockSize: + ADD $0x01, R1, R1 + +memmove_emit_remainder_calcBlockSize: + ADD R5, R1, R0 + MOVD R0, R1 + JMP emit_literal_done_emit_remainder_calcBlockSize + +memmove_long_emit_remainder_calcBlockSize: + ADD R5, R1, R0 + MOVD R0, R1 + +emit_literal_done_emit_remainder_calcBlockSize: + MOVD R1, ret+32(FP) + RET + +// func calcBlockSizeSmall(src []byte, tmp *[2048]byte) int +// Requires: BMI, SSE2 +TEXT ·calcBlockSizeSmall(SB), $24-40 + MOVD tmp+24(FP), R0 + MOVD $0, R1 + MOVD $0x00000010, R2 + MOVD R0, R3 + VEOR V0.B16, V0.B16, V0.B16 + +zero_loop_calcBlockSizeSmall: + FMOVQ F0, (R3) + FMOVQ F0, 16(R3) + FMOVQ F0, 32(R3) + FMOVQ F0, 48(R3) + FMOVQ F0, 64(R3) + FMOVQ F0, 80(R3) + FMOVQ F0, 96(R3) + FMOVQ F0, 112(R3) + ADD $0x80, R3, R3 + SUBS $1, R2, R2 + BNE zero_loop_calcBlockSizeSmall + MOVD $0x00000000, R16 + MOVW R16, 20(RSP) + MOVD src_len+8(FP), R2 + SUB $9, R2, R3 + SUB $8, R2, R5 + MOVW R5, 16(RSP) + LSR $0x05, R2, R2 + SUBW R2, R3, R3 + ADD R3, R1, R3 + MOVD R3, 8(RSP) + MOVD $0x00000001, R2 + MOVW R2, 24(RSP) + MOVD src_base+0(FP), R3 + +search_loop_calcBlockSizeSmall: + MOVWU R2, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + LSRW $0x04, R5, R5 + ADD R5, R2, R5 + ADD $4, R5, R5 + MOVWU R5, R5 + MOVWU 16(RSP), R16 + CMPW R16, R5 + BHS emit_remainder_calcBlockSizeSmall + MOVD (R3)(R2), R6 + MOVW R5, 28(RSP) + MOVD $0x9e3779b1, R8 + MOVD R6, R9 + MOVD R6, R10 + LSR $0x08, R10, R10 + LSL $0x20, R9, R9 + MUL R8, R9, R9 + LSR $0x37, R9, R9 + LSL $0x20, R10, R10 + MUL R8, R10, R10 + LSR $0x37, R10, R10 + MOVWU (R0)(R9<<2), R5 + MOVWU (R0)(R10<<2), R7 + MOVW R2, (R0)(R9<<2) + ADD $1, R2, R9 + MOVWU R9, R9 + MOVW R9, (R0)(R10<<2) + MOVD R6, R9 + LSR $0x10, R9, R9 + LSL $0x20, R9, R9 + MUL R8, R9, R9 + LSR $0x37, R9, R9 + MOVWU R2, R8 + MOVWU 24(RSP), R16 + SUBW R16, R8, R8 + ADD R8, R3, R15 + MOVWU 1(R15), R10 + MOVD R6, R8 + LSR $0x08, R8, R8 + CMPW R10, R8 + BNE no_repeat_found_calcBlockSizeSmall + ADD $1, R2, R6 + MOVWU R6, R6 + MOVWU 20(RSP), R5 + MOVWU R6, R7 + MOVWU 24(RSP), R16 + SUBSW R16, R7, R7 + BEQ repeat_extend_back_end_calcBlockSizeSmall + +repeat_extend_back_loop_calcBlockSizeSmall: + CMPW R5, R6 + BLS repeat_extend_back_end_calcBlockSizeSmall + ADD R7, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + ADD R6, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R9 + AND $0xff, R9, R16 + AND $0xff, R8, R15 + CMP R16, R15 + BNE repeat_extend_back_end_calcBlockSizeSmall + SUB $1, R6, R6 + MOVWU R6, R6 + SUBSW $1, R7, R7 + BNE repeat_extend_back_loop_calcBlockSizeSmall + +repeat_extend_back_end_calcBlockSizeSmall: + MOVWU R6, R5 + MOVWU 20(RSP), R16 + SUBW R16, R5, R5 + ADD R5, R1, R5 + ADD $3, R5, R5 + MOVD 8(RSP), R16 + CMP R16, R5 + BLO repeat_dst_size_check_calcBlockSizeSmall + MOVD $0x00000000, R16 + MOVD R16, ret+32(FP) + RET + +repeat_dst_size_check_calcBlockSizeSmall: + MOVWU 20(RSP), R5 + CMPW R6, R5 + BEQ emit_literal_done_repeat_emit_calcBlockSizeSmall + MOVWU R6, R7 + MOVW R6, 20(RSP) + ADD R5, R3, R8 + SUBW R5, R7, R7 + SUB $1, R7, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_repeat_emit_calcBlockSizeSmall + CMPW $0x00000100, R5 + BLO two_bytes_repeat_emit_calcBlockSizeSmall + BLO three_bytes_repeat_emit_calcBlockSizeSmall + +three_bytes_repeat_emit_calcBlockSizeSmall: + ADD $0x03, R1, R1 + JMP memmove_long_repeat_emit_calcBlockSizeSmall + +two_bytes_repeat_emit_calcBlockSizeSmall: + ADD $0x02, R1, R1 + CMPW $0x40, R5 + BLO memmove_repeat_emit_calcBlockSizeSmall + JMP memmove_long_repeat_emit_calcBlockSizeSmall + +one_byte_repeat_emit_calcBlockSizeSmall: + ADD $0x01, R1, R1 + +memmove_repeat_emit_calcBlockSizeSmall: + ADD R7, R1, R1 + JMP emit_literal_done_repeat_emit_calcBlockSizeSmall + +memmove_long_repeat_emit_calcBlockSizeSmall: + ADD R7, R1, R1 + +emit_literal_done_repeat_emit_calcBlockSizeSmall: + ADDW $0x05, R2, R2 + MOVWU R2, R5 + MOVWU 24(RSP), R16 + SUBW R16, R5, R5 + MOVD src_len+8(FP), R7 + SUBW R2, R7, R7 + ADD R2, R3, R8 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R10 + +matchlen_loopback_16_repeat_extend_calcBlockSizeSmall: + CMPW $0x10, R7 + BLO matchlen_match8_repeat_extend_calcBlockSizeSmall + MOVD (R8)(R10), R9 + ADD R10, R8, R15 + MOVD 8(R15), R11 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_calcBlockSizeSmall + ADD R10, R5, R15 + MOVD 8(R15), R16 + EOR R16, R11, R11 + TST R11, R11 + BNE matchlen_bsf_16repeat_extend_calcBlockSizeSmall + SUB $16, R7, R7 + MOVWU R7, R7 + ADD $16, R10, R10 + MOVWU R10, R10 + JMP matchlen_loopback_16_repeat_extend_calcBlockSizeSmall + +matchlen_bsf_16repeat_extend_calcBlockSizeSmall: + RBIT R11, R11 + CLZ R11, R11 + ASR $0x03, R11, R11 + ADD R11, R10, R10 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_calcBlockSizeSmall + +matchlen_match8_repeat_extend_calcBlockSizeSmall: + CMPW $0x08, R7 + BLO matchlen_match4_repeat_extend_calcBlockSizeSmall + MOVD (R8)(R10), R9 + MOVD (R5)(R10), R16 + EOR R16, R9, R9 + TST R9, R9 + BNE matchlen_bsf_8_repeat_extend_calcBlockSizeSmall + SUB $8, R7, R7 + MOVWU R7, R7 + ADD $8, R10, R10 + MOVWU R10, R10 + JMP matchlen_match4_repeat_extend_calcBlockSizeSmall + +matchlen_bsf_8_repeat_extend_calcBlockSizeSmall: + RBIT R9, R9 + CLZ R9, R9 + ASR $0x03, R9, R9 + ADD R9, R10, R10 + MOVWU R10, R10 + JMP repeat_extend_forward_end_calcBlockSizeSmall + +matchlen_match4_repeat_extend_calcBlockSizeSmall: + CMPW $0x04, R7 + BLO matchlen_match2_repeat_extend_calcBlockSizeSmall + MOVWU (R8)(R10), R9 + MOVWU (R5)(R10), R16 + CMPW R9, R16 + BNE matchlen_match2_repeat_extend_calcBlockSizeSmall + SUB $4, R7, R7 + MOVWU R7, R7 + ADD $4, R10, R10 + MOVWU R10, R10 + +matchlen_match2_repeat_extend_calcBlockSizeSmall: + CMPW $0x01, R7 + BEQ matchlen_match1_repeat_extend_calcBlockSizeSmall + BLO repeat_extend_forward_end_calcBlockSizeSmall + MOVHU (R8)(R10), R16 + BFI $0, R16, $16, R9 + ADD R10, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R9, R16 + CMP R16, R15 + BNE matchlen_match1_repeat_extend_calcBlockSizeSmall + ADD $2, R10, R10 + MOVWU R10, R10 + SUBSW $0x02, R7, R7 + BEQ repeat_extend_forward_end_calcBlockSizeSmall + +matchlen_match1_repeat_extend_calcBlockSizeSmall: + MOVBU (R8)(R10), R16 + BFI $0, R16, $8, R9 + ADD R10, R5, R15 + MOVBU (R15), R15 + AND $0xff, R9, R16 + CMP R16, R15 + BNE repeat_extend_forward_end_calcBlockSizeSmall + ADD $1, R10, R10 + MOVWU R10, R10 + +repeat_extend_forward_end_calcBlockSizeSmall: + ADDW R10, R2, R2 + MOVWU R2, R5 + SUBW R6, R5, R5 + MOVWU 24(RSP), R6 + + // emitCopy +two_byte_offset_repeat_as_copy_calcBlockSizeSmall: + CMPW $0x40, R5 + BLS two_byte_offset_short_repeat_as_copy_calcBlockSizeSmall + SUB $60, R5, R5 + MOVWU R5, R5 + ADD $0x03, R1, R1 + JMP two_byte_offset_repeat_as_copy_calcBlockSizeSmall + +two_byte_offset_short_repeat_as_copy_calcBlockSizeSmall: + MOVWU R5, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R5 + BHS emit_copy_three_repeat_as_copy_calcBlockSizeSmall + ADD $0x02, R1, R1 + JMP repeat_end_emit_calcBlockSizeSmall + +emit_copy_three_repeat_as_copy_calcBlockSizeSmall: + ADD $0x03, R1, R1 + +repeat_end_emit_calcBlockSizeSmall: + MOVW R2, 20(RSP) + JMP search_loop_calcBlockSizeSmall + +no_repeat_found_calcBlockSizeSmall: + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate_match_calcBlockSizeSmall + LSR $0x08, R6, R6 + MOVWU (R0)(R9<<2), R5 + ADD $2, R2, R8 + MOVWU R8, R8 + MOVWU (R3)(R7), R16 + CMPW R6, R16 + BEQ candidate2_match_calcBlockSizeSmall + MOVW R8, (R0)(R9<<2) + LSR $0x08, R6, R6 + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ candidate3_match_calcBlockSizeSmall + MOVWU 28(RSP), R2 + JMP search_loop_calcBlockSizeSmall + +candidate3_match_calcBlockSizeSmall: + ADDW $0x02, R2, R2 + JMP candidate_match_calcBlockSizeSmall + +candidate2_match_calcBlockSizeSmall: + MOVW R8, (R0)(R9<<2) + ADDW $1, R2, R2 + MOVWU R7, R5 + +candidate_match_calcBlockSizeSmall: + MOVWU 20(RSP), R6 + TSTW R5, R5 + BEQ match_extend_back_end_calcBlockSizeSmall + +match_extend_back_loop_calcBlockSizeSmall: + CMPW R6, R2 + BLS match_extend_back_end_calcBlockSizeSmall + ADD R5, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R7 + ADD R2, R3, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R8 + AND $0xff, R8, R16 + AND $0xff, R7, R15 + CMP R16, R15 + BNE match_extend_back_end_calcBlockSizeSmall + SUB $1, R2, R2 + MOVWU R2, R2 + SUBSW $1, R5, R5 + BEQ match_extend_back_end_calcBlockSizeSmall + JMP match_extend_back_loop_calcBlockSizeSmall + +match_extend_back_end_calcBlockSizeSmall: + MOVWU R2, R6 + MOVWU 20(RSP), R16 + SUBW R16, R6, R6 + ADD R6, R1, R6 + ADD $3, R6, R6 + MOVD 8(RSP), R16 + CMP R16, R6 + BLO match_dst_size_check_calcBlockSizeSmall + MOVD $0x00000000, R16 + MOVD R16, ret+32(FP) + RET + +match_dst_size_check_calcBlockSizeSmall: + MOVWU R2, R6 + MOVWU 20(RSP), R7 + CMPW R6, R7 + BEQ emit_literal_done_match_emit_calcBlockSizeSmall + MOVWU R6, R8 + MOVW R6, 20(RSP) + ADD R7, R3, R6 + SUBW R7, R8, R8 + SUB $1, R8, R6 + MOVWU R6, R6 + CMPW $0x3c, R6 + BLO one_byte_match_emit_calcBlockSizeSmall + CMPW $0x00000100, R6 + BLO two_bytes_match_emit_calcBlockSizeSmall + BLO three_bytes_match_emit_calcBlockSizeSmall + +three_bytes_match_emit_calcBlockSizeSmall: + ADD $0x03, R1, R1 + JMP memmove_long_match_emit_calcBlockSizeSmall + +two_bytes_match_emit_calcBlockSizeSmall: + ADD $0x02, R1, R1 + CMPW $0x40, R6 + BLO memmove_match_emit_calcBlockSizeSmall + JMP memmove_long_match_emit_calcBlockSizeSmall + +one_byte_match_emit_calcBlockSizeSmall: + ADD $0x01, R1, R1 + +memmove_match_emit_calcBlockSizeSmall: + ADD R8, R1, R1 + JMP emit_literal_done_match_emit_calcBlockSizeSmall + +memmove_long_match_emit_calcBlockSizeSmall: + ADD R8, R1, R1 + +emit_literal_done_match_emit_calcBlockSizeSmall: +match_nolit_loop_calcBlockSizeSmall: + MOVWU R2, R6 + SUBW R5, R6, R6 + MOVW R6, 24(RSP) + ADDW $0x04, R2, R2 + ADDW $0x04, R5, R5 + MOVD src_len+8(FP), R6 + SUBW R2, R6, R6 + ADD R2, R3, R7 + ADD R5, R3, R5 + + // matchLen + MOVD $0, R9 + +matchlen_loopback_16_match_nolit_calcBlockSizeSmall: + CMPW $0x10, R6 + BLO matchlen_match8_match_nolit_calcBlockSizeSmall + MOVD (R7)(R9), R8 + ADD R9, R7, R15 + MOVD 8(R15), R10 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_calcBlockSizeSmall + ADD R9, R5, R15 + MOVD 8(R15), R16 + EOR R16, R10, R10 + TST R10, R10 + BNE matchlen_bsf_16match_nolit_calcBlockSizeSmall + SUB $16, R6, R6 + MOVWU R6, R6 + ADD $16, R9, R9 + MOVWU R9, R9 + JMP matchlen_loopback_16_match_nolit_calcBlockSizeSmall + +matchlen_bsf_16match_nolit_calcBlockSizeSmall: + RBIT R10, R10 + CLZ R10, R10 + ASR $0x03, R10, R10 + ADD R10, R9, R9 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_calcBlockSizeSmall + +matchlen_match8_match_nolit_calcBlockSizeSmall: + CMPW $0x08, R6 + BLO matchlen_match4_match_nolit_calcBlockSizeSmall + MOVD (R7)(R9), R8 + MOVD (R5)(R9), R16 + EOR R16, R8, R8 + TST R8, R8 + BNE matchlen_bsf_8_match_nolit_calcBlockSizeSmall + SUB $8, R6, R6 + MOVWU R6, R6 + ADD $8, R9, R9 + MOVWU R9, R9 + JMP matchlen_match4_match_nolit_calcBlockSizeSmall + +matchlen_bsf_8_match_nolit_calcBlockSizeSmall: + RBIT R8, R8 + CLZ R8, R8 + ASR $0x03, R8, R8 + ADD R8, R9, R9 + MOVWU R9, R9 + JMP match_nolit_end_calcBlockSizeSmall + +matchlen_match4_match_nolit_calcBlockSizeSmall: + CMPW $0x04, R6 + BLO matchlen_match2_match_nolit_calcBlockSizeSmall + MOVWU (R7)(R9), R8 + MOVWU (R5)(R9), R16 + CMPW R8, R16 + BNE matchlen_match2_match_nolit_calcBlockSizeSmall + SUB $4, R6, R6 + MOVWU R6, R6 + ADD $4, R9, R9 + MOVWU R9, R9 + +matchlen_match2_match_nolit_calcBlockSizeSmall: + CMPW $0x01, R6 + BEQ matchlen_match1_match_nolit_calcBlockSizeSmall + BLO match_nolit_end_calcBlockSizeSmall + MOVHU (R7)(R9), R16 + BFI $0, R16, $16, R8 + ADD R9, R5, R15 + MOVHU (R15), R15 + AND $0xffff, R8, R16 + CMP R16, R15 + BNE matchlen_match1_match_nolit_calcBlockSizeSmall + ADD $2, R9, R9 + MOVWU R9, R9 + SUBSW $0x02, R6, R6 + BEQ match_nolit_end_calcBlockSizeSmall + +matchlen_match1_match_nolit_calcBlockSizeSmall: + MOVBU (R7)(R9), R16 + BFI $0, R16, $8, R8 + ADD R9, R5, R15 + MOVBU (R15), R15 + AND $0xff, R8, R16 + CMP R16, R15 + BNE match_nolit_end_calcBlockSizeSmall + ADD $1, R9, R9 + MOVWU R9, R9 + +match_nolit_end_calcBlockSizeSmall: + ADDW R9, R2, R2 + MOVWU 24(RSP), R5 + ADDW $0x04, R9, R9 + MOVW R2, 20(RSP) + + // emitCopy +two_byte_offset_match_nolit_calcBlockSizeSmall: + CMPW $0x40, R9 + BLS two_byte_offset_short_match_nolit_calcBlockSizeSmall + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R1, R1 + JMP two_byte_offset_match_nolit_calcBlockSizeSmall + +two_byte_offset_short_match_nolit_calcBlockSizeSmall: + MOVWU R9, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R9 + BHS emit_copy_three_match_nolit_calcBlockSizeSmall + ADD $0x02, R1, R1 + JMP match_nolit_emitcopy_end_calcBlockSizeSmall + +emit_copy_three_match_nolit_calcBlockSizeSmall: + ADD $0x03, R1, R1 + +match_nolit_emitcopy_end_calcBlockSizeSmall: + MOVWU 16(RSP), R16 + CMPW R16, R2 + BHS emit_remainder_calcBlockSizeSmall + ADD R2, R3, R15 + MOVD -2(R15), R6 + MOVD 8(RSP), R16 + CMP R16, R1 + BLO match_nolit_dst_ok_calcBlockSizeSmall + MOVD $0x00000000, R16 + MOVD R16, ret+32(FP) + RET + +match_nolit_dst_ok_calcBlockSizeSmall: + MOVD $0x9e3779b1, R8 + MOVD R6, R7 + LSR $0x10, R6, R6 + MOVD R6, R5 + LSL $0x20, R7, R7 + MUL R8, R7, R7 + LSR $0x37, R7, R7 + LSL $0x20, R5, R5 + MUL R8, R5, R5 + LSR $0x37, R5, R5 + SUB $2, R2, R8 + MOVWU R8, R8 + ADD R5<<2, R0, R9 + MOVWU (R9), R5 + MOVW R8, (R0)(R7<<2) + MOVW R2, (R9) + MOVWU (R3)(R5), R16 + CMPW R6, R16 + BEQ match_nolit_loop_calcBlockSizeSmall + ADDW $1, R2, R2 + JMP search_loop_calcBlockSizeSmall + +emit_remainder_calcBlockSizeSmall: + MOVD src_len+8(FP), R0 + MOVWU 20(RSP), R16 + SUBW R16, R0, R0 + ADD R0, R1, R0 + ADD $3, R0, R0 + MOVD 8(RSP), R16 + CMP R16, R0 + BLO emit_remainder_ok_calcBlockSizeSmall + MOVD $0x00000000, R16 + MOVD R16, ret+32(FP) + RET + +emit_remainder_ok_calcBlockSizeSmall: + MOVD src_len+8(FP), R0 + MOVWU 20(RSP), R2 + CMPW R0, R2 + BEQ emit_literal_done_emit_remainder_calcBlockSizeSmall + MOVWU R0, R5 + MOVW R0, 20(RSP) + ADD R2, R3, R0 + SUBW R2, R5, R5 + SUB $1, R5, R0 + MOVWU R0, R0 + CMPW $0x3c, R0 + BLO one_byte_emit_remainder_calcBlockSizeSmall + CMPW $0x00000100, R0 + BLO two_bytes_emit_remainder_calcBlockSizeSmall + BLO three_bytes_emit_remainder_calcBlockSizeSmall + +three_bytes_emit_remainder_calcBlockSizeSmall: + ADD $0x03, R1, R1 + JMP memmove_long_emit_remainder_calcBlockSizeSmall + +two_bytes_emit_remainder_calcBlockSizeSmall: + ADD $0x02, R1, R1 + CMPW $0x40, R0 + BLO memmove_emit_remainder_calcBlockSizeSmall + JMP memmove_long_emit_remainder_calcBlockSizeSmall + +one_byte_emit_remainder_calcBlockSizeSmall: + ADD $0x01, R1, R1 + +memmove_emit_remainder_calcBlockSizeSmall: + ADD R5, R1, R0 + MOVD R0, R1 + JMP emit_literal_done_emit_remainder_calcBlockSizeSmall + +memmove_long_emit_remainder_calcBlockSizeSmall: + ADD R5, R1, R0 + MOVD R0, R1 + +emit_literal_done_emit_remainder_calcBlockSizeSmall: + MOVD R1, ret+32(FP) + RET + +// func emitLiteral(dst []byte, lit []byte) int +// Requires: SSE2 +TEXT ·emitLiteral(SB), NOSPLIT, $0-56 + MOVD lit_len+32(FP), R2 + MOVD dst_base+0(FP), R0 + MOVD lit_base+24(FP), R1 + TST R2, R2 + BEQ emit_literal_end_standalone_skip + MOVWU R2, R3 + SUB $1, R2, R5 + MOVWU R5, R5 + CMPW $0x3c, R5 + BLO one_byte_standalone + CMPW $0x00000100, R5 + BLO two_bytes_standalone + CMPW $0x00010000, R5 + BLO three_bytes_standalone + CMPW $0x01000000, R5 + BLO four_bytes_standalone + MOVD $0xfc, R16 + MOVB R16, (R0) + MOVW R5, 1(R0) + ADD $0x05, R3, R3 + ADD $0x05, R0, R0 + JMP memmove_long_standalone + +four_bytes_standalone: + MOVWU R5, R6 + LSRW $0x10, R6, R6 + MOVD $0xf8, R16 + MOVB R16, (R0) + MOVH R5, 1(R0) + MOVB R6, 3(R0) + ADD $0x04, R3, R3 + ADD $0x04, R0, R0 + JMP memmove_long_standalone + +three_bytes_standalone: + MOVD $0xf4, R16 + MOVB R16, (R0) + MOVH R5, 1(R0) + ADD $0x03, R3, R3 + ADD $0x03, R0, R0 + JMP memmove_long_standalone + +two_bytes_standalone: + MOVD $0xf0, R16 + MOVB R16, (R0) + MOVB R5, 1(R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + CMPW $0x40, R5 + BLO memmove_standalone + JMP memmove_long_standalone + +one_byte_standalone: + LSLW $0x02, R5, R16 + BFI $0, R16, $8, R5 + MOVB R5, (R0) + ADD $0x01, R3, R3 + ADD $0x01, R0, R0 + +memmove_standalone: + // genMemMoveShort + CMP $0x03, R2 + BLO emit_lit_memmove_standalone_memmove_move_1or2 + BEQ emit_lit_memmove_standalone_memmove_move_3 + CMP $0x08, R2 + BLO emit_lit_memmove_standalone_memmove_move_4through7 + CMP $0x10, R2 + BLS emit_lit_memmove_standalone_memmove_move_8through16 + CMP $0x20, R2 + BLS emit_lit_memmove_standalone_memmove_move_17through32 + JMP emit_lit_memmove_standalone_memmove_move_33through64 + +emit_lit_memmove_standalone_memmove_move_1or2: + MOVBU (R1), R16 + BFI $0, R16, $8, R5 + ADD R2, R1, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R1 + MOVB R5, (R0) + ADD R2, R0, R15 + MOVB R1, -1(R15) + JMP emit_literal_end_standalone + +emit_lit_memmove_standalone_memmove_move_3: + MOVHU (R1), R16 + BFI $0, R16, $16, R5 + MOVBU 2(R1), R16 + BFI $0, R16, $8, R1 + MOVH R5, (R0) + MOVB R1, 2(R0) + JMP emit_literal_end_standalone + +emit_lit_memmove_standalone_memmove_move_4through7: + MOVWU (R1), R5 + ADD R2, R1, R15 + MOVWU -4(R15), R1 + MOVW R5, (R0) + ADD R2, R0, R15 + MOVW R1, -4(R15) + JMP emit_literal_end_standalone + +emit_lit_memmove_standalone_memmove_move_8through16: + MOVD (R1), R5 + ADD R2, R1, R15 + MOVD -8(R15), R1 + MOVD R5, (R0) + ADD R2, R0, R15 + MOVD R1, -8(R15) + JMP emit_literal_end_standalone + +emit_lit_memmove_standalone_memmove_move_17through32: + FMOVQ (R1), F0 + ADD R2, R1, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R0) + ADD R2, R0, R15 + FMOVQ F1, -16(R15) + JMP emit_literal_end_standalone + +emit_lit_memmove_standalone_memmove_move_33through64: + FMOVQ (R1), F0 + FMOVQ 16(R1), F1 + ADD R2, R1, R15 + FMOVQ -32(R15), F2 + ADD R2, R1, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R0) + FMOVQ F1, 16(R0) + ADD R2, R0, R15 + FMOVQ F2, -32(R15) + ADD R2, R0, R15 + FMOVQ F3, -16(R15) + JMP emit_literal_end_standalone + JMP emit_literal_end_standalone + +memmove_long_standalone: + // genMemMoveLong + MOVD R1, R5 + MOVD R0, R6 + MOVD R2, R7 + +emit_lit_memmove_long_standalonelarge_big_loop_back: + FMOVQ (R5), F0 + FMOVQ 16(R5), F1 + FMOVQ F0, (R6) + FMOVQ F1, 16(R6) + ADD $0x20, R5, R5 + ADD $0x20, R6, R6 + SUB $0x20, R7, R7 + CMP $0x20, R7 + BHS emit_lit_memmove_long_standalonelarge_big_loop_back + ADD R2, R1, R15 + FMOVQ -32(R15), F0 + ADD R2, R1, R15 + FMOVQ -16(R15), F1 + ADD R2, R0, R15 + FMOVQ F0, -32(R15) + ADD R2, R0, R15 + FMOVQ F1, -16(R15) + JMP emit_literal_end_standalone + JMP emit_literal_end_standalone + +emit_literal_end_standalone_skip: + MOVD $0, R3 + +emit_literal_end_standalone: + MOVD R3, ret+48(FP) + RET + +// func emitRepeat(dst []byte, offset int, length int) int +TEXT ·emitRepeat(SB), NOSPLIT, $0-48 + MOVD $0, R3 + MOVD dst_base+0(FP), R0 + MOVD offset+24(FP), R1 + MOVD length+32(FP), R2 + + // emitRepeat +emit_repeat_again_standalone: + MOVWU R2, R5 + SUB $4, R2, R2 + MOVWU R2, R2 + CMPW $0x08, R5 + BLS repeat_two_standalone + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_standalone + CMPW $0x00000800, R1 + BLO repeat_two_offset_standalone + +cant_repeat_two_offset_standalone: + CMPW $0x00000104, R2 + BLO repeat_three_standalone + CMPW $0x00010100, R2 + BLO repeat_four_standalone + CMPW $0x0100ffff, R2 + BLO repeat_five_standalone + SUB $16842747, R2, R2 + MOVWU R2, R2 + MOVD $0xfffb001d, R16 + MOVW R16, (R0) + MOVD $0xff, R16 + MOVB R16, 4(R0) + ADD $0x05, R0, R0 + ADD $0x05, R3, R3 + JMP emit_repeat_again_standalone + +repeat_five_standalone: + SUB $65536, R2, R2 + MOVWU R2, R2 + MOVWU R2, R1 + MOVD $0x001d, R16 + MOVH R16, (R0) + MOVH R2, 2(R0) + ASRW $0x10, R1, R1 + MOVB R1, 4(R0) + ADD $0x05, R3, R3 + ADD $0x05, R0, R0 + JMP gen_emit_repeat_end + +repeat_four_standalone: + SUB $256, R2, R2 + MOVWU R2, R2 + MOVD $0x0019, R16 + MOVH R16, (R0) + MOVH R2, 2(R0) + ADD $0x04, R3, R3 + ADD $0x04, R0, R0 + JMP gen_emit_repeat_end + +repeat_three_standalone: + SUB $4, R2, R2 + MOVWU R2, R2 + MOVD $0x0015, R16 + MOVH R16, (R0) + MOVB R2, 2(R0) + ADD $0x03, R3, R3 + ADD $0x03, R0, R0 + JMP gen_emit_repeat_end + +repeat_two_standalone: + LSLW $0x02, R2, R2 + ORRW $0x01, R2, R2 + MOVH R2, (R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + JMP gen_emit_repeat_end + +repeat_two_offset_standalone: + MOVD $0, R5 + ADD R2<<2, R5, R2 + ADD $1, R2, R2 + MOVWU R2, R2 + MOVB R1, 1(R0) + ASRW $0x08, R1, R1 + LSLW $0x05, R1, R1 + ORRW R1, R2, R2 + MOVB R2, (R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + +gen_emit_repeat_end: + MOVD R3, ret+40(FP) + RET + +// func emitCopy(dst []byte, offset int, length int) int +TEXT ·emitCopy(SB), NOSPLIT, $0-48 + MOVD $0, R3 + MOVD dst_base+0(FP), R0 + MOVD offset+24(FP), R1 + MOVD length+32(FP), R2 + + // emitCopy + CMPW $0x00010000, R1 + BLO two_byte_offset_standalone + CMPW $0x40, R2 + BLS four_bytes_remain_standalone + MOVD $0xff, R16 + MOVB R16, (R0) + MOVW R1, 1(R0) + SUB $64, R2, R2 + MOVWU R2, R2 + ADD $0x05, R3, R3 + ADD $0x05, R0, R0 + CMPW $0x04, R2 + BLO four_bytes_remain_standalone + + // emitRepeat +emit_repeat_again_standalone_emit_copy: + MOVWU R2, R5 + SUB $4, R2, R2 + MOVWU R2, R2 + CMPW $0x08, R5 + BLS repeat_two_standalone_emit_copy + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_standalone_emit_copy + CMPW $0x00000800, R1 + BLO repeat_two_offset_standalone_emit_copy + +cant_repeat_two_offset_standalone_emit_copy: + CMPW $0x00000104, R2 + BLO repeat_three_standalone_emit_copy + CMPW $0x00010100, R2 + BLO repeat_four_standalone_emit_copy + CMPW $0x0100ffff, R2 + BLO repeat_five_standalone_emit_copy + SUB $16842747, R2, R2 + MOVWU R2, R2 + MOVD $0xfffb001d, R16 + MOVW R16, (R0) + MOVD $0xff, R16 + MOVB R16, 4(R0) + ADD $0x05, R0, R0 + ADD $0x05, R3, R3 + JMP emit_repeat_again_standalone_emit_copy + +repeat_five_standalone_emit_copy: + SUB $65536, R2, R2 + MOVWU R2, R2 + MOVWU R2, R1 + MOVD $0x001d, R16 + MOVH R16, (R0) + MOVH R2, 2(R0) + ASRW $0x10, R1, R1 + MOVB R1, 4(R0) + ADD $0x05, R3, R3 + ADD $0x05, R0, R0 + JMP gen_emit_copy_end + +repeat_four_standalone_emit_copy: + SUB $256, R2, R2 + MOVWU R2, R2 + MOVD $0x0019, R16 + MOVH R16, (R0) + MOVH R2, 2(R0) + ADD $0x04, R3, R3 + ADD $0x04, R0, R0 + JMP gen_emit_copy_end + +repeat_three_standalone_emit_copy: + SUB $4, R2, R2 + MOVWU R2, R2 + MOVD $0x0015, R16 + MOVH R16, (R0) + MOVB R2, 2(R0) + ADD $0x03, R3, R3 + ADD $0x03, R0, R0 + JMP gen_emit_copy_end + +repeat_two_standalone_emit_copy: + LSLW $0x02, R2, R2 + ORRW $0x01, R2, R2 + MOVH R2, (R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + JMP gen_emit_copy_end + +repeat_two_offset_standalone_emit_copy: + MOVD $0, R5 + ADD R2<<2, R5, R2 + ADD $1, R2, R2 + MOVWU R2, R2 + MOVB R1, 1(R0) + ASRW $0x08, R1, R1 + LSLW $0x05, R1, R1 + ORRW R1, R2, R2 + MOVB R2, (R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + JMP gen_emit_copy_end + +four_bytes_remain_standalone: + TSTW R2, R2 + BEQ gen_emit_copy_end + MOVD $0, R5 + ADD R2<<2, R5, R2 + SUB $1, R2, R2 + MOVWU R2, R2 + MOVB R2, (R0) + MOVW R1, 1(R0) + ADD $0x05, R3, R3 + ADD $0x05, R0, R0 + JMP gen_emit_copy_end + +two_byte_offset_standalone: + CMPW $0x40, R2 + BLS two_byte_offset_short_standalone + CMPW $0x00000800, R1 + BHS long_offset_short_standalone + MOVD $0x00000001, R5 + ADD $16, R5, R5 + MOVWU R5, R5 + MOVB R1, 1(R0) + MOVWU R1, R6 + LSRW $0x08, R6, R6 + LSLW $0x05, R6, R6 + ORRW R6, R5, R5 + MOVB R5, (R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + SUBW $0x08, R2, R2 + + // emitRepeat + SUB $4, R2, R2 + MOVWU R2, R2 + JMP cant_repeat_two_offset_standalone_emit_copy_short_2b + +emit_repeat_again_standalone_emit_copy_short_2b: + MOVWU R2, R5 + SUB $4, R2, R2 + MOVWU R2, R2 + CMPW $0x08, R5 + BLS repeat_two_standalone_emit_copy_short_2b + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_standalone_emit_copy_short_2b + CMPW $0x00000800, R1 + BLO repeat_two_offset_standalone_emit_copy_short_2b + +cant_repeat_two_offset_standalone_emit_copy_short_2b: + CMPW $0x00000104, R2 + BLO repeat_three_standalone_emit_copy_short_2b + CMPW $0x00010100, R2 + BLO repeat_four_standalone_emit_copy_short_2b + CMPW $0x0100ffff, R2 + BLO repeat_five_standalone_emit_copy_short_2b + SUB $16842747, R2, R2 + MOVWU R2, R2 + MOVD $0xfffb001d, R16 + MOVW R16, (R0) + MOVD $0xff, R16 + MOVB R16, 4(R0) + ADD $0x05, R0, R0 + ADD $0x05, R3, R3 + JMP emit_repeat_again_standalone_emit_copy_short_2b + +repeat_five_standalone_emit_copy_short_2b: + SUB $65536, R2, R2 + MOVWU R2, R2 + MOVWU R2, R1 + MOVD $0x001d, R16 + MOVH R16, (R0) + MOVH R2, 2(R0) + ASRW $0x10, R1, R1 + MOVB R1, 4(R0) + ADD $0x05, R3, R3 + ADD $0x05, R0, R0 + JMP gen_emit_copy_end + +repeat_four_standalone_emit_copy_short_2b: + SUB $256, R2, R2 + MOVWU R2, R2 + MOVD $0x0019, R16 + MOVH R16, (R0) + MOVH R2, 2(R0) + ADD $0x04, R3, R3 + ADD $0x04, R0, R0 + JMP gen_emit_copy_end + +repeat_three_standalone_emit_copy_short_2b: + SUB $4, R2, R2 + MOVWU R2, R2 + MOVD $0x0015, R16 + MOVH R16, (R0) + MOVB R2, 2(R0) + ADD $0x03, R3, R3 + ADD $0x03, R0, R0 + JMP gen_emit_copy_end + +repeat_two_standalone_emit_copy_short_2b: + LSLW $0x02, R2, R2 + ORRW $0x01, R2, R2 + MOVH R2, (R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + JMP gen_emit_copy_end + +repeat_two_offset_standalone_emit_copy_short_2b: + MOVD $0, R5 + ADD R2<<2, R5, R2 + ADD $1, R2, R2 + MOVWU R2, R2 + MOVB R1, 1(R0) + ASRW $0x08, R1, R1 + LSLW $0x05, R1, R1 + ORRW R1, R2, R2 + MOVB R2, (R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + JMP gen_emit_copy_end + +long_offset_short_standalone: + MOVD $0xee, R16 + MOVB R16, (R0) + MOVH R1, 1(R0) + SUB $60, R2, R2 + MOVWU R2, R2 + ADD $0x03, R0, R0 + ADD $0x03, R3, R3 + + // emitRepeat +emit_repeat_again_standalone_emit_copy_short: + MOVWU R2, R5 + SUB $4, R2, R2 + MOVWU R2, R2 + CMPW $0x08, R5 + BLS repeat_two_standalone_emit_copy_short + CMPW $0x0c, R5 + BHS cant_repeat_two_offset_standalone_emit_copy_short + CMPW $0x00000800, R1 + BLO repeat_two_offset_standalone_emit_copy_short + +cant_repeat_two_offset_standalone_emit_copy_short: + CMPW $0x00000104, R2 + BLO repeat_three_standalone_emit_copy_short + CMPW $0x00010100, R2 + BLO repeat_four_standalone_emit_copy_short + CMPW $0x0100ffff, R2 + BLO repeat_five_standalone_emit_copy_short + SUB $16842747, R2, R2 + MOVWU R2, R2 + MOVD $0xfffb001d, R16 + MOVW R16, (R0) + MOVD $0xff, R16 + MOVB R16, 4(R0) + ADD $0x05, R0, R0 + ADD $0x05, R3, R3 + JMP emit_repeat_again_standalone_emit_copy_short + +repeat_five_standalone_emit_copy_short: + SUB $65536, R2, R2 + MOVWU R2, R2 + MOVWU R2, R1 + MOVD $0x001d, R16 + MOVH R16, (R0) + MOVH R2, 2(R0) + ASRW $0x10, R1, R1 + MOVB R1, 4(R0) + ADD $0x05, R3, R3 + ADD $0x05, R0, R0 + JMP gen_emit_copy_end + +repeat_four_standalone_emit_copy_short: + SUB $256, R2, R2 + MOVWU R2, R2 + MOVD $0x0019, R16 + MOVH R16, (R0) + MOVH R2, 2(R0) + ADD $0x04, R3, R3 + ADD $0x04, R0, R0 + JMP gen_emit_copy_end + +repeat_three_standalone_emit_copy_short: + SUB $4, R2, R2 + MOVWU R2, R2 + MOVD $0x0015, R16 + MOVH R16, (R0) + MOVB R2, 2(R0) + ADD $0x03, R3, R3 + ADD $0x03, R0, R0 + JMP gen_emit_copy_end + +repeat_two_standalone_emit_copy_short: + LSLW $0x02, R2, R2 + ORRW $0x01, R2, R2 + MOVH R2, (R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + JMP gen_emit_copy_end + +repeat_two_offset_standalone_emit_copy_short: + MOVD $0, R5 + ADD R2<<2, R5, R2 + ADD $1, R2, R2 + MOVWU R2, R2 + MOVB R1, 1(R0) + ASRW $0x08, R1, R1 + LSLW $0x05, R1, R1 + ORRW R1, R2, R2 + MOVB R2, (R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + JMP gen_emit_copy_end + +two_byte_offset_short_standalone: + MOVWU R2, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R2 + BHS emit_copy_three_standalone + CMPW $0x00000800, R1 + BHS emit_copy_three_standalone + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R1, 1(R0) + LSRW $0x08, R1, R1 + LSLW $0x05, R1, R1 + ORRW R1, R5, R5 + MOVB R5, (R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + JMP gen_emit_copy_end + +emit_copy_three_standalone: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R0) + MOVH R1, 1(R0) + ADD $0x03, R3, R3 + ADD $0x03, R0, R0 + +gen_emit_copy_end: + MOVD R3, ret+40(FP) + RET + +// func emitCopyNoRepeat(dst []byte, offset int, length int) int +TEXT ·emitCopyNoRepeat(SB), NOSPLIT, $0-48 + MOVD $0, R3 + MOVD dst_base+0(FP), R0 + MOVD offset+24(FP), R1 + MOVD length+32(FP), R2 + + // emitCopy + CMPW $0x00010000, R1 + BLO two_byte_offset_standalone_snappy + +four_bytes_loop_back_standalone_snappy: + CMPW $0x40, R2 + BLS four_bytes_remain_standalone_snappy + MOVD $0xff, R16 + MOVB R16, (R0) + MOVW R1, 1(R0) + SUB $64, R2, R2 + MOVWU R2, R2 + ADD $0x05, R3, R3 + ADD $0x05, R0, R0 + CMPW $0x04, R2 + BLO four_bytes_remain_standalone_snappy + JMP four_bytes_loop_back_standalone_snappy + +four_bytes_remain_standalone_snappy: + TSTW R2, R2 + BEQ gen_emit_copy_end_snappy + MOVD $0, R5 + ADD R2<<2, R5, R2 + SUB $1, R2, R2 + MOVWU R2, R2 + MOVB R2, (R0) + MOVW R1, 1(R0) + ADD $0x05, R3, R3 + ADD $0x05, R0, R0 + JMP gen_emit_copy_end_snappy + +two_byte_offset_standalone_snappy: + CMPW $0x40, R2 + BLS two_byte_offset_short_standalone_snappy + MOVD $0xee, R16 + MOVB R16, (R0) + MOVH R1, 1(R0) + SUB $60, R2, R2 + MOVWU R2, R2 + ADD $0x03, R0, R0 + ADD $0x03, R3, R3 + JMP two_byte_offset_standalone_snappy + +two_byte_offset_short_standalone_snappy: + MOVWU R2, R5 + LSLW $0x02, R5, R5 + CMPW $0x0c, R2 + BHS emit_copy_three_standalone_snappy + CMPW $0x00000800, R1 + BHS emit_copy_three_standalone_snappy + SUB $15, R5, R5 + MOVWU R5, R5 + MOVB R1, 1(R0) + LSRW $0x08, R1, R1 + LSLW $0x05, R1, R1 + ORRW R1, R5, R5 + MOVB R5, (R0) + ADD $0x02, R3, R3 + ADD $0x02, R0, R0 + JMP gen_emit_copy_end_snappy + +emit_copy_three_standalone_snappy: + SUB $2, R5, R5 + MOVWU R5, R5 + MOVB R5, (R0) + MOVH R1, 1(R0) + ADD $0x03, R3, R3 + ADD $0x03, R0, R0 + +gen_emit_copy_end_snappy: + MOVD R3, ret+40(FP) + RET + +// func matchLen(a []byte, b []byte) int +// Requires: BMI +TEXT ·matchLen(SB), NOSPLIT, $0-56 + MOVD a_base+0(FP), R0 + MOVD b_base+24(FP), R1 + MOVD a_len+8(FP), R2 + + // matchLen + MOVD $0, R5 + +matchlen_loopback_16_standalone: + CMPW $0x10, R2 + BLO matchlen_match8_standalone + MOVD (R0)(R5), R3 + ADD R5, R0, R15 + MOVD 8(R15), R6 + MOVD (R1)(R5), R16 + EOR R16, R3, R3 + TST R3, R3 + BNE matchlen_bsf_8_standalone + ADD R5, R1, R15 + MOVD 8(R15), R16 + EOR R16, R6, R6 + TST R6, R6 + BNE matchlen_bsf_16standalone + SUB $16, R2, R2 + MOVWU R2, R2 + ADD $16, R5, R5 + MOVWU R5, R5 + JMP matchlen_loopback_16_standalone + +matchlen_bsf_16standalone: + RBIT R6, R6 + CLZ R6, R6 + ASR $0x03, R6, R6 + ADD R6, R5, R5 + ADD $8, R5, R5 + MOVWU R5, R5 + JMP gen_match_len_end + +matchlen_match8_standalone: + CMPW $0x08, R2 + BLO matchlen_match4_standalone + MOVD (R0)(R5), R3 + MOVD (R1)(R5), R16 + EOR R16, R3, R3 + TST R3, R3 + BNE matchlen_bsf_8_standalone + SUB $8, R2, R2 + MOVWU R2, R2 + ADD $8, R5, R5 + MOVWU R5, R5 + JMP matchlen_match4_standalone + +matchlen_bsf_8_standalone: + RBIT R3, R3 + CLZ R3, R3 + ASR $0x03, R3, R3 + ADD R3, R5, R5 + MOVWU R5, R5 + JMP gen_match_len_end + +matchlen_match4_standalone: + CMPW $0x04, R2 + BLO matchlen_match2_standalone + MOVWU (R0)(R5), R3 + MOVWU (R1)(R5), R16 + CMPW R3, R16 + BNE matchlen_match2_standalone + SUB $4, R2, R2 + MOVWU R2, R2 + ADD $4, R5, R5 + MOVWU R5, R5 + +matchlen_match2_standalone: + CMPW $0x01, R2 + BEQ matchlen_match1_standalone + BLO gen_match_len_end + MOVHU (R0)(R5), R16 + BFI $0, R16, $16, R3 + ADD R5, R1, R15 + MOVHU (R15), R15 + AND $0xffff, R3, R16 + CMP R16, R15 + BNE matchlen_match1_standalone + ADD $2, R5, R5 + MOVWU R5, R5 + SUBSW $0x02, R2, R2 + BEQ gen_match_len_end + +matchlen_match1_standalone: + MOVBU (R0)(R5), R16 + BFI $0, R16, $8, R3 + ADD R5, R1, R15 + MOVBU (R15), R15 + AND $0xff, R3, R16 + CMP R16, R15 + BNE gen_match_len_end + ADD $1, R5, R5 + MOVWU R5, R5 + +gen_match_len_end: + MOVD R5, ret+48(FP) + RET + +// func cvtLZ4BlockAsm(dst []byte, src []byte) (uncompressed int, dstUsed int) +// Requires: SSE2 +TEXT ·cvtLZ4BlockAsm(SB), NOSPLIT, $0-64 + MOVD $0, R5 + MOVD dst_base+0(FP), R0 + MOVD dst_len+8(FP), R1 + MOVD src_base+24(FP), R2 + MOVD src_len+32(FP), R3 + ADD R3, R2, R3 + ADD R1, R0, R1 + SUB $8, R1, R1 + MOVD $0, R6 + +lz4_s2_loop: + CMP R3, R2 + BHS lz4_s2_corrupt + CMP R1, R0 + BHS lz4_s2_dstfull + MOVBU (R2), R7 + MOVD R7, R8 + MOVD R7, R9 + LSR $0x04, R8, R8 + AND $0x0f, R9, R9 + CMP $0xf0, R7 + BLO lz4_s2_ll_end + +lz4_s2_ll_loop: + ADD $1, R2, R2 + CMP R3, R2 + BHS lz4_s2_corrupt + MOVBU (R2), R7 + ADD R7, R8, R8 + CMP $0xff, R7 + BEQ lz4_s2_ll_loop + +lz4_s2_ll_end: + ADD R8, R2, R7 + ADD $0x04, R9, R9 + CMP R3, R7 + BHS lz4_s2_corrupt + ADD $1, R2, R2 + ADD $1, R7, R7 + TST R8, R8 + BEQ lz4_s2_lits_done + ADD R8, R0, R10 + CMP R1, R10 + BHS lz4_s2_dstfull + ADD R8, R5, R5 + SUB $1, R8, R10 + MOVWU R10, R10 + CMPW $0x3c, R10 + BLO one_byte_lz4_s2 + CMPW $0x00000100, R10 + BLO two_bytes_lz4_s2 + CMPW $0x00010000, R10 + BLO three_bytes_lz4_s2 + CMPW $0x01000000, R10 + BLO four_bytes_lz4_s2 + MOVD $0xfc, R16 + MOVB R16, (R0) + MOVW R10, 1(R0) + ADD $0x05, R0, R0 + JMP memmove_long_lz4_s2 + +four_bytes_lz4_s2: + MOVWU R10, R11 + LSRW $0x10, R11, R11 + MOVD $0xf8, R16 + MOVB R16, (R0) + MOVH R10, 1(R0) + MOVB R11, 3(R0) + ADD $0x04, R0, R0 + JMP memmove_long_lz4_s2 + +three_bytes_lz4_s2: + MOVD $0xf4, R16 + MOVB R16, (R0) + MOVH R10, 1(R0) + ADD $0x03, R0, R0 + JMP memmove_long_lz4_s2 + +two_bytes_lz4_s2: + MOVD $0xf0, R16 + MOVB R16, (R0) + MOVB R10, 1(R0) + ADD $0x02, R0, R0 + CMPW $0x40, R10 + BLO memmove_lz4_s2 + JMP memmove_long_lz4_s2 + +one_byte_lz4_s2: + LSLW $0x02, R10, R16 + BFI $0, R16, $8, R10 + MOVB R10, (R0) + ADD $0x01, R0, R0 + +memmove_lz4_s2: + ADD R8, R0, R10 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_lz4_s2_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_lz4_s2_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_lz4_s2_memmove_move_17through32 + JMP emit_lit_memmove_lz4_s2_memmove_move_33through64 + +emit_lit_memmove_lz4_s2_memmove_move_8: + MOVD (R2), R11 + MOVD R11, (R0) + JMP memmove_end_copy_lz4_s2 + +emit_lit_memmove_lz4_s2_memmove_move_8through16: + MOVD (R2), R11 + ADD R8, R2, R15 + MOVD -8(R15), R2 + MOVD R11, (R0) + ADD R8, R0, R15 + MOVD R2, -8(R15) + JMP memmove_end_copy_lz4_s2 + +emit_lit_memmove_lz4_s2_memmove_move_17through32: + FMOVQ (R2), F0 + ADD R8, R2, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R0) + ADD R8, R0, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_lz4_s2 + +emit_lit_memmove_lz4_s2_memmove_move_33through64: + FMOVQ (R2), F0 + FMOVQ 16(R2), F1 + ADD R8, R2, R15 + FMOVQ -32(R15), F2 + ADD R8, R2, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R0) + FMOVQ F1, 16(R0) + ADD R8, R0, R15 + FMOVQ F2, -32(R15) + ADD R8, R0, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_lz4_s2: + MOVD R10, R0 + JMP lz4_s2_lits_emit_done + +memmove_long_lz4_s2: + ADD R8, R0, R10 + + // genMemMoveLong + MOVD R2, R11 + MOVD R0, R12 + MOVD R8, R13 + +emit_lit_memmove_long_lz4_s2large_big_loop_back: + FMOVQ (R11), F0 + FMOVQ 16(R11), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R11, R11 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_lz4_s2large_big_loop_back + ADD R8, R2, R15 + FMOVQ -32(R15), F0 + ADD R8, R2, R15 + FMOVQ -16(R15), F1 + ADD R8, R0, R15 + FMOVQ F0, -32(R15) + ADD R8, R0, R15 + FMOVQ F1, -16(R15) + MOVD R10, R0 + +lz4_s2_lits_emit_done: + MOVD R7, R2 + +lz4_s2_lits_done: + CMP R3, R2 + BNE lz4_s2_match + CMP $0x04, R9 + BEQ lz4_s2_done + JMP lz4_s2_corrupt + +lz4_s2_match: + ADD $2, R2, R7 + CMP R3, R7 + BHS lz4_s2_corrupt + MOVHU (R2), R8 + MOVD R7, R2 + TST R8, R8 + BEQ lz4_s2_corrupt + CMP R5, R8 + BHI lz4_s2_corrupt + CMP $0x13, R9 + BNE lz4_s2_ml_done + +lz4_s2_ml_loop: + MOVBU (R2), R7 + ADD $1, R2, R2 + ADD R7, R9, R9 + CMP R3, R2 + BHS lz4_s2_corrupt + CMP $0xff, R7 + BEQ lz4_s2_ml_loop + +lz4_s2_ml_done: + ADD R9, R5, R5 + CMP R6, R8 + BNE lz4_s2_docopy + + // emitRepeat +emit_repeat_again_lz4_s2: + MOVWU R9, R7 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R7 + BLS repeat_two_lz4_s2 + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_lz4_s2 + CMPW $0x00000800, R8 + BLO repeat_two_offset_lz4_s2 + +cant_repeat_two_offset_lz4_s2: + CMPW $0x00000104, R9 + BLO repeat_three_lz4_s2 + CMPW $0x00010100, R9 + BLO repeat_four_lz4_s2 + CMPW $0x0100ffff, R9 + BLO repeat_five_lz4_s2 + SUB $16842747, R9, R9 + MOVWU R9, R9 + MOVD $0xfffb001d, R16 + MOVW R16, (R0) + MOVD $0xff, R16 + MOVB R16, 4(R0) + ADD $0x05, R0, R0 + JMP emit_repeat_again_lz4_s2 + +repeat_five_lz4_s2: + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R8 + MOVD $0x001d, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ASRW $0x10, R8, R8 + MOVB R8, 4(R0) + ADD $0x05, R0, R0 + JMP lz4_s2_loop + +repeat_four_lz4_s2: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ADD $0x04, R0, R0 + JMP lz4_s2_loop + +repeat_three_lz4_s2: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R0) + MOVB R9, 2(R0) + ADD $0x03, R0, R0 + JMP lz4_s2_loop + +repeat_two_lz4_s2: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R0) + ADD $0x02, R0, R0 + JMP lz4_s2_loop + +repeat_two_offset_lz4_s2: + MOVD $0, R7 + ADD R9<<2, R7, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R8, 1(R0) + ASRW $0x08, R8, R8 + LSLW $0x05, R8, R8 + ORRW R8, R9, R9 + MOVB R9, (R0) + ADD $0x02, R0, R0 + JMP lz4_s2_loop + +lz4_s2_docopy: + MOVD R8, R6 + + // emitCopy + CMPW $0x40, R9 + BLS two_byte_offset_short_lz4_s2 + CMPW $0x00000800, R8 + BHS long_offset_short_lz4_s2 + MOVD $0x00000001, R7 + ADD $16, R7, R7 + MOVWU R7, R7 + MOVB R8, 1(R0) + MOVWU R8, R10 + LSRW $0x08, R10, R10 + LSLW $0x05, R10, R10 + ORRW R10, R7, R7 + MOVB R7, (R0) + ADD $0x02, R0, R0 + SUBW $0x08, R9, R9 + + // emitRepeat + SUB $4, R9, R9 + MOVWU R9, R9 + JMP cant_repeat_two_offset_lz4_s2_emit_copy_short_2b + +emit_repeat_again_lz4_s2_emit_copy_short_2b: + MOVWU R9, R7 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R7 + BLS repeat_two_lz4_s2_emit_copy_short_2b + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_lz4_s2_emit_copy_short_2b + CMPW $0x00000800, R8 + BLO repeat_two_offset_lz4_s2_emit_copy_short_2b + +cant_repeat_two_offset_lz4_s2_emit_copy_short_2b: + CMPW $0x00000104, R9 + BLO repeat_three_lz4_s2_emit_copy_short_2b + CMPW $0x00010100, R9 + BLO repeat_four_lz4_s2_emit_copy_short_2b + CMPW $0x0100ffff, R9 + BLO repeat_five_lz4_s2_emit_copy_short_2b + SUB $16842747, R9, R9 + MOVWU R9, R9 + MOVD $0xfffb001d, R16 + MOVW R16, (R0) + MOVD $0xff, R16 + MOVB R16, 4(R0) + ADD $0x05, R0, R0 + JMP emit_repeat_again_lz4_s2_emit_copy_short_2b + +repeat_five_lz4_s2_emit_copy_short_2b: + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R8 + MOVD $0x001d, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ASRW $0x10, R8, R8 + MOVB R8, 4(R0) + ADD $0x05, R0, R0 + JMP lz4_s2_loop + +repeat_four_lz4_s2_emit_copy_short_2b: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ADD $0x04, R0, R0 + JMP lz4_s2_loop + +repeat_three_lz4_s2_emit_copy_short_2b: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R0) + MOVB R9, 2(R0) + ADD $0x03, R0, R0 + JMP lz4_s2_loop + +repeat_two_lz4_s2_emit_copy_short_2b: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R0) + ADD $0x02, R0, R0 + JMP lz4_s2_loop + +repeat_two_offset_lz4_s2_emit_copy_short_2b: + MOVD $0, R7 + ADD R9<<2, R7, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R8, 1(R0) + ASRW $0x08, R8, R8 + LSLW $0x05, R8, R8 + ORRW R8, R9, R9 + MOVB R9, (R0) + ADD $0x02, R0, R0 + JMP lz4_s2_loop + +long_offset_short_lz4_s2: + MOVD $0xee, R16 + MOVB R16, (R0) + MOVH R8, 1(R0) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R0, R0 + + // emitRepeat +emit_repeat_again_lz4_s2_emit_copy_short: + MOVWU R9, R7 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R7 + BLS repeat_two_lz4_s2_emit_copy_short + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_lz4_s2_emit_copy_short + CMPW $0x00000800, R8 + BLO repeat_two_offset_lz4_s2_emit_copy_short + +cant_repeat_two_offset_lz4_s2_emit_copy_short: + CMPW $0x00000104, R9 + BLO repeat_three_lz4_s2_emit_copy_short + CMPW $0x00010100, R9 + BLO repeat_four_lz4_s2_emit_copy_short + CMPW $0x0100ffff, R9 + BLO repeat_five_lz4_s2_emit_copy_short + SUB $16842747, R9, R9 + MOVWU R9, R9 + MOVD $0xfffb001d, R16 + MOVW R16, (R0) + MOVD $0xff, R16 + MOVB R16, 4(R0) + ADD $0x05, R0, R0 + JMP emit_repeat_again_lz4_s2_emit_copy_short + +repeat_five_lz4_s2_emit_copy_short: + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R8 + MOVD $0x001d, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ASRW $0x10, R8, R8 + MOVB R8, 4(R0) + ADD $0x05, R0, R0 + JMP lz4_s2_loop + +repeat_four_lz4_s2_emit_copy_short: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ADD $0x04, R0, R0 + JMP lz4_s2_loop + +repeat_three_lz4_s2_emit_copy_short: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R0) + MOVB R9, 2(R0) + ADD $0x03, R0, R0 + JMP lz4_s2_loop + +repeat_two_lz4_s2_emit_copy_short: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R0) + ADD $0x02, R0, R0 + JMP lz4_s2_loop + +repeat_two_offset_lz4_s2_emit_copy_short: + MOVD $0, R7 + ADD R9<<2, R7, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R8, 1(R0) + ASRW $0x08, R8, R8 + LSLW $0x05, R8, R8 + ORRW R8, R9, R9 + MOVB R9, (R0) + ADD $0x02, R0, R0 + JMP lz4_s2_loop + +two_byte_offset_short_lz4_s2: + MOVWU R9, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R9 + BHS emit_copy_three_lz4_s2 + CMPW $0x00000800, R8 + BHS emit_copy_three_lz4_s2 + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R8, 1(R0) + LSRW $0x08, R8, R8 + LSLW $0x05, R8, R8 + ORRW R8, R7, R7 + MOVB R7, (R0) + ADD $0x02, R0, R0 + JMP lz4_s2_loop + +emit_copy_three_lz4_s2: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R0) + MOVH R8, 1(R0) + ADD $0x03, R0, R0 + JMP lz4_s2_loop + +lz4_s2_done: + MOVD dst_base+0(FP), R1 + SUB R1, R0, R0 + MOVD R5, uncompressed+48(FP) + MOVD R0, dstUsed+56(FP) + RET + +lz4_s2_corrupt: + MOVD $0, R0 + SUB $1, R0, R5 + MOVD R5, uncompressed+48(FP) + RET + +lz4_s2_dstfull: + MOVD $0, R0 + SUB $2, R0, R5 + MOVD R5, uncompressed+48(FP) + RET + +// func cvtLZ4sBlockAsm(dst []byte, src []byte) (uncompressed int, dstUsed int) +// Requires: SSE2 +TEXT ·cvtLZ4sBlockAsm(SB), NOSPLIT, $0-64 + MOVD $0, R5 + MOVD dst_base+0(FP), R0 + MOVD dst_len+8(FP), R1 + MOVD src_base+24(FP), R2 + MOVD src_len+32(FP), R3 + ADD R3, R2, R3 + ADD R1, R0, R1 + SUB $8, R1, R1 + MOVD $0, R6 + +lz4s_s2_loop: + CMP R3, R2 + BHS lz4s_s2_corrupt + CMP R1, R0 + BHS lz4s_s2_dstfull + MOVBU (R2), R7 + MOVD R7, R8 + MOVD R7, R9 + LSR $0x04, R8, R8 + AND $0x0f, R9, R9 + CMP $0xf0, R7 + BLO lz4s_s2_ll_end + +lz4s_s2_ll_loop: + ADD $1, R2, R2 + CMP R3, R2 + BHS lz4s_s2_corrupt + MOVBU (R2), R7 + ADD R7, R8, R8 + CMP $0xff, R7 + BEQ lz4s_s2_ll_loop + +lz4s_s2_ll_end: + ADD R8, R2, R7 + ADD $0x03, R9, R9 + CMP R3, R7 + BHS lz4s_s2_corrupt + ADD $1, R2, R2 + ADD $1, R7, R7 + TST R8, R8 + BEQ lz4s_s2_lits_done + ADD R8, R0, R10 + CMP R1, R10 + BHS lz4s_s2_dstfull + ADD R8, R5, R5 + SUB $1, R8, R10 + MOVWU R10, R10 + CMPW $0x3c, R10 + BLO one_byte_lz4s_s2 + CMPW $0x00000100, R10 + BLO two_bytes_lz4s_s2 + CMPW $0x00010000, R10 + BLO three_bytes_lz4s_s2 + CMPW $0x01000000, R10 + BLO four_bytes_lz4s_s2 + MOVD $0xfc, R16 + MOVB R16, (R0) + MOVW R10, 1(R0) + ADD $0x05, R0, R0 + JMP memmove_long_lz4s_s2 + +four_bytes_lz4s_s2: + MOVWU R10, R11 + LSRW $0x10, R11, R11 + MOVD $0xf8, R16 + MOVB R16, (R0) + MOVH R10, 1(R0) + MOVB R11, 3(R0) + ADD $0x04, R0, R0 + JMP memmove_long_lz4s_s2 + +three_bytes_lz4s_s2: + MOVD $0xf4, R16 + MOVB R16, (R0) + MOVH R10, 1(R0) + ADD $0x03, R0, R0 + JMP memmove_long_lz4s_s2 + +two_bytes_lz4s_s2: + MOVD $0xf0, R16 + MOVB R16, (R0) + MOVB R10, 1(R0) + ADD $0x02, R0, R0 + CMPW $0x40, R10 + BLO memmove_lz4s_s2 + JMP memmove_long_lz4s_s2 + +one_byte_lz4s_s2: + LSLW $0x02, R10, R16 + BFI $0, R16, $8, R10 + MOVB R10, (R0) + ADD $0x01, R0, R0 + +memmove_lz4s_s2: + ADD R8, R0, R10 + + // genMemMoveShort + CMP $0x08, R8 + BLS emit_lit_memmove_lz4s_s2_memmove_move_8 + CMP $0x10, R8 + BLS emit_lit_memmove_lz4s_s2_memmove_move_8through16 + CMP $0x20, R8 + BLS emit_lit_memmove_lz4s_s2_memmove_move_17through32 + JMP emit_lit_memmove_lz4s_s2_memmove_move_33through64 + +emit_lit_memmove_lz4s_s2_memmove_move_8: + MOVD (R2), R11 + MOVD R11, (R0) + JMP memmove_end_copy_lz4s_s2 + +emit_lit_memmove_lz4s_s2_memmove_move_8through16: + MOVD (R2), R11 + ADD R8, R2, R15 + MOVD -8(R15), R2 + MOVD R11, (R0) + ADD R8, R0, R15 + MOVD R2, -8(R15) + JMP memmove_end_copy_lz4s_s2 + +emit_lit_memmove_lz4s_s2_memmove_move_17through32: + FMOVQ (R2), F0 + ADD R8, R2, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R0) + ADD R8, R0, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_lz4s_s2 + +emit_lit_memmove_lz4s_s2_memmove_move_33through64: + FMOVQ (R2), F0 + FMOVQ 16(R2), F1 + ADD R8, R2, R15 + FMOVQ -32(R15), F2 + ADD R8, R2, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R0) + FMOVQ F1, 16(R0) + ADD R8, R0, R15 + FMOVQ F2, -32(R15) + ADD R8, R0, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_lz4s_s2: + MOVD R10, R0 + JMP lz4s_s2_lits_emit_done + +memmove_long_lz4s_s2: + ADD R8, R0, R10 + + // genMemMoveLong + MOVD R2, R11 + MOVD R0, R12 + MOVD R8, R13 + +emit_lit_memmove_long_lz4s_s2large_big_loop_back: + FMOVQ (R11), F0 + FMOVQ 16(R11), F1 + FMOVQ F0, (R12) + FMOVQ F1, 16(R12) + ADD $0x20, R11, R11 + ADD $0x20, R12, R12 + SUB $0x20, R13, R13 + CMP $0x20, R13 + BHS emit_lit_memmove_long_lz4s_s2large_big_loop_back + ADD R8, R2, R15 + FMOVQ -32(R15), F0 + ADD R8, R2, R15 + FMOVQ -16(R15), F1 + ADD R8, R0, R15 + FMOVQ F0, -32(R15) + ADD R8, R0, R15 + FMOVQ F1, -16(R15) + MOVD R10, R0 + +lz4s_s2_lits_emit_done: + MOVD R7, R2 + +lz4s_s2_lits_done: + CMP R3, R2 + BNE lz4s_s2_match + CMP $0x03, R9 + BEQ lz4s_s2_done + JMP lz4s_s2_corrupt + +lz4s_s2_match: + CMP $0x03, R9 + BEQ lz4s_s2_loop + ADD $2, R2, R7 + CMP R3, R7 + BHS lz4s_s2_corrupt + MOVHU (R2), R8 + MOVD R7, R2 + TST R8, R8 + BEQ lz4s_s2_corrupt + CMP R5, R8 + BHI lz4s_s2_corrupt + CMP $0x12, R9 + BNE lz4s_s2_ml_done + +lz4s_s2_ml_loop: + MOVBU (R2), R7 + ADD $1, R2, R2 + ADD R7, R9, R9 + CMP R3, R2 + BHS lz4s_s2_corrupt + CMP $0xff, R7 + BEQ lz4s_s2_ml_loop + +lz4s_s2_ml_done: + ADD R9, R5, R5 + CMP R6, R8 + BNE lz4s_s2_docopy + + // emitRepeat +emit_repeat_again_lz4_s2: + MOVWU R9, R7 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R7 + BLS repeat_two_lz4_s2 + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_lz4_s2 + CMPW $0x00000800, R8 + BLO repeat_two_offset_lz4_s2 + +cant_repeat_two_offset_lz4_s2: + CMPW $0x00000104, R9 + BLO repeat_three_lz4_s2 + CMPW $0x00010100, R9 + BLO repeat_four_lz4_s2 + CMPW $0x0100ffff, R9 + BLO repeat_five_lz4_s2 + SUB $16842747, R9, R9 + MOVWU R9, R9 + MOVD $0xfffb001d, R16 + MOVW R16, (R0) + MOVD $0xff, R16 + MOVB R16, 4(R0) + ADD $0x05, R0, R0 + JMP emit_repeat_again_lz4_s2 + +repeat_five_lz4_s2: + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R8 + MOVD $0x001d, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ASRW $0x10, R8, R8 + MOVB R8, 4(R0) + ADD $0x05, R0, R0 + JMP lz4s_s2_loop + +repeat_four_lz4_s2: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ADD $0x04, R0, R0 + JMP lz4s_s2_loop + +repeat_three_lz4_s2: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R0) + MOVB R9, 2(R0) + ADD $0x03, R0, R0 + JMP lz4s_s2_loop + +repeat_two_lz4_s2: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R0) + ADD $0x02, R0, R0 + JMP lz4s_s2_loop + +repeat_two_offset_lz4_s2: + MOVD $0, R7 + ADD R9<<2, R7, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R8, 1(R0) + ASRW $0x08, R8, R8 + LSLW $0x05, R8, R8 + ORRW R8, R9, R9 + MOVB R9, (R0) + ADD $0x02, R0, R0 + JMP lz4s_s2_loop + +lz4s_s2_docopy: + MOVD R8, R6 + + // emitCopy + CMPW $0x40, R9 + BLS two_byte_offset_short_lz4_s2 + CMPW $0x00000800, R8 + BHS long_offset_short_lz4_s2 + MOVD $0x00000001, R7 + ADD $16, R7, R7 + MOVWU R7, R7 + MOVB R8, 1(R0) + MOVWU R8, R10 + LSRW $0x08, R10, R10 + LSLW $0x05, R10, R10 + ORRW R10, R7, R7 + MOVB R7, (R0) + ADD $0x02, R0, R0 + SUBW $0x08, R9, R9 + + // emitRepeat + SUB $4, R9, R9 + MOVWU R9, R9 + JMP cant_repeat_two_offset_lz4_s2_emit_copy_short_2b + +emit_repeat_again_lz4_s2_emit_copy_short_2b: + MOVWU R9, R7 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R7 + BLS repeat_two_lz4_s2_emit_copy_short_2b + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_lz4_s2_emit_copy_short_2b + CMPW $0x00000800, R8 + BLO repeat_two_offset_lz4_s2_emit_copy_short_2b + +cant_repeat_two_offset_lz4_s2_emit_copy_short_2b: + CMPW $0x00000104, R9 + BLO repeat_three_lz4_s2_emit_copy_short_2b + CMPW $0x00010100, R9 + BLO repeat_four_lz4_s2_emit_copy_short_2b + CMPW $0x0100ffff, R9 + BLO repeat_five_lz4_s2_emit_copy_short_2b + SUB $16842747, R9, R9 + MOVWU R9, R9 + MOVD $0xfffb001d, R16 + MOVW R16, (R0) + MOVD $0xff, R16 + MOVB R16, 4(R0) + ADD $0x05, R0, R0 + JMP emit_repeat_again_lz4_s2_emit_copy_short_2b + +repeat_five_lz4_s2_emit_copy_short_2b: + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R8 + MOVD $0x001d, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ASRW $0x10, R8, R8 + MOVB R8, 4(R0) + ADD $0x05, R0, R0 + JMP lz4s_s2_loop + +repeat_four_lz4_s2_emit_copy_short_2b: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ADD $0x04, R0, R0 + JMP lz4s_s2_loop + +repeat_three_lz4_s2_emit_copy_short_2b: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R0) + MOVB R9, 2(R0) + ADD $0x03, R0, R0 + JMP lz4s_s2_loop + +repeat_two_lz4_s2_emit_copy_short_2b: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R0) + ADD $0x02, R0, R0 + JMP lz4s_s2_loop + +repeat_two_offset_lz4_s2_emit_copy_short_2b: + MOVD $0, R7 + ADD R9<<2, R7, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R8, 1(R0) + ASRW $0x08, R8, R8 + LSLW $0x05, R8, R8 + ORRW R8, R9, R9 + MOVB R9, (R0) + ADD $0x02, R0, R0 + JMP lz4s_s2_loop + +long_offset_short_lz4_s2: + MOVD $0xee, R16 + MOVB R16, (R0) + MOVH R8, 1(R0) + SUB $60, R9, R9 + MOVWU R9, R9 + ADD $0x03, R0, R0 + + // emitRepeat +emit_repeat_again_lz4_s2_emit_copy_short: + MOVWU R9, R7 + SUB $4, R9, R9 + MOVWU R9, R9 + CMPW $0x08, R7 + BLS repeat_two_lz4_s2_emit_copy_short + CMPW $0x0c, R7 + BHS cant_repeat_two_offset_lz4_s2_emit_copy_short + CMPW $0x00000800, R8 + BLO repeat_two_offset_lz4_s2_emit_copy_short + +cant_repeat_two_offset_lz4_s2_emit_copy_short: + CMPW $0x00000104, R9 + BLO repeat_three_lz4_s2_emit_copy_short + CMPW $0x00010100, R9 + BLO repeat_four_lz4_s2_emit_copy_short + CMPW $0x0100ffff, R9 + BLO repeat_five_lz4_s2_emit_copy_short + SUB $16842747, R9, R9 + MOVWU R9, R9 + MOVD $0xfffb001d, R16 + MOVW R16, (R0) + MOVD $0xff, R16 + MOVB R16, 4(R0) + ADD $0x05, R0, R0 + JMP emit_repeat_again_lz4_s2_emit_copy_short + +repeat_five_lz4_s2_emit_copy_short: + SUB $65536, R9, R9 + MOVWU R9, R9 + MOVWU R9, R8 + MOVD $0x001d, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ASRW $0x10, R8, R8 + MOVB R8, 4(R0) + ADD $0x05, R0, R0 + JMP lz4s_s2_loop + +repeat_four_lz4_s2_emit_copy_short: + SUB $256, R9, R9 + MOVWU R9, R9 + MOVD $0x0019, R16 + MOVH R16, (R0) + MOVH R9, 2(R0) + ADD $0x04, R0, R0 + JMP lz4s_s2_loop + +repeat_three_lz4_s2_emit_copy_short: + SUB $4, R9, R9 + MOVWU R9, R9 + MOVD $0x0015, R16 + MOVH R16, (R0) + MOVB R9, 2(R0) + ADD $0x03, R0, R0 + JMP lz4s_s2_loop + +repeat_two_lz4_s2_emit_copy_short: + LSLW $0x02, R9, R9 + ORRW $0x01, R9, R9 + MOVH R9, (R0) + ADD $0x02, R0, R0 + JMP lz4s_s2_loop + +repeat_two_offset_lz4_s2_emit_copy_short: + MOVD $0, R7 + ADD R9<<2, R7, R9 + ADD $1, R9, R9 + MOVWU R9, R9 + MOVB R8, 1(R0) + ASRW $0x08, R8, R8 + LSLW $0x05, R8, R8 + ORRW R8, R9, R9 + MOVB R9, (R0) + ADD $0x02, R0, R0 + JMP lz4s_s2_loop + +two_byte_offset_short_lz4_s2: + MOVWU R9, R7 + LSLW $0x02, R7, R7 + CMPW $0x0c, R9 + BHS emit_copy_three_lz4_s2 + CMPW $0x00000800, R8 + BHS emit_copy_three_lz4_s2 + SUB $15, R7, R7 + MOVWU R7, R7 + MOVB R8, 1(R0) + LSRW $0x08, R8, R8 + LSLW $0x05, R8, R8 + ORRW R8, R7, R7 + MOVB R7, (R0) + ADD $0x02, R0, R0 + JMP lz4s_s2_loop + +emit_copy_three_lz4_s2: + SUB $2, R7, R7 + MOVWU R7, R7 + MOVB R7, (R0) + MOVH R8, 1(R0) + ADD $0x03, R0, R0 + JMP lz4s_s2_loop + +lz4s_s2_done: + MOVD dst_base+0(FP), R1 + SUB R1, R0, R0 + MOVD R5, uncompressed+48(FP) + MOVD R0, dstUsed+56(FP) + RET + +lz4s_s2_corrupt: + MOVD $0, R0 + SUB $1, R0, R5 + MOVD R5, uncompressed+48(FP) + RET + +lz4s_s2_dstfull: + MOVD $0, R0 + SUB $2, R0, R5 + MOVD R5, uncompressed+48(FP) + RET + +// func cvtLZ4BlockSnappyAsm(dst []byte, src []byte) (uncompressed int, dstUsed int) +// Requires: SSE2 +TEXT ·cvtLZ4BlockSnappyAsm(SB), NOSPLIT, $0-64 + MOVD $0, R5 + MOVD dst_base+0(FP), R0 + MOVD dst_len+8(FP), R1 + MOVD src_base+24(FP), R2 + MOVD src_len+32(FP), R3 + ADD R3, R2, R3 + ADD R1, R0, R1 + SUB $8, R1, R1 + +lz4_snappy_loop: + CMP R3, R2 + BHS lz4_snappy_corrupt + CMP R1, R0 + BHS lz4_snappy_dstfull + MOVBU (R2), R6 + MOVD R6, R7 + MOVD R6, R8 + LSR $0x04, R7, R7 + AND $0x0f, R8, R8 + CMP $0xf0, R6 + BLO lz4_snappy_ll_end + +lz4_snappy_ll_loop: + ADD $1, R2, R2 + CMP R3, R2 + BHS lz4_snappy_corrupt + MOVBU (R2), R6 + ADD R6, R7, R7 + CMP $0xff, R6 + BEQ lz4_snappy_ll_loop + +lz4_snappy_ll_end: + ADD R7, R2, R6 + ADD $0x04, R8, R8 + CMP R3, R6 + BHS lz4_snappy_corrupt + ADD $1, R2, R2 + ADD $1, R6, R6 + TST R7, R7 + BEQ lz4_snappy_lits_done + ADD R7, R0, R9 + CMP R1, R9 + BHS lz4_snappy_dstfull + ADD R7, R5, R5 + SUB $1, R7, R9 + MOVWU R9, R9 + CMPW $0x3c, R9 + BLO one_byte_lz4_snappy + CMPW $0x00000100, R9 + BLO two_bytes_lz4_snappy + CMPW $0x00010000, R9 + BLO three_bytes_lz4_snappy + CMPW $0x01000000, R9 + BLO four_bytes_lz4_snappy + MOVD $0xfc, R16 + MOVB R16, (R0) + MOVW R9, 1(R0) + ADD $0x05, R0, R0 + JMP memmove_long_lz4_snappy + +four_bytes_lz4_snappy: + MOVWU R9, R10 + LSRW $0x10, R10, R10 + MOVD $0xf8, R16 + MOVB R16, (R0) + MOVH R9, 1(R0) + MOVB R10, 3(R0) + ADD $0x04, R0, R0 + JMP memmove_long_lz4_snappy + +three_bytes_lz4_snappy: + MOVD $0xf4, R16 + MOVB R16, (R0) + MOVH R9, 1(R0) + ADD $0x03, R0, R0 + JMP memmove_long_lz4_snappy + +two_bytes_lz4_snappy: + MOVD $0xf0, R16 + MOVB R16, (R0) + MOVB R9, 1(R0) + ADD $0x02, R0, R0 + CMPW $0x40, R9 + BLO memmove_lz4_snappy + JMP memmove_long_lz4_snappy + +one_byte_lz4_snappy: + LSLW $0x02, R9, R16 + BFI $0, R16, $8, R9 + MOVB R9, (R0) + ADD $0x01, R0, R0 + +memmove_lz4_snappy: + ADD R7, R0, R9 + + // genMemMoveShort + CMP $0x08, R7 + BLS emit_lit_memmove_lz4_snappy_memmove_move_8 + CMP $0x10, R7 + BLS emit_lit_memmove_lz4_snappy_memmove_move_8through16 + CMP $0x20, R7 + BLS emit_lit_memmove_lz4_snappy_memmove_move_17through32 + JMP emit_lit_memmove_lz4_snappy_memmove_move_33through64 + +emit_lit_memmove_lz4_snappy_memmove_move_8: + MOVD (R2), R10 + MOVD R10, (R0) + JMP memmove_end_copy_lz4_snappy + +emit_lit_memmove_lz4_snappy_memmove_move_8through16: + MOVD (R2), R10 + ADD R7, R2, R15 + MOVD -8(R15), R2 + MOVD R10, (R0) + ADD R7, R0, R15 + MOVD R2, -8(R15) + JMP memmove_end_copy_lz4_snappy + +emit_lit_memmove_lz4_snappy_memmove_move_17through32: + FMOVQ (R2), F0 + ADD R7, R2, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R0) + ADD R7, R0, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_lz4_snappy + +emit_lit_memmove_lz4_snappy_memmove_move_33through64: + FMOVQ (R2), F0 + FMOVQ 16(R2), F1 + ADD R7, R2, R15 + FMOVQ -32(R15), F2 + ADD R7, R2, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R0) + FMOVQ F1, 16(R0) + ADD R7, R0, R15 + FMOVQ F2, -32(R15) + ADD R7, R0, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_lz4_snappy: + MOVD R9, R0 + JMP lz4_snappy_lits_emit_done + +memmove_long_lz4_snappy: + ADD R7, R0, R9 + + // genMemMoveLong + MOVD R2, R10 + MOVD R0, R11 + MOVD R7, R12 + +emit_lit_memmove_long_lz4_snappylarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R11) + FMOVQ F1, 16(R11) + ADD $0x20, R10, R10 + ADD $0x20, R11, R11 + SUB $0x20, R12, R12 + CMP $0x20, R12 + BHS emit_lit_memmove_long_lz4_snappylarge_big_loop_back + ADD R7, R2, R15 + FMOVQ -32(R15), F0 + ADD R7, R2, R15 + FMOVQ -16(R15), F1 + ADD R7, R0, R15 + FMOVQ F0, -32(R15) + ADD R7, R0, R15 + FMOVQ F1, -16(R15) + MOVD R9, R0 + +lz4_snappy_lits_emit_done: + MOVD R6, R2 + +lz4_snappy_lits_done: + CMP R3, R2 + BNE lz4_snappy_match + CMP $0x04, R8 + BEQ lz4_snappy_done + JMP lz4_snappy_corrupt + +lz4_snappy_match: + ADD $2, R2, R6 + CMP R3, R6 + BHS lz4_snappy_corrupt + MOVHU (R2), R7 + MOVD R6, R2 + TST R7, R7 + BEQ lz4_snappy_corrupt + CMP R5, R7 + BHI lz4_snappy_corrupt + CMP $0x13, R8 + BNE lz4_snappy_ml_done + +lz4_snappy_ml_loop: + MOVBU (R2), R6 + ADD $1, R2, R2 + ADD R6, R8, R8 + CMP R3, R2 + BHS lz4_snappy_corrupt + CMP $0xff, R6 + BEQ lz4_snappy_ml_loop + +lz4_snappy_ml_done: + ADD R8, R5, R5 + + // emitCopy +two_byte_offset_lz4_s2: + CMPW $0x40, R8 + BLS two_byte_offset_short_lz4_s2 + MOVD $0xee, R16 + MOVB R16, (R0) + MOVH R7, 1(R0) + SUB $60, R8, R8 + MOVWU R8, R8 + ADD $0x03, R0, R0 + CMP R1, R0 + BHS lz4_snappy_loop + JMP two_byte_offset_lz4_s2 + +two_byte_offset_short_lz4_s2: + MOVWU R8, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R8 + BHS emit_copy_three_lz4_s2 + CMPW $0x00000800, R7 + BHS emit_copy_three_lz4_s2 + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R7, 1(R0) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R6, R6 + MOVB R6, (R0) + ADD $0x02, R0, R0 + JMP lz4_snappy_loop + +emit_copy_three_lz4_s2: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R0) + MOVH R7, 1(R0) + ADD $0x03, R0, R0 + JMP lz4_snappy_loop + +lz4_snappy_done: + MOVD dst_base+0(FP), R1 + SUB R1, R0, R0 + MOVD R5, uncompressed+48(FP) + MOVD R0, dstUsed+56(FP) + RET + +lz4_snappy_corrupt: + MOVD $0, R0 + SUB $1, R0, R5 + MOVD R5, uncompressed+48(FP) + RET + +lz4_snappy_dstfull: + MOVD $0, R0 + SUB $2, R0, R5 + MOVD R5, uncompressed+48(FP) + RET + +// func cvtLZ4sBlockSnappyAsm(dst []byte, src []byte) (uncompressed int, dstUsed int) +// Requires: SSE2 +TEXT ·cvtLZ4sBlockSnappyAsm(SB), NOSPLIT, $0-64 + MOVD $0, R5 + MOVD dst_base+0(FP), R0 + MOVD dst_len+8(FP), R1 + MOVD src_base+24(FP), R2 + MOVD src_len+32(FP), R3 + ADD R3, R2, R3 + ADD R1, R0, R1 + SUB $8, R1, R1 + +lz4s_snappy_loop: + CMP R3, R2 + BHS lz4s_snappy_corrupt + CMP R1, R0 + BHS lz4s_snappy_dstfull + MOVBU (R2), R6 + MOVD R6, R7 + MOVD R6, R8 + LSR $0x04, R7, R7 + AND $0x0f, R8, R8 + CMP $0xf0, R6 + BLO lz4s_snappy_ll_end + +lz4s_snappy_ll_loop: + ADD $1, R2, R2 + CMP R3, R2 + BHS lz4s_snappy_corrupt + MOVBU (R2), R6 + ADD R6, R7, R7 + CMP $0xff, R6 + BEQ lz4s_snappy_ll_loop + +lz4s_snappy_ll_end: + ADD R7, R2, R6 + ADD $0x03, R8, R8 + CMP R3, R6 + BHS lz4s_snappy_corrupt + ADD $1, R2, R2 + ADD $1, R6, R6 + TST R7, R7 + BEQ lz4s_snappy_lits_done + ADD R7, R0, R9 + CMP R1, R9 + BHS lz4s_snappy_dstfull + ADD R7, R5, R5 + SUB $1, R7, R9 + MOVWU R9, R9 + CMPW $0x3c, R9 + BLO one_byte_lz4s_snappy + CMPW $0x00000100, R9 + BLO two_bytes_lz4s_snappy + CMPW $0x00010000, R9 + BLO three_bytes_lz4s_snappy + CMPW $0x01000000, R9 + BLO four_bytes_lz4s_snappy + MOVD $0xfc, R16 + MOVB R16, (R0) + MOVW R9, 1(R0) + ADD $0x05, R0, R0 + JMP memmove_long_lz4s_snappy + +four_bytes_lz4s_snappy: + MOVWU R9, R10 + LSRW $0x10, R10, R10 + MOVD $0xf8, R16 + MOVB R16, (R0) + MOVH R9, 1(R0) + MOVB R10, 3(R0) + ADD $0x04, R0, R0 + JMP memmove_long_lz4s_snappy + +three_bytes_lz4s_snappy: + MOVD $0xf4, R16 + MOVB R16, (R0) + MOVH R9, 1(R0) + ADD $0x03, R0, R0 + JMP memmove_long_lz4s_snappy + +two_bytes_lz4s_snappy: + MOVD $0xf0, R16 + MOVB R16, (R0) + MOVB R9, 1(R0) + ADD $0x02, R0, R0 + CMPW $0x40, R9 + BLO memmove_lz4s_snappy + JMP memmove_long_lz4s_snappy + +one_byte_lz4s_snappy: + LSLW $0x02, R9, R16 + BFI $0, R16, $8, R9 + MOVB R9, (R0) + ADD $0x01, R0, R0 + +memmove_lz4s_snappy: + ADD R7, R0, R9 + + // genMemMoveShort + CMP $0x08, R7 + BLS emit_lit_memmove_lz4s_snappy_memmove_move_8 + CMP $0x10, R7 + BLS emit_lit_memmove_lz4s_snappy_memmove_move_8through16 + CMP $0x20, R7 + BLS emit_lit_memmove_lz4s_snappy_memmove_move_17through32 + JMP emit_lit_memmove_lz4s_snappy_memmove_move_33through64 + +emit_lit_memmove_lz4s_snappy_memmove_move_8: + MOVD (R2), R10 + MOVD R10, (R0) + JMP memmove_end_copy_lz4s_snappy + +emit_lit_memmove_lz4s_snappy_memmove_move_8through16: + MOVD (R2), R10 + ADD R7, R2, R15 + MOVD -8(R15), R2 + MOVD R10, (R0) + ADD R7, R0, R15 + MOVD R2, -8(R15) + JMP memmove_end_copy_lz4s_snappy + +emit_lit_memmove_lz4s_snappy_memmove_move_17through32: + FMOVQ (R2), F0 + ADD R7, R2, R15 + FMOVQ -16(R15), F1 + FMOVQ F0, (R0) + ADD R7, R0, R15 + FMOVQ F1, -16(R15) + JMP memmove_end_copy_lz4s_snappy + +emit_lit_memmove_lz4s_snappy_memmove_move_33through64: + FMOVQ (R2), F0 + FMOVQ 16(R2), F1 + ADD R7, R2, R15 + FMOVQ -32(R15), F2 + ADD R7, R2, R15 + FMOVQ -16(R15), F3 + FMOVQ F0, (R0) + FMOVQ F1, 16(R0) + ADD R7, R0, R15 + FMOVQ F2, -32(R15) + ADD R7, R0, R15 + FMOVQ F3, -16(R15) + +memmove_end_copy_lz4s_snappy: + MOVD R9, R0 + JMP lz4s_snappy_lits_emit_done + +memmove_long_lz4s_snappy: + ADD R7, R0, R9 + + // genMemMoveLong + MOVD R2, R10 + MOVD R0, R11 + MOVD R7, R12 + +emit_lit_memmove_long_lz4s_snappylarge_big_loop_back: + FMOVQ (R10), F0 + FMOVQ 16(R10), F1 + FMOVQ F0, (R11) + FMOVQ F1, 16(R11) + ADD $0x20, R10, R10 + ADD $0x20, R11, R11 + SUB $0x20, R12, R12 + CMP $0x20, R12 + BHS emit_lit_memmove_long_lz4s_snappylarge_big_loop_back + ADD R7, R2, R15 + FMOVQ -32(R15), F0 + ADD R7, R2, R15 + FMOVQ -16(R15), F1 + ADD R7, R0, R15 + FMOVQ F0, -32(R15) + ADD R7, R0, R15 + FMOVQ F1, -16(R15) + MOVD R9, R0 + +lz4s_snappy_lits_emit_done: + MOVD R6, R2 + +lz4s_snappy_lits_done: + CMP R3, R2 + BNE lz4s_snappy_match + CMP $0x03, R8 + BEQ lz4s_snappy_done + JMP lz4s_snappy_corrupt + +lz4s_snappy_match: + CMP $0x03, R8 + BEQ lz4s_snappy_loop + ADD $2, R2, R6 + CMP R3, R6 + BHS lz4s_snappy_corrupt + MOVHU (R2), R7 + MOVD R6, R2 + TST R7, R7 + BEQ lz4s_snappy_corrupt + CMP R5, R7 + BHI lz4s_snappy_corrupt + CMP $0x12, R8 + BNE lz4s_snappy_ml_done + +lz4s_snappy_ml_loop: + MOVBU (R2), R6 + ADD $1, R2, R2 + ADD R6, R8, R8 + CMP R3, R2 + BHS lz4s_snappy_corrupt + CMP $0xff, R6 + BEQ lz4s_snappy_ml_loop + +lz4s_snappy_ml_done: + ADD R8, R5, R5 + + // emitCopy +two_byte_offset_lz4_s2: + CMPW $0x40, R8 + BLS two_byte_offset_short_lz4_s2 + MOVD $0xee, R16 + MOVB R16, (R0) + MOVH R7, 1(R0) + SUB $60, R8, R8 + MOVWU R8, R8 + ADD $0x03, R0, R0 + CMP R1, R0 + BHS lz4s_snappy_loop + JMP two_byte_offset_lz4_s2 + +two_byte_offset_short_lz4_s2: + MOVWU R8, R6 + LSLW $0x02, R6, R6 + CMPW $0x0c, R8 + BHS emit_copy_three_lz4_s2 + CMPW $0x00000800, R7 + BHS emit_copy_three_lz4_s2 + SUB $15, R6, R6 + MOVWU R6, R6 + MOVB R7, 1(R0) + LSRW $0x08, R7, R7 + LSLW $0x05, R7, R7 + ORRW R7, R6, R6 + MOVB R6, (R0) + ADD $0x02, R0, R0 + JMP lz4s_snappy_loop + +emit_copy_three_lz4_s2: + SUB $2, R6, R6 + MOVWU R6, R6 + MOVB R6, (R0) + MOVH R7, 1(R0) + ADD $0x03, R0, R0 + JMP lz4s_snappy_loop + +lz4s_snappy_done: + MOVD dst_base+0(FP), R1 + SUB R1, R0, R0 + MOVD R5, uncompressed+48(FP) + MOVD R0, dstUsed+56(FP) + RET + +lz4s_snappy_corrupt: + MOVD $0, R0 + SUB $1, R0, R5 + MOVD R5, uncompressed+48(FP) + RET + +lz4s_snappy_dstfull: + MOVD $0, R0 + SUB $2, R0, R5 + MOVD R5, uncompressed+48(FP) + RET diff --git a/src/vendor/github.com/klauspost/compress/s2/encodeblock_amd64.go b/src/vendor/github.com/klauspost/compress/s2/encodeblock_asm.go similarity index 98% rename from src/vendor/github.com/klauspost/compress/s2/encodeblock_amd64.go rename to src/vendor/github.com/klauspost/compress/s2/encodeblock_asm.go index f43aa815..fb602efd 100644 --- a/src/vendor/github.com/klauspost/compress/s2/encodeblock_amd64.go +++ b/src/vendor/github.com/klauspost/compress/s2/encodeblock_asm.go @@ -1,6 +1,6 @@ -// Code generated by command: go run gen.go -out ../encodeblock_amd64.s -stubs ../encodeblock_amd64.go -pkg=s2. DO NOT EDIT. +// Code generated by command: go run gen.go -out ../encodeblock_amd64.s -stubs ../encodeblock_asm.go -pkg=s2. DO NOT EDIT. -//go:build !appengine && !noasm && gc && !noasm +//go:build (amd64 || arm64) && !appengine && !noasm && gc && !noasm package s2 diff --git a/src/vendor/github.com/klauspost/compress/s2/lz4convert.go b/src/vendor/github.com/klauspost/compress/s2/lz4convert.go index 46ed908e..01b5fb5c 100644 --- a/src/vendor/github.com/klauspost/compress/s2/lz4convert.go +++ b/src/vendor/github.com/klauspost/compress/s2/lz4convert.go @@ -32,7 +32,7 @@ func (l *LZ4Converter) ConvertBlock(dst, src []byte) ([]byte, int, error) { s, d := 0, len(dst) dst = dst[:cap(dst)] - if !debug && hasAmd64Asm { + if !debug && hasAsm { res, sz := cvtLZ4BlockAsm(dst[d:], src) if res < 0 { const ( @@ -288,7 +288,7 @@ func (l *LZ4Converter) ConvertBlockSnappy(dst, src []byte) ([]byte, int, error) s, d := 0, len(dst) dst = dst[:cap(dst)] // Use assembly when possible - if !debug && hasAmd64Asm { + if !debug && hasAsm { res, sz := cvtLZ4BlockSnappyAsm(dst[d:], src) if res < 0 { const ( diff --git a/src/vendor/github.com/klauspost/compress/s2/lz4sconvert.go b/src/vendor/github.com/klauspost/compress/s2/lz4sconvert.go index 000f3971..7b4de58f 100644 --- a/src/vendor/github.com/klauspost/compress/s2/lz4sconvert.go +++ b/src/vendor/github.com/klauspost/compress/s2/lz4sconvert.go @@ -37,7 +37,7 @@ func (l *LZ4sConverter) ConvertBlock(dst, src []byte) ([]byte, int, error) { s, d := 0, len(dst) dst = dst[:cap(dst)] - if !debug && hasAmd64Asm { + if !debug && hasAsm { res, sz := cvtLZ4sBlockAsm(dst[d:], src) if res < 0 { const ( @@ -297,7 +297,7 @@ func (l *LZ4sConverter) ConvertBlockSnappy(dst, src []byte) ([]byte, int, error) s, d := 0, len(dst) dst = dst[:cap(dst)] // Use assembly when possible - if !debug && hasAmd64Asm { + if !debug && hasAsm { res, sz := cvtLZ4sBlockSnappyAsm(dst[d:], src) if res < 0 { const ( diff --git a/src/vendor/github.com/klauspost/compress/s2/reader.go b/src/vendor/github.com/klauspost/compress/s2/reader.go index 17443e2c..5c6cb4cf 100644 --- a/src/vendor/github.com/klauspost/compress/s2/reader.go +++ b/src/vendor/github.com/klauspost/compress/s2/reader.go @@ -451,9 +451,7 @@ func (r *Reader) DecodeConcurrent(w io.Writer, concurrent int) (written int64, e } // Writer var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { for toWrite := range queue { entry := <-toWrite reUse <- toWrite @@ -480,7 +478,7 @@ func (r *Reader) DecodeConcurrent(w io.Writer, concurrent int) (written int64, e } aWritten += int64(n) } - }() + }) defer func() { if r.err != nil { diff --git a/src/vendor/github.com/klauspost/compress/s2/writer.go b/src/vendor/github.com/klauspost/compress/s2/writer.go index 09f1cff3..8cf2e4e9 100644 --- a/src/vendor/github.com/klauspost/compress/s2/writer.go +++ b/src/vendor/github.com/klauspost/compress/s2/writer.go @@ -139,11 +139,9 @@ func (w *Writer) Reset(writer io.Writer) { toWrite := make(chan chan result, w.concurrency) w.output = toWrite - w.writerWg.Add(1) // Start a writer goroutine that will write all output in order. - go func() { - defer w.writerWg.Done() + w.writerWg.Go(func() { // Get a queued write. for write := range toWrite { @@ -175,7 +173,7 @@ func (w *Writer) Reset(writer io.Writer) { // This can be used for synchronizing flushes. close(write) } - }() + }) } // Write satisfies the io.Writer interface. diff --git a/src/vendor/github.com/klauspost/compress/zstd/blockdec.go b/src/vendor/github.com/klauspost/compress/zstd/blockdec.go index 2329e996..51f9da03 100644 --- a/src/vendor/github.com/klauspost/compress/zstd/blockdec.go +++ b/src/vendor/github.com/klauspost/compress/zstd/blockdec.go @@ -400,8 +400,9 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err } } var err error - // Use our out buffer. - huff.MaxDecodedSize = litRegenSize + // Decoder.Decompress* uses cap(dst) for the size limit. Do not write + // MaxDecodedSize on hist.huffTree: with a trained dictionary that + // pointer aliases the shared dict.litEnc and concurrent DecodeAll races. if fourStreams { literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals) } else { @@ -673,10 +674,6 @@ func (b *blockDec) executeSequences(hist *history) error { hbytes := hist.b if len(hbytes) > hist.windowSize { hbytes = hbytes[len(hbytes)-hist.windowSize:] - // We do not need history anymore. - if hist.dict != nil { - hist.dict.content = nil - } } hist.decoders.windowSize = hist.windowSize hist.decoders.out = b.dst[:0] diff --git a/src/vendor/github.com/klauspost/compress/zstd/dict.go b/src/vendor/github.com/klauspost/compress/zstd/dict.go index 4f1c4938..67f40e79 100644 --- a/src/vendor/github.com/klauspost/compress/zstd/dict.go +++ b/src/vendor/github.com/klauspost/compress/zstd/dict.go @@ -296,40 +296,81 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { if offset > 3 { newOffsets[offset-3]++ } else { - newOffsets[uint32(o.Offsets[offset-1])]++ + // Repeat codes reference the training Offsets. Skip unset + // (zero) entries so they are not ranked as real offsets. + prev := o.Offsets[offset-1] + if prev > 0 { + newOffsets[uint32(prev)]++ + } } } } // Find most used offsets. var sortedOffsets []uint32 for k := range newOffsets { + if k == 0 { + continue + } sortedOffsets = append(sortedOffsets, k) } sort.Slice(sortedOffsets, func(i, j int) bool { a, b := sortedOffsets[i], sortedOffsets[j] - if a == b { + ca, cb := newOffsets[a], newOffsets[b] + if ca == cb { // Prefer the longer offset - return sortedOffsets[i] > sortedOffsets[j] + return a > b } - return newOffsets[sortedOffsets[i]] > newOffsets[sortedOffsets[j]] + return ca > cb }) - if len(sortedOffsets) > 3 { - if debug { - print("Offsets:") - for i, v := range sortedOffsets { - if i > 20 { - break - } - printf("[%d: %d],", v, newOffsets[v]) + if debug { + print("Offsets:") + for i, v := range sortedOffsets { + if i > 20 { + break } - println("") + printf("[%d: %d],", v, newOffsets[v]) + } + println("") + } + // Dictionary recent-offsets must be three positive values within the + // history. Ranked matches may be fewer (or empty when only unset + // repeat codes were seen), so fill remaining slots with defaults. + used := make(map[int]bool, 3) + var finalOffsets [3]int + nOff := 0 + for _, v := range sortedOffsets { + iv := int(v) + if iv <= 0 || iv > len(hist) || used[iv] { + continue + } + finalOffsets[nOff] = iv + used[iv] = true + nOff++ + if nOff == 3 { + break } - - sortedOffsets = sortedOffsets[:3] } - for i, v := range sortedOffsets { - o.Offsets[i] = int(v) + for _, def := range []int{1, 4, 8} { + if nOff == 3 { + break + } + if def <= len(hist) && !used[def] { + finalOffsets[nOff] = def + used[def] = true + nOff++ + } + } + for def := 1; nOff < 3 && def <= len(hist); def++ { + if !used[def] { + finalOffsets[nOff] = def + used[def] = true + nOff++ + } + } + if nOff < 3 { + return nil, fmt.Errorf("could not determine 3 valid dictionary offsets (history size %d)", len(hist)) } + o.Offsets = finalOffsets if debug { println("New repeat offsets", o.Offsets) } @@ -337,6 +378,9 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { if nUsed == 0 || seqs == 0 { return nil, fmt.Errorf("%d blocks, %d sequences found", nUsed, seqs) } + if litTotal == 0 { + return nil, errors.New("0 literals found") + } if debug { println("Sequences:", seqs, "Blocks:", nUsed, "Literals:", litTotal) } @@ -517,11 +561,10 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[1]))) out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[2]))) out.Write(hist) + if _, err := loadDict(out.Bytes()); err != nil { + return nil, fmt.Errorf("built dictionary failed validation: %w", err) + } if debug { - _, err := loadDict(out.Bytes()) - if err != nil { - panic(err) - } i, err := InspectDictionary(out.Bytes()) if err != nil { panic(err) diff --git a/src/vendor/github.com/klauspost/compress/zstd/fse_decoder_arm64.s b/src/vendor/github.com/klauspost/compress/zstd/fse_decoder_arm64.s index 77ee3913..b6b46078 100644 --- a/src/vendor/github.com/klauspost/compress/zstd/fse_decoder_arm64.s +++ b/src/vendor/github.com/klauspost/compress/zstd/fse_decoder_arm64.s @@ -1,7 +1,7 @@ // Code generated by command: go run gen_fse.go -out ../fse_decoder.s -arch amd64,arm64 -pkg=zstd. DO NOT EDIT. // EXPERIMENTAL arm64 output lowered from an amd64 avo program. -//go:build arm64 && !appengine && !noasm && gc && !noasm +//go:build arm64 && (!appengine && !noasm && gc && !noasm) // func buildDtable_asm(s *fseDecoder, ctx *buildDtableAsmContext) int TEXT ·buildDtable_asm(SB), $0-24 @@ -26,11 +26,10 @@ TEXT ·buildDtable_asm(SB), $0-24 JMP init_main_loop_condition init_main_loop: - ADD R8<<1, R1, R15 - MOVH (R15), R9 - AND $0xffff, R9, R15 + MOVH (R1)(R8<<1), R9 MOVD $-1, R16 AND $0xffff, R16, R16 + AND $0xffff, R9, R15 CMP R16, R15 BNE do_not_update_high_threshold ADD R7<<3, R5, R15 @@ -39,8 +38,7 @@ init_main_loop: MOVD $0x0000000000000001, R9 do_not_update_high_threshold: - ADD R8<<1, R3, R15 - MOVH R9, (R15) + MOVH R9, (R3)(R8<<1) ADD $1, R8, R8 init_main_loop_condition: @@ -64,8 +62,7 @@ init_main_loop_condition: spread_main_loop: MOVD $0, R12 - ADD R11<<1, R1, R15 - MOVH (R15), R13 + MOVH (R1)(R11<<1), R13 JMP spread_inner_loop_condition spread_inner_loop: @@ -102,11 +99,9 @@ spread_check_ok: build_table_main_table: ADD R6<<3, R5, R15 MOVBU 1(R15), R1 - ADD R1<<1, R3, R15 - MOVHU (R15), R7 + MOVHU (R3)(R1<<1), R7 ADD $1, R7, R8 - ADD R1<<1, R3, R15 - MOVH R8, (R15) + MOVH R8, (R3)(R1<<1) MOVD R7, R8 CLZ R8, R16 MOVD $63, R8 @@ -129,12 +124,10 @@ build_table_main_table: RET build_table_check1_ok: - AND $0xff, R1, R15 - AND $0xff, R1, R16 - TST R16, R15 + TST $0xff, R1 BNE build_table_check2_ok - AND $0xffff, R7, R15 AND $0xffff, R6, R16 + AND $0xffff, R7, R15 CMP R16, R15 BNE build_table_check2_ok MOVD ctx+8(FP), R0 diff --git a/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go b/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go index fc40c820..9c0cbc16 100644 --- a/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go +++ b/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go @@ -52,6 +52,11 @@ func (d *Digest) Reset() { d.n = 0 } +// maxAsmSize bounds the input handed to a single writeBlocks call. Assembly is +// never preemptible, so an unbounded call holds every P in stop-the-world for +// its duration. Whole 32-byte blocks, so Write can feed it in pieces. +const maxAsmSize = 128 << 10 // 4096 whole 32-byte blocks + // Size always returns 8 bytes. func (d *Digest) Size() int { return 8 } @@ -83,6 +88,13 @@ func (d *Digest) Write(b []byte) (n int, err error) { d.n = 0 } + for len(b) >= maxAsmSize { + // Assembly is not preemptible, so hashing a large buffer in one call + // blocks every stop-the-world for the whole call. Feed it in chunks. + writeBlocks(d, b[:maxAsmSize]) + b = b[maxAsmSize:] + } + if len(b) >= 32 { // One or more full blocks left. nw := writeBlocks(d, b) diff --git a/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s b/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s index ddb63aa9..e4c688ef 100644 --- a/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s +++ b/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s @@ -175,7 +175,11 @@ finalize: RET // func writeBlocks(d *Digest, b []byte) int -TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 +// +// Deliberately not NOSPLIT: the stack check is the preemption point that lets a +// stop-the-world proceed between chunks. The frame must be >= abi.StackSmall +// (128), or the assembler marks this leaf NOSPLIT anyway and drops that check. +TEXT ·writeBlocks(SB), $128-40 // Load fixed primes needed for round. MOVQ ·primes+0(SB), prime1 MOVQ ·primes+8(SB), prime2 diff --git a/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s b/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s index ae7d4d32..e88cc2fc 100644 --- a/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s +++ b/src/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s @@ -163,7 +163,11 @@ finalize: RET // func writeBlocks(s *Digest, b []byte) int -TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 +// +// Deliberately not NOSPLIT: the stack check is the preemption point that lets a +// stop-the-world proceed between chunks. The frame must be >= abi.StackSmall +// (128), or the assembler marks this leaf NOSPLIT anyway and drops that check. +TEXT ·writeBlocks(SB), $128-40 LDP ·primes+0(SB), (prime1, prime2) // Load state. Assume v[1-4] are stored contiguously. diff --git a/src/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s b/src/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s index 3fc381c7..9c4f8d35 100644 --- a/src/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s +++ b/src/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s @@ -55,43 +55,43 @@ sequenceDecs_decode_amd64_fill_check_overread: sequenceDecs_decode_amd64_fill_end: // Update offset - MOVQ R9, AX - MOVQ BX, CX - MOVQ DX, R15 - SHLQ CL, R15 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decode_amd64_of_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decode_amd64_of_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decode_amd64_of_update_zero - NEGQ CX - SHRQ CL, R15 - ADDQ R15, AX + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_amd64_of_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX sequenceDecs_decode_amd64_of_update_zero: MOVQ AX, 16(R10) // Update match length - MOVQ R8, AX - MOVQ BX, CX - MOVQ DX, R15 - SHLQ CL, R15 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decode_amd64_ml_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decode_amd64_ml_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decode_amd64_ml_update_zero - NEGQ CX - SHRQ CL, R15 - ADDQ R15, AX + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX sequenceDecs_decode_amd64_ml_update_zero: MOVQ AX, 8(R10) @@ -126,22 +126,22 @@ sequenceDecs_decode_amd64_fill_2_check_overread: sequenceDecs_decode_amd64_fill_2_end: // Update literal length - MOVQ DI, AX - MOVQ BX, CX - MOVQ DX, R15 - SHLQ CL, R15 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decode_amd64_ll_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decode_amd64_ll_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decode_amd64_ll_update_zero - NEGQ CX - SHRQ CL, R15 - ADDQ R15, AX + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX sequenceDecs_decode_amd64_ll_update_zero: MOVQ AX, (R10) @@ -163,7 +163,7 @@ sequenceDecs_decode_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R15 MOVL $0x00000001, BP - MOVB R14, CL + MOVBLZX R14, CX SHLL CL, BP DECL BP ANDQ BP, R15 @@ -182,7 +182,7 @@ sequenceDecs_decode_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R15 MOVL $0x00000001, BP - MOVB R14, CL + MOVBLZX R14, CX SHLL CL, BP DECL BP ANDQ BP, R15 @@ -201,7 +201,7 @@ sequenceDecs_decode_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R15 MOVL $0x00000001, BP - MOVB R14, CL + MOVBLZX R14, CX SHLL CL, BP DECL BP ANDQ BP, R15 @@ -383,64 +383,64 @@ sequenceDecs_decode_56_amd64_fill_check_overread: sequenceDecs_decode_56_amd64_fill_end: // Update offset - MOVQ R9, AX - MOVQ BX, CX - MOVQ DX, R15 - SHLQ CL, R15 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decode_56_amd64_of_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decode_56_amd64_of_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decode_56_amd64_of_update_zero - NEGQ CX - SHRQ CL, R15 - ADDQ R15, AX + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_56_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_56_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_56_amd64_of_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX sequenceDecs_decode_56_amd64_of_update_zero: MOVQ AX, 16(R10) // Update match length - MOVQ R8, AX - MOVQ BX, CX - MOVQ DX, R15 - SHLQ CL, R15 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decode_56_amd64_ml_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decode_56_amd64_ml_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decode_56_amd64_ml_update_zero - NEGQ CX - SHRQ CL, R15 - ADDQ R15, AX + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_56_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_56_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_56_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX sequenceDecs_decode_56_amd64_ml_update_zero: MOVQ AX, 8(R10) // Update literal length - MOVQ DI, AX - MOVQ BX, CX - MOVQ DX, R15 - SHLQ CL, R15 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decode_56_amd64_ll_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decode_56_amd64_ll_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decode_56_amd64_ll_update_zero - NEGQ CX - SHRQ CL, R15 - ADDQ R15, AX + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_56_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_56_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_56_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX sequenceDecs_decode_56_amd64_ll_update_zero: MOVQ AX, (R10) @@ -462,7 +462,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R15 MOVL $0x00000001, BP - MOVB R14, CL + MOVBLZX R14, CX SHLL CL, BP DECL BP ANDQ BP, R15 @@ -481,7 +481,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R15 MOVL $0x00000001, BP - MOVB R14, CL + MOVBLZX R14, CX SHLL CL, BP DECL BP ANDQ BP, R15 @@ -500,7 +500,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R15 MOVL $0x00000001, BP - MOVB R14, CL + MOVBLZX R14, CX SHLL CL, BP DECL BP ANDQ BP, R15 @@ -1258,13 +1258,13 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVW (R14), R11 - MOVB 2(R14), R12 - MOVW R11, (BX) - MOVB R12, 2(BX) - ADDQ R13, R14 - ADDQ R13, BX - JMP copy_4_end + MOVWQZX (R14), R11 + MOVB 2(R14), R12 + MOVW R11, (BX) + MOVB R12, 2(BX) + ADDQ R13, R14 + ADDQ R13, BX + JMP copy_4_end copy_4_move_4through7: MOVL (R14), R11 @@ -1327,13 +1327,13 @@ copy_5_move_1or2: JMP copy_5_end copy_5_move_3: - MOVW (R14), R15 - MOVB 2(R14), BP - MOVW R15, (BX) - MOVB BP, 2(BX) - ADDQ R11, R14 - ADDQ R11, BX - JMP copy_5_end + MOVWQZX (R14), R15 + MOVB 2(R14), BP + MOVW R15, (BX) + MOVB BP, 2(BX) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 @@ -1384,12 +1384,12 @@ copy_overlapping_match: ADDQ R13, DI copy_slow_3: - MOVB (R11), R12 - MOVB R12, (BX) - INCQ R11 - INCQ BX - DECQ R13 - JNZ copy_slow_3 + MOVBQZX (R11), R12 + MOVB R12, (BX) + INCQ R11 + INCQ BX + DECQ R13 + JNZ copy_slow_3 handle_loop: ADDQ $0x18, AX @@ -1494,13 +1494,13 @@ copy_1_move_1or2: JMP copy_1_end copy_1_move_3: - MOVW (SI), R14 - MOVB 2(SI), R15 - MOVW R14, (BX) - MOVB R15, 2(BX) - ADDQ R11, SI - ADDQ R11, BX - JMP copy_1_end + MOVWQZX (SI), R14 + MOVB 2(SI), R15 + MOVW R14, (BX) + MOVB R15, 2(BX) + ADDQ R11, SI + ADDQ R11, BX + JMP copy_1_end copy_1_move_4through7: MOVL (SI), R14 @@ -1563,13 +1563,13 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVW (R14), R11 - MOVB 2(R14), R12 - MOVW R11, (BX) - MOVB R12, 2(BX) - ADDQ R13, R14 - ADDQ R13, BX - JMP copy_4_end + MOVWQZX (R14), R11 + MOVB 2(R14), R12 + MOVW R11, (BX) + MOVB R12, 2(BX) + ADDQ R13, R14 + ADDQ R13, BX + JMP copy_4_end copy_4_move_4through7: MOVL (R14), R11 @@ -1632,13 +1632,13 @@ copy_5_move_1or2: JMP copy_5_end copy_5_move_3: - MOVW (R14), R15 - MOVB 2(R14), BP - MOVW R15, (BX) - MOVB BP, 2(BX) - ADDQ R11, R14 - ADDQ R11, BX - JMP copy_5_end + MOVWQZX (R14), R15 + MOVB 2(R14), BP + MOVW R15, (BX) + MOVB BP, 2(BX) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 @@ -1707,13 +1707,13 @@ copy_2_move_1or2: JMP copy_2_end copy_2_move_3: - MOVW (R11), R12 - MOVB 2(R11), R14 - MOVW R12, (BX) - MOVB R14, 2(BX) - ADDQ R13, R11 - ADDQ R13, BX - JMP copy_2_end + MOVWQZX (R11), R12 + MOVB 2(R11), R14 + MOVW R12, (BX) + MOVB R14, 2(BX) + ADDQ R13, R11 + ADDQ R13, BX + JMP copy_2_end copy_2_move_4through7: MOVL (R11), R12 @@ -1740,12 +1740,12 @@ copy_overlapping_match: ADDQ R13, DI copy_slow_3: - MOVB (R11), R12 - MOVB R12, (BX) - INCQ R11 - INCQ BX - DECQ R13 - JNZ copy_slow_3 + MOVBQZX (R11), R12 + MOVB R12, (BX) + INCQ R11 + INCQ BX + DECQ R13 + JNZ copy_slow_3 handle_loop: ADDQ $0x18, AX @@ -1853,43 +1853,43 @@ sequenceDecs_decodeSync_amd64_fill_check_overread: sequenceDecs_decodeSync_amd64_fill_end: // Update offset - MOVQ R9, AX - MOVQ BX, CX - MOVQ DX, R14 - SHLQ CL, R14 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decodeSync_amd64_of_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decodeSync_amd64_of_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decodeSync_amd64_of_update_zero - NEGQ CX - SHRQ CL, R14 - ADDQ R14, AX + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_amd64_of_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX sequenceDecs_decodeSync_amd64_of_update_zero: MOVQ AX, 8(SP) // Update match length - MOVQ R8, AX - MOVQ BX, CX - MOVQ DX, R14 - SHLQ CL, R14 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decodeSync_amd64_ml_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decodeSync_amd64_ml_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decodeSync_amd64_ml_update_zero - NEGQ CX - SHRQ CL, R14 - ADDQ R14, AX + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX sequenceDecs_decodeSync_amd64_ml_update_zero: MOVQ AX, 16(SP) @@ -1924,22 +1924,22 @@ sequenceDecs_decodeSync_amd64_fill_2_check_overread: sequenceDecs_decodeSync_amd64_fill_2_end: // Update literal length - MOVQ DI, AX - MOVQ BX, CX - MOVQ DX, R14 - SHLQ CL, R14 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decodeSync_amd64_ll_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decodeSync_amd64_ll_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decodeSync_amd64_ll_update_zero - NEGQ CX - SHRQ CL, R14 - ADDQ R14, AX + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX sequenceDecs_decodeSync_amd64_ll_update_zero: MOVQ AX, 24(SP) @@ -1961,7 +1961,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R14 MOVL $0x00000001, R15 - MOVB R13, CL + MOVBLZX R13, CX SHLL CL, R15 DECL R15 ANDQ R15, R14 @@ -1980,7 +1980,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R14 MOVL $0x00000001, R15 - MOVB R13, CL + MOVBLZX R13, CX SHLL CL, R15 DECL R15 ANDQ R15, R14 @@ -1999,7 +1999,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R14 MOVL $0x00000001, R15 - MOVB R13, CL + MOVBLZX R13, CX SHLL CL, R15 DECL R15 ANDQ R15, R14 @@ -2081,7 +2081,7 @@ sequenceDecs_decodeSync_amd64_match_len_ofs_ok: MOVQ 16(SP), R13 // Check if we have enough space in s.out - LEAQ (AX)(R13*1), R14 + LEAQ 16(AX)(R13*1), R14 ADDQ R10, R14 CMPQ R14, 32(SP) JA error_not_enough_space @@ -2143,13 +2143,13 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVW (R14), AX - MOVB 2(R14), CL - MOVW AX, (R10) - MOVB CL, 2(R10) - ADDQ R13, R14 - ADDQ R13, R10 - JMP copy_4_end + MOVWQZX (R14), AX + MOVB 2(R14), CL + MOVW AX, (R10) + MOVB CL, 2(R10) + ADDQ R13, R14 + ADDQ R13, R10 + JMP copy_4_end copy_4_move_4through7: MOVL (R14), AX @@ -2209,13 +2209,13 @@ copy_5_move_1or2: JMP copy_5_end copy_5_move_3: - MOVW (R14), R15 - MOVB 2(R14), BP - MOVW R15, (R10) - MOVB BP, 2(R10) - ADDQ AX, R14 - ADDQ AX, R10 - JMP copy_5_end + MOVWQZX (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R10) + MOVB BP, 2(R10) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 @@ -2266,12 +2266,12 @@ copy_overlapping_match: ADDQ R13, R12 copy_slow_3: - MOVB (AX), CL - MOVB CL, (R10) - INCQ AX - INCQ R10 - DECQ R13 - JNZ copy_slow_3 + MOVBQZX (AX), CX + MOVB CL, (R10) + INCQ AX + INCQ R10 + DECQ R13 + JNZ copy_slow_3 handle_loop: MOVQ ctx+16(FP), AX @@ -2601,7 +2601,7 @@ sequenceDecs_decodeSync_bmi2_match_len_ofs_ok: MOVQ 16(SP), R13 // Check if we have enough space in s.out - LEAQ (CX)(R13*1), R14 + LEAQ 16(CX)(R13*1), R14 ADDQ R9, R14 CMPQ R14, 32(SP) JA error_not_enough_space @@ -2663,13 +2663,13 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVW (R14), CX - MOVB 2(R14), R12 - MOVW CX, (R9) - MOVB R12, 2(R9) - ADDQ R13, R14 - ADDQ R13, R9 - JMP copy_4_end + MOVWQZX (R14), CX + MOVB 2(R14), R12 + MOVW CX, (R9) + MOVB R12, 2(R9) + ADDQ R13, R14 + ADDQ R13, R9 + JMP copy_4_end copy_4_move_4through7: MOVL (R14), CX @@ -2729,13 +2729,13 @@ copy_5_move_1or2: JMP copy_5_end copy_5_move_3: - MOVW (R14), R15 - MOVB 2(R14), BP - MOVW R15, (R9) - MOVB BP, 2(R9) - ADDQ CX, R14 - ADDQ CX, R9 - JMP copy_5_end + MOVWQZX (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R9) + MOVB BP, 2(R9) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 @@ -2786,12 +2786,12 @@ copy_overlapping_match: ADDQ R13, R11 copy_slow_3: - MOVB (CX), R12 - MOVB R12, (R9) - INCQ CX - INCQ R9 - DECQ R13 - JNZ copy_slow_3 + MOVBQZX (CX), R12 + MOVB R12, (R9) + INCQ CX + INCQ R9 + DECQ R13 + JNZ copy_slow_3 handle_loop: MOVQ ctx+16(FP), CX @@ -2935,43 +2935,43 @@ sequenceDecs_decodeSync_safe_amd64_fill_check_overread: sequenceDecs_decodeSync_safe_amd64_fill_end: // Update offset - MOVQ R9, AX - MOVQ BX, CX - MOVQ DX, R14 - SHLQ CL, R14 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decodeSync_safe_amd64_of_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decodeSync_safe_amd64_of_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decodeSync_safe_amd64_of_update_zero - NEGQ CX - SHRQ CL, R14 - ADDQ R14, AX + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_safe_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_safe_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_safe_amd64_of_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX sequenceDecs_decodeSync_safe_amd64_of_update_zero: MOVQ AX, 8(SP) // Update match length - MOVQ R8, AX - MOVQ BX, CX - MOVQ DX, R14 - SHLQ CL, R14 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decodeSync_safe_amd64_ml_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decodeSync_safe_amd64_ml_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decodeSync_safe_amd64_ml_update_zero - NEGQ CX - SHRQ CL, R14 - ADDQ R14, AX + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_safe_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_safe_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_safe_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX sequenceDecs_decodeSync_safe_amd64_ml_update_zero: MOVQ AX, 16(SP) @@ -3006,22 +3006,22 @@ sequenceDecs_decodeSync_safe_amd64_fill_2_check_overread: sequenceDecs_decodeSync_safe_amd64_fill_2_end: // Update literal length - MOVQ DI, AX - MOVQ BX, CX - MOVQ DX, R14 - SHLQ CL, R14 - MOVB AH, CL - SHRQ $0x20, AX - TESTQ CX, CX - JZ sequenceDecs_decodeSync_safe_amd64_ll_update_zero - ADDQ CX, BX - CMPQ BX, $0x40 - JA sequenceDecs_decodeSync_safe_amd64_ll_update_zero - CMPQ CX, $0x40 - JAE sequenceDecs_decodeSync_safe_amd64_ll_update_zero - NEGQ CX - SHRQ CL, R14 - ADDQ R14, AX + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVBLZX AH, CX + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_safe_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_safe_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_safe_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX sequenceDecs_decodeSync_safe_amd64_ll_update_zero: MOVQ AX, 24(SP) @@ -3043,7 +3043,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R14 MOVL $0x00000001, R15 - MOVB R13, CL + MOVBLZX R13, CX SHLL CL, R15 DECL R15 ANDQ R15, R14 @@ -3062,7 +3062,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R14 MOVL $0x00000001, R15 - MOVB R13, CL + MOVBLZX R13, CX SHLL CL, R15 DECL R15 ANDQ R15, R14 @@ -3081,7 +3081,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: MOVQ CX, BX ROLQ CL, R14 MOVL $0x00000001, R15 - MOVB R13, CL + MOVBLZX R13, CX SHLL CL, R15 DECL R15 ANDQ R15, R14 @@ -3206,13 +3206,13 @@ copy_1_move_1or2: JMP copy_1_end copy_1_move_3: - MOVW (R11), R14 - MOVB 2(R11), R15 - MOVW R14, (R10) - MOVB R15, 2(R10) - ADDQ AX, R11 - ADDQ AX, R10 - JMP copy_1_end + MOVWQZX (R11), R14 + MOVB 2(R11), R15 + MOVW R14, (R10) + MOVB R15, 2(R10) + ADDQ AX, R11 + ADDQ AX, R10 + JMP copy_1_end copy_1_move_4through7: MOVL (R11), R14 @@ -3276,13 +3276,13 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVW (R14), AX - MOVB 2(R14), CL - MOVW AX, (R10) - MOVB CL, 2(R10) - ADDQ R13, R14 - ADDQ R13, R10 - JMP copy_4_end + MOVWQZX (R14), AX + MOVB 2(R14), CL + MOVW AX, (R10) + MOVB CL, 2(R10) + ADDQ R13, R14 + ADDQ R13, R10 + JMP copy_4_end copy_4_move_4through7: MOVL (R14), AX @@ -3342,13 +3342,13 @@ copy_5_move_1or2: JMP copy_5_end copy_5_move_3: - MOVW (R14), R15 - MOVB 2(R14), BP - MOVW R15, (R10) - MOVB BP, 2(R10) - ADDQ AX, R14 - ADDQ AX, R10 - JMP copy_5_end + MOVWQZX (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R10) + MOVB BP, 2(R10) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 @@ -3417,13 +3417,13 @@ copy_2_move_1or2: JMP copy_2_end copy_2_move_3: - MOVW (AX), CX - MOVB 2(AX), R14 - MOVW CX, (R10) - MOVB R14, 2(R10) - ADDQ R13, AX - ADDQ R13, R10 - JMP copy_2_end + MOVWQZX (AX), CX + MOVB 2(AX), R14 + MOVW CX, (R10) + MOVB R14, 2(R10) + ADDQ R13, AX + ADDQ R13, R10 + JMP copy_2_end copy_2_move_4through7: MOVL (AX), CX @@ -3450,12 +3450,12 @@ copy_overlapping_match: ADDQ R13, R12 copy_slow_3: - MOVB (AX), CL - MOVB CL, (R10) - INCQ AX - INCQ R10 - DECQ R13 - JNZ copy_slow_3 + MOVBQZX (AX), CX + MOVB CL, (R10) + INCQ AX + INCQ R10 + DECQ R13 + JNZ copy_slow_3 handle_loop: MOVQ ctx+16(FP), AX @@ -3828,13 +3828,13 @@ copy_1_move_1or2: JMP copy_1_end copy_1_move_3: - MOVW (R10), R14 - MOVB 2(R10), R15 - MOVW R14, (R9) - MOVB R15, 2(R9) - ADDQ CX, R10 - ADDQ CX, R9 - JMP copy_1_end + MOVWQZX (R10), R14 + MOVB 2(R10), R15 + MOVW R14, (R9) + MOVB R15, 2(R9) + ADDQ CX, R10 + ADDQ CX, R9 + JMP copy_1_end copy_1_move_4through7: MOVL (R10), R14 @@ -3898,13 +3898,13 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVW (R14), CX - MOVB 2(R14), R12 - MOVW CX, (R9) - MOVB R12, 2(R9) - ADDQ R13, R14 - ADDQ R13, R9 - JMP copy_4_end + MOVWQZX (R14), CX + MOVB 2(R14), R12 + MOVW CX, (R9) + MOVB R12, 2(R9) + ADDQ R13, R14 + ADDQ R13, R9 + JMP copy_4_end copy_4_move_4through7: MOVL (R14), CX @@ -3964,13 +3964,13 @@ copy_5_move_1or2: JMP copy_5_end copy_5_move_3: - MOVW (R14), R15 - MOVB 2(R14), BP - MOVW R15, (R9) - MOVB BP, 2(R9) - ADDQ CX, R14 - ADDQ CX, R9 - JMP copy_5_end + MOVWQZX (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R9) + MOVB BP, 2(R9) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end copy_5_move_4through7: MOVL (R14), R15 @@ -4039,13 +4039,13 @@ copy_2_move_1or2: JMP copy_2_end copy_2_move_3: - MOVW (CX), R12 - MOVB 2(CX), R14 - MOVW R12, (R9) - MOVB R14, 2(R9) - ADDQ R13, CX - ADDQ R13, R9 - JMP copy_2_end + MOVWQZX (CX), R12 + MOVB 2(CX), R14 + MOVW R12, (R9) + MOVB R14, 2(R9) + ADDQ R13, CX + ADDQ R13, R9 + JMP copy_2_end copy_2_move_4through7: MOVL (CX), R12 @@ -4072,12 +4072,12 @@ copy_overlapping_match: ADDQ R13, R11 copy_slow_3: - MOVB (CX), R12 - MOVB R12, (R9) - INCQ CX - INCQ R9 - DECQ R13 - JNZ copy_slow_3 + MOVBQZX (CX), R12 + MOVB R12, (R9) + INCQ CX + INCQ R9 + DECQ R13 + JNZ copy_slow_3 handle_loop: MOVQ ctx+16(FP), CX diff --git a/src/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s b/src/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s index a468e5fc..fa48be19 100644 --- a/src/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s +++ b/src/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s @@ -1,7 +1,7 @@ // Code generated by command: go run gen.go -out ../seqdec.s -arch amd64,arm64 -pkg=zstd. DO NOT EDIT. // EXPERIMENTAL arm64 output lowered from an amd64 avo program. -//go:build arm64 && !appengine && !noasm && gc && !noasm +//go:build arm64 && (!appengine && !noasm && gc && !noasm) // func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // Requires: CMOV @@ -12,7 +12,7 @@ TEXT ·sequenceDecs_decode_arm64(SB), $8-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 @@ -24,7 +24,7 @@ TEXT ·sequenceDecs_decode_arm64(SB), $8-32 MOVD 160(R0), R12 sequenceDecs_decode_amd64_main_loop: - MOVD (RSP), R13 + MOVD 8(RSP), R13 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -148,14 +148,12 @@ sequenceDecs_decode_amd64_ll_update_zero: MOVD R0, (R9) // Fill bitreader for state updates - MOVD R13, (RSP) - MOVD R8, R0 - LSR $0x08, R0, R0 - MOVBU R0, R0 - MOVD ctx+16(FP), R1 - MOVD 96(R1), R16 - CMP $0x00, R16 - BEQ sequenceDecs_decode_amd64_skip_update + MOVD R13, 8(RSP) + UBFX $8, R8, $8, R0 + MOVD ctx+16(FP), R1 + MOVD 96(R1), R16 + CMP $0x00, R16 + BEQ sequenceDecs_decode_amd64_skip_update // Update Literal Length State MOVBU R6, R13 @@ -166,7 +164,7 @@ sequenceDecs_decode_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + MOVBU R13, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -175,8 +173,7 @@ sequenceDecs_decode_amd64_ll_update_zero: // Load ctx.llTable MOVD ctx+16(FP), R1 MOVD (R1), R1 - ADD R6<<3, R1, R15 - MOVD (R15), R6 + MOVD (R1)(R6<<3), R6 // Update Match Length State MOVBU R7, R13 @@ -187,7 +184,7 @@ sequenceDecs_decode_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + MOVBU R13, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -196,8 +193,7 @@ sequenceDecs_decode_amd64_ll_update_zero: // Load ctx.mlTable MOVD ctx+16(FP), R1 MOVD 24(R1), R1 - ADD R7<<3, R1, R15 - MOVD (R15), R7 + MOVD (R1)(R7<<3), R7 // Update Offset State MOVBU R8, R13 @@ -208,7 +204,7 @@ sequenceDecs_decode_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + MOVBU R13, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -217,8 +213,7 @@ sequenceDecs_decode_amd64_ll_update_zero: // Load ctx.ofTable MOVD ctx+16(FP), R1 MOVD 48(R1), R1 - ADD R8<<3, R1, R15 - MOVD (R15), R8 + MOVD (R1)(R8<<3), R8 sequenceDecs_decode_amd64_skip_update: // Adjust offset @@ -360,7 +355,7 @@ TEXT ·sequenceDecs_decode_56_arm64(SB), $8-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 @@ -372,7 +367,7 @@ TEXT ·sequenceDecs_decode_56_arm64(SB), $8-32 MOVD 160(R0), R12 sequenceDecs_decode_56_amd64_main_loop: - MOVD (RSP), R13 + MOVD 8(RSP), R13 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -467,14 +462,12 @@ sequenceDecs_decode_56_amd64_ll_update_zero: MOVD R0, (R9) // Fill bitreader for state updates - MOVD R13, (RSP) - MOVD R8, R0 - LSR $0x08, R0, R0 - MOVBU R0, R0 - MOVD ctx+16(FP), R1 - MOVD 96(R1), R16 - CMP $0x00, R16 - BEQ sequenceDecs_decode_56_amd64_skip_update + MOVD R13, 8(RSP) + UBFX $8, R8, $8, R0 + MOVD ctx+16(FP), R1 + MOVD 96(R1), R16 + CMP $0x00, R16 + BEQ sequenceDecs_decode_56_amd64_skip_update // Update Literal Length State MOVBU R6, R13 @@ -485,7 +478,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + MOVBU R13, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -494,8 +487,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: // Load ctx.llTable MOVD ctx+16(FP), R1 MOVD (R1), R1 - ADD R6<<3, R1, R15 - MOVD (R15), R6 + MOVD (R1)(R6<<3), R6 // Update Match Length State MOVBU R7, R13 @@ -506,7 +498,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + MOVBU R13, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -515,8 +507,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: // Load ctx.mlTable MOVD ctx+16(FP), R1 MOVD 24(R1), R1 - ADD R7<<3, R1, R15 - MOVD (R15), R7 + MOVD (R1)(R7<<3), R7 // Update Offset State MOVBU R8, R13 @@ -527,7 +518,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + MOVBU R13, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -536,8 +527,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: // Load ctx.ofTable MOVD ctx+16(FP), R1 MOVD 48(R1), R1 - ADD R8<<3, R1, R15 - MOVD (R15), R8 + MOVD (R1)(R8<<3), R8 sequenceDecs_decode_56_amd64_skip_update: // Adjust offset @@ -710,16 +700,16 @@ main_loop: MOVD $0, R13 copy_1: - ADD R13, R5, R15 - VLD1 (R15), [V0.B16] - ADD R13, R3, R15 - VST1 [V0.B16], (R15) - ADD $0x10, R13, R13 - CMP R10, R13 - BLO copy_1 - ADD R10, R5, R5 - ADD R10, R3, R3 - ADD R10, R6, R6 + ADD R13, R5, R15 + FMOVQ (R15), F0 + ADD R13, R3, R15 + FMOVQ F0, (R15) + ADD $0x10, R13, R13 + CMP R10, R13 + BLO copy_1 + ADD R10, R5, R5 + ADD R10, R3, R3 + ADD R10, R6, R6 // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) check_offset: @@ -742,21 +732,19 @@ check_offset: BLO copy_4_small copy_4_loop: - VLD1 (R13), [V0.B16] - VST1 [V0.B16], (R3) - ADD $0x10, R13, R13 - ADD $0x10, R3, R3 - SUBS $0x10, R10, R10 - BHS copy_4_loop - ADD R10, R13, R13 - ADD $16, R13, R13 - ADD R10, R3, R3 - ADD $16, R3, R3 - ADD $-16, R13, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R3, R15 - VST1 [V0.B16], (R15) - JMP copy_4_end + FMOVQ (R13), F0 + FMOVQ F0, (R3) + ADD $0x10, R13, R13 + ADD $0x10, R3, R3 + SUBS $0x10, R10, R10 + BHS copy_4_loop + ADD R10, R13, R13 + ADD $16, R13, R13 + ADD R10, R3, R3 + ADD $16, R3, R3 + FMOVQ -16(R13), F0 + FMOVQ F0, -16(R3) + JMP copy_4_end copy_4_small: CMP $0x03, R12 @@ -766,13 +754,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R10 - MOVB 2(R13), R11 - MOVH R10, (R3) - MOVB R11, 2(R3) - ADD R12, R13, R13 - ADD R12, R3, R3 - JMP copy_4_end + MOVHU (R13), R10 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R11 + MOVH R10, (R3) + MOVB R11, 2(R3) + ADD R12, R13, R13 + ADD R12, R3, R3 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R10 @@ -809,21 +798,19 @@ copy_all_from_history: BLO copy_5_small copy_5_loop: - VLD1 (R13), [V0.B16] - VST1 [V0.B16], (R3) - ADD $0x10, R13, R13 - ADD $0x10, R3, R3 - SUBS $0x10, R14, R14 - BHS copy_5_loop - ADD R14, R13, R13 - ADD $16, R13, R13 - ADD R14, R3, R3 - ADD $16, R3, R3 - ADD $-16, R13, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R3, R15 - VST1 [V0.B16], (R15) - JMP copy_5_end + FMOVQ (R13), F0 + FMOVQ F0, (R3) + ADD $0x10, R13, R13 + ADD $0x10, R3, R3 + SUBS $0x10, R14, R14 + BHS copy_5_loop + ADD R14, R13, R13 + ADD $16, R13, R13 + ADD R14, R3, R3 + ADD $16, R3, R3 + FMOVQ -16(R13), F0 + FMOVQ F0, -16(R3) + JMP copy_5_end copy_5_small: CMP $0x03, R10 @@ -834,24 +821,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R10, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R3) - ADD R10, R3, R15 - MOVB R4, -1(R15) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R10, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R3) + ADD R10, R3, R15 + MOVB R4, -1(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R3) - MOVB R4, 2(R3) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R3) + MOVB R4, 2(R3) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -893,25 +883,25 @@ copy_match: ADD R12, R3, R3 copy_2: - VLD1 (R10), [V0.B16] - VST1 [V0.B16], (R11) - ADD $0x10, R10, R10 - ADD $0x10, R11, R11 - SUBS $0x10, R12, R12 - BHI copy_2 - JMP handle_loop + FMOVQ (R10), F0 + FMOVQ F0, (R11) + ADD $0x10, R10, R10 + ADD $0x10, R11, R11 + SUBS $0x10, R12, R12 + BHI copy_2 + JMP handle_loop // Copy overlapping match copy_overlapping_match: ADD R12, R6, R6 copy_slow_3: - MOVB (R10), R11 - MOVB R11, (R3) - ADD $1, R10, R10 - ADD $1, R3, R3 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R10), R11 + MOVB R11, (R3) + ADD $1, R10, R10 + ADD $1, R3, R3 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: ADD $0x18, R0, R0 @@ -991,21 +981,19 @@ main_loop: BLO copy_1_small copy_1_loop: - VLD1 (R5), [V0.B16] - VST1 [V0.B16], (R3) - ADD $0x10, R5, R5 - ADD $0x10, R3, R3 - SUBS $0x10, R13, R13 - BHS copy_1_loop - ADD R13, R5, R5 - ADD $16, R5, R5 - ADD R13, R3, R3 - ADD $16, R3, R3 - ADD $-16, R5, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R3, R15 - VST1 [V0.B16], (R15) - JMP copy_1_end + FMOVQ (R5), F0 + FMOVQ F0, (R3) + ADD $0x10, R5, R5 + ADD $0x10, R3, R3 + SUBS $0x10, R13, R13 + BHS copy_1_loop + ADD R13, R5, R5 + ADD $16, R5, R5 + ADD R13, R3, R3 + ADD $16, R3, R3 + FMOVQ -16(R5), F0 + FMOVQ F0, -16(R3) + JMP copy_1_end copy_1_small: CMP $0x03, R10 @@ -1016,24 +1004,27 @@ copy_1_small: JMP copy_1_move_8through16 copy_1_move_1or2: - MOVB (R5), R13 - ADD R10, R5, R15 - MOVB -1(R15), R14 - MOVB R13, (R3) - ADD R10, R3, R15 - MOVB R14, -1(R15) - ADD R10, R5, R5 - ADD R10, R3, R3 - JMP copy_1_end + MOVBU (R5), R16 + BFI $0, R16, $8, R13 + ADD R10, R5, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R14 + MOVB R13, (R3) + ADD R10, R3, R15 + MOVB R14, -1(R15) + ADD R10, R5, R5 + ADD R10, R3, R3 + JMP copy_1_end copy_1_move_3: - MOVH (R5), R13 - MOVB 2(R5), R14 - MOVH R13, (R3) - MOVB R14, 2(R3) - ADD R10, R5, R5 - ADD R10, R3, R3 - JMP copy_1_end + MOVHU (R5), R13 + MOVBU 2(R5), R16 + BFI $0, R16, $8, R14 + MOVH R13, (R3) + MOVB R14, 2(R3) + ADD R10, R5, R5 + ADD R10, R3, R3 + JMP copy_1_end copy_1_move_4through7: MOVWU (R5), R13 @@ -1080,21 +1071,19 @@ check_offset: BLO copy_4_small copy_4_loop: - VLD1 (R13), [V0.B16] - VST1 [V0.B16], (R3) - ADD $0x10, R13, R13 - ADD $0x10, R3, R3 - SUBS $0x10, R10, R10 - BHS copy_4_loop - ADD R10, R13, R13 - ADD $16, R13, R13 - ADD R10, R3, R3 - ADD $16, R3, R3 - ADD $-16, R13, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R3, R15 - VST1 [V0.B16], (R15) - JMP copy_4_end + FMOVQ (R13), F0 + FMOVQ F0, (R3) + ADD $0x10, R13, R13 + ADD $0x10, R3, R3 + SUBS $0x10, R10, R10 + BHS copy_4_loop + ADD R10, R13, R13 + ADD $16, R13, R13 + ADD R10, R3, R3 + ADD $16, R3, R3 + FMOVQ -16(R13), F0 + FMOVQ F0, -16(R3) + JMP copy_4_end copy_4_small: CMP $0x03, R12 @@ -1104,13 +1093,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R10 - MOVB 2(R13), R11 - MOVH R10, (R3) - MOVB R11, 2(R3) - ADD R12, R13, R13 - ADD R12, R3, R3 - JMP copy_4_end + MOVHU (R13), R10 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R11 + MOVH R10, (R3) + MOVB R11, 2(R3) + ADD R12, R13, R13 + ADD R12, R3, R3 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R10 @@ -1147,21 +1137,19 @@ copy_all_from_history: BLO copy_5_small copy_5_loop: - VLD1 (R13), [V0.B16] - VST1 [V0.B16], (R3) - ADD $0x10, R13, R13 - ADD $0x10, R3, R3 - SUBS $0x10, R14, R14 - BHS copy_5_loop - ADD R14, R13, R13 - ADD $16, R13, R13 - ADD R14, R3, R3 - ADD $16, R3, R3 - ADD $-16, R13, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R3, R15 - VST1 [V0.B16], (R15) - JMP copy_5_end + FMOVQ (R13), F0 + FMOVQ F0, (R3) + ADD $0x10, R13, R13 + ADD $0x10, R3, R3 + SUBS $0x10, R14, R14 + BHS copy_5_loop + ADD R14, R13, R13 + ADD $16, R13, R13 + ADD R14, R3, R3 + ADD $16, R3, R3 + FMOVQ -16(R13), F0 + FMOVQ F0, -16(R3) + JMP copy_5_end copy_5_small: CMP $0x03, R10 @@ -1172,24 +1160,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R10, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R3) - ADD R10, R3, R15 - MOVB R4, -1(R15) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R10, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R3) + ADD R10, R3, R15 + MOVB R4, -1(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R3) - MOVB R4, 2(R3) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R3) + MOVB R4, 2(R3) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -1232,21 +1223,19 @@ copy_match: BLO copy_2_small copy_2_loop: - VLD1 (R10), [V0.B16] - VST1 [V0.B16], (R3) - ADD $0x10, R10, R10 - ADD $0x10, R3, R3 - SUBS $0x10, R11, R11 - BHS copy_2_loop - ADD R11, R10, R10 - ADD $16, R10, R10 - ADD R11, R3, R3 - ADD $16, R3, R3 - ADD $-16, R10, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R3, R15 - VST1 [V0.B16], (R15) - JMP copy_2_end + FMOVQ (R10), F0 + FMOVQ F0, (R3) + ADD $0x10, R10, R10 + ADD $0x10, R3, R3 + SUBS $0x10, R11, R11 + BHS copy_2_loop + ADD R11, R10, R10 + ADD $16, R10, R10 + ADD R11, R3, R3 + ADD $16, R3, R3 + FMOVQ -16(R10), F0 + FMOVQ F0, -16(R3) + JMP copy_2_end copy_2_small: CMP $0x03, R12 @@ -1257,24 +1246,27 @@ copy_2_small: JMP copy_2_move_8through16 copy_2_move_1or2: - MOVB (R10), R11 - ADD R12, R10, R15 - MOVB -1(R15), R13 - MOVB R11, (R3) - ADD R12, R3, R15 - MOVB R13, -1(R15) - ADD R12, R10, R10 - ADD R12, R3, R3 - JMP copy_2_end + MOVBU (R10), R16 + BFI $0, R16, $8, R11 + ADD R12, R10, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R13 + MOVB R11, (R3) + ADD R12, R3, R15 + MOVB R13, -1(R15) + ADD R12, R10, R10 + ADD R12, R3, R3 + JMP copy_2_end copy_2_move_3: - MOVH (R10), R11 - MOVB 2(R10), R13 - MOVH R11, (R3) - MOVB R13, 2(R3) - ADD R12, R10, R10 - ADD R12, R3, R3 - JMP copy_2_end + MOVHU (R10), R11 + MOVBU 2(R10), R16 + BFI $0, R16, $8, R13 + MOVH R11, (R3) + MOVB R13, 2(R3) + ADD R12, R10, R10 + ADD R12, R3, R3 + JMP copy_2_end copy_2_move_4through7: MOVWU (R10), R11 @@ -1305,12 +1297,12 @@ copy_overlapping_match: ADD R12, R6, R6 copy_slow_3: - MOVB (R10), R11 - MOVB R11, (R3) - ADD $1, R10, R10 - ADD $1, R3, R3 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R10), R11 + MOVB R11, (R3) + ADD $1, R10, R10 + ADD $1, R3, R3 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: ADD $0x18, R0, R0 @@ -1361,41 +1353,41 @@ TEXT ·sequenceDecs_decodeSync_arm64(SB), $64-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 MOVD 88(R0), R8 MOVD $0, R1 - MOVD R1, 8(RSP) MOVD R1, 16(RSP) MOVD R1, 24(RSP) + MOVD R1, 32(RSP) MOVD 112(R0), R9 MOVD 128(R0), R1 - MOVD R1, 32(RSP) + MOVD R1, 40(RSP) MOVD 144(R0), R10 MOVD 136(R0), R11 MOVD 200(R0), R1 - MOVD R1, 56(RSP) + MOVD R1, 64(RSP) MOVD 176(R0), R1 - MOVD R1, 48(RSP) + MOVD R1, 56(RSP) MOVD 184(R0), R0 - MOVD R0, 40(RSP) - MOVD 40(RSP), R0 - MOVD 48(RSP), R16 + MOVD R0, 48(RSP) + MOVD 48(RSP), R0 + MOVD 56(RSP), R16 ADD R0, R16, R16 - MOVD R16, 48(RSP) + MOVD R16, 56(RSP) // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 ADD R9, R16, R16 - MOVD R16, 32(RSP) + MOVD R16, 40(RSP) // outBase += outPosition ADD R11, R9, R9 sequenceDecs_decodeSync_amd64_main_loop: - MOVD (RSP), R12 + MOVD 8(RSP), R12 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -1445,7 +1437,7 @@ sequenceDecs_decodeSync_amd64_fill_end: ADD R13, R0, R0 sequenceDecs_decodeSync_amd64_of_update_zero: - MOVD R0, 8(RSP) + MOVD R0, 16(RSP) // Update match length MOVD R7, R0 @@ -1466,7 +1458,7 @@ sequenceDecs_decodeSync_amd64_of_update_zero: ADD R13, R0, R0 sequenceDecs_decodeSync_amd64_ml_update_zero: - MOVD R0, 16(RSP) + MOVD R0, 24(RSP) // Fill bitreader to have enough for the remaining CMP $0x08, R5 @@ -1516,17 +1508,15 @@ sequenceDecs_decodeSync_amd64_fill_2_end: ADD R13, R0, R0 sequenceDecs_decodeSync_amd64_ll_update_zero: - MOVD R0, 24(RSP) + MOVD R0, 32(RSP) // Fill bitreader for state updates - MOVD R12, (RSP) - MOVD R8, R0 - LSR $0x08, R0, R0 - MOVBU R0, R0 - MOVD ctx+16(FP), R1 - MOVD 96(R1), R16 - CMP $0x00, R16 - BEQ sequenceDecs_decodeSync_amd64_skip_update + MOVD R12, 8(RSP) + UBFX $8, R8, $8, R0 + MOVD ctx+16(FP), R1 + MOVD 96(R1), R16 + CMP $0x00, R16 + BEQ sequenceDecs_decodeSync_amd64_skip_update // Update Literal Length State MOVBU R6, R12 @@ -1537,7 +1527,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + MOVBU R12, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -1546,8 +1536,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: // Load ctx.llTable MOVD ctx+16(FP), R1 MOVD (R1), R1 - ADD R6<<3, R1, R15 - MOVD (R15), R6 + MOVD (R1)(R6<<3), R6 // Update Match Length State MOVBU R7, R12 @@ -1558,7 +1547,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + MOVBU R12, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -1567,8 +1556,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: // Load ctx.mlTable MOVD ctx+16(FP), R1 MOVD 24(R1), R1 - ADD R7<<3, R1, R15 - MOVD (R15), R7 + MOVD (R1)(R7<<3), R7 // Update Offset State MOVBU R8, R12 @@ -1579,7 +1567,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + MOVBU R12, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -1588,24 +1576,21 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: // Load ctx.ofTable MOVD ctx+16(FP), R1 MOVD 48(R1), R1 - ADD R8<<3, R1, R15 - MOVD (R15), R8 + MOVD (R1)(R8<<3), R8 sequenceDecs_decodeSync_amd64_skip_update: // Adjust offset - MOVD s+0(FP), R1 - MOVD 8(RSP), R12 - CMP $0x01, R0 - BLS sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0 - ADD $144, R1, R15 - VLD1 (R15), [V0.B16] - MOVD R12, 144(R1) - ADD $152, R1, R15 - VST1 [V0.B16], (R15) - JMP sequenceDecs_decodeSync_amd64_after_adjust + MOVD s+0(FP), R1 + MOVD 16(RSP), R12 + CMP $0x01, R0 + BLS sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0 + FMOVQ 144(R1), F0 + MOVD R12, 144(R1) + FMOVQ F0, 152(R1) + JMP sequenceDecs_decodeSync_amd64_after_adjust sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0: - MOVD 24(RSP), R16 + MOVD 32(RSP), R16 CMP $0x00000000, R16 BNE sequenceDecs_decodeSync_amd64_adjust_offset_maybezero ADD $1, R12, R12 @@ -1643,11 +1628,11 @@ sequenceDecs_decodeSync_amd64_adjust_skip: MOVD R13, R12 sequenceDecs_decodeSync_amd64_after_adjust: - MOVD R12, 8(RSP) + MOVD R12, 16(RSP) // Check values - MOVD 16(RSP), R0 - MOVD 24(RSP), R1 + MOVD 24(RSP), R0 + MOVD 32(RSP), R1 ADD R1, R0, R13 MOVD s+0(FP), R14 MOVD 256(R14), R16 @@ -1666,14 +1651,15 @@ sequenceDecs_decodeSync_amd64_after_adjust: BNE sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch sequenceDecs_decodeSync_amd64_match_len_ofs_ok: - MOVD 24(RSP), R0 - MOVD 8(RSP), R1 - MOVD 16(RSP), R12 + MOVD 32(RSP), R0 + MOVD 16(RSP), R1 + MOVD 24(RSP), R12 // Check if we have enough space in s.out ADD R12, R0, R13 + ADD $16, R13, R13 ADD R9, R13, R13 - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 CMP R16, R13 BHI error_not_enough_space @@ -1683,25 +1669,25 @@ sequenceDecs_decodeSync_amd64_match_len_ofs_ok: MOVD $0, R13 copy_1: - ADD R13, R10, R15 - VLD1 (R15), [V0.B16] - ADD R13, R9, R15 - VST1 [V0.B16], (R15) - ADD $0x10, R13, R13 - CMP R0, R13 - BLO copy_1 - ADD R0, R10, R10 - ADD R0, R9, R9 - ADD R0, R11, R11 + ADD R13, R10, R15 + FMOVQ (R15), F0 + ADD R13, R9, R15 + FMOVQ F0, (R15) + ADD $0x10, R13, R13 + CMP R0, R13 + BLO copy_1 + ADD R0, R10, R10 + ADD R0, R9, R9 + ADD R0, R11, R11 // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) check_offset: MOVD R11, R0 - MOVD 40(RSP), R16 + MOVD 48(RSP), R16 ADD R16, R0, R0 CMP R0, R1 BGT error_match_off_too_big - MOVD 56(RSP), R16 + MOVD 64(RSP), R16 CMP R16, R1 BGT error_match_off_too_big @@ -1709,7 +1695,7 @@ check_offset: MOVD R1, R0 SUBS R11, R0, R0 BLS copy_match - MOVD 48(RSP), R13 + MOVD 56(RSP), R13 SUB R0, R13, R13 CMP R0, R12 BGT copy_all_from_history @@ -1718,21 +1704,19 @@ check_offset: BLO copy_4_small copy_4_loop: - VLD1 (R13), [V0.B16] - VST1 [V0.B16], (R9) - ADD $0x10, R13, R13 - ADD $0x10, R9, R9 - SUBS $0x10, R0, R0 - BHS copy_4_loop - ADD R0, R13, R13 - ADD $16, R13, R13 - ADD R0, R9, R9 - ADD $16, R9, R9 - ADD $-16, R13, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R9, R15 - VST1 [V0.B16], (R15) - JMP copy_4_end + FMOVQ (R13), F0 + FMOVQ F0, (R9) + ADD $0x10, R13, R13 + ADD $0x10, R9, R9 + SUBS $0x10, R0, R0 + BHS copy_4_loop + ADD R0, R13, R13 + ADD $16, R13, R13 + ADD R0, R9, R9 + ADD $16, R9, R9 + FMOVQ -16(R13), F0 + FMOVQ F0, -16(R9) + JMP copy_4_end copy_4_small: CMP $0x03, R12 @@ -1742,13 +1726,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R0 - MOVB 2(R13), R1 - MOVH R0, (R9) - MOVB R1, 2(R9) - ADD R12, R13, R13 - ADD R12, R9, R9 - JMP copy_4_end + MOVHU (R13), R0 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R1 + MOVH R0, (R9) + MOVB R1, 2(R9) + ADD R12, R13, R13 + ADD R12, R9, R9 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R0 @@ -1782,21 +1767,19 @@ copy_all_from_history: BLO copy_5_small copy_5_loop: - VLD1 (R13), [V0.B16] - VST1 [V0.B16], (R9) - ADD $0x10, R13, R13 - ADD $0x10, R9, R9 - SUBS $0x10, R14, R14 - BHS copy_5_loop - ADD R14, R13, R13 - ADD $16, R13, R13 - ADD R14, R9, R9 - ADD $16, R9, R9 - ADD $-16, R13, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R9, R15 - VST1 [V0.B16], (R15) - JMP copy_5_end + FMOVQ (R13), F0 + FMOVQ F0, (R9) + ADD $0x10, R13, R13 + ADD $0x10, R9, R9 + SUBS $0x10, R14, R14 + BHS copy_5_loop + ADD R14, R13, R13 + ADD $16, R13, R13 + ADD R14, R9, R9 + ADD $16, R9, R9 + FMOVQ -16(R13), F0 + FMOVQ F0, -16(R9) + JMP copy_5_end copy_5_small: CMP $0x03, R0 @@ -1807,24 +1790,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R0, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R9) - ADD R0, R9, R15 - MOVB R4, -1(R15) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R0, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R9) + ADD R0, R9, R15 + MOVB R4, -1(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R9) - MOVB R4, 2(R9) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R9) + MOVB R4, 2(R9) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -1866,25 +1852,25 @@ copy_match: ADD R12, R9, R9 copy_2: - VLD1 (R0), [V0.B16] - VST1 [V0.B16], (R1) - ADD $0x10, R0, R0 - ADD $0x10, R1, R1 - SUBS $0x10, R12, R12 - BHI copy_2 - JMP handle_loop + FMOVQ (R0), F0 + FMOVQ F0, (R1) + ADD $0x10, R0, R0 + ADD $0x10, R1, R1 + SUBS $0x10, R12, R12 + BHI copy_2 + JMP handle_loop // Copy overlapping match copy_overlapping_match: ADD R12, R11, R11 copy_slow_3: - MOVB (R0), R1 - MOVB R1, (R9) - ADD $1, R0, R0 - ADD $1, R9, R9 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R0), R1 + MOVB R1, (R9) + ADD $1, R0, R0 + ADD $1, R9, R9 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: MOVD ctx+16(FP), R0 @@ -1913,7 +1899,7 @@ loop_finished: // Return with match length error sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch: - MOVD 16(RSP), R0 + MOVD 24(RSP), R0 MOVD ctx+16(FP), R1 MOVD R0, 216(R1) MOVD $0x00000001, R16 @@ -1923,7 +1909,7 @@ sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch: // Return with match too long error sequenceDecs_decodeSync_amd64_error_match_len_too_big: MOVD ctx+16(FP), R0 - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD $0x00000002, R16 MOVD R16, ret+24(FP) @@ -1932,7 +1918,7 @@ sequenceDecs_decodeSync_amd64_error_match_len_too_big: // Return with match offset too long error error_match_off_too_big: MOVD ctx+16(FP), R0 - MOVD 8(RSP), R1 + MOVD 16(RSP), R1 MOVD R1, 224(R0) MOVD R11, 136(R0) MOVD $0x00000003, R16 @@ -1942,7 +1928,7 @@ error_match_off_too_big: // Return with not enough literals error error_not_enough_literals: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) MOVD $0x00000004, R16 MOVD R16, ret+24(FP) @@ -1957,9 +1943,9 @@ error_overread: // Return with not enough output space error error_not_enough_space: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD R11, 136(R0) MOVD $0x00000005, R16 @@ -1977,41 +1963,41 @@ TEXT ·sequenceDecs_decodeSync_safe_arm64(SB), $64-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 MOVD 88(R0), R8 MOVD $0, R1 - MOVD R1, 8(RSP) MOVD R1, 16(RSP) MOVD R1, 24(RSP) + MOVD R1, 32(RSP) MOVD 112(R0), R9 MOVD 128(R0), R1 - MOVD R1, 32(RSP) + MOVD R1, 40(RSP) MOVD 144(R0), R10 MOVD 136(R0), R11 MOVD 200(R0), R1 - MOVD R1, 56(RSP) + MOVD R1, 64(RSP) MOVD 176(R0), R1 - MOVD R1, 48(RSP) + MOVD R1, 56(RSP) MOVD 184(R0), R0 - MOVD R0, 40(RSP) - MOVD 40(RSP), R0 - MOVD 48(RSP), R16 + MOVD R0, 48(RSP) + MOVD 48(RSP), R0 + MOVD 56(RSP), R16 ADD R0, R16, R16 - MOVD R16, 48(RSP) + MOVD R16, 56(RSP) // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 ADD R9, R16, R16 - MOVD R16, 32(RSP) + MOVD R16, 40(RSP) // outBase += outPosition ADD R11, R9, R9 sequenceDecs_decodeSync_safe_amd64_main_loop: - MOVD (RSP), R12 + MOVD 8(RSP), R12 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -2061,7 +2047,7 @@ sequenceDecs_decodeSync_safe_amd64_fill_end: ADD R13, R0, R0 sequenceDecs_decodeSync_safe_amd64_of_update_zero: - MOVD R0, 8(RSP) + MOVD R0, 16(RSP) // Update match length MOVD R7, R0 @@ -2082,7 +2068,7 @@ sequenceDecs_decodeSync_safe_amd64_of_update_zero: ADD R13, R0, R0 sequenceDecs_decodeSync_safe_amd64_ml_update_zero: - MOVD R0, 16(RSP) + MOVD R0, 24(RSP) // Fill bitreader to have enough for the remaining CMP $0x08, R5 @@ -2132,17 +2118,15 @@ sequenceDecs_decodeSync_safe_amd64_fill_2_end: ADD R13, R0, R0 sequenceDecs_decodeSync_safe_amd64_ll_update_zero: - MOVD R0, 24(RSP) + MOVD R0, 32(RSP) // Fill bitreader for state updates - MOVD R12, (RSP) - MOVD R8, R0 - LSR $0x08, R0, R0 - MOVBU R0, R0 - MOVD ctx+16(FP), R1 - MOVD 96(R1), R16 - CMP $0x00, R16 - BEQ sequenceDecs_decodeSync_safe_amd64_skip_update + MOVD R12, 8(RSP) + UBFX $8, R8, $8, R0 + MOVD ctx+16(FP), R1 + MOVD 96(R1), R16 + CMP $0x00, R16 + BEQ sequenceDecs_decodeSync_safe_amd64_skip_update // Update Literal Length State MOVBU R6, R12 @@ -2153,7 +2137,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + MOVBU R12, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -2162,8 +2146,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: // Load ctx.llTable MOVD ctx+16(FP), R1 MOVD (R1), R1 - ADD R6<<3, R1, R15 - MOVD (R15), R6 + MOVD (R1)(R6<<3), R6 // Update Match Length State MOVBU R7, R12 @@ -2174,7 +2157,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + MOVBU R12, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -2183,8 +2166,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: // Load ctx.mlTable MOVD ctx+16(FP), R1 MOVD 24(R1), R1 - ADD R7<<3, R1, R15 - MOVD (R15), R7 + MOVD (R1)(R7<<3), R7 // Update Offset State MOVBU R8, R12 @@ -2195,7 +2177,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + MOVBU R12, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -2204,24 +2186,21 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: // Load ctx.ofTable MOVD ctx+16(FP), R1 MOVD 48(R1), R1 - ADD R8<<3, R1, R15 - MOVD (R15), R8 + MOVD (R1)(R8<<3), R8 sequenceDecs_decodeSync_safe_amd64_skip_update: // Adjust offset - MOVD s+0(FP), R1 - MOVD 8(RSP), R12 - CMP $0x01, R0 - BLS sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0 - ADD $144, R1, R15 - VLD1 (R15), [V0.B16] - MOVD R12, 144(R1) - ADD $152, R1, R15 - VST1 [V0.B16], (R15) - JMP sequenceDecs_decodeSync_safe_amd64_after_adjust + MOVD s+0(FP), R1 + MOVD 16(RSP), R12 + CMP $0x01, R0 + BLS sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0 + FMOVQ 144(R1), F0 + MOVD R12, 144(R1) + FMOVQ F0, 152(R1) + JMP sequenceDecs_decodeSync_safe_amd64_after_adjust sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0: - MOVD 24(RSP), R16 + MOVD 32(RSP), R16 CMP $0x00000000, R16 BNE sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero ADD $1, R12, R12 @@ -2259,11 +2238,11 @@ sequenceDecs_decodeSync_safe_amd64_adjust_skip: MOVD R13, R12 sequenceDecs_decodeSync_safe_amd64_after_adjust: - MOVD R12, 8(RSP) + MOVD R12, 16(RSP) // Check values - MOVD 16(RSP), R0 - MOVD 24(RSP), R1 + MOVD 24(RSP), R0 + MOVD 32(RSP), R1 ADD R1, R0, R13 MOVD s+0(FP), R14 MOVD 256(R14), R16 @@ -2282,14 +2261,14 @@ sequenceDecs_decodeSync_safe_amd64_after_adjust: BNE sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok: - MOVD 24(RSP), R0 - MOVD 8(RSP), R1 - MOVD 16(RSP), R12 + MOVD 32(RSP), R0 + MOVD 16(RSP), R1 + MOVD 24(RSP), R12 // Check if we have enough space in s.out ADD R12, R0, R13 ADD R9, R13, R13 - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 CMP R16, R13 BHI error_not_enough_space @@ -2301,21 +2280,19 @@ sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok: BLO copy_1_small copy_1_loop: - VLD1 (R10), [V0.B16] - VST1 [V0.B16], (R9) - ADD $0x10, R10, R10 - ADD $0x10, R9, R9 - SUBS $0x10, R13, R13 - BHS copy_1_loop - ADD R13, R10, R10 - ADD $16, R10, R10 - ADD R13, R9, R9 - ADD $16, R9, R9 - ADD $-16, R10, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R9, R15 - VST1 [V0.B16], (R15) - JMP copy_1_end + FMOVQ (R10), F0 + FMOVQ F0, (R9) + ADD $0x10, R10, R10 + ADD $0x10, R9, R9 + SUBS $0x10, R13, R13 + BHS copy_1_loop + ADD R13, R10, R10 + ADD $16, R10, R10 + ADD R13, R9, R9 + ADD $16, R9, R9 + FMOVQ -16(R10), F0 + FMOVQ F0, -16(R9) + JMP copy_1_end copy_1_small: CMP $0x03, R0 @@ -2326,24 +2303,27 @@ copy_1_small: JMP copy_1_move_8through16 copy_1_move_1or2: - MOVB (R10), R13 - ADD R0, R10, R15 - MOVB -1(R15), R14 - MOVB R13, (R9) - ADD R0, R9, R15 - MOVB R14, -1(R15) - ADD R0, R10, R10 - ADD R0, R9, R9 - JMP copy_1_end + MOVBU (R10), R16 + BFI $0, R16, $8, R13 + ADD R0, R10, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R14 + MOVB R13, (R9) + ADD R0, R9, R15 + MOVB R14, -1(R15) + ADD R0, R10, R10 + ADD R0, R9, R9 + JMP copy_1_end copy_1_move_3: - MOVH (R10), R13 - MOVB 2(R10), R14 - MOVH R13, (R9) - MOVB R14, 2(R9) - ADD R0, R10, R10 - ADD R0, R9, R9 - JMP copy_1_end + MOVHU (R10), R13 + MOVBU 2(R10), R16 + BFI $0, R16, $8, R14 + MOVH R13, (R9) + MOVB R14, 2(R9) + ADD R0, R10, R10 + ADD R0, R9, R9 + JMP copy_1_end copy_1_move_4through7: MOVWU (R10), R13 @@ -2372,11 +2352,11 @@ copy_1_end: // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) check_offset: MOVD R11, R0 - MOVD 40(RSP), R16 + MOVD 48(RSP), R16 ADD R16, R0, R0 CMP R0, R1 BGT error_match_off_too_big - MOVD 56(RSP), R16 + MOVD 64(RSP), R16 CMP R16, R1 BGT error_match_off_too_big @@ -2384,7 +2364,7 @@ check_offset: MOVD R1, R0 SUBS R11, R0, R0 BLS copy_match - MOVD 48(RSP), R13 + MOVD 56(RSP), R13 SUB R0, R13, R13 CMP R0, R12 BGT copy_all_from_history @@ -2393,21 +2373,19 @@ check_offset: BLO copy_4_small copy_4_loop: - VLD1 (R13), [V0.B16] - VST1 [V0.B16], (R9) - ADD $0x10, R13, R13 - ADD $0x10, R9, R9 - SUBS $0x10, R0, R0 - BHS copy_4_loop - ADD R0, R13, R13 - ADD $16, R13, R13 - ADD R0, R9, R9 - ADD $16, R9, R9 - ADD $-16, R13, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R9, R15 - VST1 [V0.B16], (R15) - JMP copy_4_end + FMOVQ (R13), F0 + FMOVQ F0, (R9) + ADD $0x10, R13, R13 + ADD $0x10, R9, R9 + SUBS $0x10, R0, R0 + BHS copy_4_loop + ADD R0, R13, R13 + ADD $16, R13, R13 + ADD R0, R9, R9 + ADD $16, R9, R9 + FMOVQ -16(R13), F0 + FMOVQ F0, -16(R9) + JMP copy_4_end copy_4_small: CMP $0x03, R12 @@ -2417,13 +2395,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R0 - MOVB 2(R13), R1 - MOVH R0, (R9) - MOVB R1, 2(R9) - ADD R12, R13, R13 - ADD R12, R9, R9 - JMP copy_4_end + MOVHU (R13), R0 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R1 + MOVH R0, (R9) + MOVB R1, 2(R9) + ADD R12, R13, R13 + ADD R12, R9, R9 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R0 @@ -2457,21 +2436,19 @@ copy_all_from_history: BLO copy_5_small copy_5_loop: - VLD1 (R13), [V0.B16] - VST1 [V0.B16], (R9) - ADD $0x10, R13, R13 - ADD $0x10, R9, R9 - SUBS $0x10, R14, R14 - BHS copy_5_loop - ADD R14, R13, R13 - ADD $16, R13, R13 - ADD R14, R9, R9 - ADD $16, R9, R9 - ADD $-16, R13, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R9, R15 - VST1 [V0.B16], (R15) - JMP copy_5_end + FMOVQ (R13), F0 + FMOVQ F0, (R9) + ADD $0x10, R13, R13 + ADD $0x10, R9, R9 + SUBS $0x10, R14, R14 + BHS copy_5_loop + ADD R14, R13, R13 + ADD $16, R13, R13 + ADD R14, R9, R9 + ADD $16, R9, R9 + FMOVQ -16(R13), F0 + FMOVQ F0, -16(R9) + JMP copy_5_end copy_5_small: CMP $0x03, R0 @@ -2482,24 +2459,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R0, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R9) - ADD R0, R9, R15 - MOVB R4, -1(R15) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R0, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R9) + ADD R0, R9, R15 + MOVB R4, -1(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R9) - MOVB R4, 2(R9) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R9) + MOVB R4, 2(R9) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -2542,21 +2522,19 @@ copy_match: BLO copy_2_small copy_2_loop: - VLD1 (R0), [V0.B16] - VST1 [V0.B16], (R9) - ADD $0x10, R0, R0 - ADD $0x10, R9, R9 - SUBS $0x10, R1, R1 - BHS copy_2_loop - ADD R1, R0, R0 - ADD $16, R0, R0 - ADD R1, R9, R9 - ADD $16, R9, R9 - ADD $-16, R0, R15 - VLD1 (R15), [V0.B16] - ADD $-16, R9, R15 - VST1 [V0.B16], (R15) - JMP copy_2_end + FMOVQ (R0), F0 + FMOVQ F0, (R9) + ADD $0x10, R0, R0 + ADD $0x10, R9, R9 + SUBS $0x10, R1, R1 + BHS copy_2_loop + ADD R1, R0, R0 + ADD $16, R0, R0 + ADD R1, R9, R9 + ADD $16, R9, R9 + FMOVQ -16(R0), F0 + FMOVQ F0, -16(R9) + JMP copy_2_end copy_2_small: CMP $0x03, R12 @@ -2567,24 +2545,27 @@ copy_2_small: JMP copy_2_move_8through16 copy_2_move_1or2: - MOVB (R0), R1 - ADD R12, R0, R15 - MOVB -1(R15), R13 - MOVB R1, (R9) - ADD R12, R9, R15 - MOVB R13, -1(R15) - ADD R12, R0, R0 - ADD R12, R9, R9 - JMP copy_2_end + MOVBU (R0), R16 + BFI $0, R16, $8, R1 + ADD R12, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R13 + MOVB R1, (R9) + ADD R12, R9, R15 + MOVB R13, -1(R15) + ADD R12, R0, R0 + ADD R12, R9, R9 + JMP copy_2_end copy_2_move_3: - MOVH (R0), R1 - MOVB 2(R0), R13 - MOVH R1, (R9) - MOVB R13, 2(R9) - ADD R12, R0, R0 - ADD R12, R9, R9 - JMP copy_2_end + MOVHU (R0), R1 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R13 + MOVH R1, (R9) + MOVB R13, 2(R9) + ADD R12, R0, R0 + ADD R12, R9, R9 + JMP copy_2_end copy_2_move_4through7: MOVWU (R0), R1 @@ -2615,12 +2596,12 @@ copy_overlapping_match: ADD R12, R11, R11 copy_slow_3: - MOVB (R0), R1 - MOVB R1, (R9) - ADD $1, R0, R0 - ADD $1, R9, R9 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R0), R1 + MOVB R1, (R9) + ADD $1, R0, R0 + ADD $1, R9, R9 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: MOVD ctx+16(FP), R0 @@ -2649,7 +2630,7 @@ loop_finished: // Return with match length error sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch: - MOVD 16(RSP), R0 + MOVD 24(RSP), R0 MOVD ctx+16(FP), R1 MOVD R0, 216(R1) MOVD $0x00000001, R16 @@ -2659,7 +2640,7 @@ sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch: // Return with match too long error sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big: MOVD ctx+16(FP), R0 - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD $0x00000002, R16 MOVD R16, ret+24(FP) @@ -2668,7 +2649,7 @@ sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big: // Return with match offset too long error error_match_off_too_big: MOVD ctx+16(FP), R0 - MOVD 8(RSP), R1 + MOVD 16(RSP), R1 MOVD R1, 224(R0) MOVD R11, 136(R0) MOVD $0x00000003, R16 @@ -2678,7 +2659,7 @@ error_match_off_too_big: // Return with not enough literals error error_not_enough_literals: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) MOVD $0x00000004, R16 MOVD R16, ret+24(FP) @@ -2693,9 +2674,9 @@ error_overread: // Return with not enough output space error error_not_enough_space: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD R11, 136(R0) MOVD $0x00000005, R16 diff --git a/src/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go b/src/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go index 55405f39..42ce5de7 100644 --- a/src/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go +++ b/src/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go @@ -77,6 +77,35 @@ const errorNotEnoughSpace = 5 // error reported when bits are overread. const errorOverread = 6 +// useSafeDecodeSync reports whether decodeSyncSimple must use the bounds-exact +// ("safe") copy variants for the current buffer geometry. +// +// When the output and literal buffers have compressedBlockOverAlloc (16) +// bytes of slack past their logical use, the assembly may use extended +// memory copies that read and write in 16-byte blocks, overrunning the end +// of a literal run or match by up to 15 bytes. Otherwise it must use the +// bounds-exact ("safe") copies. This mirrors the analogous, always-dynamic +// selection in executeSimple below. +// +// The unsafe copies were disabled in #644 (2022) as a mitigation for a +// crash, but that crash's root cause — an unguarded bitReader overread that +// produced out-of-range match offsets/lengths — was fixed three days later +// in #645, which also added the fuzz corpus that has guarded this path since. +// See #1168. An asan-instrumented fuzz job (see .github/workflows/go.yml) +// covers the extended-copy path, which -race and plain fuzzing cannot. +func (s *sequenceDecs) useSafeDecodeSync() bool { + if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSizeAlloc { + return true + } + if s.maxSyncLen > 0 && cap(s.out)-len(s.out)-compressedBlockOverAlloc < int(s.maxSyncLen) { + return true + } + if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc { + return true + } + return false +} + // decode sequences from the stream with the provided history but without a dictionary. func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { if len(s.dict) > 0 { @@ -86,9 +115,7 @@ func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { return false, nil } - // FIXME: Using unsafe memory copies leads to rare, random crashes - // with fuzz testing. It is therefore disabled for now. - const useSafe = true + useSafe := s.useSafeDecodeSync() br := s.br diff --git a/src/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/src/vendor/github.com/mattn/go-isatty/isatty_tiocgwinsz.go similarity index 62% rename from src/vendor/github.com/mattn/go-isatty/isatty_tcgets.go rename to src/vendor/github.com/mattn/go-isatty/isatty_tiocgwinsz.go index 0337d8cf..6aecf870 100644 --- a/src/vendor/github.com/mattn/go-isatty/isatty_tcgets.go +++ b/src/vendor/github.com/mattn/go-isatty/isatty_tiocgwinsz.go @@ -8,8 +8,12 @@ package isatty import "golang.org/x/sys/unix" // IsTerminal return true if the file descriptor is terminal. +// TIOCGWINSZ is used instead of TCGETS because TCGETS shares its ioctl +// number with SNDCTL_TMR_TIMEBASE of the OSS sound API, so it may succeed +// (and even change the device mode) on non-tty devices. musl's isatty does +// the same. func IsTerminal(fd uintptr) bool { - _, err := unix.IoctlGetTermios(int(fd), unix.TCGETS) + _, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ) return err == nil } diff --git a/src/vendor/github.com/molecule-man/go-brrr/.gitignore b/src/vendor/github.com/molecule-man/go-brrr/.gitignore new file mode 100644 index 00000000..944b90e5 --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/.gitignore @@ -0,0 +1,39 @@ +# 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 + +# Code coverage profiles and other test artifacts +*.out +coverage.* +*.coverprofile +profile.cov + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work +go.work.sum + +# Build artifacts +/bin/ +/lib/ + +# Test and benchmark caches +.cache/ + +# env file +.env + +# Editor/IDE +# .idea/ +# .vscode/ diff --git a/src/vendor/github.com/molecule-man/go-brrr/.gitmodules b/src/vendor/github.com/molecule-man/go-brrr/.gitmodules new file mode 100644 index 00000000..1e0a3d17 --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/.gitmodules @@ -0,0 +1,3 @@ +[submodule "brotli-ref"] + path = brotli-ref + url = git@github.com:google/brotli.git diff --git a/src/vendor/github.com/molecule-man/go-brrr/.golangci.yml b/src/vendor/github.com/molecule-man/go-brrr/.golangci.yml new file mode 100644 index 00000000..e061d21f --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/.golangci.yml @@ -0,0 +1,139 @@ +version: "2" + +run: + timeout: 5m + modules-download-mode: readonly + +linters: + enable: + # Enabled by default linters: + - errcheck # Check for unchecked errors + - govet # Reports suspicious constructs + - ineffassign # Detect ineffectual assignments + - staticcheck # Go static analysis (includes gosimple in v2) + - modernize # Suggest simplifications using modern Go features + - misspell # Finds commonly misspelled English words + - revive # Fast, configurable, extensible, flexible, and beautiful linter for Go + - unconvert # Remove unnecessary type conversions + - unparam # Find unused function parameters + # - dupl # Check for duplicate code + - gocritic # Highly extensible Go linter + - nilerr # Find code that returns nil even though it checks that error is not nil + - errorlint # Find misuses of errors + - prealloc # Find slice declarations that could potentially be pre-allocated + - decorder # Check declaration order and count of types, constants, variables and functions + - funcorder # Check function order within Go files + - depguard # Enforce import restrictions + - unused # Check for unused constants, variables, functions and types + - nolintlint # Find ill-formed or unnecessary nolint directives + + disable: + # Additional useful linters: + - bodyclose # Check if HTTP response body is closed + - gosec # Security-focused linter + + settings: + decorder: + dec-order: + - const + - var + - type + - func + disable-dec-order-check: false + disable-dec-num-check: true + disable-init-func-first-check: false + + gocritic: + enabled-tags: + - diagnostic + - style + - performance + disabled-checks: + - unnamedResult + + revive: + rules: + - name: exported + disabled: false + - name: package-comments + disabled: false + + depguard: + rules: + no-fmt: + list-mode: lax + files: + - "*.go" + - "!*_test.go" + deny: + - pkg: "fmt$" + desc: "use strconv, errors, or io instead of fmt" + + errcheck: + check-blank: false + check-type-assertions: false + + gosec: + excludes: + - G104 # Audit errors not checked (covered by errcheck) + + govet: + enable-all: true + disable: + - shadow + + exclusions: + generated: strict + rules: + # Exclude some linters from running on test files. + - path: _test\.go + linters: + - gosec + - gocritic + - decorder + - path: _test\.go + linters: + - govet + text: "fieldalignment" + + # C-ported Huffman table code: gosec's slice-bounds (G602) and + # int-overflow (G115) heuristics produce false positives here. + - path: entropy\.go + linters: + - gosec + - path: huffman\.go + linters: + - gosec + + # Allow panic in main package + - path: main\.go + linters: + - gocritic + text: "exitAfterDefer" + + # CGo files: dupImport is required (import "C" must be separate), + # and dupSubExpr false-positives on CGo return value comparisons. + - path: _cgo\.go + linters: + - gocritic + +formatters: + enable: + - gofmt # Check if code is formatted with gofmt + - goimports # Check import statements are formatted well + +issues: + max-issues-per-linter: 0 + max-same-issues: 0 + uniq-by-line: true + +output: + formats: + text: + path: stdout + print-linter-name: true + colors: true + sort-order: + - linter + - severity + - file diff --git a/src/vendor/github.com/molecule-man/go-brrr/.pre-commit-config.yaml b/src/vendor/github.com/molecule-man/go-brrr/.pre-commit-config.yaml new file mode 100644 index 00000000..3e7cf5ad --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/.pre-commit-config.yaml @@ -0,0 +1,38 @@ +fail_fast: false +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: check-case-conflict + - id: check-merge-conflict + - id: check-symlinks + - id: check-yaml + args: + - --unsafe + - id: end-of-file-fixer + exclude: '\.bin$' + - id: trailing-whitespace + exclude: '\.bin$' + + - repo: local + hooks: + - id: embedmd + name: embedmd + entry: embedmd -d README.md + language: system + pass_filenames: false + stages: [pre-commit] + - id: lint + name: lint + entry: golangci-lint run ./... + types: [go] + language: system + pass_filenames: false + stages: [pre-commit] + - id: test + name: test + entry: go test -short ./... + types: [go] + language: system + pass_filenames: false + stages: [pre-commit] diff --git a/src/vendor/github.com/andybalholm/brotli/LICENSE b/src/vendor/github.com/molecule-man/go-brrr/LICENSE similarity index 79% rename from src/vendor/github.com/andybalholm/brotli/LICENSE rename to src/vendor/github.com/molecule-man/go-brrr/LICENSE index 33b7cdd2..48103a8d 100644 --- a/src/vendor/github.com/andybalholm/brotli/LICENSE +++ b/src/vendor/github.com/molecule-man/go-brrr/LICENSE @@ -1,4 +1,6 @@ -Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors. +MIT License + +Copyright (c) 2026 Andrii Berezhynskyi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -7,13 +9,13 @@ 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 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 +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. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/vendor/github.com/molecule-man/go-brrr/Makefile b/src/vendor/github.com/molecule-man/go-brrr/Makefile new file mode 100644 index 00000000..5fbc19b9 --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/Makefile @@ -0,0 +1,16 @@ +.PHONY: init +init: + git submodule update --init + go install golang.org/x/perf/cmd/benchstat@latest + go install github.com/campoy/embedmd@latest + $(MAKE) lib/libbrotli_cref.a + +lib/libbrotli_cref.a: testdata/build_libbrotli_cref.sh \ + $(wildcard brotli-ref/c/common/*.c) \ + $(wildcard brotli-ref/c/dec/*.c) \ + $(wildcard brotli-ref/c/enc/*.c) \ + $(wildcard brotli-ref/c/common/*.h) \ + $(wildcard brotli-ref/c/dec/*.h) \ + $(wildcard brotli-ref/c/enc/*.h) \ + $(wildcard brotli-ref/c/include/brotli/*.h) + testdata/build_libbrotli_cref.sh diff --git a/src/vendor/github.com/molecule-man/go-brrr/README.md b/src/vendor/github.com/molecule-man/go-brrr/README.md new file mode 100644 index 00000000..35fde943 --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/README.md @@ -0,0 +1,192 @@ +![go brrr](assets/go-brrr-logo.jpg) + +# go-brrr - Brotli compression for Go + +[![CI](https://github.com/molecule-man/go-brrr/actions/workflows/ci.yml/badge.svg)](https://github.com/molecule-man/go-brrr/actions/workflows/ci.yml) +[![Go Reference](https://pkg.go.dev/badge/github.com/molecule-man/go-brrr.svg)](https://pkg.go.dev/github.com/molecule-man/go-brrr) +[![Go Report Card](https://goreportcard.com/badge/github.com/molecule-man/go-brrr)](https://goreportcard.com/report/github.com/molecule-man/go-brrr) +[![Version](https://img.shields.io/github/v/tag/molecule-man/go-brrr?sort=semver)](https://github.com/molecule-man/go-brrr/tags) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) + +Brotli compression library for Go (RFC 7932), with encoder and decoder support. + +## Highlights + +- **No C toolchain.** Builds with standard Go tooling. +- **Faster than other pure-Go brotli libraries** at every quality level we measure (see [Benchmarks](#benchmarks)). +- **Even faster than CGO brotli** on levels 2-9. +- **Compound dictionaries.** +- **Encoder tuning.** `LGWin` (window size) and `SizeHint` (expected total input size) are exposed via `WriterOptions`. `SizeHint` lets the encoder pick context modeling and hasher parameters tuned for the actual payload size. + +## Status + +The encoder and decoder are covered by compatibility tests and fuzzing. The public API is stable and follows semantic versioning. + +## Compatibility + +go-brrr implements Brotli RFC 7932 and is tested against the Brotli reference corpus. Encoded output is byte-compatible with the C reference implementation. + +## Compared to other Go brotli libraries + +| | go-brrr | [andybalholm](https://github.com/andybalholm/brotli) | [google/brotli/go/brotli](https://github.com/google/brotli/tree/master/go/brotli) | [cbrotli](https://github.com/google/brotli/tree/master/go/cbrotli) | +|---|---|---|---|---| +| Pure Go (no cgo) | ✓ | ✓ | ✓ | ✗ | +| Encoder | ✓ | ✓ | ✗ | ✓ | +| Decoder | ✓ | ✓ | ✓ | ✓ | +| Compound dictionaries (encode) | ✓ | ✗ | n/a | ✓ | +| Compound dictionaries (decode) | ✓ | ✗ | ✓ | ✓ | +| `LGWin` tuning | ✓ | ✓ | n/a | ✓ | +| `SizeHint` | ✓ | ✗ | n/a | ✗ | +| Writer `Reset` | ✓ | ✓ | n/a | ✗ | +| Reader `Reset` | ✓ | ✓ | ✗ | ✗ | + +If you're using `andybalholm/brotli`, go-brrr is a near drop-in upgrade with higher throughput on both compression and decompression, plus compound-dictionary and `SizeHint` support. If you're using `cbrotli`, go-brrr gives up cgo, adds multi-chunk compound dictionaries, and exposes poolable `Writer`/`Reader` instances. `cbrotli` has no `Reset`, so each stream allocates a fresh encoder/decoder state, which is noticeable on many-small-file workloads. + +## Install + +```sh +go get github.com/molecule-man/go-brrr +``` + +```go +import "github.com/molecule-man/go-brrr" +``` + +The import path is `github.com/molecule-man/go-brrr`; the package name is `brrr`. + +## Examples + +### Compression + +[embedmd]:# (example_test.go go /func Example_compress/ /^}/) +```go +func Example_compress() { + input := []byte("Hello, brotli!") + + var compressed bytes.Buffer + w, err := brrr.NewWriter(&compressed, 6) + if err != nil { + log.Fatal(err) + } + if _, err := w.Write(input); err != nil { + log.Fatal(err) + } + if err := w.Close(); err != nil { + log.Fatal(err) + } +} +``` + +More examples are available in [example_test.go](example_test.go) and the [Go package docs](https://pkg.go.dev/github.com/molecule-man/go-brrr#pkg-examples): round-trip compression and decompression, one-shot decompression, reusing writers and readers, pooling, and compound dictionaries. + +## When to use go-brrr + +The best use case for brotli is **static asset compression** - CSS, JS, HTML, fonts, WASM - where you compress once at build time and serve the result millions of times. Use **quality 11** for this: speed doesn't matter because you pay the cost once, and brotli q11 delivers ratios that neither gzip nor zstd can match. Every browser shipped since 2016 supports `Content-Encoding: br`. + +For on-the-fly compression, brotli q5–6 is a strong choice if you're already using zstd at its highest level: q5 is often **faster** with a **better ratio**, and q6 is only slightly slower with an even better ratio. At lower compression levels, zstd is significantly faster - if throughput is your priority and you don't need the best ratio, zstd is the better tool for the job. + +If you compress or decompress repeatedly (e.g. per request in a webserver), keep `*brrr.Writer` and `*brrr.Reader` instances in `sync.Pool`s and `Reset` each one into the next stream rather than allocating new instances each time. See the [compiled examples](example_test.go). + +## Implementation notes + +go-brrr is optimized for throughput. Some hot paths intentionally use larger functions, duplicated loops, and specialized code where benchmarks showed measurable wins. These choices stay local to performance-sensitive encoder and decoder internals; public APIs stay small and conventional. + +## Acknowledgments + +This library is a port of the [Brotli reference implementation](https://github.com/google/brotli) by the Brotli Authors, licensed under the MIT License. + +## Compression Speed vs Ratio + +All benchmarks were taken on the following setup with turboboost, etc, being +disabled via [denoise-amd.sh](scripts/denoise-amd.sh): + +``` +goos: linux +goarch: amd64 +cpu: AMD Ryzen 5 7535HS with Radeon Graphics +``` + +Compared against [klauspost/compress](https://github.com/klauspost/compress) zstd (pure Go) and stdlib gzip. Single CPU, no parallelism. These plots measure reused streaming encoders: the timed loop resets a warmed writer and discards compressed output, while ratio is measured from a warmup buffer. + +| Compression | Decompression | +|---|---| +| ![HTML 522KB](assets/gh_522KB_html.png) | ![HTML 522KB](assets/gh_522KB_html_decompress.png) | +| ![JS 187KB](assets/reactcore_187KB_js.png) | ![JS 187KB](assets/reactcore_187KB_js_decompress.png) | +| ![JSON 58KB](assets/github_events_58KB_json.png) | ![JSON 58KB](assets/github_events_58KB_json_decompress.png) | + +## Benchmarks + +Compared against other Go brotli libraries. **go-brrr** is the base in all comparisons. The smaller the number the better. + +- **andybalholm** - [github.com/andybalholm/brotli](https://github.com/andybalholm/brotli), pure Go encoder and decoder. +- **google-brotli** - [github.com/google/brotli/go/brotli](https://github.com/google/brotli/tree/master/go/brotli), Google's official pure Go decoder, transpiled from the Java reference. Decompression only, no encoder. +- **cbrotli** - [github.com/google/brotli/go/cbrotli](https://github.com/google/brotli/tree/master/go/cbrotli), Google's official cgo bindings to the C reference implementation. Including a cgo library in a pure Go comparison isn't apples-to-apples, but it is a useful comparison against Google's C implementation as exposed through its Go bindings. + +### One-shot Compression + +The table below measures end-to-end throughput through each package's public Go API for many independent brotli streams, not only the inner compression loop. Each payload is written as a complete stream with a fresh public writer instance so `cbrotli`, which has no resettable writer API, can be included. + +`go-brrr` still benefits from internal reuse in that shape: encoder arenas, hashers, hash tables, and scratch buffers are kept reusable through reset paths and internal `sync.Pool`s. That avoids repeated large allocations and zeroing, which matters for small and mid-size payloads. `cbrotli` uses the C reference encoder underneath, but each payload creates a new `BrotliEncoderState` through `cbrotli.NewWriter` and destroys it on `Close`, paying setup, teardown, cgo, and allocation costs for every stream. + +Read these rows as repeated complete-stream compression through the Go APIs. They are not a claim that every pure-Go compression hot path is faster than the C implementation; the same table shows quality levels where `cbrotli` is faster. + + +| | go-brrr (sec/op) | andybalholm (sec/op) | cbrotli (sec/op) | +| --- | --- | --- | --- | +| CompressOneshot/q=0/payload=VariedPayloads | 6.515m ± 1% | 12.420m ± 0% +90.64% (p=0.000 n=8) | 6.847m ± 0% +5.10% (p=0.000 n=8) | +| CompressOneshot/q=1/payload=VariedPayloads | 9.797m ± 0% | 20.169m ± 0% +105.88% (p=0.000 n=8) | 10.808m ± 0% +10.32% (p=0.000 n=8) | +| CompressOneshot/q=2/payload=VariedPayloads | 14.68m ± 0% | 38.86m ± 2% +164.76% (p=0.000 n=8) | 17.93m ± 0% +22.14% (p=0.000 n=8) | +| CompressOneshot/q=3/payload=VariedPayloads | 16.06m ± 0% | 44.34m ± 1% +176.12% (p=0.000 n=8) | 20.85m ± 0% +29.87% (p=0.000 n=8) | +| CompressOneshot/q=4/payload=VariedPayloads | 25.68m ± 0% | 61.37m ± 1% +138.97% (p=0.000 n=8) | 29.96m ± 0% +16.67% (p=0.000 n=8) | +| CompressOneshot/q=5/payload=VariedPayloads | 36.41m ± 0% | 80.19m ± 1% +120.22% (p=0.000 n=8) | 47.13m ± 0% +29.43% (p=0.000 n=8) | +| CompressOneshot/q=6/payload=VariedPayloads | 43.87m ± 0% | 90.57m ± 1% +106.47% (p=0.000 n=8) | 54.78m ± 0% +24.88% (p=0.000 n=8) | +| CompressOneshot/q=7/payload=VariedPayloads | 50.34m ± 0% | 127.34m ± 1% +152.96% (p=0.000 n=8) | 110.24m ± 0% +119.00% (p=0.000 n=8) | +| CompressOneshot/q=8/payload=VariedPayloads | 58.95m ± 0% | 146.62m ± 1% +148.72% (p=0.000 n=8) | 81.03m ± 1% +37.46% (p=0.000 n=8) | +| CompressOneshot/q=9/payload=VariedPayloads | 74.02m ± 0% | 209.77m ± 2% +183.41% (p=0.000 n=8) | 237.70m ± 0% +221.15% (p=0.000 n=8) | +| CompressOneshot/q=10/payload=VariedPayloads | 1221.7m ± 2% | 1368.5m ± 1% +12.01% (p=0.000 n=8) | 864.3m ± 0% -29.26% (p=0.000 n=8) | +| CompressOneshot/q=11/payload=VariedPayloads | 2.939 ± 1% | 3.424 ± 1% +16.51% (p=0.000 n=8) | 2.266 ± 0% -22.89% (p=0.000 n=8) | +| **geomean** | 52.96m | 111.1m +109.76% | 67.47m +27.40% | + + +*Streaming* uses `brrr.NewReader` + `io.ReadAll`; *one-shot* uses `brrr.Decompress` on a complete in-memory blob. + +### Streaming Decompression + +As cbrotli doesn't have the "resettable" API it's not included here. + + +| | go-brrr (sec/op) | andybalholm (sec/op) | +| --- | --- | --- | +| Decompress/q=4/payload=VariedPayloads | 5.378m ± 0% | 9.539m ± 0% +77.36% | +| Decompress/q=5/payload=VariedPayloads | 5.302m ± 0% | 9.143m ± 0% +72.43% | +| Decompress/q=6/payload=VariedPayloads | 5.146m ± 0% | 8.881m ± 0% +72.56% | +| Decompress/q=11/payload=VariedPayloads | 5.621m ± 0% | 8.959m ± 0% +59.37% | +| **geomean** | 5.359m | 9.127m +70.30% | + + +### One-shot Decompression + + +| | go-brrr (sec/op) | andybalholm (sec/op) | cbrotli (sec/op) | google-brotli (sec/op) | +| --- | --- | --- | --- | --- | +| DecompressOneshot/q=4/payload=VariedPayloads | 5.458m ± 0% | 10.042m ± 0% +84.01% | 5.191m ± 2% -4.89% | 10.595m ± 0% +94.13% | +| DecompressOneshot/q=5/payload=VariedPayloads | 5.458m ± 1% | 9.609m ± 0% +76.07% | 5.022m ± 11% ~ | 10.541m ± 0% +93.14% | +| DecompressOneshot/q=6/payload=VariedPayloads | 5.329m ± 1% | 9.384m ± 0% +76.11% | 4.916m ± 4% -7.74% | 10.240m ± 1% +92.17% | +| DecompressOneshot/q=11/payload=VariedPayloads | 5.816m ± 1% | 9.540m ± 0% +64.03% | 6.981m ± 1% +20.03% | **crashed** | +| **geomean** | 5.512m | 9.641m +74.91% | 5.469m -0.78% | 10.46m +93.14% | + + + +The `VariedPayloads` benchmark rotates through a heterogeneous mix of files, guarding against benchmark-shaped optimizations - wins that only show up when the same input is fed back-to-back should not move these rows. Payloads span small JSON API responses, mid-size HTML and JS bundles, and larger English prose, drawn from the [Brotli reference test corpus](https://github.com/google/brotli/tree/master/tests/testdata) and the local [testdata/](testdata/) directory. + +| File | Size | Source | +|-----------------------|-------:|------------| +| github_events_2k.json | 2.2 KB | testdata | +| github_events_5k.json | 5.2 KB | testdata | +| github_events_8k.json | 8.3 KB | testdata | +| asyoulik.txt | 122 KB | brotli-ref | +| alice29.txt | 149 KB | brotli-ref | +| gh_172KB.html | 167 KB | testdata | +| reactcore_187KB.js | 182 KB | testdata | +| lcet10.txt | 417 KB | brotli-ref | +| plrabn12.txt | 471 KB | brotli-ref | diff --git a/src/vendor/github.com/molecule-man/go-brrr/bitreader.go b/src/vendor/github.com/molecule-man/go-brrr/bitreader.go new file mode 100644 index 00000000..d8b21788 --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/bitreader.go @@ -0,0 +1,279 @@ +// Bit-level reading primitives for the decoder input stream. + +package brrr + +import "unsafe" + +// fastInputSlack is the minimum bytes of unconsumed input required for +// fast-path bit reading (162 bits + 7 bytes of margin). +const fastInputSlack = 28 + +// bitReaderState is a snapshot of a bitReader, used to save and restore +// position for speculative reads that may need to be rolled back. +type bitReaderState struct { + pos int + val uint64 + bitPos uint +} + +// init resets the bit reader to a clean initial state. +func (br *bitReader) init() { + br.val = 0 + br.bitPos = 0 + br.input = nil + br.inputLen = 0 + br.pos = 0 + br.inputBase = nil + br.fastEnd = -1 // no input → always fail fast-path check +} + +// setInput sets the input buffer for the bit reader. The reader starts +// consuming from the beginning of data. +func (br *bitReader) setInput(data []byte) { + br.input = data + br.inputLen = len(data) + br.pos = 0 + br.inputBase = unsafe.Pointer(unsafe.SliceData(data)) + br.fastEnd = len(data) - fastInputSlack +} + +// warmup pulls bytes until the accumulator is non-empty. +// Returns false if data is required but there is no input available. +func (br *bitReader) warmup() bool { + if br.bitPos == 0 { + br.val = 0 + if !br.pullByte() { + return false + } + } + return true +} + +// saveState returns a snapshot of the current reader position. +func (br *bitReader) saveState() bitReaderState { + return bitReaderState{ + pos: br.pos, + val: br.val, + bitPos: br.bitPos, + } +} + +// restoreState restores the reader to a previously saved state. +func (br *bitReader) restoreState(s bitReaderState) { + br.pos = s.pos + br.val = s.val + br.bitPos = s.bitPos +} + +// availIn returns the number of unconsumed input bytes (excluding bits +// already loaded into the accumulator). +func (br *bitReader) availIn() int { + return br.inputLen - br.pos +} + +// availBits returns the number of valid bits in the accumulator. +func (br *bitReader) availBits() uint { + return br.bitPos +} + +// remainingBytes returns the number of unread bytes, including whole bytes +// buffered in the accumulator. Capped at 1<<30. +func (br *bitReader) remainingBytes() int { + const remainingCap = 1 << 30 + avail := br.availIn() + if avail > remainingCap { + return remainingCap + } + return avail + int(br.bitPos>>3) +} + +// checkInputAmount reports whether enough unconsumed input remains for +// fast-path bit reading. Uses precomputed fastEnd to avoid a subtraction. +func (br *bitReader) checkInputAmount() bool { + return br.pos <= br.fastEnd +} + +// fillBitWindow ensures that at least nBits+1 bits are available in the +// accumulator. If the accumulator has 32 or fewer valid bits, 4 bytes are +// loaded from input. nBits must be in the range [1..24]. +func (br *bitReader) fillBitWindow(nBits uint) { + _ = nBits // used for documentation; the 64-bit path handles up to 32 + if br.bitPos <= 32 { + br.val |= uint64(*(*uint32)(unsafe.Add(br.inputBase, br.pos))) << br.bitPos + br.bitPos += 32 + br.pos += 4 + } +} + +// fillBitWindow16 ensures at least 17 bits are available. +func (br *bitReader) fillBitWindow16() { + br.fillBitWindow(17) +} + +// bitsUnmasked returns the raw accumulator value. The number of valid bits +// is given by availBits. +func (br *bitReader) bitsUnmasked() uint64 { + return br.val +} + +// getBits returns n bits from the accumulator without advancing. The +// accumulator is filled first if needed. +func (br *bitReader) getBits(n uint) uint64 { + br.fillBitWindow(n) + return br.val & bitMask(n) +} + +// dropBits discards the lowest n bits from the accumulator. +// n must be less than 64; in practice it is at most 15 (max Huffman code length). +// The & 63 mask is a no-op on the value but lets the compiler emit a plain +// shift instead of Go's safe-shift sequence (SHRQ+CMPQ+SBBQ+ANDQ → SHRQ). +func (br *bitReader) dropBits(n uint) { + br.bitPos -= n + br.val >>= n & 63 +} + +// takeBits returns the lowest n bits and discards them. +func (br *bitReader) takeBits(n uint) uint64 { + v := br.val & bitMask(n) + br.dropBits(n) + return v +} + +// readBits reads up to 24 bits from the input. The accumulator is filled +// first if needed. +func (br *bitReader) readBits(n uint) uint64 { + br.fillBitWindow(n) + return br.takeBits(n) +} + +// readBits32 reads up to 32 bits from the input. On 64-bit platforms this +// is identical to readBits. +func (br *bitReader) readBits32(n uint) uint64 { + br.fillBitWindow(n) + return br.takeBits(n) +} + +// pullByte loads one byte from input into the accumulator. Returns false +// if no input is available. +func (br *bitReader) pullByte() bool { + if br.pos >= br.inputLen { + return false + } + br.val |= uint64(br.input[br.pos]) << br.bitPos + br.bitPos += 8 + br.pos++ + return true +} + +// safeGetBits peeks at n bits, pulling bytes as needed. Returns the value +// and true on success, or 0 and false if insufficient input. +func (br *bitReader) safeGetBits(n uint) (uint64, bool) { + for br.bitPos < n { + if !br.pullByte() { + return 0, false + } + } + return br.val & bitMask(n), true +} + +// safeReadBits reads up to 24 bits, pulling bytes as needed. Returns the +// value and true on success, or 0 and false if insufficient input. +func (br *bitReader) safeReadBits(n uint) (uint64, bool) { + for br.bitPos < n { + if !br.pullByte() { + return 0, false + } + } + return br.takeBits(n), true +} + +// safeReadBits32 reads up to 32 bits, pulling bytes as needed. On 64-bit +// platforms this is identical to safeReadBits for n <= 24; for n > 24 it +// falls back to safeReadBits32Slow. +func (br *bitReader) safeReadBits32(n uint) (uint64, bool) { + if n <= 24 { + return br.safeReadBits(n) + } + return br.safeReadBits32Slow(n) +} + +// safeReadBits32Slow handles safe reads of more than 24 bits by splitting +// into two 16-bit reads with state save/restore on failure. +func (br *bitReader) safeReadBits32Slow(n uint) (uint64, bool) { + memento := br.saveState() + lowVal, ok := br.safeReadBits(16) + if !ok { + br.restoreState(memento) + return 0, false + } + highVal, ok := br.safeReadBits(n - 16) + if !ok { + br.restoreState(memento) + return 0, false + } + return lowVal | (highVal << 16), true +} + +// normalize clears any bits above bitPos in the accumulator (Spectre +// mitigation for cases where bytes are skipped without being loaded). +func (br *bitReader) normalize() { + if br.bitPos < 64 { + br.val &= bitMask(br.bitPos) + } +} + +// unload pushes unused whole bytes from the accumulator back into the +// unconsumed input by decrementing pos. +func (br *bitReader) unload() { + unusedBytes := br.bitPos >> 3 + unusedBits := unusedBytes << 3 + if unusedBytes > 0 { + br.pos -= int(unusedBytes) + } + br.bitPos -= unusedBits + br.normalize() +} + +// jumpToByteBoundary advances to the next byte boundary and verifies that +// any skipped padding bits are zero. Returns false if non-zero padding is +// found. +func (br *bitReader) jumpToByteBoundary() bool { + padBitsCount := br.bitPos & 0x7 + padBits := uint64(0) + if padBitsCount != 0 { + padBits = br.takeBits(padBitsCount) + } + br.normalize() + return padBits == 0 +} + +// dropBytes advances the byte position by n. The accumulator must be empty. +func (br *bitReader) dropBytes(n int) { + br.pos += n +} + +// copyBytes copies num bytes from the reader to dest. Drains the +// accumulator first, then copies directly from input. +func (br *bitReader) copyBytes(dest []byte) { + i := 0 + num := len(dest) + for br.bitPos >= 8 && i < num { + dest[i] = byte(br.val) + br.dropBits(8) + i++ + } + br.normalize() + if i < num { + copy(dest[i:], br.input[br.pos:br.pos+num-i]) + br.pos += num - i + } +} + +// bitMask returns a mask with the lowest n bits set. +// Uses shift-subtract instead of a table lookup to avoid a memory load +// and reduce L1 cache pressure in the decode hot path. +// The & 63 lets the compiler prove the shift is in-range, eliminating +// the Go overflow check. All callers pass n ≤ 24. +func bitMask(n uint) uint64 { + return (uint64(1) << (n & 63)) - 1 +} diff --git a/src/vendor/github.com/molecule-man/go-brrr/brotli.go b/src/vendor/github.com/molecule-man/go-brrr/brotli.go new file mode 100644 index 00000000..f9a283c1 --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/brotli.go @@ -0,0 +1,54 @@ +// Public package-level constants and option structs. + +package brrr + +// Compression level constants. +const ( + BestSpeed = 0 + BestCompression = 11 +) + +// Window size limits (RFC 7932 Section 9.1). +const ( + minLGWin = 10 + maxLGWin = 24 + defaultLGWin = 22 +) + +// WriterOptions configures advanced tuning knobs for the brotli encoder. +// The compression level is passed positionally to NewWriter / NewWriterOptions. +type WriterOptions struct { + // Dictionaries are compound dictionary chunks the encoder may reference + // as backward distances beyond the ring buffer, useful when inputs share + // content with a known corpus. Build each chunk once with + // [PrepareDictionary] and share the resulting *PreparedDictionary across + // any number of Writers. Up to 15 chunks are allowed and compound + // dictionaries require compression level >= 2. Dictionaries are preserved + // across Reset. + Dictionaries []*PreparedDictionary + + // LGWin sets the base-2 logarithm of the sliding window size (10–24). + // 0 selects the default (22). + LGWin int + + // SizeHint is the expected total input size in bytes. When set, the + // encoder uses it to make better decisions about context modeling and + // hasher selection for large inputs. 0 means unknown; the encoder will + // auto-estimate from the first Write call. + // + // SizeHint is advisory: a lower-than-actual value is safe in both + // correctness and compression ratio. The encoder transparently + // promotes its internal hasher to the unbounded variant if buffered + // input crosses the size-tuned threshold, preserving the bucket state + // that was learned under the small-hint dispatch. + SizeHint uint +} + +// ReaderOptions configures the brotli decoder. +type ReaderOptions struct { + // Dictionaries are compound dictionary chunks the decoder will use to + // resolve backward references beyond the ring buffer. They must match + // the dictionaries supplied to the encoder. Up to 15 chunks are allowed; + // each must be non-empty. Dictionaries are preserved across Reset. + Dictionaries [][]byte +} diff --git a/src/vendor/github.com/molecule-man/go-brrr/decode.go b/src/vendor/github.com/molecule-man/go-brrr/decode.go new file mode 100644 index 00000000..aeb47c30 --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/decode.go @@ -0,0 +1,2320 @@ +// Brotli decompression via a suspendable state machine (dec/decode.c). + +package brrr + +import ( + "errors" + "sync" + "unsafe" + + "github.com/molecule-man/go-brrr/internal/core" +) + +// Decoder-specific constants. +const ( + huffmanTableBits = 8 + huffmanTableMask = 0xFF + ringBufferWriteAheadSlack = 542 + maxAllowedDistance = 0x7FFFFFFC + + // symListBase is the offset into symbolListsArray that makes C-style + // negative indices in nextSymbol[] addressable. + symListBase = core.HuffmanMaxCodeLength + 1 +) + +// Static prefix code for the complex code length code lengths (RFC 7932 §3.5). +var codeLengthPrefixLength = [16]byte{ + 2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4, +} + +var codeLengthPrefixValue = [16]byte{ + 0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5, +} + +// Sentinel errors returned by Decompress. +var errPadding = errors.New("brotli: non-zero padding bits") + +var decodeStatePool = sync.Pool{ + New: func() any { + s := new(decodeState) + s.init() + return s + }, +} + +// decRingBufPool caches decoder ring buffer slices to reduce allocation +// pressure in streaming (Reader) decompression, where a new decodeState is +// created per Reader. The oneshot Decompress path already pools the entire +// decodeState (including its ring buffer). +var decRingBufPool sync.Pool + +func getDecRingBuf(size int) []byte { + if v := decRingBufPool.Get(); v != nil { + bp := v.(*[]byte) + if cap(*bp) >= size { + return (*bp)[:size] + } + // Wrong size — let GC reclaim it. + } + return make([]byte, size) +} + +func putDecRingBuf(buf []byte) { + if buf != nil { + b := buf[:cap(buf)] + decRingBufPool.Put(&b) + } +} + +// Decompress decodes the brotli-compressed data and returns the original bytes. +func Decompress(data []byte) ([]byte, error) { + s := decodeStatePool.Get().(*decodeState) + s.initForReuse() + s.br.setInput(data) + var output []byte + var err error + for { + switch s.decompressStream(&output) { + case decoderResultSuccess: + result := s.flushOutput(output) + decodeStatePool.Put(s) + return result, nil + case decoderResultError: + err = s.err + decodeStatePool.Put(s) + return nil, err + case decoderResultNeedsMoreInput: + decodeStatePool.Put(s) + return nil, decompressError("truncated input") + case decoderResultNeedsMoreOutput: + output = s.flushOutput(output) + } + } +} + +// decompressStream advances the decoder state machine. Returns a result +// indicating success, error, or that more input/output is needed. +func (s *decodeState) decompressStream(output *[]byte) decoderResult { + for { + switch s.state { + case decoderStateUninited: + if !s.br.warmup() { + return decoderResultNeedsMoreInput + } + if err := s.decodeWindowBits(); err != nil { + s.err = err + return decoderResultError + } + s.state = decoderStateInitialize + fallthrough + + case decoderStateInitialize: + s.maxBackwardDistance = (1 << s.windowBits) - core.WindowGap + allTrees := reuseHuffmanCodes(s.blockTypeTrees, 3*(huffmanMaxSize258+huffmanMaxSize26)) + s.blockTypeTrees = allTrees[:3*huffmanMaxSize258] + s.blockLenTrees = allTrees[3*huffmanMaxSize258:] + s.state = decoderStateMetablockBegin + fallthrough + + case decoderStateMetablockBegin: + s.metablockBegin() + s.state = decoderStateMetablockHeader + fallthrough + + case decoderStateMetablockHeader: + result := s.decodeMetaBlockLength() + if result != decoderResultSuccess { + return result + } + if s.isMetadata || s.isUncompressed { + if !s.br.jumpToByteBoundary() { + s.err = errPadding + return decoderResultError + } + } + if s.isMetadata { + s.state = decoderStateMetadata + break + } + if s.metaBlockRemainingLen == 0 { + s.state = decoderStateMetablockDone + break + } + s.calculateRingBufferSize() + if s.isUncompressed { + s.state = decoderStateUncompressed + break + } + s.state = decoderStateBeforeCompressedMetablockHeader + fallthrough + + case decoderStateBeforeCompressedMetablockHeader: + h := &s.headerArena + s.loopCounter = 0 + h.subLoopCounter = 0 + h.symbolLists = h.symbolListsArray[core.HuffmanMaxCodeLength+1:] + h.substateHuffman = huffmanNone + h.substateTreeGroup = treeGroupNone + h.substateContextMap = contextMapNone + s.state = decoderStateHuffmanCode0 + fallthrough + + case decoderStateHuffmanCode0: + if s.loopCounter >= 3 { + s.state = decoderStateMetablockHeader2 + break + } + result := s.decodeVarLenUint8(&s.numBlockTypes[s.loopCounter]) + if result != decoderResultSuccess { + return result + } + s.numBlockTypes[s.loopCounter]++ + if s.numBlockTypes[s.loopCounter] < 2 { + s.loopCounter++ + break + } + s.state = decoderStateHuffmanCode1 + fallthrough + + case decoderStateHuffmanCode1: + alphabetSize := s.numBlockTypes[s.loopCounter] + 2 + treeOffset := s.loopCounter * huffmanMaxSize258 + result := s.readHuffmanCode(alphabetSize, alphabetSize, + s.blockTypeTrees[treeOffset:], nil) + if result != decoderResultSuccess { + return result + } + s.state = decoderStateHuffmanCode2 + fallthrough + + case decoderStateHuffmanCode2: + treeOffset := s.loopCounter * huffmanMaxSize26 + result := s.readHuffmanCode(core.AlphabetSizeBlockCount, core.AlphabetSizeBlockCount, + s.blockLenTrees[treeOffset:], nil) + if result != decoderResultSuccess { + return result + } + s.state = decoderStateHuffmanCode3 + fallthrough + + case decoderStateHuffmanCode3: + treeOffset := s.loopCounter * huffmanMaxSize26 + bl, ok := safeReadBlockLength(s, s.blockLenTrees[treeOffset:]) + if !ok { + return decoderResultNeedsMoreInput + } + s.blockLength[s.loopCounter] = bl + s.loopCounter++ + s.state = decoderStateHuffmanCode0 + + case decoderStateMetablockHeader2: + bits, ok := s.br.safeReadBits(6) + if !ok { + return decoderResultNeedsMoreInput + } + s.distancePostfixBits = uint(bits & bitMask(2)) + bits >>= 2 + s.numDirectDistanceCodes = uint(bits) << s.distancePostfixBits + s.contextModes = reuseBytes(s.contextModes, int(s.numBlockTypes[0])) + s.loopCounter = 0 + s.state = decoderStateContextModes + fallthrough + + case decoderStateContextModes: + result := s.readContextModes() + if result != decoderResultSuccess { + return result + } + s.state = decoderStateContextMap1 + fallthrough + + case decoderStateContextMap1: + result := s.decodeContextMap(s.numBlockTypes[0]<= s.ringbufferSize { + continue + } + } + if s.metaBlockRemainingLen == 0 { + s.state = decoderStateMetablockDone + } else { + s.state = decoderStateCommandBegin + } + case decoderStateCommandPostWrite2: + s.state = decoderStateCommandPostWrapCopy + default: // CommandInnerWrite + if s.loopCounter == 0 { + if s.metaBlockRemainingLen == 0 { + s.state = decoderStateMetablockDone + } else { + s.state = decoderStateCommandPostDecodeLiterals + } + } else { + s.state = decoderStateCommandInner + } + } + + case decoderStateMetadata: + result := s.skipMetadataBlock() + if result != decoderResultSuccess { + return result + } + s.state = decoderStateMetablockDone + + case decoderStateUncompressed: + result := s.copyUncompressedBlock(output) + if result != decoderResultSuccess { + return result + } + s.state = decoderStateMetablockDone + + case decoderStateMetablockDone: + if s.metaBlockRemainingLen < 0 { + s.err = decompressError("negative remaining metablock length") + return decoderResultError + } + if !s.isLastMetablock { + s.state = decoderStateMetablockBegin + break + } + if !s.br.jumpToByteBoundary() { + s.err = errPadding + return decoderResultError + } + s.state = decoderStateDone + fallthrough + + case decoderStateDone: + return decoderResultSuccess + + default: + s.err = decompressError("unhandled decoder state") + return decoderResultError + } + } +} + +// flushOutput appends any unwritten ring buffer content to output. Bytes +// beyond ringbufferSize (in the slack region after a dictionary word write) +// are left for writeRingBuffer to wrap. +func (s *decodeState) flushOutput(output []byte) []byte { + pos := min(s.pos, s.ringbufferSize) + flushed := int(s.partialPosOut) - int(s.rbRoundtrips)*s.ringbufferSize + if pos > flushed { + output = append(output, s.ringbuffer[flushed:pos]...) + s.partialPosOut += uint(pos - flushed) + } + return output +} + +// writeRingBuffer flushes the ring buffer when it fills, appending to output. +func (s *decodeState) writeRingBuffer(output *[]byte) { + if s.pos >= s.ringbufferSize { + if s.ringbufferSize < 1< 0 { + copy(s.ringbuffer, s.ringbuffer[s.ringbufferSize:s.ringbufferSize+s.pos]) + } + s.maxDistance = s.maxBackwardDistance + } +} + +// --- Window bits --- + +func (s *decodeState) decodeWindowBits() error { + br := &s.br + n := br.takeBits(1) + if n == 0 { + s.windowBits = 16 + return nil + } + n = br.takeBits(3) + if n != 0 { + s.windowBits = int(17+n) & 63 + return nil + } + n = br.takeBits(3) + if n == 1 { + return decompressError("invalid window bits") + } + if n != 0 { + s.windowBits = int(8+n) & 63 + return nil + } + s.windowBits = 17 + return nil +} + +// --- Variable-length uint8 --- + +func (s *decodeState) decodeVarLenUint8(value *uint) decoderResult { + br := &s.br + switch s.substateDecodeUint8 { + case decodeUint8None: + bits, ok := br.safeReadBits(1) + if !ok { + return decoderResultNeedsMoreInput + } + if bits == 0 { + *value = 0 + return decoderResultSuccess + } + fallthrough + + case decodeUint8Short: + bits, ok := br.safeReadBits(3) + if !ok { + s.substateDecodeUint8 = decodeUint8Short + return decoderResultNeedsMoreInput + } + if bits == 0 { + *value = 1 + s.substateDecodeUint8 = decodeUint8None + return decoderResultSuccess + } + // Use *value as temporary storage for nbits (must be persisted). + *value = uint(bits) + fallthrough + + case decodeUint8Long: + bits, ok := br.safeReadBits(*value) + if !ok { + s.substateDecodeUint8 = decodeUint8Long + return decoderResultNeedsMoreInput + } + *value = (1 << *value) + uint(bits) + s.substateDecodeUint8 = decodeUint8None + return decoderResultSuccess + } + s.err = decompressError("unreachable decodeVarLenUint8 state") + return decoderResultError +} + +// --- Metablock header --- + +func (s *decodeState) decodeMetaBlockLength() decoderResult { + br := &s.br + for { + switch s.substateMetablockHeader { + case metablockHeaderNone: + bits, ok := br.safeReadBits(1) + if !ok { + return decoderResultNeedsMoreInput + } + s.isLastMetablock = bits != 0 + s.metaBlockRemainingLen = 0 + s.isUncompressed = false + s.isMetadata = false + if !s.isLastMetablock { + s.substateMetablockHeader = metablockHeaderNibbles + break + } + s.substateMetablockHeader = metablockHeaderEmpty + fallthrough + + case metablockHeaderEmpty: + bits, ok := br.safeReadBits(1) + if !ok { + return decoderResultNeedsMoreInput + } + if bits != 0 { + // Empty last metablock. + s.substateMetablockHeader = metablockHeaderNone + return decoderResultSuccess + } + s.substateMetablockHeader = metablockHeaderNibbles + fallthrough + + case metablockHeaderNibbles: + bits, ok := br.safeReadBits(2) + if !ok { + return decoderResultNeedsMoreInput + } + s.sizeNibbles = int(bits + 4) + s.loopCounter = 0 + if bits == 3 { + s.isMetadata = true + s.substateMetablockHeader = metablockHeaderReserved + break + } + s.substateMetablockHeader = metablockHeaderSize + fallthrough + + case metablockHeaderSize: + i := s.loopCounter + for i < s.sizeNibbles { + bits, ok := br.safeReadBits(4) + if !ok { + s.loopCounter = i + return decoderResultNeedsMoreInput + } + if i+1 == s.sizeNibbles && s.sizeNibbles > 4 && bits == 0 { + s.err = decompressError("exuberant nibble") + return decoderResultError + } + s.metaBlockRemainingLen |= int(bits) << (i * 4) + i++ + } + s.substateMetablockHeader = metablockHeaderUncompressed + fallthrough + + case metablockHeaderUncompressed: + if !s.isLastMetablock { + bits, ok := br.safeReadBits(1) + if !ok { + return decoderResultNeedsMoreInput + } + s.isUncompressed = bits != 0 + } + s.metaBlockRemainingLen++ + s.substateMetablockHeader = metablockHeaderNone + return decoderResultSuccess + + case metablockHeaderReserved: + bits, ok := br.safeReadBits(1) + if !ok { + return decoderResultNeedsMoreInput + } + if bits != 0 { + s.err = decompressError("reserved bit set in metadata header") + return decoderResultError + } + s.substateMetablockHeader = metablockHeaderBytes + fallthrough + + case metablockHeaderBytes: + bits, ok := br.safeReadBits(2) + if !ok { + return decoderResultNeedsMoreInput + } + if bits == 0 { + s.substateMetablockHeader = metablockHeaderNone + return decoderResultSuccess + } + s.sizeNibbles = int(bits) + s.loopCounter = 0 + s.substateMetablockHeader = metablockHeaderMetadata + fallthrough + + case metablockHeaderMetadata: + i := s.loopCounter + for i < s.sizeNibbles { + bits, ok := br.safeReadBits(8) + if !ok { + s.loopCounter = i + return decoderResultNeedsMoreInput + } + if i+1 == s.sizeNibbles && s.sizeNibbles > 1 && bits == 0 { + s.err = decompressError("exuberant metadata nibble") + return decoderResultError + } + s.metaBlockRemainingLen |= int(bits) << (i * 8) + i++ + } + s.metaBlockRemainingLen++ + s.substateMetablockHeader = metablockHeaderNone + return decoderResultSuccess + + default: + s.err = decompressError("unreachable metablock header state") + return decoderResultError + } + } +} + +// --- Metadata skip --- + +func (s *decodeState) skipMetadataBlock() decoderResult { + br := &s.br + for s.metaBlockRemainingLen > 0 { + avail := br.remainingBytes() + if avail == 0 { + return decoderResultNeedsMoreInput + } + n := min(avail, s.metaBlockRemainingLen) + // Skip n bytes. + for range n { + if br.bitPos >= 8 { + br.dropBits(8) + } else { + br.pos++ + } + } + s.metaBlockRemainingLen -= n + } + return decoderResultSuccess +} + +// --- Ring buffer --- + +func (s *decodeState) calculateRingBufferSize() { + windowSize := 1 << s.windowBits + newSize := windowSize + if s.ringbufferSize == windowSize { + return + } + if s.isMetadata { + return + } + + outputSize := s.pos + s.metaBlockRemainingLen + minSize := s.ringbufferSize + if minSize == 0 { + minSize = 1024 + } + if minSize < outputSize { + minSize = outputSize + } + + if s.cannyRingbufferAllocation { + for (newSize >> 1) >= minSize { + newSize >>= 1 + } + } + s.newRingbufferSize = newSize +} + +func (s *decodeState) ensureRingBuffer() { + if s.ringbufferSize == s.newRingbufferSize { + return + } + newSize := s.newRingbufferSize + ringBufferWriteAheadSlack + if cap(s.ringbuffer) >= newSize { + s.ringbuffer = s.ringbuffer[:newSize] + } else { + newBuf := getDecRingBuf(newSize) + if s.ringbuffer != nil { + copy(newBuf, s.ringbuffer[:s.pos]) + putDecRingBuf(s.ringbuffer) + } + s.ringbuffer = newBuf + } + s.ringbuffer[s.newRingbufferSize-2] = 0 + s.ringbuffer[s.newRingbufferSize-1] = 0 + s.ringbufferSize = s.newRingbufferSize + s.ringbufferMask = s.newRingbufferSize - 1 +} + +// --- Uncompressed block --- + +func (s *decodeState) copyUncompressedBlock(output *[]byte) decoderResult { + s.ensureRingBuffer() + br := &s.br + for { + if s.substateUncompressed == uncompressedWrite { + s.writeRingBuffer(output) + s.substateUncompressed = uncompressedNone + continue + } + if s.metaBlockRemainingLen == 0 { + return decoderResultSuccess + } + avail := br.remainingBytes() + if avail == 0 { + return decoderResultNeedsMoreInput + } + n := min(avail, s.metaBlockRemainingLen) + if s.pos+n > s.ringbufferSize { + n = s.ringbufferSize - s.pos + } + br.copyBytes(s.ringbuffer[s.pos : s.pos+n]) + s.pos += n + s.metaBlockRemainingLen -= n + if s.pos >= s.ringbufferSize { + s.substateUncompressed = uncompressedWrite + return decoderResultNeedsMoreOutput + } + } +} + +// --- Block type switching --- + +// decodeBlockTypeAndLength reads a block type and new block length. +// Returns true if a block switch occurred (i.e., num_block_types > 1). +func (s *decodeState) decodeBlockTypeAndLength(safe bool, treeType int) bool { + maxBlockType := s.numBlockTypes[treeType] + if maxBlockType <= 1 { + return false + } + + typeTree := s.blockTypeTrees[treeType*huffmanMaxSize258:] + lenTree := s.blockLenTrees[treeType*huffmanMaxSize26:] + br := &s.br + rb := &s.blockTypeRB + + var blockType uint + if !safe { + br.fillBitWindow(16) + blockType = decodeSymbol(br.val, typeTree, br) + s.blockLength[treeType] = readBlockLength(lenTree, br) + } else { + memento := br.saveState() + var ok bool + blockType, ok = safeReadSymbol(typeTree, br) + if !ok { + return false + } + bl, ok := safeReadBlockLength(s, lenTree) + if !ok { + s.substateReadBlockLength = readBlockLengthNone + br.restoreState(memento) + return false + } + s.blockLength[treeType] = bl + } + + switch blockType { + case 1: + blockType = rb[treeType*2+1] + 1 + case 0: + blockType = rb[treeType*2] + default: + blockType -= 2 + } + if blockType >= maxBlockType { + blockType -= maxBlockType + } + rb[treeType*2] = rb[treeType*2+1] + rb[treeType*2+1] = blockType + return true +} + +// --- Trivial literal context detection --- + +func (s *decodeState) detectTrivialLiteralBlockTypes() { + s.trivialLiteralContexts = [8]uint32{} + for i := range s.numBlockTypes[0] { + offset := i << core.LiteralContextBits + sample := s.contextMap[offset] + trivial := true + for j := range uint(1 << core.LiteralContextBits) { + if s.contextMap[offset+j] != sample { + trivial = false + break + } + } + if trivial { + s.trivialLiteralContexts[i>>5] |= 1 << (i & 31) + } + } +} + +func (s *decodeState) prepareLiteralDecoding() { + blockType := s.blockTypeRB[1] + contextOffset := blockType << core.LiteralContextBits + s.contextMapSliceIdx = int(contextOffset) + trivial := s.trivialLiteralContexts[blockType>>5] + s.trivialLiteralContext = int((trivial >> (blockType & 31)) & 1) + s.literalHTree = s.literalHGroup.codes[s.literalHGroup.htrees[s.contextMap[s.contextMapSliceIdx]]:] + contextMode := s.contextModes[blockType] & 3 + s.contextLookup = core.ContextLookupTable[uint(contextMode)<<9:] + if s.trivialLiteralContext == 0 { + ctxMap := s.contextMap[s.contextMapSliceIdx:] + htrees := s.literalHGroup.htrees + codesBase := unsafe.Pointer(unsafe.SliceData(s.literalHGroup.codes)) + for ctx := range 64 { + offset := htrees[ctxMap[ctx]] + s.literalCodesOffsets[ctx] = offset + s.literalCodesPtrs[ctx] = unsafe.Add(codesBase, uintptr(offset)*4) + } + } +} + +// --- Compressed metablock header sub-functions --- + +// --- Context modes --- + +func (s *decodeState) readContextModes() decoderResult { + br := &s.br + i := s.loopCounter + for uint(i) < s.numBlockTypes[0] { + bits, ok := br.safeReadBits(2) + if !ok { + s.loopCounter = i + return decoderResultNeedsMoreInput + } + s.contextModes[i] = byte(bits) + i++ + } + s.loopCounter = i + return decoderResultSuccess +} + +// --- Context map --- + +func (s *decodeState) decodeContextMap(contextMapSize uint, contextMap *[]byte, numHTrees *uint) decoderResult { + br := &s.br + h := &s.headerArena + + for { + switch h.substateContextMap { + case contextMapNone: + result := s.decodeVarLenUint8(numHTrees) + if result != decoderResultSuccess { + return result + } + (*numHTrees)++ + + *contextMap = reuseBytes(*contextMap, int(contextMapSize)) + if *numHTrees <= 1 { + // Trivial context map: all zeros. + clear(*contextMap) + return decoderResultSuccess + } + h.substateContextMap = contextMapReadPrefix + fallthrough + + case contextMapReadPrefix: + bits, ok := br.safeGetBits(5) + if !ok { + return decoderResultNeedsMoreInput + } + if bits&1 != 0 { + h.maxRunLengthPrefix = uint(bits>>1) + 1 + br.dropBits(5) + } else { + h.maxRunLengthPrefix = 0 + br.dropBits(1) + } + alphabetSize := *numHTrees + h.maxRunLengthPrefix + h.substateHuffman = huffmanNone + h.substateContextMap = contextMapHuffman + // Save code for RLE decoding (h.code stores maxRunLengthPrefix). + h.code = h.maxRunLengthPrefix + _ = alphabetSize // used in next case + fallthrough + + case contextMapHuffman: + alphabetSize := *numHTrees + h.code + result := s.readHuffmanCode(alphabetSize, alphabetSize, + h.contextMapTable[:], nil) + if result != decoderResultSuccess { + return result + } + h.contextIndex = 0 + h.code = 0xFFFF // sentinel: no pending RLE + h.substateContextMap = contextMapDecode + fallthrough + + case contextMapDecode: + code := h.code + skipPreamble := code != 0xFFFF + for h.contextIndex < contextMapSize || skipPreamble { + if !skipPreamble { + var ok bool + code, ok = safeReadSymbol(h.contextMapTable[:], br) + if !ok { + h.code = 0xFFFF + return decoderResultNeedsMoreInput + } + if code == 0 { + (*contextMap)[h.contextIndex] = 0 + h.contextIndex++ + continue + } + if code > h.maxRunLengthPrefix { + (*contextMap)[h.contextIndex] = byte(code - h.maxRunLengthPrefix) + h.contextIndex++ + continue + } + } else { + skipPreamble = false + } + // RLE: zero-fill. + reps, ok := br.safeReadBits(code) + if !ok { + h.code = code + return decoderResultNeedsMoreInput + } + reps += 1 << code + if h.contextIndex+uint(reps) > contextMapSize { + s.err = decompressError("context map repeat overflow") + return decoderResultError + } + for range int(reps) { + (*contextMap)[h.contextIndex] = 0 + h.contextIndex++ + } + } + h.substateContextMap = contextMapTransform + fallthrough + + case contextMapTransform: + bits, ok := br.safeReadBits(1) + if !ok { + return decoderResultNeedsMoreInput + } + if bits != 0 { + s.inverseMoveToFrontTransform(*contextMap) + } + h.substateContextMap = contextMapNone + return decoderResultSuccess + + default: + s.err = decompressError("unreachable context map state") + return decoderResultError + } + } +} + +// inverseMoveToFrontTransform applies the inverse MTF transform in-place. +func (s *decodeState) inverseMoveToFrontTransform(v []byte) { + var list [256]byte + for i := range 256 { + list[i] = byte(i) + } + + upperBound := uint(0) + for i := range v { + idx := int(v[i]) + val := list[idx] + upperBound |= uint(idx) + v[i] = val + copy(list[1:idx+1], list[:idx]) + list[0] = val + } + s.mtfUpperBound = upperBound >> 2 +} + +// --- Huffman tree group decode --- + +func (s *decodeState) huffmanTreeGroupDecode(group *huffmanTreeGroup) decoderResult { + h := &s.headerArena + if h.substateTreeGroup != treeGroupLoop { + h.htreeIndex = 0 + h.next = 0 + h.substateTreeGroup = treeGroupLoop + } + for h.htreeIndex < int(group.numHTrees) { + var tableSize uint32 + result := s.readHuffmanCode(uint(group.alphabetSizeMax), uint(group.alphabetSizeLimit), + group.codes[h.next:], &tableSize) + if result != decoderResultSuccess { + return result + } + group.htrees[h.htreeIndex] = h.next + h.next += int(tableSize) + h.htreeIndex++ + } + h.substateTreeGroup = treeGroupNone + return decoderResultSuccess +} + +// --- Read Huffman code --- + +func (s *decodeState) readHuffmanCode(alphabetSizeMax, alphabetSizeLimit uint, table []core.HuffmanCode, optTableSize *uint32) decoderResult { + br := &s.br + h := &s.headerArena + + for { + switch h.substateHuffman { + case huffmanNone: + bits, ok := br.safeReadBits(2) + if !ok { + return decoderResultNeedsMoreInput + } + h.subLoopCounter = uint(bits) + if bits != 1 { + // Complex prefix code. + h.space = 32 + h.repeat = 0 + h.codeLengthHisto = [16]uint16{} + h.codeLengthCodeLengths = [core.AlphabetSizeCodeLengths]byte{} + h.substateHuffman = huffmanComplex + continue + } + fallthrough + + case huffmanSimpleSize: + bits, ok := br.safeReadBits(2) + if !ok { + h.substateHuffman = huffmanSimpleSize + return decoderResultNeedsMoreInput + } + h.symbol = uint(bits) // num_symbols (0..3 means 1..4) + h.subLoopCounter = 0 + fallthrough + + case huffmanSimpleRead: + result := s.readSimpleHuffmanSymbols(alphabetSizeMax, alphabetSizeLimit) + if result != decoderResultSuccess { + return result + } + fallthrough + + case huffmanSimpleBuild: + if h.symbol == 3 { + bits, ok := br.safeReadBits(1) + if !ok { + h.substateHuffman = huffmanSimpleBuild + return decoderResultNeedsMoreInput + } + h.symbol += uint(bits) + } + tableSize := core.BuildSimpleHuffmanTable(table, huffmanTableBits, + h.symbolListsArray[:4], uint32(h.symbol)) + if optTableSize != nil { + *optTableSize = tableSize + } + h.substateHuffman = huffmanNone + return decoderResultSuccess + + case huffmanComplex: + result := s.readCodeLengthCodeLengths() + if result != decoderResultSuccess { + return result + } + core.BuildCodeLengthsHuffmanTable(h.table[:], h.codeLengthCodeLengths[:], h.codeLengthHisto[:]) + h.codeLengthHisto = [16]uint16{} + + // Initialize symbol lists for core.BuildHuffmanTable. + h.symbolLists = h.symbolListsArray[:] + for i := 0; i <= core.HuffmanMaxCodeLength; i++ { + h.nextSymbol[i] = i - symListBase + h.symbolListsArray[i] = 0xFFFF + } + + h.symbol = 0 + h.prevCodeLen = core.InitialRepeatedCodeLength + h.repeat = 0 + h.repeatCodeLen = 0 + h.space = 32768 + h.substateHuffman = huffmanLengthSymbols + fallthrough + + case huffmanLengthSymbols: + result := s.readSymbolCodeLengths(alphabetSizeLimit) + if result != decoderResultSuccess { + return result + } + if h.space != 0 { + s.err = decompressError("huffman space not zero") + return decoderResultError + } + sl := core.SymbolList{Storage: h.symbolLists, Offset: symListBase} + tableSize := core.BuildHuffmanTable(table, huffmanTableBits, sl, h.codeLengthHisto[:]) + if optTableSize != nil { + *optTableSize = tableSize + } + h.substateHuffman = huffmanNone + return decoderResultSuccess + + default: + s.err = decompressError("unreachable huffman state") + return decoderResultError + } + } +} + +// readSimpleHuffmanSymbols reads 1..4 symbol values for simple Huffman codes. +func (s *decodeState) readSimpleHuffmanSymbols(alphabetSizeMax, alphabetSizeLimit uint) decoderResult { + br := &s.br + h := &s.headerArena + + maxBits := uint(0) + if alphabetSizeMax > 1 { + v := alphabetSizeMax - 1 + for v > 0 { + maxBits++ + v >>= 1 + } + } + + i := h.subLoopCounter + numSymbols := h.symbol + for i <= numSymbols { + v, ok := br.safeReadBits(maxBits) + if !ok { + h.subLoopCounter = i + h.substateHuffman = huffmanSimpleRead + return decoderResultNeedsMoreInput + } + if uint(v) >= alphabetSizeLimit { + s.err = decompressError("simple huffman alphabet overflow") + return decoderResultError + } + h.symbolListsArray[i] = uint16(v) + i++ + } + + // Check for duplicates. + for i := range numSymbols { + for k := i + 1; k <= numSymbols; k++ { + if h.symbolListsArray[i] == h.symbolListsArray[k] { + s.err = decompressError("duplicate simple huffman symbols") + return decoderResultError + } + } + } + + return decoderResultSuccess +} + +// readCodeLengthCodeLengths reads code length code lengths using the static +// prefix code (RFC 7932 §3.5). Can suspend and resume via h.subLoopCounter. +func (s *decodeState) readCodeLengthCodeLengths() decoderResult { + br := &s.br + h := &s.headerArena + numCodes := h.repeat + space := h.space + i := h.subLoopCounter + for i < core.AlphabetSizeCodeLengths { + codeLenIdx := core.CodeLengthCodeOrder[i] + ix, prefixAvailable := br.safeGetBits(4) + if !prefixAvailable { + avail := br.availBits() + if avail != 0 { + ix = br.bitsUnmasked() & 0xF + } else { + ix = 0 + } + if uint(codeLengthPrefixLength[ix]) > avail { + h.subLoopCounter = i + h.repeat = numCodes + h.space = space + h.substateHuffman = huffmanComplex + return decoderResultNeedsMoreInput + } + } + v := codeLengthPrefixValue[ix] + br.dropBits(uint(codeLengthPrefixLength[ix])) + h.codeLengthCodeLengths[codeLenIdx] = v + if v != 0 { + space -= 32 >> v + numCodes++ + h.codeLengthHisto[v]++ + if space-1 >= 32 { + break + } + } + i++ + } + if numCodes != 1 && space != 0 { + s.err = decompressError("invalid code length code space") + return decoderResultError + } + return decoderResultSuccess +} + +// processSingleCodeLength processes a single code length symbol. +func (h *metablockHeaderArena) processSingleCodeLength(codeLen uint) { + h.repeat = 0 + if codeLen != 0 { + h.symbolListsArray[h.nextSymbol[codeLen]+symListBase] = uint16(h.symbol) + h.nextSymbol[codeLen] = int(h.symbol) + h.prevCodeLen = codeLen + h.space -= 32768 >> codeLen + h.codeLengthHisto[codeLen]++ + } + h.symbol++ +} + +// processRepeatedCodeLength processes a repeated code length (16 or 17). +func (h *metablockHeaderArena) processRepeatedCodeLength(codeLen, repeatDelta, alphabetSize uint) { + extraBits := uint(3) + newLen := uint(0) + if codeLen == core.RepeatPreviousCodeLength { + newLen = h.prevCodeLen + extraBits = 2 + } + if h.repeatCodeLen != newLen { + h.repeat = 0 + h.repeatCodeLen = newLen + } + oldRepeat := h.repeat + if h.repeat > 0 { + h.repeat -= 2 + h.repeat <<= extraBits + } + h.repeat += repeatDelta + 3 + delta := h.repeat - oldRepeat + if h.symbol+delta > alphabetSize { + h.symbol = alphabetSize + h.space = 0xFFFFF + return + } + if h.repeatCodeLen != 0 { + sym := h.symbol + last := sym + delta + next := h.nextSymbol[h.repeatCodeLen] + for sym < last { + h.symbolListsArray[next+symListBase] = uint16(sym) + next = int(sym) + sym++ + } + h.symbol = last + h.nextSymbol[h.repeatCodeLen] = next + h.space -= delta << (15 - h.repeatCodeLen) + h.codeLengthHisto[h.repeatCodeLen] += uint16(delta) + } else { + h.symbol += delta + } +} + +func (s *decodeState) readSymbolCodeLengths(alphabetSize uint) decoderResult { + br := &s.br + h := &s.headerArena + + if !br.warmup() { + return decoderResultNeedsMoreInput + } + + // Batched fast path: hoist bit reader state into locals and process + // single code lengths in a tight loop without per-symbol method calls. + if br.checkInputAmount() { + val := br.val + bitPos := br.bitPos + brPos := br.pos + inputBase := br.inputBase + tableBase := unsafe.Pointer(&h.table[0]) + symbol := h.symbol + + for symbol < alphabetSize && h.space > 0 { + // fillBitWindow inline + if bitPos <= 32 { + if brPos > br.fastEnd { + break + } + val |= uint64(*(*uint32)(unsafe.Add(inputBase, brPos))) << bitPos + bitPos += 32 + brPos += 4 + } + + // Decode code length from table — the table has exactly 32 entries + // (1 << core.HuffmanMaxCodeLengthCodeLength), so masking with 0x1F is + // always in bounds. + raw := *(*uint32)(unsafe.Add(tableBase, (val&0x1F)*4)) + drop := uint(raw & 0xFF) + codeLen := uint(raw >> 16) + + bitPos -= drop + val >>= drop & 63 + + if codeLen >= core.RepeatPreviousCodeLength { + // Handle repeat code: inline processRepeatedCodeLength + // to avoid function call overhead and unnecessary br write-backs. + extraBits := uint(2) + newLen := uint(0) + if codeLen == core.RepeatPreviousCodeLength { + newLen = h.prevCodeLen + } else { + extraBits = 3 + } + repeatDelta := uint(val & bitMask(extraBits)) + bitPos -= extraBits + val >>= extraBits & 63 + + if h.repeatCodeLen != newLen { + h.repeat = 0 + h.repeatCodeLen = newLen + } + oldRepeat := h.repeat + if h.repeat > 0 { + h.repeat -= 2 + h.repeat <<= extraBits + } + h.repeat += repeatDelta + 3 + delta := h.repeat - oldRepeat + switch { + case symbol+delta > alphabetSize: + symbol = alphabetSize + h.space = 0xFFFFF + case newLen != 0: + last := symbol + delta + next := h.nextSymbol[newLen] + for symbol < last { + h.symbolListsArray[next+symListBase] = uint16(symbol) + next = int(symbol) + symbol++ + } + h.nextSymbol[newLen] = next + h.space -= delta << (15 - newLen) + h.codeLengthHisto[newLen] += uint16(delta) + default: + symbol += delta + } + + if brPos > br.fastEnd { + h.symbol = symbol + br.val = val + br.bitPos = bitPos + br.pos = brPos + goto slow + } + continue + } + + // processSingleCodeLength inline + h.repeat = 0 + if codeLen != 0 { + h.symbolListsArray[h.nextSymbol[codeLen]+symListBase] = uint16(symbol) + h.nextSymbol[codeLen] = int(symbol) + h.prevCodeLen = codeLen + h.space -= 32768 >> codeLen + h.codeLengthHisto[codeLen]++ + } + symbol++ + } + + h.symbol = symbol + br.val = val + br.bitPos = bitPos + br.pos = brPos + } + +slow: + for h.symbol < alphabetSize && h.space > 0 { + p := h.table[:] + if br.checkInputAmount() { + // Fast path. + br.fillBitWindow16() + entry := p[br.bitsUnmasked()&bitMask(core.HuffmanMaxCodeLengthCodeLength)] + br.dropBits(uint(entry.Bits)) + codeLen := uint(entry.Value) + if codeLen < core.RepeatPreviousCodeLength { + h.processSingleCodeLength(codeLen) + } else { + extraBits := uint(2) + if codeLen != core.RepeatPreviousCodeLength { + extraBits = 3 + } + repeatDelta := uint(br.bitsUnmasked() & bitMask(extraBits)) + br.dropBits(extraBits) + h.processRepeatedCodeLength(codeLen, repeatDelta, alphabetSize) + } + } else { + // Safe path. + availBits := br.availBits() + var bits uint64 + if availBits != 0 { + bits = br.bitsUnmasked() + } + entry := p[bits&bitMask(core.HuffmanMaxCodeLengthCodeLength)] + if uint(entry.Bits) > availBits { + if !br.pullByte() { + return decoderResultNeedsMoreInput + } + continue + } + codeLen := uint(entry.Value) + if codeLen < core.RepeatPreviousCodeLength { + br.dropBits(uint(entry.Bits)) + h.processSingleCodeLength(codeLen) + } else { + extraBits := codeLen - 14 + repeatDelta := uint((bits >> uint(entry.Bits)) & bitMask(extraBits)) + if availBits < uint(entry.Bits)+extraBits { + if !br.pullByte() { + return decoderResultNeedsMoreInput + } + continue + } + br.dropBits(uint(entry.Bits) + extraBits) + h.processRepeatedCodeLength(codeLen, repeatDelta, alphabetSize) + } + } + } + return decoderResultSuccess +} + +// --- Distance LUT --- + +func (s *decodeState) calculateDistanceLut() { + b := &s.bodyArena + npostfix := s.distancePostfixBits + ndirect := s.numDirectDistanceCodes + alphabetSizeLimit := uint(s.distanceHGroup.alphabetSizeLimit) + + // Skip recomputation when the parameters haven't changed. + if b.cachedValid && + b.cachedPostfix == npostfix && + b.cachedDirect == ndirect && + b.cachedAlphabetSizeLim == alphabetSizeLimit { + return + } + + postfix := uint(1) << npostfix + + i := uint(core.NumDistanceShortCodes) + + // Fill direct codes. + for j := range ndirect { + b.distExtraBits[i] = 0 + b.distOffset[i] = j + 1 + i++ + } + + // Fill regular distance codes. + bits := uint(1) + half := uint(0) + for i < alphabetSizeLimit { + base := ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1 + for j := range postfix { + b.distExtraBits[i] = byte(bits) + b.distOffset[i] = base + j + i++ + } + bits += half + half ^= 1 + } + + b.cachedPostfix = npostfix + b.cachedDirect = ndirect + b.cachedAlphabetSizeLim = alphabetSizeLimit + b.cachedValid = true +} + +// --- Command processing (the hot loop) --- + +func (s *decodeState) processCommands() decoderResult { + br := &s.br + pos := s.pos + i := s.loopCounter + var cmdCode uint + var ok bool + var v core.CmdLutElement + var insertLenExtra uint64 + var literal uint + var p1, p2 byte + + // Dispatch to the correct entry point based on state. + switch s.state { + case decoderStateCommandInner: + goto commandInner + case decoderStateCommandPostDecodeLiterals: + goto commandPostDecodeLiterals + case decoderStateCommandPostWrapCopy: + goto commandPostWrapCopy + } + +commandBegin: + if s.blockLength[1] == 0 && s.numBlockTypes[1] > 1 { + if br.checkInputAmount() { + s.decodeBlockTypeAndLength(false, 1) + } else if !s.decodeBlockTypeAndLength(true, 1) { + s.state = decoderStateCommandBegin + s.pos = pos + return decoderResultNeedsMoreInput + } + s.htreeCommand = s.insertCopyHGroup.codes[s.insertCopyHGroup.htrees[s.blockTypeRB[3]]:] + } + + // Read command. + if br.checkInputAmount() { + br.fillBitWindow(16) + val := br.val + // Inline command symbol decode with unsafe pointer arithmetic to + // avoid bounds checks on every command (same pattern as distanceSymbolEntryFast). + cmdTableBase := unsafe.Pointer(unsafe.SliceData(s.htreeCommand)) + idx := val & huffmanTableMask + raw := *(*uint32)(unsafe.Add(cmdTableBase, idx*4)) + cmdDrop := uint(raw & 0xFF) + cmdCode = uint(raw >> 16) + if cmdDrop > huffmanTableBits { + nbits := cmdDrop - huffmanTableBits + idx2 := idx + uint64(cmdCode) + ((val >> huffmanTableBits) & bitMask(nbits)) + raw = *(*uint32)(unsafe.Add(cmdTableBase, idx2*4)) + cmdDrop = huffmanTableBits + uint(raw&0xFF) + cmdCode = uint(raw >> 16) + } + + v = *(*core.CmdLutElement)(unsafe.Add(unsafe.Pointer(&core.CmdLut[0]), uintptr(cmdCode)*unsafe.Sizeof(core.CmdLutElement{}))) + s.distanceCode = int(v.DistanceCode) + s.distanceContext = int(v.Context) + s.distCodesOffset = s.distCodesCache[s.distanceContext&3] + i = int(v.InsertLenOffset) + + // Combined drop + readBits for insertLenExtra + copyLenExtra: + // use local val/bitPos to avoid redundant stores/loads of br.val + // and br.bitPos across intervening struct writes. + val >>= cmdDrop & 63 + bitPos := br.bitPos - cmdDrop + + insertLenExtra = 0 + if v.InsertLenExtraBits != 0 { + if bitPos <= 32 { + val |= uint64(*(*uint32)(unsafe.Add(br.inputBase, br.pos))) << bitPos + bitPos += 32 + br.pos += 4 + } + insertLenExtra = val & bitMask(uint(v.InsertLenExtraBits)) + val >>= uint(v.InsertLenExtraBits) & 63 + bitPos -= uint(v.InsertLenExtraBits) + } + + if bitPos <= 32 { + val |= uint64(*(*uint32)(unsafe.Add(br.inputBase, br.pos))) << bitPos + bitPos += 32 + br.pos += 4 + } + copyExtra := val & bitMask(uint(v.CopyLenExtraBits)) + val >>= uint(v.CopyLenExtraBits) & 63 + bitPos -= uint(v.CopyLenExtraBits) + + br.val = val + br.bitPos = bitPos + + s.copyLength = int(v.CopyLenOffset) + int(copyExtra) + } else { + cmdMemento := br.saveState() + cmdCode, ok = safeReadSymbol(s.htreeCommand, br) + if !ok { + s.state = decoderStateCommandBegin + s.pos = pos + return decoderResultNeedsMoreInput + } + s.safeCmdMemento = cmdMemento + + v = core.CmdLut[cmdCode] + s.distanceCode = int(v.DistanceCode) + s.distanceContext = int(v.Context) + s.distCodesOffset = s.distCodesCache[s.distanceContext] + i = int(v.InsertLenOffset) + + insertLenExtra = 0 + if v.InsertLenExtraBits != 0 { + insertLenExtra, ok = br.safeReadBits(uint(v.InsertLenExtraBits)) + if !ok { + br.restoreState(s.safeCmdMemento) + s.state = decoderStateCommandBegin + s.pos = pos + return decoderResultNeedsMoreInput + } + } + var val uint64 + val, ok = br.safeReadBits(uint(v.CopyLenExtraBits)) + if !ok { + br.restoreState(s.safeCmdMemento) + s.state = decoderStateCommandBegin + s.pos = pos + return decoderResultNeedsMoreInput + } + s.copyLength = int(v.CopyLenOffset) + int(val) + } + s.blockLength[1]-- + i += int(insertLenExtra) + + s.metaBlockRemainingLen -= i + if i == 0 { + goto commandPostDecodeLiterals + } + +commandInner: + // CommandInner: read i literal bytes. + if s.trivialLiteralContext != 0 { + for i > 0 { + if s.blockLength[0] == 0 && s.numBlockTypes[0] > 1 { + if br.checkInputAmount() { + s.decodeBlockTypeAndLength(false, 0) + } else if !s.decodeBlockTypeAndLength(true, 0) { + s.state = decoderStateCommandInner + s.pos = pos + s.loopCounter = i + return decoderResultNeedsMoreInput + } + s.prepareLiteralDecoding() + if s.trivialLiteralContext == 0 { + goto commandInner + } + } + + // Batch decode: when we have enough input, ringbuffer space, + // and block length, decode multiple literals without per-symbol checks. + n := min(i, int(s.blockLength[0]), s.ringbufferSize-pos, (br.availIn()-4)/2) + if n == 1 { + // Inline single-symbol decode to avoid decodeLiteralsBatch + // function-call overhead (register save/restore) for the common + // case of insert_len=1. Safe because n=1 implies availIn>=6>4. + br.fillBitWindow(16) + s.ringbuffer[pos] = byte(decodeSymbol(br.val, s.literalHTree, br)) + pos++ + i-- + s.blockLength[0]-- + if pos == s.ringbufferSize { + s.state = decoderStateCommandInnerWrite + s.pos = pos + s.loopCounter = i + return decoderResultNeedsMoreOutput + } + continue + } else if n > 1 { + decodeLiteralsBatch(s.ringbuffer[pos:], n, s.literalHTree, br) + pos += n + i -= n + s.blockLength[0] -= uint(n) + if pos == s.ringbufferSize { + s.state = decoderStateCommandInnerWrite + s.pos = pos + s.loopCounter = i + return decoderResultNeedsMoreOutput + } + continue + } + + // Slow path: not enough input for batch, decode one symbol at a time. + if br.checkInputAmount() { + br.fillBitWindow(16) + literal = decodeSymbol(br.val, s.literalHTree, br) + } else { + literal, ok = safeReadSymbol(s.literalHTree, br) + if !ok { + s.state = decoderStateCommandInner + s.pos = pos + s.loopCounter = i + return decoderResultNeedsMoreInput + } + } + s.ringbuffer[pos] = byte(literal) + s.blockLength[0]-- + pos++ + if pos == s.ringbufferSize { + s.state = decoderStateCommandInnerWrite + i-- + s.pos = pos + s.loopCounter = i + return decoderResultNeedsMoreOutput + } + i-- + } + } else { + p1 = s.ringbuffer[(pos-1)&s.ringbufferMask] + p2 = s.ringbuffer[(pos-2)&s.ringbufferMask] + for i > 0 { + if s.blockLength[0] == 0 && s.numBlockTypes[0] > 1 { + if br.checkInputAmount() { + s.decodeBlockTypeAndLength(false, 0) + } else if !s.decodeBlockTypeAndLength(true, 0) { + s.state = decoderStateCommandInner + s.pos = pos + s.loopCounter = i + return decoderResultNeedsMoreInput + } + s.prepareLiteralDecoding() + if s.trivialLiteralContext != 0 { + goto commandInner + } + } + + // Batch decode: when we have enough input, ringbuffer space, + // and block length, decode multiple context-dependent literals + // without per-symbol bounds checks. + n := min(i, int(s.blockLength[0]), s.ringbufferSize-pos, (br.availIn()-4)/2) + if n > 0 { + p1, p2 = decodeLiteralsContextBatch( + s.ringbuffer[pos:], n, + &s.literalCodesPtrs, + s.contextLookup, p1, p2, br, + ) + pos += n + i -= n + s.blockLength[0] -= uint(n) + if pos == s.ringbufferSize { + s.state = decoderStateCommandInnerWrite + s.pos = pos + s.loopCounter = i + return decoderResultNeedsMoreOutput + } + continue + } + + ctx := s.contextLookup[p1] | s.contextLookup[256+int(p2)] + hc := s.literalHGroup.codes[s.literalCodesOffsets[ctx]:] + p2 = p1 + if br.checkInputAmount() { + br.fillBitWindow(16) + p1 = byte(decodeSymbol(br.val, hc, br)) + } else { + literal, ok = safeReadSymbol(hc, br) + if !ok { + s.state = decoderStateCommandInner + s.pos = pos + s.loopCounter = i + return decoderResultNeedsMoreInput + } + p1 = byte(literal) + } + s.ringbuffer[pos] = p1 + s.blockLength[0]-- + pos++ + if pos == s.ringbufferSize { + s.state = decoderStateCommandInnerWrite + i-- + s.pos = pos + s.loopCounter = i + return decoderResultNeedsMoreOutput + } + i-- + } + } + + if s.metaBlockRemainingLen <= 0 { + s.state = decoderStateMetablockDone + s.pos = pos + s.loopCounter = i + return decoderResultSuccess + } + +commandPostDecodeLiterals: + if s.distanceCode >= 0 { + // Implicit distance. + if s.distanceCode != 0 { + s.distanceContext = 0 + } else { + s.distanceContext = 1 + } + s.distRBIdx-- + s.distanceCode = s.distRB[s.distRBIdx&3] + } else { + // Read distance code. + if s.blockLength[2] == 0 && s.numBlockTypes[2] > 1 { + if br.checkInputAmount() { + s.decodeBlockTypeAndLength(false, 2) + } else if !s.decodeBlockTypeAndLength(true, 2) { + s.state = decoderStateCommandPostDecodeLiterals + s.pos = pos + s.loopCounter = i + return decoderResultNeedsMoreInput + } + s.distContextMapSliceIdx = int(s.blockTypeRB[5]) << core.DistanceContextBits + s.updateDistCodesCache() + s.distCodesOffset = s.distCodesCache[s.distanceContext] + } + // Inlined fast path of readDistance to avoid function call overhead + // (readDistance exceeds the compiler's inlining budget). + if br.checkInputAmount() { + br.fillBitWindow(16) + val := br.val + raw := distanceSymbolEntryFast(val, s.distanceHGroup.codes, s.distCodesOffset) + drop := uint(raw & 0xFF) + code := uint(raw >> 16) + if drop > huffmanTableBits { + code, drop = decodeDistanceSymbolSecondLevel(val, s.distanceHGroup.codes, s.distCodesOffset, code, drop) + } + // Combined dropBits + readBits32: use locals to avoid + // redundant stores/loads of br.val and br.bitPos. + val >>= drop & 63 + bitPos := br.bitPos - drop + s.blockLength[2]-- + s.distanceContext = 0 + if code&^0xF == 0 { + br.val = val + br.bitPos = bitPos + s.distanceCode = int(code) + s.takeDistanceFromRingBuffer() + } else { + b := &s.bodyArena + nExtra := uint(*(*byte)(unsafe.Add(unsafe.Pointer(&b.distExtraBits[0]), uintptr(code)))) + offset := *(*uint)(unsafe.Add(unsafe.Pointer(&b.distOffset[0]), uintptr(code)*unsafe.Sizeof(uint(0)))) + if bitPos <= 32 { + val |= uint64(*(*uint32)(unsafe.Add(br.inputBase, br.pos))) << bitPos + bitPos += 32 + br.pos += 4 + } + bits := val & bitMask(nExtra) + br.val = val >> (nExtra & 63) + br.bitPos = bitPos - nExtra + s.distanceCode = int(offset + uint(bits)< s.maxDistance { + if s.distanceCode > maxAllowedDistance { + s.err = decompressError("invalid backward reference distance") + return decoderResultError + } + + compoundSize := s.compoundDictSize() + + switch { + case s.distanceCode-s.maxDistance <= compoundSize: + // Compound dictionary reference. + address := compoundSize - (s.distanceCode - s.maxDistance) + if !s.compoundDict.initCopy(s, address, i) { + s.err = decompressError("invalid compound dictionary reference") + return decoderResultError + } + pos += s.compoundDict.copyTo(s, pos) + if pos >= s.ringbufferSize { + s.state = decoderStateCommandPostWrite1 + s.pos = pos + s.loopCounter = 0 + return decoderResultNeedsMoreOutput + } + + case i >= core.DictMinWordLength && i <= core.DictMaxWordLength: + // Static dictionary reference. + address := s.distanceCode - s.maxDistance - 1 - compoundSize + shift := uint(core.DictSizeBitsByLength[i]) + if shift == 0 { + s.err = decompressError("invalid static dictionary reference") + return decoderResultError + } + wordIdx := address & ((1 << shift) - 1) + transformIdx := address >> shift + if transformIdx >= core.NumTransforms { + s.err = decompressError("invalid dictionary transform") + return decoderResultError + } + offset := int(core.DictOffsetsByLength[i]) + wordIdx*i + word := core.DictData[offset : offset+i] + + // Compensate double distance-ring-buffer roll. + s.distRBIdx += s.distanceContext + + if transformIdx == int(core.TransformCutOffs[0]) { + copy(s.ringbuffer[pos:], word) + } else { + i = core.TransformDictionaryWord(s.ringbuffer[pos:], word, transformIdx) + if i == 0 { + s.err = decompressError("invalid dictionary transform") + return decoderResultError + } + } + pos += i + s.metaBlockRemainingLen -= i + if pos >= s.ringbufferSize { + s.state = decoderStateCommandPostWrite1 + s.pos = pos + s.loopCounter = 0 + return decoderResultNeedsMoreOutput + } + + default: + s.err = decompressError("invalid dictionary word length") + return decoderResultError + } + + if s.metaBlockRemainingLen <= 0 { + s.state = decoderStateMetablockDone + s.pos = pos + s.loopCounter = 0 + return decoderResultSuccess + } + goto commandBegin + } + + // Copy from ring buffer. + s.distRB[s.distRBIdx&3] = s.distanceCode + s.distRBIdx++ + s.metaBlockRemainingLen -= i + + { + srcStart := (pos - s.distanceCode) & s.ringbufferMask + dstEnd := pos + i + srcEnd := srcStart + i + + // Eagerly copy 16 bytes using direct pointer arithmetic. + // The ring buffer has 542 bytes of slack past ringbufferSize, + // so pos+16 and srcStart+16 are always within bounds. + base := unsafe.Pointer(unsafe.SliceData(s.ringbuffer)) + *(*[16]byte)(unsafe.Add(base, pos)) = *(*[16]byte)(unsafe.Add(base, srcStart)) + + if (srcEnd > pos && dstEnd > srcStart) || + dstEnd >= s.ringbufferSize || srcEnd >= s.ringbufferSize { + // Overlapping or wrapping — fall back to byte-by-byte. + goto commandPostWrapCopy + } + + pos += i + if i > 16 { + // Use fixed-size 16-byte copies for sizes up to 96 to avoid + // the overhead of a memmove function call on moderate copies. + src16 := srcStart + 16 + dst16 := pos - i + 16 + *(*[16]byte)(unsafe.Add(base, dst16)) = *(*[16]byte)(unsafe.Add(base, src16)) + if i > 32 { + *(*[16]byte)(unsafe.Add(base, dst16+16)) = *(*[16]byte)(unsafe.Add(base, src16+16)) + if i > 48 { + *(*[16]byte)(unsafe.Add(base, dst16+32)) = *(*[16]byte)(unsafe.Add(base, src16+32)) + if i > 64 { + *(*[16]byte)(unsafe.Add(base, dst16+48)) = *(*[16]byte)(unsafe.Add(base, src16+48)) + if i > 80 { + *(*[16]byte)(unsafe.Add(base, dst16+64)) = *(*[16]byte)(unsafe.Add(base, src16+64)) + if i > 96 { + copy(s.ringbuffer[dst16+80:pos], s.ringbuffer[src16+80:srcEnd]) + } + } + } + } + } + } + + goto postCopy + } + +commandPostWrapCopy: + for i > 0 { + s.ringbuffer[pos] = s.ringbuffer[(pos-s.distanceCode)&s.ringbufferMask] + pos++ + i-- + if pos == s.ringbufferSize { + s.state = decoderStateCommandPostWrite2 + s.pos = pos + s.loopCounter = i + return decoderResultNeedsMoreOutput + } + } + +postCopy: + + if s.metaBlockRemainingLen <= 0 { + s.state = decoderStateMetablockDone + s.pos = pos + s.loopCounter = i + return decoderResultSuccess + } + goto commandBegin +} + +// --- Distance reading --- + +func (s *decodeState) readDistance(br *bitReader) decoderResult { + b := &s.bodyArena + distTree := s.distanceHGroup.codes[s.distCodesOffset:] + + if br.checkInputAmount() { + br.fillBitWindow(16) + code := decodeSymbol(br.val, distTree, br) + s.blockLength[2]-- + s.distanceContext = 0 + if code&^0xF == 0 { + s.distanceCode = int(code) + s.takeDistanceFromRingBuffer() + return decoderResultSuccess + } + // After the first checkInputAmount (availIn >= 28) and one + // fillBitWindow (consuming at most 4 bytes), at least 24 bytes + // remain — enough for readBits32's inner fillBitWindow. + bits := br.readBits32(uint(b.distExtraBits[code])) + s.distanceCode = int(b.distOffset[code] + uint(bits)<> s.distanceCode + s.distanceCode = s.distRB[(s.distRBIdx-offset)&3] + s.distRBIdx -= s.distanceContext + } else { + indexDelta := 3 + base := s.distanceCode - 10 + if s.distanceCode < 10 { + base = s.distanceCode - 4 + } else { + indexDelta = 2 + } + delta := ((0x605142 >> (4 * base)) & 0xF) - 3 + s.distanceCode = s.distRB[(s.distRBIdx+indexDelta)&0x3] + delta + if s.distanceCode <= 0 { + s.distanceCode = 0x7FFFFFFF + } + } +} + +// decompressError formats a decode-stage error. +func decompressError(msg string) error { + return errors.New("brotli: " + msg) +} + +// --- Huffman symbol reading --- + +// decodeSymbol decodes a Huffman symbol from the bit reader using a two-level table. +// Requires at least 15 bits available. +func decodeSymbol(bits uint64, table []core.HuffmanCode, br *bitReader) uint { + idx := bits & huffmanTableMask + entry := table[idx] + drop := uint(entry.Bits) + if drop > huffmanTableBits { + nbits := drop - huffmanTableBits + entry = table[idx+uint64(entry.Value)+((bits>>huffmanTableBits)&bitMask(nbits))] + // Second-level entry.Bits stores codeLen-rootBits; combine both drops + // into a single shift to reduce overhead on the hot path. + drop = huffmanTableBits + uint(entry.Bits) + } + br.dropBits(drop) + return uint(entry.Value) +} + +// distanceSymbolEntryFast loads the first-level distance Huffman table entry. +func distanceSymbolEntryFast(bits uint64, table []core.HuffmanCode, offset int) uint32 { + tableBase := unsafe.Add( + unsafe.Pointer(unsafe.SliceData(table)), + uintptr(offset)*unsafe.Sizeof(core.HuffmanCode{}), + ) + idx := bits & huffmanTableMask + return *(*uint32)(unsafe.Add(tableBase, idx*4)) +} + +// decodeDistanceSymbolSecondLevel decodes a second-level distance Huffman entry. +func decodeDistanceSymbolSecondLevel(bits uint64, table []core.HuffmanCode, offset int, code, drop uint) (uint, uint) { + tableBase := unsafe.Add( + unsafe.Pointer(unsafe.SliceData(table)), + uintptr(offset)*unsafe.Sizeof(core.HuffmanCode{}), + ) + nbits := drop - huffmanTableBits + idx := (bits & huffmanTableMask) + uint64(code) + ((bits >> huffmanTableBits) & bitMask(nbits)) + raw := *(*uint32)(unsafe.Add(tableBase, idx*4)) + return uint(raw >> 16), huffmanTableBits + uint(raw&0xFF) +} + +// decodeLiteralsBatch decodes n literal symbols from br into dst using table. +// It hoists the bitReader state into local variables to keep them in registers +// and avoid repeated struct field access on the hot path. +// The loop is 2x-unrolled: after one fill (bitPos goes from ≤32 to ≥33), +// two Huffman decodes (each consuming ≤15 bits) are safe without a second fill +// since 33−30 = 3 bits always remain, and the next pair will refill. +func decodeLiteralsBatch(dst []byte, n int, table []core.HuffmanCode, br *bitReader) { + val := br.val + bitPos := br.bitPos + brPos := br.pos + inputBase := br.inputBase + tableBase := unsafe.Pointer(unsafe.SliceData(table)) + + j := 0 + for ; j+1 < n; j += 2 { + // fillBitWindow inline — one fill covers two symbols. + if bitPos <= 32 { + val |= uint64(*(*uint32)(unsafe.Add(inputBase, brPos))) << bitPos + bitPos += 32 + brPos += 4 + } + + // Symbol 1 + idx := val & huffmanTableMask + raw := *(*uint32)(unsafe.Add(tableBase, idx*4)) + drop := uint(raw & 0xFF) + value := uint(raw >> 16) + if drop > huffmanTableBits { + nbits := drop - huffmanTableBits + idx2 := idx + uint64(value) + ((val >> huffmanTableBits) & bitMask(nbits)) + raw = *(*uint32)(unsafe.Add(tableBase, idx2*4)) + drop = huffmanTableBits + uint(raw&0xFF) + value = uint(raw >> 16) + } + bitPos -= drop + val >>= drop & 63 + dst[j] = byte(value) + + // Symbol 2 — at least 18 bits remain (33 − 15), enough for any code (max 15). + idx = val & huffmanTableMask + raw = *(*uint32)(unsafe.Add(tableBase, idx*4)) + drop = uint(raw & 0xFF) + value = uint(raw >> 16) + if drop > huffmanTableBits { + nbits := drop - huffmanTableBits + idx2 := idx + uint64(value) + ((val >> huffmanTableBits) & bitMask(nbits)) + raw = *(*uint32)(unsafe.Add(tableBase, idx2*4)) + drop = huffmanTableBits + uint(raw&0xFF) + value = uint(raw >> 16) + } + bitPos -= drop + val >>= drop & 63 + dst[j+1] = byte(value) + } + + // Handle remaining odd element. + if j < n { + if bitPos <= 32 { + val |= uint64(*(*uint32)(unsafe.Add(inputBase, brPos))) << bitPos + bitPos += 32 + brPos += 4 + } + idx := val & huffmanTableMask + raw := *(*uint32)(unsafe.Add(tableBase, idx*4)) + drop := uint(raw & 0xFF) + value := uint(raw >> 16) + if drop > huffmanTableBits { + nbits := drop - huffmanTableBits + idx2 := idx + uint64(value) + ((val >> huffmanTableBits) & bitMask(nbits)) + raw = *(*uint32)(unsafe.Add(tableBase, idx2*4)) + drop = huffmanTableBits + uint(raw&0xFF) + value = uint(raw >> 16) + } + bitPos -= drop + val >>= drop & 63 + dst[j] = byte(value) + } + + br.val = val + br.bitPos = bitPos + br.pos = brPos +} + +// decodeLiteralsContextBatch decodes n literals using context-dependent Huffman +// trees. It hoists bitReader state into locals and uses unsafe pointer arithmetic +// to avoid per-symbol bounds checks. Returns updated (p1, p2) context bytes. +func decodeLiteralsContextBatch( + dst []byte, n int, + ptrs *[64]unsafe.Pointer, + contextLookup []byte, p1, p2 byte, + br *bitReader, +) (byte, byte) { + val := br.val + bitPos := br.bitPos + brPos := br.pos + inputBase := br.inputBase + ctxBase := unsafe.Pointer(unsafe.SliceData(contextLookup)) + // Use an incrementing pointer instead of an index to avoid spilling the + // loop counter onto the stack — on x86-64 the shift in fillBitWindow + // requires CX, which would otherwise evict j every iteration. + dstPtr := unsafe.Pointer(unsafe.SliceData(dst)) + + for n > 0 { + n-- + // fillBitWindow inline + if bitPos <= 32 { + val |= uint64(*(*uint32)(unsafe.Add(inputBase, brPos))) << bitPos + bitPos += 32 + brPos += 4 + } + + // Context lookup inline — contextLookup has 512 entries, + // p1 indexes [0..255], p2 indexes [256..511]. + ctx := *(*byte)(unsafe.Add(ctxBase, int(p1))) | *(*byte)(unsafe.Add(ctxBase, 256+int(p2))) + tableBase := ptrs[ctx&63] + + // decodeSymbol inline + idx := val & huffmanTableMask + raw := *(*uint32)(unsafe.Add(tableBase, idx*4)) + drop := uint(raw & 0xFF) + value := uint(raw >> 16) + if drop > huffmanTableBits { + nbits := drop - huffmanTableBits + idx2 := idx + uint64(value) + ((val >> huffmanTableBits) & bitMask(nbits)) + raw = *(*uint32)(unsafe.Add(tableBase, idx2*4)) + drop = huffmanTableBits + uint(raw&0xFF) + value = uint(raw >> 16) + } + // dropBits inline + bitPos -= drop + val >>= drop & 63 + + p2 = p1 + p1 = byte(value) + *(*byte)(dstPtr) = p1 + dstPtr = unsafe.Add(dstPtr, 1) + } + + br.val = val + br.bitPos = bitPos + br.pos = brPos + return p1, p2 +} + +// safeDecodeSymbol is a fallback when fewer than 15 bits may be available. +func safeDecodeSymbol(table []core.HuffmanCode, br *bitReader) (uint, bool) { + availBits := br.availBits() + if availBits == 0 { + if table[0].Bits == 0 { + return uint(table[0].Value), true + } + return 0, false + } + val := br.bitsUnmasked() + idx := val & huffmanTableMask + entry := table[idx] + if uint(entry.Bits) <= huffmanTableBits { + if uint(entry.Bits) <= availBits { + br.dropBits(uint(entry.Bits)) + return uint(entry.Value), true + } + return 0, false + } + if availBits <= huffmanTableBits { + return 0, false + } + sub := (val & bitMask(uint(entry.Bits))) >> huffmanTableBits + availBits -= huffmanTableBits + entry2 := table[idx+uint64(entry.Value)+sub] + if availBits < uint(entry2.Bits) { + return 0, false + } + br.dropBits(huffmanTableBits + uint(entry2.Bits)) + return uint(entry2.Value), true +} + +// safeReadSymbol tries the fast path (15 bits), falls back to safe decode. +func safeReadSymbol(table []core.HuffmanCode, br *bitReader) (uint, bool) { + val, ok := br.safeGetBits(15) + if ok { + return decodeSymbol(val, table, br), true + } + return safeDecodeSymbol(table, br) +} + +// --- Block length reading --- + +func readBlockLength(table []core.HuffmanCode, br *bitReader) uint { + br.fillBitWindow(16) + code := decodeSymbol(br.val, table, br) + nbits := core.BlockLengthNBits[code] + return uint(core.BlockLengthOffset[code]) + uint(br.readBits(uint(nbits))) +} + +func safeReadBlockLength(s *decodeState, table []core.HuffmanCode) (uint, bool) { + br := &s.br + var index uint + if s.substateReadBlockLength == readBlockLengthNone { + var ok bool + index, ok = safeReadSymbol(table, br) + if !ok { + return 0, false + } + } else { + index = s.blockLengthIndex + } + nbits := uint(core.BlockLengthNBits[index]) + bits, ok := br.safeReadBits(nbits) + if !ok { + s.blockLengthIndex = index + s.substateReadBlockLength = readBlockLengthSuffix + return 0, false + } + s.substateReadBlockLength = readBlockLengthNone + return uint(core.BlockLengthOffset[index]) + uint(bits), true +} diff --git a/src/vendor/github.com/molecule-man/go-brrr/decode_state.go b/src/vendor/github.com/molecule-man/go-brrr/decode_state.go new file mode 100644 index 00000000..430ed982 --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/decode_state.go @@ -0,0 +1,625 @@ +// Decoder state machine types, enums, and initialization. + +package brrr + +import ( + "unsafe" + + "github.com/molecule-man/go-brrr/internal/core" + "github.com/molecule-man/go-brrr/internal/encoder" +) + +// Decoder-specific constants. +const ( + // Maximum block/metablock length (used as default when no block switching). + blockSizeCap = 1 << 24 + + // Maximum Huffman table sizes for the decoder, indexed by alphabet size. + huffmanMaxSize272 = 646 // for context map symbols (max 272) + huffmanMaxSize258 = 632 // for block type symbols (max 258) + huffmanMaxSize26 = 396 // for block count symbols (26) +) + +const ( + decoderResultError decoderResult = iota + decoderResultSuccess + decoderResultNeedsMoreInput + decoderResultNeedsMoreOutput +) + +const ( + decoderStateUninited decoderState = iota + decoderStateLargeWindowBits + decoderStateInitialize + decoderStateMetablockBegin + decoderStateMetablockHeader + decoderStateMetablockHeader2 + decoderStateContextModes + decoderStateCommandBegin + decoderStateCommandInner + decoderStateCommandPostDecodeLiterals + decoderStateCommandPostWrapCopy + decoderStateUncompressed + decoderStateMetadata + decoderStateCommandInnerWrite + decoderStateMetablockDone + decoderStateCommandPostWrite1 + decoderStateCommandPostWrite2 + decoderStateBeforeCompressedMetablockHeader + decoderStateHuffmanCode0 + decoderStateHuffmanCode1 + decoderStateHuffmanCode2 + decoderStateHuffmanCode3 + decoderStateContextMap1 + decoderStateContextMap2 + decoderStateTreeGroup + decoderStateBeforeCompressedMetablockBody + decoderStateDone +) + +const ( + metablockHeaderNone metablockHeaderState = iota + metablockHeaderEmpty + metablockHeaderNibbles + metablockHeaderSize + metablockHeaderUncompressed + metablockHeaderReserved + metablockHeaderBytes + metablockHeaderMetadata +) + +const ( + uncompressedNone uncompressedState = iota + uncompressedWrite +) + +const ( + treeGroupNone treeGroupState = iota + treeGroupLoop +) + +const ( + contextMapNone contextMapState = iota + contextMapReadPrefix + contextMapHuffman + contextMapDecode + contextMapTransform +) + +const ( + huffmanNone huffmanState = iota + huffmanSimpleSize + huffmanSimpleRead + huffmanSimpleBuild + huffmanComplex + huffmanLengthSymbols +) + +const ( + decodeUint8None decodeUint8State = iota + decodeUint8Short + decodeUint8Long +) + +const ( + readBlockLengthNone readBlockLengthState = iota + readBlockLengthSuffix +) + +// decoderResult indicates the outcome of a decode step. +type decoderResult int + +// decoderState enumerates the top-level states of the streaming decoder. +type decoderState int + +// metablockHeaderState enumerates states within metablock header parsing. +type metablockHeaderState int + +// uncompressedState enumerates states within uncompressed metablock processing. +type uncompressedState int + +// treeGroupState enumerates states within Huffman tree group decoding. +type treeGroupState int + +// contextMapState enumerates states within context map decoding. +type contextMapState int + +// huffmanState enumerates states within Huffman code reading. +type huffmanState int + +// decodeUint8State enumerates states within uint8 decoding. +type decodeUint8State int + +// readBlockLengthState enumerates states within block length reading. +type readBlockLengthState int + +// bitReader holds the bit-level reading state for the decoder input stream. +type bitReader struct { + inputBase unsafe.Pointer // cached base pointer for bounds-check-free loads + input []byte // full input buffer (set via setInput) + pos int // current byte position in input + val uint64 // pre-fetched bits + bitPos uint // number of valid bits in val + inputLen int // cached len(input) to avoid slice header reads + fastEnd int // inputLen - fastInputSlack; checkInputAmount is pos <= fastEnd +} + +// huffmanTreeGroup holds a collection of Huffman trees sharing the same +// alphabet size. Used by the decoder to store literal, insert-copy, and +// distance Huffman trees. +type huffmanTreeGroup struct { + htrees []int // indices into codes for each tree's root + codes []core.HuffmanCode // flat backing array for all trees + alphabetSizeMax uint16 + alphabetSizeLimit uint16 + numHTrees uint16 +} + +// metablockHeaderArena holds temporary state used during metablock header +// decoding. Reused across metablocks. +type metablockHeaderArena struct { + // List of heads of symbol chains. + symbolLists []uint16 + + substateTreeGroup treeGroupState + substateContextMap contextMapState + substateHuffman huffmanState + + subLoopCounter uint + + repeatCodeLen uint + prevCodeLen uint + + // For ReadHuffmanCode. + symbol uint + repeat uint + space uint + + // Huffman table for code length histograms. + table [32]core.HuffmanCode + symbolListsArray [core.HuffmanMaxCodeLength + 1 + core.AlphabetSizeInsertAndCopyLength]uint16 + // Tails of symbol chains. + nextSymbol [32]int + codeLengthCodeLengths [core.AlphabetSizeCodeLengths]byte + // Population counts for the code lengths. + codeLengthHisto [16]uint16 + + // For HuffmanTreeGroupDecode. + htreeIndex int + next int // index into codes slice + + // For DecodeContextMap. + contextIndex uint + maxRunLengthPrefix uint + code uint + contextMapTable [huffmanMaxSize272]core.HuffmanCode +} + +// metablockBodyArena holds temporary state used during metablock body +// decoding. Not used simultaneously with metablockHeaderArena. +type metablockBodyArena struct { + distExtraBits [core.NumHistogramDistanceSymbols]byte + distOffset [core.NumHistogramDistanceSymbols]uint + + // Cache key for calculateDistanceLut: skip recomputation when params match. + cachedPostfix uint + cachedDirect uint + cachedAlphabetSizeLim uint + cachedValid bool +} + +// decoderCompoundDictionary holds compound dictionary chunks for the decoder. +// The decoder uses these chunks as a virtual LZ77 prefix: backward references +// beyond the ring buffer are resolved against the concatenated chunk data. +type decoderCompoundDictionary struct { + chunks [16][]byte + chunkOffsets [17]int // cumulative byte offsets; chunkOffsets[0] = 0 + numChunks int + totalSize int + blockBits int // -1 until lazily initialized + blockMap [256]byte // maps address >> blockBits to chunk index + // Copy state for suspension across ringbuffer writes. + brIndex int + brOffset int + brLength int + brCopied int +} + +// attach appends a dictionary chunk. +// decodeState holds the full state of a streaming brotli decoder. +// +// Fields are ordered with all pointer-containing types first (slices, +// interfaces, structs embedding slices) to minimize the GC scan range. +type decodeState struct { + // Pointer-containing fields. + br bitReader + err error + ringbuffer []byte + htreeCommand []core.HuffmanCode // slice into insertCopyHGroup.codes + contextLookup []byte + distContextMap []byte + literalHTree []core.HuffmanCode // slice into literalHGroup.codes + contextMap []byte + contextModes []byte + blockTypeTrees []core.HuffmanCode + blockLenTrees []core.HuffmanCode + literalHGroup huffmanTreeGroup + insertCopyHGroup huffmanTreeGroup + distanceHGroup huffmanTreeGroup + compoundDict *decoderCompoundDictionary + + // literalCodesPtrs caches a precomputed unsafe.Pointer for each of the + // 64 literal contexts. Each entry is codesBase + literalCodesOffsets[ctx]*4, + // eliminating a multiply and add from the critical path in + // decodeLiteralsContextBatch. Always populated alongside literalCodesOffsets + // by prepareLiteralDecoding; never zeroed by initForReuse. + // Placed here (in the pointer section) to keep all pointer-containing + // fields contiguous and avoid extending the GC scan range into the + // large scalar arrays. + literalCodesPtrs [64]unsafe.Pointer + + // In C these are a union; Go embeds both since they are never used + // simultaneously. headerArena contains a slice so it must precede + // scalar-only fields. + headerArena metablockHeaderArena + + // Scalar fields (no pointers beyond this point). + state decoderState + loopCounter int // reused for several disjoint loops + + // Temporary storage for remaining input during streaming. When the + // decoder runs out of input mid-operation, unread bytes from br.input + // are stashed here. The bitReader is then repointed at this buffer to + // resume decoding. 64 bits are enough to make progress in decoding. + bufferLength uint + buffer [8]byte + + pos int + maxBackwardDistance int + maxDistance int + ringbufferSize int + ringbufferMask int + distRBIdx int + distRB [4]int + safeCmdMemento bitReaderState // saved before safe command symbol read + metaBlockRemainingLen int + // Indices into contextMap and distContextMap slices. + contextMapSliceIdx int + distContextMapSliceIdx int + + // True if the literal context map histogram type always matches the block + // type, so context tracking is not needed (faster decoding). + trivialLiteralContext int + // Actual after command decode, before distance computation; then reused + // as a temporary variable. + distanceContext int + blockLength [3]uint + blockLengthIndex uint + numBlockTypes [3]uint + blockTypeRB [6]uint + distancePostfixBits uint + numDirectDistanceCodes uint + numDistHTrees uint + numLiteralHTrees uint + + // For partial write operations. + rbRoundtrips uint // how many times we wrapped around the ring buffer + partialPosOut uint // total output to the user + + // For InverseMoveToFrontTransform. + mtfUpperBound uint + + copyLength int + distanceCode int + + // States inside function calls. + substateMetablockHeader metablockHeaderState + substateUncompressed uncompressedState + substateDecodeUint8 decodeUint8State + substateReadBlockLength readBlockLengthState + + newRingbufferSize int + windowBits int + sizeNibbles int + + trivialLiteralContexts [8]uint32 // 256 bits + + isLastMetablock bool + isUncompressed bool + isMetadata bool + cannyRingbufferAllocation bool + distHTreeIndex byte + distCodesOffset int // cached s.distanceHGroup.htrees[distHTreeIndex] + + // distCodesCache maps each of the 4 distance contexts to the + // corresponding htrees offset for the current distance block type. + // Avoids two dependent memory loads (distContextMap → htrees) + // per command in processCommands. + distCodesCache [4]int + + // The C reference exposes BrotliDecoderSetMetadataCallbacks (decode.h) + // which lets callers receive metadata block contents via a start/chunk + // callback pair. The decoder already skips metadata blocks correctly; + // exposing their contents is a future enhancement. The idiomatic Go + // approach would be a MetadataHandler interface or io.Writer rather than + // C-style function pointers. + + bodyArena metablockBodyArena + + // literalCodesOffsets maps each of the 64 literal contexts to the + // corresponding codes offset for the current literal block type. + // Avoids two dependent memory loads (contextMap → htrees) + // per literal in the non-trivial context path of processCommands. + // Placed at end of struct to avoid shifting hot fields. + literalCodesOffsets [64]int +} + +func (g *huffmanTreeGroup) init(alphabetSizeMax, alphabetSizeLimit, ntrees uint16) { + maxTableSize := int(alphabetSizeLimit) + 376 + g.alphabetSizeMax = alphabetSizeMax + g.alphabetSizeLimit = alphabetSizeLimit + g.numHTrees = ntrees + g.codes = reuseHuffmanCodes(g.codes, int(ntrees)*maxTableSize) + g.htrees = reuseInts(g.htrees, int(ntrees)) +} + +func (cd *decoderCompoundDictionary) attach(data []byte) error { + if len(data) == 0 { + return encoder.ErrEmptyDict + } + if cd.numChunks == 15 { + return encoder.ErrTooManyDicts + } + cd.chunks[cd.numChunks] = data + cd.numChunks++ + cd.totalSize += len(data) + cd.chunkOffsets[cd.numChunks] = cd.totalSize + return nil +} + +// ensureInit lazily builds the block map for O(1) chunk lookup. +func (cd *decoderCompoundDictionary) ensureInit() { + if cd.blockBits != -1 { + return + } + blockBits := 8 + for (cd.totalSize-1)>>blockBits != 0 { + blockBits++ + } + blockBits -= 8 + cd.blockBits = blockBits + + cursor := 0 + index := 0 + for cursor < cd.totalSize { + for cd.chunkOffsets[index+1] < cursor { + index++ + } + cd.blockMap[cursor>>blockBits] = byte(index) + cursor += 1 << blockBits + } +} + +// initCopy sets up a copy operation from compound dictionary at address for +// length bytes. Updates the distance ring buffer and decrements +// metaBlockRemainingLen. Returns false if the address+length exceeds the +// total dictionary size. +func (cd *decoderCompoundDictionary) initCopy(s *decodeState, address, length int) bool { + cd.ensureInit() + index := int(cd.blockMap[address>>cd.blockBits]) + for address >= cd.chunkOffsets[index+1] { + index++ + } + if cd.totalSize < address+length { + return false + } + s.distRB[s.distRBIdx&3] = s.distanceCode + s.distRBIdx++ + s.metaBlockRemainingLen -= length + cd.brIndex = index + cd.brOffset = address - cd.chunkOffsets[index] + cd.brLength = length + cd.brCopied = 0 + return true +} + +// copyTo copies bytes from compound dictionary chunks into s.ringbuffer[pos:], +// handling chunk boundaries and stopping when the ringbuffer is full. +// Returns the number of bytes copied. +func (cd *decoderCompoundDictionary) copyTo(s *decodeState, pos int) int { + origPos := pos + for cd.brLength != cd.brCopied { + copySrc := cd.chunks[cd.brIndex][cd.brOffset:] + space := s.ringbufferSize - pos + remChunkLen := (cd.chunkOffsets[cd.brIndex+1] - cd.chunkOffsets[cd.brIndex]) - cd.brOffset + length := min(cd.brLength-cd.brCopied, min(remChunkLen, space)) + copy(s.ringbuffer[pos:], copySrc[:length]) + pos += length + cd.brOffset += length + cd.brCopied += length + if length == remChunkLen { + cd.brIndex++ + cd.brOffset = 0 + } + if pos == s.ringbufferSize { + break + } + } + return pos - origPos +} + +// init resets s to a clean initial state, ready to begin decoding. +func (s *decodeState) init() { + *s = decodeState{} + s.initDefaults() +} + +func (s *decodeState) initDefaults() { + + s.state = decoderStateUninited + s.cannyRingbufferAllocation = true + + s.distRB = [4]int{16, 15, 11, 4} + + s.mtfUpperBound = 63 +} + +func (s *decodeState) initForReuse() { + // Reset the decoder state for reuse, preserving heap-allocated backing + // arrays. Unlike the previous *s = decodeState{} approach, this avoids + // zeroing ~10 KB of arena arrays (headerArena.contextMapTable, + // headerArena.symbolListsArray, bodyArena, literalCodesOffsets) that are + // always fully initialized before being read. + + // Reset only the scalar bitReader fields that must be zero. + // inputBase and input are stale but will be overwritten by setInput + // before any read, so skipping those two pointer-bearing fields avoids + // two GC write barriers per Decompress call. + s.br.val = 0 + s.br.bitPos = 0 + s.br.pos = 0 + s.br.inputLen = 0 + s.br.fastEnd = 0 + s.err = nil + + // Nil out slices that are derived from preserved slices or set during + // decompression. The saved backing slices (ringbuffer, blockTypeTrees, + // contextMap, etc.) are kept; derived slices are re-derived later. + s.htreeCommand = nil + s.contextLookup = nil + s.literalHTree = nil + s.blockLenTrees = nil + s.compoundDict = nil + + // Zero the huffmanTreeGroup metadata (preserved slice headers stay). + s.literalHGroup.alphabetSizeMax = 0 + s.literalHGroup.alphabetSizeLimit = 0 + s.literalHGroup.numHTrees = 0 + s.insertCopyHGroup.alphabetSizeMax = 0 + s.insertCopyHGroup.alphabetSizeLimit = 0 + s.insertCopyHGroup.numHTrees = 0 + s.distanceHGroup.alphabetSizeMax = 0 + s.distanceHGroup.alphabetSizeLimit = 0 + s.distanceHGroup.numHTrees = 0 + + // Zero only the small scalar fields in headerArena; the large arrays + // (table, symbolListsArray, nextSymbol, codeLengthCodeLengths, + // codeLengthHisto, contextMapTable) are always initialized before use. + s.headerArena.symbolLists = nil + s.headerArena.substateTreeGroup = 0 + s.headerArena.substateContextMap = 0 + s.headerArena.substateHuffman = 0 + s.headerArena.subLoopCounter = 0 + s.headerArena.repeatCodeLen = 0 + s.headerArena.prevCodeLen = 0 + s.headerArena.symbol = 0 + s.headerArena.repeat = 0 + s.headerArena.space = 0 + s.headerArena.htreeIndex = 0 + s.headerArena.next = 0 + s.headerArena.contextIndex = 0 + s.headerArena.maxRunLengthPrefix = 0 + s.headerArena.code = 0 + + // Bulk-zero the contiguous scalar block (state through distCodesCache). + // This region contains no pointers, so raw memclr is safe. + // bodyArena and literalCodesOffsets are NOT zeroed — they are always + // fully written by calculateDistanceLut / prepareLiteralDecoding + // before being read. + start := unsafe.Pointer(&s.state) + size := uintptr(unsafe.Pointer(&s.distCodesCache)) - uintptr(start) + unsafe.Sizeof(s.distCodesCache) + clear(unsafe.Slice((*byte)(start), size)) + + s.initDefaults() +} + +// metablockBegin resets per-metablock state at the start of each metablock. +func (s *decodeState) metablockBegin() { + s.metaBlockRemainingLen = 0 + s.blockLength = [3]uint{blockSizeCap, blockSizeCap, blockSizeCap} + s.numBlockTypes = [3]uint{1, 1, 1} + s.blockTypeRB = [6]uint{1, 0, 1, 0, 1, 0} + s.contextMap = s.contextMap[:0] + s.contextModes = s.contextModes[:0] + s.distContextMap = s.distContextMap[:0] + s.contextMapSliceIdx = 0 + s.distContextMapSliceIdx = 0 + s.distHTreeIndex = 0 + s.distCodesOffset = 0 + s.distCodesCache = [4]int{} + // literalHTree and contextLookup are always overwritten by + // prepareLiteralDecoding before use — skipping the nil assignments here + // avoids two GC write barriers per metablock. + // literalHGroup/insertCopyHGroup/distanceHGroup .codes and .htrees are + // always overwritten by huffmanTreeGroup.init via reuseHuffmanCodes / + // reuseInts (which only check cap, not len) before use — skipping the + // [:0] reslices here avoids six more GC write barriers per metablock. +} + +// updateDistCodesCache fills distCodesCache with the htrees offset for each +// of the 4 distance contexts at the current distContextMapSliceIdx. +func (s *decodeState) updateDistCodesCache() { + base := s.distContextMapSliceIdx + for ctx := range s.distCodesCache { + idx := s.distContextMap[base+ctx] + s.distCodesCache[ctx] = s.distanceHGroup.htrees[idx] + } +} + +// stashTail copies unread bytes from br.input into the internal buffer +// for later resumption. Called when the decoder needs more input while +// reading directly from caller-supplied data. +func (s *decodeState) stashTail() { + s.br.unload() + avail := min(s.br.availIn(), len(s.buffer)) + copy(s.buffer[:avail], s.br.input[s.br.pos:s.br.pos+avail]) + s.bufferLength = uint(avail) +} + +// useStashedTail repoints the bitReader at the internal buffer so +// decoding can resume from the stashed tail bytes. +func (s *decodeState) useStashedTail() { + s.br.setInput(s.buffer[:s.bufferLength]) +} + +// compoundDictSize returns the total size of attached compound dictionaries, +// or 0 if none are attached. +func (s *decodeState) compoundDictSize() int { + if s.compoundDict == nil { + return 0 + } + return s.compoundDict.totalSize +} + +// attachCompoundDict appends a compound dictionary chunk to the decoder state. +// Lazily allocates the decoderCompoundDictionary on first call. +func (s *decodeState) attachCompoundDict(data []byte) error { + if s.compoundDict == nil { + s.compoundDict = &decoderCompoundDictionary{blockBits: -1} + } + return s.compoundDict.attach(data) +} + +// No explicit cleanup method is needed for decodeState: all resources are +// Go-managed (slices, pointers), and Reader.Close already zeroes the state. + +func reuseBytes(buf []byte, size int) []byte { + if cap(buf) >= size { + return buf[:size] + } + return make([]byte, size) +} + +func reuseInts(buf []int, size int) []int { + if cap(buf) >= size { + return buf[:size] + } + return make([]int, size) +} + +func reuseHuffmanCodes(buf []core.HuffmanCode, size int) []core.HuffmanCode { + if cap(buf) >= size { + return buf[:size] + } + return make([]core.HuffmanCode, size) +} diff --git a/src/vendor/github.com/molecule-man/go-brrr/dictionary.go b/src/vendor/github.com/molecule-man/go-brrr/dictionary.go new file mode 100644 index 00000000..f957efbd --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/dictionary.go @@ -0,0 +1,27 @@ +package brrr + +import "github.com/molecule-man/go-brrr/internal/encoder" + +// PreparedDictionary is a compound dictionary chunk built once and shared +// across many Writers. See [WriterOptions.Dictionaries]. It is an opaque +// handle; build one with [PrepareDictionary]. +type PreparedDictionary struct { + impl *encoder.PreparedDictionary +} + +// PrepareDictionary builds an immutable [PreparedDictionary] from the given +// source bytes, suitable for use as a compound dictionary chunk via +// [WriterOptions.Dictionaries]. The returned dictionary may be shared across +// any number of Writers and goroutines. +// +// The returned dictionary keeps a reference to data; the caller must not +// mutate data while any Writer holding the dictionary is still in use. +// +// Returns an error if data is empty. +func PrepareDictionary(data []byte) (*PreparedDictionary, error) { + impl, err := encoder.PrepareDictionary(data) + if err != nil { + return nil, err + } + return &PreparedDictionary{impl: impl}, nil +} diff --git a/src/vendor/github.com/molecule-man/go-brrr/doc.go b/src/vendor/github.com/molecule-man/go-brrr/doc.go new file mode 100644 index 00000000..30366235 --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/doc.go @@ -0,0 +1,81 @@ +/* +Package brrr implements the Brotli compressed data format (RFC 7932). + +Brotli is a lossless compression algorithm that typically produces +better ratios than gzip and zstd at the cost of slower compression. +Decompression is fast at every quality level. Every major browser has +accepted Content-Encoding: br since 2016, which makes brotli a good +match for static web asset pipelines. + +# Basic usage + +Streaming compression through an io.Writer: + + var buf bytes.Buffer + w, err := brrr.NewWriter(&buf, 6) + if err != nil { + log.Fatal(err) + } + if _, err := w.Write(data); err != nil { + log.Fatal(err) + } + if err := w.Close(); err != nil { + log.Fatal(err) + } + +Streaming decompression through an io.Reader: + + r := brrr.NewReader(src) + if _, err := io.Copy(dst, r); err != nil { + log.Fatal(err) + } + +One-shot decompression of a complete in-memory blob: + + out, err := brrr.Decompress(compressed) + +# Key types + + - [Writer] implements io.WriteCloser and compresses data written to + an underlying io.Writer. Close must be called to finalize the + brotli stream. + - [Reader] implements io.Reader and decompresses a brotli stream + read from an underlying io.Reader. + - [Decompress] is a convenience function for one-shot decompression + of a complete in-memory blob. + +Writer and Reader both expose Reset methods, so the same instance can +be reused across payloads without reallocating per-call buffers. Both +also accept compound dictionaries — useful when the payloads share +content with a known corpus. The encoder takes pre-built +[PreparedDictionary] values via [WriterOptions.Dictionaries], so the +hash table is built once and may be shared across many Writers and +goroutines. The decoder takes raw dictionary bytes via +[ReaderOptions.Dictionaries]. + +# Choosing a quality level + +Quality controls the ratio/speed trade-off on a scale of 0 to 11: + + - Quality 0–1 use fast one-pass and two-pass encoders optimised for + throughput. + - Quality 2–9 use a streaming encoder that spends progressively more + work per byte for better ratios. + - Quality 10–11 use a Zopfli-style optimal-parsing encoder that + produces the best ratios but is orders of magnitude slower than + the lower levels. + +The canonical use case for brotli is static asset compression — CSS, +JS, HTML, fonts, WASM — where the data is compressed once at build +time and served many times; quality 11 is the right choice there. For +on-the-fly compression, quality 5–6 gives a good balance of speed and +ratio. + +# Compatibility + +Output is byte-compatible with the reference implementation at +https://github.com/google/brotli. Any conforming brotli decoder can +read streams produced by this package, and this package can decode +any valid brotli stream. +*/ +package brrr diff --git a/src/vendor/github.com/molecule-man/go-brrr/internal/core/cmdlut.go b/src/vendor/github.com/molecule-man/go-brrr/internal/core/cmdlut.go new file mode 100644 index 00000000..2442408e --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/internal/core/cmdlut.go @@ -0,0 +1,722 @@ +// Command symbol lookup table for the decoder (RFC 7932 Section 5). + +package core + +// CmdLut maps each of the 704 command symbols to its decoding parameters. +var CmdLut = [AlphabetSizeInsertAndCopyLength]CmdLutElement{ + {0x00, 0x00, 0, 0x00, 0x0000, 0x0002}, + {0x00, 0x00, 0, 0x01, 0x0000, 0x0003}, + {0x00, 0x00, 0, 0x02, 0x0000, 0x0004}, + {0x00, 0x00, 0, 0x03, 0x0000, 0x0005}, + {0x00, 0x00, 0, 0x03, 0x0000, 0x0006}, + {0x00, 0x00, 0, 0x03, 0x0000, 0x0007}, + {0x00, 0x00, 0, 0x03, 0x0000, 0x0008}, + {0x00, 0x00, 0, 0x03, 0x0000, 0x0009}, + {0x00, 0x00, 0, 0x00, 0x0001, 0x0002}, + {0x00, 0x00, 0, 0x01, 0x0001, 0x0003}, + {0x00, 0x00, 0, 0x02, 0x0001, 0x0004}, + {0x00, 0x00, 0, 0x03, 0x0001, 0x0005}, + {0x00, 0x00, 0, 0x03, 0x0001, 0x0006}, + {0x00, 0x00, 0, 0x03, 0x0001, 0x0007}, + {0x00, 0x00, 0, 0x03, 0x0001, 0x0008}, + {0x00, 0x00, 0, 0x03, 0x0001, 0x0009}, + {0x00, 0x00, 0, 0x00, 0x0002, 0x0002}, + {0x00, 0x00, 0, 0x01, 0x0002, 0x0003}, + {0x00, 0x00, 0, 0x02, 0x0002, 0x0004}, + {0x00, 0x00, 0, 0x03, 0x0002, 0x0005}, + {0x00, 0x00, 0, 0x03, 0x0002, 0x0006}, + {0x00, 0x00, 0, 0x03, 0x0002, 0x0007}, + {0x00, 0x00, 0, 0x03, 0x0002, 0x0008}, + {0x00, 0x00, 0, 0x03, 0x0002, 0x0009}, + {0x00, 0x00, 0, 0x00, 0x0003, 0x0002}, + {0x00, 0x00, 0, 0x01, 0x0003, 0x0003}, + {0x00, 0x00, 0, 0x02, 0x0003, 0x0004}, + {0x00, 0x00, 0, 0x03, 0x0003, 0x0005}, + {0x00, 0x00, 0, 0x03, 0x0003, 0x0006}, + {0x00, 0x00, 0, 0x03, 0x0003, 0x0007}, + {0x00, 0x00, 0, 0x03, 0x0003, 0x0008}, + {0x00, 0x00, 0, 0x03, 0x0003, 0x0009}, + {0x00, 0x00, 0, 0x00, 0x0004, 0x0002}, + {0x00, 0x00, 0, 0x01, 0x0004, 0x0003}, + {0x00, 0x00, 0, 0x02, 0x0004, 0x0004}, + {0x00, 0x00, 0, 0x03, 0x0004, 0x0005}, + {0x00, 0x00, 0, 0x03, 0x0004, 0x0006}, + {0x00, 0x00, 0, 0x03, 0x0004, 0x0007}, + {0x00, 0x00, 0, 0x03, 0x0004, 0x0008}, + {0x00, 0x00, 0, 0x03, 0x0004, 0x0009}, + {0x00, 0x00, 0, 0x00, 0x0005, 0x0002}, + {0x00, 0x00, 0, 0x01, 0x0005, 0x0003}, + {0x00, 0x00, 0, 0x02, 0x0005, 0x0004}, + {0x00, 0x00, 0, 0x03, 0x0005, 0x0005}, + {0x00, 0x00, 0, 0x03, 0x0005, 0x0006}, + {0x00, 0x00, 0, 0x03, 0x0005, 0x0007}, + {0x00, 0x00, 0, 0x03, 0x0005, 0x0008}, + {0x00, 0x00, 0, 0x03, 0x0005, 0x0009}, + {0x01, 0x00, 0, 0x00, 0x0006, 0x0002}, + {0x01, 0x00, 0, 0x01, 0x0006, 0x0003}, + {0x01, 0x00, 0, 0x02, 0x0006, 0x0004}, + {0x01, 0x00, 0, 0x03, 0x0006, 0x0005}, + {0x01, 0x00, 0, 0x03, 0x0006, 0x0006}, + {0x01, 0x00, 0, 0x03, 0x0006, 0x0007}, + {0x01, 0x00, 0, 0x03, 0x0006, 0x0008}, + {0x01, 0x00, 0, 0x03, 0x0006, 0x0009}, + {0x01, 0x00, 0, 0x00, 0x0008, 0x0002}, + {0x01, 0x00, 0, 0x01, 0x0008, 0x0003}, + {0x01, 0x00, 0, 0x02, 0x0008, 0x0004}, + {0x01, 0x00, 0, 0x03, 0x0008, 0x0005}, + {0x01, 0x00, 0, 0x03, 0x0008, 0x0006}, + {0x01, 0x00, 0, 0x03, 0x0008, 0x0007}, + {0x01, 0x00, 0, 0x03, 0x0008, 0x0008}, + {0x01, 0x00, 0, 0x03, 0x0008, 0x0009}, + {0x00, 0x01, 0, 0x03, 0x0000, 0x000a}, + {0x00, 0x01, 0, 0x03, 0x0000, 0x000c}, + {0x00, 0x02, 0, 0x03, 0x0000, 0x000e}, + {0x00, 0x02, 0, 0x03, 0x0000, 0x0012}, + {0x00, 0x03, 0, 0x03, 0x0000, 0x0016}, + {0x00, 0x03, 0, 0x03, 0x0000, 0x001e}, + {0x00, 0x04, 0, 0x03, 0x0000, 0x0026}, + {0x00, 0x04, 0, 0x03, 0x0000, 0x0036}, + {0x00, 0x01, 0, 0x03, 0x0001, 0x000a}, + {0x00, 0x01, 0, 0x03, 0x0001, 0x000c}, + {0x00, 0x02, 0, 0x03, 0x0001, 0x000e}, + {0x00, 0x02, 0, 0x03, 0x0001, 0x0012}, + {0x00, 0x03, 0, 0x03, 0x0001, 0x0016}, + {0x00, 0x03, 0, 0x03, 0x0001, 0x001e}, + {0x00, 0x04, 0, 0x03, 0x0001, 0x0026}, + {0x00, 0x04, 0, 0x03, 0x0001, 0x0036}, + {0x00, 0x01, 0, 0x03, 0x0002, 0x000a}, + {0x00, 0x01, 0, 0x03, 0x0002, 0x000c}, + {0x00, 0x02, 0, 0x03, 0x0002, 0x000e}, + {0x00, 0x02, 0, 0x03, 0x0002, 0x0012}, + {0x00, 0x03, 0, 0x03, 0x0002, 0x0016}, + {0x00, 0x03, 0, 0x03, 0x0002, 0x001e}, + {0x00, 0x04, 0, 0x03, 0x0002, 0x0026}, + {0x00, 0x04, 0, 0x03, 0x0002, 0x0036}, + {0x00, 0x01, 0, 0x03, 0x0003, 0x000a}, + {0x00, 0x01, 0, 0x03, 0x0003, 0x000c}, + {0x00, 0x02, 0, 0x03, 0x0003, 0x000e}, + {0x00, 0x02, 0, 0x03, 0x0003, 0x0012}, + {0x00, 0x03, 0, 0x03, 0x0003, 0x0016}, + {0x00, 0x03, 0, 0x03, 0x0003, 0x001e}, + {0x00, 0x04, 0, 0x03, 0x0003, 0x0026}, + {0x00, 0x04, 0, 0x03, 0x0003, 0x0036}, + {0x00, 0x01, 0, 0x03, 0x0004, 0x000a}, + {0x00, 0x01, 0, 0x03, 0x0004, 0x000c}, + {0x00, 0x02, 0, 0x03, 0x0004, 0x000e}, + {0x00, 0x02, 0, 0x03, 0x0004, 0x0012}, + {0x00, 0x03, 0, 0x03, 0x0004, 0x0016}, + {0x00, 0x03, 0, 0x03, 0x0004, 0x001e}, + {0x00, 0x04, 0, 0x03, 0x0004, 0x0026}, + {0x00, 0x04, 0, 0x03, 0x0004, 0x0036}, + {0x00, 0x01, 0, 0x03, 0x0005, 0x000a}, + {0x00, 0x01, 0, 0x03, 0x0005, 0x000c}, + {0x00, 0x02, 0, 0x03, 0x0005, 0x000e}, + {0x00, 0x02, 0, 0x03, 0x0005, 0x0012}, + {0x00, 0x03, 0, 0x03, 0x0005, 0x0016}, + {0x00, 0x03, 0, 0x03, 0x0005, 0x001e}, + {0x00, 0x04, 0, 0x03, 0x0005, 0x0026}, + {0x00, 0x04, 0, 0x03, 0x0005, 0x0036}, + {0x01, 0x01, 0, 0x03, 0x0006, 0x000a}, + {0x01, 0x01, 0, 0x03, 0x0006, 0x000c}, + {0x01, 0x02, 0, 0x03, 0x0006, 0x000e}, + {0x01, 0x02, 0, 0x03, 0x0006, 0x0012}, + {0x01, 0x03, 0, 0x03, 0x0006, 0x0016}, + {0x01, 0x03, 0, 0x03, 0x0006, 0x001e}, + {0x01, 0x04, 0, 0x03, 0x0006, 0x0026}, + {0x01, 0x04, 0, 0x03, 0x0006, 0x0036}, + {0x01, 0x01, 0, 0x03, 0x0008, 0x000a}, + {0x01, 0x01, 0, 0x03, 0x0008, 0x000c}, + {0x01, 0x02, 0, 0x03, 0x0008, 0x000e}, + {0x01, 0x02, 0, 0x03, 0x0008, 0x0012}, + {0x01, 0x03, 0, 0x03, 0x0008, 0x0016}, + {0x01, 0x03, 0, 0x03, 0x0008, 0x001e}, + {0x01, 0x04, 0, 0x03, 0x0008, 0x0026}, + {0x01, 0x04, 0, 0x03, 0x0008, 0x0036}, + {0x00, 0x00, -1, 0x00, 0x0000, 0x0002}, + {0x00, 0x00, -1, 0x01, 0x0000, 0x0003}, + {0x00, 0x00, -1, 0x02, 0x0000, 0x0004}, + {0x00, 0x00, -1, 0x03, 0x0000, 0x0005}, + {0x00, 0x00, -1, 0x03, 0x0000, 0x0006}, + {0x00, 0x00, -1, 0x03, 0x0000, 0x0007}, + {0x00, 0x00, -1, 0x03, 0x0000, 0x0008}, + {0x00, 0x00, -1, 0x03, 0x0000, 0x0009}, + {0x00, 0x00, -1, 0x00, 0x0001, 0x0002}, + {0x00, 0x00, -1, 0x01, 0x0001, 0x0003}, + {0x00, 0x00, -1, 0x02, 0x0001, 0x0004}, + {0x00, 0x00, -1, 0x03, 0x0001, 0x0005}, + {0x00, 0x00, -1, 0x03, 0x0001, 0x0006}, + {0x00, 0x00, -1, 0x03, 0x0001, 0x0007}, + {0x00, 0x00, -1, 0x03, 0x0001, 0x0008}, + {0x00, 0x00, -1, 0x03, 0x0001, 0x0009}, + {0x00, 0x00, -1, 0x00, 0x0002, 0x0002}, + {0x00, 0x00, -1, 0x01, 0x0002, 0x0003}, + {0x00, 0x00, -1, 0x02, 0x0002, 0x0004}, + {0x00, 0x00, -1, 0x03, 0x0002, 0x0005}, + {0x00, 0x00, -1, 0x03, 0x0002, 0x0006}, + {0x00, 0x00, -1, 0x03, 0x0002, 0x0007}, + {0x00, 0x00, -1, 0x03, 0x0002, 0x0008}, + {0x00, 0x00, -1, 0x03, 0x0002, 0x0009}, + {0x00, 0x00, -1, 0x00, 0x0003, 0x0002}, + {0x00, 0x00, -1, 0x01, 0x0003, 0x0003}, + {0x00, 0x00, -1, 0x02, 0x0003, 0x0004}, + {0x00, 0x00, -1, 0x03, 0x0003, 0x0005}, + {0x00, 0x00, -1, 0x03, 0x0003, 0x0006}, + {0x00, 0x00, -1, 0x03, 0x0003, 0x0007}, + {0x00, 0x00, -1, 0x03, 0x0003, 0x0008}, + {0x00, 0x00, -1, 0x03, 0x0003, 0x0009}, + {0x00, 0x00, -1, 0x00, 0x0004, 0x0002}, + {0x00, 0x00, -1, 0x01, 0x0004, 0x0003}, + {0x00, 0x00, -1, 0x02, 0x0004, 0x0004}, + {0x00, 0x00, -1, 0x03, 0x0004, 0x0005}, + {0x00, 0x00, -1, 0x03, 0x0004, 0x0006}, + {0x00, 0x00, -1, 0x03, 0x0004, 0x0007}, + {0x00, 0x00, -1, 0x03, 0x0004, 0x0008}, + {0x00, 0x00, -1, 0x03, 0x0004, 0x0009}, + {0x00, 0x00, -1, 0x00, 0x0005, 0x0002}, + {0x00, 0x00, -1, 0x01, 0x0005, 0x0003}, + {0x00, 0x00, -1, 0x02, 0x0005, 0x0004}, + {0x00, 0x00, -1, 0x03, 0x0005, 0x0005}, + {0x00, 0x00, -1, 0x03, 0x0005, 0x0006}, + {0x00, 0x00, -1, 0x03, 0x0005, 0x0007}, + {0x00, 0x00, -1, 0x03, 0x0005, 0x0008}, + {0x00, 0x00, -1, 0x03, 0x0005, 0x0009}, + {0x01, 0x00, -1, 0x00, 0x0006, 0x0002}, + {0x01, 0x00, -1, 0x01, 0x0006, 0x0003}, + {0x01, 0x00, -1, 0x02, 0x0006, 0x0004}, + {0x01, 0x00, -1, 0x03, 0x0006, 0x0005}, + {0x01, 0x00, -1, 0x03, 0x0006, 0x0006}, + {0x01, 0x00, -1, 0x03, 0x0006, 0x0007}, + {0x01, 0x00, -1, 0x03, 0x0006, 0x0008}, + {0x01, 0x00, -1, 0x03, 0x0006, 0x0009}, + {0x01, 0x00, -1, 0x00, 0x0008, 0x0002}, + {0x01, 0x00, -1, 0x01, 0x0008, 0x0003}, + {0x01, 0x00, -1, 0x02, 0x0008, 0x0004}, + {0x01, 0x00, -1, 0x03, 0x0008, 0x0005}, + {0x01, 0x00, -1, 0x03, 0x0008, 0x0006}, + {0x01, 0x00, -1, 0x03, 0x0008, 0x0007}, + {0x01, 0x00, -1, 0x03, 0x0008, 0x0008}, + {0x01, 0x00, -1, 0x03, 0x0008, 0x0009}, + {0x00, 0x01, -1, 0x03, 0x0000, 0x000a}, + {0x00, 0x01, -1, 0x03, 0x0000, 0x000c}, + {0x00, 0x02, -1, 0x03, 0x0000, 0x000e}, + {0x00, 0x02, -1, 0x03, 0x0000, 0x0012}, + {0x00, 0x03, -1, 0x03, 0x0000, 0x0016}, + {0x00, 0x03, -1, 0x03, 0x0000, 0x001e}, + {0x00, 0x04, -1, 0x03, 0x0000, 0x0026}, + {0x00, 0x04, -1, 0x03, 0x0000, 0x0036}, + {0x00, 0x01, -1, 0x03, 0x0001, 0x000a}, + {0x00, 0x01, -1, 0x03, 0x0001, 0x000c}, + {0x00, 0x02, -1, 0x03, 0x0001, 0x000e}, + {0x00, 0x02, -1, 0x03, 0x0001, 0x0012}, + {0x00, 0x03, -1, 0x03, 0x0001, 0x0016}, + {0x00, 0x03, -1, 0x03, 0x0001, 0x001e}, + {0x00, 0x04, -1, 0x03, 0x0001, 0x0026}, + {0x00, 0x04, -1, 0x03, 0x0001, 0x0036}, + {0x00, 0x01, -1, 0x03, 0x0002, 0x000a}, + {0x00, 0x01, -1, 0x03, 0x0002, 0x000c}, + {0x00, 0x02, -1, 0x03, 0x0002, 0x000e}, + {0x00, 0x02, -1, 0x03, 0x0002, 0x0012}, + {0x00, 0x03, -1, 0x03, 0x0002, 0x0016}, + {0x00, 0x03, -1, 0x03, 0x0002, 0x001e}, + {0x00, 0x04, -1, 0x03, 0x0002, 0x0026}, + {0x00, 0x04, -1, 0x03, 0x0002, 0x0036}, + {0x00, 0x01, -1, 0x03, 0x0003, 0x000a}, + {0x00, 0x01, -1, 0x03, 0x0003, 0x000c}, + {0x00, 0x02, -1, 0x03, 0x0003, 0x000e}, + {0x00, 0x02, -1, 0x03, 0x0003, 0x0012}, + {0x00, 0x03, -1, 0x03, 0x0003, 0x0016}, + {0x00, 0x03, -1, 0x03, 0x0003, 0x001e}, + {0x00, 0x04, -1, 0x03, 0x0003, 0x0026}, + {0x00, 0x04, -1, 0x03, 0x0003, 0x0036}, + {0x00, 0x01, -1, 0x03, 0x0004, 0x000a}, + {0x00, 0x01, -1, 0x03, 0x0004, 0x000c}, + {0x00, 0x02, -1, 0x03, 0x0004, 0x000e}, + {0x00, 0x02, -1, 0x03, 0x0004, 0x0012}, + {0x00, 0x03, -1, 0x03, 0x0004, 0x0016}, + {0x00, 0x03, -1, 0x03, 0x0004, 0x001e}, + {0x00, 0x04, -1, 0x03, 0x0004, 0x0026}, + {0x00, 0x04, -1, 0x03, 0x0004, 0x0036}, + {0x00, 0x01, -1, 0x03, 0x0005, 0x000a}, + {0x00, 0x01, -1, 0x03, 0x0005, 0x000c}, + {0x00, 0x02, -1, 0x03, 0x0005, 0x000e}, + {0x00, 0x02, -1, 0x03, 0x0005, 0x0012}, + {0x00, 0x03, -1, 0x03, 0x0005, 0x0016}, + {0x00, 0x03, -1, 0x03, 0x0005, 0x001e}, + {0x00, 0x04, -1, 0x03, 0x0005, 0x0026}, + {0x00, 0x04, -1, 0x03, 0x0005, 0x0036}, + {0x01, 0x01, -1, 0x03, 0x0006, 0x000a}, + {0x01, 0x01, -1, 0x03, 0x0006, 0x000c}, + {0x01, 0x02, -1, 0x03, 0x0006, 0x000e}, + {0x01, 0x02, -1, 0x03, 0x0006, 0x0012}, + {0x01, 0x03, -1, 0x03, 0x0006, 0x0016}, + {0x01, 0x03, -1, 0x03, 0x0006, 0x001e}, + {0x01, 0x04, -1, 0x03, 0x0006, 0x0026}, + {0x01, 0x04, -1, 0x03, 0x0006, 0x0036}, + {0x01, 0x01, -1, 0x03, 0x0008, 0x000a}, + {0x01, 0x01, -1, 0x03, 0x0008, 0x000c}, + {0x01, 0x02, -1, 0x03, 0x0008, 0x000e}, + {0x01, 0x02, -1, 0x03, 0x0008, 0x0012}, + {0x01, 0x03, -1, 0x03, 0x0008, 0x0016}, + {0x01, 0x03, -1, 0x03, 0x0008, 0x001e}, + {0x01, 0x04, -1, 0x03, 0x0008, 0x0026}, + {0x01, 0x04, -1, 0x03, 0x0008, 0x0036}, + {0x02, 0x00, -1, 0x00, 0x000a, 0x0002}, + {0x02, 0x00, -1, 0x01, 0x000a, 0x0003}, + {0x02, 0x00, -1, 0x02, 0x000a, 0x0004}, + {0x02, 0x00, -1, 0x03, 0x000a, 0x0005}, + {0x02, 0x00, -1, 0x03, 0x000a, 0x0006}, + {0x02, 0x00, -1, 0x03, 0x000a, 0x0007}, + {0x02, 0x00, -1, 0x03, 0x000a, 0x0008}, + {0x02, 0x00, -1, 0x03, 0x000a, 0x0009}, + {0x02, 0x00, -1, 0x00, 0x000e, 0x0002}, + {0x02, 0x00, -1, 0x01, 0x000e, 0x0003}, + {0x02, 0x00, -1, 0x02, 0x000e, 0x0004}, + {0x02, 0x00, -1, 0x03, 0x000e, 0x0005}, + {0x02, 0x00, -1, 0x03, 0x000e, 0x0006}, + {0x02, 0x00, -1, 0x03, 0x000e, 0x0007}, + {0x02, 0x00, -1, 0x03, 0x000e, 0x0008}, + {0x02, 0x00, -1, 0x03, 0x000e, 0x0009}, + {0x03, 0x00, -1, 0x00, 0x0012, 0x0002}, + {0x03, 0x00, -1, 0x01, 0x0012, 0x0003}, + {0x03, 0x00, -1, 0x02, 0x0012, 0x0004}, + {0x03, 0x00, -1, 0x03, 0x0012, 0x0005}, + {0x03, 0x00, -1, 0x03, 0x0012, 0x0006}, + {0x03, 0x00, -1, 0x03, 0x0012, 0x0007}, + {0x03, 0x00, -1, 0x03, 0x0012, 0x0008}, + {0x03, 0x00, -1, 0x03, 0x0012, 0x0009}, + {0x03, 0x00, -1, 0x00, 0x001a, 0x0002}, + {0x03, 0x00, -1, 0x01, 0x001a, 0x0003}, + {0x03, 0x00, -1, 0x02, 0x001a, 0x0004}, + {0x03, 0x00, -1, 0x03, 0x001a, 0x0005}, + {0x03, 0x00, -1, 0x03, 0x001a, 0x0006}, + {0x03, 0x00, -1, 0x03, 0x001a, 0x0007}, + {0x03, 0x00, -1, 0x03, 0x001a, 0x0008}, + {0x03, 0x00, -1, 0x03, 0x001a, 0x0009}, + {0x04, 0x00, -1, 0x00, 0x0022, 0x0002}, + {0x04, 0x00, -1, 0x01, 0x0022, 0x0003}, + {0x04, 0x00, -1, 0x02, 0x0022, 0x0004}, + {0x04, 0x00, -1, 0x03, 0x0022, 0x0005}, + {0x04, 0x00, -1, 0x03, 0x0022, 0x0006}, + {0x04, 0x00, -1, 0x03, 0x0022, 0x0007}, + {0x04, 0x00, -1, 0x03, 0x0022, 0x0008}, + {0x04, 0x00, -1, 0x03, 0x0022, 0x0009}, + {0x04, 0x00, -1, 0x00, 0x0032, 0x0002}, + {0x04, 0x00, -1, 0x01, 0x0032, 0x0003}, + {0x04, 0x00, -1, 0x02, 0x0032, 0x0004}, + {0x04, 0x00, -1, 0x03, 0x0032, 0x0005}, + {0x04, 0x00, -1, 0x03, 0x0032, 0x0006}, + {0x04, 0x00, -1, 0x03, 0x0032, 0x0007}, + {0x04, 0x00, -1, 0x03, 0x0032, 0x0008}, + {0x04, 0x00, -1, 0x03, 0x0032, 0x0009}, + {0x05, 0x00, -1, 0x00, 0x0042, 0x0002}, + {0x05, 0x00, -1, 0x01, 0x0042, 0x0003}, + {0x05, 0x00, -1, 0x02, 0x0042, 0x0004}, + {0x05, 0x00, -1, 0x03, 0x0042, 0x0005}, + {0x05, 0x00, -1, 0x03, 0x0042, 0x0006}, + {0x05, 0x00, -1, 0x03, 0x0042, 0x0007}, + {0x05, 0x00, -1, 0x03, 0x0042, 0x0008}, + {0x05, 0x00, -1, 0x03, 0x0042, 0x0009}, + {0x05, 0x00, -1, 0x00, 0x0062, 0x0002}, + {0x05, 0x00, -1, 0x01, 0x0062, 0x0003}, + {0x05, 0x00, -1, 0x02, 0x0062, 0x0004}, + {0x05, 0x00, -1, 0x03, 0x0062, 0x0005}, + {0x05, 0x00, -1, 0x03, 0x0062, 0x0006}, + {0x05, 0x00, -1, 0x03, 0x0062, 0x0007}, + {0x05, 0x00, -1, 0x03, 0x0062, 0x0008}, + {0x05, 0x00, -1, 0x03, 0x0062, 0x0009}, + {0x02, 0x01, -1, 0x03, 0x000a, 0x000a}, + {0x02, 0x01, -1, 0x03, 0x000a, 0x000c}, + {0x02, 0x02, -1, 0x03, 0x000a, 0x000e}, + {0x02, 0x02, -1, 0x03, 0x000a, 0x0012}, + {0x02, 0x03, -1, 0x03, 0x000a, 0x0016}, + {0x02, 0x03, -1, 0x03, 0x000a, 0x001e}, + {0x02, 0x04, -1, 0x03, 0x000a, 0x0026}, + {0x02, 0x04, -1, 0x03, 0x000a, 0x0036}, + {0x02, 0x01, -1, 0x03, 0x000e, 0x000a}, + {0x02, 0x01, -1, 0x03, 0x000e, 0x000c}, + {0x02, 0x02, -1, 0x03, 0x000e, 0x000e}, + {0x02, 0x02, -1, 0x03, 0x000e, 0x0012}, + {0x02, 0x03, -1, 0x03, 0x000e, 0x0016}, + {0x02, 0x03, -1, 0x03, 0x000e, 0x001e}, + {0x02, 0x04, -1, 0x03, 0x000e, 0x0026}, + {0x02, 0x04, -1, 0x03, 0x000e, 0x0036}, + {0x03, 0x01, -1, 0x03, 0x0012, 0x000a}, + {0x03, 0x01, -1, 0x03, 0x0012, 0x000c}, + {0x03, 0x02, -1, 0x03, 0x0012, 0x000e}, + {0x03, 0x02, -1, 0x03, 0x0012, 0x0012}, + {0x03, 0x03, -1, 0x03, 0x0012, 0x0016}, + {0x03, 0x03, -1, 0x03, 0x0012, 0x001e}, + {0x03, 0x04, -1, 0x03, 0x0012, 0x0026}, + {0x03, 0x04, -1, 0x03, 0x0012, 0x0036}, + {0x03, 0x01, -1, 0x03, 0x001a, 0x000a}, + {0x03, 0x01, -1, 0x03, 0x001a, 0x000c}, + {0x03, 0x02, -1, 0x03, 0x001a, 0x000e}, + {0x03, 0x02, -1, 0x03, 0x001a, 0x0012}, + {0x03, 0x03, -1, 0x03, 0x001a, 0x0016}, + {0x03, 0x03, -1, 0x03, 0x001a, 0x001e}, + {0x03, 0x04, -1, 0x03, 0x001a, 0x0026}, + {0x03, 0x04, -1, 0x03, 0x001a, 0x0036}, + {0x04, 0x01, -1, 0x03, 0x0022, 0x000a}, + {0x04, 0x01, -1, 0x03, 0x0022, 0x000c}, + {0x04, 0x02, -1, 0x03, 0x0022, 0x000e}, + {0x04, 0x02, -1, 0x03, 0x0022, 0x0012}, + {0x04, 0x03, -1, 0x03, 0x0022, 0x0016}, + {0x04, 0x03, -1, 0x03, 0x0022, 0x001e}, + {0x04, 0x04, -1, 0x03, 0x0022, 0x0026}, + {0x04, 0x04, -1, 0x03, 0x0022, 0x0036}, + {0x04, 0x01, -1, 0x03, 0x0032, 0x000a}, + {0x04, 0x01, -1, 0x03, 0x0032, 0x000c}, + {0x04, 0x02, -1, 0x03, 0x0032, 0x000e}, + {0x04, 0x02, -1, 0x03, 0x0032, 0x0012}, + {0x04, 0x03, -1, 0x03, 0x0032, 0x0016}, + {0x04, 0x03, -1, 0x03, 0x0032, 0x001e}, + {0x04, 0x04, -1, 0x03, 0x0032, 0x0026}, + {0x04, 0x04, -1, 0x03, 0x0032, 0x0036}, + {0x05, 0x01, -1, 0x03, 0x0042, 0x000a}, + {0x05, 0x01, -1, 0x03, 0x0042, 0x000c}, + {0x05, 0x02, -1, 0x03, 0x0042, 0x000e}, + {0x05, 0x02, -1, 0x03, 0x0042, 0x0012}, + {0x05, 0x03, -1, 0x03, 0x0042, 0x0016}, + {0x05, 0x03, -1, 0x03, 0x0042, 0x001e}, + {0x05, 0x04, -1, 0x03, 0x0042, 0x0026}, + {0x05, 0x04, -1, 0x03, 0x0042, 0x0036}, + {0x05, 0x01, -1, 0x03, 0x0062, 0x000a}, + {0x05, 0x01, -1, 0x03, 0x0062, 0x000c}, + {0x05, 0x02, -1, 0x03, 0x0062, 0x000e}, + {0x05, 0x02, -1, 0x03, 0x0062, 0x0012}, + {0x05, 0x03, -1, 0x03, 0x0062, 0x0016}, + {0x05, 0x03, -1, 0x03, 0x0062, 0x001e}, + {0x05, 0x04, -1, 0x03, 0x0062, 0x0026}, + {0x05, 0x04, -1, 0x03, 0x0062, 0x0036}, + {0x00, 0x05, -1, 0x03, 0x0000, 0x0046}, + {0x00, 0x05, -1, 0x03, 0x0000, 0x0066}, + {0x00, 0x06, -1, 0x03, 0x0000, 0x0086}, + {0x00, 0x07, -1, 0x03, 0x0000, 0x00c6}, + {0x00, 0x08, -1, 0x03, 0x0000, 0x0146}, + {0x00, 0x09, -1, 0x03, 0x0000, 0x0246}, + {0x00, 0x0a, -1, 0x03, 0x0000, 0x0446}, + {0x00, 0x18, -1, 0x03, 0x0000, 0x0846}, + {0x00, 0x05, -1, 0x03, 0x0001, 0x0046}, + {0x00, 0x05, -1, 0x03, 0x0001, 0x0066}, + {0x00, 0x06, -1, 0x03, 0x0001, 0x0086}, + {0x00, 0x07, -1, 0x03, 0x0001, 0x00c6}, + {0x00, 0x08, -1, 0x03, 0x0001, 0x0146}, + {0x00, 0x09, -1, 0x03, 0x0001, 0x0246}, + {0x00, 0x0a, -1, 0x03, 0x0001, 0x0446}, + {0x00, 0x18, -1, 0x03, 0x0001, 0x0846}, + {0x00, 0x05, -1, 0x03, 0x0002, 0x0046}, + {0x00, 0x05, -1, 0x03, 0x0002, 0x0066}, + {0x00, 0x06, -1, 0x03, 0x0002, 0x0086}, + {0x00, 0x07, -1, 0x03, 0x0002, 0x00c6}, + {0x00, 0x08, -1, 0x03, 0x0002, 0x0146}, + {0x00, 0x09, -1, 0x03, 0x0002, 0x0246}, + {0x00, 0x0a, -1, 0x03, 0x0002, 0x0446}, + {0x00, 0x18, -1, 0x03, 0x0002, 0x0846}, + {0x00, 0x05, -1, 0x03, 0x0003, 0x0046}, + {0x00, 0x05, -1, 0x03, 0x0003, 0x0066}, + {0x00, 0x06, -1, 0x03, 0x0003, 0x0086}, + {0x00, 0x07, -1, 0x03, 0x0003, 0x00c6}, + {0x00, 0x08, -1, 0x03, 0x0003, 0x0146}, + {0x00, 0x09, -1, 0x03, 0x0003, 0x0246}, + {0x00, 0x0a, -1, 0x03, 0x0003, 0x0446}, + {0x00, 0x18, -1, 0x03, 0x0003, 0x0846}, + {0x00, 0x05, -1, 0x03, 0x0004, 0x0046}, + {0x00, 0x05, -1, 0x03, 0x0004, 0x0066}, + {0x00, 0x06, -1, 0x03, 0x0004, 0x0086}, + {0x00, 0x07, -1, 0x03, 0x0004, 0x00c6}, + {0x00, 0x08, -1, 0x03, 0x0004, 0x0146}, + {0x00, 0x09, -1, 0x03, 0x0004, 0x0246}, + {0x00, 0x0a, -1, 0x03, 0x0004, 0x0446}, + {0x00, 0x18, -1, 0x03, 0x0004, 0x0846}, + {0x00, 0x05, -1, 0x03, 0x0005, 0x0046}, + {0x00, 0x05, -1, 0x03, 0x0005, 0x0066}, + {0x00, 0x06, -1, 0x03, 0x0005, 0x0086}, + {0x00, 0x07, -1, 0x03, 0x0005, 0x00c6}, + {0x00, 0x08, -1, 0x03, 0x0005, 0x0146}, + {0x00, 0x09, -1, 0x03, 0x0005, 0x0246}, + {0x00, 0x0a, -1, 0x03, 0x0005, 0x0446}, + {0x00, 0x18, -1, 0x03, 0x0005, 0x0846}, + {0x01, 0x05, -1, 0x03, 0x0006, 0x0046}, + {0x01, 0x05, -1, 0x03, 0x0006, 0x0066}, + {0x01, 0x06, -1, 0x03, 0x0006, 0x0086}, + {0x01, 0x07, -1, 0x03, 0x0006, 0x00c6}, + {0x01, 0x08, -1, 0x03, 0x0006, 0x0146}, + {0x01, 0x09, -1, 0x03, 0x0006, 0x0246}, + {0x01, 0x0a, -1, 0x03, 0x0006, 0x0446}, + {0x01, 0x18, -1, 0x03, 0x0006, 0x0846}, + {0x01, 0x05, -1, 0x03, 0x0008, 0x0046}, + {0x01, 0x05, -1, 0x03, 0x0008, 0x0066}, + {0x01, 0x06, -1, 0x03, 0x0008, 0x0086}, + {0x01, 0x07, -1, 0x03, 0x0008, 0x00c6}, + {0x01, 0x08, -1, 0x03, 0x0008, 0x0146}, + {0x01, 0x09, -1, 0x03, 0x0008, 0x0246}, + {0x01, 0x0a, -1, 0x03, 0x0008, 0x0446}, + {0x01, 0x18, -1, 0x03, 0x0008, 0x0846}, + {0x06, 0x00, -1, 0x00, 0x0082, 0x0002}, + {0x06, 0x00, -1, 0x01, 0x0082, 0x0003}, + {0x06, 0x00, -1, 0x02, 0x0082, 0x0004}, + {0x06, 0x00, -1, 0x03, 0x0082, 0x0005}, + {0x06, 0x00, -1, 0x03, 0x0082, 0x0006}, + {0x06, 0x00, -1, 0x03, 0x0082, 0x0007}, + {0x06, 0x00, -1, 0x03, 0x0082, 0x0008}, + {0x06, 0x00, -1, 0x03, 0x0082, 0x0009}, + {0x07, 0x00, -1, 0x00, 0x00c2, 0x0002}, + {0x07, 0x00, -1, 0x01, 0x00c2, 0x0003}, + {0x07, 0x00, -1, 0x02, 0x00c2, 0x0004}, + {0x07, 0x00, -1, 0x03, 0x00c2, 0x0005}, + {0x07, 0x00, -1, 0x03, 0x00c2, 0x0006}, + {0x07, 0x00, -1, 0x03, 0x00c2, 0x0007}, + {0x07, 0x00, -1, 0x03, 0x00c2, 0x0008}, + {0x07, 0x00, -1, 0x03, 0x00c2, 0x0009}, + {0x08, 0x00, -1, 0x00, 0x0142, 0x0002}, + {0x08, 0x00, -1, 0x01, 0x0142, 0x0003}, + {0x08, 0x00, -1, 0x02, 0x0142, 0x0004}, + {0x08, 0x00, -1, 0x03, 0x0142, 0x0005}, + {0x08, 0x00, -1, 0x03, 0x0142, 0x0006}, + {0x08, 0x00, -1, 0x03, 0x0142, 0x0007}, + {0x08, 0x00, -1, 0x03, 0x0142, 0x0008}, + {0x08, 0x00, -1, 0x03, 0x0142, 0x0009}, + {0x09, 0x00, -1, 0x00, 0x0242, 0x0002}, + {0x09, 0x00, -1, 0x01, 0x0242, 0x0003}, + {0x09, 0x00, -1, 0x02, 0x0242, 0x0004}, + {0x09, 0x00, -1, 0x03, 0x0242, 0x0005}, + {0x09, 0x00, -1, 0x03, 0x0242, 0x0006}, + {0x09, 0x00, -1, 0x03, 0x0242, 0x0007}, + {0x09, 0x00, -1, 0x03, 0x0242, 0x0008}, + {0x09, 0x00, -1, 0x03, 0x0242, 0x0009}, + {0x0a, 0x00, -1, 0x00, 0x0442, 0x0002}, + {0x0a, 0x00, -1, 0x01, 0x0442, 0x0003}, + {0x0a, 0x00, -1, 0x02, 0x0442, 0x0004}, + {0x0a, 0x00, -1, 0x03, 0x0442, 0x0005}, + {0x0a, 0x00, -1, 0x03, 0x0442, 0x0006}, + {0x0a, 0x00, -1, 0x03, 0x0442, 0x0007}, + {0x0a, 0x00, -1, 0x03, 0x0442, 0x0008}, + {0x0a, 0x00, -1, 0x03, 0x0442, 0x0009}, + {0x0c, 0x00, -1, 0x00, 0x0842, 0x0002}, + {0x0c, 0x00, -1, 0x01, 0x0842, 0x0003}, + {0x0c, 0x00, -1, 0x02, 0x0842, 0x0004}, + {0x0c, 0x00, -1, 0x03, 0x0842, 0x0005}, + {0x0c, 0x00, -1, 0x03, 0x0842, 0x0006}, + {0x0c, 0x00, -1, 0x03, 0x0842, 0x0007}, + {0x0c, 0x00, -1, 0x03, 0x0842, 0x0008}, + {0x0c, 0x00, -1, 0x03, 0x0842, 0x0009}, + {0x0e, 0x00, -1, 0x00, 0x1842, 0x0002}, + {0x0e, 0x00, -1, 0x01, 0x1842, 0x0003}, + {0x0e, 0x00, -1, 0x02, 0x1842, 0x0004}, + {0x0e, 0x00, -1, 0x03, 0x1842, 0x0005}, + {0x0e, 0x00, -1, 0x03, 0x1842, 0x0006}, + {0x0e, 0x00, -1, 0x03, 0x1842, 0x0007}, + {0x0e, 0x00, -1, 0x03, 0x1842, 0x0008}, + {0x0e, 0x00, -1, 0x03, 0x1842, 0x0009}, + {0x18, 0x00, -1, 0x00, 0x5842, 0x0002}, + {0x18, 0x00, -1, 0x01, 0x5842, 0x0003}, + {0x18, 0x00, -1, 0x02, 0x5842, 0x0004}, + {0x18, 0x00, -1, 0x03, 0x5842, 0x0005}, + {0x18, 0x00, -1, 0x03, 0x5842, 0x0006}, + {0x18, 0x00, -1, 0x03, 0x5842, 0x0007}, + {0x18, 0x00, -1, 0x03, 0x5842, 0x0008}, + {0x18, 0x00, -1, 0x03, 0x5842, 0x0009}, + {0x02, 0x05, -1, 0x03, 0x000a, 0x0046}, + {0x02, 0x05, -1, 0x03, 0x000a, 0x0066}, + {0x02, 0x06, -1, 0x03, 0x000a, 0x0086}, + {0x02, 0x07, -1, 0x03, 0x000a, 0x00c6}, + {0x02, 0x08, -1, 0x03, 0x000a, 0x0146}, + {0x02, 0x09, -1, 0x03, 0x000a, 0x0246}, + {0x02, 0x0a, -1, 0x03, 0x000a, 0x0446}, + {0x02, 0x18, -1, 0x03, 0x000a, 0x0846}, + {0x02, 0x05, -1, 0x03, 0x000e, 0x0046}, + {0x02, 0x05, -1, 0x03, 0x000e, 0x0066}, + {0x02, 0x06, -1, 0x03, 0x000e, 0x0086}, + {0x02, 0x07, -1, 0x03, 0x000e, 0x00c6}, + {0x02, 0x08, -1, 0x03, 0x000e, 0x0146}, + {0x02, 0x09, -1, 0x03, 0x000e, 0x0246}, + {0x02, 0x0a, -1, 0x03, 0x000e, 0x0446}, + {0x02, 0x18, -1, 0x03, 0x000e, 0x0846}, + {0x03, 0x05, -1, 0x03, 0x0012, 0x0046}, + {0x03, 0x05, -1, 0x03, 0x0012, 0x0066}, + {0x03, 0x06, -1, 0x03, 0x0012, 0x0086}, + {0x03, 0x07, -1, 0x03, 0x0012, 0x00c6}, + {0x03, 0x08, -1, 0x03, 0x0012, 0x0146}, + {0x03, 0x09, -1, 0x03, 0x0012, 0x0246}, + {0x03, 0x0a, -1, 0x03, 0x0012, 0x0446}, + {0x03, 0x18, -1, 0x03, 0x0012, 0x0846}, + {0x03, 0x05, -1, 0x03, 0x001a, 0x0046}, + {0x03, 0x05, -1, 0x03, 0x001a, 0x0066}, + {0x03, 0x06, -1, 0x03, 0x001a, 0x0086}, + {0x03, 0x07, -1, 0x03, 0x001a, 0x00c6}, + {0x03, 0x08, -1, 0x03, 0x001a, 0x0146}, + {0x03, 0x09, -1, 0x03, 0x001a, 0x0246}, + {0x03, 0x0a, -1, 0x03, 0x001a, 0x0446}, + {0x03, 0x18, -1, 0x03, 0x001a, 0x0846}, + {0x04, 0x05, -1, 0x03, 0x0022, 0x0046}, + {0x04, 0x05, -1, 0x03, 0x0022, 0x0066}, + {0x04, 0x06, -1, 0x03, 0x0022, 0x0086}, + {0x04, 0x07, -1, 0x03, 0x0022, 0x00c6}, + {0x04, 0x08, -1, 0x03, 0x0022, 0x0146}, + {0x04, 0x09, -1, 0x03, 0x0022, 0x0246}, + {0x04, 0x0a, -1, 0x03, 0x0022, 0x0446}, + {0x04, 0x18, -1, 0x03, 0x0022, 0x0846}, + {0x04, 0x05, -1, 0x03, 0x0032, 0x0046}, + {0x04, 0x05, -1, 0x03, 0x0032, 0x0066}, + {0x04, 0x06, -1, 0x03, 0x0032, 0x0086}, + {0x04, 0x07, -1, 0x03, 0x0032, 0x00c6}, + {0x04, 0x08, -1, 0x03, 0x0032, 0x0146}, + {0x04, 0x09, -1, 0x03, 0x0032, 0x0246}, + {0x04, 0x0a, -1, 0x03, 0x0032, 0x0446}, + {0x04, 0x18, -1, 0x03, 0x0032, 0x0846}, + {0x05, 0x05, -1, 0x03, 0x0042, 0x0046}, + {0x05, 0x05, -1, 0x03, 0x0042, 0x0066}, + {0x05, 0x06, -1, 0x03, 0x0042, 0x0086}, + {0x05, 0x07, -1, 0x03, 0x0042, 0x00c6}, + {0x05, 0x08, -1, 0x03, 0x0042, 0x0146}, + {0x05, 0x09, -1, 0x03, 0x0042, 0x0246}, + {0x05, 0x0a, -1, 0x03, 0x0042, 0x0446}, + {0x05, 0x18, -1, 0x03, 0x0042, 0x0846}, + {0x05, 0x05, -1, 0x03, 0x0062, 0x0046}, + {0x05, 0x05, -1, 0x03, 0x0062, 0x0066}, + {0x05, 0x06, -1, 0x03, 0x0062, 0x0086}, + {0x05, 0x07, -1, 0x03, 0x0062, 0x00c6}, + {0x05, 0x08, -1, 0x03, 0x0062, 0x0146}, + {0x05, 0x09, -1, 0x03, 0x0062, 0x0246}, + {0x05, 0x0a, -1, 0x03, 0x0062, 0x0446}, + {0x05, 0x18, -1, 0x03, 0x0062, 0x0846}, + {0x06, 0x01, -1, 0x03, 0x0082, 0x000a}, + {0x06, 0x01, -1, 0x03, 0x0082, 0x000c}, + {0x06, 0x02, -1, 0x03, 0x0082, 0x000e}, + {0x06, 0x02, -1, 0x03, 0x0082, 0x0012}, + {0x06, 0x03, -1, 0x03, 0x0082, 0x0016}, + {0x06, 0x03, -1, 0x03, 0x0082, 0x001e}, + {0x06, 0x04, -1, 0x03, 0x0082, 0x0026}, + {0x06, 0x04, -1, 0x03, 0x0082, 0x0036}, + {0x07, 0x01, -1, 0x03, 0x00c2, 0x000a}, + {0x07, 0x01, -1, 0x03, 0x00c2, 0x000c}, + {0x07, 0x02, -1, 0x03, 0x00c2, 0x000e}, + {0x07, 0x02, -1, 0x03, 0x00c2, 0x0012}, + {0x07, 0x03, -1, 0x03, 0x00c2, 0x0016}, + {0x07, 0x03, -1, 0x03, 0x00c2, 0x001e}, + {0x07, 0x04, -1, 0x03, 0x00c2, 0x0026}, + {0x07, 0x04, -1, 0x03, 0x00c2, 0x0036}, + {0x08, 0x01, -1, 0x03, 0x0142, 0x000a}, + {0x08, 0x01, -1, 0x03, 0x0142, 0x000c}, + {0x08, 0x02, -1, 0x03, 0x0142, 0x000e}, + {0x08, 0x02, -1, 0x03, 0x0142, 0x0012}, + {0x08, 0x03, -1, 0x03, 0x0142, 0x0016}, + {0x08, 0x03, -1, 0x03, 0x0142, 0x001e}, + {0x08, 0x04, -1, 0x03, 0x0142, 0x0026}, + {0x08, 0x04, -1, 0x03, 0x0142, 0x0036}, + {0x09, 0x01, -1, 0x03, 0x0242, 0x000a}, + {0x09, 0x01, -1, 0x03, 0x0242, 0x000c}, + {0x09, 0x02, -1, 0x03, 0x0242, 0x000e}, + {0x09, 0x02, -1, 0x03, 0x0242, 0x0012}, + {0x09, 0x03, -1, 0x03, 0x0242, 0x0016}, + {0x09, 0x03, -1, 0x03, 0x0242, 0x001e}, + {0x09, 0x04, -1, 0x03, 0x0242, 0x0026}, + {0x09, 0x04, -1, 0x03, 0x0242, 0x0036}, + {0x0a, 0x01, -1, 0x03, 0x0442, 0x000a}, + {0x0a, 0x01, -1, 0x03, 0x0442, 0x000c}, + {0x0a, 0x02, -1, 0x03, 0x0442, 0x000e}, + {0x0a, 0x02, -1, 0x03, 0x0442, 0x0012}, + {0x0a, 0x03, -1, 0x03, 0x0442, 0x0016}, + {0x0a, 0x03, -1, 0x03, 0x0442, 0x001e}, + {0x0a, 0x04, -1, 0x03, 0x0442, 0x0026}, + {0x0a, 0x04, -1, 0x03, 0x0442, 0x0036}, + {0x0c, 0x01, -1, 0x03, 0x0842, 0x000a}, + {0x0c, 0x01, -1, 0x03, 0x0842, 0x000c}, + {0x0c, 0x02, -1, 0x03, 0x0842, 0x000e}, + {0x0c, 0x02, -1, 0x03, 0x0842, 0x0012}, + {0x0c, 0x03, -1, 0x03, 0x0842, 0x0016}, + {0x0c, 0x03, -1, 0x03, 0x0842, 0x001e}, + {0x0c, 0x04, -1, 0x03, 0x0842, 0x0026}, + {0x0c, 0x04, -1, 0x03, 0x0842, 0x0036}, + {0x0e, 0x01, -1, 0x03, 0x1842, 0x000a}, + {0x0e, 0x01, -1, 0x03, 0x1842, 0x000c}, + {0x0e, 0x02, -1, 0x03, 0x1842, 0x000e}, + {0x0e, 0x02, -1, 0x03, 0x1842, 0x0012}, + {0x0e, 0x03, -1, 0x03, 0x1842, 0x0016}, + {0x0e, 0x03, -1, 0x03, 0x1842, 0x001e}, + {0x0e, 0x04, -1, 0x03, 0x1842, 0x0026}, + {0x0e, 0x04, -1, 0x03, 0x1842, 0x0036}, + {0x18, 0x01, -1, 0x03, 0x5842, 0x000a}, + {0x18, 0x01, -1, 0x03, 0x5842, 0x000c}, + {0x18, 0x02, -1, 0x03, 0x5842, 0x000e}, + {0x18, 0x02, -1, 0x03, 0x5842, 0x0012}, + {0x18, 0x03, -1, 0x03, 0x5842, 0x0016}, + {0x18, 0x03, -1, 0x03, 0x5842, 0x001e}, + {0x18, 0x04, -1, 0x03, 0x5842, 0x0026}, + {0x18, 0x04, -1, 0x03, 0x5842, 0x0036}, + {0x06, 0x05, -1, 0x03, 0x0082, 0x0046}, + {0x06, 0x05, -1, 0x03, 0x0082, 0x0066}, + {0x06, 0x06, -1, 0x03, 0x0082, 0x0086}, + {0x06, 0x07, -1, 0x03, 0x0082, 0x00c6}, + {0x06, 0x08, -1, 0x03, 0x0082, 0x0146}, + {0x06, 0x09, -1, 0x03, 0x0082, 0x0246}, + {0x06, 0x0a, -1, 0x03, 0x0082, 0x0446}, + {0x06, 0x18, -1, 0x03, 0x0082, 0x0846}, + {0x07, 0x05, -1, 0x03, 0x00c2, 0x0046}, + {0x07, 0x05, -1, 0x03, 0x00c2, 0x0066}, + {0x07, 0x06, -1, 0x03, 0x00c2, 0x0086}, + {0x07, 0x07, -1, 0x03, 0x00c2, 0x00c6}, + {0x07, 0x08, -1, 0x03, 0x00c2, 0x0146}, + {0x07, 0x09, -1, 0x03, 0x00c2, 0x0246}, + {0x07, 0x0a, -1, 0x03, 0x00c2, 0x0446}, + {0x07, 0x18, -1, 0x03, 0x00c2, 0x0846}, + {0x08, 0x05, -1, 0x03, 0x0142, 0x0046}, + {0x08, 0x05, -1, 0x03, 0x0142, 0x0066}, + {0x08, 0x06, -1, 0x03, 0x0142, 0x0086}, + {0x08, 0x07, -1, 0x03, 0x0142, 0x00c6}, + {0x08, 0x08, -1, 0x03, 0x0142, 0x0146}, + {0x08, 0x09, -1, 0x03, 0x0142, 0x0246}, + {0x08, 0x0a, -1, 0x03, 0x0142, 0x0446}, + {0x08, 0x18, -1, 0x03, 0x0142, 0x0846}, + {0x09, 0x05, -1, 0x03, 0x0242, 0x0046}, + {0x09, 0x05, -1, 0x03, 0x0242, 0x0066}, + {0x09, 0x06, -1, 0x03, 0x0242, 0x0086}, + {0x09, 0x07, -1, 0x03, 0x0242, 0x00c6}, + {0x09, 0x08, -1, 0x03, 0x0242, 0x0146}, + {0x09, 0x09, -1, 0x03, 0x0242, 0x0246}, + {0x09, 0x0a, -1, 0x03, 0x0242, 0x0446}, + {0x09, 0x18, -1, 0x03, 0x0242, 0x0846}, + {0x0a, 0x05, -1, 0x03, 0x0442, 0x0046}, + {0x0a, 0x05, -1, 0x03, 0x0442, 0x0066}, + {0x0a, 0x06, -1, 0x03, 0x0442, 0x0086}, + {0x0a, 0x07, -1, 0x03, 0x0442, 0x00c6}, + {0x0a, 0x08, -1, 0x03, 0x0442, 0x0146}, + {0x0a, 0x09, -1, 0x03, 0x0442, 0x0246}, + {0x0a, 0x0a, -1, 0x03, 0x0442, 0x0446}, + {0x0a, 0x18, -1, 0x03, 0x0442, 0x0846}, + {0x0c, 0x05, -1, 0x03, 0x0842, 0x0046}, + {0x0c, 0x05, -1, 0x03, 0x0842, 0x0066}, + {0x0c, 0x06, -1, 0x03, 0x0842, 0x0086}, + {0x0c, 0x07, -1, 0x03, 0x0842, 0x00c6}, + {0x0c, 0x08, -1, 0x03, 0x0842, 0x0146}, + {0x0c, 0x09, -1, 0x03, 0x0842, 0x0246}, + {0x0c, 0x0a, -1, 0x03, 0x0842, 0x0446}, + {0x0c, 0x18, -1, 0x03, 0x0842, 0x0846}, + {0x0e, 0x05, -1, 0x03, 0x1842, 0x0046}, + {0x0e, 0x05, -1, 0x03, 0x1842, 0x0066}, + {0x0e, 0x06, -1, 0x03, 0x1842, 0x0086}, + {0x0e, 0x07, -1, 0x03, 0x1842, 0x00c6}, + {0x0e, 0x08, -1, 0x03, 0x1842, 0x0146}, + {0x0e, 0x09, -1, 0x03, 0x1842, 0x0246}, + {0x0e, 0x0a, -1, 0x03, 0x1842, 0x0446}, + {0x0e, 0x18, -1, 0x03, 0x1842, 0x0846}, + {0x18, 0x05, -1, 0x03, 0x5842, 0x0046}, + {0x18, 0x05, -1, 0x03, 0x5842, 0x0066}, + {0x18, 0x06, -1, 0x03, 0x5842, 0x0086}, + {0x18, 0x07, -1, 0x03, 0x5842, 0x00c6}, + {0x18, 0x08, -1, 0x03, 0x5842, 0x0146}, + {0x18, 0x09, -1, 0x03, 0x5842, 0x0246}, + {0x18, 0x0a, -1, 0x03, 0x5842, 0x0446}, + {0x18, 0x18, -1, 0x03, 0x5842, 0x0846}, +} + +// CmdLutElement maps a command symbol to its insert/copy length parameters +// and distance context. +type CmdLutElement struct { + InsertLenExtraBits uint8 + CopyLenExtraBits uint8 + DistanceCode int8 + Context uint8 + InsertLenOffset uint16 + CopyLenOffset uint16 +} diff --git a/src/vendor/github.com/molecule-man/go-brrr/internal/core/constants.go b/src/vendor/github.com/molecule-man/go-brrr/internal/core/constants.go new file mode 100644 index 00000000..1b53c09a --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/internal/core/constants.go @@ -0,0 +1,63 @@ +package core + +// Alphabet sizes from the brotli specification. +// https://datatracker.ietf.org/doc/html/rfc7932#section-3.3 +const ( + AlphabetSizeLiteral = 256 + AlphabetSizeInsertAndCopyLength = 704 + AlphabetSizeBlockCount = 26 + + // NumDistanceShortCodes is the number of distance short codes that reference + // the ring buffer of recent distances (RFC 7932 Section 4). + NumDistanceShortCodes = 16 + + // AlphabetSizeCodeLengths is the size of the code length alphabet + // (RFC 7932 Section 3.5): 18 = 16 literal lengths + repeat-previous (16) + // + repeat-zero (17). + AlphabetSizeCodeLengths = 18 + + // NumHistogramDistanceSymbols is the fixed histogram bin count used for + // distance histograms in the block splitter and histogram clustering. + // Matches BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS in the C reference. + NumHistogramDistanceSymbols = 544 + + // MaxDistanceBits is the maximum number of extra bits in a distance code + // (RFC 7932 Section 4). The distance alphabet size formula uses this as + // the MAXNBITS parameter. + MaxDistanceBits = 24 + + // WindowGap is the safety margin between the window size and the maximum + // backward distance. Reserves space for ring-buffer read-ahead in the + // streaming encoder. + WindowGap = 16 + + // RepeatPreviousCodeLength and InitialRepeatedCodeLength are entropy + // coding constants from RFC 7932 Section 3.5. + // https://datatracker.ietf.org/doc/html/rfc7932#section-3.5 + RepeatPreviousCodeLength = 16 // used for repeating previous non-zero code length + InitialRepeatedCodeLength = 8 // "code length of 8 is repeated" +) + +// CodeLengthCodeOrder is the order in which code length codes are transmitted +// (RFC 7932 section 3.5). +var CodeLengthCodeOrder = [...]byte{ + 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, +} + +// BlockLengthOffset and BlockLengthNBits are block length prefix code ranges +// (RFC 7932 Section 6). Each entry is {offset, nbits}; the block length for +// code c is: +// +// offset[c] + ReadBits(nbits[c]) +var BlockLengthOffset = [AlphabetSizeBlockCount]uint32{ + 1, 5, 9, 13, 17, 25, 33, 41, 49, 65, 81, 97, + 113, 145, 177, 209, 241, 305, 369, 497, 753, 1265, 2289, 4337, + 8433, 16625, +} + +// BlockLengthNBits is the extra-bit count for each block-length prefix code. +var BlockLengthNBits = [AlphabetSizeBlockCount]uint32{ + 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 24, +} diff --git a/src/vendor/github.com/molecule-man/go-brrr/internal/core/context.go b/src/vendor/github.com/molecule-man/go-brrr/internal/core/context.go new file mode 100644 index 00000000..b61753ac --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/internal/core/context.go @@ -0,0 +1,202 @@ +// Context modeling lookup tables for literal encoding (quality >= 5). +// +// Brotli uses four context modes to predict the next literal byte based on +// the two preceding bytes (p1, p2). The context ID feeds into the context +// map, which selects a Huffman tree for coding the next byte. +// +// The four modes are: +// +// - contextLSB6: context is the low 6 bits of p1 (p2 ignored). +// - contextMSB6: context is the high 6 bits of p1 (p2 ignored). +// - contextUTF8: second-order model tuned for UTF-8 text. For ASCII +// bytes the context encodes character class of p1 (16 classes) and +// broad class of p2 (4 classes), giving 64 contexts. For multi-byte +// sequences it distinguishes continuation vs. lead bytes. +// - contextSigned: second-order model tuned for signed integer data. +// Similar to MSB6 but with 8 buckets for p1 and 8 for p2. +// +// The context is computed as: +// +// context = contextLookupTable[mode<<9 + p1] | contextLookupTable[mode<<9 + 256 + p2] +// +// Each mode occupies 512 bytes in the table: 256 for the p1 contribution +// and 256 for the p2 contribution. The result is a 6-bit context ID (0..63). +// +// RFC 7932 Section 7.1. + +package core + +// Context mode constants. Each selects a 512-byte region of the lookup table. +const ( + ContextLSB6 = 0 + ContextMSB6 = 1 + ContextUTF8 = 2 + ContextSigned = 3 +) + +// Context bit widths for the two symbol categories that use context modeling. +const ( + LiteralContextBits = 6 // 64 literal contexts per block type + DistanceContextBits = 2 // 4 distance contexts per block type +) + +// ContextLookupTable maps (mode, p1, p2) triples to 6-bit context IDs. +// Layout: 4 modes x 512 bytes (256 for p1, 256 for p2). +var ContextLookupTable = [2048]byte{ + // contextLSB6, p1: identity mapping of low 6 bits. + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + + // contextLSB6, p2: all zeros (p2 doesn't contribute). + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + // contextMSB6, p1: high 6 bits (value >> 2). + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, + 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, + 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, + 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, + 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, + 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, + 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, + 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, + 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, + 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, + 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, + 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, + 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, + 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, + + // contextMSB6, p2: all zeros (p2 doesn't contribute). + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + // contextUTF8, p1. + // ASCII range: 16 character classes mapped to context * 4. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12, + 12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, + 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12, + 12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56, + 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0, + // Continuation byte range (128-191): alternating 0,1. + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + // Lead byte range (192-255): alternating 2,3. + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + + // contextUTF8, p2. + // ASCII range: 4 broad classes (control/space=0, punct=1, upper/digit=2, lower=3). + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0, + // Continuation byte range (128-191): all zeros. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // Lead byte range (192-255): 0 for 192-207, 2 for 208-255. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + + // contextSigned, p1: signed magnitude buckets (8 ranges * 8). + 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56, + + // contextSigned, p2: signed magnitude buckets (8 ranges). + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, +} + +// ContextLookup computes a 6-bit context ID from the two preceding bytes +// p1 (last) and p2 (second-to-last) for the given context mode. +func ContextLookup(mode uint, p1, p2 byte) byte { + lut := ContextLookupTable[mode<<9:] + return lut[p1] | lut[256+int(p2)] +} diff --git a/src/vendor/github.com/molecule-man/go-brrr/internal/core/dictionary.bin b/src/vendor/github.com/molecule-man/go-brrr/internal/core/dictionary.bin new file mode 100644 index 00000000..a585c0e2 --- /dev/null +++ b/src/vendor/github.com/molecule-man/go-brrr/internal/core/dictionary.bin @@ -0,0 +1,432 @@ +timedownlifeleftbackcodedatashowonlysitecityopenjustlikefreeworktextyearoverbodyloveformbookplaylivelinehelphomesidemorewordlongthemviewfindpagedaysfullheadtermeachareafromtruemarkableuponhighdatelandnewsevennextcasebothpostusedmadehandherewhatnameLinkblogsizebaseheldmakemainuser') +holdendswithNewsreadweresigntakehavegameseencallpathwellplusmenufilmpartjointhislistgoodneedwayswestjobsmindalsologorichuseslastteamarmyfoodkingwilleastwardbestfirePageknowaway.pngmovethanloadgiveselfnotemuchfeedmanyrockicononcelookhidediedHomerulehostajaxinfoclublawslesshalfsomesuchzone100%onescareTimeracebluefourweekfacehopegavehardlostwhenparkkeptpassshiproomHTMLplanTypedonesavekeepflaglinksoldfivetookratetownjumpthusdarkcardfilefearstaykillthatfallautoever.comtalkshopvotedeepmoderestturnbornbandfellroseurl(skinrolecomeactsagesmeetgold.jpgitemvaryfeltthensenddropViewcopy1.0"stopelseliestourpack.gifpastcss?graymean>rideshotlatesaidroadvar feeljohnrickportfast'UA-deadpoorbilltypeU.S.woodmust2px;Inforankwidewantwalllead[0];paulwavesure$('#waitmassarmsgoesgainlangpaid!-- lockunitrootwalkfirmwifexml"songtest20pxkindrowstoolfontmailsafestarmapscorerainflowbabyspansays4px;6px;artsfootrealwikiheatsteptriporg/lakeweaktoldFormcastfansbankveryrunsjulytask1px;goalgrewslowedgeid="sets5px;.js?40pxif (soonseatnonetubezerosentreedfactintogiftharm18pxcamehillboldzoomvoideasyringfillpeakinitcost3px;jacktagsbitsrolleditknewnearironfreddiskwentsoilputs/js/holyT22:ISBNT20:adamsees

json', 'contT21: RSSloopasiamoon

soulLINEfortcartT14:

80px!--<9px;T04:mike:46ZniceinchYorkricezh:'));puremageparatonebond:37Z_of_']);000,zh:tankyardbowlbush:56ZJava30px +|} +%C3%:34ZjeffEXPIcashvisagolfsnowzh:quer.csssickmeatmin.binddellhirepicsrent:36ZHTTP-201fotowolfEND xbox:54ZBODYdick; +} +exit:35Zvarsbeat'});diet999;anne}}sonyguysfuckpipe|- +!002)ndow[1];[]; +Log salt + bangtrimbath){ +00px +});ko:feesad> s:// [];tollplug(){ +{ + .js'200pdualboat.JPG); +}quot); + +'); + +} 201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037201320122011201020092008200720062005200420032002200120001999199819971996199519941993199219911990198919881987198619851984198319821981198019791978197719761975197419731972197119701969196819671966196519641963196219611960195919581957195619551954195319521951195010001024139400009999comomásesteestaperotodohacecadaañobiendíaasívidacasootroforosolootracualdijosidograntipotemadebealgoquéestonadatrespococasabajotodasinoaguapuesunosantediceluisellamayozonaamorpisoobraclicellodioshoracasiзанаомрарутанепоотизнодотожеонихНаеебымыВысовывоНообПолиниРФНеМытыОнимдаЗаДаНуОбтеИзейнуммТыужفيأنمامعكلأورديافىهولملكاولهبسالإنهيأيقدهلثمبهلوليبلايبكشيامأمنتبيلنحبهممشوشfirstvideolightworldmediawhitecloseblackrightsmallbooksplacemusicfieldorderpointvalueleveltableboardhousegroupworksyearsstatetodaywaterstartstyledeathpowerphonenighterrorinputabouttermstitletoolseventlocaltimeslargewordsgamesshortspacefocusclearmodelblockguideradiosharewomenagainmoneyimagenamesyounglineslatercolorgreenfront&watchforcepricerulesbeginaftervisitissueareasbelowindextotalhourslabelprintpressbuiltlinksspeedstudytradefoundsenseundershownformsrangeaddedstillmovedtakenaboveflashfixedoftenotherviewschecklegalriveritemsquickshapehumanexistgoingmoviethirdbasicpeacestagewidthloginideaswrotepagesusersdrivestorebreaksouthvoicesitesmonthwherebuildwhichearthforumthreesportpartyClicklowerlivesclasslayerentrystoryusagesoundcourtyour birthpopuptypesapplyImagebeinguppernoteseveryshowsmeansextramatchtrackknownearlybegansuperpapernorthlearngivennamedendedTermspartsGroupbrandusingwomanfalsereadyaudiotakeswhile.com/livedcasesdailychildgreatjudgethoseunitsneverbroadcoastcoverapplefilescyclesceneplansclickwritequeenpieceemailframeolderphotolimitcachecivilscaleenterthemetheretouchboundroyalaskedwholesincestock namefaithheartemptyofferscopeownedmightalbumthinkbloodarraymajortrustcanonunioncountvalidstoneStyleLoginhappyoccurleft:freshquitefilmsgradeneedsurbanfightbasishoverauto;route.htmlmixedfinalYour slidetopicbrownalonedrawnsplitreachRightdatesmarchquotegoodsLinksdoubtasyncthumballowchiefyouthnovel10px;serveuntilhandsCheckSpacequeryjamesequaltwice0,000Startpanelsongsroundeightshiftworthpostsleadsweeksavoidthesemilesplanesmartalphaplantmarksratesplaysclaimsalestextsstarswrong

thing.org/multiheardPowerstandtokensolid(thisbringshipsstafftriedcallsfullyfactsagentThis //-->adminegyptEvent15px;Emailtrue"crossspentblogsbox">notedleavechinasizesguestrobotheavytrue,sevengrandcrimesignsawaredancephase> + + +name=diegopage swiss--> + +#fff;">Log.com"treatsheet) && 14px;sleepntentfiledja:id="cName"worseshots-box-delta +<bears:48Z spendbakershops= "";php">ction13px;brianhellosize=o=%2F joinmaybe, fjsimg" ")[0]MTopBType"newlyDanskczechtrailknowsfaq">zh-cn10); +-1");type=bluestrulydavis.js';> + +form jesus100% menu. + +walesrisksumentddingb-likteachgif" vegasdanskeestishqipsuomisobredesdeentretodospuedeañosestátienehastaotrospartedondenuevohacerformamismomejormundoaquídíassóloayudafechatodastantomenosdatosotrassitiomuchoahoralugarmayorestoshorastenerantesfotosestaspaísnuevasaludforosmedioquienmesespoderchileserávecesdecirjoséestarventagrupohechoellostengoamigocosasnivelgentemismaairesjuliotemashaciafavorjuniolibrepuntobuenoautorabrilbuenatextomarzosaberlistaluegocómoenerojuegoperúhaberestoynuncamujervalorfueralibrogustaigualvotoscasosguíapuedosomosavisousteddebennochebuscafaltaeurosseriedichocursoclavecasasleónplazolargoobrasvistaapoyojuntotratavistocrearcampohemoscincocargopisosordenhacenáreadiscopedrocercapuedapapelmenorútilclarojorgecalleponertardenadiemarcasigueellassiglocochemotosmadreclaserestoniñoquedapasarbancohijosviajepabloéstevienereinodejarfondocanalnorteletracausatomarmanoslunesautosvillavendopesartipostengamarcollevapadreunidovamoszonasambosbandamariaabusomuchasubirriojavivirgradochicaallíjovendichaestantalessalirsuelopesosfinesllamabuscoéstalleganegroplazahumorpagarjuntadobleislasbolsabañohablaluchaÁreadicenjugarnotasvalleallácargadolorabajoestégustomentemariofirmacostofichaplatahogarartesleyesaquelmuseobasespocosmitadcielochicomiedoganarsantoetapadebesplayaredessietecortecoreadudasdeseoviejodeseaaguas"domaincommonstatuseventsmastersystemactionbannerremovescrollupdateglobalmediumfilternumberchangeresultpublicscreenchoosenormaltravelissuessourcetargetspringmodulemobileswitchphotosborderregionitselfsocialactivecolumnrecordfollowtitle>eitherlengthfamilyfriendlayoutauthorcreatereviewsummerserverplayedplayerexpandpolicyformatdoublepointsseriespersonlivingdesignmonthsforcesuniqueweightpeopleenergynaturesearchfigurehavingcustomoffsetletterwindowsubmitrendergroupsuploadhealthmethodvideosschoolfutureshadowdebatevaluesObjectothersrightsleaguechromesimplenoticesharedendingseasonreportonlinesquarebuttonimagesenablemovinglatestwinterFranceperiodstrongrepeatLondondetailformeddemandsecurepassedtoggleplacesdevicestaticcitiesstreamyellowattackstreetflighthiddeninfo">openedusefulvalleycausesleadersecretseconddamagesportsexceptratingsignedthingseffectfieldsstatesofficevisualeditorvolumeReportmuseummoviesparentaccessmostlymother" id="marketgroundchancesurveybeforesymbolmomentspeechmotioninsidematterCenterobjectexistsmiddleEuropegrowthlegacymannerenoughcareeransweroriginportalclientselectrandomclosedtopicscomingfatheroptionsimplyraisedescapechosenchurchdefinereasoncorneroutputmemoryiframepolicemodelsNumberduringoffersstyleskilledlistedcalledsilvermargindeletebetterbrowselimitsGlobalsinglewidgetcenterbudgetnowrapcreditclaimsenginesafetychoicespirit-stylespreadmakingneededrussiapleaseextentScriptbrokenallowschargedividefactormember-basedtheoryconfigaroundworkedhelpedChurchimpactshouldalwayslogo" bottomlist">){var prefixorangeHeader.push(couplegardenbridgelaunchReviewtakingvisionlittledatingButtonbeautythemesforgotSearchanchoralmostloadedChangereturnstringreloadMobileincomesupplySourceordersviewed courseAbout islandPhilipawardshandleimportOfficeregardskillsnationSportsdegreeweekly (e.g.behinddoctorloggedunitedbeyond-scaleacceptservedmarineFootercamera +_form"leavesstress" /> +.gif" onloadloaderOxfordsistersurvivlistenfemaleDesignsize="appealtext">levelsthankshigherforcedanimalanyoneAfricaagreedrecentPeople
wonderpricesturned|| {};main">inlinesundaywrap">failedcensusminutebeaconquotes150px|estateremoteemail"linkedright;signalformal1.htmlsignupprincefloat:.png" forum.AccesspaperssoundsextendHeightsliderUTF-8"& Before. WithstudioownersmanageprofitjQueryannualparamsboughtfamousgooglelongeri++) {israelsayingdecidehome">headerensurebranchpiecesblock;statedtop">boston.test(avatartested_countforumsschemaindex,filledsharesreaderalert(appearSubmitline">body"> +* TheThoughseeingjerseyNews +System DavidcancertablesprovedApril reallydriveritem">more">boardscolorscampusfirst || [];media.guitarfinishwidth:showedOther .php" assumelayerswilsonstoresreliefswedenCustomeasily your String + +Whiltaylorclear:resortfrenchthough") + "buyingbrandsMembername">oppingsector5px;">vspacepostermajor coffeemartinmaturehappenkansaslink">Images=falsewhile hspace0& + +In powerPolski-colorjordanBottomStart -count2.htmlnews">01.jpgOnline-rightmillerseniorISBN 00,000 guidesvalue)ectionrepair.xml" rights.html-blockregExp:hoverwithinvirginphones using + var >'); + + +bahasabrasilgalegomagyarpolskisrpskiردو中文简体繁體信息中国我们一个公司管理论坛可以服务时间个人产品自己企业查看工作联系没有网站所有评论中心文章用户首页作者技术问题相关下载搜索使用软件在线主题资料视频回复注册网络收藏内容推荐市场消息空间发布什么好友生活图片发展如果手机新闻最新方式北京提供关于更多这个系统知道游戏广告其他发表安全第一会员进行点击版权电子世界设计免费教育加入活动他们商品博客现在上海如何已经留言详细社区登录本站需要价格支持国际链接国家建设朋友阅读法律位置经济选择这样当前分类排行因为交易最后音乐不能通过行业科技可能设备合作大家社会研究专业全部项目这里还是开始情况电脑文件品牌帮助文化资源大学学习地址浏览投资工程要求怎么时候功能主要目前资讯城市方法电影招聘声明任何健康数据美国汽车介绍但是交流生产所以电话显示一些单位人员分析地图旅游工具学生系列网友帖子密码频道控制地区基本全国网上重要第二喜欢进入友情这些考试发现培训以上政府成为环境香港同时娱乐发送一定开发作品标准欢迎解决地方一下以及责任或者客户代表积分女人数码销售出现离线应用列表不同编辑统计查询不要有关机构很多播放组织政策直接能力来源時間看到热门关键专区非常英语百度希望美女比较知识规定建议部门意见精彩日本提高发言方面基金处理权限影片银行还有分享物品经营添加专家这种话题起来业务公告记录简介质量男人影响引用报告部分快速咨询时尚注意申请学校应该历史只是返回购买名称为了成功说明供应孩子专题程序一般會員只有其它保护而且今天窗口动态状态特别认为必须更新小说我們作为媒体包括那么一样国内是否根据电视学院具有过程由于人才出来不过正在明星故事关系标题商务输入一直基础教学了解建筑结果全球通知计划对于艺术相册发生真的建立等级类型经验实现制作来自标签以下原创无法其中個人一切指南关闭集团第三关注因此照片深圳商业广州日期高级最近综合表示专辑行为交通评价觉得精华家庭完成感觉安装得到邮件制度食品虽然转载报价记者方案行政人民用品东西提出酒店然后付款热点以前完全发帖设置领导工业医院看看经典原因平台各种增加材料新增之后职业效果今年论文我国告诉版主修改参与打印快乐机械观点存在精神获得利用继续你们这么模式语言能够雅虎操作风格一起科学体育短信条件治疗运动产业会议导航先生联盟可是問題结构作用调查資料自动负责农业访问实施接受讨论那个反馈加强女性范围服務休闲今日客服觀看参加的话一点保证图书有效测试移动才能决定股票不断需求不得办法之间采用营销投诉目标爱情摄影有些複製文学机会数字装修购物农村全面精品其实事情水平提示上市谢谢普通教师上传类别歌曲拥有创新配件只要时代資訊达到人生订阅老师展示心理贴子網站主題自然级别简单改革那些来说打开代码删除证券节目重点次數多少规划资金找到以后大全主页最佳回答天下保障现代检查投票小时沒有正常甚至代理目录公开复制金融幸福版本形成准备行情回到思想怎样协议认证最好产生按照服装广东动漫采购新手组图面板参考政治容易天地努力人们升级速度人物调整流行造成文字韩国贸易开展相關表现影视如此美容大小报道条款心情许多法规家居书店连接立即举报技巧奥运登入以来理论事件自由中华办公妈妈真正不错全文合同价值别人监督具体世纪团队创业承担增长有人保持商家维修台湾左右股份答案实际电信经理生命宣传任务正式特色下来协会只能当然重新內容指导运行日志賣家超过土地浙江支付推出站长杭州执行制造之一推广现场描述变化传统歌手保险课程医疗经过过去之前收入年度杂志美丽最高登陆未来加工免责教程版块身体重庆出售成本形式土豆出價东方邮箱南京求职取得职位相信页面分钟网页确定图例网址积极错误目的宝贝机关风险授权病毒宠物除了評論疾病及时求购站点儿童每天中央认识每个天津字体台灣维护本页个性官方常见相机战略应当律师方便校园股市房屋栏目员工导致突然道具本网结合档案劳动另外美元引起改变第四会计說明隐私宝宝规范消费共同忘记体系带来名字發表开放加盟受到二手大量成人数量共享区域女孩原则所在结束通信超级配置当时优秀性感房产遊戲出口提交就业保健程度参数事业整个山东情感特殊分類搜尋属于门户财务声音及其财经坚持干部成立利益考虑成都包装用戶比赛文明招商完整真是眼睛伙伴威望领域卫生优惠論壇公共良好充分符合附件特点不可英文资产根本明显密碼公众民族更加享受同学启动适合原来问答本文美食绿色稳定终于生物供求搜狐力量严重永远写真有限竞争对象费用不好绝对十分促进点评影音优势不少欣赏并且有点方向全新信用设施形象资格突破随着重大于是毕业智能化工完美商城统一出版打造產品概况用于保留因素中國存储贴图最愛长期口价理财基地安排武汉里面创建天空首先完善驱动下面不再诚信意义阳光英国漂亮军事玩家群众农民即可名稱家具动画想到注明小学性能考研硬件观看清楚搞笑首頁黄金适用江苏真实主管阶段註冊翻译权利做好似乎通讯施工狀態也许环保培养概念大型机票理解匿名cuandoenviarmadridbuscariniciotiempoporquecuentaestadopuedenjuegoscontraestánnombretienenperfilmaneraamigosciudadcentroaunquepuedesdentroprimerpreciosegúnbuenosvolverpuntossemanahabíaagostonuevosunidoscarlosequiponiñosmuchosalgunacorreoimagenpartirarribamaríahombreempleoverdadcambiomuchasfueronpasadolíneaparecenuevascursosestabaquierolibroscuantoaccesomiguelvarioscuatrotienesgruposseráneuropamediosfrenteacercademásofertacochesmodeloitalialetrasalgúncompracualesexistecuerposiendoprensallegarviajesdineromurciapodrápuestodiariopuebloquieremanuelpropiocrisisciertoseguromuertefuentecerrargrandeefectopartesmedidapropiaofrecetierrae-mailvariasformasfuturoobjetoseguirriesgonormasmismosúnicocaminositiosrazóndebidopruebatoledoteníajesúsesperococinaorigentiendacientocádizhablarseríalatinafuerzaestiloguerraentraréxitolópezagendavídeoevitarpaginametrosjavierpadresfácilcabezaáreassalidaenvíojapónabusosbienestextosllevarpuedanfuertecomúnclaseshumanotenidobilbaounidadestáseditarcreadoдлячтокакилиэтовсеегопритакещеужеКакбезбылониВсеподЭтотомчемнетлетразонагдемнеДляПринаснихтемктогодвоттамСШАмаяЧтовасвамемуТакдванамэтиэтуВамтехпротутнаддняВоттринейВаснимсамтотрубОнимирнееОООлицэтаОнанемдоммойдвеоносудकेहैकीसेकाकोऔरपरनेएककिभीइसकरतोहोआपहीयहयातकथाjagranआजजोअबदोगईजागएहमइनवहयेथेथीघरजबदीकईजीवेनईनएहरउसमेकमवोलेसबमईदेओरआमबसभरबनचलमनआगसीलीعلىإلىهذاآخرعددالىهذهصورغيركانولابينعرضذلكهنايومقالعليانالكنحتىقبلوحةاخرفقطعبدركنإذاكمااحدإلافيهبعضكيفبحثومنوهوأناجدالهاسلمعندليسعبرصلىمنذبهاأنهمثلكنتالاحيثمصرشرححولوفياذالكلمرةانتالفأبوخاصأنتانهاليعضووقدابنخيربنتلكمشاءوهيابوقصصومارقمأحدنحنعدمرأياحةكتبدونيجبمنهتحتجهةسنةيتمكرةغزةنفسبيتللهلناتلكقلبلماعنهأولشيءنورأمافيكبكلذاترتببأنهمسانكبيعفقدحسنلهمشعرأهلشهرقطرطلبprofileservicedefaulthimselfdetailscontentsupportstartedmessagesuccessfashioncountryaccountcreatedstoriesresultsrunningprocesswritingobjectsvisiblewelcomearticleunknownnetworkcompanydynamicbrowserprivacyproblemServicerespectdisplayrequestreservewebsitehistoryfriendsoptionsworkingversionmillionchannelwindow.addressvisitedweathercorrectproductedirectforwardyou canremovedsubjectcontrolarchivecurrentreadinglibrarylimitedmanagerfurthersummarymachineminutesprivatecontextprogramsocietynumberswrittenenabledtriggersourcesloadingelementpartnerfinallyperfectmeaningsystemskeepingculture",journalprojectsurfaces"expiresreviewsbalanceEnglishContentthroughPlease opinioncontactaverageprimaryvillageSpanishgallerydeclinemeetingmissionpopularqualitymeasuregeneralspeciessessionsectionwriterscounterinitialreportsfiguresmembersholdingdisputeearlierexpressdigitalpictureAnothermarriedtrafficleadingchangedcentralvictoryimages/reasonsstudiesfeaturelistingmust beschoolsVersionusuallyepisodeplayinggrowingobviousoverlaypresentactions</ul> +wrapperalreadycertainrealitystorageanotherdesktopofferedpatternunusualDigitalcapitalWebsitefailureconnectreducedAndroiddecadesregular & animalsreleaseAutomatgettingmethodsnothingPopularcaptionletterscapturesciencelicensechangesEngland=1&History = new CentralupdatedSpecialNetworkrequirecommentwarningCollegetoolbarremainsbecauseelectedDeutschfinanceworkersquicklybetweenexactlysettingdiseaseSocietyweaponsexhibit<!--Controlclassescoveredoutlineattacksdevices(windowpurposetitle="Mobile killingshowingItaliandroppedheavilyeffects-1']); +confirmCurrentadvancesharingopeningdrawingbillionorderedGermanyrelated</form>includewhetherdefinedSciencecatalogArticlebuttonslargestuniformjourneysidebarChicagoholidayGeneralpassage,"animatefeelingarrivedpassingnaturalroughly. + +The but notdensityBritainChineselack oftributeIreland" data-factorsreceivethat isLibraryhusbandin factaffairsCharlesradicalbroughtfindinglanding:lang="return leadersplannedpremiumpackageAmericaEdition]"Messageneed tovalue="complexlookingstationbelievesmaller-mobilerecordswant tokind ofFirefoxyou aresimilarstudiedmaximumheadingrapidlyclimatekingdomemergedamountsfoundedpioneerformuladynastyhow to SupportrevenueeconomyResultsbrothersoldierlargelycalling."AccountEdward segmentRobert effortsPacificlearnedup withheight:we haveAngelesnations_searchappliedacquiremassivegranted: falsetreatedbiggestbenefitdrivingStudiesminimumperhapsmorningsellingis usedreversevariant role="missingachievepromotestudentsomeoneextremerestorebottom:evolvedall thesitemapenglishway to AugustsymbolsCompanymattersmusicalagainstserving})(); +paymenttroubleconceptcompareparentsplayersregionsmonitor ''The winningexploreadaptedGalleryproduceabilityenhancecareers). The collectSearch ancientexistedfooter handlerprintedconsoleEasternexportswindowsChannelillegalneutralsuggest_headersigning.html">settledwesterncausing-webkitclaimedJusticechaptervictimsThomas mozillapromisepartieseditionoutside:false,hundredOlympic_buttonauthorsreachedchronicdemandssecondsprotectadoptedprepareneithergreatlygreateroverallimprovecommandspecialsearch.worshipfundingthoughthighestinsteadutilityquarterCulturetestingclearlyexposedBrowserliberal} catchProjectexamplehide();FloridaanswersallowedEmperordefenseseriousfreedomSeveral-buttonFurtherout of != nulltrainedDenmarkvoid(0)/all.jspreventRequestStephen + +When observe</h2> +Modern provide" alt="borders. + +For + +Many artistspoweredperformfictiontype ofmedicalticketsopposedCouncilwitnessjusticeGeorge Belgium...</a>twitternotablywaitingwarfare Other rankingphrasesmentionsurvivescholar</p> + Countryignoredloss ofjust asGeorgiastrange<head><stopped1']); +islandsnotableborder:list ofcarried100,000</h3> + severalbecomesselect wedding00.htmlmonarchoff theteacherhighly biologylife ofor evenrise of»plusonehunting(thoughDouglasjoiningcirclesFor theAncientVietnamvehiclesuch ascrystalvalue =Windowsenjoyeda smallassumed<a id="foreign All rihow theDisplayretiredhoweverhidden;battlesseekingcabinetwas notlook atconductget theJanuaryhappensturninga:hoverOnline French lackingtypicalextractenemieseven ifgeneratdecidedare not/searchbeliefs-image:locatedstatic.login">convertviolententeredfirst">circuitFinlandchemistshe was10px;">as suchdivided</span>will beline ofa greatmystery/index.fallingdue to railwaycollegemonsterdescentit withnuclearJewish protestBritishflowerspredictreformsbutton who waslectureinstantsuicidegenericperiodsmarketsSocial fishingcombinegraphicwinners<br /><by the NaturalPrivacycookiesoutcomeresolveSwedishbrieflyPersianso muchCenturydepictscolumnshousingscriptsnext tobearingmappingrevisedjQuery(-width:title">tooltipSectiondesignsTurkishyounger.match(})(); + +burningoperatedegreessource=Richardcloselyplasticentries</tr> +color:#ul id="possessrollingphysicsfailingexecutecontestlink toDefault<br /> +: true,chartertourismclassicproceedexplain</h1> +online.?xml vehelpingdiamonduse theairlineend -->).attr(readershosting#ffffffrealizeVincentsignals src="/ProductdespitediversetellingPublic held inJoseph theatreaffects<style>a largedoesn'tlater, ElementfaviconcreatorHungaryAirportsee theso thatMichaelSystemsPrograms, and width=e"tradingleft"> +personsGolden Affairsgrammarformingdestroyidea ofcase ofoldest this is.src = cartoonregistrCommonsMuslimsWhat isin manymarkingrevealsIndeed,equally/show_aoutdoorescape(Austriageneticsystem,In the sittingHe alsoIslandsAcademy + <!--Daniel bindingblock">imposedutilizeAbraham(except{width:putting).html(|| []; +DATA[ *kitchenmountedactual dialectmainly _blank'installexpertsif(typeIt also© ">Termsborn inOptionseasterntalkingconcerngained ongoingjustifycriticsfactoryits ownassaultinvitedlastinghis ownhref="/" rel="developconcertdiagramdollarsclusterphp?id=alcohol);})();using a><span>vesselsrevivalAddressamateurandroidallegedillnesswalkingcentersqualifymatchesunifiedextinctDefensedied in + <!-- customslinkingLittle Book ofeveningmin.js?are thekontakttoday's.html" target=wearingAll Rig; +})();raising Also, crucialabout">declare--> +<scfirefoxas muchappliesindex, s, but type = + +<!--towardsRecordsPrivateForeignPremierchoicesVirtualreturnsCommentPoweredinline;povertychamberLiving volumesAnthonylogin" RelatedEconomyreachescuttinggravitylife inChapter-shadowNotable</td> + returnstadiumwidgetsvaryingtravelsheld bywho arework infacultyangularwho hadairporttown of + +Some 'click'chargeskeywordit willcity of(this);Andrew unique checkedor more300px; return;rsion="pluginswithin herselfStationFederalventurepublishsent totensionactresscome tofingersDuke ofpeople,exploitwhat isharmonya major":"httpin his menu"> +monthlyofficercouncilgainingeven inSummarydate ofloyaltyfitnessand wasemperorsupremeSecond hearingRussianlongestAlbertalateralset of small">.appenddo withfederalbank ofbeneathDespiteCapitalgrounds), and percentit fromclosingcontainInsteadfifteenas well.yahoo.respondfighterobscurereflectorganic= Math.editingonline paddinga wholeonerroryear ofend of barrierwhen itheader home ofresumedrenamedstrong>heatingretainscloudfrway of March 1knowingin partBetweenlessonsclosestvirtuallinks">crossedEND -->famous awardedLicenseHealth fairly wealthyminimalAfricancompetelabel">singingfarmersBrasil)discussreplaceGregoryfont copursuedappearsmake uproundedboth ofblockedsaw theofficescoloursif(docuwhen heenforcepush(fuAugust UTF-8">Fantasyin mostinjuredUsuallyfarmingclosureobject defenceuse of Medical<body> +evidentbe usedkeyCodesixteenIslamic#000000entire widely active (typeofone cancolor =speakerextendsPhysicsterrain<tbody>funeralviewingmiddle cricketprophetshifteddoctorsRussell targetcompactalgebrasocial-bulk ofman and</td> + he left).val()false);logicalbankinghome tonaming Arizonacredits); +}); +founderin turnCollinsbefore But thechargedTitle">CaptainspelledgoddessTag -->Adding:but wasRecent patientback in=false&Lincolnwe knowCounterJudaismscript altered']); + has theunclearEvent',both innot all + +<!-- placinghard to centersort ofclientsstreetsBernardassertstend tofantasydown inharbourFreedomjewelry/about..searchlegendsis mademodern only ononly toimage" linear painterand notrarely acronymdelivershorter00&as manywidth="/* <![Ctitle =of the lowest picked escapeduses ofpeoples PublicMatthewtacticsdamagedway forlaws ofeasy to windowstrong simple}catch(seventhinfoboxwent topaintedcitizenI don'tretreat. Some ww."); +bombingmailto:made in. Many carries||{};wiwork ofsynonymdefeatsfavoredopticalpageTraunless sendingleft"><comScorAll thejQuery.touristClassicfalse" Wilhelmsuburbsgenuinebishops.split(global followsbody ofnominalContactsecularleft tochiefly-hidden-banner</li> + +. When in bothdismissExplorealways via thespañolwelfareruling arrangecaptainhis sonrule ofhe tookitself,=0&(calledsamplesto makecom/pagMartin Kennedyacceptsfull ofhandledBesides//--></able totargetsessencehim to its by common.mineralto takeways tos.org/ladvisedpenaltysimple:if theyLettersa shortHerbertstrikes groups.lengthflightsoverlapslowly lesser social </p> + it intoranked rate oful> + attemptpair ofmake itKontaktAntoniohaving ratings activestreamstrapped").css(hostilelead tolittle groups,Picture--> + + rows=" objectinverse<footerCustomV><\/scrsolvingChamberslaverywoundedwhereas!= 'undfor allpartly -right:Arabianbacked centuryunit ofmobile-Europe,is homerisk ofdesiredClintoncost ofage of become none ofp"Middle ead')[0Criticsstudios>©group">assemblmaking pressedwidget.ps:" ? rebuiltby someFormer editorsdelayedCanonichad thepushingclass="but arepartialBabylonbottom carrierCommandits useAs withcoursesa thirddenotesalso inHouston20px;">accuseddouble goal ofFamous ).bind(priests Onlinein Julyst + "gconsultdecimalhelpfulrevivedis veryr'+'iptlosing femalesis alsostringsdays ofarrivalfuture <objectforcingString(" /> + here isencoded. The balloondone by/commonbgcolorlaw of Indianaavoidedbut the2px 3pxjquery.after apolicy.men andfooter-= true;for usescreen.Indian image =family,http://  driverseternalsame asnoticedviewers})(); + is moreseasonsformer the newis justconsent Searchwas thewhy theshippedbr><br>width: height=made ofcuisineis thata very Admiral fixed;normal MissionPress, ontariocharsettry to invaded="true"spacingis mosta more totallyfall of}); + immensetime inset outsatisfyto finddown tolot of Playersin Junequantumnot thetime todistantFinnishsrc = (single help ofGerman law andlabeledforestscookingspace">header-well asStanleybridges/globalCroatia About [0]; + it, andgroupedbeing a){throwhe madelighterethicalFFFFFF"bottom"like a employslive inas seenprintermost ofub-linkrejectsand useimage">succeedfeedingNuclearinformato helpWomen'sNeitherMexicanprotein<table by manyhealthylawsuitdevised.push({sellerssimply Through.cookie Image(older">us.js"> Since universlarger open to!-- endlies in']); + marketwho is ("DOMComanagedone fortypeof Kingdomprofitsproposeto showcenter;made itdressedwere inmixtureprecisearisingsrc = 'make a securedBaptistvoting + var March 2grew upClimate.removeskilledway the</head>face ofacting right">to workreduceshas haderectedshow();action=book ofan area== "htt<header +<html>conformfacing cookie.rely onhosted .customhe wentbut forspread Family a meansout theforums.footage">MobilClements" id="as highintense--><!--female is seenimpliedset thea stateand hisfastestbesidesbutton_bounded"><img Infoboxevents,a youngand areNative cheaperTimeoutand hasengineswon the(mostlyright: find a -bottomPrince area ofmore ofsearch_nature,legallyperiod,land ofor withinducedprovingmissilelocallyAgainstthe wayk"px;"> +pushed abandonnumeralCertainIn thismore inor somename isand, incrownedISBN 0-createsOctobermay notcenter late inDefenceenactedwish tobroadlycoolingonload=it. TherecoverMembersheight assumes<html> +people.in one =windowfooter_a good reklamaothers,to this_cookiepanel">London,definescrushedbaptismcoastalstatus title" move tolost inbetter impliesrivalryservers SystemPerhapses and contendflowinglasted rise inGenesisview ofrising seem tobut in backinghe willgiven agiving cities.flow of Later all butHighwayonly bysign ofhe doesdiffersbattery&lasinglesthreatsintegertake onrefusedcalled =US&See thenativesby thissystem.head of:hover,lesbiansurnameand allcommon/header__paramsHarvard/pixel.removalso longrole ofjointlyskyscraUnicodebr /> +AtlantanucleusCounty,purely count">easily build aonclicka givenpointerh"events else { +ditionsnow the, with man whoorg/Webone andcavalryHe diedseattle00,000 {windowhave toif(windand itssolely m"renewedDetroitamongsteither them inSenatorUs</a><King ofFrancis-produche usedart andhim andused byscoringat hometo haverelatesibilityfactionBuffalolink"><what hefree toCity ofcome insectorscountedone daynervoussquare };if(goin whatimg" alis onlysearch/tuesdaylooselySolomonsexual - <a hrmedium"DO NOT France,with a war andsecond take a > + + +market.highwaydone inctivity"last">obligedrise to"undefimade to Early praisedin its for hisathleteJupiterYahoo! termed so manyreally s. The a woman?value=direct right" bicycleacing="day andstatingRather,higher Office are nowtimes, when a pay foron this-link">;borderaround annual the Newput the.com" takin toa brief(in thegroups.; widthenzymessimple in late{returntherapya pointbanninginks"> +();" rea place\u003Caabout atr> + ccount gives a<SCRIPTRailwaythemes/toolboxById("xhumans,watchesin some if (wicoming formats Under but hashanded made bythan infear ofdenoted/iframeleft involtagein eacha"base ofIn manyundergoregimesaction </p> +<ustomVa;></importsor thatmostly &re size="</a></ha classpassiveHost = WhetherfertileVarious=[];(fucameras/></td>acts asIn some> + +<!organis <br />Beijingcatalàdeutscheuropeueuskaragaeilgesvenskaespañamensajeusuariotrabajoméxicopáginasiempresistemaoctubreduranteañadirempresamomentonuestroprimeratravésgraciasnuestraprocesoestadoscalidadpersonanúmeroacuerdomúsicamiembroofertasalgunospaísesejemploderechoademásprivadoagregarenlacesposiblehotelessevillaprimeroúltimoeventosarchivoculturamujeresentradaanuncioembargomercadograndesestudiomejoresfebrerodiseñoturismocódigoportadaespaciofamiliaantoniopermiteguardaralgunaspreciosalguiensentidovisitastítuloconocersegundoconsejofranciaminutossegundatenemosefectosmálagasesiónrevistagranadacompraringresogarcíaacciónecuadorquienesinclusodeberámateriahombresmuestrapodríamañanaúltimaestamosoficialtambienningúnsaludospodemosmejorarpositionbusinesshomepagesecuritylanguagestandardcampaignfeaturescategoryexternalchildrenreservedresearchexchangefavoritetemplatemilitaryindustryservicesmaterialproductsz-index:commentssoftwarecompletecalendarplatformarticlesrequiredmovementquestionbuildingpoliticspossiblereligionphysicalfeedbackregisterpicturesdisabledprotocolaudiencesettingsactivityelementslearninganythingabstractprogressoverviewmagazineeconomictrainingpressurevarious <strong>propertyshoppingtogetheradvancedbehaviordownloadfeaturedfootballselectedLanguagedistanceremembertrackingpasswordmodifiedstudentsdirectlyfightingnortherndatabasefestivalbreakinglocationinternetdropdownpracticeevidencefunctionmarriageresponseproblemsnegativeprogramsanalysisreleasedbanner">purchasepoliciesregionalcreativeargumentbookmarkreferrerchemicaldivisioncallbackseparateprojectsconflicthardwareinterestdeliverymountainobtained= false;for(var acceptedcapacitycomputeridentityaircraftemployedproposeddomesticincludesprovidedhospitalverticalcollapseapproachpartnerslogo"><adaughterauthor" culturalfamilies/images/assemblypowerfulteachingfinisheddistrictcriticalcgi-bin/purposesrequireselectionbecomingprovidesacademicexerciseactuallymedicineconstantaccidentMagazinedocumentstartingbottom">observed: "extendedpreviousSoftwarecustomerdecisionstrengthdetailedslightlyplanningtextareacurrencyeveryonestraighttransferpositiveproducedheritageshippingabsolutereceivedrelevantbutton" violenceanywherebenefitslaunchedrecentlyalliancefollowedmultiplebulletinincludedoccurredinternal$(this).republic><tr><tdcongressrecordedultimatesolution<ul id="discoverHome</a>websitesnetworksalthoughentirelymemorialmessagescontinueactive">somewhatvictoriaWestern title="LocationcontractvisitorsDownloadwithout right"> +measureswidth = variableinvolvedvirginianormallyhappenedaccountsstandingnationalRegisterpreparedcontrolsaccuratebirthdaystrategyofficialgraphicscriminalpossiblyconsumerPersonalspeakingvalidateachieved.jpg" />machines</h2> + keywordsfriendlybrotherscombinedoriginalcomposedexpectedadequatepakistanfollow" valuable</label>relativebringingincreasegovernorplugins/List of Header">" name=" ("graduate</head> +commercemalaysiadirectormaintain;height:schedulechangingback to catholicpatternscolor: #greatestsuppliesreliable</ul> + <select citizensclothingwatching<li id="specificcarryingsentence<center>contrastthinkingcatch(e)southernMichael merchantcarouselpadding:interior.split("lizationOctober ){returnimproved--> + +coveragechairman.png" />subjectsRichard whateverprobablyrecoverybaseballjudgmentconnect..css" /> websitereporteddefault"/></a> +electricscotlandcreationquantity. ISBN 0did not instance-search-" lang="speakersComputercontainsarchivesministerreactiondiscountItalianocriteriastrongly: 'http:'script'coveringofferingappearedBritish identifyFacebooknumerousvehiclesconcernsAmericanhandlingdiv id="William provider_contentaccuracysection andersonflexibleCategorylawrence<script>layout="approved maximumheader"></table>Serviceshamiltoncurrent canadianchannels/themes//articleoptionalportugalvalue=""intervalwirelessentitledagenciesSearch" measuredthousandspending…new Date" size="pageNamemiddle" " /></a>hidden">sequencepersonaloverflowopinionsillinoislinks"> + <title>versionssaturdayterminalitempropengineersectionsdesignerproposal="false"Españolreleasessubmit" er"additionsymptomsorientedresourceright"><pleasurestationshistory.leaving border=contentscenter">. + +Some directedsuitablebulgaria.show();designedGeneral conceptsExampleswilliamsOriginal"><span>search">operatorrequestsa "allowingDocumentrevision. + +The yourselfContact michiganEnglish columbiapriorityprintingdrinkingfacilityreturnedContent officersRussian generate-8859-1"indicatefamiliar qualitymargin:0 contentviewportcontacts-title">portable.length eligibleinvolvesatlanticonload="default.suppliedpaymentsglossary + +After guidance</td><tdencodingmiddle">came to displaysscottishjonathanmajoritywidgets.clinicalthailandteachers<head> + affectedsupportspointer;toString</small>oklahomawill be investor0" alt="holidaysResourcelicensed (which . After considervisitingexplorerprimary search" android"quickly meetingsestimate;return ;color:# height=approval, " checked.min.js"magnetic></a></hforecast. While thursdaydvertiseéhasClassevaluateorderingexistingpatients Online coloradoOptions"campbell<!-- end</span><<br /> +_popups|sciences," quality Windows assignedheight: <b classle" value=" Companyexamples<iframe believespresentsmarshallpart of properly). + +The taxonomymuch of </span> +" data-srtuguêsscrollTo project<head> +attorneyemphasissponsorsfancyboxworld's wildlifechecked=sessionsprogrammpx;font- Projectjournalsbelievedvacationthompsonlightingand the special border=0checking</tbody><button Completeclearfix +<head> +article <sectionfindingsrole in popular Octoberwebsite exposureused to changesoperatedclickingenteringcommandsinformed numbers </div>creatingonSubmitmarylandcollegesanalyticlistingscontact.loggedInadvisorysiblingscontent"s")s. This packagescheckboxsuggestspregnanttomorrowspacing=icon.pngjapanesecodebasebutton">gamblingsuch as , while </span> missourisportingtop:1px .</span>tensionswidth="2lazyloadnovemberused in height="cript"> + </<tr><td height:2/productcountry include footer" <!-- title"></jquery.</form> +(简体)(繁體)hrvatskiitalianoromânătürkçeاردوtambiénnoticiasmensajespersonasderechosnacionalserviciocontactousuariosprogramagobiernoempresasanunciosvalenciacolombiadespuésdeportesproyectoproductopúbliconosotroshistoriapresentemillonesmediantepreguntaanteriorrecursosproblemasantiagonuestrosopiniónimprimirmientrasaméricavendedorsociedadrespectorealizarregistropalabrasinterésentoncesespecialmiembrosrealidadcórdobazaragozapáginassocialesbloqueargestiónalquilersistemascienciascompletoversióncompletaestudiospúblicaobjetivoalicantebuscadorcantidadentradasaccionesarchivossuperiormayoríaalemaniafunciónúltimoshaciendoaquellosediciónfernandoambientefacebooknuestrasclientesprocesosbastantepresentareportarcongresopublicarcomerciocontratojóvenesdistritotécnicaconjuntoenergíatrabajarasturiasrecienteutilizarboletínsalvadorcorrectatrabajosprimerosnegocioslibertaddetallespantallapróximoalmeríaanimalesquiénescorazónsecciónbuscandoopcionesexteriorconceptotodavíagaleríaescribirmedicinalicenciaconsultaaspectoscríticadólaresjusticiadeberánperíodonecesitamantenerpequeñorecibidatribunaltenerifecancióncanariasdescargadiversosmallorcarequieretécnicodeberíaviviendafinanzasadelantefuncionaconsejosdifícilciudadesantiguasavanzadatérminounidadessánchezcampañasoftonicrevistascontienesectoresmomentosfacultadcréditodiversassupuestofactoressegundospequeñaгодаеслиестьбылобытьэтомЕслитогоменявсехэтойдажебылигодуденьэтотбыласебяодинсебенадосайтфотонегосвоисвойигрытожевсемсвоюлишьэтихпокаднейдомамиралиботемухотядвухсетилюдиделомиретебясвоевидечегоэтимсчеттемыценысталведьтемеводытебевышенамитипатомуправлицаоднагодызнаюмогудругвсейидеткиноодноделаделесрокиюнявесьЕстьразанашиاللهالتيجميعخاصةالذيعليهجديدالآنالردتحكمصفحةكانتاللييكونشبكةفيهابناتحواءأكثرخلالالحبدليلدروساضغطتكونهناكساحةناديالطبعليكشكرايمكنمنهاشركةرئيسنشيطماذاالفنشبابتعبررحمةكافةيقولمركزكلمةأحمدقلبييعنيصورةطريقشاركجوالأخرىمعناابحثعروضبشكلمسجلبنانخالدكتابكليةبدونأيضايوجدفريقكتبتأفضلمطبخاكثرباركافضلاحلىنفسهأيامردودأنهاديناالانمعرضتعلمداخلممكن���������������������� +  + ������������������������������������������������resourcescountriesquestionsequipmentcommunityavailablehighlightDTD/xhtmlmarketingknowledgesomethingcontainerdirectionsubscribeadvertisecharacter" value="</select>Australia" class="situationauthorityfollowingprimarilyoperationchallengedevelopedanonymousfunction functionscompaniesstructureagreement" title="potentialeducationargumentssecondarycopyrightlanguagesexclusivecondition</form> +statementattentionBiography} else { +solutionswhen the Analyticstemplatesdangeroussatellitedocumentspublisherimportantprototypeinfluence»</effectivegenerallytransformbeautifultransportorganizedpublishedprominentuntil thethumbnailNational .focus();over the migrationannouncedfooter"> +exceptionless thanexpensiveformationframeworkterritoryndicationcurrentlyclassNamecriticismtraditionelsewhereAlexanderappointedmaterialsbroadcastmentionedaffiliate</option>treatmentdifferent/default.Presidentonclick="biographyotherwisepermanentFrançaisHollywoodexpansionstandards</style> +reductionDecember preferredCambridgeopponentsBusiness confusion> +<title>presentedexplaineddoes not worldwideinterfacepositionsnewspaper</table> +mountainslike the essentialfinancialselectionaction="/abandonedEducationparseInt(stabilityunable to +relationsNote thatefficientperformedtwo yearsSince thethereforewrapper">alternateincreasedBattle ofperceivedtrying tonecessaryportrayedelectionsElizabethdiscoveryinsurances.length;legendaryGeographycandidatecorporatesometimesservices.inheritedCommunityreligiouslocationsCommitteebuildingsthe worldno longerbeginningreferencecannot befrequencytypicallyinto the relative;recordingpresidentinitiallytechniquethe otherit can beexistenceunderlinethis timetelephoneitemscopepracticesadvantage);return For otherprovidingdemocracyboth the extensivesufferingsupportedcomputers functionpracticalsaid thatit may beEnglish +suspectedmargin: 0spiritual + +microsoftgraduallydiscussedhe becameexecutivejquery.jshouseholdconfirmedpurchasedliterallydestroyedup to thevariationremainingit is notcenturiesJapanese among thecompletedalgorithminterestsrebellionundefinedencourageresizableinvolvingsensitiveuniversalprovision(althoughfeaturingconducted), which continued-header">February numerous overflow:componentfragmentsexcellentcolspan="technicalnear the Advanced source ofexpressedHong Kong Facebookmultiple mechanismelevationoffensive + sponsoreddocument.or "there arethose whomovementsprocessesdifficultsubmittedrecommendconvincedpromoting" width=".replace(classicalcoalitionhis firstdecisionsassistantindicatedevolution-wrapper"enough toalong thedelivered--> + + +
Archbishop class="nobeing usedapproachesprivilegesnoscript> +results inmay be theEaster eggmechanismsreasonablePopulationCollectionselected">noscript> /index.phparrival of-jssdk'));managed toincompletecasualtiescompletionChristiansSeptember arithmeticproceduresmight haveProductionit appearsPhilosophyfriendshipleading togiving thetoward theguaranteeddocumentedcolor:#000video gamecommissionreflectingchange theassociatedsans-serifonkeypress; padding:He was theunderlyingtypically , and the srcElementsuccessivesince the should be networkingaccountinguse of thelower thanshows that + complaintscontinuousquantitiesastronomerhe did notdue to itsapplied toan averageefforts tothe futureattempt toTherefore,capabilityRepublicanwas formedElectronickilometerschallengespublishingthe formerindigenousdirectionssubsidiaryconspiracydetails ofand in theaffordablesubstancesreason forconventionitemtype="absolutelysupposedlyremained aattractivetravellingseparatelyfocuses onelementaryapplicablefound thatstylesheetmanuscriptstands for no-repeat(sometimesCommercialin Americaundertakenquarter ofan examplepersonallyindex.php? +percentagebest-knowncreating a" dir="ltrLieutenant +
is said tostructuralreferendummost oftena separate-> +
implementedcan be seenthere was ademonstratecontainer">connectionsthe Britishwas written!important;px; margin-followed byability to complicatedduring the immigrationalso called

as follows:merged withthrough thecommercial pointed outopportunityview of therequirementdivision ofprogramminghe receivedsetInterval">maintainingChristopherMuch of thewritings of" height="2size of theversion of mixture of between theExamples ofeducationalcompetitive onsubmit="director ofdistinctive/DTD XHTML relating totendency toprovince ofwhich woulddespite thescientific legislature.innerHTML allegationsAgriculturewas used inapproach tointelligentyears later,sans-serifdeterminingPerformanceappearances, which is foundationsabbreviatedhigher thans from the individual composed ofsupposed toclaims thatattributionfont-size:1elements ofHistorical his brotherat the timeanniversarygoverned byrelated to ultimately innovationsit is stillcan only bedefinitionstoGMTStringA number ofimg class="Eventually,was changedoccurred inneighboringdistinguishwhen he wasintroducingterrestrialMany of theargues thatan Americanconquest ofwidespread were killedscreen and In order toexpected todescendantsare locatedlegislativegenerations backgroundmost peopleyears afterthere is nothe highestfrequently they do notargued thatshowed thatpredominanttheologicalby the timeconsideringshort-livedcan be usedvery littleone of the had alreadyinterpretedcommunicatefeatures ofgovernment,entered the" height="3Independentpopulationslarge-scale. Although used in thedestructionpossibilitystarting intwo or moreexpressionssubordinatelarger thanhistory and +Continentaleliminatingwill not bepractice ofin front ofsite of theensure thatto create amississippipotentiallyoutstandingbetter thanwhat is nowsituated inmeta name="TraditionalsuggestionsTranslationthe form ofatmosphericideologicalenterprisescalculatingeast of theremnants ofpluginspage/index.php?remained intransformedHe was alsowas alreadystatisticalin favor ofMinistry ofmovement offormulationis required +question ofwas electedto become abecause of some peopleinspired bysuccessful a time whenmore commonamongst thean officialwidth:100%;technology,was adoptedto keep thesettlementslive birthsindex.html"Connecticutassigned to&times;account foralign=rightthe companyalways beenreturned toinvolvementBecause thethis period" name="q" confined toa result ofvalue="" />is actuallyEnvironment + +Conversely,> +
this is notthe presentif they areand finallya matter of +
+ +faster thanmajority ofafter whichcomparativeto maintainimprove theawarded theer" class="frameborderrestorationin the sameanalysis oftheir firstDuring the continentalsequence offunction(){font-size: work on the +adopted theproperty ofdirected byeffectivelywas broughtchildren ofProgramminglonger thanmanuscriptswar againstby means ofand most ofsimilar to proprietaryoriginatingprestigiousgrammaticalexperience.to make theIt was alsois found incompetitorsin the U.S.replace thebrought thecalculationfall of thethe generalpracticallyin honor ofreleased inresidentialand some ofking of thereaction to1st Earl ofculture andprincipally + they can beback to thesome of hisexposure toare similarform of theaddFavoritecitizenshippart in thepeople within practiceto continue&minus;approved by the first allowed theand for thefunctioningplaying thesolution toheight="0" in his bookmore than afollows thecreated thepresence in nationalistthe idea ofa characterwere forced class="btndays of thefeatured inshowing theinterest inin place ofturn of thethe head ofLord of thepoliticallyhas its ownEducationalapproval ofsome of theeach other,behavior ofand becauseand anotherappeared onrecorded inblack"may includethe world'scan lead torefers to aborder="0" government winning theresulted in while the Washington,the subjectcity in the>

+ reflect theto completebecame moreradioactiverejected bywithout anyhis father,which couldcopy of theto indicatea politicalaccounts ofconstitutesworked witherof his lifeaccompaniedclientWidthprevent theLegislativedifferentlytogether inhas severalfor anothertext of thefounded thee with the is used forchanged theusually theplace wherewhereas the> The currentthe site ofsubstantialexperience,in the Westthey shouldslovenčinacomentariosuniversidadcondicionesactividadesexperienciatecnologíaproducciónpuntuaciónaplicacióncontraseñacategoríasregistrarseprofesionaltratamientoregístratesecretaríaprincipalesprotecciónimportantesimportanciaposibilidadinteresantecrecimientonecesidadessuscribirseasociacióndisponiblesevaluaciónestudiantesresponsableresoluciónguadalajararegistradosoportunidadcomercialesfotografíaautoridadesingenieríatelevisióncompetenciaoperacionesestablecidosimplementeactualmentenavegaciónconformidadline-height:font-family:" : "http://applicationslink" href="specifically// +/index.html"window.open( !important;application/independence//www.googleorganizationautocompleterequirementsconservative
most notably/>
notification'undefined')Furthermore,believe thatinnerHTML = prior to thedramaticallyreferring tonegotiationsheadquartersSouth AfricaunsuccessfulPennsylvaniaAs a result, +
English (US)appendChild(transmissions. However, intelligence" tabindex="float:right;Commonwealthranging fromin which theat least onereproductionencyclopedia;font-size:1jurisdictionat that time">compensationchampionshipmedia="all" violation ofreference toreturn true;Strict//EN" transactionsinterventionverificationInformation difficultiesChampionshipcapabilities} + +Christianityfor example,Professionalrestrictionssuggest thatwas released(such as theremoveClass(unemploymentthe Americanstructure of/index.html published inspan class=""> + +f (document.border: 1px {font-size:1treatment of0" height="1modificationIndependencedivided intogreater thanachievementsestablishingJavaScript" neverthelesssignificanceBroadcasting> container"> +such as the influence ofa particularsrc='http://navigation" half of the substantial  advantage ofdiscovery offundamental metropolitanthe opposite" xml:lang="deliberatelyalign=centerevolution ofpreservationimprovementsbeginning inJesus ChristPublicationsdisagreementtext-align:r, function()similaritiesbody>is currentlyalphabeticalis sometimestype="image/many of the flow:hidden;available indescribe theexistence ofall over thethe Internet